Snap for 9932955 from 6755a619c71943131573dd55b964ed114f1d3856 to studio-hedgehog-release

Change-Id: I47b32a0b107093044502ebe82bbfe8d3792b5f2b
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..fbd04c1
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,16 @@
+BasedOnStyle: Chromium
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: true
+AlignConsecutiveMacros: true
+AlignEscapedNewlines: true
+# AlignOperands: Align
+AlignTrailingComments: true
+AlwaysBreakAfterReturnType: AllDefinitions
+BreakBeforeBraces: Allman
+ColumnLimit: 80
+DerivePointerAlignment: false
+IndentCaseLabels: false
+PointerAlignment: Left
+SpaceBeforeParens: ControlStatements
+SpacesInParentheses: true
diff --git a/.gitignore b/.gitignore
index a47f568..e4f1510 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
-config.mk
-objs/vc2010/
-build
+/build/
+/config.mk
+include/dlg/
+src/dlg/dlg.c
+subprojects/*
+!subprojects/*.wrap
+/tests/data/*
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..c51e136
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,230 @@
+# CI setup for FreeType.
+
+stages:
+ - build
+
+# FIXME: Use --werror once warnings are fixed.
+variables:
+  MESON_ARGS: --fatal-meson-warnings --default-library=both
+  MESON_ARGS_WINDOWS: ${MESON_ARGS} --force-fallback-for=zlib
+
+.build windows common:
+  # TODO: should probably get its own image at some point instead of reusing the GStreamer one
+  # See https://gitlab.freedesktop.org/gstreamer/gstreamer/container_registry/18035 for latest
+  image: "registry.freedesktop.org/gstreamer/gstreamer/amd64/windows:2022-07-29.3-main"
+  stage: 'build'
+  tags:
+    - 'docker'
+    - 'windows'
+    - '2022'
+    - 'gstreamer-windows'
+
+.build linux common:
+  # See
+  # https://gitlab.freedesktop.org/freetype/docker-images/container_registry/20896
+  image: 'registry.freedesktop.org/freetype/docker-images/debian:latest'
+  stage: 'build'
+
+.build macos common:
+  stage: 'build'
+  tags:
+    - 'gst-macos-11.1'
+
+.build windows meson:
+  extends: '.build windows common'
+  variables:
+    # Make sure any failure in PowerShell scripts is fatal.
+    ErrorActionPreference: 'Stop'
+    WarningPreference: 'Stop'
+    # Uncomment the following key if you need to pass custom args, as well
+    # with the `$env:MESON_ARGS` line in the `script:` blocks.
+    # MESON_ARGS: >-
+    #   -Dfoo=enabled
+    #   -Dbar=disabled
+  before_script:
+    # Update RootCAs in order to access to some sites.
+    - certutil -generateSSTFromWU "C:\roots.sst"
+    - Import-Certificate -CertStoreLocation "Cert:\LocalMachine\Root" "C:\roots.sst"
+    # Make sure meson is up to date so we don't need to rebuild the image
+    # with each release.
+    - pip3 install -U 'meson==0.59.*'
+    - pip3 install --upgrade certifi
+    - pip3 install -U ninja
+
+    # Generate a UWP cross-file in case it's used
+    - $PSDefaultParameterValues['Out-File:Encoding'] = 'ASCII'
+    - echo "[binaries]" > uwp-crossfile.meson
+    - echo "c = 'cl'" >> uwp-crossfile.meson
+    - echo "strip = ['true']" >> uwp-crossfile.meson
+    - echo "[built-in options]" >> uwp-crossfile.meson
+    - echo "c_args = ['-DWINAPI_FAMILY=WINAPI_FAMILY_APP', '-DUNICODE', '-D_WIN32_WINNT=0x0A00', '-we4013']" >> uwp-crossfile.meson
+    - echo "c_winlibs = ['windowsapp.lib']" >> uwp-crossfile.meson
+  script:
+    # For some reason, options are separated by newlines instead of spaces,
+    # so we have to replace them first.
+    #
+    # - $env:MESON_ARGS = $env:MESON_ARGS.replace("`n"," ")
+    #
+    # Gitlab executes PowerShell in docker, but `VsDevCmd.bat` is a batch
+    # script.  Environment variables substitutions is done by PowerShell
+    # before calling `cmd.exe`, that's why we use `$env:FOO` instead of
+    # `%FOO%`.
+    - cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=$env:ARCH $env:VS_UWP &&
+        meson setup build $env:MESON_ARGS_WINDOWS $env:MESON_ARGS_UWP &&
+        meson compile --verbose -C build
+        $env:MESON_WINDOWS_TESTS"
+
+
+# Format of job names:
+# <OS> <Build-Tool> <Build-Params> <Architecture> 
+
+
+# Windows jobs.
+
+windows meson vs2019 amd64:
+  extends: '.build windows meson'
+  variables:
+    ARCH: 'amd64'
+    MESON_WINDOWS_TESTS: '&& meson test -C build && meson test -C build --benchmark'
+
+windows meson vs2019 x86:
+  extends: '.build windows meson'
+  variables:
+    ARCH: 'x86'
+    MESON_WINDOWS_TESTS: '&& meson test -C build && meson test -C build --benchmark'
+
+windows meson vs2019 amd64 uwp:
+  extends: '.build windows meson'
+  variables:
+    ARCH: 'amd64'
+    VS_UWP: '-app_platform=UWP'
+    MESON_ARGS_UWP: '--cross-file uwp-crossfile.meson -Dc_winlibs="windowsapp.lib"'
+
+# Linux Jobs.
+#
+# Jobs with "libs" in the name force-enable libraries.
+# They are disabled for the remaining jobs.
+
+linux autotools:
+  extends: '.build linux common'
+  script: |
+    ./autogen.sh
+    ./configure --with-brotli=no \
+                --with-bzip2=no \
+                --with-harfbuzz=no \
+                --with-png=no \
+                --with-zlib=no \
+                CC=gcc
+
+    make -j$(nproc) && make install
+
+linux autotools libs:
+  extends: '.build linux common'
+  script: |
+    ./autogen.sh
+    ./configure --with-brotli=yes \
+                --with-bzip2=yes \
+                --with-harfbuzz=yes \
+                --with-png=yes \
+                --with-zlib=yes \
+                CC=gcc
+
+    make -j$(nproc) && make install
+
+linux autotools libs clang:
+  extends: '.build linux common'
+  script: |
+    ./autogen.sh
+    ./configure --with-brotli=yes \
+                --with-bzip2=yes \
+                --with-harfbuzz=yes \
+                --with-png=yes \
+                --with-zlib=yes \
+                CC=clang
+
+    make -j$(nproc) && make install
+
+linux meson:
+  extends: '.build linux common'
+  script: |
+    meson setup build ${MESON_ARGS} \
+                      -Dbrotli=disabled \
+                      -Dbzip2=disabled \
+                      -Dharfbuzz=disabled \
+                      -Dpng=disabled \
+                      -Dzlib=disabled
+
+    meson compile --verbose -C build
+    meson install -C build
+
+linux meson libs:
+  extends: '.build linux common'
+  script: |
+    meson setup build ${MESON_ARGS} \
+                      -Dbrotli=enabled \
+                      -Dbzip2=enabled \
+                      -Dharfbuzz=disabled \
+                      -Dpng=disabled \
+                      -Dzlib=disabled
+
+    meson compile --verbose -C build
+    meson install -C build
+
+linux cmake:
+  extends: '.build linux common'
+  script: |
+    cmake -B build -D FT_DISABLE_BROTLI=TRUE \
+                   -D FT_DISABLE_BZIP2=TRUE \
+                   -D FT_DISABLE_HARFBUZZ=TRUE \
+                   -D FT_DISABLE_PNG=TRUE \
+                   -D FT_DISABLE_ZLIB=TRUE
+
+    cmake --build build --target install
+
+linux cmake libs:
+  extends: '.build linux common'
+  script: |
+    cmake -B build -D FT_REQUIRE_BROTLI=TRUE \
+                   -D FT_REQUIRE_BZIP2=TRUE \
+                   -D FT_REQUIRE_HARFBUZZ=TRUE \
+                   -D FT_REQUIRE_PNG=TRUE \
+                   -D FT_REQUIRE_ZLIB=TRUE
+
+    cmake --build build --target install
+
+
+# MacOS jobs.
+
+macos autotools:
+  extends: '.build macos common'
+  before_script:
+    - '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"'
+  script:
+    - brew install autoconf automake libtool
+    - ./autogen.sh
+    - ./configure
+    - 'make -j$(sysctl -n hw.logicalcpu)'
+    - make install
+
+macos autotools clang:
+  extends: '.build macos common'
+  before_script:
+    - '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"'
+  script:
+    - brew install autoconf automake libtool
+    - ./autogen.sh
+    - './configure CC=clang'
+    - 'make -j$(sysctl -n hw.logicalcpu)'
+    - make install
+
+macos meson:
+  extends: '.build macos common'
+  script:
+    - pip3 install --upgrade pip
+    - pip3 install -U meson
+    - pip3 install --upgrade certifi
+    - pip3 install -U ninja
+
+    - meson setup build ${MESON_ARGS}
+    - meson compile --verbose -C build
+    - sudo meson install -C build
diff --git a/.mailmap b/.mailmap
index c406e23..533274d 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,9 +1,24 @@
+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>
 Alexei Podtelezhnikov (Алексей Подтележников) <apodtele@gmail.com>
-Behdad Esfahbod <behdad@behdad.org> <behdad.esfahbod@gmail.com>
-Bram Tassyns <bramt@enfocus.be> bram tassyns <BramT@enfocus.be>
-Bram Tassyns <bramt@enfocus.be> <BramT@enfocus.com>
+Nikhil Ramakrishnan (निखिल रामकृष्णन) <ramakrishnan.nikhil@gmail.com>
+Dominik Röttsches <drott@chromium.org> <drott@google.com>
+Kostya Serebryany <kcc@google.com> <konstantin.s.serebryany@gmail.com>
 Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> <sssa@flavor1.ipc.hiroshima-u.ac.jp>
 Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> sssa <sssa@IPA2004-mps.local>
+Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> sssa <sssa@sssas-powerbook-g4-12.local>
 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>
+David Turner <david@freetype.org> <david.turner.dev@gmail.com>
+David Turner <david@freetype.org> <digit@google.com>
+Anuj Verma (अनुज वर्मा) <anujv@iitbhilai.ac.in>
 Ben Wagner <bungeman@gmail.com> Bungeman <bungeman@gmail.com>
-Ewald Hew (Hew Yih Shiuan 丘毅宣) <ewaldhew@gmail.com>
+Ben Wagner <bungeman@gmail.com> <bungeman@google.com>
+Ben Wagner <bungeman@gmail.com> <bungeman@chromium.org>
+Nikolaus Waxweiler <madigens@gmail.com> <nikolaus.waxweiler@daltonmaag.com>
diff --git a/Android.bp b/Android.bp
index df3dde6..3680aff 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,10 +1,61 @@
-cc_library_shared {
-    name: "libft2",
+package {
+    default_applicable_licenses: ["external_freetype_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+    name: "external_freetype_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD-3-Clause",
+        "SPDX-license-identifier-FSFAP",
+        "SPDX-license-identifier-FTL",
+        "SPDX-license-identifier-MIT",
+
+        // For src/autofit/ft-hb.{h|c}. This file is not used but included from source file.
+        // "SPDX-license-Identifier-MIT-Modern-Variant"
+
+        // TODO: Following licenses left from original. Check where these licenses are came from.
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-ISC",
+        "SPDX-license-identifier-LGPL",
+        "legacy_unencumbered",
+    ],
+    license_text: [
+        "LICENSE.TXT",
+        "LICENSE",
+        "NOTICE",
+
+        "docs/FTL.TXT",
+        "LICENSE_APACHE2.TXT",
+        "LICENSE_MIT.TXT",
+        "LICENSE_BSD_3_CLAUSE.TXT",
+        "LICENSE_MIT_MODERN_VARIANT.TXT",
+    ],
+}
+
+cc_defaults {
+    name: "libft2_defaults",
     host_supported: true,
+    // TODO(b/153609531): remove when no longer needed.
+    native_bridge_supported: true,
 
     // compile in ARM mode, since the glyph loader/renderer is a hotspot
     // when loading complex pages in the browser
-    //
     arch: {
         arm: {
             instruction_set: "arm",
@@ -32,8 +83,10 @@
         "src/pshinter/pshinter.c",
         "src/psnames/psnames.c",
         "src/raster/raster.c",
+        "src/sdf/sdf.c",
         "src/sfnt/sfnt.c",
         "src/smooth/smooth.c",
+        "src/svg/svg.c",
         "src/truetype/truetype.c",
         "src/type1/type1.c",
     ],
@@ -54,6 +107,23 @@
         "-Wno-unused-parameter",
         // Disabling some of modules results in warnings
         "-Wno-unused-variable",
+        // Temporary disables unused function warning
+        "-Wno-unused-function",
+    ],
+}
+
+cc_library {
+    name: "libft2",
+    defaults: ["libft2_defaults"],
+
+    cflags: [
+        // Usually these are defined in include/freetype/config/ftoption.h
+        // we have commented them and defined them here to allow for the
+        // no dependency variant libft2.nodep below.
+        "-DFT_CONFIG_OPTION_USE_PNG",
+        "-DFT_CONFIG_OPTION_USE_ZLIB",
+        "-DFT_CONFIG_OPTION_SYSTEM_ZLIB",
+
         // the following is for testing only, and should not be used in final
         // builds of the product
         // "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER",
@@ -81,11 +151,125 @@
             enabled: true,
         },
     },
+
+    llndk: {
+        private: true,
+        symbol_file: "libft2.map.txt",
+    },
 }
 
-llndk_library {
-    name: "libft2",
-    vendor_available: false,
-    symbol_file: "libft2.map.txt",
-    export_include_dirs: ["include"],
+// variant of libft2 without any library dependencies.
+cc_library_static {
+    name: "libft2.nodep",
+    vendor_available: true,
+    defaults: ["libft2_defaults"],
 }
+
+// Following defines unused files that is under licenses that are different
+// from default licenses.
+
+license {
+    name: "external_freetype_license.builds.unused.unix.GPLv2",
+    visibility: ["//visibility:private"],
+    license_kinds: [
+      "SPDX-license-identifier-GPL-2.0-with-autoconf-exception",
+    ],
+    license_text: [
+        "builds/unix/LICENSE_GPLv2_WITH_AUTOCONF_EXCEPTION.TXT",
+    ],
+}
+
+filegroup {
+    name: "freetype.builds.unix.GPLv2",
+    visibility: ["//visibility:private"],
+    licenses: ["external_freetype_license.builds.unused.unix.GPLv2"],
+    srcs: ["builds/unix/pkg.m4"],
+}
+
+license {
+    name: "external_freetype_license.builds.unused.unix.GPLv3",
+    visibility: ["//visibility:private"],
+    license_kinds: [
+      "SPDX-license-identifier-GPL-3.0-with-autoconf-exception",
+    ],
+    license_text: [
+        // For builds/unix/ax_pthread.m4
+        "builds/unix/LICENSE_GPLv3_WITH_AUTOCONF_EXCEPTION.TXT",
+    ],
+}
+
+filegroup {
+    name: "freetype.builds.unix.GPLv3",
+    visibility: ["//visibility:private"],
+    licenses: ["external_freetype_license.builds.unused.unix.GPLv3"],
+    srcs: ["builds/unix/ax_pthread.m4"],
+}
+
+license {
+    name: "external_freetype_license.builds.unused.zlib",
+    visibility: ["//visibility:private"],
+    license_kinds: [
+        "SPDX-license-identifier-Zlib",
+    ],
+    license_text: [
+        "src/gzip/LICENSE_ZLIB.TXT"
+    ],
+}
+
+filegroup {
+    name: "freetype.unused.zlib",
+    visibility: ["//visibility:private"],
+    licenses: ["external_freetype_license.builds.unused.zlib"],
+    srcs: [
+        "src/gzip/adler32.c",
+        "src/gzip/crc32.c",
+        "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
+        "src/gzip/inflate.c",
+        "src/gzip/inflate.h",
+        "src/gzip/inftrees.c",
+        "src/gzip/inftrees.h",
+        "src/gzip/zlib.h",
+        "src/gzip/zutil.c",
+        "src/gzip/zutil.h",
+    ],
+}
+
+license {
+    name: "external_freetype_license.unused.base.pcf",
+    visibility: ["//visibility:private"],
+    license_kinds: [
+      "SPDX-license-identifier-FTL",
+      "SPDX-license-identifier-MIT",
+      "legacy_notice",  // For src/base/pcf/pcfutil.c
+    ],
+    license_text: [
+        "docs/FTL.TXT",
+        "LICENSE_MIT.TXT",
+    ],
+}
+
+filegroup {
+    name: "freetype.unused.base.pcf",
+    visibility: ["//visibility:private"],
+    licenses: ["external_freetype_license.unused.base.pcf"],
+    srcs: [
+        "src/pcf/module.mk",
+        "src/pcf/pcfdrivr.c",
+        "src/pcf/pcfdrivr.h",
+        "src/pcf/pcferror.h",
+        "src/pcf/pcf.h",
+        "src/pcf/pcfread.c",
+        "src/pcf/pcfread.h",
+        "src/pcf/pcfutil.c",
+        "src/pcf/pcfutil.h",
+        "src/pcf/README",
+        "src/pcf/rules.mk",
+    ],
+}
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f58337..554b580 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 # CMakeLists.txt
 #
-# Copyright 2013-2018 by
+# Copyright (C) 2013-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # Written originally by John Cary <cary@txcorp.com>
@@ -12,16 +12,20 @@
 # fully.
 #
 #
-# The following will 1. create a build directory and 2. change into it and
+# The following will (1) create a build directory, and (2) change into it and
 # call cmake to configure the build with default parameters as a static
-# library.
+# library.  See
 #
-#   cmake -E make_directory build
-#   cmake -E chdir build cmake ..
+#   https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
+#
+# for information about debug or release builds, for example
+#
+#   cmake -B build -D CMAKE_BUILD_TYPE=Release
+#
 #
 # For a dynamic library, use
 #
-#   cmake -E chdir build cmake -D BUILD_SHARED_LIBS:BOOL=true ..
+#   cmake -B build -D BUILD_SHARED_LIBS=true -D CMAKE_BUILD_TYPE=Release
 #
 # For a framework on OS X, use
 #
@@ -39,7 +43,8 @@
 #
 #   cmake -E chdir build cmake -G Xcode -D IOS_PLATFORM=SIMULATOR64 ..
 #
-# Finally, build the project with:
+#
+# Finally, build the project with
 #
 #   cmake --build build
 #
@@ -56,44 +61,68 @@
 #
 # Some notes.
 #
-# . `cmake' creates configuration files in
+# - Say `cmake -LAH` to see all configuration options.
+#
+# - `cmake' creates configuration files in
 #
 #     <build-directory>/include/freetype/config
 #
 #   which should be further modified if necessary.
 #
-# . You can use `cmake' directly on a freshly cloned FreeType git
+# - You can use `cmake' directly on a freshly cloned FreeType git
 #   repository.
 #
-# . `CMakeLists.txt' is provided as-is since it is normally not used by the
+# - `CMakeLists.txt' is provided as-is since it is normally not used by the
 #   developer team.
 #
-# . Set the `FT_WITH_ZLIB', `FT_WITH_BZIP2', `FT_WITH_PNG', and
-#   `FT_WITH_HARFBUZZ' CMake variables to `ON' to force using a dependency.
-#   Leave a variable undefined (which is the default) to use the dependency
-#   only if it is available.  Set `CMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE' to
-#   disable a dependency completely (CMake package name, so `BZip2' instead of
-#   `BZIP2'). Example:
+# - Set the `FT_REQUIRE_ZLIB', `FT_REQUIRE_BZIP2', `FT_REQUIRE_PNG',
+#   `FT_REQUIRE_HARFBUZZ', and `FT_REQUIRE_BROTLI' CMake variables to `ON'
+#   or `TRUE' to force using a dependency.  Leave a variable undefined
+#   (which is the default) to use the dependency only if it is available.
+#   Example:
 #
-#     cmake -DFT_WITH_ZLIB=ON -DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE [...]
+#     cmake -B build -D FT_REQUIRE_ZLIB=TRUE \
+#                    -D FT_REQUIRE_BZIP2=TRUE \
+#                    -D FT_REQUIRE_PNG=TRUE \
+#                    -D FT_REQUIRE_HARFBUZZ=TRUE \
+#                    -D FT_REQUIRE_BROTLI=TRUE [...]
 #
-# . Installation of FreeType can be controlled with the CMake variables
+# - Set `FT_DISABLE_XXX=TRUE' to disable a dependency completely (where
+#   `XXX' is a CMake package name like `BZip2').  Example for disabling all
+#   dependencies:
+#
+#     cmake -B build -D FT_DISABLE_ZLIB=TRUE \
+#                    -D FT_DISABLE_BZIP2=TRUE \
+#                    -D FT_DISABLE_PNG=TRUE \
+#                    -D FT_DISABLE_HARFBUZZ=TRUE \
+#                    -D FT_DISABLE_BROTLI=TRUE [...]
+#
+# - NOTE: If a package is set as DISABLED, it cannot be set as REQUIRED
+#   without unsetting the DISABLED value first.  For example, if
+#   `FT_DISABLE_HARFBUZZ=TRUE' has been set (Cache is present), you need to
+#   call `FT_DISABLE_HARFBUZZ=FALSE' before calling
+#   `FT_REQUIRE_HARFBUZZ=TRUE'.
+#
+# - Installation of FreeType can be controlled with the CMake variables
 #   `SKIP_INSTALL_HEADERS', `SKIP_INSTALL_LIBRARIES', and `SKIP_INSTALL_ALL'
 #   (this is compatible with the same CMake variables in zlib's CMake
 #   support).
 
-# FreeType explicitly marks the API to be exported and relies on the compiler
-# to hide all other symbols. CMake supports a C_VISBILITY_PRESET property
-# starting with 2.8.12.
-cmake_minimum_required(VERSION 2.8.12)
+# To minimize the number of cmake_policy() workarounds,
+# CMake >= 3 is requested.
+cmake_minimum_required(VERSION 3.0)
 
 if (NOT CMAKE_VERSION VERSION_LESS 3.3)
   # Allow symbol visibility settings also on static libraries. CMake < 3.3
-  # only sets the propery on a shared library build.
+  # only sets the property on a shared library build.
   cmake_policy(SET CMP0063 NEW)
+
+  # Support new IN_LIST if() operator.
+  cmake_policy(SET CMP0057 NEW)
 endif ()
 
 include(CheckIncludeFile)
+include(CMakeDependentOption)
 
 # CMAKE_TOOLCHAIN_FILE must be set before `project' is called, which
 # configures the base build environment and references the toolchain file
@@ -134,28 +163,62 @@
 project(freetype C)
 
 set(VERSION_MAJOR "2")
-set(VERSION_MINOR "9")
-set(VERSION_PATCH "1")
+set(VERSION_MINOR "13")
+set(VERSION_PATCH "0")
 
-# SOVERSION scheme: CURRENT.AGE.REVISION
-#   If there was an incompatible interface change:
-#     Increment CURRENT. Set AGE and REVISION to 0
-#   If there was a compatible interface change:
-#     Increment AGE. Set REVISION to 0
-#   If the source code was changed, but there were no interface changes:
-#     Increment REVISION.
-set(LIBRARY_VERSION "6.16.0")
-set(LIBRARY_SOVERSION "6")
+# Generate LIBRARY_VERSION and LIBRARY_SOVERSION.
+set(LIBTOOL_REGEX "version_info='([0-9]+):([0-9]+):([0-9]+)'")
+file(STRINGS "${PROJECT_SOURCE_DIR}/builds/unix/configure.raw"
+  VERSION_INFO
+  REGEX ${LIBTOOL_REGEX})
+string(REGEX REPLACE
+  ${LIBTOOL_REGEX} "\\1"
+  LIBTOOL_CURRENT "${VERSION_INFO}")
+string(REGEX REPLACE
+  ${LIBTOOL_REGEX} "\\2"
+  LIBTOOL_REVISION "${VERSION_INFO}")
+string(REGEX REPLACE
+  ${LIBTOOL_REGEX} "\\3"
+  LIBTOOL_AGE "${VERSION_INFO}")
 
-# These options mean "require x and complain if not found". They'll get
-# optionally found anyway. Use `-DCMAKE_DISABLE_FIND_PACKAGE_x=TRUE` to disable
-# searching for a packge entirely (x is the CMake package name, so "BZip2"
-# instead of "BZIP2").
-option(FT_WITH_ZLIB "Use system zlib instead of internal library." OFF)
-option(FT_WITH_BZIP2 "Support bzip2 compressed fonts." OFF)
-option(FT_WITH_PNG "Support PNG compressed OpenType embedded bitmaps." OFF)
-option(FT_WITH_HARFBUZZ "Improve auto-hinting of OpenType fonts." OFF)
+# This is what libtool does internally on Unix platforms.
+math(EXPR LIBRARY_SOVERSION "${LIBTOOL_CURRENT} - ${LIBTOOL_AGE}")
+set(LIBRARY_VERSION "${LIBRARY_SOVERSION}.${LIBTOOL_AGE}.${LIBTOOL_REVISION}")
 
+# External dependency library detection is automatic.  See the notes at the
+# top of this file, for how to force or disable dependencies completely.
+option(FT_DISABLE_ZLIB
+  "Disable use of system zlib and use internal zlib library instead." OFF)
+cmake_dependent_option(FT_REQUIRE_ZLIB
+  "Require system zlib instead of internal zlib library." OFF
+  "NOT FT_DISABLE_ZLIB" OFF)
+
+option(FT_DISABLE_BZIP2
+  "Disable support of bzip2 compressed fonts." OFF)
+cmake_dependent_option(FT_REQUIRE_BZIP2
+  "Require support of bzip2 compressed fonts." OFF
+  "NOT FT_DISABLE_BZIP2" OFF)
+
+option(FT_DISABLE_PNG
+  "Disable support of PNG compressed OpenType embedded bitmaps." OFF)
+cmake_dependent_option(FT_REQUIRE_PNG
+  "Require support of PNG compressed OpenType embedded bitmaps." OFF
+  "NOT FT_DISABLE_PNG" OFF)
+
+option(FT_DISABLE_HARFBUZZ
+  "Disable HarfBuzz (used for improving auto-hinting of OpenType fonts)." OFF)
+cmake_dependent_option(FT_REQUIRE_HARFBUZZ
+  "Require HarfBuzz for improving auto-hinting of OpenType fonts." OFF
+  "NOT FT_DISABLE_HARFBUZZ" OFF)
+
+option(FT_DISABLE_BROTLI
+  "Disable support of compressed WOFF2 fonts." OFF)
+cmake_dependent_option(FT_REQUIRE_BROTLI
+  "Require support of compressed WOFF2 fonts." OFF
+  "NOT FT_DISABLE_BROTLI" OFF)
+
+option(FT_ENABLE_ERROR_STRINGS
+  "Enable support for meaningful error descriptions." OFF)
 
 # Disallow in-source builds
 if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
@@ -179,43 +242,66 @@
     message(FATAL_ERROR
       "You should use Xcode generator with BUILD_FRAMEWORK enabled")
   endif ()
-  set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
+  set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)")
   set(BUILD_SHARED_LIBS ON)
 endif ()
 
 
 # Find dependencies
-if (FT_WITH_HARFBUZZ)
-  find_package(HarfBuzz 1.3.0 REQUIRED)
-else ()
-  find_package(HarfBuzz 1.3.0)
+include(FindPkgConfig)
+
+if (NOT FT_DISABLE_HARFBUZZ)
+  set(HARFBUZZ_MIN_VERSION "2.0.0")
+  if (FT_REQUIRE_HARFBUZZ)
+    find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION} REQUIRED)
+  else ()
+    find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION})
+  endif ()
 endif ()
 
-if (FT_WITH_PNG)
-  find_package(PNG REQUIRED)
-else ()
-  find_package(PNG)
+if (NOT FT_DISABLE_PNG)
+  if (FT_REQUIRE_PNG)
+    find_package(PNG REQUIRED)
+  else ()
+    find_package(PNG)
+  endif ()
 endif ()
 
-if (FT_WITH_ZLIB)
-  find_package(ZLIB REQUIRED)
-else ()
-  find_package(ZLIB)
+if (NOT FT_DISABLE_ZLIB)
+  if (FT_REQUIRE_ZLIB)
+    find_package(ZLIB REQUIRED)
+  else ()
+    find_package(ZLIB)
+  endif ()
 endif ()
 
-if (FT_WITH_BZIP2)
-  find_package(BZip2 REQUIRED)
-else ()
-  find_package(BZip2)
+if (NOT FT_DISABLE_BZIP2)
+  # Genuine BZip2 does not provide bzip2.pc, but some platforms have it.
+  # For better dependency in freetype2.pc, bzip2.pc is searched
+  # regardless of the availability of libbz2. If bzip2.pc is found,
+  # Requires.private is used instead of Libs.private.
+  if (FT_REQUIRE_BZIP2)
+    find_package(BZip2 REQUIRED)
+  else ()
+    find_package(BZip2)
+  endif ()
+  pkg_check_modules(PC_BZIP2 bzip2)
+endif ()
+
+if (NOT FT_DISABLE_BROTLI)
+  if (FT_REQUIRE_BROTLI)
+    find_package(BrotliDec REQUIRED)
+  else ()
+    find_package(BrotliDec)
+  endif ()
 endif ()
 
 # Create the configuration file
 if (UNIX)
   check_include_file("unistd.h" HAVE_UNISTD_H)
   check_include_file("fcntl.h" HAVE_FCNTL_H)
-  check_include_file("stdint.h" HAVE_STDINT_H)
 
-  file(READ "${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.in"
+  file(READ "${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.h.in"
     FTCONFIG_H)
   if (HAVE_UNISTD_H)
     string(REGEX REPLACE
@@ -227,19 +313,20 @@
       "#undef +(HAVE_FCNTL_H)" "#define \\1 1"
       FTCONFIG_H "${FTCONFIG_H}")
   endif ()
-  if (HAVE_STDINT_H)
-    string(REGEX REPLACE
-      "#undef +(HAVE_STDINT_H)" "#define \\1 1"
-      FTCONFIG_H "${FTCONFIG_H}")
-  endif ()
-  string(REPLACE "/undef " "#undef "
-    FTCONFIG_H "${FTCONFIG_H}")
-else()
+else ()
   file(READ "${PROJECT_SOURCE_DIR}/include/freetype/config/ftconfig.h"
     FTCONFIG_H)
 endif ()
-file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h"
-  "${FTCONFIG_H}")
+
+set(FTCONFIG_H_NAME "${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h")
+if (EXISTS "${FTCONFIG_H_NAME}")
+  file(READ "${FTCONFIG_H_NAME}" ORIGINAL_FTCONFIG_H)
+else ()
+  set(ORIGINAL_FTCONFIG_H "")
+endif ()
+if (NOT (ORIGINAL_FTCONFIG_H STREQUAL FTCONFIG_H))
+  file(WRITE "${FTCONFIG_H_NAME}" "${FTCONFIG_H}")
+endif ()
 
 
 # Create the options file
@@ -265,8 +352,27 @@
     "/\\* +(#define +FT_CONFIG_OPTION_USE_HARFBUZZ) +\\*/" "\\1"
     FTOPTION_H "${FTOPTION_H}")
 endif ()
-file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h"
-  "${FTOPTION_H}")
+if (BROTLIDEC_FOUND)
+  string(REGEX REPLACE
+    "/\\* +(#define +FT_CONFIG_OPTION_USE_BROTLI) +\\*/" "\\1"
+    FTOPTION_H "${FTOPTION_H}")
+endif ()
+
+if (FT_ENABLE_ERROR_STRINGS)
+  string(REGEX REPLACE
+    "/\\* +(#define +FT_CONFIG_OPTION_ERROR_STRINGS) +\\*/" "\\1"
+    FTOPTION_H "${FTOPTION_H}")
+endif ()
+
+set(FTOPTION_H_NAME "${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h")
+if (EXISTS "${FTOPTION_H_NAME}")
+  file(READ "${FTOPTION_H_NAME}" ORIGINAL_FTOPTION_H)
+else ()
+  set(ORIGINAL_FTOPTION_H "")
+endif ()
+if (NOT (ORIGINAL_FTOPTION_H STREQUAL FTOPTION_H))
+  file(WRITE "${FTOPTION_H_NAME}" "${FTOPTION_H}")
+endif ()
 
 
 file(GLOB PUBLIC_HEADERS "include/ft2build.h" "include/freetype/*.h")
@@ -292,7 +398,6 @@
   src/base/ftpfr.c
   src/base/ftstroke.c
   src/base/ftsynth.c
-  src/base/ftsystem.c
   src/base/fttype1.c
   src/base/ftwinfnt.c
   src/bdf/bdf.c
@@ -308,14 +413,24 @@
   src/pshinter/pshinter.c
   src/psnames/psnames.c
   src/raster/raster.c
+  src/sdf/sdf.c
   src/sfnt/sfnt.c
   src/smooth/smooth.c
+  src/svg/svg.c
   src/truetype/truetype.c
   src/type1/type1.c
   src/type42/type42.c
   src/winfonts/winfnt.c
 )
 
+if (UNIX)
+  list(APPEND BASE_SRCS "builds/unix/ftsystem.c")
+elseif (WIN32)
+  list(APPEND BASE_SRCS "builds/windows/ftsystem.c")
+else ()
+  list(APPEND BASE_SRCS "src/base/ftsystem.c")
+endif ()
+
 if (WIN32)
   enable_language(RC)
   list(APPEND BASE_SRCS builds/windows/ftdebug.c
@@ -333,7 +448,7 @@
 
 if (NOT DISABLE_FORCE_DEBUG_POSTFIX)
   set(CMAKE_DEBUG_POSTFIX d)
-endif()
+endif ()
 
 
 add_library(freetype
@@ -372,9 +487,13 @@
       $<INSTALL_INTERFACE:include/freetype2>
       $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
       $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
-    PRIVATE 
+    PRIVATE
       ${CMAKE_CURRENT_BINARY_DIR}/include
-      ${CMAKE_CURRENT_SOURCE_DIR}/include)
+      ${CMAKE_CURRENT_SOURCE_DIR}/include
+
+      # Make <ftconfig.h> available for builds/unix/ftsystem.c.
+      ${CMAKE_CURRENT_BINARY_DIR}/include/freetype/config
+)
 
 
 if (BUILD_FRAMEWORK)
@@ -383,35 +502,55 @@
   )
   set_target_properties(freetype PROPERTIES
     FRAMEWORK TRUE
-    MACOSX_FRAMEWORK_INFO_PLIST builds/mac/freetype-Info.plist
+    MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/builds/mac/freetype-Info.plist
     PUBLIC_HEADER "${PUBLIC_HEADERS}"
     XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
   )
 endif ()
 
+# 'freetype-interface' is an interface library, to be accessed with
+# `EXPORT_NAME Freetype::Freetype`.  This is the target name provided by
+# CMake's `FindFreetype.cmake`, so we provide it for compatibility.
+add_library(freetype-interface INTERFACE)
+set_target_properties(freetype-interface PROPERTIES
+  EXPORT_NAME Freetype::Freetype
+  INTERFACE_LINK_LIBRARIES freetype)
 
-set(PKG_CONFIG_REQUIRED_PRIVATE "")
+set(PKGCONFIG_REQUIRES "")
+set(PKGCONFIG_REQUIRES_PRIVATE "")
+set(PKGCONFIG_LIBS "-L\${libdir} -lfreetype")
+set(PKGCONFIG_LIBS_PRIVATE "")
 
 if (ZLIB_FOUND)
   target_link_libraries(freetype PRIVATE ${ZLIB_LIBRARIES})
   target_include_directories(freetype PRIVATE ${ZLIB_INCLUDE_DIRS})
-  list(APPEND PKG_CONFIG_REQUIRED_PRIVATE zlib)
+  list(APPEND PKGCONFIG_REQUIRES_PRIVATE "zlib")
 endif ()
 if (BZIP2_FOUND)
   target_link_libraries(freetype PRIVATE ${BZIP2_LIBRARIES})
   target_include_directories(freetype PRIVATE ${BZIP2_INCLUDE_DIR}) # not BZIP2_INCLUDE_DIRS
-  list(APPEND PKG_CONFIG_REQUIRED_PRIVATE bzip2)
+  if (PC_BZIP2_FOUND)
+    list(APPEND PKGCONFIG_REQUIRES_PRIVATE "bzip2")
+  else ()
+    list(APPEND PKGCONFIG_LIBS_PRIVATE "-lbz2")
+  endif ()
 endif ()
 if (PNG_FOUND)
   target_link_libraries(freetype PRIVATE ${PNG_LIBRARIES})
   target_compile_definitions(freetype PRIVATE ${PNG_DEFINITIONS})
   target_include_directories(freetype PRIVATE ${PNG_INCLUDE_DIRS})
-  list(APPEND PKG_CONFIG_REQUIRED_PRIVATE libpng)
+  list(APPEND PKGCONFIG_REQUIRES_PRIVATE "libpng")
 endif ()
-if (HARFBUZZ_FOUND)
-  target_link_libraries(freetype PRIVATE ${HARFBUZZ_LIBRARIES})
-  target_include_directories(freetype PRIVATE ${HARFBUZZ_INCLUDE_DIRS})
-  list(APPEND PKG_CONFIG_REQUIRED_PRIVATE harfbuzz)
+if (HarfBuzz_FOUND)
+  target_link_libraries(freetype PRIVATE ${HarfBuzz_LIBRARY})
+  target_include_directories(freetype PRIVATE ${HarfBuzz_INCLUDE_DIRS})
+  list(APPEND PKGCONFIG_REQUIRES_PRIVATE "harfbuzz >= ${HARFBUZZ_MIN_VERSION}")
+endif ()
+if (BROTLIDEC_FOUND)
+  target_link_libraries(freetype PRIVATE ${BROTLIDEC_LIBRARIES})
+  target_compile_definitions(freetype PRIVATE ${BROTLIDEC_DEFINITIONS})
+  target_include_directories(freetype PRIVATE ${BROTLIDEC_INCLUDE_DIRS})
+  list(APPEND PKGCONFIG_REQUIRES_PRIVATE "libbrotlidec")
 endif ()
 
 
@@ -436,39 +575,68 @@
 
 if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
   # Generate the pkg-config file
-  if (UNIX)
-    file(READ ${PROJECT_SOURCE_DIR}/builds/unix/freetype2.in FREETYPE2_PC_IN)
+  file(READ "${PROJECT_SOURCE_DIR}/builds/unix/freetype2.in" FREETYPE2_PC_IN)
 
-    string(REPLACE ";" ", " PKG_CONFIG_REQUIRED_PRIVATE "${PKG_CONFIG_REQUIRED_PRIVATE}")
+  string(REPLACE ";" ", " PKGCONFIG_REQUIRES_PRIVATE "${PKGCONFIG_REQUIRES_PRIVATE}")
 
-    string(REPLACE "%prefix%" ${CMAKE_INSTALL_PREFIX}
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
-    string(REPLACE "%exec_prefix%" "\${prefix}"
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
-    string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}"
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
-    string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}"
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
-    string(REPLACE "%ft_version%" "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
-    string(REPLACE "%REQUIRES_PRIVATE%" "${PKG_CONFIG_REQUIRED_PRIVATE}"
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
-    string(REPLACE "%LIBS_PRIVATE%" ""  # All libs support pkg-config
-           FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  string(REPLACE "%prefix%" ${CMAKE_INSTALL_PREFIX}
+          FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  string(REPLACE "%exec_prefix%" "\${prefix}"
+          FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}"
+          FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}"
+          FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  string(REPLACE "%ft_version%" "${LIBTOOL_CURRENT}.${LIBTOOL_REVISION}.${LIBTOOL_AGE}"
+          FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
 
-    file(WRITE ${PROJECT_BINARY_DIR}/freetype2.pc ${FREETYPE2_PC_IN})
+  if (BUILD_SHARED_LIBS)
+    string(REPLACE "%PKGCONFIG_REQUIRES%" "${PKGCONFIG_REQUIRES}"
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+    string(REPLACE "%PKGCONFIG_REQUIRES_PRIVATE%" "${PKGCONFIG_REQUIRES_PRIVATE}"
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+    string(REPLACE "%PKGCONFIG_LIBS%" "${PKGCONFIG_LIBS}"
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+    string(REPLACE "%PKGCONFIG_LIBS_PRIVATE%" "${PKGCONFIG_LIBS_PRIVATE}"
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  else ()
+    string(REPLACE "%PKGCONFIG_REQUIRES%" "${PKGCONFIG_REQUIRES} ${PKGCONFIG_REQUIRES_PRIVATE}"
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+    string(REPLACE "%PKGCONFIG_REQUIRES_PRIVATE%" ""
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+    string(REPLACE "%PKGCONFIG_LIBS%" "${PKGCONFIG_LIBS} ${PKGCONFIG_LIBS_PRIVATE}"
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+    string(REPLACE "%PKGCONFIG_LIBS_PRIVATE%" ""
+            FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
+  endif ()
 
-    install(
-      FILES ${PROJECT_BINARY_DIR}/freetype2.pc
-      DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
-      COMPONENT pkgconfig)
+  set(FREETYPE2_PC_IN_NAME "${PROJECT_BINARY_DIR}/freetype2.pc")
+  if (EXISTS "${FREETYPE2_PC_IN_NAME}")
+    file(READ "${FREETYPE2_PC_IN_NAME}" ORIGINAL_FREETYPE2_PC_IN)
+  else ()
+    set(ORIGINAL_FREETYPE2_PC_IN "")
+  endif ()
+  if (NOT (ORIGINAL_FREETYPE2_PC_IN STREQUAL FREETYPE2_PC_IN))
+    file(WRITE "${FREETYPE2_PC_IN_NAME}" ${FREETYPE2_PC_IN})
   endif ()
 
   install(
-    TARGETS freetype
+    FILES ${PROJECT_BINARY_DIR}/freetype2.pc
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
+    COMPONENT pkgconfig)
+
+  include(CMakePackageConfigHelpers)
+  write_basic_package_version_file(
+    ${PROJECT_BINARY_DIR}/freetype-config-version.cmake
+    VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+    COMPATIBILITY SameMajorVersion)
+
+  install(
+    TARGETS freetype freetype-interface
       EXPORT freetype-targets
       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
       ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
       FRAMEWORK DESTINATION Library/Frameworks
       COMPONENT libraries)
   install(
@@ -476,6 +644,10 @@
       DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype
       FILE freetype-config.cmake
       COMPONENT headers)
+  install(
+    FILES ${PROJECT_BINARY_DIR}/freetype-config-version.cmake
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype
+    COMPONENT headers)
 endif ()
 
 
@@ -483,7 +655,7 @@
 set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The FreeType font rendering library.")
 set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/docs/LICENSE.TXT")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT")
 
 set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
 set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
@@ -492,9 +664,9 @@
 
 if (WIN32)
   set(CPACK_GENERATOR ZIP)
-else()
+else ()
   set(CPACK_GENERATOR TGZ)
-endif()
+endif ()
 
 set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
 set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers")
diff --git a/Jamfile b/Jamfile
deleted file mode 100644
index 9078a5f..0000000
--- a/Jamfile
+++ /dev/null
@@ -1,222 +0,0 @@
-# FreeType 2 top Jamfile.
-#
-# Copyright 2001-2018 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.
-
-
-# The HDRMACRO is already defined in FTJam and is used to add
-# the content of certain macros to the list of included header
-# files.
-#
-# We can compile FreeType 2 with classic Jam however thanks to
-# the following code
-#
-if ! $(JAM_TOOLSET)
-{
-  rule HDRMACRO
-  {
-    # nothing
-  }
-}
-
-
-# We need to invoke a SubDir rule if the FT2 source directory top is not the
-# current directory.  This allows us to build FreeType 2 as part of a larger
-# project easily.
-#
-if $(FT2_TOP) != $(DOT)
-{
-  SubDir  FT2_TOP ;
-}
-
-
-# The following macros define the include directory, the source directory,
-# and the final library name (without library extensions).  They can be
-# replaced by other definitions when the library is compiled as part of
-# a larger project.
-#
-
-# Name of FreeType include directory during compilation.
-# This is relative to FT2_TOP.
-#
-FT2_INCLUDE_DIR ?= include ;
-
-# Name of FreeType source directory during compilation.
-# This is relative to FT2_TOP.
-#
-FT2_SRC_DIR ?= src ;
-
-# Name of final library, without extension.
-#
-FT2_LIB ?= $(LIBPREFIX)freetype ;
-
-
-# Define FT2_BUILD_INCLUDE to point to your build-specific directory.
-# This is prepended to FT2_INCLUDE_DIR.  It can be used to specify
-# the location of a custom <ft2build.h> which will point to custom
-# versions of `ftmodule.h' and `ftoption.h', for example.
-#
-FT2_BUILD_INCLUDE ?= ;
-
-# The list of modules to compile on any given build of the library.
-# By default, this will contain _all_ modules defined in FT2_SRC_DIR.
-#
-# IMPORTANT: You'll need to change the content of `ftmodule.h' as well
-#            if you modify this list or provide your own.
-#
-FT2_COMPONENTS ?= autofit    # auto-fitter
-                  base       # base component (public APIs)
-                  bdf        # BDF font driver
-                  bzip2      # support for bzip2-compressed PCF font
-                  cache      # cache sub-system
-                  cff        # CFF/CEF font driver
-                  cid        # PostScript CID-keyed font driver
-                  gzip       # support for gzip-compressed PCF font
-                  lzw        # support for LZW-compressed PCF font
-                  pcf        # PCF font driver
-                  pfr        # PFR/TrueDoc font driver
-                  psaux      # common PostScript routines module
-                  pshinter   # PostScript hinter module
-                  psnames    # PostScript names handling
-                  raster     # monochrome rasterizer
-                  sfnt       # SFNT-based format support routines
-                  smooth     # anti-aliased rasterizer
-                  truetype   # TrueType font driver
-                  type1      # PostScript Type 1 font driver
-                  type42     # PostScript Type 42 (embedded TrueType) driver
-                  winfonts   # Windows FON/FNT font driver
-                  ;
-
-
-# Don't touch.
-#
-FT2_INCLUDE  = $(FT2_BUILD_INCLUDE)
-               [ FT2_SubDir $(FT2_INCLUDE_DIR) ] ;
-
-FT2_SRC      = [ FT2_SubDir $(FT2_SRC_DIR) ] ;
-
-# Location of API Reference Documentation
-#
-if $(DOC_DIR)
-{
-  DOC_DIR = $(DOCDIR:T) ;
-}
-else
-{
-  DOC_DIR = docs/reference ;
-}
-
-
-# Only used by FreeType developers.
-#
-if $(DEBUG_HINTER)
-{
-  CCFLAGS += -DDEBUG_HINTER ;
-}
-
-
-# We need `include' in the current include path in order to
-# compile any part of FreeType 2.
-#
-HDRS += $(FT2_INCLUDE) ;
-
-
-# We need to #define FT2_BUILD_LIBRARY so that our sources find the
-# internal headers
-#
-CCFLAGS += -DFT2_BUILD_LIBRARY ;
-
-# Uncomment the following line if you want to build individual source files
-# for each FreeType 2 module.  This is only useful during development, and
-# is better defined as an environment variable anyway!
-#
-# FT2_MULTI = true ;
-
-
-# The files `ftheader.h', `internal.h', and `ftserv.h' are used to define
-# macros that are later used in #include statements.  They need to be parsed
-# in order to record these definitions.
-#
-HDRMACRO  [ FT2_SubDir  $(FT2_INCLUDE_DIR) freetype config ftheader.h ] ;
-HDRMACRO  [ FT2_SubDir  $(FT2_INCLUDE_DIR) freetype internal internal.h ] ;
-HDRMACRO  [ FT2_SubDir  $(FT2_INCLUDE_DIR) freetype internal ftserv.h ] ;
-
-
-# Now include the Jamfile in `freetype2/src', used to drive the compilation
-# of each FreeType 2 component and/or module.
-#
-SubInclude  FT2_TOP $(FT2_SRC_DIR) ;
-
-# Handle the generation of the `ftexport.sym' file, which contains the list
-# of exported symbols.  This can be used on Unix by libtool.
-#
-SubInclude FT2_TOP $(FT2_SRC_DIR) tools ;
-
-rule GenExportSymbols
-{
-  local  apinames = apinames$(SUFEXE) ;
-  local  aheader ;
-  local  headers ;
-
-  for aheader in [ Glob $(2) : *.h ]
-  {
-    switch $(aheader)
-    {
-      case */ftmac.h :
-        if ( $(MAC) || $(OS) = MACOSX ) {
-          headers += $(aheader) ;
-        }
-      case *.h : headers += $(aheader) ;
-    }
-  }
-
-  LOCATE on $(1) = $(ALL_LOCATE_TARGET) ;
-
-  APINAMES on $(1) = apinames$(SUFEXE) ;
-
-  Depends            $(1) : $(apinames) $(headers) ;
-  GenExportSymbols1  $(1) : $(headers) ;
-  Clean              clean : $(1) ;
-}
-
-actions GenExportSymbols1 bind APINAMES
-{
-  $(APINAMES) $(2) > $(1)
-}
-
-GenExportSymbols  ftexport.sym : include/freetype ;
-
-# Test files (hinter debugging).  Only used by FreeType developers.
-#
-if $(DEBUG_HINTER)
-{
-  SubInclude FT2_TOP tests ;
-}
-
-rule RefDoc
-{
-  Depends  $1 : all ;
-  NotFile  $1 ;
-  Always   $1 ;
-}
-
-actions RefDoc
-{
-  python $(FT2_SRC)/tools/docmaker/docmaker.py
-         --prefix=ft2
-         --title=FreeType-2.9.1
-         --output=$(DOC_DIR)
-         $(FT2_INCLUDE)/freetype/*.h
-         $(FT2_INCLUDE)/freetype/config/*.h
-}
-
-RefDoc  refdoc ;
-
-
-# end of top Jamfile
diff --git a/Jamrules b/Jamrules
deleted file mode 100644
index bdd04bc..0000000
--- a/Jamrules
+++ /dev/null
@@ -1,71 +0,0 @@
-# FreeType 2 JamRules.
-#
-# Copyright 2001-2018 by
-# David Turner, Robert Wilhelm, and Werner Lemberg.
-#
-# This file is part of the FreeType project, and may only be used, modified,
-# and distributed under the terms of the FreeType project license,
-# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
-# indicate that you have read the license and understand and accept it
-# fully.
-
-
-# This file contains the Jam rules needed to build the FreeType 2 library.
-# It is shared by all Jamfiles and is included only once in the build
-# process.
-#
-
-
-# Call SubDirHdrs on a list of directories.
-#
-rule AddSubDirHdrs
-{
-  local x ;
-
-  for x in $(<)
-  {
-    SubDirHdrs $(x) ;
-  }
-}
-
-
-# Determine prefix of library file.  We must use "libxxxxx" on Unix systems,
-# while all other simply use the real name.
-#
-if $(UNIX)
-{
-  LIBPREFIX ?= lib ;
-}
-else
-{
-  LIBPREFIX ?= "" ;
-}
-
-# FT2_TOP contains the location of the FreeType source directory.  You can
-# set it to a specific value if you want to compile the library as part of a
-# larger project.
-#
-FT2_TOP ?= $(DOT) ;
-
-# Define a new rule used to declare a sub directory of the Nirvana source
-# tree.
-#
-rule FT2_SubDir
-{
-  if $(FT2_TOP) = $(DOT)
-  {
-    return [ FDirName  $(<) ] ;
-  }
-  else
-  {
-    return [ FDirName  $(FT2_TOP) $(<) ] ;
-  }
-}
-
-# We also set ALL_LOCATE_TARGET in order to place all object and library
-# files in "objs".
-#
-ALL_LOCATE_TARGET ?= [ FT2_SubDir  objs ] ;
-
-
-# end of Jamrules
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6089bcf
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,2246 @@
+    Copyright (C) 2000-2004, 2006-2011, 2013, 2014 by
+    Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 2001, 2002 by
+    Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 2001-2008, 2011, 2013, 2014 by
+    Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 2000, 2001, 2002, 2003, 2006, 2010 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 2001, 2002, 2003, 2004 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2000, 2001, 2004 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2000-2001, 2002 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2000-2001, 2003 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2000-2010, 2012-2014 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2003 by
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 1995-2003, 2010 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2005, 2010 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2011, 2016 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2017 Jean-loup Gailly
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2017 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2019 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly        Mark Adler
+jloup@gzip.org          madler@alumni.caltech.edu
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1995-2022 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 1996-2019 by
+David Turner, Robert Wilhelm, Werner Lemberg, and Google Inc.
+
+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) 1996-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner.
+
+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) 1996-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and Detlef Wuerkner.
+
+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) 1996-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
+
+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) 1996-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) 1996-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) 1996-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) 1996-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) 1996-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+Copyright 2003 Huw D M Davies for Codeweavers
+Copyright 2007 Dmitry Timoshkov for Codeweavers
+
+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) 1996-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+Copyright 2007 Dmitry Timoshkov for Codeweavers
+
+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) 1996-2023 by
+Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2000 by Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE 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) 2000, 2001, 2003, 2008 by
+Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 2000-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) 2000-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) 2000-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) 2000-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) 2001, 2002, 2003, 2008 by
+Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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) 2001-2002 by Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE 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.
+
+*** Portions of the driver (that is, bdflib.c and bdf.h):
+
+Copyright 2000 Computing Research Labs, New Mexico State University
+Copyright 2001-2002, 2011 Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2001-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) 2001-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) 2001-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) 2001-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) 2001-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.
+
+As a special exception to the FreeType project license, this file may be
+distributed as part of a program that contains a configuration script
+generated by Autoconf, under the same distribution terms as the rest of
+that program.
+
+serial 7
+
+-------------------------------------------------------------------
+
+Copyright (C) 2002-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) 2002-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) 2002-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) 2002-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) 2002-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) 2002-2023 by
+Roberto Alameda.
+
+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) 2003-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
+
+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) 2003-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) 2003-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) 2003-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) 2003-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) 2003-2023 by
+Masatake YAMATO, Redhat K.K.,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2004-2019 Mark Adler
+For conditions of distribution and use, see copyright notice in zlib.h
+
+-------------------------------------------------------------------
+
+Copyright (C) 2004-2023 by
+Albert Chin-A-Young.
+
+based on `src/lzw/rules.mk'
+
+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) 2004-2023 by
+Albert Chin-A-Young.
+
+based on code in `src/gzip/ftgzip.c'
+
+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) 2004-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg and George Williams.
+
+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) 2004-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.
+
+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) 2004-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) 2004-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) 2004-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) 2004-2023 by
+Masatake YAMATO and Redhat K.K.
+
+FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are
+derived from ftobjs.c.
+
+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) 2004-2023 by
+Masatake YAMATO and Redhat K.K.
+
+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) 2004-2023 by
+Masatake YAMATO and Redhat K.K.
+
+This file 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) 2004-2023 by
+Masatake YAMATO, Red Hat K.K.,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2004-2023 by
+Masatake YAMATO, Redhat K.K,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2004-2023 by
+suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2004-2023 by
+suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used, modified,
+and distributed under the terms of the FreeType project license,
+LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+indicate that you have read the license and understand and accept it
+fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2004-2023 by
+suzuki toshiya, Masatake YAMATO, Red hat K.K.,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This  file is  part  of the  FreeType  project, and  may  only be  used,
+modified,  and  distributed under  the  terms  of  the FreeType  project
+license, LICENSE.TXT.  By continuing  to use, modify, or distribute this
+file  you indicate that  you have  read the  license and  understand and
+accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2005, 2007, 2008, 2013 by George Williams
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2005-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Copyright 2013 by Google, Inc.
+Google Author(s): Behdad Esfahbod.
+
+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) 2005-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) 2005-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) 2005-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) 2005-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) 2005-2023 by
+David Turner.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+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) 2005-2023 by
+Werner Lemberg and Detlef Würkner.
+
+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) 2005-2023 by
+Werner Lemberg and Detlef Würkner.
+
+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) 2005-2023 by
+suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2006-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) 2006-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) 2006-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) 2006-2023 by
+suzuki toshiya, 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) 2007 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2007-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) 2007-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Written by George Williams.
+
+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) 2007-2023 by
+David Turner.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+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) 2007-2023 by
+Dereg Clegg and Michael Toftdal.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+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) 2007-2023 by
+Derek Clegg and Michael Toftdal.
+
+This file is part of the FreeType project, and may only be used,
+modified, and distributed under the terms of the FreeType project
+license, LICENSE.TXT.  By continuing to use, modify, or distribute
+this file you indicate that you have read the license and
+understand and accept it fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2007-2023 by
+Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.
+
+This file is part of the FreeType project, and may only be used,
+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) 2008-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.
+
+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) 2008-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) 2008-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) 2009-2023 by
+Oran Agra and Mickey Gabel.
+
+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 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
+indicate that you have read the license and understand and accept it
+fully.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2010-2023 by
+Joel Klinghed.
+
+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
+Joel Klinghed.
+
+based on `src/gzip/ftgzip.c'
+
+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
+Joel Klinghed.
+
+based on `src/lzw/rules.mk'
+
+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) 2012-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) 2013-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) 2013-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) 2013-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Written originally by John Cary <cary@txcorp.com>
+
+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) 2013-2023 by
+Google, Inc.
+Written by Stuart Gill and Behdad Esfahbod.
+
+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) 2014-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Written by David Wimsey <david@wimsey.us>
+
+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) 2015-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) 2015-2023 by
+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) 2016-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) 2016-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) 2017-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) 2017-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) 2018-2023 by
+Armin Hasitzka, 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) 2018-2023 by
+David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg.
+
+Originally written by Shao Yu Zhang <shaozhang@fb.com>.
+
+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) 2018-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Originally written by Shao Yu Zhang <shaozhang@fb.com>.
+
+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) 2018-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) 2018-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) 2018-2023 by
+Nikhil Ramakrishnan, 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) 2019-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Written by Werner Lemberg <wl@gnu.org>
+
+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) 2019-2023 by
+Nikhil Ramakrishnan, 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) 2020-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) 2020-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) 2020-2023 by
+David Turner, Robert Wilhelm, and Werner Lemberg.
+
+Written by Anuj Verma.
+
+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) 2021-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) 2022-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and
+Dominik Röttsches.
+
+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) 2022-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+
+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) 2022-2023 by
+David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+
+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) 2001 Alexander Peslyak and it is hereby released to the
+general public under the following terms:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted.
+
+There's ABSOLUTELY NO WARRANTY, express or implied.
+
+(This is a heavily cut-down "BSD license".)
+
+This differs from Colin Plumb's older public domain implementation in that
+no exactly 32-bit integer data type is required (any 32-bit or wider
+unsigned integer data type will do), there's no compile-time endianness
+configuration, and the function prototypes match OpenSSL's.  No code from
+Colin Plumb's implementation has been reused; this comment merely compares
+the properties of the two independent implementations.
+
+The primary goals of this implementation are portability and ease of use.
+It is meant to be fast, but not as fast as possible.  Some known
+optimizations are not included to reduce source code size and avoid
+compile-time configuration.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+general public under the following terms:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted.
+
+There's ABSOLUTELY NO WARRANTY, express or implied.
+
+See md5.c for more information.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <https://www.gnu.org/licenses/>.
+
+As a special exception, the respective Autoconf Macro's copyright owner
+gives unlimited permission to copy, distribute and modify the configure
+scripts that are the output of Autoconf when processing the Macro. You
+need not follow the terms of the GNU General Public License when using
+or distributing such scripts, even though portions of the text of the
+Macro appear in them. The GNU General Public License (GPL) does govern
+all other use of the material that constitutes the Autoconf Macro.
+
+This special exception to the GPL applies to versions of the Autoconf
+Macro released by the Autoconf Archive. When you make and distribute a
+modified version of the Autoconf Macro, you may extend this special
+exception to the GPL to apply to your modified version as well.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice
+and this notice are preserved. This file is offered as-is, without any
+warranty.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2009 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice
+and this notice are preserved. This file is offered as-is, without any
+warranty.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2012, Intel Corporation
+Copyright (c) 2019 Sony Interactive Entertainment Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+* Neither the name of Intel Corporation nor the names of its contributors may
+  be used to endorse or promote products derived from this software without
+  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Try to find Harfbuzz include and library directories.
+
+After successful discovery, this will set for inclusion where needed:
+HarfBuzz_INCLUDE_DIRS - containg the HarfBuzz headers
+HarfBuzz_LIBRARIES - containg the HarfBuzz library
+
+-------------------------------------------------------------------
+
+Copyright 1990, 1994, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+-------------------------------------------------------------------
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright 2000 Computing Research Labs, New Mexico State University
+Copyright 2001-2004, 2011 Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright 2000 Computing Research Labs, New Mexico State University
+Copyright 2001-2014
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright 2000 Computing Research Labs, New Mexico State University
+Copyright 2001-2015
+  Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright 2000, 2006 by
+Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2001, 2002, 2006 by
+Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+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 2001, 2002, 2012 Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright 2001, 2012 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 2003 by
+Masatake YAMATO and Redhat K.K.
+
+This file 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 2006-2013 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2007-2013 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2007-2014 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2009-2013 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2009-2014 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2011-2013 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2013 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright 2013-2014 Adobe Systems Incorporated.
+
+This software, and all works of authorship, whether in source or
+object code form as indicated by the copyright notice(s) included
+herein (collectively, the "Work") is made available, and may only be
+used, modified, and distributed under the FreeType Project License,
+LICENSE.TXT.  Additionally, subject to the terms and conditions of the
+FreeType Project License, each contributor to the Work hereby grants
+to any individual or legal entity exercising permissions granted by
+the FreeType Project License and this section (hereafter, "You" or
+"Your") a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and
+otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such contributor that are necessarily
+infringed by their contribution(s) alone or by combination of their
+contribution(s) with the Work to which such contribution(s) was
+submitted.  If You institute patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+the Work or a contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+By using, modifying, or distributing the Work you indicate that you
+have read and understood the terms and conditions of the
+FreeType Project License as well as those provided in this section,
+and you accept them fully.
+
+-------------------------------------------------------------------
+
+Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception to the GNU General Public License, if you
+distribute this file as part of a program that contains a
+configuration script generated by Autoconf, you may include it under
+the same distribution terms that you use for the rest of that program.
+
+-------------------------------------------------------------------
+
+Copyright © 2009, 2023  Red Hat, Inc.
+Copyright © 2015  Google, Inc.
+
+Permission is hereby granted, without written agreement and without
+license or royalty fees, to use, copy, modify, and distribute this
+software and its documentation for any purpose, provided that the
+above copyright notice and the following two paragraphs appear in
+all copies of this software.
+
+IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+Red Hat Author(s): Behdad Esfahbod, Matthias Clasen
+Google Author(s): Behdad Esfahbod
+
+-------------------------------------------------------------------
+
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..8b9ce9e
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,46 @@
+FREETYPE LICENSES
+-----------------
+
+The FreeType  2 font  engine is  copyrighted work  and cannot  be used
+legally without  a software  license.  In order  to make  this project
+usable to  a vast majority of  developers, we distribute it  under two
+mutually exclusive open-source licenses.
+
+This means that *you* must choose  *one* of the two licenses described
+below, then obey all its terms and conditions when using FreeType 2 in
+any of your projects or products.
+
+  - The FreeType License,  found in the file  `docs/FTL.TXT`, which is
+    similar to the  original BSD license *with*  an advertising clause
+    that forces  you to explicitly  cite the FreeType project  in your
+    product's  documentation.  All  details are  in the  license file.
+    This license is suited to products which don't use the GNU General
+    Public License.
+
+    Note that  this license  is compatible to  the GNU  General Public
+    License version 3, but not version 2.
+
+  - The   GNU   General   Public   License   version   2,   found   in
+    `docs/GPLv2.TXT`  (any  later  version  can  be  used  also),  for
+    programs  which  already  use  the  GPL.  Note  that  the  FTL  is
+    incompatible with GPLv2 due to its advertisement clause.
+
+The contributed  BDF and PCF  drivers come  with a license  similar to
+that  of the  X Window  System.   It is  compatible to  the above  two
+licenses (see files `src/bdf/README`  and `src/pcf/README`).  The same
+holds   for   the   source    code   files   `src/base/fthash.c`   and
+`include/freetype/internal/fthash.h`; they were part of the BDF driver
+in earlier FreeType versions.
+
+The gzip  module uses the  zlib license (see  `src/gzip/zlib.h`) which
+too is compatible to the above two licenses.
+
+The files `src/autofit/ft-hb.c` and `src/autofit/ft-hb.h` contain code
+taken almost  verbatim from the  HarfBuzz file `hb-ft.cc`,  which uses
+the 'Old MIT' license, compatible to the above two licenses.
+
+The  MD5 checksum  support  (only used  for  debugging in  development
+builds) is in the public domain.
+
+
+--- end of LICENSE.TXT ---
diff --git a/LICENSE_APACHE2.TXT b/LICENSE_APACHE2.TXT
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE_APACHE2.TXT
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/LICENSE_BSD_3_CLAUSE.TXT b/LICENSE_BSD_3_CLAUSE.TXT
new file mode 100644
index 0000000..7fc8815
--- /dev/null
+++ b/LICENSE_BSD_3_CLAUSE.TXT
@@ -0,0 +1,12 @@
+Redistribution and use in source and binary forms are permitted
+provided that the above copyright notice and this paragraph are
+duplicated in all such forms and that any documentation,
+advertising materials, and other materials related to such
+distribution and use acknowledge that the software was developed
+by Stanford University.  The name of the University may not be used
+to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/LICENSE_FSFAP.TXT b/LICENSE_FSFAP.TXT
new file mode 100644
index 0000000..662cfe1
--- /dev/null
+++ b/LICENSE_FSFAP.TXT
@@ -0,0 +1,4 @@
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without any warranty.
diff --git a/LICENSE_MIT.TXT b/LICENSE_MIT.TXT
new file mode 100644
index 0000000..e7aefb8
--- /dev/null
+++ b/LICENSE_MIT.TXT
@@ -0,0 +1,25 @@
+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.
+
+Except as contained in this notice, the name(s) of the above
+copyright holders shall not be used in advertising or otherwise
+to promote the sale, use or other dealings in this Software
+without prior written authorization.
+
+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.
diff --git a/LICENSE_MIT_MODERN_VARIANT.TXT b/LICENSE_MIT_MODERN_VARIANT.TXT
new file mode 100644
index 0000000..2922808
--- /dev/null
+++ b/LICENSE_MIT_MODERN_VARIANT.TXT
@@ -0,0 +1,17 @@
+Permission is hereby granted, without written agreement and without
+license or royalty fees, to use, copy, modify, and distribute this
+software and its documentation for any purpose, provided that the
+above copyright notice and the following two paragraphs appear in
+all copies of this software.
+
+IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/METADATA b/METADATA
index 6d97d66..1d9bbd4 100644
--- a/METADATA
+++ b/METADATA
@@ -9,10 +9,14 @@
     type: GIT
     value: "git://git.sv.nongnu.org/freetype/freetype2.git"
   }
-  version: "96b5e500909cfce39ff78feabefd8063a229b951"
+  version: "0b62c1e43dc4b0e3c50662aac757e4f7321e5466"
+  license_type: RESTRICTED
   last_upgrade_date {
-    year: 2018
-    month: 7
-    day: 27
+    year: 2022
+    month: 12
+    day: 14
+  }
+  security {
+      tag: "NVD-CPE2.3:cpe:/a:freetype:freetype:2.10.4"
   }
 }
diff --git a/Makefile b/Makefile
index 0c7ee0e..14fba30 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/README b/README
index c23b99e..327b94d 100644
--- a/README
+++ b/README
@@ -1,77 +1,100 @@
-  FreeType 2.9.1
-  ==============
+FreeType 2.13.0
+===============
 
-  Homepage: https://www.freetype.org
+Homepage: https://www.freetype.org
 
-  FreeType is a freely available software library to render fonts.
+FreeType is a freely available software library to render fonts.
 
-  It  is  written  in  C,  designed to  be  small,  efficient,  highly
-  customizable, and  portable while capable of  producing high-quality
-  output  (glyph  images) of  most  vector  and bitmap  font  formats.
+It  is  written  in  C,   designed  to  be  small,  efficient,  highly
+customizable,  and portable  while capable  of producing  high-quality
+output (glyph images) of most vector and bitmap font formats.
 
-  Please   read   the  docs/CHANGES   file,   it  contains   IMPORTANT
-  INFORMATION.
+Please   read  the   `docs/CHANGES`   file,   it  contains   IMPORTANT
+INFORMATION.
 
-  Read the  files `docs/INSTALL*'  for installation  instructions; see
-  the file `docs/LICENSE.TXT' for the available licenses.
+Read the files `docs/INSTALL*`  for installation instructions; see the
+file `docs/LICENSE.TXT` for the available licenses.
 
-  The FreeType 2 API reference is located in `docs/reference'; use the
-  file   `ft2-toc.html'   as   the   top  entry   point.    Additional
-  documentation is available as a separate package from our sites.  Go
-  to
+For using FreeType's git repository  instead of a distribution bundle,
+please read file  `README.git`.  Note that you have  to actually clone
+the repository; using a snapshot will  not work (in other words, don't
+use gitlab's 'Download' button).
 
-    https://download.savannah.gnu.org/releases/freetype/
+The FreeType 2 API reference is located in directory `docs/reference`;
+use the file  `index.html` as the top entry point.   [Please note that
+currently  the search  function  for  locally installed  documentation
+doesn't work due to cross-site scripting issues.]
 
-  and download one of the following files.
+Additional documentation is  available as a separate  package from our
+sites.  Go to
 
-    freetype-doc-2.9.1.tar.bz2
-    freetype-doc-2.9.1.tar.gz
-    ftdoc291.zip
+  https://download.savannah.gnu.org/releases/freetype/
 
-  To view the documentation online, go to
+and download one of the following files.
 
-    https://www.freetype.org/freetype2/documentation.html
+  freetype-doc-2.13.0.tar.xz
+  freetype-doc-2.13.0.tar.gz
+  ftdoc2130.zip
+
+To view the documentation online, go to
+
+  https://www.freetype.org/freetype2/docs/
 
 
-  Mailing Lists
-  =============
+Mailing Lists
+-------------
 
-  The preferred way  of communication with the FreeType  team is using
-  e-mail lists.
+The preferred  way of  communication with the  FreeType team  is using
+e-mail lists.
 
-    general use and discussion:      freetype@nongnu.org
-    engine internals, porting, etc.: freetype-devel@nongnu.org
-    announcements:                   freetype-announce@nongnu.org
-    git repository tracker:          freetype-commit@nongnu.org
+  general use and discussion:      freetype@nongnu.org
+  engine internals, porting, etc.: freetype-devel@nongnu.org
+  announcements:                   freetype-announce@nongnu.org
+  git repository tracker:          freetype-commit@nongnu.org
 
-  The lists are moderated; see
+The lists are moderated; see
 
-    https://www.freetype.org/contact.html
+  https://www.freetype.org/contact.html
 
-  how to subscribe.
+how to subscribe.
 
 
-  Bugs
-  ====
+Bugs
+----
 
-  Please submit bug reports at
+Please submit bug reports at
 
-    https://savannah.nongnu.org/bugs/?group=freetype
+  https://gitlab.freedesktop.org/freetype/freetype/-/issues
 
-  Alternatively,    you   might    report    bugs    by   e-mail    to
-  `freetype-devel@nongnu.org'.   Don't  forget   to  send  a  detailed
-  explanation of the problem --  there is nothing worse than receiving
-  a terse message that only says `it doesn't work'.
+Alternatively,    you    might    report    bugs    by    e-mail    to
+`freetype-devel@nongnu.org`.    Don't  forget   to  send   a  detailed
+explanation of the problem -- there  is nothing worse than receiving a
+terse message that only says 'it doesn't work'.
 
 
-  Enjoy!
+Patches
+-------
+
+For larger changes please provide merge requests at
+
+  https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests
+
+Alternatively, you can send patches to the `freetype-devel@nongnu.org`
+mailing list  -- and thank you  in advance for your  work on improving
+FreeType!
+
+Details on the process can be found here:
+
+  https://www.freetype.org/developer.html#patches
 
 
-    The FreeType Team
+Enjoy!
+
+  The FreeType Team
 
 ----------------------------------------------------------------------
 
-Copyright 2006-2018 by
+Copyright (C) 2006-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/README.android b/README.android
index a2f5020..adc7a2c 100644
--- a/README.android
+++ b/README.android
@@ -26,6 +26,7 @@
   ex: for 2.8.1: http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?h=VER-2-8-1&id=39ce3ac499d4cd7371031a062f410953c8ecce29
 * In <checkout_dir>, run git merge <commit_sha>
   i.e. git merge 39ce3ac499d4cd7371031a062f410953c8ecce29
+* Update version and last upgrade date in MEATADATA file.
 * Upload the changes.
   ex: git push origin HEAD:refs/for/master
 * Gerrit will run the text related tests.
diff --git a/README.git b/README.git
index a3d7fc0..117d74f 100644
--- a/README.git
+++ b/README.git
@@ -1,4 +1,36 @@
-The git  archive doesn't  contain pre-built configuration  scripts for
+README.git
+==========
+
+
+repository issues
+-----------------
+
+FreeType's official repository site is
+
+  https://gitlab.freedesktop.org/freetype  ,
+
+from  which the  'freetype.git' and  'freetype-demos.git' repositories
+can be cloned in the usual way.
+
+  git clone https://gitlab.freedesktop.org/freetype/freetype.git
+  git clone https://gitlab.freedesktop.org/freetype/freetype-demos.git
+
+If you  want to  use the  Savannah mirror  instead, you  have to  do a
+slightly different  incantation because  the repository  names contain
+digit '2' for historical reasons.
+
+  git clone \
+    https://git.savannah.nongnu.org/git/freetype/freetype2.git \
+    freetype
+  git clone \
+    https://git.savannah.nongnu.org/git/freetype/freetype2-demos.git \
+    freetype-demos
+
+
+standard builds with `configure`
+--------------------------------
+
+The git repository doesn't contain pre-built configuration scripts for
 UNIXish platforms.  To generate them say
 
   sh autogen.sh
@@ -10,34 +42,54 @@
   autoconf (2.62)
 
 The versions given  in parentheses are known to  work.  Newer versions
-should work too, of course.   Note that autogen.sh also sets up proper
-file permissions for the `configure' and auxiliary scripts.
+should  work too,  of course.   Note  that `autogen.sh`  also sets  up
+proper file permissions for the `configure` and auxiliary scripts.
 
-The autogen.sh script  now checks the version of  above three packages
-whether they match the numbers  above.  Otherwise it will complain and
-suggest either upgrading or using  an environment variable to point to
-a more recent version of the required tool(s).
+The `autogen.sh` script checks whether the versions of the above three
+tools match the numbers above.  Otherwise it will complain and suggest
+either  upgrading or  using  environment variables  to  point to  more
+recent versions of the required tools.
 
-Note that  `aclocal' is provided  by the `automake' package  on Linux,
-and that `libtoolize' is called `glibtoolize' on Darwin (OS X).
+Note that  `aclocal` is provided  by the 'automake' package  on Linux,
+and that `libtoolize` is called `glibtoolize` on Darwin (OS X).
 
 
-For static builds which  don't use platform specific optimizations, no
+alternative build methods
+-------------------------
+
+For static  builds that don't use  platform-specific optimizations, no
 configure script is necessary at all; saying
 
   make setup ansi
   make
 
-should work on all platforms which have GNU make (or makepp).
+should work on all platforms that have GNU `make` (or `makepp`).
+
+A build  with `cmake`  or `meson`  can be done  directly from  the git
+repository.  However, if you want  to use the `FT_DEBUG_LOGGING` macro
+(see file `docs/DEBUG` for more information) it is currently mandatory
+to execute `autogen.sh`  in advance; this script clones  the 'dlg' git
+submodule and copies some files into FreeType's source tree.
 
 
-Similarly, a  build with  `cmake' can  be done  directly from  the git
-repository.
+Code of Conduct
+---------------
 
+Please note that  this project is released with a  Contributor Code of
+Conduct (CoC).  By participating in this project you agree to abide by
+its terms, which you can find in the following link:
+
+  https://www.freedesktop.org/wiki/CodeOfConduct
+
+CoC issues may  be raised to the project maintainers  at the following
+address:
+
+  wl@gnu.org
+  apodtele@gmail.com
 
 ----------------------------------------------------------------------
 
-Copyright 2005-2018 by
+Copyright (C) 2005-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/README.version b/README.version
deleted file mode 100644
index f0f1f78..0000000
--- a/README.version
+++ /dev/null
@@ -1,3 +0,0 @@
-URL: http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=96b5e500909cfce39ff78feabefd8063a229b951
-Version: 2.9.1 ..96b5e500909cfce39ff78feabefd8063a229b951 
-BugComponent: 75970
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..279657d
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "minikin_tests"
+    }
+  ]
+}
diff --git a/autogen.sh b/autogen.sh
index ab90e64..ff5e46f 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright 2005-2018 by
+# Copyright (C) 2005-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -110,7 +110,10 @@
   fi
 }
 
-if test ! -f ./builds/unix/configure.raw; then
+# Solaris 10's shell doesn't like the `!` operator to negate the exit status.
+if test -f ./builds/unix/configure.raw; then
+  :
+else
   echo "You must be in the same directory as \`autogen.sh'."
   echo "Bootstrapping doesn't work if srcdir != builddir."
   exit 1
@@ -138,18 +141,25 @@
 check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4
 check_tool_version $AUTOCONF   autoconf   AUTOCONF   2.62
 
-# This sets freetype_major, freetype_minor, and freetype_patch.
-eval `sed -nf version.sed include/freetype/freetype.h`
+# This sets FREETYPE version.
+eval `sed -n \
+-e 's/^#define  *\(FREETYPE_MAJOR\)  *\([0-9][0-9]*\).*/\1=\2/p' \
+-e 's/^#define  *\(FREETYPE_MINOR\)  *\([0-9][0-9]*\).*/\1=\2/p' \
+-e 's/^#define  *\(FREETYPE_PATCH\)  *\([0-9][0-9]*\).*/\1=\2/p' \
+include/freetype/freetype.h`
 
-# We set freetype-patch to an empty value if it is zero.
-if test "$freetype_patch" = ".0"; then
-  freetype_patch=
+if test "$FREETYPE_PATCH" = "0"; then
+  FREETYPE=$FREETYPE_MAJOR.$FREETYPE_MINOR
+else
+  FREETYPE=$FREETYPE_MAJOR.$FREETYPE_MINOR.$FREETYPE_PATCH
 fi
 
+echo "FreeType $FREETYPE:"
+
 cd builds/unix
 
 echo "generating \`configure.ac'"
-sed -e "s;@VERSION@;$freetype_major$freetype_minor$freetype_patch;" \
+sed -e "s;@VERSION@;$FREETYPE;" \
   < configure.raw > configure.ac
 
 run aclocal -I . --force
@@ -162,4 +172,29 @@
 
 chmod +x ./configure
 
+# Copy all necessary 'dlg' files.
+copy_submodule_files ()
+{
+  echo "Copying files from \`subprojects/dlg' to \`src/dlg' and \`include/dlg'"
+  mkdir include/dlg 2> /dev/null
+  cp $DLG_INC_DIR/output.h include/dlg
+  cp $DLG_INC_DIR/dlg.h include/dlg
+  cp $DLG_SRC_DIR/* src/dlg
+}
+
+if test -e ".git"; then
+  DLG_INC_DIR=subprojects/dlg/include/dlg
+  DLG_SRC_DIR=subprojects/dlg/src/dlg
+
+  if test -d "$DLG_INC_DIR"; then
+    :
+  else
+    echo "Checking out submodule in \`subprojects/dlg':"
+    git submodule init
+    git submodule update
+  fi
+
+  copy_submodule_files
+fi
+
 # EOF
diff --git a/builds/amiga/README b/builds/amiga/README
index 29e97d6..5b2abef 100644
--- a/builds/amiga/README
+++ b/builds/amiga/README
@@ -1,7 +1,7 @@
 
 README for the builds/amiga subdirectory.
 
-Copyright 2005-2018 by
+Copyright (C) 2005-2023 by
 Werner Lemberg and Detlef Würkner.
 
 This file is part of the FreeType project, and may only be used, modified,
@@ -26,7 +26,7 @@
 http://ragriffi.home.sprynet.com).
 
 You will also need the latest include files and amiga.lib from the
-Amiga web site (http://www.amiga.com/3.9/download/NDK3.9.lha) for
+Amiga web site (https://os.amigaworld.de/download.php?id=3) for
 AmigaOS 3.9; the generated code should work under AmigaOS 2.04 and up.
 
 To use it, call "smake assign" and then "smake" from the builds/amiga
diff --git a/builds/amiga/include/config/ftconfig.h b/builds/amiga/include/config/ftconfig.h
index 0217e0e..de074bf 100644
--- a/builds/amiga/include/config/ftconfig.h
+++ b/builds/amiga/include/config/ftconfig.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Amiga-specific configuration file (specification only).              */
 /*                                                                         */
-/*  Copyright 2005-2018 by                                                 */
+/*  Copyright (C) 2005-2023 by                                             */
 /*  Werner Lemberg and Detlef Würkner.                                     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/builds/amiga/include/config/ftmodule.h b/builds/amiga/include/config/ftmodule.h
index f8baab5..bf33367 100644
--- a/builds/amiga/include/config/ftmodule.h
+++ b/builds/amiga/include/config/ftmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Amiga-specific FreeType module selection.                            */
 /*                                                                         */
-/*  Copyright 2005-2018 by                                                 */
+/*  Copyright (C) 2005-2023 by                                             */
 /*  Werner Lemberg and Detlef Würkner.                                     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -137,8 +137,6 @@
 
 #ifdef FT_USE_SMOOTH
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
 #endif
 
 #ifdef FT_USE_OTV
diff --git a/builds/amiga/makefile b/builds/amiga/makefile
index 6a7700a..4a33fdd 100644
--- a/builds/amiga/makefile
+++ b/builds/amiga/makefile
@@ -5,7 +5,7 @@
 #
 
 
-# Copyright 2005-2018 by
+# Copyright (C) 2005-2023 by
 # Werner Lemberg and Detlef Würkner.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/amiga/makefile.os4 b/builds/amiga/makefile.os4
index 0d340cf..dfc3e9f 100644
--- a/builds/amiga/makefile.os4
+++ b/builds/amiga/makefile.os4
@@ -4,7 +4,7 @@
 #
 
 
-# Copyright 2005-2018 by
+# Copyright (C) 2005-2023 by
 # Werner Lemberg and Detlef Würkner.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/amiga/smakefile b/builds/amiga/smakefile
index f5de308..ca3da66 100644
--- a/builds/amiga/smakefile
+++ b/builds/amiga/smakefile
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2005-2018 by
+# Copyright (C) 2005-2023 by
 # Werner Lemberg and Detlef Würkner.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/amiga/src/base/ftdebug.c b/builds/amiga/src/base/ftdebug.c
index f3ba48c..a209297 100644
--- a/builds/amiga/src/base/ftdebug.c
+++ b/builds/amiga/src/base/ftdebug.c
@@ -1,76 +1,78 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftdebug.c                                                              */
-/*                                                                         */
-/*    Debugging and logging component for amiga (body).                    */
-/*                                                                         */
-/*  Copyright 1996-2018 by                                                 */
-/*  David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner.       */
-/*                                                                         */
-/*  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.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * ftdebug.c
+ *
+ *   Debugging and logging component for amiga (body).
+ *
+ * Copyright (C) 1996-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Detlef Wuerkner.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* This component contains various macros and functions used to ease the */
-  /* debugging of the FreeType engine.  Its main purpose is in assertion   */
-  /* checking, tracing, and error detection.                               */
-  /*                                                                       */
-  /* There are now three debugging modes:                                  */
-  /*                                                                       */
-  /* - trace mode                                                          */
-  /*                                                                       */
-  /*   Error and trace messages are sent to the log file (which can be the */
-  /*   standard error output).                                             */
-  /*                                                                       */
-  /* - error mode                                                          */
-  /*                                                                       */
-  /*   Only error messages are generated.                                  */
-  /*                                                                       */
-  /* - release mode:                                                       */
-  /*                                                                       */
-  /*   No error message is sent or generated.  The code is free from any   */
-  /*   debugging parts.                                                    */
-  /*                                                                       */
-  /*************************************************************************/
+  /**************************************************************************
+   *
+   * This component contains various macros and functions used to ease the
+   * debugging of the FreeType engine.  Its main purpose is in assertion
+   * checking, tracing, and error detection.
+   *
+   * There are now three debugging modes:
+   *
+   * - trace mode
+   *
+   *   Error and trace messages are sent to the log file (which can be the
+   *   standard error output).
+   *
+   * - error mode
+   *
+   *   Only error messages are generated.
+   *
+   * - release mode:
+   *
+   *   No error message is sent or generated.  The code is free from any
+   *   debugging parts.
+   *
+   */
 
 
   /*
-   * Based on the default ftdebug.c,
-   * replaced vprintf() with KVPrintF(),
-   * commented out exit(),
-   * replaced getenv() with GetVar().
+   * Based on the default `ftdebug.c' file,
+   * replaced `vprintf' with `KVPrintF',
+   * commented out `exit',
+   * replaced `getenv' with `GetVar'.
    */
 
 #include <exec/types.h>
 #include <utility/tagitem.h>
 #include <dos/exall.h>
 #include <dos/var.h>
+
 #define __NOLIBBASE__
 #define __NOLOBALIFACE__
 #define __USE_INLINE__
+
 #include <proto/dos.h>
 #include <clib/debug_protos.h>
 
 #ifndef __amigaos4__
-  extern struct Library *DOSBase;
+  extern struct Library*  DOSBase;
 #else
-  extern struct DOSIFace *IDOS;
+  extern struct DOSIFace*  IDOS;
 #endif
 
 
 #include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
 
 
-#if defined( FT_DEBUG_LEVEL_ERROR )
+#ifdef FT_DEBUG_LEVEL_ERROR
 
   /* documentation is in ftdebug.h */
 
@@ -100,7 +102,7 @@
     KVPrintF( fmt, ap );
     va_end( ap );
 
-/*  exit( EXIT_FAILURE ); */
+    /* exit( EXIT_FAILURE ); */
   }
 
 
@@ -111,9 +113,19 @@
             int          line,
             const char*  file )
   {
+#if 0
+    /* activating the code in this block makes FreeType very chatty */
+    fprintf( stderr,
+             "%s:%d: error 0x%02x: %s\n",
+             file,
+             line,
+             error,
+             FT_Error_String( error ) );
+#else
     FT_UNUSED( error );
     FT_UNUSED( line );
     FT_UNUSED( file );
+#endif
 
     return 0;
   }
@@ -124,16 +136,23 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-  /* array of trace levels, initialized to 0 */
-  int  ft_trace_levels[trace_count];
+  /* array of trace levels, initialized to 0; */
+  /* this gets adjusted at run-time           */
+  static int  ft_trace_levels_enabled[trace_count];
 
+  /* array of trace levels, always initialized to 0 */
+  static int  ft_trace_levels_disabled[trace_count];
+
+  /* a pointer to either `ft_trace_levels_enabled' */
+  /* or `ft_trace_levels_disabled'                 */
+  int*  ft_trace_levels;
 
   /* define array of trace toggle names */
 #define FT_TRACE_DEF( x )  #x ,
 
   static const char*  ft_trace_toggles[trace_count + 1] =
   {
-#include FT_INTERNAL_TRACE_H
+#include <freetype/internal/fttrace.h>
     NULL
   };
 
@@ -164,33 +183,51 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Initialize the tracing sub-system.  This is done by retrieving the    */
-  /* value of the `FT2_DEBUG' environment variable.  It must be a list of  */
-  /* toggles, separated by spaces, `;', or `,'.  Example:                  */
-  /*                                                                       */
-  /*    export FT2_DEBUG="any:3 memory:7 stream:5"                         */
-  /*                                                                       */
-  /* This requests that all levels be set to 3, except the trace level for */
-  /* the memory and stream components which are set to 7 and 5,            */
-  /* respectively.                                                         */
-  /*                                                                       */
-  /* See the file `include/freetype/internal/fttrace.h' for details of the */
-  /* available toggle names.                                               */
-  /*                                                                       */
-  /* The level must be between 0 and 7; 0 means quiet (except for serious  */
-  /* runtime errors), and 7 means _very_ verbose.                          */
-  /*                                                                       */
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Disable( void )
+  {
+    ft_trace_levels = ft_trace_levels_disabled;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Enable( void )
+  {
+    ft_trace_levels = ft_trace_levels_enabled;
+  }
+
+
+  /**************************************************************************
+   *
+   * Initialize the tracing sub-system.  This is done by retrieving the
+   * value of the `FT2_DEBUG' environment variable.  It must be a list of
+   * toggles, separated by spaces, `;', or `,'.  Example:
+   *
+   *   export FT2_DEBUG="any:3 memory:7 stream:5"
+   *
+   * This requests that all levels be set to 3, except the trace level for
+   * the memory and stream components which are set to 7 and 5,
+   * respectively.
+   *
+   * See the file `include/freetype/internal/fttrace.h' for details of
+   * the available toggle names.
+   *
+   * The level must be between 0 and 7; 0 means quiet (except for serious
+   * runtime errors), and 7 means _very_ verbose.
+   */
   FT_BASE_DEF( void )
   ft_debug_init( void )
   {
-/*  const char*  ft2_debug = getenv( "FT2_DEBUG" ); */
+    /* const char*  ft2_debug = ft_getenv( "FT2_DEBUG" ); */
     char         buf[256];
     const char*  ft2_debug = &buf[0];
 
 
-/*  if ( ft2_debug ) */
+    /* if ( ft2_debug ) */
     if ( GetVar( "FT2_DEBUG", (STRPTR)ft2_debug, 256, LV_VAR ) > 0 )
     {
       const char*  p = ft2_debug;
@@ -250,14 +287,16 @@
             {
               /* special case for `any' */
               for ( n = 0; n < trace_count; n++ )
-                ft_trace_levels[n] = level;
+                ft_trace_levels_enabled[n] = level;
             }
             else
-              ft_trace_levels[found] = level;
+              ft_trace_levels_enabled[found] = level;
           }
         }
       }
     }
+
+    ft_trace_levels = ft_trace_levels_enabled;
   }
 
 
@@ -287,11 +326,23 @@
   }
 
 
+  FT_BASE_DEF( void )
+  FT_Trace_Disable( void )
+  {
+    /* nothing */
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Enable( void )
+  {
+    /* nothing */
+  }
+
+
 #endif /* !FT_DEBUG_LEVEL_TRACE */
 
-/*
-Local Variables:
-coding: latin-1
-End:
-*/
+
 /* END */
diff --git a/builds/amiga/src/base/ftsystem.c b/builds/amiga/src/base/ftsystem.c
index babaeeb..d85845c 100644
--- a/builds/amiga/src/base/ftsystem.c
+++ b/builds/amiga/src/base/ftsystem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Amiga-specific FreeType low-level system interface (body).           */
 /*                                                                         */
-/*  Copyright 1996-2018 by                                                 */
+/*  Copyright (C) 1996-2023 by                                             */
 /*  David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner.       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -96,10 +96,10 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_SYSTEM_H
-#include FT_ERRORS_H
-#include FT_TYPES_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftsystem.h>
+#include <freetype/fterrors.h>
+#include <freetype/fttypes.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -235,7 +235,7 @@
   /* messages during execution.                                            */
   /*                                                                       */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_io
+#define FT_COMPONENT  io
 
   /* We use the macro STREAM_FILE for convenience to extract the       */
   /* system-specific stream handle from a given FreeType stream object */
@@ -264,7 +264,7 @@
 
     stream->descriptor.pointer = NULL;
     stream->size               = 0;
-    stream->base               = 0;
+    stream->base               = NULL;
   }
 
 
diff --git a/builds/ansi/ansi-def.mk b/builds/ansi/ansi-def.mk
index 1484f96..8217893 100644
--- a/builds/ansi/ansi-def.mk
+++ b/builds/ansi/ansi-def.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -13,12 +13,15 @@
 # fully.
 
 
-DELETE    := rm -f
-CAT       := cat
-SEP       := /
-BUILD_DIR := $(TOP_DIR)/builds/ansi
-PLATFORM  := ansi
+DELETE       := rm -f
+CAT          := cat
+SEP          := /
+PLATFORM_DIR := $(TOP_DIR)/builds/ansi
+PLATFORM     := ansi
 
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+BIN := bin
 
 # The directory where all library files are placed.
 #
@@ -61,14 +64,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS :=
+ANSIFLAGS ?=
 
 
 # EOF
diff --git a/builds/ansi/ansi.mk b/builds/ansi/ansi.mk
index c06732c..ad40939 100644
--- a/builds/ansi/ansi.mk
+++ b/builds/ansi/ansi.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/atari/README.TXT b/builds/atari/README.TXT
index ffe6545..1300817 100644
--- a/builds/atari/README.TXT
+++ b/builds/atari/README.TXT
@@ -15,7 +15,7 @@
 
     INCLUDE;E:\freetype2\include
 
-- The file `freetype2/include/Ft2build.h' must be patched as follows to
+- The file `freetype/include/Ft2build.h' must be patched as follows to
   include ATARI.H:
 
     #ifndef FT2_BUILD_GENERIC_H_
@@ -40,7 +40,7 @@
 
     INCLUDE;E:\freetype2\include
 
-- In der Datei freetype2/include/Ft2build.h muss zu Beginn
+- In der Datei freetype/include/Ft2build.h muss zu Beginn
   ein #include "ATARI.H" wie folgt eingefgt werden:
 
     #ifndef FT2_BUILD_GENERIC_H_
diff --git a/builds/beos/beos-def.mk b/builds/beos/beos-def.mk
index 89c54dd..1cca80c 100644
--- a/builds/beos/beos-def.mk
+++ b/builds/beos/beos-def.mk
@@ -5,7 +5,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -15,12 +15,15 @@
 # fully.
 
 
-DELETE    := rm -f
-CAT       := cat
-SEP       := /
-BUILD_DIR := $(TOP_DIR)/builds/beos
-PLATFORM  := beos
+DELETE       := rm -f
+CAT          := cat
+SEP          := /
+PLATFORM_DIR := $(TOP_DIR)/builds/beos
+PLATFORM     := beos
 
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+BIN := bin
 
 # The directory where all library files are placed.
 #
@@ -63,14 +66,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS :=
+ANSIFLAGS ?=
 
 
 # EOF
diff --git a/builds/beos/beos.mk b/builds/beos/beos.mk
index 619ceaf..69ca1f1 100644
--- a/builds/beos/beos.mk
+++ b/builds/beos/beos.mk
@@ -2,7 +2,7 @@
 # FreeType 2 configuration rules for a BeOS system
 #
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/beos/detect.mk b/builds/beos/detect.mk
index 82f6205..dd1b5a6 100644
--- a/builds/beos/detect.mk
+++ b/builds/beos/detect.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -27,11 +27,11 @@
 
 ifeq ($(PLATFORM),beos)
 
-  DELETE      := rm -f
-  CAT         := cat
-  SEP         := /
-  BUILD_DIR   := $(TOP_DIR)/builds/beos
-  CONFIG_FILE := beos.mk
+  DELETE         := rm -f
+  CAT            := cat
+  SEP            := /
+  PLATFORM_DIR   := $(TOP_DIR)/builds/beos
+  CONFIG_FILE    := beos.mk
 
   setup: std_setup
 
diff --git a/builds/cmake/FindBrotliDec.cmake b/builds/cmake/FindBrotliDec.cmake
new file mode 100644
index 0000000..81036cb
--- /dev/null
+++ b/builds/cmake/FindBrotliDec.cmake
@@ -0,0 +1,52 @@
+# FindBrotliDec.cmake
+#
+# Copyright (C) 2019-2023 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# Written by Werner Lemberg <wl@gnu.org>
+#
+# 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.
+#
+#
+# Try to find libbrotlidec include and library directories.
+#
+# If found, the following variables are set.
+#
+#   BROTLIDEC_INCLUDE_DIRS
+#   BROTLIDEC_LIBRARIES
+
+find_package(PkgConfig QUIET)
+
+pkg_check_modules(PC_BROTLIDEC QUIET libbrotlidec)
+
+if (PC_BROTLIDEC_VERSION)
+  set(BROTLIDEC_VERSION "${PC_BROTLIDEC_VERSION}")
+endif ()
+
+
+find_path(BROTLIDEC_INCLUDE_DIRS
+  NAMES brotli/decode.h
+  HINTS ${PC_BROTLIDEC_INCLUDEDIR}
+        ${PC_BROTLIDEC_INCLUDE_DIRS}
+  PATH_SUFFIXES brotli)
+
+find_library(BROTLIDEC_LIBRARIES
+  NAMES brotlidec
+  HINTS ${PC_BROTLIDEC_LIBDIR}
+        ${PC_BROTLIDEC_LIBRARY_DIRS})
+
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  BrotliDec
+  REQUIRED_VARS BROTLIDEC_INCLUDE_DIRS BROTLIDEC_LIBRARIES
+  FOUND_VAR BROTLIDEC_FOUND
+  VERSION_VAR BROTLIDEC_VERSION)
+
+mark_as_advanced(
+  BROTLIDEC_INCLUDE_DIRS
+  BROTLIDEC_LIBRARIES)
diff --git a/builds/cmake/FindHarfBuzz.cmake b/builds/cmake/FindHarfBuzz.cmake
index ee0d52e..b481fa4 100644
--- a/builds/cmake/FindHarfBuzz.cmake
+++ b/builds/cmake/FindHarfBuzz.cmake
@@ -1,4 +1,5 @@
 # Copyright (c) 2012, Intel Corporation
+# Copyright (c) 2019 Sony Interactive Entertainment Inc.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -27,55 +28,176 @@
 # Try to find Harfbuzz include and library directories.
 #
 # After successful discovery, this will set for inclusion where needed:
-# HARFBUZZ_INCLUDE_DIRS - containg the HarfBuzz headers
-# HARFBUZZ_LIBRARIES - containg the HarfBuzz library
+# HarfBuzz_INCLUDE_DIRS - containg the HarfBuzz headers
+# HarfBuzz_LIBRARIES - containg the HarfBuzz library
 
-include(FindPkgConfig)
+#[=======================================================================[.rst:
+FindHarfBuzz
+--------------
+
+Find HarfBuzz headers and libraries.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+``HarfBuzz::HarfBuzz``
+  The HarfBuzz library, if found.
+
+``HarfBuzz::ICU``
+  The HarfBuzz ICU library, if found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables in your project:
+
+``HarfBuzz_FOUND``
+  true if (the requested version of) HarfBuzz is available.
+``HarfBuzz_VERSION``
+  the version of HarfBuzz.
+``HarfBuzz_LIBRARIES``
+  the libraries to link against to use HarfBuzz.
+``HarfBuzz_INCLUDE_DIRS``
+  where to find the HarfBuzz headers.
+``HarfBuzz_COMPILE_OPTIONS``
+  this should be passed to target_compile_options(), if the
+  target is not used for linking
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
 pkg_check_modules(PC_HARFBUZZ QUIET harfbuzz)
+set(HarfBuzz_COMPILE_OPTIONS ${PC_HARFBUZZ_CFLAGS_OTHER})
+set(HarfBuzz_VERSION ${PC_HARFBUZZ_CFLAGS_VERSION})
 
-find_path(HARFBUZZ_INCLUDE_DIRS
+find_path(HarfBuzz_INCLUDE_DIR
     NAMES hb.h
-    HINTS ${PC_HARFBUZZ_INCLUDEDIR}
-          ${PC_HARFBUZZ_INCLUDE_DIRS}
+    HINTS ${PC_HARFBUZZ_INCLUDEDIR} ${PC_HARFBUZZ_INCLUDE_DIRS}
     PATH_SUFFIXES harfbuzz
 )
 
-find_library(HARFBUZZ_LIBRARIES NAMES harfbuzz
-    HINTS ${PC_HARFBUZZ_LIBDIR}
-          ${PC_HARFBUZZ_LIBRARY_DIRS}
+find_library(HarfBuzz_LIBRARY
+    NAMES ${HarfBuzz_NAMES} harfbuzz
+    HINTS ${PC_HARFBUZZ_LIBDIR} ${PC_HARFBUZZ_LIBRARY_DIRS}
 )
 
-if (HARFBUZZ_INCLUDE_DIRS)
-    if (EXISTS "${HARFBUZZ_INCLUDE_DIRS}/hb-version.h")
-        file(READ "${HARFBUZZ_INCLUDE_DIRS}/hb-version.h" _harfbuzz_version_content)
+if (HarfBuzz_INCLUDE_DIR AND NOT HarfBuzz_VERSION)
+    if (EXISTS "${HarfBuzz_INCLUDE_DIR}/hb-version.h")
+        file(READ "${HarfBuzz_INCLUDE_DIR}/hb-version.h" _harfbuzz_version_content)
 
         string(REGEX MATCH "#define +HB_VERSION_STRING +\"([0-9]+\\.[0-9]+\\.[0-9]+)\"" _dummy "${_harfbuzz_version_content}")
-        set(HARFBUZZ_VERSION "${CMAKE_MATCH_1}")
+        set(HarfBuzz_VERSION "${CMAKE_MATCH_1}")
     endif ()
 endif ()
 
-if ("${harfbuzz_FIND_VERSION}" VERSION_GREATER "${HARFBUZZ_VERSION}")
-    message(FATAL_ERROR "Required version (" ${harfbuzz_FIND_VERSION} ") is higher than found version (" ${HARFBUZZ_VERSION} ")")
+if ("${HarfBuzz_FIND_VERSION}" VERSION_GREATER "${HarfBuzz_VERSION}")
+  if (HarfBuzz_FIND_REQUIRED)
+    message(FATAL_ERROR
+      "Required version (" ${HarfBuzz_FIND_VERSION} ")"
+      " is higher than found version (" ${HarfBuzz_VERSION} ")")
+  else ()
+    message(WARNING
+      "Required version (" ${HarfBuzz_FIND_VERSION} ")"
+      " is higher than found version (" ${HarfBuzz_VERSION} ")")
+    unset(HarfBuzz_VERSION)
+    unset(HarfBuzz_INCLUDE_DIRS)
+    unset(HarfBuzz_LIBRARIES)
+    return ()
+  endif ()
+endif ()
+
+# Find components
+if (HarfBuzz_INCLUDE_DIR AND HarfBuzz_LIBRARY)
+    set(_HarfBuzz_REQUIRED_LIBS_FOUND ON)
+    set(HarfBuzz_LIBS_FOUND "HarfBuzz (required): ${HarfBuzz_LIBRARY}")
+else ()
+    set(_HarfBuzz_REQUIRED_LIBS_FOUND OFF)
+    set(HarfBuzz_LIBS_NOT_FOUND "HarfBuzz (required)")
+endif ()
+
+if (NOT CMAKE_VERSION VERSION_LESS 3.3)
+  if ("ICU" IN_LIST HarfBuzz_FIND_COMPONENTS)
+      pkg_check_modules(PC_HARFBUZZ_ICU QUIET harfbuzz-icu)
+      set(HarfBuzz_ICU_COMPILE_OPTIONS ${PC_HARFBUZZ_ICU_CFLAGS_OTHER})
+
+      find_path(HarfBuzz_ICU_INCLUDE_DIR
+          NAMES hb-icu.h
+          HINTS ${PC_HARFBUZZ_ICU_INCLUDEDIR} ${PC_HARFBUZZ_ICU_INCLUDE_DIRS}
+          PATH_SUFFIXES harfbuzz
+      )
+
+      find_library(HarfBuzz_ICU_LIBRARY
+          NAMES ${HarfBuzz_ICU_NAMES} harfbuzz-icu
+          HINTS ${PC_HARFBUZZ_ICU_LIBDIR} ${PC_HARFBUZZ_ICU_LIBRARY_DIRS}
+      )
+
+      if (HarfBuzz_ICU_LIBRARY)
+          if (HarfBuzz_FIND_REQUIRED_ICU)
+              list(APPEND HarfBuzz_LIBS_FOUND "ICU (required): ${HarfBuzz_ICU_LIBRARY}")
+          else ()
+            list(APPEND HarfBuzz_LIBS_FOUND "ICU (optional): ${HarfBuzz_ICU_LIBRARY}")
+          endif ()
+      else ()
+          if (HarfBuzz_FIND_REQUIRED_ICU)
+            set(_HarfBuzz_REQUIRED_LIBS_FOUND OFF)
+            list(APPEND HarfBuzz_LIBS_NOT_FOUND "ICU (required)")
+          else ()
+            list(APPEND HarfBuzz_LIBS_NOT_FOUND "ICU (optional)")
+          endif ()
+      endif ()
+  endif ()
+endif ()
+
+if (NOT HarfBuzz_FIND_QUIETLY)
+    if (HarfBuzz_LIBS_FOUND)
+        message(STATUS "Found the following HarfBuzz libraries:")
+        foreach (found ${HarfBuzz_LIBS_FOUND})
+            message(STATUS " ${found}")
+        endforeach ()
+    endif ()
+    if (HarfBuzz_LIBS_NOT_FOUND)
+        message(STATUS "The following HarfBuzz libraries were not found:")
+        foreach (found ${HarfBuzz_LIBS_NOT_FOUND})
+            message(STATUS " ${found}")
+        endforeach ()
+    endif ()
 endif ()
 
 include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(
-    harfbuzz 
-        REQUIRED_VARS HARFBUZZ_INCLUDE_DIRS HARFBUZZ_LIBRARIES
-        VERSION_VAR HARFBUZZ_VERSION)
-
-mark_as_advanced(
-    HARFBUZZ_INCLUDE_DIRS
-    HARFBUZZ_LIBRARIES
+find_package_handle_standard_args(HarfBuzz
+    FOUND_VAR HarfBuzz_FOUND
+    REQUIRED_VARS HarfBuzz_INCLUDE_DIR HarfBuzz_LIBRARY _HarfBuzz_REQUIRED_LIBS_FOUND
+    VERSION_VAR HarfBuzz_VERSION
 )
 
-# Allows easy linking as in 
-#   target_link_libraries(freetype PRIVATE Harfbuzz::Harfbuzz)
 if (NOT CMAKE_VERSION VERSION_LESS 3.1)
-    if (HARFBUZZ_FOUND AND NOT TARGET Harfbuzz::Harfbuzz)
-        add_library(Harfbuzz::Harfbuzz INTERFACE IMPORTED)
-        set_target_properties(
-            Harfbuzz::Harfbuzz PROPERTIES
-                INTERFACE_INCLUDE_DIRECTORIES "${HARFBUZZ_INCLUDE_DIRS}")
-    endif ()
+  if (HarfBuzz_LIBRARY AND NOT TARGET HarfBuzz::HarfBuzz)
+      add_library(HarfBuzz::HarfBuzz UNKNOWN IMPORTED GLOBAL)
+      set_target_properties(HarfBuzz::HarfBuzz PROPERTIES
+          IMPORTED_LOCATION "${HarfBuzz_LIBRARY}"
+          INTERFACE_COMPILE_OPTIONS "${HarfBuzz_COMPILE_OPTIONS}"
+          INTERFACE_INCLUDE_DIRECTORIES "${HarfBuzz_INCLUDE_DIR}"
+      )
+  endif ()
+
+  if (HarfBuzz_ICU_LIBRARY AND NOT TARGET HarfBuzz::ICU)
+      add_library(HarfBuzz::ICU UNKNOWN IMPORTED GLOBAL)
+      set_target_properties(HarfBuzz::ICU PROPERTIES
+          IMPORTED_LOCATION "${HarfBuzz_ICU_LIBRARY}"
+          INTERFACE_COMPILE_OPTIONS "${HarfBuzz_ICU_COMPILE_OPTIONS}"
+          INTERFACE_INCLUDE_DIRECTORIES "${HarfBuzz_ICU_INCLUDE_DIR}"
+      )
+  endif ()
+endif ()
+
+mark_as_advanced(
+    HarfBuzz_INCLUDE_DIR
+    HarfBuzz_ICU_INCLUDE_DIR
+    HarfBuzz_LIBRARY
+    HarfBuzz_ICU_LIBRARY
+)
+
+if (HarfBuzz_FOUND)
+   set(HarfBuzz_LIBRARIES ${HarfBuzz_LIBRARY} ${HarfBuzz_ICU_LIBRARY})
+   set(HarfBuzz_INCLUDE_DIRS ${HarfBuzz_INCLUDE_DIR} ${HarfBuzz_ICU_INCLUDE_DIR})
 endif ()
diff --git a/builds/cmake/iOS.cmake b/builds/cmake/iOS.cmake
index c6da70c..7aba7c5 100644
--- a/builds/cmake/iOS.cmake
+++ b/builds/cmake/iOS.cmake
@@ -1,6 +1,6 @@
 # iOS.cmake
 #
-# Copyright 2014-2018 by
+# Copyright (C) 2014-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # Written by David Wimsey <david@wimsey.us>
diff --git a/builds/cmake/testbuild.sh b/builds/cmake/testbuild.sh
index 1fa3a18..007170b 100755
--- a/builds/cmake/testbuild.sh
+++ b/builds/cmake/testbuild.sh
@@ -1,6 +1,6 @@
 #!/bin/sh -e
 
-# Copyright 2015-2018 by
+# Copyright (C) 2015-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -93,7 +93,7 @@
 #include <stdlib.h>
 
 #include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 
 FT_Library library;
diff --git a/builds/compiler/ansi-cc.mk b/builds/compiler/ansi-cc.mk
index 99fe8cb..f8386f6 100644
--- a/builds/compiler/ansi-cc.mk
+++ b/builds/compiler/ansi-cc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -59,7 +59,7 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c
@@ -68,7 +68,7 @@
 #
 #  we assume the compiler is already strictly ANSI
 #
-ANSIFLAGS :=
+ANSIFLAGS ?=
 
 
 # Library linking
diff --git a/builds/compiler/bcc-dev.mk b/builds/compiler/bcc-dev.mk
index 8d67fa1..d01ed7c 100644
--- a/builds/compiler/bcc-dev.mk
+++ b/builds/compiler/bcc-dev.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -60,14 +60,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -q -c -y -d -v -Od -w-par -w-ccc -w-rch -w-pro -w-aus
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS := -A
+ANSIFLAGS ?= -A
 
 
 # Library linking
diff --git a/builds/compiler/bcc.mk b/builds/compiler/bcc.mk
index 02d4833..a484bba 100644
--- a/builds/compiler/bcc.mk
+++ b/builds/compiler/bcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -60,14 +60,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c -q -y -d -v -Od -w-par -w-ccc -w-rch -w-pro -w-aus
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS := -A
+ANSIFLAGS ?= -A
 
 
 # Library linking
diff --git a/builds/compiler/emx.mk b/builds/compiler/emx.mk
index 2926b11..34d06b2 100644
--- a/builds/compiler/emx.mk
+++ b/builds/compiler/emx.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2003-2018 by
+# Copyright (C) 2003-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -58,14 +58,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c -g -O6 -Wall
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS :=
+ANSIFLAGS ?=
 
 
 # Library linking
diff --git a/builds/compiler/gcc-dev.mk b/builds/compiler/gcc-dev.mk
index 48d2848..a6ded52 100644
--- a/builds/compiler/gcc-dev.mk
+++ b/builds/compiler/gcc-dev.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -59,7 +59,7 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 ifndef CFLAGS
@@ -82,8 +82,9 @@
 endif
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
+# You can override this on the command line.
 #
-ANSIFLAGS := -ansi -pedantic
+ANSIFLAGS ?= -std=c99 -pedantic
 
 
 # Library linking
diff --git a/builds/compiler/gcc.mk b/builds/compiler/gcc.mk
index 9c77239..20ca969 100644
--- a/builds/compiler/gcc.mk
+++ b/builds/compiler/gcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -58,14 +58,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c -g -O3 -Wall
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS := -ansi -pedantic
+ANSIFLAGS ?= -std=c99 -pedantic
 
 
 # Library linking
diff --git a/builds/compiler/intelc.mk b/builds/compiler/intelc.mk
index e9236d3..1f72493 100644
--- a/builds/compiler/intelc.mk
+++ b/builds/compiler/intelc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -61,7 +61,7 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 #   Note that the Intel C/C++ compiler version 4.5 complains about
@@ -74,7 +74,7 @@
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS := /Qansi_alias /Za
+ANSIFLAGS ?= /Qansi_alias /Za
 
 # Library linking
 #
diff --git a/builds/compiler/unix-lcc.mk b/builds/compiler/unix-lcc.mk
index 09fffeb..af11d17 100644
--- a/builds/compiler/unix-lcc.mk
+++ b/builds/compiler/unix-lcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -60,7 +60,7 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c -g
@@ -71,7 +71,7 @@
 #
 #  the "-A" flag simply increments verbosity about non ANSI code
 #
-ANSIFLAGS := -A
+ANSIFLAGS ?= -A
 
 
 # library linking
diff --git a/builds/compiler/visualage.mk b/builds/compiler/visualage.mk
index 10299da..75e9023 100644
--- a/builds/compiler/visualage.mk
+++ b/builds/compiler/visualage.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/compiler/visualc.mk b/builds/compiler/visualc.mk
index 74f498b..30b03fc 100644
--- a/builds/compiler/visualc.mk
+++ b/builds/compiler/visualc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -63,14 +63,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= /nologo /c /Ox /W3 /WX
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS := /Za /D_CRT_SECURE_NO_DEPRECATE
+ANSIFLAGS ?= /Za /D_CRT_SECURE_NO_DEPRECATE
 
 
 # Library linking
diff --git a/builds/compiler/watcom.mk b/builds/compiler/watcom.mk
index e455922..61f8cd7 100644
--- a/builds/compiler/watcom.mk
+++ b/builds/compiler/watcom.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -60,14 +60,14 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -zq
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
-ANSIFLAGS := -za
+ANSIFLAGS ?= -za
 
 
 # Library linking
diff --git a/builds/compiler/win-lcc.mk b/builds/compiler/win-lcc.mk
index 1356c1c..92f653e 100644
--- a/builds/compiler/win-lcc.mk
+++ b/builds/compiler/win-lcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -60,7 +60,7 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
 CFLAGS ?= -c -g2 -O
@@ -69,7 +69,7 @@
 #
 #  LCC is pure ANSI anyway!
 #
-ANSIFLAGS :=
+ANSIFLAGS ?=
 
 
 # library linking
diff --git a/builds/detect.mk b/builds/detect.mk
index eb7f797..d5cddb0 100644
--- a/builds/detect.mk
+++ b/builds/detect.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -16,7 +16,7 @@
 # This sub-Makefile is in charge of detecting the current platform.  It sets
 # the following variables:
 #
-#   BUILD_DIR    The configuration and system-specific directory.  Usually
+#   PLATFORM_DIR The configuration and system-specific directory.  Usually
 #                `builds/$(PLATFORM)' but can be different for custom builds
 #                of the library.
 #
@@ -49,8 +49,8 @@
 BUILD_CONFIG := $(TOP_DIR)/builds
 
 # These two assignments must be delayed.
-BUILD_DIR    = $(BUILD_CONFIG)/$(PLATFORM)
-CONFIG_RULES = $(BUILD_DIR)/$(CONFIG_FILE)
+PLATFORM_DIR = $(BUILD_CONFIG)/$(PLATFORM)
+CONFIG_RULES = $(PLATFORM_DIR)/$(CONFIG_FILE)
 
 # We define the BACKSLASH variable to hold a single back-slash character.
 # This is needed because a line like
@@ -113,14 +113,14 @@
 	$(info )
 	$(info $(empty)  platform                    $(PLATFORM))
 	$(info $(empty)  compiler                    $(CC))
-	$(info $(empty)  configuration directory     $(subst /,$(SEP),$(BUILD_DIR)))
+	$(info $(empty)  configuration directory     $(subst /,$(SEP),$(PLATFORM_DIR)))
 	$(info $(empty)  configuration rules         $(subst /,$(SEP),$(CONFIG_RULES)))
 	$(info )
 	$(info If this does not correspond to your system or settings please remove the file)
 	$(info `$(CONFIG_MK)' from this directory then read the INSTALL file for help.)
 	$(info )
 	$(info Otherwise, simply type `$(MAKE)' again to build the library,)
-	$(info or `$(MAKE) refdoc' to build the API reference (this needs python >= 2.6).)
+	$(info or `$(MAKE) refdoc' to build the API reference (this needs Python >= 3.5).)
 	$(info )
 	@$(COPY) $(subst /,$(SEP),$(CONFIG_RULES) $(CONFIG_MK))
 
diff --git a/builds/dos/detect.mk b/builds/dos/detect.mk
index 14d8c03..8ed148b 100644
--- a/builds/dos/detect.mk
+++ b/builds/dos/detect.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/dos/dos-def.mk b/builds/dos/dos-def.mk
index cb1154d..37cb2c1 100644
--- a/builds/dos/dos-def.mk
+++ b/builds/dos/dos-def.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -13,12 +13,15 @@
 # fully.
 
 
-DELETE    := del
-CAT       := type
-SEP       := $(strip \ )
-BUILD_DIR := $(TOP_DIR)/builds/dos
-PLATFORM  := dos
+DELETE       := del
+CAT          := type
+SEP          := $(strip \ )
+PLATFORM_DIR := $(TOP_DIR)/builds/dos
+PLATFORM     := dos
 
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+BIN := Scripts
 
 # The executable file extension (for tools), *with* leading dot.
 #
diff --git a/builds/dos/dos-emx.mk b/builds/dos/dos-emx.mk
index dedcc3f..23181d7 100644
--- a/builds/dos/dos-emx.mk
+++ b/builds/dos/dos-emx.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2003-2018 by
+# Copyright (C) 2003-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/dos/dos-gcc.mk b/builds/dos/dos-gcc.mk
index 53099ab..cd695db 100644
--- a/builds/dos/dos-gcc.mk
+++ b/builds/dos/dos-gcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/dos/dos-wat.mk b/builds/dos/dos-wat.mk
index 1bd00e7..a6b65cb 100644
--- a/builds/dos/dos-wat.mk
+++ b/builds/dos/dos-wat.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2003-2018 by
+# Copyright (C) 2003-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/exports.mk b/builds/exports.mk
index 59fe31a..b10924a 100644
--- a/builds/exports.mk
+++ b/builds/exports.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2005-2018 by
+# Copyright (C) 2005-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/freetype.mk b/builds/freetype.mk
index 6f68a0f..d96ded0 100644
--- a/builds/freetype.mk
+++ b/builds/freetype.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -20,8 +20,8 @@
 # The following variables (set by other Makefile components, in the
 # environment, or on the command line) are used:
 #
-#   BUILD_DIR      The architecture dependent directory,
-#                  e.g. `$(TOP_DIR)/builds/unix'.  Added to INCLUDES also.
+#   PLATFORM_DIR   The architecture-dependent directory,
+#                  e.g., `$(TOP_DIR)/builds/unix'.  Added to INCLUDES also.
 #
 #   OBJ_DIR        The directory in which object files are created.
 #
@@ -75,7 +75,7 @@
 # The targets `objects' and `library' are defined at the end of this
 # Makefile after all other rules have been included.
 #
-.PHONY: single multi objects library refdoc
+.PHONY: single multi objects library refdoc refdoc-venv
 
 # default target -- build single objects and library
 #
@@ -104,7 +104,7 @@
 
 # The documentation directory.
 #
-DOC_DIR ?= $(TOP_DIR)/docs/reference
+DOC_DIR ?= $(TOP_DIR)/docs
 
 # The final name of the library file.
 #
@@ -121,17 +121,19 @@
 #
 INCLUDES := $(subst /,$(COMPILER_SEP),$(OBJ_DIR) \
                                       $(DEVEL_DIR) \
-                                      $(BUILD_DIR) \
+                                      $(PLATFORM_DIR) \
                                       $(TOP_DIR)/include)
 
 INCLUDE_FLAGS := $(INCLUDES:%=$I%)
 
+# For a development build, we assume that the external library dependencies
+# defined in `ftoption.h' are fulfilled, so we directly access the necessary
+# include directory information using `pkg-config'.
+#
 ifdef DEVEL_DIR
-  # We assume that all library dependencies for FreeType are fulfilled for a
-  # development build, so we directly access the necessary include directory
-  # information using `pkg-config'.
-  INCLUDE_FLAGS += $(shell pkg-config --cflags libpng \
-                                               harfbuzz )
+  INCLUDE_FLAGS += $(shell pkg-config --cflags libpng)
+  INCLUDE_FLAGS += $(shell pkg-config --cflags harfbuzz)
+  INCLUDE_FLAGS += $(shell pkg-config --cflags libbrotlidec)
 endif
 
 
@@ -146,25 +148,13 @@
 # FreeType.  This is required to let our sources include the internal
 # headers (something forbidden by clients).
 #
-# Finally, we define FT_CONFIG_MODULES_H so that the compiler uses the
-# generated version of `ftmodule.h' in $(OBJ_DIR).  If there is an
-# `ftoption.h' files in $(OBJ_DIR), define FT_CONFIG_OPTIONS_H too.
-#
-ifneq ($(wildcard $(OBJ_DIR)/ftoption.h),)
-  FTOPTION_H    := $(OBJ_DIR)/ftoption.h
-  FTOPTION_FLAG := $DFT_CONFIG_OPTIONS_H="<ftoption.h>"
-else ifneq ($(wildcard $(BUILD_DIR)/ftoption.h),)
-  FTOPTION_H    := $(BUILD_DIR)/ftoption.h
-  FTOPTION_FLAG := $DFT_CONFIG_OPTIONS_H="<ftoption.h>"
-endif
-
 # `CPPFLAGS' might be specified by the user in the environment.
 #
-FT_CFLAGS  = $(CPPFLAGS) \
-             $(CFLAGS) \
-             $DFT2_BUILD_LIBRARY \
-             $DFT_CONFIG_MODULES_H="<ftmodule.h>" \
-             $(FTOPTION_FLAG)
+FT_CFLAGS = $(CPPFLAGS) \
+            $(CFLAGS) \
+            $DFT2_BUILD_LIBRARY
+
+FT_COMPILE := $(CC) $(ANSIFLAGS) $(INCLUDE_FLAGS) $(FT_CFLAGS)
 
 
 # Include the `exports' rules file.
@@ -179,16 +169,22 @@
 
 # Define $(PUBLIC_H) as the list of all public header files located in
 # `$(TOP_DIR)/include/freetype'.  $(INTERNAL_H), and $(CONFIG_H) are defined
-# similarly.
+# similarly.  $(FTOPTION_H) is the option file used in the compilation.
 #
 # This is used to simplify the dependency rules -- if one of these files
 # changes, the whole library is recompiled.
 #
+ifneq ($(wildcard $(OBJ_DIR)/ftoption.h),)
+  FTOPTION_H := $(OBJ_DIR)/ftoption.h
+else ifneq ($(wildcard $(PLATFORM_DIR)/ftoption.h),)
+  FTOPTION_H := $(PLATFORM_DIR)/ftoption.h
+endif
+
 PUBLIC_H   := $(wildcard $(PUBLIC_DIR)/*.h)
 INTERNAL_H := $(wildcard $(INTERNAL_DIR)/*.h) \
               $(wildcard $(SERVICES_DIR)/*.h)
 CONFIG_H   := $(wildcard $(CONFIG_DIR)/*.h) \
-              $(wildcard $(BUILD_DIR)/config/*.h) \
+              $(wildcard $(PLATFORM_DIR)/config/*.h) \
               $(FTMODULE_H) \
               $(FTOPTION_H)
 DEVEL_H    := $(wildcard $(TOP_DIR)/devel/*.h)
@@ -196,8 +192,6 @@
 FREETYPE_H := $(PUBLIC_H) $(INTERNAL_H) $(CONFIG_H) $(DEVEL_H)
 
 
-FT_COMPILE := $(CC) $(ANSIFLAGS) $(INCLUDE_FLAGS) $(FT_CFLAGS)
-
 # ftsystem component
 #
 FTSYS_SRC ?= $(BASE_DIR)/ftsystem.c
@@ -226,6 +220,7 @@
 #
 include $(SRC_DIR)/base/rules.mk
 include $(patsubst %,$(SRC_DIR)/%/rules.mk,$(MODULES))
+include $(SRC_DIR)/dlg/rules.mk
 
 
 # ftinit component
@@ -266,8 +261,8 @@
 
 # All FreeType library objects.
 #
-OBJ_M := $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M)
-OBJ_S := $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S)
+OBJ_M := $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M) $(DLG_OBJS_M)
+OBJ_S := $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S) $(DLG_OBJS_S)
 
 
 # The target `multi' on the Make command line indicates that we want to
@@ -289,18 +284,51 @@
 
 library: $(PROJECT_LIBRARY)
 
-
-# Option `-B' disables generation of .pyc files (available since python 2.6)
+# Run `docwriter' in the current Python environment.
 #
-refdoc:
-	python -B $(SRC_DIR)/tools/docmaker/docmaker.py \
-                  --prefix=ft2                          \
-                  --title=FreeType-$(version)           \
-                  --output=$(DOC_DIR)                   \
-                  $(PUBLIC_DIR)/*.h                     \
-                  $(PUBLIC_DIR)/config/*.h              \
-                  $(PUBLIC_DIR)/cache/*.h
+PYTHON ?= python
 
+refdoc:
+	@echo Running docwriter...
+	$(PYTHON) -m docwriter \
+                  --prefix=ft2 \
+                  --title=FreeType-$(version) \
+                  --site=reference \
+                  --output=$(DOC_DIR) \
+                  $(PUBLIC_DIR)/*.h \
+                  $(PUBLIC_DIR)/config/*.h \
+                  $(PUBLIC_DIR)/cache/*.h
+	@echo Building static site...
+	cd $(DOC_DIR) && mkdocs build
+	@echo Done.
+
+# Variables for running `refdoc' with Python's `virtualenv'.  The
+# environment is created in `DOC_DIR/env' and is gitignored.
+#
+# We still need to cd into `DOC_DIR' to build `mkdocs' because paths in
+# `mkdocs.yml' are relative to the current working directory.
+#
+VENV_NAME  := env
+VENV_DIR   := $(DOC_DIR)$(SEP)$(VENV_NAME)
+ENV_PYTHON := $(VENV_DIR)$(SEP)$(BIN)$(SEP)$(PYTHON)
+
+refdoc-venv:
+	@echo Setting up virtualenv for Python...
+	virtualenv --python=$(PYTHON) $(VENV_DIR)
+	@echo Installing docwriter...
+	$(ENV_PYTHON) -m pip install docwriter
+	@echo Running docwriter...
+	$(ENV_PYTHON) -m docwriter \
+                      --prefix=ft2 \
+                      --title=FreeType-$(version) \
+                      --site=reference \
+                      --output=$(DOC_DIR) \
+                      $(PUBLIC_DIR)/*.h \
+                      $(PUBLIC_DIR)/config/*.h \
+                      $(PUBLIC_DIR)/cache/*.h
+	@echo Building static site...
+	cd $(DOC_DIR) && $(VENV_NAME)$(SEP)$(BIN)$(SEP)python -m mkdocs build
+	@echo Done.
 
 .PHONY: clean_project_std distclean_project_std
 
diff --git a/builds/link_dos.mk b/builds/link_dos.mk
index 3b0e8da..b3dc451 100644
--- a/builds/link_dos.mk
+++ b/builds/link_dos.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/link_std.mk b/builds/link_std.mk
index 8ba5e64..aca8ec4 100644
--- a/builds/link_std.mk
+++ b/builds/link_std.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/mac/README b/builds/mac/README
index f58e47d..092487a 100644
--- a/builds/mac/README
+++ b/builds/mac/README
@@ -46,7 +46,7 @@
 
   Required files are downloadable from:
 
-      http://developer.apple.com/tools/mpw-tools/index.html
+      http://macintoshgarden.org/apps/macintosh-programmers-workshop
 
   Also you can find documents how to update by MPW-PR.
 
@@ -54,7 +54,7 @@
   skeletons. Python bundled to Mac OS X is enough. For
   classic MacOS, MacPython is available:
 
-      http://homepages.cwi.nl/~jack/macpython/
+      https://homepages.cwi.nl/~jack/macpython/
 
   MPW requires all files are typed by resource fork.
   ResEdit bundled to MPW is enough. In Mac OS X,
@@ -280,7 +280,7 @@
     migrate to FSRef datatype. The big differences of FSRef
     against FSSpec are explained in Apple TechNotes 2078.
 
-    http://developer.apple.com/technotes/tn2002/tn2078.html
+    https://developer.apple.com/library/archive/technotes/tn2078/
 
     - filename length: the max length of file
     name of FSRef is 255 chars (it is limit of HFS+),
@@ -314,7 +314,7 @@
     of FontManager emulation without QuickDraw is
     explained in
 
-      http://www.gyve.org/~mpsuzuki/ats_benchmark.html
+      http://gyvern.ipc.hiroshima-u.ac.jp/~mpsuzuki/ats_benchmark.html
 
   A-3. Framework Availabilities
   -----------------------------
diff --git a/builds/mac/freetype-Info.plist b/builds/mac/freetype-Info.plist
index b3d114d..344e5ac 100644
--- a/builds/mac/freetype-Info.plist
+++ b/builds/mac/freetype-Info.plist
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
-          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+          "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
 
 <plist version="1.0">
 
@@ -9,7 +9,7 @@
   <string>English</string>
 
   <key>CFBundleExecutable</key>
-  <string>FreeType</string>
+  <string>freetype</string>
 
   <key>CFBundleGetInfoString</key>
   <string>FreeType ${PROJECT_VERSION}</string>
diff --git a/builds/mac/ftmac.c b/builds/mac/ftmac.c
index c45546c..8fe5565 100644
--- a/builds/mac/ftmac.c
+++ b/builds/mac/ftmac.c
@@ -5,7 +5,7 @@
 /*    Mac FOND support.  Written by just@letterror.com.                    */
 /*  Heavily Fixed by mpsuzuki, George Williams and Sean McBride            */
 /*                                                                         */
-/*  Copyright 1996-2018 by                                                 */
+/*  Copyright (C) 1996-2023 by                                             */
 /*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -62,10 +62,9 @@
   */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/freetype.h>
+#include <freetype/tttags.h>
+#include <freetype/internal/ftstream.h>
 #include "ftbase.h"
 
 #if defined( __GNUC__ ) || defined( __IBMC__ )
@@ -98,7 +97,7 @@
 
 #define FT_DEPRECATED_ATTRIBUTE
 
-#include FT_MAC_H
+#include <freetype/ftmac.h>
 
   /* undefine blocking-macros in ftmac.h */
 #undef FT_GetFile_From_Mac_Name
@@ -448,7 +447,7 @@
 
     stream->descriptor.pointer = NULL;
     stream->size               = 0;
-    stream->base               = 0;
+    stream->base               = NULL;
   }
 
 
@@ -780,9 +779,10 @@
       style = (StyleTable*)p;
       p += sizeof ( StyleTable );
       string_count = EndianS16_BtoN( *(short*)(p) );
+      string_count = FT_MIN( 64, string_count );
       p += sizeof ( short );
 
-      for ( i = 0; i < string_count && i < 64; i++ )
+      for ( i = 0; i < string_count; i++ )
       {
         names[i] = p;
         p       += names[i][0];
@@ -799,7 +799,7 @@
           ps_name[ps_name_len] = 0;
         }
         if ( style->indexes[face_index] > 1 &&
-             style->indexes[face_index] <= FT_MIN( string_count, 64 ) )
+             style->indexes[face_index] <= string_count )
         {
           unsigned char*  suffixes = names[style->indexes[face_index] - 1];
 
@@ -939,7 +939,7 @@
     if ( lwfn_file_name[0] )
     {
       err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
-                                 buff, sizeof ( buff )  );
+                                 buff, sizeof ( buff ) );
       if ( !err )
         have_lwfn = 1;
     }
@@ -1011,7 +1011,7 @@
       old_total_size = total_size;
     }
 
-    if ( FT_ALLOC( buffer, (FT_Long)total_size ) )
+    if ( FT_QALLOC( buffer, (FT_Long)total_size ) )
       goto Error;
 
     /* Second pass: append all POST data to the buffer, add PFB fields. */
@@ -1127,7 +1127,7 @@
       return FT_THROW( Invalid_Handle );
 
     sfnt_size = (FT_ULong)GetHandleSize( sfnt );
-    if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
+    if ( FT_QALLOC( sfnt_data, (FT_Long)sfnt_size ) )
     {
       ReleaseResource( sfnt );
       return error;
diff --git a/builds/meson/extract_freetype_version.py b/builds/meson/extract_freetype_version.py
new file mode 100644
index 0000000..c4c60e7
--- /dev/null
+++ b/builds/meson/extract_freetype_version.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-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.
+
+"""Extract the FreeType version numbers from `<freetype/freetype.h>`.
+
+This script parses the header to extract the version number defined there.
+By default, the full dotted version number is printed, but `--major`,
+`--minor` or `--patch` can be used to only print one of these values
+instead.
+"""
+
+from __future__ import print_function
+
+import argparse
+import os
+import re
+import sys
+
+# Expected input:
+#
+#  ...
+#  #define FREETYPE_MAJOR  2
+#  #define FREETYPE_MINOR  10
+#  #define FREETYPE_PATCH  2
+#  ...
+
+RE_MAJOR = re.compile(r"^ \#define \s+ FREETYPE_MAJOR \s+ (.*) $", re.X)
+RE_MINOR = re.compile(r"^ \#define \s+ FREETYPE_MINOR \s+ (.*) $", re.X)
+RE_PATCH = re.compile(r"^ \#define \s+ FREETYPE_PATCH \s+ (.*) $", re.X)
+
+
+def parse_freetype_header(header):
+    major = None
+    minor = None
+    patch = None
+
+    for line in header.splitlines():
+        line = line.rstrip()
+        m = RE_MAJOR.match(line)
+        if m:
+            assert major == None, "FREETYPE_MAJOR appears more than once!"
+            major = m.group(1)
+            continue
+
+        m = RE_MINOR.match(line)
+        if m:
+            assert minor == None, "FREETYPE_MINOR appears more than once!"
+            minor = m.group(1)
+            continue
+
+        m = RE_PATCH.match(line)
+        if m:
+            assert patch == None, "FREETYPE_PATCH appears more than once!"
+            patch = m.group(1)
+            continue
+
+    assert (
+        major and minor and patch
+    ), "This header is missing one of FREETYPE_MAJOR, FREETYPE_MINOR or FREETYPE_PATCH!"
+
+    return (major, minor, patch)
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    group = parser.add_mutually_exclusive_group()
+    group.add_argument(
+        "--major",
+        action="store_true",
+        help="Only print the major version number.",
+    )
+    group.add_argument(
+        "--minor",
+        action="store_true",
+        help="Only print the minor version number.",
+    )
+    group.add_argument(
+        "--patch",
+        action="store_true",
+        help="Only print the patch version number.",
+    )
+
+    parser.add_argument(
+        "input",
+        metavar="FREETYPE_H",
+        help="The input freetype.h header to parse.",
+    )
+
+    args = parser.parse_args()
+    with open(args.input) as f:
+        header = f.read()
+
+    version = parse_freetype_header(header)
+
+    if args.major:
+        print(version[0])
+    elif args.minor:
+        print(version[1])
+    elif args.patch:
+        print(version[2])
+    else:
+        print("%s.%s.%s" % version)
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/builds/meson/extract_libtool_version.py b/builds/meson/extract_libtool_version.py
new file mode 100644
index 0000000..6fac74c
--- /dev/null
+++ b/builds/meson/extract_libtool_version.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-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.
+
+"""Extract the libtool version from `configure.raw`.
+
+This script parses the `configure.raw` file to extract the libtool version
+number.  By default, the full dotted version number is printed, but
+`--major`, `--minor` or `--patch` can be used to only print one of these
+values instead.
+"""
+
+from __future__ import print_function
+
+import argparse
+import os
+import re
+import sys
+
+# Expected input:
+#
+#  ...
+#  version_info='23:2:17'
+#  ...
+
+RE_VERSION_INFO = re.compile(r"^version_info='(\d+):(\d+):(\d+)'")
+
+
+def parse_configure_raw(header):
+    major = None
+    minor = None
+    patch = None
+
+    for line in header.splitlines():
+        line = line.rstrip()
+        m = RE_VERSION_INFO.match(line)
+        if m:
+            assert major == None, "version_info appears more than once!"
+            major = m.group(1)
+            minor = m.group(2)
+            patch = m.group(3)
+            continue
+
+    assert (
+        major and minor and patch
+    ), "This input file is missing a version_info definition!"
+
+    return (major, minor, patch)
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    group = parser.add_mutually_exclusive_group()
+    group.add_argument(
+        "--major",
+        action="store_true",
+        help="Only print the major version number.",
+    )
+    group.add_argument(
+        "--minor",
+        action="store_true",
+        help="Only print the minor version number.",
+    )
+    group.add_argument(
+        "--patch",
+        action="store_true",
+        help="Only print the patch version number.",
+    )
+    group.add_argument(
+        "--soversion",
+        action="store_true",
+        help="Only print the libtool library suffix.",
+    )
+
+    parser.add_argument(
+        "input",
+        metavar="CONFIGURE_RAW",
+        help="The input configure.raw file to parse.",
+    )
+
+    args = parser.parse_args()
+    with open(args.input) as f:
+        raw_file = f.read()
+
+    version = parse_configure_raw(raw_file)
+
+    if args.major:
+        print(version[0])
+    elif args.minor:
+        print(version[1])
+    elif args.patch:
+        print(version[2])
+    elif args.soversion:
+        # Convert libtool version_info to the library suffix.
+        # (current,revision, age) -> (current - age, age, revision)
+        print(
+            "%d.%s.%s"
+            % (int(version[0]) - int(version[2]), version[2], version[1])
+        )
+    else:
+        print("%s.%s.%s" % version)
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/builds/meson/generate_reference_docs.py b/builds/meson/generate_reference_docs.py
new file mode 100644
index 0000000..4208bb6
--- /dev/null
+++ b/builds/meson/generate_reference_docs.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-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.
+
+"""Generate FreeType reference documentation."""
+
+from __future__ import print_function
+
+import argparse
+import glob
+import os
+import subprocess
+import sys
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    parser.add_argument(
+        "--input-dir",
+        required=True,
+        help="Top-level FreeType source directory.",
+    )
+
+    parser.add_argument(
+        "--version", required=True, help='FreeType version (e.g. "2.x.y").'
+    )
+
+    parser.add_argument(
+        "--output-dir", required=True, help="Output directory."
+    )
+
+    args = parser.parse_args()
+
+    # Get the list of input files of interest.
+    include_dir = os.path.join(args.input_dir, "include")
+    include_config_dir = os.path.join(include_dir, "config")
+    include_cache_dir = os.path.join(include_dir, "cache")
+
+    all_headers = (
+        glob.glob(os.path.join(args.input_dir, "include", "freetype", "*.h"))
+        + glob.glob(
+            os.path.join(
+                args.input_dir, "include", "freetype", "config", "*.h"
+            )
+        )
+        + glob.glob(
+            os.path.join(
+                args.input_dir, "include", "freetype", "cache", "*.h"
+            )
+        )
+    )
+
+    if not os.path.exists(args.output_dir):
+        os.makedirs(args.output_dir)
+    else:
+        assert os.path.isdir(args.output_dir), (
+            "Not a directory: " + args.output_dir
+        )
+
+    cmds = [
+        sys.executable,
+        "-m",
+        "docwriter",
+        "--prefix=ft2",
+        "--title=FreeType-" + args.version,
+        "--site=reference",
+        "--output=" + args.output_dir,
+    ] + all_headers
+
+    print("Running docwriter...")
+    subprocess.check_call(cmds)
+
+    print("Building static site...")
+    subprocess.check_call(
+        [sys.executable, "-m", "mkdocs", "build"], cwd=args.output_dir
+    )
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/builds/meson/parse_modules_cfg.py b/builds/meson/parse_modules_cfg.py
new file mode 100644
index 0000000..6030bb2
--- /dev/null
+++ b/builds/meson/parse_modules_cfg.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-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.
+
+"""Parse modules.cfg and dump its output either as ftmodule.h or a list of
+base extensions.
+"""
+
+from __future__ import print_function
+
+import argparse
+import os
+import re
+import sys
+
+# Expected input:
+#
+#  ...
+#  FONT_MODULES += <name>
+#  HINTING_MODULES += <name>
+#  RASTER_MODULES += <name>
+#  AUX_MODULES += <name>
+#  BASE_EXTENSIONS += <name>
+#  ...
+
+
+def parse_modules_cfg(input_file):
+
+    lists = {
+        "FONT_MODULES": [],
+        "HINTING_MODULES": [],
+        "RASTER_MODULES": [],
+        "AUX_MODULES": [],
+        "BASE_EXTENSIONS": [],
+    }
+
+    for line in input_file.splitlines():
+        line = line.rstrip()
+        # Ignore empty lines and those that start with a comment.
+        if not line or line[0] == "#":
+            continue
+
+        items = line.split()
+        assert len(items) == 3 and items[1] == "+=", (
+            "Unexpected input line [%s]" % line
+        )
+        assert items[0] in lists, (
+            "Unexpected configuration variable name " + items[0]
+        )
+
+        lists[items[0]].append(items[2])
+
+    return lists
+
+
+def generate_ftmodule(lists):
+    result = "/* This is a generated file. */\n"
+    for driver in lists["FONT_MODULES"]:
+        if driver == "sfnt":  # Special case for the sfnt 'driver'.
+            result += "FT_USE_MODULE( FT_Module_Class, sfnt_module_class )\n"
+            continue
+
+        name = {
+            "truetype": "tt",
+            "type1": "t1",
+            "cid": "t1cid",
+            "type42": "t42",
+            "winfonts": "winfnt",
+        }.get(driver, driver)
+        result += (
+            "FT_USE_MODULE( FT_Driver_ClassRec, %s_driver_class )\n" % name
+        )
+
+    for module in lists["HINTING_MODULES"]:
+        result += (
+            "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module
+        )
+
+    for module in lists["RASTER_MODULES"]:
+        names = {
+            "raster": ("ft_raster1",),
+            "smooth": ("ft_smooth",),
+            "svg": ("ft_svg",),
+            "sdf": ("ft_sdf", "ft_bitmap_sdf"),
+        }.get(module)
+        for name in names:
+            result += (
+                "FT_USE_MODULE( FT_Renderer_Class, %s_renderer_class )\n" % name
+            )
+
+    for module in lists["AUX_MODULES"]:
+        if module in ("psaux", "psnames", "otvalid", "gxvalid"):
+            result += (
+                "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module
+            )
+
+    result += "/* EOF */\n"
+    return result
+
+
+def generate_main_modules(lists):
+    return "\n".join(
+        lists["FONT_MODULES"]
+        + lists["HINTING_MODULES"]
+        + lists["RASTER_MODULES"]
+    )
+
+
+def generate_aux_modules(lists):
+    return "\n".join(lists["AUX_MODULES"])
+
+
+def generate_base_extensions(lists):
+    return "\n".join(lists["BASE_EXTENSIONS"])
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    parser.add_argument(
+        "--format",
+        required=True,
+        choices=(
+            "ftmodule.h",
+            "main-modules",
+            "aux-modules",
+            "base-extensions-list",
+        ),
+        help="Select output format.",
+    )
+
+    parser.add_argument(
+        "input",
+        metavar="CONFIGURE_RAW",
+        help="The input configure.raw file to parse.",
+    )
+
+    parser.add_argument("--output", help="Output file (default is stdout).")
+
+    args = parser.parse_args()
+    with open(args.input) as f:
+        input_data = f.read()
+
+    lists = parse_modules_cfg(input_data)
+
+    if args.format == "ftmodule.h":
+        result = generate_ftmodule(lists)
+    elif args.format == "main-modules":
+        result = generate_main_modules(lists)
+    elif args.format == "aux-modules":
+        result = generate_aux_modules(lists)
+    elif args.format == "base-extensions-list":
+        result = generate_base_extensions(lists)
+    else:
+        assert False, "Invalid output format!"
+
+    if args.output:
+        with open(args.output, "w") as f:
+            f.write(result)
+    else:
+        print(result)
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/builds/meson/process_ftoption_h.py b/builds/meson/process_ftoption_h.py
new file mode 100644
index 0000000..98daa8c
--- /dev/null
+++ b/builds/meson/process_ftoption_h.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-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.
+
+"""Toggle settings in `ftoption.h` file based on command-line arguments.
+
+This script takes an `ftoption.h` file as input and rewrites
+`#define`/`#undef` lines in it based on `--enable=CONFIG_VARNAME` or
+`--disable=CONFIG_VARNAME` arguments passed to it, where `CONFIG_VARNAME` is
+configuration variable name, such as `FT_CONFIG_OPTION_USE_LZW`, that may
+appear in the file.
+
+Note that if one of `CONFIG_VARNAME` is not found in the input file, this
+script exits with an error message listing the missing variable names.
+"""
+
+import argparse
+import os
+import re
+import sys
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    parser.add_argument(
+        "input", metavar="FTOPTION_H", help="Path to input ftoption.h file."
+    )
+
+    parser.add_argument("--output", help="Output to file instead of stdout.")
+
+    parser.add_argument(
+        "--enable",
+        action="append",
+        default=[],
+        help="Enable a given build option (e.g. FT_CONFIG_OPTION_USE_LZW).",
+    )
+
+    parser.add_argument(
+        "--disable",
+        action="append",
+        default=[],
+        help="Disable a given build option.",
+    )
+
+    args = parser.parse_args()
+
+    common_options = set(args.enable) & set(args.disable)
+    if common_options:
+        parser.error(
+            "Options cannot be both enabled and disabled: %s"
+            % sorted(common_options)
+        )
+        return 1
+
+    with open(args.input) as f:
+        input_file = f.read()
+
+    options_seen = set()
+
+    new_lines = []
+    for line in input_file.splitlines():
+        # Expected formats:
+        #   #define <CONFIG_VAR>
+        #   /* #define <CONFIG_VAR> */
+        #   #undef <CONFIG_VAR>
+        line = line.rstrip()
+        if line.startswith("/* #define ") and line.endswith(" */"):
+            option_name = line[11:-3].strip()
+            option_enabled = False
+        elif line.startswith("#define "):
+            option_name = line[8:].strip()
+            option_enabled = True
+        elif line.startswith("#undef "):
+            option_name = line[7:].strip()
+            option_enabled = False
+        else:
+            new_lines.append(line)
+            continue
+
+        options_seen.add(option_name)
+        if option_enabled and option_name in args.disable:
+            line = "#undef " + option_name
+        elif not option_enabled and option_name in args.enable:
+            line = "#define " + option_name
+        new_lines.append(line)
+
+    result = "\n".join(new_lines) + "\n"
+
+    # Sanity check that all command-line options were actually processed.
+    cmdline_options = set(args.enable) | set(args.disable)
+    assert cmdline_options.issubset(
+        options_seen
+    ), "Could not find options in input file: " + ", ".join(
+        sorted(cmdline_options - options_seen)
+    )
+
+    if args.output:
+        with open(args.output, "w") as f:
+            f.write(result)
+    else:
+        print(result)
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/builds/modules.mk b/builds/modules.mk
index 9a7a4a0..a75baaf 100644
--- a/builds/modules.mk
+++ b/builds/modules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/os2/detect.mk b/builds/os2/detect.mk
index 5a80a22..afdba74 100644
--- a/builds/os2/detect.mk
+++ b/builds/os2/detect.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/os2/os2-def.mk b/builds/os2/os2-def.mk
index 7ad1ffb..917ef2d 100644
--- a/builds/os2/os2-def.mk
+++ b/builds/os2/os2-def.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -13,11 +13,15 @@
 # fully.
 
 
-DELETE    := del
-CAT       := type
-SEP       := $(strip \ )
-BUILD_DIR := $(TOP_DIR)/builds/os2
-PLATFORM  := os2
+DELETE       := del
+CAT          := type
+SEP          := $(strip \ )
+PLATFORM_DIR := $(TOP_DIR)/builds/os2
+PLATFORM     := os2
+
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+BIN := Scripts
 
 # The executable file extension (for tools), *with* leading dot.
 #
diff --git a/builds/os2/os2-dev.mk b/builds/os2/os2-dev.mk
index 505a754..3584fb6 100644
--- a/builds/os2/os2-dev.mk
+++ b/builds/os2/os2-dev.mk
@@ -5,7 +5,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/os2/os2-gcc.mk b/builds/os2/os2-gcc.mk
index 65026b1..e17c5be 100644
--- a/builds/os2/os2-gcc.mk
+++ b/builds/os2/os2-gcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/symbian/bld.inf b/builds/symbian/bld.inf
index 9c6d8dc..6168922 100644
--- a/builds/symbian/bld.inf
+++ b/builds/symbian/bld.inf
@@ -2,7 +2,7 @@
 // FreeType 2 project for the symbian platform
 //
 
-// Copyright 2008-2018 by
+// Copyright (C) 2008-2023 by
 // David Turner, Robert Wilhelm, and Werner Lemberg.
 //
 // This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/symbian/freetype.mmp b/builds/symbian/freetype.mmp
index 4e4a041..297678e 100644
--- a/builds/symbian/freetype.mmp
+++ b/builds/symbian/freetype.mmp
@@ -2,7 +2,7 @@
 // FreeType 2 makefile for the symbian platform
 //
 
-// Copyright 2008-2018 by
+// Copyright (C) 2008-2023 by
 // David Turner, Robert Wilhelm, and Werner Lemberg.
 //
 // This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/toplevel.mk b/builds/toplevel.mk
index 7ce0ed8..a0e0c87 100644
--- a/builds/toplevel.mk
+++ b/builds/toplevel.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -103,6 +103,7 @@
   check_platform := 1
 endif
 
+
 # Include the automatic host platform detection rules when we need to
 # check the platform.
 #
@@ -112,6 +113,17 @@
 
   include $(TOP_DIR)/builds/detect.mk
 
+  # For builds directly from the git repository we need to copy files
+  # from `subprojects/dlg' to `src/dlg' and `include/dlg'.
+  #
+  ifeq ($(wildcard $(TOP_DIR)/src/dlg/dlg.*),)
+    ifeq ($(wildcard $(TOP_DIR)/subprojects/dlg/*),)
+      copy_submodule: check_out_submodule
+    endif
+
+    setup: copy_submodule
+  endif
+
   # This rule makes sense for Unix only to remove files created by a run of
   # the configure script which hasn't been successful (so that no
   # `config.mk' has been created).  It uses the built-in $(RM) command of
@@ -127,12 +139,12 @@
   ifneq ($(is_unix),)
 
     distclean:
-	  $(RM) builds/unix/config.cache
-	  $(RM) builds/unix/config.log
-	  $(RM) builds/unix/config.status
-	  $(RM) builds/unix/unix-def.mk
-	  $(RM) builds/unix/unix-cc.mk
-	  $(RM) builds/unix/freetype2.pc
+	  $(RM) $(TOP_DIR)/builds/unix/config.cache
+	  $(RM) $(TOP_DIR)/builds/unix/config.log
+	  $(RM) $(TOP_DIR)/builds/unix/config.status
+	  $(RM) $(TOP_DIR)/builds/unix/unix-def.mk
+	  $(RM) $(TOP_DIR)/builds/unix/unix-cc.mk
+	  $(RM) $(TOP_DIR)/builds/unix/freetype2.pc
 	  $(RM) nul
 
   endif # test is_unix
@@ -154,6 +166,23 @@
 endif # test check_platform
 
 
+.PHONY: check_out_submodule copy_submodule
+
+check_out_submodule:
+	$(info Checking out submodule in `subprojects/dlg')
+	git --git-dir=$(TOP_DIR) submodule init
+	git --git-dir=$(TOP_DIR) submodule update
+
+copy_submodule:
+	$(info Copying files from `subprojects/dlg' to `src/dlg' and `include/dlg')
+  ifeq ($(wildcard $(TOP_DIR)/include/dlg),)
+	mkdir $(subst /,$(SEP),$(TOP_DIR)/include/dlg)
+  endif
+	$(COPY) $(subst /,$(SEP),$(TOP_DIR)/subprojects/dlg/include/dlg/output.h $(TOP_DIR)/include/dlg)
+	$(COPY) $(subst /,$(SEP),$(TOP_DIR)/subprojects/dlg/include/dlg/dlg.h $(TOP_DIR)/include/dlg)
+	$(COPY) $(subst /,$(SEP),$(TOP_DIR)/subprojects/dlg/src/dlg/dlg.c $(TOP_DIR)/src/dlg)
+
+
 # We always need the list of modules in ftmodule.h.
 #
 all setup: $(FTMODULE_H)
@@ -191,13 +220,14 @@
 patch := $(subst |,$(space),$(work))
 patch := $(firstword $(patch))
 
-ifneq ($(findstring x0x,x$(patch)x),)
-  version := $(major).$(minor)
-  winversion := $(major)$(minor)
-else
+# ifneq ($(findstring x0x,x$(patch)x),)
+#   version := $(major).$(minor)
+#   winversion := $(major)$(minor)
+# else
   version := $(major).$(minor).$(patch)
   winversion := $(major)$(minor)$(patch)
-endif
+  version_tag := VER-$(major)-$(minor)-$(patch)
+# endif
 
 
 # This target builds the tarballs.
@@ -208,7 +238,7 @@
 dist:
 	-rm -rf tmp
 	rm -f freetype-$(version).tar.gz
-	rm -f freetype-$(version).tar.bz2
+	rm -f freetype-$(version).tar.xz
 	rm -f ft$(winversion).zip
 
 	for d in `find . -wholename '*/.git' -prune \
@@ -219,30 +249,26 @@
 
 	currdir=`pwd` ; \
 	for f in `find . -wholename '*/.git' -prune \
+	                 -o -name .gitattributes \
 	                 -o -name .gitignore \
+	                 -o -name .gitlab-ci.yml \
+	                 -o -name .gitmodules \
 	                 -o -name .mailmap \
 	                 -o -type d \
 	                 -o -print` ; do \
 	  ln -s $$currdir/$$f tmp/$$f ; \
 	done
 
-	@# Prevent generation of .pyc files.  Python follows (soft) links if
-	@# the link's directory is write protected, so we have temporarily
-	@# disable write access here too.
-	chmod -w src/tools/docmaker
-
 	cd tmp ; \
 	$(MAKE) devel ; \
 	$(MAKE) do-dist
 
-	chmod +w src/tools/docmaker
-
 	mv tmp freetype-$(version)
 
 	tar -H ustar -chf - freetype-$(version) \
 	| gzip -9 -c > freetype-$(version).tar.gz
 	tar -H ustar -chf - freetype-$(version) \
-	| bzip2 -c > freetype-$(version).tar.bz2
+	| xz -c > freetype-$(version).tar.xz
 
 	@# Use CR/LF for zip files.
 	zip -lr9 ft$(winversion).zip freetype-$(version)
@@ -257,6 +283,10 @@
 CONFIG_GUESS = ~/git/config/config.guess
 CONFIG_SUB   = ~/git/config/config.sub
 
+# We also use this repository to access the gnulib script that converts git
+# commit messages to a ChangeLog file.
+CHANGELOG_SCRIPT = ~/git/config/gitlog-to-changelog
+
 
 # Don't say `make do-dist'.  Always use `make dist' instead.
 #
@@ -264,14 +294,29 @@
 
 do-dist: distclean refdoc
 	@# Without removing the files, `autoconf' and friends follow links.
-	rm -f builds/unix/aclocal.m4
-	rm -f builds/unix/configure.ac
-	rm -f builds/unix/configure
+	rm -f $(TOP_DIR)/builds/unix/aclocal.m4
+	rm -f $(TOP_DIR)/builds/unix/configure.ac
+	rm -f $(TOP_DIR)/builds/unix/configure
 
 	sh autogen.sh
-	rm -rf builds/unix/autom4te.cache
+	rm -rf $(TOP_DIR)/builds/unix/autom4te.cache
 
-	cp $(CONFIG_GUESS) builds/unix
-	cp $(CONFIG_SUB) builds/unix
+	cp $(CONFIG_GUESS) $(TOP_DIR)/builds/unix
+	cp $(CONFIG_SUB) $(TOP_DIR)/builds/unix
+
+	@# Generate `ChangeLog' file with commits since release 2.11.0
+	@# (when we stopped creating this file manually).
+	$(CHANGELOG_SCRIPT) \
+	  --format='%B%n' \
+	  --no-cluster \
+	  -- VER-2-11-0..$(version_tag) \
+	> ChangeLog
+
+	@# Remove intermediate files created by the `refdoc' target.
+	rm -rf $(TOP_DIR)/docs/markdown
+	rm -f $(TOP_DIR)/docs/mkdocs.yml
+
+	@# Remove more stuff related to git.
+	rm -rf (TOP_DIR)/subprojects/dlg
 
 # EOF
diff --git a/builds/unix/LICENSE_GPLv2_WITH_AUTOCONF_EXCEPTION.TXT b/builds/unix/LICENSE_GPLv2_WITH_AUTOCONF_EXCEPTION.TXT
new file mode 100644
index 0000000..ddd4e8f
--- /dev/null
+++ b/builds/unix/LICENSE_GPLv2_WITH_AUTOCONF_EXCEPTION.TXT
@@ -0,0 +1,307 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+Autoconf Exception
+
+As a special exception, the Free Software Foundation gives unlimited
+permission to copy, distribute and modify the configure scripts that are the
+output of Autoconf. You need not follow the terms of the GNU General Public
+License when using or distributing such scripts, even though portions of the
+text of Autoconf appear in them. The GNU General Public License (GPL) does
+govern all other use of the material that constitutes the Autoconf program.
+
+Certain portions of the Autoconf source text are designed to be copied (in
+certain cases, depending on the input) into the output of Autoconf. We call
+these the "data" portions. The rest of the Autoconf source text consists of
+comments plus executable code that decides which of the data portions to
+output in any given case. We call these comments and executable code the "non-
+data" portions. Autoconf never copies any of the non-data portions into its
+output.
+
+This special exception to the GPL applies to versions of Autoconf released by
+the Free Software Foundation. When you make and distribute a modified version
+of Autoconf, you may extend this special exception to the GPL to apply to your
+modified version as well, *unless* your modified version has the potential to
+copy into its output some of the text that was the non-data portion of the
+version that you started with. (In other words, unless your change moves or
+copies text from the non-data portions to the data portions.) If your
+modification has such potential, you must delete any notice of this special
+exception to the GPL from your modified version.
+
+                     END OF TERMS AND CONDITIONS
+
diff --git a/builds/unix/LICENSE_GPLv3_WITH_AUTOCONF_EXCEPTION.TXT b/builds/unix/LICENSE_GPLv3_WITH_AUTOCONF_EXCEPTION.TXT
new file mode 100644
index 0000000..b37355e
--- /dev/null
+++ b/builds/unix/LICENSE_GPLv3_WITH_AUTOCONF_EXCEPTION.TXT
@@ -0,0 +1,663 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+AUTOCONF CONFIGURE SCRIPT EXCEPTION
+
+Version 3.0, 18 August 2009
+
+Copyright © 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+This Exception is an additional permission under section 7 of the GNU General
+Public License, version 3 ("GPLv3"). It applies to a given file that bears a
+notice placed by the copyright holder of the file stating that the file is
+governed by GPLv3 along with this Exception.
+
+The purpose of this Exception is to allow distribution of Autoconf&apos;s
+typical output under terms of the recipient&apos;s choice (including
+proprietary).
+
+0. Definitions.   
+"Covered Code" is the source or object code of a version of Autoconf that is a
+covered work under this License.
+
+"Normally Copied Code" for a version of Autoconf means all parts of its
+Covered Code which that version can copy from its code (i.e., not from its
+input file) into its minimally verbose, non-debugging and non-tracing output.
+
+"Ineligible Code" is Covered Code that is not Normally Copied Code.
+
+1. Grant of Additional Permission.   
+You have permission to propagate output of Autoconf, even if such propagation
+would otherwise violate the terms of GPLv3. However, if by modifying Autoconf
+you cause any Ineligible Code of the version you received to become Normally
+Copied Code of your modified version, then you void this Exception for the
+resulting covered work. If you convey that resulting covered work, you must
+remove this Exception in accordance with the second paragraph of Section 7 of
+GPLv3.
+
+2. No Weakening of Autoconf Copyleft.   
+The availability of this Exception does not imply any general presumption that
+third-party software is unaffected by the copyleft requirements of the license
+of Autoconf.
diff --git a/builds/unix/ax_compare_version.m4 b/builds/unix/ax_compare_version.m4
new file mode 100644
index 0000000..ffb4997
--- /dev/null
+++ b/builds/unix/ax_compare_version.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+#   This macro compares two version strings. Due to the various number of
+#   minor-version numbers that can exist, and the fact that string
+#   comparisons are not compatible with numeric comparisons, this is not
+#   necessarily trivial to do in a autoconf script. This macro makes doing
+#   these comparisons easy.
+#
+#   The six basic comparisons are available, as well as checking equality
+#   limited to a certain number of minor-version levels.
+#
+#   The operator OP determines what type of comparison to do, and can be one
+#   of:
+#
+#    eq  - equal (test A == B)
+#    ne  - not equal (test A != B)
+#    le  - less than or equal (test A <= B)
+#    ge  - greater than or equal (test A >= B)
+#    lt  - less than (test A < B)
+#    gt  - greater than (test A > B)
+#
+#   Additionally, the eq and ne operator can have a number after it to limit
+#   the test to that number of minor versions.
+#
+#    eq0 - equal up to the length of the shorter version
+#    ne0 - not equal up to the length of the shorter version
+#    eqN - equal up to N sub-version levels
+#    neN - not equal up to N sub-version levels
+#
+#   When the condition is true, shell commands ACTION-IF-TRUE are run,
+#   otherwise shell commands ACTION-IF-FALSE are run. The environment
+#   variable 'ax_compare_version' is always set to either 'true' or 'false'
+#   as well.
+#
+#   Examples:
+#
+#     AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+#     AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+#   would both be true.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+#     AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+#   would both be false.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+#   would be true because it is only comparing two minor versions.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+#   would be true because it is only comparing the lesser number of minor
+#   versions of the two values.
+#
+#   Note: The characters that separate the version numbers do not matter. An
+#   empty string is the same as version 0. OP is evaluated by autoconf, not
+#   configure, so must be a string, not a variable.
+#
+#   The author would like to acknowledge Guido Draheim whose advice about
+#   the m4_case and m4_ifvaln functions make this macro only include the
+#   portions necessary to perform the specific comparison specified by the
+#   OP argument in the final configure script.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 13
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # Used to indicate true or false condition
+  ax_compare_version=false
+
+  # Convert the two version strings to be compared into a format that
+  # allows a simple string comparison.  The end result is that a version
+  # string of the form 1.12.5-r617 will be converted to the form
+  # 0001001200050617.  In other words, each number is zero padded to four
+  # digits, and non digits are removed.
+  AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+  A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+                     -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/[[^0-9]]//g'`
+
+  AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+  B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+                     -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/[[^0-9]]//g'`
+
+  dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+  dnl # then the first line is used to determine if the condition is true.
+  dnl # The sed right after the echo is to remove any indented white space.
+  m4_case(m4_tolower($2),
+  [lt],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+  ],
+  [gt],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+  ],
+  [le],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+  ],
+  [ge],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+  ],[
+    dnl Split the operator from the subversion count if present.
+    m4_bmatch(m4_substr($2,2),
+    [0],[
+      # A count of zero means use the length of the shorter version.
+      # Determine the number of characters in A and B.
+      ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+      ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+      # Set A to no more than B's length and B to no more than A's length.
+      A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+      B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+    ],
+    [[0-9]+],[
+      # A count greater than zero means use only that many subversions
+      A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+      B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+    ],
+    [.+],[
+      AC_WARNING(
+        [invalid OP numeric parameter: $2])
+    ],[])
+
+    # Pad zeros at end of numbers to make same length.
+    ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+    B="$B`echo $A | sed 's/./0/g'`"
+    A="$ax_compare_version_tmp_A"
+
+    # Check for equality or inequality as necessary.
+    m4_case(m4_tolower(m4_substr($2,0,2)),
+    [eq],[
+      test "x$A" = "x$B" && ax_compare_version=true
+    ],
+    [ne],[
+      test "x$A" != "x$B" && ax_compare_version=true
+    ],[
+      AC_WARNING([invalid OP parameter: $2])
+    ])
+  ])
+
+  AS_VAR_POPDEF([A])dnl
+  AS_VAR_POPDEF([B])dnl
+
+  dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+  if test "$ax_compare_version" = "true" ; then
+    m4_ifvaln([$4],[$4],[:])dnl
+    m4_ifvaln([$5],[else $5])dnl
+  fi
+]) dnl AX_COMPARE_VERSION
diff --git a/builds/unix/ax_prog_python_version.m4 b/builds/unix/ax_prog_python_version.m4
new file mode 100644
index 0000000..dbc3dbf
--- /dev/null
+++ b/builds/unix/ax_prog_python_version.m4
@@ -0,0 +1,66 @@
+# ===========================================================================
+#  https://www.gnu.org/software/autoconf-archive/ax_prog_python_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PROG_PYTHON_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+#   Makes sure that python supports the version indicated. If true the shell
+#   commands in ACTION-IF-TRUE are executed. If not the shell commands in
+#   ACTION-IF-FALSE are run. Note if $PYTHON is not set (for example by
+#   running AC_CHECK_PROG or AC_PATH_PROG) the macro will fail.
+#
+#   Example:
+#
+#     AC_PATH_PROG([PYTHON],[python])
+#     AX_PROG_PYTHON_VERSION([2.4.4],[ ... ],[ ... ])
+#
+#   This will check to make sure that the python you have supports at least
+#   version 2.4.4.
+#
+#   NOTE: This macro uses the $PYTHON variable to perform the check.
+#   AX_WITH_PYTHON can be used to set that variable prior to running this
+#   macro. The $PYTHON_VERSION variable will be valorized with the detected
+#   version.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 12
+
+AC_DEFUN([AX_PROG_PYTHON_VERSION],[
+    AC_REQUIRE([AC_PROG_SED])
+    AC_REQUIRE([AC_PROG_GREP])
+
+    AS_IF([test -n "$PYTHON"],[
+        ax_python_version="$1"
+
+        AC_MSG_CHECKING([for python version])
+        changequote(<<,>>)
+        python_version=`$PYTHON -V 2>&1 | $GREP "^Python " | $SED -e 's/^.* \([0-9]*\.[0-9]*\.[0-9]*\)/\1/'`
+        changequote([,])
+        AC_MSG_RESULT($python_version)
+
+	AC_SUBST([PYTHON_VERSION],[$python_version])
+
+        AX_COMPARE_VERSION([$ax_python_version],[le],[$python_version],[
+	    :
+            $2
+        ],[
+	    :
+            $3
+        ])
+    ],[
+        AC_MSG_WARN([could not find the python interpreter])
+        $3
+    ])
+])
diff --git a/builds/unix/ax_pthread.m4 b/builds/unix/ax_pthread.m4
new file mode 100644
index 0000000..e5858e5
--- /dev/null
+++ b/builds/unix/ax_pthread.m4
@@ -0,0 +1,522 @@
+# ===========================================================================
+#        https://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
+#   needed for multi-threaded programs (defaults to the value of CC
+#   respectively CXX otherwise). (This is necessary on e.g. AIX to use the
+#   special cc_r/CC_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also to link with them as well. For example, you might link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#   $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threaded programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#     CXX="$PTHREAD_CXX"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
+#   that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#   Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 30
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_TARGET])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_SED])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on Tru64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+        ax_pthread_save_CC="$CC"
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
+        AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
+        AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test "x$ax_pthread_ok" = "xno"; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        CC="$ax_pthread_save_CC"
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items with a "," contain both
+# C compiler flags (before ",") and linker flags (after ","). Other items
+# starting with a "-" are C compiler flags, and remaining items are
+# library names, except for "none" which indicates that we try without
+# any flags at all, and "pthread-config" which is a program returning
+# the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+#           (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads and
+#      -D_REENTRANT too), HP C (must be checked before -lpthread, which
+#      is present but should not be used directly; and before -mthreads,
+#      because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case $target_os in
+
+        freebsd*)
+
+        # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+        # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+        ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+        ;;
+
+        hpux*)
+
+        # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+        # multi-threading and also sets -lpthread."
+
+        ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+        ;;
+
+        openedition*)
+
+        # IBM z/OS requires a feature-test macro to be defined in order to
+        # enable POSIX threads at all, so give the user a hint if this is
+        # not set. (We don't define these ourselves, as they can affect
+        # other portions of the system API in unpredictable ways.)
+
+        AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
+            [
+#            if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+             AX_PTHREAD_ZOS_MISSING
+#            endif
+            ],
+            [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
+        ;;
+
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed. (N.B.: The stubs are missing
+        # pthread_cleanup_push, or rather a function called by this macro,
+        # so we could check for that, but who knows whether they'll stub
+        # that too in a future libc.)  So we'll check first for the
+        # standard Solaris way of linking pthreads (-mt -lpthread).
+
+        ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
+        ;;
+esac
+
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+    [ax_cv_PTHREAD_CLANG],
+    [ax_cv_PTHREAD_CLANG=no
+     # Note that Autoconf sets GCC=yes for Clang as well as GCC
+     if test "x$GCC" = "xyes"; then
+        AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+            [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+#            if defined(__clang__) && defined(__llvm__)
+             AX_PTHREAD_CC_IS_CLANG
+#            endif
+            ],
+            [ax_cv_PTHREAD_CLANG=yes])
+     fi
+    ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+# Note that for GCC and Clang -pthread generally implies -lpthread,
+# except when -nostdlib is passed.
+# This is problematic using libtool to build C++ shared libraries with pthread:
+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
+# To solve this, first try -pthread together with -lpthread for GCC
+
+AS_IF([test "x$GCC" = "xyes"],
+      [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
+
+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
+
+AS_IF([test "x$ax_pthread_clang" = "xyes"],
+      [ax_pthread_flags="-pthread,-lpthread -pthread"])
+
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $target_os in
+        darwin* | hpux* | linux* | osf* | solaris*)
+        ax_pthread_check_macro="_REENTRANT"
+        ;;
+
+        aix*)
+        ax_pthread_check_macro="_THREAD_SAFE"
+        ;;
+
+        *)
+        ax_pthread_check_macro="--"
+        ;;
+esac
+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
+      [ax_pthread_check_cond=0],
+      [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
+
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+        case $ax_pthread_try_flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                *,*)
+                PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
+                PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
+                AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+                PTHREAD_CFLAGS="$ax_pthread_try_flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+                AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+                PTHREAD_LIBS="-l$ax_pthread_try_flag"
+                ;;
+        esac
+
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+#                       if $ax_pthread_check_cond
+#                        error "$ax_pthread_check_macro must be defined"
+#                       endif
+                        static void *some_global = NULL;
+                        static void routine(void *a)
+                          {
+                             /* To avoid any unused-parameter or
+                                unused-but-set-parameter warning.  */
+                             some_global = a;
+                          }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+            [ax_pthread_ok=yes],
+            [])
+
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+
+        AC_MSG_RESULT([$ax_pthread_ok])
+        AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+        # Clang takes -pthread; it has never supported any other flag
+
+        # (Note 1: This will need to be revisited if a system that Clang
+        # supports has POSIX threads in a separate library.  This tends not
+        # to be the way of modern systems, but it's conceivable.)
+
+        # (Note 2: On some systems, notably Darwin, -pthread is not needed
+        # to get POSIX threads support; the API is always present and
+        # active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
+        # -pthread does define _REENTRANT, and while the Darwin headers
+        # ignore this macro, third-party headers might not.)
+
+        # However, older versions of Clang make a point of warning the user
+        # that, in an invocation where only linking and no compilation is
+        # taking place, the -pthread option has no effect ("argument unused
+        # during compilation").  They expect -pthread to be passed in only
+        # when source code is being compiled.
+        #
+        # Problem is, this is at odds with the way Automake and most other
+        # C build frameworks function, which is that the same flags used in
+        # compilation (CFLAGS) are also used in linking.  Many systems
+        # supported by AX_PTHREAD require exactly this for POSIX threads
+        # support, and in fact it is often not straightforward to specify a
+        # flag that is used only in the compilation phase and not in
+        # linking.  Such a scenario is extremely rare in practice.
+        #
+        # Even though use of the -pthread flag in linking would only print
+        # a warning, this can be a nuisance for well-run software projects
+        # that build with -Werror.  So if the active version of Clang has
+        # this misfeature, we search for an option to squash it.
+
+        AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
+            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
+            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+             # Create an alternate version of $ac_link that compiles and
+             # links in two steps (.c -> .o, .o -> exe) instead of one
+             # (.c -> exe), because the warning occurs only in the second
+             # step
+             ax_pthread_save_ac_link="$ac_link"
+             ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+             ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
+             ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+             ax_pthread_save_CFLAGS="$CFLAGS"
+             for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+                AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
+                CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+                ac_link="$ax_pthread_save_ac_link"
+                AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+                    [ac_link="$ax_pthread_2step_ac_link"
+                     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+                         [break])
+                    ])
+             done
+             ac_link="$ax_pthread_save_ac_link"
+             CFLAGS="$ax_pthread_save_CFLAGS"
+             AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
+             ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+            ])
+
+        case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+                no | unknown) ;;
+                *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+        esac
+
+fi # $ax_pthread_clang = yes
+
+
+
+# Various other checks:
+if test "x$ax_pthread_ok" = "xyes"; then
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_CACHE_CHECK([for joinable pthread attribute],
+            [ax_cv_PTHREAD_JOINABLE_ATTR],
+            [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+             for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+                 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                                                 [int attr = $ax_pthread_attr; return attr /* ; */])],
+                                [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
+                                [])
+             done
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+               test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+               test "x$ax_pthread_joinable_attr_defined" != "xyes"],
+              [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
+                                  [$ax_cv_PTHREAD_JOINABLE_ATTR],
+                                  [Define to necessary symbol if this constant
+                                   uses a non-standard name on your system.])
+               ax_pthread_joinable_attr_defined=yes
+              ])
+
+        AC_CACHE_CHECK([whether more special flags are required for pthreads],
+            [ax_cv_PTHREAD_SPECIAL_FLAGS],
+            [ax_cv_PTHREAD_SPECIAL_FLAGS=no
+             case $target_os in
+             solaris*)
+             ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+             ;;
+             esac
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+               test "x$ax_pthread_special_flags_added" != "xyes"],
+              [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+               ax_pthread_special_flags_added=yes])
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            [ax_cv_PTHREAD_PRIO_INHERIT],
+            [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                             [[int i = PTHREAD_PRIO_INHERIT;
+                                               return i;]])],
+                            [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                            [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+               test "x$ax_pthread_prio_inherit_defined" != "xyes"],
+              [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
+               ax_pthread_prio_inherit_defined=yes
+              ])
+
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != "xyes"; then
+            case $target_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                    [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                    [#handle absolute path differently from PATH based program lookup
+                     AS_CASE(["x$CC"],
+                         [x/*],
+                         [
+			   AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
+			   AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
+			 ],
+                         [
+			   AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
+			   AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
+			 ]
+                     )
+                    ])
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+AC_SUBST([PTHREAD_CXX])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test "x$ax_pthread_ok" = "xyes"; then
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+        :
+else
+        ax_pthread_ok=no
+        $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw
index f18bb3d..8e98283 100644
--- a/builds/unix/configure.raw
+++ b/builds/unix/configure.raw
@@ -2,7 +2,7 @@
 #
 # Process this file with autoconf to produce a configure script.
 #
-# Copyright 2001-2018 by
+# Copyright (C) 2001-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -12,12 +12,12 @@
 # fully.
 
 AC_INIT([FreeType], [@VERSION@], [freetype@nongnu.org], [freetype])
-AC_CONFIG_SRCDIR([ftconfig.in])
+AC_CONFIG_SRCDIR([ftconfig.h.in])
 
 
 # Don't forget to update `docs/VERSIONS.TXT'!
 
-version_info='22:1:16'
+version_info='25:0:19'
 AC_SUBST([version_info])
 ft_version=`echo $version_info | tr : .`
 AC_SUBST([ft_version])
@@ -37,7 +37,7 @@
 PKG_PROG_PKG_CONFIG([0.24])
 
 LT_INIT(win32-dll)
-LT_PROG_RC
+AC_CHECK_HEADER([windows.h], [LT_PROG_RC])
 
 
 # checks for native programs to generate building tool
@@ -50,7 +50,7 @@
 
   AC_MSG_CHECKING([for suffix of native executables])
   rm -f a.* b.* a_out.exe conftest.*
-  echo > conftest.c "int main() { return 0;}"
+  echo > conftest.c "int main(void) { return 0;}"
   ${CC_BUILD} conftest.c || AC_MSG_ERROR([native C compiler is not working])
   rm -f conftest.c
   if test -x a.out -o -x b.out -o -x conftest; then
@@ -97,85 +97,12 @@
 
 # checks for header files
 
-AC_HEADER_STDC
 AC_CHECK_HEADERS([fcntl.h unistd.h])
 
 
 # checks for typedefs, structures, and compiler characteristics
 
 AC_C_CONST
-AC_CHECK_SIZEOF([int])
-AC_CHECK_SIZEOF([long])
-AC_TYPE_LONG_LONG_INT
-
-
-# check whether cpp computation of size of int and long in ftconfig.in works
-
-AC_MSG_CHECKING([whether cpp computation of bit length in ftconfig.in works])
-orig_CPPFLAGS="${CPPFLAGS}"
-CPPFLAGS="-I${srcdir} -I. -I${srcdir}/../../include/freetype/config ${CPPFLAGS}"
-
-ac_clean_files=
-if test ! -f ft2build.h; then
-  ac_clean_files=ft2build.h
-  touch ft2build.h
-fi
-
-cat > conftest.c <<\_ACEOF
-#include <limits.h>
-#define FT_CONFIG_OPTIONS_H "ftoption.h"
-#define FT_CONFIG_STANDARD_LIBRARY_H "ftstdlib.h"
-#define FT_UINT_MAX  UINT_MAX
-#define FT_ULONG_MAX ULONG_MAX
-#include "ftconfig.in"
-_ACEOF
-echo >> conftest.c "#if FT_SIZEOF_INT == "${ac_cv_sizeof_int}
-echo >> conftest.c "ac_cpp_ft_sizeof_int="${ac_cv_sizeof_int}
-echo >> conftest.c "#endif"
-echo >> conftest.c "#if FT_SIZEOF_LONG == "${ac_cv_sizeof_long}
-echo >> conftest.c "ac_cpp_ft_sizeof_long="${ac_cv_sizeof_long}
-echo >> conftest.c "#endif"
-
-${CPP} ${CPPFLAGS} conftest.c | ${GREP} ac_cpp_ft > conftest.sh
-eval `cat conftest.sh`
-rm -f conftest.* $ac_clean_files
-
-if test x != "x${ac_cpp_ft_sizeof_int}" \
-   -a x != x"${ac_cpp_ft_sizeof_long}"; then
-  unset ft_use_autoconf_sizeof_types
-else
-  ft_use_autoconf_sizeof_types=yes
-fi
-
-AC_ARG_ENABLE(biarch-config,
-[  --enable-biarch-config  install biarch ftconfig.h to support multiple
-                          architectures by single file], [], [])
-
-case :${ft_use_autoconf_sizeof_types}:${enable_biarch_config}: in
-  :yes:yes:)
-    AC_MSG_RESULT([broken but use it])
-    unset ft_use_autoconf_sizeof_types
-    ;;
-  ::no:)
-    AC_MSG_RESULT([works but ignore it])
-    ft_use_autoconf_sizeof_types=yes
-    ;;
-  ::yes: | :::)
-    AC_MSG_RESULT([yes])
-    unset ft_use_autoconf_sizeof_types
-    ;;
-  *)
-    AC_MSG_RESULT([no])
-    ft_use_autoconf_sizeof_types=yes
-    ;;
-esac
-
-if test x"${ft_use_autoconf_sizeof_types}" = xyes; then
-  AC_DEFINE([FT_USE_AUTOCONF_SIZEOF_TYPES], [],
-            [Define if autoconf sizeof types should be used.])
-fi
-
-CPPFLAGS="${orig_CPPFLAGS}"
 
 AC_ARG_ENABLE([freetype-config],
   AS_HELP_STRING([--enable-freetype-config], [install freetype-config]),
@@ -192,53 +119,56 @@
 AC_SYS_LARGEFILE
 
 # Here we check whether we can use our mmap file component.
+#
+# Note that `ftsystem.c` for Windows has its own mmap-like implementation
+# not covered by `AC_FUNC_MMAP` and/or `FT_UNMAP_PARAM`.
 
 AC_ARG_ENABLE([mmap],
   AS_HELP_STRING([--disable-mmap],
                  [do not check mmap() and do not use]),
-  [enable_mmap="no"],[enable_mmap="yes"])
+  [enable_mmap="no"], [enable_mmap="yes"])
 if test "x${enable_mmap}" != "xno"; then
-  AC_FUNC_MMAP
-fi
-if test "x${enable_mmap}" = "xno" \
-   -o "$ac_cv_func_mmap_fixed_mapped" != "yes"; then
-  FTSYS_SRC='$(BASE_DIR)/ftsystem.c'
-else
-  FTSYS_SRC='$(BUILD_DIR)/ftsystem.c'
+  case "$host" in
+  *-*-mingw*)
+    AC_MSG_CHECKING([for working mmap])
+    AC_MSG_RESULT([using MapViewOfFile in Windows])
+    FTSYS_SRC='$(TOP_DIR)/builds/windows/ftsystem.c'
+    ;;
+  *)
+    AC_FUNC_MMAP
+    if test "$ac_cv_func_mmap_fixed_mapped" = "yes"; then
+      FTSYS_SRC='$(PLATFORM_DIR)/ftsystem.c'
 
-  AC_CHECK_DECLS([munmap],
-    [],
-    [],
-    [
+      AC_CHECK_DECLS([munmap],
+        [],
+        [],
+        [
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <sys/mman.h>
 
-    ])
+        ])
 
-  FT_MUNMAP_PARAM
+      FT_MUNMAP_PARAM
+    fi
+    ;;
+  esac
+fi
+
+if test -z "$FTSYS_SRC"; then
+  FTSYS_SRC='$(BASE_DIR)/ftsystem.c'
 fi
 AC_SUBST([FTSYS_SRC])
 
-AC_CHECK_FUNCS([memcpy memmove])
-
 
 # get compiler flags right
 #
-#   We try to make the compiler work for C89-strict source.  Even if the
-#   C compiler is gcc and C89 flags are available, some system headers
-#   (e.g., Android Bionic libc) are broken in C89 mode.  We have to check
-#   whether the compilation finishes successfully.
-#
-#   Due to bugs in mingwrt 4.0.3 we don't use `-ansi' for MinGW.
-#
-#   To avoid zillions of
-#
-#     ISO C90 does not support 'long long'
-#
-#   warnings, we disable `-pedantic' for gcc version < 4.6.
+#   We try to make the compiler work for C99-strict source.  Even if the
+#   C compiler is gcc and C99 flags are available, some system headers
+#   might be broken in C99 mode.  We have to check whether compilation
+#   finishes successfully.
 #
 if test "x$GCC" = xyes; then
   XX_CFLAGS="-Wall"
@@ -250,23 +180,11 @@
     XX_ANSIFLAGS="-pedantic"
     ;;
   *)
-    GCC_VERSION=`$CC -dumpversion`
-    GCC_MAJOR=`echo "$GCC_VERSION" | sed 's/\([[^.]][[^.]]*\).*/\1/'`
-    GCC_MINOR=`echo "$GCC_VERSION" | sed 's/[[^.]][[^.]]*.\([[^.]][[^.]]*\).*/\1/'`
-
-    XX_PEDANTIC=-pedantic
-    if test $GCC_MAJOR -lt 4; then
-      XX_PEDANTIC=
-    else
-      if test $GCC_MAJOR -eq 4 -a $GCC_MINOR -lt 6; then
-        XX_PEDANTIC=
-      fi
-    fi
-
     XX_ANSIFLAGS=""
-    for a in $XX_PEDANTIC -ansi
+
+    for a in "-pedantic" "-std=c99"
     do
-      AC_MSG_CHECKING([gcc compiler flag ${a} to assure ANSI C works correctly])
+      AC_MSG_CHECKING([$CC compiler flag ${a} to assure ANSI C99 works correctly])
       orig_CFLAGS="${CFLAGS}"
       CFLAGS="${CFLAGS} ${XX_ANSIFLAGS} ${a}"
       AC_COMPILE_IFELSE([
@@ -315,7 +233,7 @@
 AC_MSG_CHECKING([for -fvisibility=hidden compiler flag])
 orig_CFLAGS="${CFLAGS}"
 CFLAGS="${CFLAGS} -fvisibility=hidden"
-AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
                [found_visibility_flag=yes
                 AC_MSG_RESULT(yes)],
                [CFLAGS="${orig_CFLAGS}"
@@ -325,7 +243,7 @@
   AC_MSG_CHECKING([for -xldscope=hidden compiler flag])
   orig_CFLAGS="${CFLAGS}"
   CFLAGS="${CFLAGS} -xldscope=hidden"
-  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
                  [found_visibility_flag=yes
                   AC_MSG_RESULT(yes)],
                  [CFLAGS="${orig_CFLAGS}"
@@ -396,6 +314,12 @@
   AC_MSG_ERROR([external zlib support requested but library not found])
 fi
 
+SYSTEM_ZLIB=
+if test "$have_zlib" != no; then
+  SYSTEM_ZLIB=yes
+fi
+AC_SUBST([SYSTEM_ZLIB])
+
 
 # check for system libbz2
 
@@ -478,17 +402,13 @@
       libpng_libsstaticconf="$LIBPNG_LIBS"
       have_libpng="yes (LIBPNG_CFLAGS and LIBPNG_LIBS)"
     else
-      # fall back to config script.
-      AC_MSG_CHECKING([for libpng-config])
-      if which libpng-config > /dev/null 2>&1; then
+      # fall back to config script
+      AC_CHECK_PROG(have_libpng, [libpng-config], [yes (libpng-config)], [no])
+      if test "$have_libpng" != no; then
         LIBPNG_CFLAGS=`libpng-config --cflags`
         LIBPNG_LIBS=`libpng-config --ldflags`
         libpng_libspriv=`libpng-config --static --ldflags`
         libpng_libsstaticconf="$libpng_libspriv"
-        have_libpng="yes (libpng-config)"
-        AC_MSG_RESULT([yes])
-      else
-        AC_MSG_RESULT([no])
       fi
     fi
   fi
@@ -508,7 +428,7 @@
 
 have_harfbuzz=no
 if test x"$with_harfbuzz" = xyes -o x"$with_harfbuzz" = xauto; then
-  harfbuzz_pkg="harfbuzz >= 1.3.0"
+  harfbuzz_pkg="harfbuzz >= 2.0.0"
   have_harfbuzz_pkg=no
 
   if test x"$HARFBUZZ_CFLAGS" = x -a x"$HARFBUZZ_LIBS" = x; then
@@ -543,19 +463,92 @@
 fi
 
 
-# check for librt
-#
-# We need `clock_gettime' for the `ftbench' demo program.
-#
-# The code is modeled after gnulib's file `clock_time.m4', ignoring
-# very old Solaris systems.
+# check for system libbrotlidec
 
+AC_ARG_WITH([brotli],
+  [AS_HELP_STRING([--with-brotli=@<:@yes|no|auto@:>@],
+                  [support decompression of WOFF2 streams @<:@default=auto@:>@])],
+  [], [with_brotli=auto])
+
+have_brotli=no
+if test x"$with_brotli" = xyes -o x"$with_brotli" = xauto; then
+  brotli_pkg="libbrotlidec"
+  have_brotli_pkg=no
+
+  if test x"$BROTLI_CFLAGS" = x -a x"$BROTLI_LIBS" = x; then
+    PKG_CHECK_EXISTS([$brotli_pkg], [have_brotli_pkg=yes])
+  fi
+  PKG_CHECK_MODULES([BROTLI], [$brotli_pkg],
+                    [have_brotli="yes (pkg-config)"], [:])
+
+  if test $have_brotli_pkg = yes; then
+    # we have libbrotlidec.pc
+    brotli_reqpriv="$brotli_pkg"
+    brotli_libspriv=
+    brotli_libsstaticconf=`$PKG_CONFIG --static --libs "$brotli_pkg"`
+  else
+    brotli_reqpriv=
+
+    if test "$have_brotli" != no; then
+      # BROTLI_CFLAGS and BROTLI_LIBS are set by the user
+      brotli_libspriv="$BROTLI_LIBS"
+      brotli_libsstaticconf="$BROTLI_LIBS"
+      have_brotli="yes (BROTLI_CFLAGS and BROTLI_LIBS)"
+    else
+      # since Brotli is quite a new library we don't fall back to a
+      # different test
+      :
+    fi
+  fi
+fi
+
+if test x"$with_brotli" = xyes -a "$have_brotli" = no; then
+  AC_MSG_ERROR([brotli support requested but library not found])
+fi
+
+
+# Checks for the demo programs.
+#
+# FreeType doesn't need this.  However, since the demo program repository
+# doesn't come with a `configure` script of its own, we integrate the tests
+# here for simplicity.
+
+# We need `clock_gettime` from 'librt' for the `ftbench` demo program.
+#
+# The code is modeled after gnulib's file `clock_time.m4`, ignoring
+# very old Solaris systems.
 LIB_CLOCK_GETTIME=
 AC_SEARCH_LIBS([clock_gettime],
                [rt],
                [test "$ac_cv_search_clock_gettime" = "none required" \
                 || LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
-AC_SUBST([LIB_CLOCK_GETTIME])
+
+FT_DEMO_CFLAGS=""
+FT_DEMO_LDFLAGS="$LIB_CLOCK_GETTIME"
+
+# 'librsvg' is needed to demonstrate SVG support.
+AC_ARG_WITH([librsvg],
+  [AS_HELP_STRING([--with-librsvg=@<:@yes|no|auto@:>@],
+                  [support OpenType SVG fonts in FreeType demo programs @<:@default=auto@:>@])],
+  [], [with_librsvg=auto])
+
+have_librsvg=no
+if test x"$with_librsvg" = xyes -o x"$with_librsvg" = xauto; then
+  PKG_CHECK_MODULES([LIBRSVG], [librsvg-2.0 >= 2.46.0],
+                    [have_librsvg="yes (pkg-config)"], [:])
+
+  if test "$have_librsvg" != no; then
+    FT_DEMO_CFLAGS="$FT_DEMO_CFLAGS $LIBRSVG_CFLAGS -DHAVE_LIBRSVG"
+    FT_DEMO_LDFLAGS="$FT_DEMO_LDFLAGS $LIBRSVG_LIBS"
+  fi
+fi
+
+if test x"$with_librsvg" = xyes -a "$have_librsvg" = no; then
+  AC_MSG_ERROR([librsvg support requested but library not found])
+fi
+
+AC_SUBST([FT_DEMO_CFLAGS])
+AC_SUBST([FT_DEMO_LDFLAGS])
 
 
 # Some options handling SDKs/archs in CFLAGS should be copied
@@ -968,38 +961,68 @@
     ;;
 esac
 
+# Check for pthreads
 
-# entries in Requires.private are separated by commas;
-REQUIRES_PRIVATE="$zlib_reqpriv,     \
-                  $bzip2_reqpriv,    \
-                  $libpng_reqpriv,   \
-                  $harfbuzz_reqpriv"
-# beautify
-REQUIRES_PRIVATE=`echo "$REQUIRES_PRIVATE" \
-                  | sed -e 's/^  *//'      \
-                        -e 's/  *$//'      \
-                        -e 's/, */,/g'     \
-                        -e 's/,,*/,/g'     \
-                        -e 's/^,*//'       \
-                        -e 's/,*$//'       \
-                        -e 's/,/, /g'`
+AX_PTHREAD([have_pthread=yes], [have_pthread=no])
 
-LIBS_PRIVATE="$zlib_libspriv     \
-              $bzip2_libspriv    \
-              $libpng_libspriv   \
-              $harfbuzz_libspriv \
-              $ft2_extra_libs"
+# Check for Python and docwriter
+
+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], [])
+
+  if test "x$have_py3" = "xyes"; then
+    PIP="$PYTHON -m $PIP"
+    AC_MSG_CHECKING([for `docwriter' Python module])
+    $PYTHON -m docwriter -h > /dev/null 2>&1
+    if test "x$?" = "x0"; then
+      have_docwriter=yes
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+  fi
+fi
+
+
+# entries in Requires.private are separated by commas
+PKGCONFIG_REQUIRES_PRIVATE="$zlib_reqpriv,     \
+                            $bzip2_reqpriv,    \
+                            $libpng_reqpriv,   \
+                            $harfbuzz_reqpriv, \
+                            $brotli_reqpriv"
 # beautify
-LIBS_PRIVATE=`echo "$LIBS_PRIVATE"  \
-              | sed -e 's/^  *//'   \
-                    -e 's/  *$//'   \
-                    -e 's/  */ /g'`
+PKGCONFIG_REQUIRES_PRIVATE=`echo "$PKGCONFIG_REQUIRES_PRIVATE" \
+                            | sed -e 's/^  *//'      \
+                                  -e 's/  *$//'      \
+                                  -e 's/, */,/g'     \
+                                  -e 's/,,*/,/g'     \
+                                  -e 's/^,*//'       \
+                                  -e 's/,*$//'       \
+                                  -e 's/,/, /g'`
+
+PKGCONFIG_LIBS_PRIVATE="$zlib_libspriv     \
+                        $bzip2_libspriv    \
+                        $libpng_libspriv   \
+                        $harfbuzz_libspriv \
+                        $brotli_libspriv   \
+                        $ft2_extra_libs"
+# beautify
+PKGCONFIG_LIBS_PRIVATE=`echo "$PKGCONFIG_LIBS_PRIVATE"  \
+                        | sed -e 's/^  *//'   \
+                              -e 's/  *$//'   \
+                              -e 's/  */ /g'`
 
 LIBSSTATIC_CONFIG="-lfreetype               \
                    $zlib_libsstaticconf     \
                    $bzip2_libsstaticconf    \
                    $libpng_libsstaticconf   \
                    $harfbuzz_libsstaticconf \
+                   $brotli_libsstaticconf   \
                    $ft2_extra_libs"
 # remove -L/usr/lib and -L/usr/lib64 since `freetype-config' adds them later
 # on if necessary; also beautify
@@ -1010,10 +1033,28 @@
                          -e 's/  *$//'                \
                          -e 's/  */ /g'`
 
+# If FreeType gets installed with `--disable-shared', don't use
+# 'private' fields.  `pkg-config' only looks into `.pc' files and is
+# completely agnostic to whether shared libraries are actually present
+# or not.  As a consequence, the user had to specify `--static' while
+# calling `pkg-config', which configure scripts are normally not
+# prepared for.
+
+PKGCONFIG_REQUIRES=
+PKGCONFIG_LIBS='-L${libdir} -lfreetype'
+
+if test $enable_shared = "no"; then
+  PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES $PKGCONFIG_REQUIRES_PRIVATE"
+  PKGCONFIG_REQUIRES_PRIVATE=
+  PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE"
+  PKGCONFIG_LIBS_PRIVATE=
+fi
 
 AC_SUBST([ftmac_c])
-AC_SUBST([REQUIRES_PRIVATE])
-AC_SUBST([LIBS_PRIVATE])
+AC_SUBST([PKGCONFIG_REQUIRES])
+AC_SUBST([PKGCONFIG_LIBS])
+AC_SUBST([PKGCONFIG_REQUIRES_PRIVATE])
+AC_SUBST([PKGCONFIG_LIBS_PRIVATE])
 AC_SUBST([LIBSSTATIC_CONFIG])
 
 AC_SUBST([hardcode_libdir_flag_spec])
@@ -1064,6 +1105,18 @@
 else
   ftoption_unset FT_CONFIG_OPTION_USE_HARFBUZZ
 fi
+if test "$have_brotli" != no; then
+  CFLAGS="$CFLAGS $BROTLI_CFLAGS"
+  LDFLAGS="$LDFLAGS $BROTLI_LIBS"
+  ftoption_set FT_CONFIG_OPTION_USE_BROTLI
+else
+  ftoption_unset FT_CONFIG_OPTION_USE_BROTLI
+fi
+
+if test "$have_pthread" != no; then
+  CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+  LDFLAGS="$LDFLAGS $PTHREAD_CFLAGS $PTHREAD_LIBS"
+fi
 
 AC_SUBST([CFLAGS])
 AC_SUBST([LDFLAGS])
@@ -1081,15 +1134,7 @@
    rm ftoption.tmp],
   [FTOPTION_H_SED="$FTOPTION_H_SED"])
 
-# configuration file -- stay in 8.3 limit
-#
-# since #undef doesn't survive in configuration header files we replace
-# `/undef' with `#undef' after creating the output file
-
-AC_CONFIG_HEADERS([ftconfig.h:ftconfig.in],
-  [mv ftconfig.h ftconfig.tmp
-   sed 's|/undef|#undef|' < ftconfig.tmp > ftconfig.h
-   rm ftconfig.tmp])
+AC_CONFIG_HEADERS([ftconfig.h])
 
 # create the Unix-specific sub-Makefiles `builds/unix/unix-def.mk'
 # and `builds/unix/unix-cc.mk' that will be used by the build system
@@ -1097,10 +1142,6 @@
 AC_CONFIG_FILES([unix-cc.mk:unix-cc.in
                  unix-def.mk:unix-def.in])
 
-# re-generate the Jamfile to use libtool now
-#
-# AC_CONFIG_FILES([../../Jamfile:../../Jamfile.in])
-
 AC_OUTPUT
 
 AC_MSG_NOTICE([
@@ -1110,6 +1151,29 @@
   bzip2:         $have_bzip2
   libpng:        $have_libpng
   harfbuzz:      $have_harfbuzz
+  brotli:        $have_brotli
+  pthread:       $have_pthread
 ])
 
+# Warn if docwriter is not installed
+
+if test $have_docwriter = no; then
+  AC_MSG_WARN([
+  `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.
+  ])
+fi
+
+# Warn if pthread is not available
+
+if test $have_pthread = no; then
+  AC_MSG_WARN([
+  `FT_DEBUG_LOGGING' will not work since the `pthread' library is not
+  available.  This warning can be safely ignored if you don't plan to use
+  this configuration macro.
+  ])
+fi
+
 # end of configure.raw
diff --git a/builds/unix/detect.mk b/builds/unix/detect.mk
index 5f9b9e2..6b87013 100644
--- a/builds/unix/detect.mk
+++ b/builds/unix/detect.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/unix/freetype-config.in b/builds/unix/freetype-config.in
index 2d5b90d..5856112 100644
--- a/builds/unix/freetype-config.in
+++ b/builds/unix/freetype-config.in
@@ -1,6 +1,6 @@
 #! /bin/sh
 #
-# Copyright 2000-2018 by
+# Copyright (C) 2000-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/unix/freetype2.in b/builds/unix/freetype2.in
index 2d759ec..fe389f4 100644
--- a/builds/unix/freetype2.in
+++ b/builds/unix/freetype2.in
@@ -7,8 +7,8 @@
 URL: https://freetype.org
 Description: A free, high-quality, and portable font engine.
 Version: %ft_version%
-Requires:
-Requires.private: %REQUIRES_PRIVATE%
-Libs: -L${libdir} -lfreetype
-Libs.private: %LIBS_PRIVATE%
+Requires: %PKGCONFIG_REQUIRES%
+Requires.private: %PKGCONFIG_REQUIRES_PRIVATE%
+Libs: %PKGCONFIG_LIBS%
+Libs.private: %PKGCONFIG_LIBS_PRIVATE%
 Cflags: -I${includedir}/freetype2
diff --git a/builds/unix/freetype2.m4 b/builds/unix/freetype2.m4
index af2e659..09ead43 100644
--- a/builds/unix/freetype2.m4
+++ b/builds/unix/freetype2.m4
@@ -1,7 +1,7 @@
 # Configure paths for FreeType2
-# Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+# Marcelo Magallon 2001-10-26, based on `gtk.m4` by Owen Taylor
 #
-# Copyright 2001-2018 by
+# Copyright (C) 2001-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -15,32 +15,32 @@
 # generated by Autoconf, under the same distribution terms as the rest of
 # that program.
 #
-# serial 4
+# serial 7
 
 # AC_CHECK_FT2([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
 # Test for FreeType 2, and define FT2_CFLAGS and FT2_LIBS.
-# MINIMUM-VERSION is what libtool reports; the default is `7.0.1' (this is
+# MINIMUM-VERSION is what libtool reports; the default is '7.0.1' (this is
 # FreeType 2.0.4).
 #
+# To make this code work with older autoconf versions, `AS_HELP_STRING` is
+# not quoted.
+#
 AC_DEFUN([AC_CHECK_FT2],
   [# Get the cflags and libraries from the freetype-config script
    #
    AC_ARG_WITH([ft-prefix],
-     dnl don't quote AS_HELP_STRING!
      AS_HELP_STRING([--with-ft-prefix=PREFIX],
                     [Prefix where FreeType is installed (optional)]),
      [ft_config_prefix="$withval"],
      [ft_config_prefix=""])
 
    AC_ARG_WITH([ft-exec-prefix],
-     dnl don't quote AS_HELP_STRING!
      AS_HELP_STRING([--with-ft-exec-prefix=PREFIX],
                     [Exec prefix where FreeType is installed (optional)]),
      [ft_config_exec_prefix="$withval"],
      [ft_config_exec_prefix=""])
 
    AC_ARG_ENABLE([freetypetest],
-     dnl don't quote AS_HELP_STRING!
      AS_HELP_STRING([--disable-freetypetest],
                     [Do not try to compile and run a test FreeType program]),
      [],
@@ -116,12 +116,12 @@
              AC_LANG_SOURCE([[
 
 #include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 int
-main()
+main(void)
 {
   FT_Library library;
   FT_Error  error;
diff --git a/builds/unix/ft-munmap.m4 b/builds/unix/ft-munmap.m4
index 00eda49..a0fcf35 100644
--- a/builds/unix/ft-munmap.m4
+++ b/builds/unix/ft-munmap.m4
@@ -1,6 +1,6 @@
 ## FreeType specific autoconf tests
 #
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/unix/ftconfig.h.in b/builds/unix/ftconfig.h.in
new file mode 100644
index 0000000..3dac561
--- /dev/null
+++ b/builds/unix/ftconfig.h.in
@@ -0,0 +1,52 @@
+/****************************************************************************
+ *
+ * ftconfig.h.in
+ *
+ *   UNIX-specific configuration file (specification only).
+ *
+ * Copyright (C) 1996-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.
+ *
+ */
+
+
+  /**************************************************************************
+   *
+   * This header file contains a number of macro definitions that are used by
+   * the rest of the engine.  Most of the macros here are automatically
+   * determined at compile time, and you should not need to change it to port
+   * FreeType, except to compile the library with a non-ANSI compiler.
+   *
+   * Note however that if some specific modifications are needed, we advise
+   * you to place a modified copy in your build directory.
+   *
+   * The build directory is usually `builds/<system>`, and contains
+   * system-specific files that are always included first when building the
+   * library.
+   *
+   */
+
+#ifndef FTCONFIG_H_
+#define FTCONFIG_H_
+
+#include <ft2build.h>
+#include FT_CONFIG_OPTIONS_H
+#include FT_CONFIG_STANDARD_LIBRARY_H
+
+#undef HAVE_UNISTD_H
+#undef HAVE_FCNTL_H
+
+#include <freetype/config/integer-types.h>
+#include <freetype/config/public-macros.h>
+#include <freetype/config/mac-support.h>
+
+#endif /* FTCONFIG_H_ */
+
+
+/* END */
diff --git a/builds/unix/ftconfig.in b/builds/unix/ftconfig.in
deleted file mode 100644
index cdb7f22..0000000
--- a/builds/unix/ftconfig.in
+++ /dev/null
@@ -1,604 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftconfig.in                                                            */
-/*                                                                         */
-/*    UNIX-specific configuration file (specification only).               */
-/*                                                                         */
-/*  Copyright 1996-2018 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This header file contains a number of macro definitions that are used */
-  /* by the rest of the engine.  Most of the macros here are automatically */
-  /* determined at compile time, and you should not need to change it to   */
-  /* port FreeType, except to compile the library with a non-ANSI          */
-  /* compiler.                                                             */
-  /*                                                                       */
-  /* Note however that if some specific modifications are needed, we       */
-  /* advise you to place a modified copy in your build directory.          */
-  /*                                                                       */
-  /* The build directory is usually `builds/<system>', and contains        */
-  /* system-specific files that are always included first when building    */
-  /* the library.                                                          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef FTCONFIG_H_
-#define FTCONFIG_H_
-
-#include <ft2build.h>
-#include FT_CONFIG_OPTIONS_H
-#include FT_CONFIG_STANDARD_LIBRARY_H
-
-
-FT_BEGIN_HEADER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
-  /*                                                                       */
-  /* These macros can be toggled to suit a specific system.  The current   */
-  /* ones are defaults used to compile FreeType in an ANSI C environment   */
-  /* (16bit compilers are also supported).  Copy this file to your own     */
-  /* `builds/<system>' directory, and edit it to port the engine.          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#undef HAVE_UNISTD_H
-#undef HAVE_FCNTL_H
-#undef HAVE_STDINT_H
-
-
-  /* There are systems (like the Texas Instruments 'C54x) where a `char' */
-  /* has 16 bits.  ANSI C says that sizeof(char) is always 1.  Since an  */
-  /* `int' has 16 bits also for this system, sizeof(int) gives 1 which   */
-  /* is probably unexpected.                                             */
-  /*                                                                     */
-  /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a      */
-  /* `char' type.                                                        */
-
-#ifndef FT_CHAR_BIT
-#define FT_CHAR_BIT  CHAR_BIT
-#endif
-
-
-#undef FT_USE_AUTOCONF_SIZEOF_TYPES
-#ifdef FT_USE_AUTOCONF_SIZEOF_TYPES
-
-#undef SIZEOF_INT
-#undef SIZEOF_LONG
-#define FT_SIZEOF_INT  SIZEOF_INT
-#define FT_SIZEOF_LONG SIZEOF_LONG
-
-#else /* !FT_USE_AUTOCONF_SIZEOF_TYPES */
-
-  /* Following cpp computation of the bit length of int and long */
-  /* is copied from default include/freetype/config/ftconfig.h.  */
-  /* If any improvement is required for this file, it should be  */
-  /* applied to the original header file for the builders that   */
-  /* do not use configure script.                                */
-
-  /* The size of an `int' type.  */
-#if                                 FT_UINT_MAX == 0xFFFFUL
-#define FT_SIZEOF_INT  (16 / FT_CHAR_BIT)
-#elif                               FT_UINT_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_INT  (32 / FT_CHAR_BIT)
-#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_INT  (64 / FT_CHAR_BIT)
-#else
-#error "Unsupported size of `int' type!"
-#endif
-
-  /* The size of a `long' type.  A five-byte `long' (as used e.g. on the */
-  /* DM642) is recognized but avoided.                                   */
-#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  (64 / FT_CHAR_BIT)
-#else
-#error "Unsupported size of `long' type!"
-#endif
-
-#endif /* !FT_USE_AUTOCONF_SIZEOF_TYPES */
-
-
-  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */
-  /* used -- this is only used to get rid of unpleasant compiler warnings */
-#ifndef FT_UNUSED
-#define FT_UNUSED( arg )  ( (arg) = (arg) )
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                     AUTOMATIC CONFIGURATION MACROS                    */
-  /*                                                                       */
-  /* These macros are computed from the ones defined above.  Don't touch   */
-  /* their definition, unless you know precisely what you are doing.  No   */
-  /* porter should need to mess with them.                                 */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Mac support                                                           */
-  /*                                                                       */
-  /*   This is the only necessary change, so it is defined here instead    */
-  /*   providing a new configuration file.                                 */
-  /*                                                                       */
-#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
-  /* no Carbon frameworks for 64bit 10.4.x */
-  /* AvailabilityMacros.h is available since Mac OS X 10.2,        */
-  /* so guess the system version by maximum errno before inclusion */
-#include <errno.h>
-#ifdef ECANCELED /* defined since 10.2 */
-#include "AvailabilityMacros.h"
-#endif
-#if defined( __LP64__ ) && \
-    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
-/undef FT_MACINTOSH
-#endif
-
-#elif defined( __SC__ ) || defined( __MRC__ )
-  /* Classic MacOS compilers */
-#include "ConditionalMacros.h"
-#if TARGET_OS_MAC
-#define FT_MACINTOSH 1
-#endif
-
-#endif
-
-
-  /* Fix compiler warning with sgi compiler */
-#if defined( __sgi ) && !defined( __GNUC__ )
-#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
-#pragma set woff 3505
-#endif
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Section>                                                             */
-  /*    basic_types                                                        */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int16                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit signed integer type.                         */
-  /*                                                                       */
-  typedef signed short  FT_Int16;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt16                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit unsigned integer type.                       */
-  /*                                                                       */
-  typedef unsigned short  FT_UInt16;
-
-  /* */
-
-
-  /* this #if 0 ... #endif clause is for documentation purposes */
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int32                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 32bit signed integer type.  The size depends on    */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef signed XXX  FT_Int32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt32                                                          */
-  /*                                                                       */
-  /*    A typedef for a 32bit unsigned integer type.  The size depends on  */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int64                                                           */
-  /*                                                                       */
-  /*    A typedef for a 64bit signed integer type.  The size depends on    */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef signed XXX  FT_Int64;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt64                                                          */
-  /*                                                                       */
-  /*    A typedef for a 64bit unsigned integer type.  The size depends on  */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt64;
-
-  /* */
-
-#endif
-
-#if FT_SIZEOF_INT == 4
-
-  typedef signed int      FT_Int32;
-  typedef unsigned int    FT_UInt32;
-
-#elif FT_SIZEOF_LONG == 4
-
-  typedef signed long     FT_Int32;
-  typedef unsigned long   FT_UInt32;
-
-#else
-#error "no 32bit type found -- please check your configuration files"
-#endif
-
-
-  /* look up an integer type that is at least 32 bits */
-#if FT_SIZEOF_INT >= 4
-
-  typedef int            FT_Fast;
-  typedef unsigned int   FT_UFast;
-
-#elif FT_SIZEOF_LONG >= 4
-
-  typedef long           FT_Fast;
-  typedef unsigned long  FT_UFast;
-
-#endif
-
-
-  /* determine whether we have a 64-bit int type  */
-  /* (mostly for environments without `autoconf') */
-#if FT_SIZEOF_LONG == 8
-
-  /* FT_LONG64 must be defined if a 64-bit type is available */
-#define FT_LONG64
-#define FT_INT64   long
-#define FT_UINT64  unsigned long
-
-  /* we handle the LLP64 scheme separately for GCC and clang, */
-  /* suppressing the `long long' warning                      */
-#elif ( FT_SIZEOF_LONG == 4 )       && \
-      defined( HAVE_LONG_LONG_INT ) && \
-      defined( __GNUC__ )
-#pragma GCC diagnostic ignored "-Wlong-long"
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A 64-bit data type may create compilation problems if you compile     */
-  /* in strict ANSI mode.  To avoid them, we disable other 64-bit data     */
-  /* types if __STDC__ is defined.  You can however ignore this rule       */
-  /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro.     */
-  /*                                                                       */
-#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
-
-#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __BORLANDC__ )  /* Borland C++ */
-
-  /* XXXX: We should probably check the value of __BORLANDC__ in order */
-  /*       to test the compiler version.                               */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __WATCOMC__ )   /* Watcom C++ */
-
-  /* Watcom doesn't provide 64-bit data types */
-
-#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( __GNUC__ )
-
-  /* GCC provides the `long long' type */
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#endif /* __STDC_VERSION__ >= 199901L */
-
-#endif /* FT_SIZEOF_LONG == 8 */
-
-#ifdef FT_LONG64
-  typedef FT_INT64   FT_Int64;
-  typedef FT_UINT64  FT_UInt64;
-#endif
-
-
-#ifdef _WIN64
-  /* only 64bit Windows uses the LLP64 data model, i.e., */
-  /* 32bit integers, 64bit pointers                      */
-#define FT_UINT_TO_POINTER( x ) (void*)(unsigned __int64)(x)
-#else
-#define FT_UINT_TO_POINTER( x ) (void*)(unsigned long)(x)
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* miscellaneous                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define FT_BEGIN_STMNT  do {
-#define FT_END_STMNT    } while ( 0 )
-#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
-
-
-  /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
-      ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
-        defined( __IBM__TYPEOF__ ) )                                 || \
-      ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  ( __typeof__ ( type ) )
-#else
-#define FT_TYPEOF( type )  /* empty */
-#endif
-
-
-  /* Use FT_LOCAL and FT_LOCAL_DEF to declare and define, respectively, */
-  /* a function that gets used only within the scope of a module.       */
-  /* Normally, both the header and source code files for such a         */
-  /* function are within a single module directory.                     */
-  /*                                                                    */
-  /* Intra-module arrays should be tagged with FT_LOCAL_ARRAY and       */
-  /* FT_LOCAL_ARRAY_DEF.                                                */
-  /*                                                                    */
-#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
-
-#define FT_LOCAL( x )      static  x
-#define FT_LOCAL_DEF( x )  static  x
-
-#else
-
-#ifdef __cplusplus
-#define FT_LOCAL( x )      extern "C"  x
-#define FT_LOCAL_DEF( x )  extern "C"  x
-#else
-#define FT_LOCAL( x )      extern  x
-#define FT_LOCAL_DEF( x )  x
-#endif
-
-#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
-
-#define FT_LOCAL_ARRAY( x )      extern const  x
-#define FT_LOCAL_ARRAY_DEF( x )  const  x
-
-
-  /* Use FT_BASE and FT_BASE_DEF to declare and define, respectively, */
-  /* functions that are used in more than a single module.  In the    */
-  /* current setup this implies that the declaration is in a header   */
-  /* file in the `include/freetype/internal' directory, and the       */
-  /* function body is in a file in `src/base'.                        */
-  /*                                                                  */
-#ifndef FT_BASE
-
-#ifdef __cplusplus
-#define FT_BASE( x )  extern "C"  x
-#else
-#define FT_BASE( x )  extern  x
-#endif
-
-#endif /* !FT_BASE */
-
-
-#ifndef FT_BASE_DEF
-
-#ifdef __cplusplus
-#define FT_BASE_DEF( x )  x
-#else
-#define FT_BASE_DEF( x )  x
-#endif
-
-#endif /* !FT_BASE_DEF */
-
-
-  /*   When compiling FreeType as a DLL or DSO with hidden visibility      */
-  /*   some systems/compilers need a special attribute in front OR after   */
-  /*   the return type of function declarations.                           */
-  /*                                                                       */
-  /*   Two macros are used within the FreeType source code to define       */
-  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
-  /*                                                                       */
-  /*     FT_EXPORT( return_type )                                          */
-  /*                                                                       */
-  /*       is used in a function declaration, as in                        */
-  /*                                                                       */
-  /*         FT_EXPORT( FT_Error )                                         */
-  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */
-  /*                                                                       */
-  /*                                                                       */
-  /*     FT_EXPORT_DEF( return_type )                                      */
-  /*                                                                       */
-  /*       is used in a function definition, as in                         */
-  /*                                                                       */
-  /*         FT_EXPORT_DEF( FT_Error )                                     */
-  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */
-  /*         {                                                             */
-  /*           ... some code ...                                           */
-  /*           return FT_Err_Ok;                                           */
-  /*         }                                                             */
-  /*                                                                       */
-  /*   You can provide your own implementation of FT_EXPORT and            */
-  /*   FT_EXPORT_DEF here if you want.                                     */
-  /*                                                                       */
-  /*   To export a variable, use FT_EXPORT_VAR.                            */
-  /*                                                                       */
-#ifndef FT_EXPORT
-
-#ifdef FT2_BUILD_LIBRARY
-
-#if defined( _WIN32 ) && defined( DLL_EXPORT )
-#define FT_EXPORT( x )  __declspec( dllexport )  x
-#elif defined( __GNUC__ ) && __GNUC__ >= 4
-#define FT_EXPORT( x )  __attribute__(( visibility( "default" ) ))  x
-#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
-#define FT_EXPORT( x )  __global  x
-#elif defined( __cplusplus )
-#define FT_EXPORT( x )  extern "C"  x
-#else
-#define FT_EXPORT( x )  extern  x
-#endif
-
-#else
-
-#if defined( _WIN32 ) && defined( DLL_IMPORT )
-#define FT_EXPORT( x )  __declspec( dllimport )  x
-#elif defined( __cplusplus )
-#define FT_EXPORT( x )  extern "C"  x
-#else
-#define FT_EXPORT( x )  extern  x
-#endif
-
-#endif
-
-#endif /* !FT_EXPORT */
-
-
-#ifndef FT_EXPORT_DEF
-
-#ifdef __cplusplus
-#define FT_EXPORT_DEF( x )  extern "C"  x
-#else
-#define FT_EXPORT_DEF( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_DEF */
-
-
-#ifndef FT_EXPORT_VAR
-
-#ifdef __cplusplus
-#define FT_EXPORT_VAR( x )  extern "C"  x
-#else
-#define FT_EXPORT_VAR( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_VAR */
-
-  /* The following macros are needed to compile the library with a   */
-  /* C++ compiler and with 16bit compilers.                          */
-  /*                                                                 */
-
-  /* This is special.  Within C++, you must specify `extern "C"' for */
-  /* functions which are used via function pointers, and you also    */
-  /* must do that for structures which contain function pointers to  */
-  /* assure C linkage -- it's not possible to have (local) anonymous */
-  /* functions which are accessed by (global) function pointers.     */
-  /*                                                                 */
-  /*                                                                 */
-  /* FT_CALLBACK_DEF is used to _define_ a callback function,        */
-  /* located in the same source code file as the structure that uses */
-  /* it.                                                             */
-  /*                                                                 */
-  /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare   */
-  /* and define a callback function, respectively, in a similar way  */
-  /* as FT_BASE and FT_BASE_DEF work.                                */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
-  /* contains pointers to callback functions.                        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
-  /* that contains pointers to callback functions.                   */
-  /*                                                                 */
-  /*                                                                 */
-  /* Some 16bit compilers have to redefine these macros to insert    */
-  /* the infamous `_cdecl' or `__fastcall' declarations.             */
-  /*                                                                 */
-#ifndef FT_CALLBACK_DEF
-#ifdef __cplusplus
-#define FT_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_CALLBACK_DEF( x )  static  x
-#endif
-#endif /* FT_CALLBACK_DEF */
-
-#ifndef FT_BASE_CALLBACK
-#ifdef __cplusplus
-#define FT_BASE_CALLBACK( x )      extern "C"  x
-#define FT_BASE_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_BASE_CALLBACK( x )      extern  x
-#define FT_BASE_CALLBACK_DEF( x )  x
-#endif
-#endif /* FT_BASE_CALLBACK */
-
-#ifndef FT_CALLBACK_TABLE
-#ifdef __cplusplus
-#define FT_CALLBACK_TABLE      extern "C"
-#define FT_CALLBACK_TABLE_DEF  extern "C"
-#else
-#define FT_CALLBACK_TABLE      extern
-#define FT_CALLBACK_TABLE_DEF  /* nothing */
-#endif
-#endif /* FT_CALLBACK_TABLE */
-
-
-FT_END_HEADER
-
-
-#endif /* FTCONFIG_H_ */
-
-
-/* END */
diff --git a/builds/unix/ftsystem.c b/builds/unix/ftsystem.c
index 8fdbeb0..5927215 100644
--- a/builds/unix/ftsystem.c
+++ b/builds/unix/ftsystem.c
@@ -1,29 +1,29 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftsystem.c                                                             */
-/*                                                                         */
-/*    Unix-specific FreeType low-level system interface (body).            */
-/*                                                                         */
-/*  Copyright 1996-2018 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.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * ftsystem.c
+ *
+ *   Unix-specific FreeType low-level system interface (body).
+ *
+ * Copyright (C) 1996-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 <ft2build.h>
   /* we use our special ftconfig.h file, not the standard one */
-#include <ftconfig.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_SYSTEM_H
-#include FT_ERRORS_H
-#include FT_TYPES_H
-#include FT_INTERNAL_STREAM_H
+#include FT_CONFIG_CONFIG_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftsystem.h>
+#include <freetype/fterrors.h>
+#include <freetype/fttypes.h>
+#include <freetype/internal/ftstream.h>
 
   /* memory-mapping includes and definitions */
 #ifdef HAVE_UNISTD_H
@@ -70,29 +70,40 @@
 #include <errno.h>
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /*                       MEMORY MANAGEMENT INTERFACE                     */
-  /*                                                                       */
-  /*************************************************************************/
+  /**************************************************************************
+   *
+   *                      MEMORY MANAGEMENT INTERFACE
+   *
+   */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    ft_alloc                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The memory allocation function.                                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    memory :: A pointer to the memory object.                          */
-  /*                                                                       */
-  /*    size   :: The requested size in bytes.                             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The address of newly allocated block.                              */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * It is not necessary to do any error checking for the
+   * allocation-related functions.  This will be done by the higher level
+   * routines like ft_mem_alloc() or ft_mem_realloc().
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_alloc
+   *
+   * @Description:
+   *   The memory allocation function.
+   *
+   * @Input:
+   *   memory ::
+   *     A pointer to the memory object.
+   *
+   *   size ::
+   *     The requested size in bytes.
+   *
+   * @Return:
+   *   The address of newly allocated block.
+   */
   FT_CALLBACK_DEF( void* )
   ft_alloc( FT_Memory  memory,
             long       size )
@@ -103,26 +114,30 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    ft_realloc                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The memory reallocation function.                                  */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    memory   :: A pointer to the memory object.                        */
-  /*                                                                       */
-  /*    cur_size :: The current size of the allocated memory block.        */
-  /*                                                                       */
-  /*    new_size :: The newly requested size in bytes.                     */
-  /*                                                                       */
-  /*    block    :: The current address of the block in memory.            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The address of the reallocated memory block.                       */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_realloc
+   *
+   * @Description:
+   *   The memory reallocation function.
+   *
+   * @Input:
+   *   memory ::
+   *     A pointer to the memory object.
+   *
+   *   cur_size ::
+   *     The current size of the allocated memory block.
+   *
+   *   new_size ::
+   *     The newly requested size in bytes.
+   *
+   *   block ::
+   *     The current address of the block in memory.
+   *
+   * @Return:
+   *   The address of the reallocated memory block.
+   */
   FT_CALLBACK_DEF( void* )
   ft_realloc( FT_Memory  memory,
               long       cur_size,
@@ -136,19 +151,21 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    ft_free                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The memory release function.                                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    memory :: A pointer to the memory object.                          */
-  /*                                                                       */
-  /*    block  :: The address of block in memory to be freed.              */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_free
+   *
+   * @Description:
+   *   The memory release function.
+   *
+   * @Input:
+   *   memory ::
+   *     A pointer to the memory object.
+   *
+   *   block ::
+   *     The address of block in memory to be freed.
+   */
   FT_CALLBACK_DEF( void )
   ft_free( FT_Memory  memory,
            void*      block )
@@ -159,38 +176,38 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /*                     RESOURCE MANAGEMENT INTERFACE                     */
-  /*                                                                       */
-  /*************************************************************************/
+  /**************************************************************************
+   *
+   *                    RESOURCE MANAGEMENT INTERFACE
+   *
+   */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_io
+#define FT_COMPONENT  io
 
   /* We use the macro STREAM_FILE for convenience to extract the       */
   /* system-specific stream handle from a given FreeType stream object */
 #define STREAM_FILE( stream )  ( (FILE*)stream->descriptor.pointer )
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    ft_close_stream_by_munmap                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The function to close a stream which is opened by mmap.            */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    stream :: A pointer to the stream object.                          */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_close_stream_by_munmap
+   *
+   * @Description:
+   *   The function to close a stream which is opened by mmap.
+   *
+   * @Input:
+   *   stream :: A pointer to the stream object.
+   */
   FT_CALLBACK_DEF( void )
   ft_close_stream_by_munmap( FT_Stream  stream )
   {
@@ -198,29 +215,29 @@
 
     stream->descriptor.pointer = NULL;
     stream->size               = 0;
-    stream->base               = 0;
+    stream->base               = NULL;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    ft_close_stream_by_free                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The function to close a stream which is created by ft_alloc.       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    stream :: A pointer to the stream object.                          */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_close_stream_by_free
+   *
+   * @Description:
+   *   The function to close a stream which is created by ft_alloc.
+   *
+   * @Input:
+   *   stream :: A pointer to the stream object.
+   */
   FT_CALLBACK_DEF( void )
   ft_close_stream_by_free( FT_Stream  stream )
   {
-    ft_free( NULL, stream->descriptor.pointer );
+    ft_free( stream->memory, stream->descriptor.pointer );
 
     stream->descriptor.pointer = NULL;
     stream->size               = 0;
-    stream->base               = 0;
+    stream->base               = NULL;
   }
 
 
@@ -296,8 +313,7 @@
                                           file,
                                           0 );
 
-    /* on some RTOS, mmap might return 0 */
-    if ( (long)stream->base != -1 && stream->base != NULL )
+    if ( stream->base != MAP_FAILED )
       stream->close = ft_close_stream_by_munmap;
     else
     {
@@ -307,7 +323,7 @@
       FT_ERROR(( "FT_Stream_Open:" ));
       FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
 
-      stream->base = (unsigned char*)ft_alloc( NULL, stream->size );
+      stream->base = (unsigned char*)ft_alloc( stream->memory, stream->size );
 
       if ( !stream->base )
       {
@@ -348,16 +364,16 @@
     stream->descriptor.pointer = stream->base;
     stream->pathname.pointer   = (char*)filepathname;
 
-    stream->read = 0;
+    stream->read = NULL;
 
     FT_TRACE1(( "FT_Stream_Open:" ));
-    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
+    FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
                 filepathname, stream->size ));
 
     return FT_Err_Ok;
 
   Fail_Read:
-    ft_free( NULL, stream->base );
+    ft_free( stream->memory, stream->base );
 
   Fail_Map:
     close( file );
@@ -392,7 +408,7 @@
     memory = (FT_Memory)malloc( sizeof ( *memory ) );
     if ( memory )
     {
-      memory->user    = 0;
+      memory->user    = NULL;
       memory->alloc   = ft_alloc;
       memory->realloc = ft_realloc;
       memory->free    = ft_free;
diff --git a/builds/unix/install.mk b/builds/unix/install.mk
index c08c3b7..2f1729b 100644
--- a/builds/unix/install.mk
+++ b/builds/unix/install.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -62,7 +62,7 @@
           $(DESTDIR)$(includedir)/freetype2/freetype/config/ftmodule.h
 	$(INSTALL_DATA) $(OBJ_BUILD)/ftoption.h                        \
           $(DESTDIR)$(includedir)/freetype2/freetype/config/ftoption.h
-	$(INSTALL_SCRIPT) -m 644 $(BUILD_DIR)/freetype2.m4             \
+	$(INSTALL_SCRIPT) -m 644 $(PLATFORM_DIR)/freetype2.m4          \
           $(DESTDIR)$(datadir)/aclocal/freetype2.m4
 	$(INSTALL_SCRIPT) -m 644 $(OBJ_BUILD)/freetype2.pc             \
           $(DESTDIR)$(libdir)/pkgconfig/freetype2.pc
diff --git a/builds/unix/unix-cc.in b/builds/unix/unix-cc.in
index 5675866..802016d 100644
--- a/builds/unix/unix-cc.in
+++ b/builds/unix/unix-cc.in
@@ -2,7 +2,7 @@
 # FreeType 2 template for Unix-specific compiler definitions
 #
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -14,7 +14,7 @@
 
 CC           := @CC@
 COMPILER_SEP := $(SEP)
-FT_LIBTOOL_DIR ?= $(BUILD_DIR)
+FT_LIBTOOL_DIR ?= $(PLATFORM_DIR)
 
 LIBTOOL := $(FT_LIBTOOL_DIR)/libtool
 
@@ -73,13 +73,16 @@
 #
 #   These should concern: debug output, optimization & warnings.
 #
-#   Use the ANSIFLAGS variable to define the compiler flags used to enfore
+#   Use the ANSIFLAGS variable to define the compiler flags used to enforce
 #   ANSI compliance.
 #
-#   We use our own FreeType configuration file.
+#   We use our own FreeType configuration files overriding defaults.
 #
 CPPFLAGS := @CPPFLAGS@
-CFLAGS   := -c @XX_CFLAGS@ @CFLAGS@ -DFT_CONFIG_CONFIG_H="<ftconfig.h>"
+CFLAGS   := -c @XX_CFLAGS@ @CFLAGS@ \
+            $DFT_CONFIG_CONFIG_H="<ftconfig.h>" \
+            $DFT_CONFIG_MODULES_H="<ftmodule.h>" \
+            $DFT_CONFIG_OPTIONS_H="<ftoption.h>"
 
 # ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
 #
@@ -87,8 +90,12 @@
 
 # C compiler to use -- we use libtool!
 #
-CCraw := $(CC)
-CC    := $(LIBTOOL) --mode=compile $(CCraw)
+# CC might be set on the command line; we store this value in `CCraw'.
+# Consequently, we use the `override' directive to ensure that the
+# libtool call is always prepended.
+#
+CCraw       := $(CC)
+override CC := $(LIBTOOL) --mode=compile $(CCraw)
 
 # Resource compiler to use on Cygwin/MinGW, usually windres.
 #
@@ -99,9 +106,7 @@
 
 # Linker flags.
 #
-LDFLAGS           := @LDFLAGS@
-LIB_CLOCK_GETTIME := @LIB_CLOCK_GETTIME@  # for ftbench
-
+LDFLAGS := @LDFLAGS@
 
 # export symbols
 #
@@ -111,11 +116,15 @@
 CCexe        := $(CCraw_build)	# used to compile `apinames' only
 
 
-# Library linking
+# Library linking.
 #
 LINK_LIBRARY = $(LIBTOOL) --mode=link $(CCraw) -o $@ $(OBJECTS_LIST) \
                           -rpath $(libdir) -version-info $(version_info) \
                           $(LDFLAGS) -no-undefined \
                           -export-symbols $(EXPORTS_LIST)
 
+# For the demo programs.
+FT_DEMO_CFLAGS := @FT_DEMO_CFLAGS@
+FT_DEMO_LDFLAGS := @FT_DEMO_LDFLAGS@
+
 # EOF
diff --git a/builds/unix/unix-def.in b/builds/unix/unix-def.in
index 6957053..d50994f 100644
--- a/builds/unix/unix-def.in
+++ b/builds/unix/unix-def.in
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -21,8 +21,13 @@
 CAT    := cat
 SEP    := /
 
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+PYTHON := @PYTHON@
+BIN    := bin
+
 # this is used for `make distclean' and `make install'
-OBJ_BUILD ?= $(BUILD_DIR)
+OBJ_BUILD ?= $(PLATFORM_DIR)
 
 # don't use `:=' here since the path stuff will be included after this file
 #
@@ -63,12 +68,14 @@
 
 # Variables needed for `freetype-config' and `freetype.pc'.
 #
-PKG_CONFIG         := @PKG_CONFIG@
-REQUIRES_PRIVATE   := @REQUIRES_PRIVATE@
-LIBS_PRIVATE       := @LIBS_PRIVATE@
-LIBSSTATIC_CONFIG  := @LIBSSTATIC_CONFIG@
-build_libtool_libs := @build_libtool_libs@
-ft_version         := @ft_version@
+PKG_CONFIG                 := @PKG_CONFIG@
+PKGCONFIG_REQUIRES         := @PKGCONFIG_REQUIRES@
+PKGCONFIG_REQUIRES_PRIVATE := @PKGCONFIG_REQUIRES_PRIVATE@
+PKGCONFIG_LIBS             := @PKGCONFIG_LIBS@
+PKGCONFIG_LIBS_PRIVATE     := @PKGCONFIG_LIBS_PRIVATE@
+LIBSSTATIC_CONFIG          := @LIBSSTATIC_CONFIG@
+build_libtool_libs         := @build_libtool_libs@
+ft_version                 := @ft_version@
 
 # The directory where all library files are placed.
 #
@@ -132,15 +139,17 @@
 
 $(OBJ_BUILD)/freetype2.pc: $(TOP_DIR)/builds/unix/freetype2.in
 	rm -f $@ $@.tmp
-	sed -e 's|%REQUIRES_PRIVATE%|$(REQUIRES_PRIVATE)|'     \
-	    -e 's|%LIBS_PRIVATE%|$(LIBS_PRIVATE)|'             \
-	    -e 's|%build_libtool_libs%|$(build_libtool_libs)|' \
-	    -e 's|%exec_prefix%|$(exec_prefix_x)|'             \
-	    -e 's|%ft_version%|$(ft_version)|'                 \
-	    -e 's|%includedir%|$(includedir_x)|'               \
-	    -e 's|%libdir%|$(libdir_x)|'                       \
-	    -e 's|%prefix%|$(prefix_x)|'                       \
-	    $<                                                 \
+	sed -e 's|%PKGCONFIG_REQUIRES%|$(PKGCONFIG_REQUIRES)|'                 \
+	    -e 's|%PKGCONFIG_REQUIRES_PRIVATE%|$(PKGCONFIG_REQUIRES_PRIVATE)|' \
+	    -e 's|%PKGCONFIG_LIBS%|$(PKGCONFIG_LIBS)|'                         \
+	    -e 's|%PKGCONFIG_LIBS_PRIVATE%|$(PKGCONFIG_LIBS_PRIVATE)|'         \
+	    -e 's|%build_libtool_libs%|$(build_libtool_libs)|'                 \
+	    -e 's|%exec_prefix%|$(exec_prefix_x)|'                             \
+	    -e 's|%ft_version%|$(ft_version)|'                                 \
+	    -e 's|%includedir%|$(includedir_x)|'                               \
+	    -e 's|%libdir%|$(libdir_x)|'                                       \
+	    -e 's|%prefix%|$(prefix_x)|'                                       \
+	    $<                                                                 \
 	    > $@.tmp
 	chmod a-w $@.tmp
 	mv $@.tmp $@
diff --git a/builds/unix/unix-dev.mk b/builds/unix/unix-dev.mk
index 5a516ad..9dd8ad6 100644
--- a/builds/unix/unix-dev.mk
+++ b/builds/unix/unix-dev.mk
@@ -6,7 +6,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/unix/unix-lcc.mk b/builds/unix/unix-lcc.mk
index 73a02d4..ded24f4 100644
--- a/builds/unix/unix-lcc.mk
+++ b/builds/unix/unix-lcc.mk
@@ -6,7 +6,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/unix/unix.mk b/builds/unix/unix.mk
index acd54d3..3505175 100644
--- a/builds/unix/unix.mk
+++ b/builds/unix/unix.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -13,8 +13,8 @@
 # fully.
 
 # We need these declarations here since unix-def.mk is a generated file.
-BUILD_DIR := $(TOP_DIR)/builds/unix
-PLATFORM  := unix
+PLATFORM_DIR := $(TOP_DIR)/builds/unix
+PLATFORM     := unix
 
 have_mk := $(wildcard $(OBJ_DIR)/unix-def.mk)
 ifneq ($(have_mk),)
@@ -22,8 +22,8 @@
   include $(OBJ_DIR)/unix-def.mk
   include $(OBJ_DIR)/unix-cc.mk
 else
-  include $(BUILD_DIR)/unix-def.mk
-  include $(BUILD_DIR)/unix-cc.mk
+  include $(PLATFORM_DIR)/unix-def.mk
+  include $(PLATFORM_DIR)/unix-cc.mk
 endif
 
 ifdef BUILD_PROJECT
diff --git a/builds/unix/unixddef.mk b/builds/unix/unixddef.mk
index a8da63a..7197347 100644
--- a/builds/unix/unixddef.mk
+++ b/builds/unix/unixddef.mk
@@ -4,7 +4,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -23,8 +23,9 @@
 CAT    := cat
 SEP    := /
 
-# we use a special devel ftoption.h
-DEVEL_DIR := $(TOP_DIR)/devel
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+BIN := bin
 
 
 # library file name
diff --git a/builds/vms/LIBS.OPT_IA64 b/builds/vms/LIBS.OPT_IA64
new file mode 100644
index 0000000..6768c76
--- /dev/null
+++ b/builds/vms/LIBS.OPT_IA64
Binary files differ
diff --git a/builds/vms/_LINK.OPT_IA64 b/builds/vms/_LINK.OPT_IA64
new file mode 100644
index 0000000..b8cbd1b
--- /dev/null
+++ b/builds/vms/_LINK.OPT_IA64
Binary files differ
diff --git a/builds/vms/ftconfig.h b/builds/vms/ftconfig.h
index 733b09b..31dfcec 100644
--- a/builds/vms/ftconfig.h
+++ b/builds/vms/ftconfig.h
@@ -1,38 +1,36 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftconfig.h                                                             */
-/*                                                                         */
-/*    VMS-specific configuration file (specification only).                */
-/*                                                                         */
-/*  Copyright 1996-2018 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.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * ftconfig.h
+ *
+ *   VMS-specific configuration file (specification only).
+ *
+ * Copyright (C) 1996-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.
+ *
+ */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* This header file contains a number of macro definitions that are used */
-  /* by the rest of the engine.  Most of the macros here are automatically */
-  /* determined at compile time, and you should not need to change it to   */
-  /* port FreeType, except to compile the library with a non-ANSI          */
-  /* compiler.                                                             */
-  /*                                                                       */
-  /* Note however that if some specific modifications are needed, we       */
-  /* advise you to place a modified copy in your build directory.          */
-  /*                                                                       */
-  /* The build directory is usually `builds/<system>', and contains        */
-  /* system-specific files that are always included first when building    */
-  /* the library.                                                          */
-  /*                                                                       */
-  /*************************************************************************/
-
+  /**************************************************************************
+   *
+   * This header file contains a number of macro definitions that are used by
+   * the rest of the engine.  Most of the macros here are automatically
+   * determined at compile time, and you should not need to change it to port
+   * FreeType, except to compile the library with a non-ANSI compiler.
+   *
+   * Note however that if some specific modifications are needed, we advise
+   * you to place a modified copy in your build directory.
+   *
+   * The build directory is usually `builds/<system>`, and contains
+   * system-specific files that are always included first when building the
+   * library.
+   *
+   */
 
 #ifndef FTCONFIG_H_
 #define FTCONFIG_H_
@@ -41,22 +39,6 @@
 #include FT_CONFIG_OPTIONS_H
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
-
-FT_BEGIN_HEADER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
-  /*                                                                       */
-  /* These macros can be toggled to suit a specific system.  The current   */
-  /* ones are defaults used to compile FreeType in an ANSI C environment   */
-  /* (16bit compilers are also supported).  Copy this file to your own     */
-  /* `builds/<system>' directory, and edit it to port the engine.          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
 #define HAVE_UNISTD_H  1
 #define HAVE_FCNTL_H   1
 
@@ -66,489 +48,9 @@
 #define FT_SIZEOF_INT   4
 #define FT_SIZEOF_LONG  4
 
-#define FT_CHAR_BIT  8
-
-
-  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */
-  /* used -- this is only used to get rid of unpleasant compiler warnings */
-#ifndef FT_UNUSED
-#define FT_UNUSED( arg )  ( (arg) = (arg) )
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                     AUTOMATIC CONFIGURATION MACROS                    */
-  /*                                                                       */
-  /* These macros are computed from the ones defined above.  Don't touch   */
-  /* their definition, unless you know precisely what you are doing.  No   */
-  /* porter should need to mess with them.                                 */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Mac support                                                           */
-  /*                                                                       */
-  /*   This is the only necessary change, so it is defined here instead    */
-  /*   providing a new configuration file.                                 */
-  /*                                                                       */
-#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
-  /* no Carbon frameworks for 64bit 10.4.x */
-  /* AvailabilityMacros.h is available since Mac OS X 10.2,        */
-  /* so guess the system version by maximum errno before inclusion */
-#include <errno.h>
-#ifdef ECANCELED /* defined since 10.2 */
-#include "AvailabilityMacros.h"
-#endif
-#if defined( __LP64__ ) && \
-    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
-#undef FT_MACINTOSH
-#endif
-
-#elif defined( __SC__ ) || defined( __MRC__ )
-  /* Classic MacOS compilers */
-#include "ConditionalMacros.h"
-#if TARGET_OS_MAC
-#define FT_MACINTOSH 1
-#endif
-
-#endif
-
-
-  /* Fix compiler warning with sgi compiler */
-#if defined( __sgi ) && !defined( __GNUC__ )
-#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
-#pragma set woff 3505
-#endif
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Section>                                                             */
-  /*    basic_types                                                        */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int16                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit signed integer type.                         */
-  /*                                                                       */
-  typedef signed short  FT_Int16;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt16                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit unsigned integer type.                       */
-  /*                                                                       */
-  typedef unsigned short  FT_UInt16;
-
-  /* */
-
-
-  /* this #if 0 ... #endif clause is for documentation purposes */
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int32                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 32bit signed integer type.  The size depends on    */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef signed XXX  FT_Int32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt32                                                          */
-  /*                                                                       */
-  /*    A typedef for a 32bit unsigned integer type.  The size depends on  */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int64                                                           */
-  /*                                                                       */
-  /*    A typedef for a 64bit signed integer type.  The size depends on    */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef signed XXX  FT_Int64;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt64                                                          */
-  /*                                                                       */
-  /*    A typedef for a 64bit unsigned integer type.  The size depends on  */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt64;
-
-  /* */
-
-#endif
-
-#if FT_SIZEOF_INT == 4
-
-  typedef signed int      FT_Int32;
-  typedef unsigned int    FT_UInt32;
-
-#elif FT_SIZEOF_LONG == 4
-
-  typedef signed long     FT_Int32;
-  typedef unsigned long   FT_UInt32;
-
-#else
-#error "no 32bit type found -- please check your configuration files"
-#endif
-
-
-  /* look up an integer type that is at least 32 bits */
-#if FT_SIZEOF_INT >= 4
-
-  typedef int            FT_Fast;
-  typedef unsigned int   FT_UFast;
-
-#elif FT_SIZEOF_LONG >= 4
-
-  typedef long           FT_Fast;
-  typedef unsigned long  FT_UFast;
-
-#endif
-
-
-  /* determine whether we have a 64-bit int type  */
-  /* (mostly for environments without `autoconf') */
-#if FT_SIZEOF_LONG == 8
-
-  /* FT_LONG64 must be defined if a 64-bit type is available */
-#define FT_LONG64
-#define FT_INT64   long
-#define FT_UINT64  unsigned long
-
-  /* we handle the LLP64 scheme separately for GCC and clang, */
-  /* suppressing the `long long' warning                      */
-#elif ( FT_SIZEOF_LONG == 4 )       && \
-      defined( HAVE_LONG_LONG_INT ) && \
-      defined( __GNUC__ )
-#pragma GCC diagnostic ignored "-Wlong-long"
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A 64-bit data type may create compilation problems if you compile     */
-  /* in strict ANSI mode.  To avoid them, we disable other 64-bit data     */
-  /* types if __STDC__ is defined.  You can however ignore this rule       */
-  /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro.     */
-  /*                                                                       */
-#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
-
-#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __BORLANDC__ )  /* Borland C++ */
-
-  /* XXXX: We should probably check the value of __BORLANDC__ in order */
-  /*       to test the compiler version.                               */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __WATCOMC__ )   /* Watcom C++ */
-
-  /* Watcom doesn't provide 64-bit data types */
-
-#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( __GNUC__ )
-
-  /* GCC provides the `long long' type */
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#endif /* __STDC_VERSION__ >= 199901L */
-
-#endif /* FT_SIZEOF_LONG == 8 */
-
-#ifdef FT_LONG64
-  typedef FT_INT64   FT_Int64;
-  typedef FT_UINT64  FT_UInt64;
-#endif
-
-
-#ifdef _WIN64
-  /* only 64bit Windows uses the LLP64 data model, i.e., */
-  /* 32bit integers, 64bit pointers                      */
-#define FT_UINT_TO_POINTER( x ) (void*)(unsigned __int64)(x)
-#else
-#define FT_UINT_TO_POINTER( x ) (void*)(unsigned long)(x)
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* miscellaneous                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define FT_BEGIN_STMNT  do {
-#define FT_END_STMNT    } while ( 0 )
-#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
-
-
-  /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
-      ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
-        defined( __IBM__TYPEOF__ ) )                                 || \
-      ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  ( __typeof__ ( type ) )
-#else
-#define FT_TYPEOF( type )  /* empty */
-#endif
-
-
-  /* Use FT_LOCAL and FT_LOCAL_DEF to declare and define, respectively, */
-  /* a function that gets used only within the scope of a module.       */
-  /* Normally, both the header and source code files for such a         */
-  /* function are within a single module directory.                     */
-  /*                                                                    */
-  /* Intra-module arrays should be tagged with FT_LOCAL_ARRAY and       */
-  /* FT_LOCAL_ARRAY_DEF.                                                */
-  /*                                                                    */
-#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
-
-#define FT_LOCAL( x )      static  x
-#define FT_LOCAL_DEF( x )  static  x
-
-#else
-
-#ifdef __cplusplus
-#define FT_LOCAL( x )      extern "C"  x
-#define FT_LOCAL_DEF( x )  extern "C"  x
-#else
-#define FT_LOCAL( x )      extern  x
-#define FT_LOCAL_DEF( x )  x
-#endif
-
-#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
-
-#define FT_LOCAL_ARRAY( x )      extern const  x
-#define FT_LOCAL_ARRAY_DEF( x )  const  x
-
-
-  /* Use FT_BASE and FT_BASE_DEF to declare and define, respectively, */
-  /* functions that are used in more than a single module.  In the    */
-  /* current setup this implies that the declaration is in a header   */
-  /* file in the `include/freetype/internal' directory, and the       */
-  /* function body is in a file in `src/base'.                        */
-  /*                                                                  */
-#ifndef FT_BASE
-
-#ifdef __cplusplus
-#define FT_BASE( x )  extern "C"  x
-#else
-#define FT_BASE( x )  extern  x
-#endif
-
-#endif /* !FT_BASE */
-
-
-#ifndef FT_BASE_DEF
-
-#ifdef __cplusplus
-#define FT_BASE_DEF( x )  x
-#else
-#define FT_BASE_DEF( x )  x
-#endif
-
-#endif /* !FT_BASE_DEF */
-
-
-  /*   When compiling FreeType as a DLL or DSO with hidden visibility      */
-  /*   some systems/compilers need a special attribute in front OR after   */
-  /*   the return type of function declarations.                           */
-  /*                                                                       */
-  /*   Two macros are used within the FreeType source code to define       */
-  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
-  /*                                                                       */
-  /*     FT_EXPORT( return_type )                                          */
-  /*                                                                       */
-  /*       is used in a function declaration, as in                        */
-  /*                                                                       */
-  /*         FT_EXPORT( FT_Error )                                         */
-  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */
-  /*                                                                       */
-  /*                                                                       */
-  /*     FT_EXPORT_DEF( return_type )                                      */
-  /*                                                                       */
-  /*       is used in a function definition, as in                         */
-  /*                                                                       */
-  /*         FT_EXPORT_DEF( FT_Error )                                     */
-  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */
-  /*         {                                                             */
-  /*           ... some code ...                                           */
-  /*           return FT_Err_Ok;                                           */
-  /*         }                                                             */
-  /*                                                                       */
-  /*   You can provide your own implementation of FT_EXPORT and            */
-  /*   FT_EXPORT_DEF here if you want.                                     */
-  /*                                                                       */
-  /*   To export a variable, use FT_EXPORT_VAR.                            */
-  /*                                                                       */
-#ifndef FT_EXPORT
-
-#ifdef FT2_BUILD_LIBRARY
-
-#if defined( _WIN32 ) && defined( DLL_EXPORT )
-#define FT_EXPORT( x )  __declspec( dllexport )  x
-#elif defined( __GNUC__ ) && __GNUC__ >= 4
-#define FT_EXPORT( x )  __attribute__(( visibility( "default" ) ))  x
-#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
-#define FT_EXPORT( x )  __global  x
-#elif defined( __cplusplus )
-#define FT_EXPORT( x )  extern "C"  x
-#else
-#define FT_EXPORT( x )  extern  x
-#endif
-
-#else
-
-#if defined( _WIN32 ) && defined( DLL_IMPORT )
-#define FT_EXPORT( x )  __declspec( dllimport )  x
-#elif defined( __cplusplus )
-#define FT_EXPORT( x )  extern "C"  x
-#else
-#define FT_EXPORT( x )  extern  x
-#endif
-
-#endif
-
-#endif /* !FT_EXPORT */
-
-
-#ifndef FT_EXPORT_DEF
-
-#ifdef __cplusplus
-#define FT_EXPORT_DEF( x )  extern "C"  x
-#else
-#define FT_EXPORT_DEF( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_DEF */
-
-
-#ifndef FT_EXPORT_VAR
-
-#ifdef __cplusplus
-#define FT_EXPORT_VAR( x )  extern "C"  x
-#else
-#define FT_EXPORT_VAR( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_VAR */
-
-  /* The following macros are needed to compile the library with a   */
-  /* C++ compiler and with 16bit compilers.                          */
-  /*                                                                 */
-
-  /* This is special.  Within C++, you must specify `extern "C"' for */
-  /* functions which are used via function pointers, and you also    */
-  /* must do that for structures which contain function pointers to  */
-  /* assure C linkage -- it's not possible to have (local) anonymous */
-  /* functions which are accessed by (global) function pointers.     */
-  /*                                                                 */
-  /*                                                                 */
-  /* FT_CALLBACK_DEF is used to _define_ a callback function,        */
-  /* located in the same source code file as the structure that uses */
-  /* it.                                                             */
-  /*                                                                 */
-  /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare   */
-  /* and define a callback function, respectively, in a similar way  */
-  /* as FT_BASE and FT_BASE_DEF work.                                */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
-  /* contains pointers to callback functions.                        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
-  /* that contains pointers to callback functions.                   */
-  /*                                                                 */
-  /*                                                                 */
-  /* Some 16bit compilers have to redefine these macros to insert    */
-  /* the infamous `_cdecl' or `__fastcall' declarations.             */
-  /*                                                                 */
-#ifndef FT_CALLBACK_DEF
-#ifdef __cplusplus
-#define FT_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_CALLBACK_DEF( x )  static  x
-#endif
-#endif /* FT_CALLBACK_DEF */
-
-#ifndef FT_BASE_CALLBACK
-#ifdef __cplusplus
-#define FT_BASE_CALLBACK( x )      extern "C"  x
-#define FT_BASE_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_BASE_CALLBACK( x )      extern  x
-#define FT_BASE_CALLBACK_DEF( x )  x
-#endif
-#endif /* FT_BASE_CALLBACK */
-
-#ifndef FT_CALLBACK_TABLE
-#ifdef __cplusplus
-#define FT_CALLBACK_TABLE      extern "C"
-#define FT_CALLBACK_TABLE_DEF  extern "C"
-#else
-#define FT_CALLBACK_TABLE      extern
-#define FT_CALLBACK_TABLE_DEF  /* nothing */
-#endif
-#endif /* FT_CALLBACK_TABLE */
-
-
-FT_END_HEADER
-
+#include <freetype/config/integer-types.h>
+#include <freetype/config/public-macros.h>
+#include <freetype/config/mac-support.h>
 
 #endif /* FTCONFIG_H_ */
 
diff --git a/builds/vms/ftsystem.c b/builds/vms/ftsystem.c
index 7d79f9a..0afd07d 100644
--- a/builds/vms/ftsystem.c
+++ b/builds/vms/ftsystem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    VMS-specific FreeType low-level system interface (body).             */
 /*                                                                         */
-/*  Copyright 1996-2018 by                                                 */
+/*  Copyright (C) 1996-2023 by                                             */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -19,11 +19,11 @@
 #include <ft2build.h>
   /* we use our special ftconfig.h file, not the standard one */
 #include <ftconfig.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_SYSTEM_H
-#include FT_ERRORS_H
-#include FT_TYPES_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftsystem.h>
+#include <freetype/fterrors.h>
+#include <freetype/fttypes.h>
+#include <freetype/internal/ftobjs.h>
 
   /* memory-mapping includes and definitions */
 #ifdef HAVE_UNISTD_H
@@ -172,7 +172,7 @@
   /* messages during execution.                                            */
   /*                                                                       */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_io
+#define FT_COMPONENT  io
 
   /* We use the macro STREAM_FILE for convenience to extract the       */
   /* system-specific stream handle from a given FreeType stream object */
@@ -197,7 +197,7 @@
 
     stream->descriptor.pointer = NULL;
     stream->size               = 0;
-    stream->base               = 0;
+    stream->base               = NULL;
   }
 
 
@@ -246,7 +246,7 @@
                                           file,
                                           0 );
 
-    if ( (long)stream->base == -1 )
+    if ( stream->base == MAP_FAILED )
     {
       FT_ERROR(( "FT_Stream_Open:" ));
       FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
@@ -259,7 +259,7 @@
     stream->pathname.pointer   = (char*)filepathname;
 
     stream->close = ft_close_stream;
-    stream->read  = 0;
+    stream->read  = NULL;
 
     FT_TRACE1(( "FT_Stream_Open:" ));
     FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
@@ -300,7 +300,7 @@
     memory = (FT_Memory)malloc( sizeof ( *memory ) );
     if ( memory )
     {
-      memory->user    = 0;
+      memory->user    = NULL;
       memory->alloc   = ft_alloc;
       memory->realloc = ft_realloc;
       memory->free    = ft_free;
diff --git a/builds/vms/vmslib.dat b/builds/vms/vmslib.dat
new file mode 100644
index 0000000..4c817da
--- /dev/null
+++ b/builds/vms/vmslib.dat
@@ -0,0 +1,28 @@
+!
+! 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/ftdebug.c b/builds/wince/ftdebug.c
index 83c5f44..6453f8d 100644
--- a/builds/wince/ftdebug.c
+++ b/builds/wince/ftdebug.c
@@ -1,53 +1,52 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftdebug.c                                                              */
-/*                                                                         */
-/*    Debugging and logging component for WinCE (body).                    */
-/*                                                                         */
-/*  Copyright 1996-2018 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.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * ftdebug.c
+ *
+ *   Debugging and logging component for WinCE (body).
+ *
+ * Copyright (C) 1996-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.
+ *
+ */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* This component contains various macros and functions used to ease the */
-  /* debugging of the FreeType engine.  Its main purpose is in assertion   */
-  /* checking, tracing, and error detection.                               */
-  /*                                                                       */
-  /* There are now three debugging modes:                                  */
-  /*                                                                       */
-  /* - trace mode                                                          */
-  /*                                                                       */
-  /*   Error and trace messages are sent to the log file (which can be the */
-  /*   standard error output).                                             */
-  /*                                                                       */
-  /* - error mode                                                          */
-  /*                                                                       */
-  /*   Only error messages are generated.                                  */
-  /*                                                                       */
-  /* - release mode:                                                       */
-  /*                                                                       */
-  /*   No error message is sent or generated.  The code is free from any   */
-  /*   debugging parts.                                                    */
-  /*                                                                       */
-  /*************************************************************************/
+  /**************************************************************************
+   *
+   * This component contains various macros and functions used to ease the
+   * debugging of the FreeType engine.  Its main purpose is in assertion
+   * checking, tracing, and error detection.
+   *
+   * There are now three debugging modes:
+   *
+   * - trace mode
+   *
+   *   Error and trace messages are sent to the log file (which can be the
+   *   standard error output).
+   *
+   * - error mode
+   *
+   *   Only error messages are generated.
+   *
+   * - release mode:
+   *
+   *   No error message is sent or generated.  The code is free from any
+   *   debugging parts.
+   *
+   */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
 
 
 #ifdef FT_DEBUG_LEVEL_ERROR
 
-
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -55,14 +54,15 @@
 #include <windows.h>
 
 
-  void
+  static void
   OutputDebugStringEx( const char*  str )
   {
     static WCHAR  buf[8192];
 
+    int  sz = MultiByteToWideChar( CP_ACP, 0, str, -1, buf,
+                                   sizeof ( buf ) / sizeof ( *buf ) );
 
-    int sz = MultiByteToWideChar( CP_ACP, 0, str, -1, buf,
-                                  sizeof ( buf ) / sizeof ( *buf ) );
+
     if ( !sz )
       lstrcpyW( buf, L"OutputDebugStringEx: MultiByteToWideChar failed" );
 
@@ -70,6 +70,8 @@
   }
 
 
+  /* documentation is in ftdebug.h */
+
   FT_BASE_DEF( void )
   FT_Message( const char*  fmt,
               ... )
@@ -87,6 +89,8 @@
   }
 
 
+  /* documentation is in ftdebug.h */
+
   FT_BASE_DEF( void )
   FT_Panic( const char*  fmt,
             ... )
@@ -111,49 +115,111 @@
             int          line,
             const char*  file )
   {
+#if 0
+    /* activating the code in this block makes FreeType very chatty */
+    fprintf( stderr,
+             "%s:%d: error 0x%02x: %s\n",
+             file,
+             line,
+             error,
+             FT_Error_String( error ) );
+#else
     FT_UNUSED( error );
     FT_UNUSED( line );
     FT_UNUSED( file );
+#endif
 
     return 0;
   }
 
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
+
 #ifdef FT_DEBUG_LEVEL_TRACE
 
+  /* array of trace levels, initialized to 0; */
+  /* this gets adjusted at run-time           */
+  static int  ft_trace_levels_enabled[trace_count];
 
-  /* array of trace levels, initialized to 0 */
-  int  ft_trace_levels[trace_count];
+  /* array of trace levels, always initialized to 0 */
+  static int  ft_trace_levels_disabled[trace_count];
+
+  /* a pointer to either `ft_trace_levels_enabled' */
+  /* or `ft_trace_levels_disabled'                 */
+  int*  ft_trace_levels;
 
   /* define array of trace toggle names */
 #define FT_TRACE_DEF( x )  #x ,
 
   static const char*  ft_trace_toggles[trace_count + 1] =
   {
-#include FT_INTERNAL_TRACE_H
+#include <freetype/internal/fttrace.h>
     NULL
   };
 
 #undef FT_TRACE_DEF
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Initialize the tracing sub-system.  This is done by retrieving the    */
-  /* value of the "FT2_DEBUG" environment variable.  It must be a list of  */
-  /* toggles, separated by spaces, `;' or `,'.  Example:                   */
-  /*                                                                       */
-  /*    "any:3 memory:6 stream:5"                                          */
-  /*                                                                       */
-  /* This will request that all levels be set to 3, except the trace level */
-  /* for the memory and stream components which are set to 6 and 5,        */
-  /* respectively.                                                         */
-  /*                                                                       */
-  /* See the file `include/freetype/internal/fttrace.h' for details of the */
-  /* available toggle names.                                               */
-  /*                                                                       */
-  /* The level must be between 0 and 6; 0 means quiet (except for serious  */
-  /* runtime errors), and 6 means _very_ verbose.                          */
-  /*                                                                       */
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( FT_Int )
+  FT_Trace_Get_Count( void )
+  {
+    return trace_count;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( const char * )
+  FT_Trace_Get_Name( FT_Int  idx )
+  {
+    int  max = FT_Trace_Get_Count();
+
+
+    if ( idx < max )
+      return ft_trace_toggles[idx];
+    else
+      return NULL;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Disable( void )
+  {
+    ft_trace_levels = ft_trace_levels_disabled;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Enable( void )
+  {
+    ft_trace_levels = ft_trace_levels_enabled;
+  }
+
+
+  /**************************************************************************
+   *
+   * Initialize the tracing sub-system.  This is done by retrieving the
+   * value of the `FT2_DEBUG' environment variable.  It must be a list of
+   * toggles, separated by spaces, `;', or `,'.  Example:
+   *
+   *   export FT2_DEBUG="any:3 memory:7 stream:5"
+   *
+   * This requests that all levels be set to 3, except the trace level for
+   * the memory and stream components which are set to 7 and 5,
+   * respectively.
+   *
+   * See the file `include/freetype/internal/fttrace.h' for details of
+   * the available toggle names.
+   *
+   * The level must be between 0 and 7; 0 means quiet (except for serious
+   * runtime errors), and 7 means _very_ verbose.
+   */
   FT_BASE_DEF( void )
   ft_debug_init( void )
   {
@@ -164,7 +230,7 @@
 
     /* const char*  ft2_debug = getenv( "FT2_DEBUG" ); */
 
-    const char*  ft2_debug = 0;
+    const char*  ft2_debug = NULL;
 
 
     if ( ft2_debug )
@@ -189,8 +255,8 @@
 
         if ( *p == ':' && p > q )
         {
-          int  n, i, len = (int)( p - q );
-          int  level = -1, found = -1;
+          FT_Int  n, i, len = (FT_Int)( p - q );
+          FT_Int  level = -1, found = -1;
 
 
           for ( n = 0; n < trace_count; n++ )
@@ -224,16 +290,18 @@
           {
             if ( found == trace_any )
             {
-              /* special case for "any" */
+              /* special case for `any' */
               for ( n = 0; n < trace_count; n++ )
-                ft_trace_levels[n] = level;
+                ft_trace_levels_enabled[n] = level;
             }
             else
-              ft_trace_levels[found] = level;
+              ft_trace_levels_enabled[found] = level;
           }
         }
       }
     }
+
+    ft_trace_levels = ft_trace_levels_enabled;
   }
 
 
@@ -247,9 +315,39 @@
   }
 
 
-#endif /* !FT_DEBUG_LEVEL_TRACE */
+  FT_BASE_DEF( FT_Int )
+  FT_Trace_Get_Count( void )
+  {
+    return 0;
+  }
 
-#endif /* FT_DEBUG_LEVEL_ERROR */
+
+  FT_BASE_DEF( const char * )
+  FT_Trace_Get_Name( FT_Int  idx )
+  {
+    FT_UNUSED( idx );
+
+    return NULL;
+  }
+
+
+  FT_BASE_DEF( void )
+  FT_Trace_Disable( void )
+  {
+    /* nothing */
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Enable( void )
+  {
+    /* nothing */
+  }
+
+
+#endif /* !FT_DEBUG_LEVEL_TRACE */
 
 
 /* END */
diff --git a/builds/wince/vc2005-ce/freetype.vcproj b/builds/wince/vc2005-ce/freetype.vcproj
index 1ca45a8..efdb587 100644
--- a/builds/wince/vc2005-ce/freetype.vcproj
+++ b/builds/wince/vc2005-ce/freetype.vcproj
@@ -21,7 +21,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -41,7 +41,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -61,7 +61,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -81,7 +81,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -101,7 +101,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -121,7 +121,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -141,7 +141,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -161,7 +161,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -181,7 +181,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -201,7 +201,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -221,7 +221,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -241,7 +241,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -261,7 +261,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST.lib" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST.lib" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -281,7 +281,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST.lib" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST.lib" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -301,7 +301,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST.lib" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST.lib" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -321,7 +321,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST.lib" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST.lib" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -341,7 +341,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST.lib" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST.lib" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -361,7 +361,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST.lib" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST.lib" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -381,7 +381,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -401,7 +401,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -421,7 +421,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -441,7 +441,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -461,7 +461,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -481,7 +481,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -501,7 +501,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -521,7 +521,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -541,7 +541,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -561,7 +561,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -581,7 +581,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -601,7 +601,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291ST_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeST_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -621,7 +621,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -641,7 +641,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -661,7 +661,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -681,7 +681,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -701,7 +701,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -721,7 +721,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -741,7 +741,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -758,7 +758,7 @@
       <Tool Name="VCManagedResourceCompilerTool" />

       <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

       <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetype291MT_D.lib" SuppressStartupBanner="true" />

+      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\wince\vc2005-ce\freetypeMT_D.lib" SuppressStartupBanner="true" />

       <Tool Name="VCALinkTool" />

       <Tool Name="VCXDCMakeTool" />

       <Tool Name="VCBscMakeTool" />

@@ -868,6 +868,10 @@
       <File RelativePath="..\..\..\include\freetype\config\ftstdlib.h">

       </File>

     </Filter>

+    <Filter Name="Resource Files" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx">

+      <File RelativePath="..\..\..\src\base\ftver.rc">

+      </File>

+    </Filter>

   </Files>

   <Globals>

   </Globals>

diff --git a/builds/wince/vc2005-ce/index.html b/builds/wince/vc2005-ce/index.html
index 02a1caf..0a8b3c6 100644
--- a/builds/wince/vc2005-ce/index.html
+++ b/builds/wince/vc2005-ce/index.html
@@ -21,21 +21,21 @@
   <li>PPC/SP WM6 (Windows Mobile 6)</li>
 </ul>
 
-It compiles the following libraries from the FreeType 2.9.1 sources:</p>
+It compiles the following libraries from the FreeType 2.13.0 sources:</p>
 
 <ul>
   <pre>
-    freetype291.lib     - release build; single threaded
-    freetype291_D.lib   - debug build;   single threaded
-    freetype291MT.lib   - release build; multi-threaded
-    freetype291MT_D.lib - debug build;   multi-threaded</pre>
+    freetype.lib     - release build; single threaded
+    freetype_D.lib   - debug build;   single threaded
+    freetypeMT.lib   - release build; multi-threaded
+    freetypeMT_D.lib - debug build;   multi-threaded</pre>
 </ul>
 
 <p>Be sure to extract the files with the Windows (CR+LF) line endings.  ZIP
 archives are already stored this way, so no further action is required.  If
 you use some <tt>.tar.*z</tt> archives, be sure to configure your extracting
 tool to convert the line endings.  For example, with <a
-href="http://www.winzip.com">WinZip</a>, you should activate the <em>TAR
+href="https://www.winzip.com">WinZip</a>, you should activate the <em>TAR
 file smart CR/LF Conversion</em> option.  Alternatively, you may consider
 using the <tt>unix2dos</tt> or <tt>u2d</tt> utilities that are floating
 around, which specifically deal with this particular problem.
diff --git a/builds/wince/vc2008-ce/freetype.vcproj b/builds/wince/vc2008-ce/freetype.vcproj
index 7a5445e..d01c5b5 100644
--- a/builds/wince/vc2008-ce/freetype.vcproj
+++ b/builds/wince/vc2008-ce/freetype.vcproj
@@ -88,7 +88,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -177,7 +177,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -266,7 +266,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -355,7 +355,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -444,7 +444,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -533,7 +533,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -621,7 +621,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -709,7 +709,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -797,7 +797,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -885,7 +885,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -973,7 +973,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1061,7 +1061,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1149,7 +1149,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1236,7 +1236,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1323,7 +1323,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1410,7 +1410,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1497,7 +1497,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1584,7 +1584,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1668,7 +1668,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1753,7 +1753,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1838,7 +1838,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1923,7 +1923,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2008,7 +2008,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2093,7 +2093,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2178,7 +2178,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2263,7 +2263,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2348,7 +2348,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2433,7 +2433,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2518,7 +2518,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2603,7 +2603,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2689,7 +2689,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2775,7 +2775,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2861,7 +2861,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2947,7 +2947,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3033,7 +3033,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3119,7 +3119,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3205,7 +3205,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3279,7 +3279,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\wince\vc2008-ce\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\wince\vc2008-ce\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3502,6 +3502,15 @@
 				>

 			</File>

 		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			>

+			<File

+				RelativePath="..\..\..\src\base\ftver.rc"

+				>

+			</File>

+		</Filter>

 	</Files>

 	<Globals>

 	</Globals>

diff --git a/builds/wince/vc2008-ce/index.html b/builds/wince/vc2008-ce/index.html
index f7a3583..747370a 100644
--- a/builds/wince/vc2008-ce/index.html
+++ b/builds/wince/vc2008-ce/index.html
@@ -21,21 +21,21 @@
   <li>PPC/SP WM6 (Windows Mobile 6)</li>
 </ul>
 
-It compiles the following libraries from the FreeType 2.9.1 sources:</p>
+It compiles the following libraries from the FreeType 2.13.0 sources:</p>
 
 <ul>
   <pre>
-    freetype291.lib     - release build; single threaded
-    freetype291_D.lib   - debug build;   single threaded
-    freetype291MT.lib   - release build; multi-threaded
-    freetype291MT_D.lib - debug build;   multi-threaded</pre>
+    freetype.lib     - release build; single threaded
+    freetype_D.lib   - debug build;   single threaded
+    freetypeMT.lib   - release build; multi-threaded
+    freetypeMT_D.lib - debug build;   multi-threaded</pre>
 </ul>
 
 <p>Be sure to extract the files with the Windows (CR+LF) line endings.  ZIP
 archives are already stored this way, so no further action is required.  If
 you use some <tt>.tar.*z</tt> archives, be sure to configure your extracting
 tool to convert the line endings.  For example, with <a
-href="http://www.winzip.com">WinZip</a>, you should activate the <em>TAR
+href="https://www.winzip.com">WinZip</a>, you should activate the <em>TAR
 file smart CR/LF Conversion</em> option.  Alternatively, you may consider
 using the <tt>unix2dos</tt> or <tt>u2d</tt> utilities that are floating
 around, which specifically deal with this particular problem.
diff --git a/builds/windows/detect.mk b/builds/windows/detect.mk
index 05b0e6a..d7908be 100644
--- a/builds/windows/detect.mk
+++ b/builds/windows/detect.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -81,9 +81,9 @@
   # (2004-11-11), and then in the devel mailing list (2004-11-20 to -23).
   #
   ifeq ($(OS),Windows_NT)
-    COPY := cmd.exe /c copy
+    COPY := >nul cmd.exe /c copy
   else
-    COPY := copy
+    COPY := >nul copy
   endif  # test NT
 
 
diff --git a/builds/windows/ftdebug.c b/builds/windows/ftdebug.c
index ec70a0e..360f8c7 100644
--- a/builds/windows/ftdebug.c
+++ b/builds/windows/ftdebug.c
@@ -1,74 +1,152 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftdebug.c                                                              */
-/*                                                                         */
-/*    Debugging and logging component for Win32 (body).                    */
-/*                                                                         */
-/*  Copyright 1996-2018 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.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * ftdebug.c
+ *
+ *   Debugging and logging component for Win32 (body).
+ *
+ * Copyright (C) 1996-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.
+ *
+ */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* This component contains various macros and functions used to ease the */
-  /* debugging of the FreeType engine.  Its main purpose is in assertion   */
-  /* checking, tracing, and error detection.                               */
-  /*                                                                       */
-  /* There are now three debugging modes:                                  */
-  /*                                                                       */
-  /* - trace mode                                                          */
-  /*                                                                       */
-  /*   Error and trace messages are sent to the log file (which can be the */
-  /*   standard error output).                                             */
-  /*                                                                       */
-  /* - error mode                                                          */
-  /*                                                                       */
-  /*   Only error messages are generated.                                  */
-  /*                                                                       */
-  /* - release mode:                                                       */
-  /*                                                                       */
-  /*   No error message is sent or generated.  The code is free from any   */
-  /*   debugging parts.                                                    */
-  /*                                                                       */
-  /*************************************************************************/
+  /**************************************************************************
+   *
+   * This component contains various macros and functions used to ease the
+   * debugging of the FreeType engine.  Its main purpose is in assertion
+   * checking, tracing, and error detection.
+   *
+   * There are now three debugging modes:
+   *
+   * - trace mode
+   *
+   *   Error and trace messages are sent to the log file (which can be the
+   *   standard error output).
+   *
+   * - error mode
+   *
+   *   Only error messages are generated.
+   *
+   * - release mode:
+   *
+   *   No error message is sent or generated.  The code is free from any
+   *   debugging parts.
+   *
+   */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/freetype.h>
+#include <freetype/ftlogging.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+
+
+#ifdef FT_DEBUG_LOGGING
+
+  /**************************************************************************
+   *
+   * Variables used to control logging.
+   *
+   * 1. `ft_default_trace_level` stores the value of trace levels, which are
+   *    provided to FreeType using the `FT2_DEBUG` environment variable.
+   *
+   * 2. `ft_fileptr` stores the `FILE*` handle.
+   *
+   * 3. `ft_component` is a string that holds the name of `FT_COMPONENT`.
+   *
+   * 4. The flag `ft_component_flag` prints the name of `FT_COMPONENT` along
+   *    with the actual log message if set to true.
+   *
+   * 5. The flag `ft_timestamp_flag` prints time along with the actual log
+   *    message if set to ture.
+   *
+   * 6. `ft_have_newline_char` is used to differentiate between a log
+   *    message with and without a trailing newline character.
+   *
+   * 7. `ft_custom_trace_level` stores the custom trace level value, which
+   *    is provided by the user at run-time.
+   *
+   * We use `static` to avoid 'unused variable' warnings.
+   *
+   */
+  static const char*  ft_default_trace_level = NULL;
+  static FILE*        ft_fileptr             = NULL;
+  static const char*  ft_component           = NULL;
+  static FT_Bool      ft_component_flag      = FALSE;
+  static FT_Bool      ft_timestamp_flag      = FALSE;
+  static FT_Bool      ft_have_newline_char   = TRUE;
+  static const char*  ft_custom_trace_level  = NULL;
+
+  /* declared in ftdebug.h */
+
+  dlg_handler            ft_default_log_handler = NULL;
+  FT_Custom_Log_Handler  custom_output_handler  = NULL;
+
+#endif /* FT_DEBUG_LOGGING */
 
 
 #ifdef FT_DEBUG_LEVEL_ERROR
 
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
 
+#ifdef _WIN32_WCE
+
+  FT_LOACAL_DEF( void )
+  OutputDebugStringA( LPCSTR lpOutputString )
+  {
+    int            len;
+    LPWSTR         lpOutputStringW;
+
+
+    /* allocate memory space for converted string */
+    len = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
+                               lpOutputString, -1, NULL, 0 );
+
+    lpOutputStringW = (LPWSTR)_alloca( len * sizeof ( WCHAR ) );
+
+    if ( !len || !lpOutputStringW )
+      return;
+
+    /* now it is safe to do the translation */
+    MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
+                         lpOutputString, -1, lpOutputStringW, len );
+
+    OutputDebugStringW( lpOutputStringW );
+  }
+
+#endif /* _WIN32_WCE */
+
+
   /* documentation is in ftdebug.h */
 
   FT_BASE_DEF( void )
   FT_Message( const char*  fmt,
               ... )
   {
-    static char  buf[8192];
-    va_list      ap;
+    va_list  ap;
 
 
     va_start( ap, fmt );
     vfprintf( stderr, fmt, ap );
-    /* send the string to the debugger as well */
-    vsprintf( buf, fmt, ap );
-    OutputDebugStringA( buf );
+#if ( defined( _WIN32_WINNT ) && _WIN32_WINNT >= 0x0400 ) || \
+    ( defined( _WIN32_WCE )   && _WIN32_WCE   >= 0x0600 )
+    if ( IsDebuggerPresent() )
+    {
+      static char  buf[1024];
+
+
+      vsnprintf( buf, sizeof buf, fmt, ap );
+      OutputDebugStringA( buf );
+    }
+#endif
     va_end( ap );
   }
 
@@ -79,13 +157,22 @@
   FT_Panic( const char*  fmt,
             ... )
   {
-    static char  buf[8192];
-    va_list      ap;
+    va_list  ap;
 
 
     va_start( ap, fmt );
-    vsprintf( buf, fmt, ap );
-    OutputDebugStringA( buf );
+    vfprintf( stderr, fmt, ap );
+#if ( defined( _WIN32_WINNT ) && _WIN32_WINNT >= 0x0400 ) || \
+    ( defined( _WIN32_WCE )   && _WIN32_WCE   >= 0x0600 )
+    if ( IsDebuggerPresent() )
+    {
+      static char  buf[1024];
+
+
+      vsnprintf( buf, sizeof buf, fmt, ap );
+      OutputDebugStringA( buf );
+    }
+#endif
     va_end( ap );
 
     exit( EXIT_FAILURE );
@@ -99,56 +186,126 @@
             int          line,
             const char*  file )
   {
+#if 0
+    /* activating the code in this block makes FreeType very chatty */
+    fprintf( stderr,
+             "%s:%d: error 0x%02x: %s\n",
+             file,
+             line,
+             error,
+             FT_Error_String( error ) );
+#else
     FT_UNUSED( error );
     FT_UNUSED( line );
     FT_UNUSED( file );
+#endif
 
     return 0;
   }
 
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
+  /* array of trace levels, initialized to 0; */
+  /* this gets adjusted at run-time           */
+  static int  ft_trace_levels_enabled[trace_count];
 
-  /* array of trace levels, initialized to 0 */
-  int  ft_trace_levels[trace_count];
+  /* array of trace levels, always initialized to 0 */
+  static int  ft_trace_levels_disabled[trace_count];
+
+  /* a pointer to either `ft_trace_levels_enabled' */
+  /* or `ft_trace_levels_disabled'                 */
+  int*  ft_trace_levels;
 
   /* define array of trace toggle names */
 #define FT_TRACE_DEF( x )  #x ,
 
   static const char*  ft_trace_toggles[trace_count + 1] =
   {
-#include FT_INTERNAL_TRACE_H
+#include <freetype/internal/fttrace.h>
     NULL
   };
 
 #undef FT_TRACE_DEF
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Initialize the tracing sub-system.  This is done by retrieving the    */
-  /* value of the "FT2_DEBUG" environment variable.  It must be a list of  */
-  /* toggles, separated by spaces, `;' or `,'.  Example:                   */
-  /*                                                                       */
-  /*    "any:3 memory:6 stream:5"                                          */
-  /*                                                                       */
-  /* This will request that all levels be set to 3, except the trace level */
-  /* for the memory and stream components which are set to 6 and 5,        */
-  /* respectively.                                                         */
-  /*                                                                       */
-  /* See the file `include/freetype/internal/fttrace.h' for details of the */
-  /* available toggle names.                                               */
-  /*                                                                       */
-  /* The level must be between 0 and 6; 0 means quiet (except for serious  */
-  /* runtime errors), and 6 means _very_ verbose.                          */
-  /*                                                                       */
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( FT_Int )
+  FT_Trace_Get_Count( void )
+  {
+    return trace_count;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( const char * )
+  FT_Trace_Get_Name( FT_Int  idx )
+  {
+    int  max = FT_Trace_Get_Count();
+
+
+    if ( idx < max )
+      return ft_trace_toggles[idx];
+    else
+      return NULL;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Disable( void )
+  {
+    ft_trace_levels = ft_trace_levels_disabled;
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Enable( void )
+  {
+    ft_trace_levels = ft_trace_levels_enabled;
+  }
+
+
+  /**************************************************************************
+   *
+   * Initialize the tracing sub-system.  This is done by retrieving the
+   * value of the `FT2_DEBUG' environment variable.  It must be a list of
+   * toggles, separated by spaces, `;', or `,'.  Example:
+   *
+   *   export FT2_DEBUG="any:3 memory:7 stream:5"
+   *
+   * This requests that all levels be set to 3, except the trace level for
+   * the memory and stream components which are set to 7 and 5,
+   * respectively.
+   *
+   * See the file `include/freetype/internal/fttrace.h' for details of
+   * the available toggle names.
+   *
+   * The level must be between 0 and 7; 0 means quiet (except for serious
+   * runtime errors), and 7 means _very_ verbose.
+   */
   FT_BASE_DEF( void )
   ft_debug_init( void )
   {
-    const char*  ft2_debug = getenv( "FT2_DEBUG" );
+    const char*  ft2_debug = NULL;
 
 
+#ifdef FT_DEBUG_LOGGING
+    if ( ft_custom_trace_level != NULL )
+      ft2_debug = ft_custom_trace_level;
+    else
+      ft2_debug = ft_default_trace_level;
+#else
+    ft2_debug = ft_getenv( "FT2_DEBUG" );
+#endif
+
     if ( ft2_debug )
     {
       const char*  p = ft2_debug;
@@ -161,6 +318,49 @@
         if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
           continue;
 
+#ifdef FT_DEBUG_LOGGING
+
+        /* check extra arguments for logging */
+        if ( *p == '-' )
+        {
+          const char*  r = ++p;
+
+
+          if ( *r == 'v' )
+          {
+            const char*  s = ++r;
+
+
+            ft_component_flag = TRUE;
+
+            if ( *s == 't' )
+            {
+              ft_timestamp_flag = TRUE;
+              p++;
+            }
+
+            p++;
+          }
+
+          else if ( *r == 't' )
+          {
+            const char*  s = ++r;
+
+
+            ft_timestamp_flag = TRUE;
+
+            if ( *s == 'v' )
+            {
+              ft_component_flag = TRUE;
+              p++;
+            }
+
+            p++;
+          }
+        }
+
+#endif /* FT_DEBUG_LOGGING */
+
         /* read toggle name, followed by ':' */
         q = p;
         while ( *p && *p != ':' )
@@ -171,8 +371,8 @@
 
         if ( *p == ':' && p > q )
         {
-          int  n, i, len = (int)( p - q );
-          int  level = -1, found = -1;
+          FT_Int  n, i, len = (FT_Int)( p - q );
+          FT_Int  level = -1, found = -1;
 
 
           for ( n = 0; n < trace_count; n++ )
@@ -206,16 +406,18 @@
           {
             if ( found == trace_any )
             {
-              /* special case for "any" */
+              /* special case for `any' */
               for ( n = 0; n < trace_count; n++ )
-                ft_trace_levels[n] = level;
+                ft_trace_levels_enabled[n] = level;
             }
             else
-              ft_trace_levels[found] = level;
+              ft_trace_levels_enabled[found] = level;
           }
         }
       }
     }
+
+    ft_trace_levels = ft_trace_levels_enabled;
   }
 
 
@@ -229,9 +431,268 @@
   }
 
 
+  FT_BASE_DEF( FT_Int )
+  FT_Trace_Get_Count( void )
+  {
+    return 0;
+  }
+
+
+  FT_BASE_DEF( const char * )
+  FT_Trace_Get_Name( FT_Int  idx )
+  {
+    FT_UNUSED( idx );
+
+    return NULL;
+  }
+
+
+  FT_BASE_DEF( void )
+  FT_Trace_Disable( void )
+  {
+    /* nothing */
+  }
+
+
+  /* documentation is in ftdebug.h */
+
+  FT_BASE_DEF( void )
+  FT_Trace_Enable( void )
+  {
+    /* nothing */
+  }
+
 #endif /* !FT_DEBUG_LEVEL_TRACE */
 
-#endif /* FT_DEBUG_LEVEL_ERROR */
+
+#ifdef FT_DEBUG_LOGGING
+
+  /**************************************************************************
+   *
+   * Initialize and de-initialize 'dlg' library.
+   *
+   */
+
+  FT_BASE_DEF( void )
+  ft_logging_init( void )
+  {
+    ft_default_log_handler = ft_log_handler;
+    ft_default_trace_level = ft_getenv( "FT2_DEBUG" );
+
+    if ( ft_getenv( "FT_LOGGING_FILE" ) )
+      ft_fileptr = ft_fopen( ft_getenv( "FT_LOGGING_FILE" ), "w" );
+    else
+      ft_fileptr = stderr;
+
+    ft_debug_init();
+
+    /* Set the default output handler for 'dlg'. */
+    dlg_set_handler( ft_default_log_handler, NULL );
+  }
+
+
+  FT_BASE_DEF( void )
+  ft_logging_deinit( void )
+  {
+    if ( ft_fileptr != stderr )
+      ft_fclose( ft_fileptr );
+  }
+
+
+  /**************************************************************************
+   *
+   * An output log handler for FreeType.
+   *
+   */
+  FT_BASE_DEF( void )
+  ft_log_handler( const struct dlg_origin*  origin,
+                  const char*               string,
+                  void*                     data )
+  {
+    char         features_buf[128];
+    char*        bufp = features_buf;
+
+    FT_UNUSED( data );
+
+
+    if ( ft_have_newline_char )
+    {
+      const char*  features        = NULL;
+      size_t       features_length = 0;
+
+
+#define FEATURES_TIMESTAMP            "[%h:%m] "
+#define FEATURES_COMPONENT            "[%t] "
+#define FEATURES_TIMESTAMP_COMPONENT  "[%h:%m %t] "
+
+      if ( ft_timestamp_flag && ft_component_flag )
+      {
+        features        = FEATURES_TIMESTAMP_COMPONENT;
+        features_length = sizeof ( FEATURES_TIMESTAMP_COMPONENT );
+      }
+      else if ( ft_timestamp_flag )
+      {
+        features        = FEATURES_TIMESTAMP;
+        features_length = sizeof ( FEATURES_TIMESTAMP );
+      }
+      else if ( ft_component_flag )
+      {
+        features        = FEATURES_COMPONENT;
+        features_length = sizeof ( FEATURES_COMPONENT );
+      }
+
+      if ( ft_component_flag || ft_timestamp_flag )
+      {
+        ft_strncpy( features_buf, features, features_length );
+        bufp += features_length - 1;
+      }
+
+      if ( ft_component_flag )
+      {
+        size_t  tag_length = ft_strlen( *origin->tags );
+        size_t  i;
+
+
+        /* To vertically align tracing messages we compensate the */
+        /* different FT_COMPONENT string lengths by inserting an  */
+        /* appropriate amount of space characters.                */
+        for ( i = 0;
+              i < FT_MAX_TRACE_LEVEL_LENGTH - tag_length;
+              i++ )
+          *bufp++ = ' ';
+      }
+    }
+
+    /* Finally add the format string for the tracing message. */
+    *bufp++ = '%';
+    *bufp++ = 'c';
+    *bufp   = '\0';
+
+    dlg_generic_outputf_stream( ft_fileptr,
+                                (const char*)features_buf,
+                                origin,
+                                string,
+                                dlg_default_output_styles,
+                                true );
+
+    if ( ft_strrchr( string, '\n' ) )
+      ft_have_newline_char = TRUE;
+    else
+      ft_have_newline_char = FALSE;
+  }
+
+
+  /* documentation is in ftdebug.h */
+  FT_BASE_DEF( void )
+  ft_add_tag( const char*  tag )
+  {
+    ft_component = tag;
+
+    dlg_add_tag( tag, NULL );
+  }
+
+
+  /* documentation is in ftdebug.h */
+  FT_BASE_DEF( void )
+  ft_remove_tag( const char*  tag )
+  {
+    dlg_remove_tag( tag, NULL );
+  }
+
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Level( const char*  level )
+  {
+    ft_component_flag     = FALSE;
+    ft_timestamp_flag     = FALSE;
+    ft_custom_trace_level = level;
+
+    ft_debug_init();
+  }
+
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Default_Level( void )
+  {
+    ft_component_flag     = FALSE;
+    ft_timestamp_flag     = FALSE;
+    ft_custom_trace_level = NULL;
+
+    ft_debug_init();
+  }
+
+
+  /**************************************************************************
+   *
+   * Functions to handle a custom log handler.
+   *
+   */
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Log_Handler( FT_Custom_Log_Handler  handler )
+  {
+    custom_output_handler = handler;
+  }
+
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Default_Log_Handler( void )
+  {
+    custom_output_handler = NULL;
+  }
+
+
+  /* documentation is in ftdebug.h */
+  FT_BASE_DEF( void )
+  FT_Logging_Callback( const char*  fmt,
+                       ... )
+  {
+    va_list  ap;
+
+
+    va_start( ap, fmt );
+    custom_output_handler( ft_component, fmt, ap );
+    va_end( ap );
+  }
+
+#else /* !FT_DEBUG_LOGGING */
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Level( const char*  level )
+  {
+    FT_UNUSED( level );
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Default_Level( void )
+  {
+    /* nothing */
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Log_Handler( FT_Custom_Log_Handler  handler )
+  {
+    FT_UNUSED( handler );
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Default_Log_Handler( void )
+  {
+    /* nothing */
+  }
+
+#endif /* !FT_DEBUG_LOGGING */
 
 
 /* END */
diff --git a/builds/windows/ftsystem.c b/builds/windows/ftsystem.c
new file mode 100644
index 0000000..418d799
--- /dev/null
+++ b/builds/windows/ftsystem.c
@@ -0,0 +1,499 @@
+/****************************************************************************
+ *
+ * ftsystem.c
+ *
+ *   Windows-specific FreeType low-level system interface (body).
+ *
+ * Copyright (C) 2021-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 <ft2build.h>
+  /* we use our special ftconfig.h file, not the standard one */
+#include FT_CONFIG_CONFIG_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftsystem.h>
+#include <freetype/fterrors.h>
+#include <freetype/fttypes.h>
+#include <freetype/internal/ftstream.h>
+
+  /* memory mapping and allocation includes and definitions */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+  /**************************************************************************
+   *
+   *                      MEMORY MANAGEMENT INTERFACE
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * It is not necessary to do any error checking for the
+   * allocation-related functions.  This will be done by the higher level
+   * routines like ft_mem_alloc() or ft_mem_realloc().
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_alloc
+   *
+   * @Description:
+   *   The memory allocation function.
+   *
+   * @Input:
+   *   memory ::
+   *     A pointer to the memory object.
+   *
+   *   size ::
+   *     The requested size in bytes.
+   *
+   * @Return:
+   *   The address of newly allocated block.
+   */
+  FT_CALLBACK_DEF( void* )
+  ft_alloc( FT_Memory  memory,
+            long       size )
+  {
+    return HeapAlloc( memory->user, 0, size );
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_realloc
+   *
+   * @Description:
+   *   The memory reallocation function.
+   *
+   * @Input:
+   *   memory ::
+   *     A pointer to the memory object.
+   *
+   *   cur_size ::
+   *     The current size of the allocated memory block.
+   *
+   *   new_size ::
+   *     The newly requested size in bytes.
+   *
+   *   block ::
+   *     The current address of the block in memory.
+   *
+   * @Return:
+   *   The address of the reallocated memory block.
+   */
+  FT_CALLBACK_DEF( void* )
+  ft_realloc( FT_Memory  memory,
+              long       cur_size,
+              long       new_size,
+              void*      block )
+  {
+    FT_UNUSED( cur_size );
+
+    return HeapReAlloc( memory->user, 0, block, new_size );
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_free
+   *
+   * @Description:
+   *   The memory release function.
+   *
+   * @Input:
+   *   memory ::
+   *     A pointer to the memory object.
+   *
+   *   block ::
+   *     The address of block in memory to be freed.
+   */
+  FT_CALLBACK_DEF( void )
+  ft_free( FT_Memory  memory,
+           void*      block )
+  {
+    HeapFree( memory->user, 0, block );
+  }
+
+
+  /**************************************************************************
+   *
+   *                    RESOURCE MANAGEMENT INTERFACE
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  io
+
+  /* We use the macro STREAM_FILE for convenience to extract the       */
+  /* system-specific stream handle from a given FreeType stream object */
+#define STREAM_FILE( stream )  ( (FILE*)stream->descriptor.pointer )
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_close_stream_by_munmap
+   *
+   * @Description:
+   *   The function to close a stream which is opened by mmap.
+   *
+   * @Input:
+   *   stream :: A pointer to the stream object.
+   */
+  FT_CALLBACK_DEF( void )
+  ft_close_stream_by_munmap( FT_Stream  stream )
+  {
+    UnmapViewOfFile( (LPCVOID)stream->descriptor.pointer );
+
+    stream->descriptor.pointer = NULL;
+    stream->size               = 0;
+    stream->base               = NULL;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   ft_close_stream_by_free
+   *
+   * @Description:
+   *   The function to close a stream which is created by ft_alloc.
+   *
+   * @Input:
+   *   stream :: A pointer to the stream object.
+   */
+  FT_CALLBACK_DEF( void )
+  ft_close_stream_by_free( FT_Stream  stream )
+  {
+    ft_free( stream->memory, stream->descriptor.pointer );
+
+    stream->descriptor.pointer = NULL;
+    stream->size               = 0;
+    stream->base               = NULL;
+  }
+
+
+  /* non-desktop Universal Windows Platform */
+#if defined( WINAPI_FAMILY ) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP
+
+#define PACK_DWORD64( hi, lo )  ( ( (DWORD64)(hi) << 32 ) | (DWORD)(lo) )
+
+#define CreateFileMapping( a, b, c, d, e, f )                          \
+          CreateFileMappingFromApp( a, b, c, PACK_DWORD64( d, e ), f )
+#define MapViewOfFile( a, b, c, d, e )                                 \
+          MapViewOfFileFromApp( a, b, PACK_DWORD64( c, d ), e )
+
+  FT_LOCAL_DEF( HANDLE )
+  CreateFileA( LPCSTR                 lpFileName,
+               DWORD                  dwDesiredAccess,
+               DWORD                  dwShareMode,
+               LPSECURITY_ATTRIBUTES  lpSecurityAttributes,
+               DWORD                  dwCreationDisposition,
+               DWORD                  dwFlagsAndAttributes,
+               HANDLE                 hTemplateFile )
+  {
+    int     len;
+    LPWSTR  lpFileNameW;
+
+    CREATEFILE2_EXTENDED_PARAMETERS  createExParams = {
+      sizeof ( CREATEFILE2_EXTENDED_PARAMETERS ),
+      dwFlagsAndAttributes & 0x0000FFFF,
+      dwFlagsAndAttributes & 0xFFF00000,
+      dwFlagsAndAttributes & 0x000F0000,
+      lpSecurityAttributes,
+      hTemplateFile };
+
+
+    /* allocate memory space for converted path name */
+    len = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
+                               lpFileName, -1, NULL, 0 );
+
+    lpFileNameW = (LPWSTR)_alloca( len * sizeof ( WCHAR ) );
+
+    if ( !len || !lpFileNameW )
+    {
+      FT_ERROR(( "FT_Stream_Open: cannot convert file name to LPWSTR\n" ));
+      return INVALID_HANDLE_VALUE;
+    }
+
+    /* now it is safe to do the translation */
+    MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
+                         lpFileName, -1, lpFileNameW, len );
+
+    /* open the file */
+    return CreateFile2( lpFileNameW, dwDesiredAccess, dwShareMode,
+                        dwCreationDisposition, &createExParams );
+  }
+
+#endif
+
+
+#if defined( _WIN32_WCE )
+
+  /* malloc.h provides implementation of alloca()/_alloca() */
+  #include <malloc.h>
+
+  FT_LOCAL_DEF( HANDLE )
+  CreateFileA( LPCSTR                 lpFileName,
+               DWORD                  dwDesiredAccess,
+               DWORD                  dwShareMode,
+               LPSECURITY_ATTRIBUTES  lpSecurityAttributes,
+               DWORD                  dwCreationDisposition,
+               DWORD                  dwFlagsAndAttributes,
+               HANDLE                 hTemplateFile )
+  {
+    int     len;
+    LPWSTR  lpFileNameW;
+
+
+    /* allocate memory space for converted path name */
+    len = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
+                               lpFileName, -1, NULL, 0 );
+
+    lpFileNameW = (LPWSTR)_alloca( len * sizeof ( WCHAR ) );
+
+    if ( !len || !lpFileNameW )
+    {
+      FT_ERROR(( "FT_Stream_Open: cannot convert file name to LPWSTR\n" ));
+      return INVALID_HANDLE_VALUE;
+    }
+
+    /* now it is safe to do the translation */
+    MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
+                         lpFileName, -1, lpFileNameW, len );
+
+    /* open the file */
+    return CreateFileW( lpFileNameW, dwDesiredAccess, dwShareMode,
+                        lpSecurityAttributes, dwCreationDisposition,
+                        dwFlagsAndAttributes, hTemplateFile );
+  }
+
+#endif
+
+
+#if defined( _WIN32_WCE ) || defined ( _WIN32_WINDOWS ) || \
+    !defined( _WIN32_WINNT ) || _WIN32_WINNT <= 0x0400
+
+  FT_LOCAL_DEF( BOOL )
+  GetFileSizeEx( HANDLE          hFile,
+                 PLARGE_INTEGER  lpFileSize )
+  {
+    lpFileSize->u.LowPart = GetFileSize( hFile,
+                                         (DWORD *)&lpFileSize->u.HighPart );
+
+    if ( lpFileSize->u.LowPart == INVALID_FILE_SIZE &&
+         GetLastError() != NO_ERROR                 )
+      return FALSE;
+    else
+      return TRUE;
+  }
+
+#endif
+
+
+  /* documentation is in ftobjs.h */
+
+  FT_BASE_DEF( FT_Error )
+  FT_Stream_Open( FT_Stream    stream,
+                  const char*  filepathname )
+  {
+    HANDLE         file;
+    HANDLE         fm;
+    LARGE_INTEGER  size;
+
+
+    if ( !stream )
+      return FT_THROW( Invalid_Stream_Handle );
+
+    /* open the file */
+    file = CreateFileA( (LPCSTR)filepathname, GENERIC_READ, FILE_SHARE_READ,
+                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
+    if ( file == INVALID_HANDLE_VALUE )
+    {
+      FT_ERROR(( "FT_Stream_Open:" ));
+      FT_ERROR(( " could not open `%s'\n", filepathname ));
+      return FT_THROW( Cannot_Open_Resource );
+    }
+
+    if ( GetFileSizeEx( file, &size ) == FALSE )
+    {
+      FT_ERROR(( "FT_Stream_Open:" ));
+      FT_ERROR(( " could not retrieve size of file `%s'\n", filepathname ));
+      goto Fail_Open;
+    }
+
+    /* `stream->size' is typedef'd to unsigned long (in `ftsystem.h'); */
+    /* So avoid overflow caused by fonts in huge files larger than     */
+    /* 2GB, do a test.                                                 */
+    if ( size.QuadPart > LONG_MAX )
+    {
+      FT_ERROR(( "FT_Stream_Open: file is too big\n" ));
+      goto Fail_Open;
+    }
+    else if ( size.QuadPart == 0 )
+    {
+      FT_ERROR(( "FT_Stream_Open: zero-length file\n" ));
+      goto Fail_Open;
+    }
+
+    fm = CreateFileMapping( file, NULL, PAGE_READONLY, 0, 0, NULL );
+    if ( fm == NULL )
+    {
+      FT_ERROR(( "FT_Stream_Open: can not map file\n" ));
+      goto Fail_Open;
+    }
+
+    /* Store only the low part of this 64 bits integer because long is */
+    /* a 32 bits type. Anyway, a check has been done above to forbid   */
+    /* a size greater than LONG_MAX                                    */
+    stream->size = size.LowPart;
+    stream->pos  = 0;
+    stream->base = (unsigned char *)
+                     MapViewOfFile( fm, FILE_MAP_READ, 0, 0, 0 );
+
+    CloseHandle( fm );
+
+    if ( stream->base != NULL )
+      stream->close = ft_close_stream_by_munmap;
+    else
+    {
+      DWORD  total_read_count;
+
+
+      FT_ERROR(( "FT_Stream_Open:" ));
+      FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
+
+      stream->base = (unsigned char*)ft_alloc( stream->memory, stream->size );
+
+      if ( !stream->base )
+      {
+        FT_ERROR(( "FT_Stream_Open:" ));
+        FT_ERROR(( " could not `alloc' memory\n" ));
+        goto Fail_Open;
+      }
+
+      total_read_count = 0;
+      do
+      {
+        DWORD  read_count;
+
+
+        if ( ReadFile( file,
+                       stream->base + total_read_count,
+                       stream->size - total_read_count,
+                       &read_count, NULL ) == FALSE )
+        {
+          FT_ERROR(( "FT_Stream_Open:" ));
+          FT_ERROR(( " error while `read'ing file `%s'\n", filepathname ));
+          goto Fail_Read;
+        }
+
+        total_read_count += read_count;
+
+      } while ( total_read_count != stream->size );
+
+      stream->close = ft_close_stream_by_free;
+    }
+
+    CloseHandle( file );
+
+    stream->descriptor.pointer = stream->base;
+    stream->pathname.pointer   = (char*)filepathname;
+
+    stream->read = NULL;
+
+    FT_TRACE1(( "FT_Stream_Open:" ));
+    FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
+                filepathname, stream->size ));
+
+    return FT_Err_Ok;
+
+  Fail_Read:
+    ft_free( stream->memory, stream->base );
+
+  Fail_Open:
+    CloseHandle( file );
+
+    stream->base = NULL;
+    stream->size = 0;
+    stream->pos  = 0;
+
+    return FT_THROW( Cannot_Open_Stream );
+  }
+
+
+#ifdef FT_DEBUG_MEMORY
+
+  extern FT_Int
+  ft_mem_debug_init( FT_Memory  memory );
+
+  extern void
+  ft_mem_debug_done( FT_Memory  memory );
+
+#endif
+
+
+  /* documentation is in ftobjs.h */
+
+  FT_BASE_DEF( FT_Memory )
+  FT_New_Memory( void )
+  {
+    HANDLE     heap;
+    FT_Memory  memory;
+
+
+    heap   = GetProcessHeap();
+    memory = heap ? (FT_Memory)HeapAlloc( heap, 0, sizeof ( *memory ) )
+                  : NULL;
+
+    if ( memory )
+    {
+      memory->user    = heap;
+      memory->alloc   = ft_alloc;
+      memory->realloc = ft_realloc;
+      memory->free    = ft_free;
+#ifdef FT_DEBUG_MEMORY
+      ft_mem_debug_init( memory );
+#endif
+    }
+
+    return memory;
+  }
+
+
+  /* documentation is in ftobjs.h */
+
+  FT_BASE_DEF( void )
+  FT_Done_Memory( FT_Memory  memory )
+  {
+#ifdef FT_DEBUG_MEMORY
+    ft_mem_debug_done( memory );
+#endif
+    memory->free( memory, memory );
+  }
+
+
+/* END */
diff --git a/builds/windows/vc2005/freetype.sln b/builds/windows/vc2005/freetype.sln
deleted file mode 100644
index ec3345d..0000000
--- a/builds/windows/vc2005/freetype.sln
+++ /dev/null
@@ -1,31 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 9.00

-# Visual Studio 2005

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "freetype.vcproj", "{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"

-EndProject

-Global

-	GlobalSection(SolutionConfigurationPlatforms) = preSolution

-		LIB Debug Multithreaded|Win32 = LIB Debug Multithreaded|Win32

-		LIB Debug Singlethreaded|Win32 = LIB Debug Singlethreaded|Win32

-		LIB Debug|Win32 = LIB Debug|Win32

-		LIB Release Multithreaded|Win32 = LIB Release Multithreaded|Win32

-		LIB Release Singlethreaded|Win32 = LIB Release Singlethreaded|Win32

-		LIB Release|Win32 = LIB Release|Win32

-	EndGlobalSection

-	GlobalSection(ProjectConfigurationPlatforms) = postSolution

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Multithreaded|Win32.ActiveCfg = Debug Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Multithreaded|Win32.Build.0 = Debug Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Singlethreaded|Win32.ActiveCfg = Debug Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Singlethreaded|Win32.Build.0 = Debug Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug|Win32.ActiveCfg = Debug|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug|Win32.Build.0 = Debug|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Multithreaded|Win32.ActiveCfg = Release Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Multithreaded|Win32.Build.0 = Release Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Singlethreaded|Win32.ActiveCfg = Release Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Singlethreaded|Win32.Build.0 = Release Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Win32.ActiveCfg = Release|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Win32.Build.0 = Release|Win32

-	EndGlobalSection

-	GlobalSection(SolutionProperties) = preSolution

-		HideSolutionNode = FALSE

-	EndGlobalSection

-EndGlobal

diff --git a/builds/windows/vc2005/freetype.vcproj b/builds/windows/vc2005/freetype.vcproj
deleted file mode 100644
index b1e2ae6..0000000
--- a/builds/windows/vc2005/freetype.vcproj
+++ /dev/null
@@ -1,217 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>

-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="freetype" ProjectGUID="{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}" TargetFrameworkVersion="131072">

-  <Platforms>

-    <Platform Name="Win32" />

-  </Platforms>

-  <ToolFiles>

-  </ToolFiles>

-  <Configurations>

-    <Configuration Name="Release|Win32" OutputDirectory=".\..\..\..\objs\release" IntermediateDirectory=".\..\..\..\objs\release" ConfigurationType="4" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2">

-      <Tool Name="VCPreBuildEventTool" />

-      <Tool Name="VCCustomBuildTool" />

-      <Tool Name="VCXMLDataGeneratorTool" />

-      <Tool Name="VCWebServiceProxyGeneratorTool" />

-      <Tool Name="VCMIDLTool" />

-      <Tool Name="VCCLCompilerTool" Optimization="2" InlineFunctionExpansion="1" AdditionalIncludeDirectories="..\..\..\include" PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY" StringPooling="true" RuntimeLibrary="2" EnableFunctionLevelLinking="true" DisableLanguageExtensions="true" PrecompiledHeaderFile=".\..\..\..\objs\release/freetype.pch" AssemblerListingLocation=".\..\..\..\objs\release/" ObjectFile=".\..\..\..\objs\release/" ProgramDataBaseFileName=".\..\..\..\objs\release/" WarningLevel="4" DebugInformationFormat="0" CompileAs="0" />

-      <Tool Name="VCManagedResourceCompilerTool" />

-      <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

-      <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\win32\vc2005\freetype291.lib" SuppressStartupBanner="true" />

-      <Tool Name="VCALinkTool" />

-      <Tool Name="VCXDCMakeTool" />

-      <Tool Name="VCBscMakeTool" />

-      <Tool Name="VCFxCopTool" />

-      <Tool Name="VCPostBuildEventTool" />

-    </Configuration>

-    <Configuration Name="Release Multithreaded|Win32" OutputDirectory=".\..\..\..\objs\release_mt" IntermediateDirectory=".\..\..\..\objs\release_mt" ConfigurationType="4" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2">

-      <Tool Name="VCPreBuildEventTool" />

-      <Tool Name="VCCustomBuildTool" />

-      <Tool Name="VCXMLDataGeneratorTool" />

-      <Tool Name="VCWebServiceProxyGeneratorTool" />

-      <Tool Name="VCMIDLTool" />

-      <Tool Name="VCCLCompilerTool" Optimization="2" InlineFunctionExpansion="1" AdditionalIncludeDirectories="..\..\..\include" PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY" StringPooling="true" RuntimeLibrary="0" EnableFunctionLevelLinking="true" DisableLanguageExtensions="true" PrecompiledHeaderFile=".\..\..\..\objs\release_mt/freetype.pch" AssemblerListingLocation=".\..\..\..\objs\release_mt/" ObjectFile=".\..\..\..\objs\release_mt/" ProgramDataBaseFileName=".\..\..\..\objs\release_mt/" WarningLevel="4" DebugInformationFormat="0" CompileAs="0" />

-      <Tool Name="VCManagedResourceCompilerTool" />

-      <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

-      <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\win32\vc2005\freetype291MT.lib" SuppressStartupBanner="true" />

-      <Tool Name="VCALinkTool" />

-      <Tool Name="VCXDCMakeTool" />

-      <Tool Name="VCBscMakeTool" />

-      <Tool Name="VCFxCopTool" />

-      <Tool Name="VCPostBuildEventTool" />

-    </Configuration>

-    <Configuration Name="Release Singlethreaded|Win32" OutputDirectory=".\..\..\..\objs\release_st" IntermediateDirectory=".\..\..\..\objs\release_st" ConfigurationType="4" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2">

-      <Tool Name="VCPreBuildEventTool" />

-      <Tool Name="VCCustomBuildTool" />

-      <Tool Name="VCXMLDataGeneratorTool" />

-      <Tool Name="VCWebServiceProxyGeneratorTool" />

-      <Tool Name="VCMIDLTool" />

-      <Tool Name="VCCLCompilerTool" Optimization="2" InlineFunctionExpansion="1" AdditionalIncludeDirectories="..\..\..\include" PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY" StringPooling="true" RuntimeLibrary="0" EnableFunctionLevelLinking="true" DisableLanguageExtensions="true" PrecompiledHeaderFile=".\..\..\..\objs\release_st/freetype.pch" AssemblerListingLocation=".\..\..\..\objs\release_st/" ObjectFile=".\..\..\..\objs\release_st/" ProgramDataBaseFileName=".\..\..\..\objs\release_st/" WarningLevel="4" DebugInformationFormat="0" CompileAs="0" />

-      <Tool Name="VCManagedResourceCompilerTool" />

-      <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="NDEBUG" Culture="1033" />

-      <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\win32\vc2005\freetype291ST.lib" />

-      <Tool Name="VCALinkTool" />

-      <Tool Name="VCXDCMakeTool" />

-      <Tool Name="VCBscMakeTool" />

-      <Tool Name="VCFxCopTool" />

-      <Tool Name="VCPostBuildEventTool" />

-    </Configuration>

-    <Configuration Name="Debug|Win32" OutputDirectory=".\..\..\..\objs\debug" IntermediateDirectory=".\..\..\..\objs\debug" ConfigurationType="4" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2">

-      <Tool Name="VCPreBuildEventTool" />

-      <Tool Name="VCCustomBuildTool" />

-      <Tool Name="VCXMLDataGeneratorTool" />

-      <Tool Name="VCWebServiceProxyGeneratorTool" />

-      <Tool Name="VCMIDLTool" />

-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\..\include" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY" BasicRuntimeChecks="3" RuntimeLibrary="3" DisableLanguageExtensions="true" PrecompiledHeaderFile=".\..\..\..\objs\debug/freetype.pch" AssemblerListingLocation=".\..\..\..\objs\debug/" ObjectFile=".\..\..\..\objs\debug/" ProgramDataBaseFileName=".\..\..\..\objs\debug/" WarningLevel="4" DebugInformationFormat="3" CompileAs="0" />

-      <Tool Name="VCManagedResourceCompilerTool" />

-      <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

-      <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\win32\vc2005\freetype291_D.lib" SuppressStartupBanner="true" />

-      <Tool Name="VCALinkTool" />

-      <Tool Name="VCXDCMakeTool" />

-      <Tool Name="VCBscMakeTool" />

-      <Tool Name="VCFxCopTool" />

-      <Tool Name="VCPostBuildEventTool" />

-    </Configuration>

-    <Configuration Name="Debug Singlethreaded|Win32" OutputDirectory=".\..\..\..\objs\debug_st" IntermediateDirectory=".\..\..\..\objs\debug_st" ConfigurationType="4" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2">

-      <Tool Name="VCPreBuildEventTool" />

-      <Tool Name="VCCustomBuildTool" />

-      <Tool Name="VCXMLDataGeneratorTool" />

-      <Tool Name="VCWebServiceProxyGeneratorTool" />

-      <Tool Name="VCMIDLTool" />

-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\..\include" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY" BasicRuntimeChecks="3" RuntimeLibrary="1" DisableLanguageExtensions="true" PrecompiledHeaderFile=".\..\..\..\objs\debug_st/freetype.pch" AssemblerListingLocation=".\..\..\..\objs\debug_st/" ObjectFile=".\..\..\..\objs\debug_st/" ProgramDataBaseFileName=".\..\..\..\objs\debug_st/" WarningLevel="4" DebugInformationFormat="3" CompileAs="0" />

-      <Tool Name="VCManagedResourceCompilerTool" />

-      <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

-      <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\win32\vc2005\freetype291ST_D.lib" SuppressStartupBanner="true" />

-      <Tool Name="VCALinkTool" />

-      <Tool Name="VCXDCMakeTool" />

-      <Tool Name="VCBscMakeTool" />

-      <Tool Name="VCFxCopTool" />

-      <Tool Name="VCPostBuildEventTool" />

-    </Configuration>

-    <Configuration Name="Debug Multithreaded|Win32" OutputDirectory=".\..\..\..\objs\debug_mt" IntermediateDirectory=".\..\..\..\objs\debug_mt" ConfigurationType="4" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2">

-      <Tool Name="VCPreBuildEventTool" />

-      <Tool Name="VCCustomBuildTool" />

-      <Tool Name="VCXMLDataGeneratorTool" />

-      <Tool Name="VCWebServiceProxyGeneratorTool" />

-      <Tool Name="VCMIDLTool" />

-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\..\include" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE" GeneratePreprocessedFile="0" BasicRuntimeChecks="3" RuntimeLibrary="1" DisableLanguageExtensions="true" PrecompiledHeaderFile=".\..\..\..\objs\debug_mt/freetype.pch" AssemblerListingLocation=".\..\..\..\objs\debug_mt/" ObjectFile=".\..\..\..\objs\debug_mt/" ProgramDataBaseFileName=".\..\..\..\objs\debug_mt/" WarningLevel="4" DebugInformationFormat="3" CompileAs="0" />

-      <Tool Name="VCManagedResourceCompilerTool" />

-      <Tool Name="VCResourceCompilerTool" PreprocessorDefinitions="_DEBUG" Culture="1033" />

-      <Tool Name="VCPreLinkEventTool" />

-      <Tool Name="VCLibrarianTool" OutputFile="..\..\..\objs\win32\vc2005\freetype291MT_D.lib" SuppressStartupBanner="true" />

-      <Tool Name="VCALinkTool" />

-      <Tool Name="VCXDCMakeTool" />

-      <Tool Name="VCBscMakeTool" />

-      <Tool Name="VCFxCopTool" />

-      <Tool Name="VCPostBuildEventTool" />

-    </Configuration>

-  </Configurations>

-  <References>

-  </References>

-  <Files>

-    <Filter Name="Source Files" Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">

-      <File RelativePath="..\..\..\src\autofit\autofit.c">

-      </File>

-      <File RelativePath="..\..\..\src\bdf\bdf.c">

-      </File>

-      <File RelativePath="..\..\..\src\cff\cff.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftbase.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftbitmap.c">

-      </File>

-      <File RelativePath="..\..\..\src\cache\ftcache.c">

-      </File>

-      <File RelativePath="..\ftdebug.c">

-        <FileConfiguration>

-          <Tool Name="VCCLCompilerTool" DisableLanguageExtensions="false" />

-        </FileConfiguration>

-      </File>

-      <File RelativePath="..\..\..\src\base\ftfstype.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftgasp.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftglyph.c">

-      </File>

-      <File RelativePath="..\..\..\src\gzip\ftgzip.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftinit.c">

-      </File>

-      <File RelativePath="..\..\..\src\lzw\ftlzw.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftstroke.c">

-      </File>

-      <File RelativePath="..\..\..\src\base\ftsystem.c">

-      </File>

-      <File RelativePath="..\..\..\src\smooth\smooth.c">

-      </File>

-      <Filter Name="FT_MODULES">

-        <File RelativePath="..\..\..\src\base\ftbdf.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftbbox.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftcid.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftmm.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftpfr.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftsynth.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\fttype1.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftwinfnt.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftgxval.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftotval.c">

-        </File>

-        <File RelativePath="..\..\..\src\base\ftpatent.c">

-        </File>

-        <File RelativePath="..\..\..\src\pcf\pcf.c">

-        </File>

-        <File RelativePath="..\..\..\src\pfr\pfr.c">

-        </File>

-        <File RelativePath="..\..\..\src\psaux\psaux.c">

-        </File>

-        <File RelativePath="..\..\..\src\pshinter\pshinter.c">

-        </File>

-        <File RelativePath="..\..\..\src\psnames\psmodule.c">

-        </File>

-        <File RelativePath="..\..\..\src\raster\raster.c">

-        </File>

-        <File RelativePath="..\..\..\src\sfnt\sfnt.c">

-        </File>

-        <File RelativePath="..\..\..\src\truetype\truetype.c">

-        </File>

-        <File RelativePath="..\..\..\src\type1\type1.c">

-        </File>

-        <File RelativePath="..\..\..\src\cid\type1cid.c">

-        </File>

-        <File RelativePath="..\..\..\src\type42\type42.c">

-        </File>

-        <File RelativePath="..\..\..\src\winfonts\winfnt.c">

-        </File>

-      </Filter>

-    </Filter>

-    <Filter Name="Header Files" Filter="h;hpp;hxx;hm;inl">

-      <File RelativePath="..\..\..\include\ft2build.h">

-      </File>

-      <File RelativePath="..\..\..\include\freetype\config\ftconfig.h">

-      </File>

-      <File RelativePath="..\..\..\include\freetype\config\ftheader.h">

-      </File>

-      <File RelativePath="..\..\..\include\freetype\config\ftmodule.h">

-      </File>

-      <File RelativePath="..\..\..\include\freetype\config\ftoption.h">

-      </File>

-      <File RelativePath="..\..\..\include\freetype\config\ftstdlib.h">

-      </File>

-    </Filter>

-  </Files>

-  <Globals>

-  </Globals>

-</VisualStudioProject>

diff --git a/builds/windows/vc2005/index.html b/builds/windows/vc2005/index.html
deleted file mode 100644
index c5e182e..0000000
--- a/builds/windows/vc2005/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html>
-<header>
-<title>
-  FreeType&nbsp;2 Project Files for VS.NET&nbsp;2005
-</title>
-
-<body>
-<h1>
-  FreeType&nbsp;2 Project Files for VS.NET&nbsp;2005
-</h1>
-
-<p>This directory contains project files for Visual C++, named
-<tt>freetype.vcproj</tt>, and Visual Studio, called <tt>freetype.sln</tt>.  It
-compiles the following libraries from the FreeType 2.9.1 sources:</p>
-
-<ul>
-  <pre>
-    freetype291.lib     - release build; single threaded
-    freetype291_D.lib   - debug build;   single threaded
-    freetype291MT.lib   - release build; multi-threaded
-    freetype291MT_D.lib - debug build;   multi-threaded</pre>
-</ul>
-
-<p>Be sure to extract the files with the Windows (CR+LF) line endings.  ZIP
-archives are already stored this way, so no further action is required.  If
-you use some <tt>.tar.*z</tt> archives, be sure to configure your extracting
-tool to convert the line endings.  For example, with <a
-href="http://www.winzip.com">WinZip</a>, you should activate the <em>TAR
-file smart CR/LF Conversion</em> option.  Alternatively, you may consider
-using the <tt>unix2dos</tt> or <tt>u2d</tt> utilities that are floating
-around, which specifically deal with this particular problem.
-
-<p>Build directories are placed in the top-level <tt>objs</tt>
-directory.</p>
-
-</body>
-</html>
diff --git a/builds/windows/vc2008/freetype.sln b/builds/windows/vc2008/freetype.sln
deleted file mode 100644
index 6c522f9..0000000
--- a/builds/windows/vc2008/freetype.sln
+++ /dev/null
@@ -1,31 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 10.00

-# Visual Studio 2008

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "freetype.vcproj", "{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"

-EndProject

-Global

-	GlobalSection(SolutionConfigurationPlatforms) = preSolution

-		LIB Debug Multithreaded|Win32 = LIB Debug Multithreaded|Win32

-		LIB Debug Singlethreaded|Win32 = LIB Debug Singlethreaded|Win32

-		LIB Debug|Win32 = LIB Debug|Win32

-		LIB Release Multithreaded|Win32 = LIB Release Multithreaded|Win32

-		LIB Release Singlethreaded|Win32 = LIB Release Singlethreaded|Win32

-		LIB Release|Win32 = LIB Release|Win32

-	EndGlobalSection

-	GlobalSection(ProjectConfigurationPlatforms) = postSolution

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Multithreaded|Win32.ActiveCfg = Debug Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Multithreaded|Win32.Build.0 = Debug Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Singlethreaded|Win32.ActiveCfg = Debug Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug Singlethreaded|Win32.Build.0 = Debug Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug|Win32.ActiveCfg = Debug|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Debug|Win32.Build.0 = Debug|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Multithreaded|Win32.ActiveCfg = Release Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Multithreaded|Win32.Build.0 = Release Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Singlethreaded|Win32.ActiveCfg = Release Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release Singlethreaded|Win32.Build.0 = Release Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Win32.ActiveCfg = Release|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.LIB Release|Win32.Build.0 = Release|Win32

-	EndGlobalSection

-	GlobalSection(SolutionProperties) = preSolution

-		HideSolutionNode = FALSE

-	EndGlobalSection

-EndGlobal

diff --git a/builds/windows/vc2008/freetype.vcproj b/builds/windows/vc2008/freetype.vcproj
deleted file mode 100644
index f526cd2..0000000
--- a/builds/windows/vc2008/freetype.vcproj
+++ /dev/null
@@ -1,668 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>

-<VisualStudioProject

-	ProjectType="Visual C++"

-	Version="9,00"

-	Name="freetype"

-	ProjectGUID="{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"

-	TargetFrameworkVersion="131072"

-	>

-	<Platforms>

-		<Platform

-			Name="Win32"

-		/>

-	</Platforms>

-	<ToolFiles>

-	</ToolFiles>

-	<Configurations>

-		<Configuration

-			Name="Release|Win32"

-			OutputDirectory=".\..\..\..\objs\release"

-			IntermediateDirectory=".\..\..\..\objs\release"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="2"

-				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY"

-				StringPooling="true"

-				RuntimeLibrary="2"

-				EnableFunctionLevelLinking="true"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\release/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\release/"

-				ObjectFile=".\..\..\..\objs\release/"

-				ProgramDataBaseFileName=".\..\..\..\objs\release/"

-				WarningLevel="4"

-				DebugInformationFormat="0"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="NDEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\win32\vc2008\freetype291.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Release Multithreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\release_mt"

-			IntermediateDirectory=".\..\..\..\objs\release_mt"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="2"

-				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY"

-				StringPooling="true"

-				RuntimeLibrary="0"

-				EnableFunctionLevelLinking="true"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\release_mt/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\release_mt/"

-				ObjectFile=".\..\..\..\objs\release_mt/"

-				ProgramDataBaseFileName=".\..\..\..\objs\release_mt/"

-				WarningLevel="4"

-				DebugInformationFormat="0"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="NDEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\win32\vc2008\freetype291MT.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Release Singlethreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\release_st"

-			IntermediateDirectory=".\..\..\..\objs\release_st"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="2"

-				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY"

-				StringPooling="true"

-				RuntimeLibrary="0"

-				EnableFunctionLevelLinking="true"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\release_st/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\release_st/"

-				ObjectFile=".\..\..\..\objs\release_st/"

-				ProgramDataBaseFileName=".\..\..\..\objs\release_st/"

-				WarningLevel="4"

-				DebugInformationFormat="0"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="NDEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\win32\vc2008\freetype291ST.lib"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Debug|Win32"

-			OutputDirectory=".\..\..\..\objs\debug"

-			IntermediateDirectory=".\..\..\..\objs\debug"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="0"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY"

-				BasicRuntimeChecks="3"

-				RuntimeLibrary="3"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\debug/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\debug/"

-				ObjectFile=".\..\..\..\objs\debug/"

-				ProgramDataBaseFileName=".\..\..\..\objs\debug/"

-				WarningLevel="4"

-				DebugInformationFormat="3"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="_DEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\win32\vc2008\freetype291_D.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Debug Singlethreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\debug_st"

-			IntermediateDirectory=".\..\..\..\objs\debug_st"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="0"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY"

-				BasicRuntimeChecks="3"

-				RuntimeLibrary="1"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\debug_st/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\debug_st/"

-				ObjectFile=".\..\..\..\objs\debug_st/"

-				ProgramDataBaseFileName=".\..\..\..\objs\debug_st/"

-				WarningLevel="4"

-				DebugInformationFormat="3"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="_DEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\win32\vc2008\freetype291ST_D.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Debug Multithreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\debug_mt"

-			IntermediateDirectory=".\..\..\..\objs\debug_mt"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="0"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE"

-				GeneratePreprocessedFile="0"

-				BasicRuntimeChecks="3"

-				RuntimeLibrary="1"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\debug_mt/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\debug_mt/"

-				ObjectFile=".\..\..\..\objs\debug_mt/"

-				ProgramDataBaseFileName=".\..\..\..\objs\debug_mt/"

-				WarningLevel="4"

-				DebugInformationFormat="3"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="_DEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\win32\vc2008\freetype291MT_D.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-	</Configurations>

-	<References>

-	</References>

-	<Files>

-		<Filter

-			Name="Source Files"

-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

-			>

-			<File

-				RelativePath="..\..\..\src\autofit\autofit.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\bdf\bdf.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\cff\cff.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftbase.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftbitmap.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\cache\ftcache.c"

-				>

-			</File>

-			<File

-				RelativePath="..\ftdebug.c"

-				>

-				<FileConfiguration>

-					<Tool

-						Name="VCCLCompilerTool"

-						DisableLanguageExtensions="false"

-					/>

-				</FileConfiguration>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftfstype.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftgasp.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftglyph.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\gzip\ftgzip.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftinit.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\lzw\ftlzw.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftstroke.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftsystem.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\smooth\smooth.c"

-				>

-			</File>

-			<Filter

-				Name="FT_MODULES"

-				>

-				<File

-					RelativePath="..\..\..\src\base\ftbbox.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftbdf.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftcid.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftmm.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftpfr.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftsynth.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\fttype1.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftwinfnt.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftgxval.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftotval.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftpatent.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\pcf\pcf.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\pfr\pfr.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\psaux\psaux.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\pshinter\pshinter.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\psnames\psmodule.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\raster\raster.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\sfnt\sfnt.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\truetype\truetype.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\type1\type1.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\cid\type1cid.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\type42\type42.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\winfonts\winfnt.c"

-					>

-				</File>

-			</Filter>

-		</Filter>

-		<Filter

-			Name="Header Files"

-			Filter="h;hpp;hxx;hm;inl"

-			>

-			<File

-				RelativePath="..\..\..\include\ft2build.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\include\freetype\config\ftconfig.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\include\freetype\config\ftheader.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\include\freetype\config\ftmodule.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\include\freetype\config\ftoption.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\include\freetype\config\ftstdlib.h"

-				>

-			</File>

-		</Filter>

-	</Files>

-	<Globals>

-	</Globals>

-</VisualStudioProject>

diff --git a/builds/windows/vc2008/index.html b/builds/windows/vc2008/index.html
deleted file mode 100644
index 25c6f9b..0000000
--- a/builds/windows/vc2008/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html>
-<header>
-<title>
-  FreeType&nbsp;2 Project Files for VS.NET&nbsp;2008
-</title>
-
-<body>
-<h1>
-  FreeType&nbsp;2 Project Files for VS.NET&nbsp;2008
-</h1>
-
-<p>This directory contains project files for Visual C++, named
-<tt>freetype.vcproj</tt>, and Visual Studio, called <tt>freetype.sln</tt>.  It
-compiles the following libraries from the FreeType 2.9.1 sources:</p>
-
-<ul>
-  <pre>
-    freetype291.lib     - release build; single threaded
-    freetype291_D.lib   - debug build;   single threaded
-    freetype291MT.lib   - release build; multi-threaded
-    freetype291MT_D.lib - debug build;   multi-threaded</pre>
-</ul>
-
-<p>Be sure to extract the files with the Windows (CR+LF) line endings.  ZIP
-archives are already stored this way, so no further action is required.  If
-you use some <tt>.tar.*z</tt> archives, be sure to configure your extracting
-tool to convert the line endings.  For example, with <a
-href="http://www.winzip.com">WinZip</a>, you should activate the <em>TAR
-file smart CR/LF Conversion</em> option.  Alternatively, you may consider
-using the <tt>unix2dos</tt> or <tt>u2d</tt> utilities that are floating
-around, which specifically deal with this particular problem.
-
-<p>Build directories are placed in the top-level <tt>objs</tt>
-directory.</p>
-
-</body>
-</html>
diff --git a/builds/windows/vc2010/freetype.sln b/builds/windows/vc2010/freetype.sln
index 8698207..d88d70a 100644
--- a/builds/windows/vc2010/freetype.sln
+++ b/builds/windows/vc2010/freetype.sln
@@ -4,34 +4,49 @@
 EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

-		Debug|Win32 = Debug|Win32

 		Debug|x64 = Debug|x64

-		Debug Static|Win32 = Debug Static|Win32

+		Debug|ARM64 = Debug|ARM64

+		Debug|Win32 = Debug|Win32

 		Debug Static|x64 = Debug Static|x64

-		Release|Win32 = Release|Win32

+		Debug Static|ARM64 = Debug Static|ARM64

+		Debug Static|Win32 = Debug Static|Win32

 		Release|x64 = Release|x64

-		Release Static|Win32 = Release Static|Win32

+		Release|ARM64 = Release|ARM64

+		Release|Win32 = Release|Win32

 		Release Static|x64 = Release Static|x64

+		Release Static|ARM64 = Release Static|ARM64

+		Release Static|Win32 = Release Static|Win32

 	EndGlobalSection

 	GlobalSection(ProjectConfigurationPlatforms) = postSolution

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.ActiveCfg = Debug|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.Build.0 = Debug|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.ActiveCfg = Debug|x64

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.Build.0 = Debug|x64

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.ActiveCfg = Debug Static|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.Build.0 = Debug Static|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|ARM64.ActiveCfg = Debug|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|ARM64.Build.0 = Debug|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.ActiveCfg = Debug|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.Build.0 = Debug|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|x64.ActiveCfg = Debug Static|x64

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|x64.Build.0 = Debug Static|x64

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.ActiveCfg = Release|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.Build.0 = Release|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|ARM64.ActiveCfg = Debug Static|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|ARM64.Build.0 = Debug Static|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.ActiveCfg = Debug Static|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.Build.0 = Debug Static|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.ActiveCfg = Release|x64

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.Build.0 = Release|x64

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.ActiveCfg = Release Static|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.Build.0 = Release Static|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|ARM64.ActiveCfg = Release|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|ARM64.Build.0 = Release|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.ActiveCfg = Release|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.Build.0 = Release|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|x64.ActiveCfg = Release Static|x64

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|x64.Build.0 = Release Static|x64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|ARM64.ActiveCfg = Release Static|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|ARM64.Build.0 = Release Static|ARM64

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.ActiveCfg = Release Static|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.Build.0 = Release Static|Win32

 	EndGlobalSection

 	GlobalSection(SolutionProperties) = preSolution

 		HideSolutionNode = FALSE

 	EndGlobalSection

+	GlobalSection(ExtensibilityGlobals) = postSolution

+		SolutionGuid = {90811697-0889-4381-80BC-C3FE8FA4931F}

+	EndGlobalSection

 EndGlobal

diff --git a/builds/windows/vc2010/freetype.vcxproj b/builds/windows/vc2010/freetype.vcxproj
index 7052c6c..4c9e2b4 100644
--- a/builds/windows/vc2010/freetype.vcxproj
+++ b/builds/windows/vc2010/freetype.vcxproj
@@ -1,10 +1,26 @@
 <?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+<!--

+  You can use this file to build FreeType with MSBuild as follows

+

+    MSBuild.exe -t:Rebuild

+                -p:Configuration=Debug

+                -p:Platform=x64

+                -p:UserDefines=FT_DEBUG_LOGGING

+                   builds/windows/vc2010/freetype.vcxproj

+

+  or with different appropriate switches. It also works with Visual Studio.

+  Additional customization can be made in `freetype.user.props`.

+-->

+<Project DefaultTargets="DlgCopy;Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

       <Configuration>Debug</Configuration>

       <Platform>Win32</Platform>

     </ProjectConfiguration>

+    <ProjectConfiguration Include="Debug|ARM64">

+      <Configuration>Debug</Configuration>

+      <Platform>ARM64</Platform>

+    </ProjectConfiguration>

     <ProjectConfiguration Include="Debug|x64">

       <Configuration>Debug</Configuration>

       <Platform>x64</Platform>

@@ -13,6 +29,10 @@
       <Configuration>Debug Static</Configuration>

       <Platform>Win32</Platform>

     </ProjectConfiguration>

+    <ProjectConfiguration Include="Debug Static|ARM64">

+      <Configuration>Debug Static</Configuration>

+      <Platform>ARM64</Platform>

+    </ProjectConfiguration>

     <ProjectConfiguration Include="Debug Static|x64">

       <Configuration>Debug Static</Configuration>

       <Platform>x64</Platform>

@@ -21,6 +41,10 @@
       <Configuration>Release</Configuration>

       <Platform>Win32</Platform>

     </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|ARM64">

+      <Configuration>Release</Configuration>

+      <Platform>ARM64</Platform>

+    </ProjectConfiguration>

     <ProjectConfiguration Include="Release|x64">

       <Configuration>Release</Configuration>

       <Platform>x64</Platform>

@@ -29,81 +53,70 @@
       <Configuration>Release Static</Configuration>

       <Platform>Win32</Platform>

     </ProjectConfiguration>

+    <ProjectConfiguration Include="Release Static|ARM64">

+      <Configuration>Release Static</Configuration>

+      <Platform>ARM64</Platform>

+    </ProjectConfiguration>

     <ProjectConfiguration Include="Release Static|x64">

       <Configuration>Release Static</Configuration>

       <Platform>x64</Platform>

     </ProjectConfiguration>

   </ItemGroup>

-  <!--

-    Switch the PlatformToolset based on the Visual Studio Version

--->

-  <PropertyGroup>

-    <!-- Assume Visual Studio 2010 / 4.0 as the default -->

-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">4.0</VisualStudioVersion>

-  </PropertyGroup>

-  <!-- Visual Studio 2010 (4.0) -->

-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '4.0'">

-    <PlatformToolset>v100</PlatformToolset>

-  </PropertyGroup>

-  <!-- Visual Studio 2013 (12.0) -->

-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'">

-    <PlatformToolset>v120</PlatformToolset>

-  </PropertyGroup>

-  <!-- Visual Studio 2015 (14.0) -->

-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'">

-    <PlatformToolset>v140</PlatformToolset>

-  </PropertyGroup>

-  <!-- Visual Studio 2017 (15.0) -->

-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '15.0'">

-    <PlatformToolset>v141</PlatformToolset>

-  </PropertyGroup>

-  <!--

-    End of: Switch the PlatformToolset based on the Visual Studio Version

--->

   <PropertyGroup Label="Globals">

     <ProjectGuid>{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}</ProjectGuid>

     <RootNamespace>FreeType</RootNamespace>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Label="PlatformToolset">

+    <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>

+  </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">

+    <ConfigurationType>DynamicLibrary</ConfigurationType>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|ARM64'" Label="Configuration">

+    <ConfigurationType>StaticLibrary</ConfigurationType>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">

+    <ConfigurationType>DynamicLibrary</ConfigurationType>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

     <ConfigurationType>DynamicLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|ARM64'" Label="Configuration">

+    <ConfigurationType>StaticLibrary</ConfigurationType>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'" Label="Configuration">

     <ConfigurationType>StaticLibrary</ConfigurationType>

-    <UseOfMfc>false</UseOfMfc>

-    <CharacterSet>Unicode</CharacterSet>

+    <CharacterSet>NotSet</CharacterSet>

   </PropertyGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

   <ImportGroup Label="ExtensionSettings">

@@ -124,13 +137,12 @@
       <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>

-      <DisableLanguageExtensions>true</DisableLanguageExtensions>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <CompileAsManaged>false</CompileAsManaged>

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

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

     </ClCompile>

@@ -138,12 +150,39 @@
       <PreprocessorDefinitions>_DEBUG;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <Culture>0x0409</Culture>

     </ResourceCompile>

-    <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

+    <Link>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

       <TargetMachine>MachineX86</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

-    </Lib>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">

+    <ClCompile>

+      <Optimization>Disabled</Optimization>

+      <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

+      <WarningLevel>Level4</WarningLevel>

+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

+      <CompileAs>Default</CompileAs>

+      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <MultiProcessorCompilation>true</MultiProcessorCompilation>

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

+      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

+    </ClCompile>

+    <ResourceCompile>

+      <PreprocessorDefinitions>_DEBUG;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <Culture>0x0409</Culture>

+    </ResourceCompile>

+    <Link>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <TargetMachine>MachineARM64</TargetMachine>

+      <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

+    </Link>

   </ItemDefinitionGroup>

   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

     <ClCompile>

@@ -152,13 +191,12 @@
       <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>

-      <DisableLanguageExtensions>true</DisableLanguageExtensions>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <CompileAsManaged>false</CompileAsManaged>

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

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

     </ClCompile>

@@ -166,12 +204,12 @@
       <PreprocessorDefinitions>_DEBUG;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <Culture>0x0409</Culture>

     </ResourceCompile>

-    <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

+    <Link>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

       <TargetMachine>MachineX64</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

-    </Lib>

+    </Link>

   </ItemDefinitionGroup>

   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">

     <ClCompile>

@@ -180,13 +218,12 @@
       <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

-      <DisableLanguageExtensions>true</DisableLanguageExtensions>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <CompileAsManaged>false</CompileAsManaged>

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

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

     </ClCompile>

@@ -195,12 +232,37 @@
       <Culture>0x0409</Culture>

     </ResourceCompile>

     <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

       <TargetMachine>MachineX86</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

     </Lib>

   </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|ARM64'">

+    <ClCompile>

+      <Optimization>Disabled</Optimization>

+      <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

+      <WarningLevel>Level4</WarningLevel>

+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

+      <CompileAs>Default</CompileAs>

+      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <MultiProcessorCompilation>true</MultiProcessorCompilation>

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

+      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

+    </ClCompile>

+    <ResourceCompile>

+      <PreprocessorDefinitions>_DEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <Culture>0x0409</Culture>

+    </ResourceCompile>

+    <Lib>

+      <TargetMachine>MachineARM64</TargetMachine>

+      <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

+    </Lib>

+  </ItemDefinitionGroup>

   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|x64'">

     <ClCompile>

       <Optimization>Disabled</Optimization>

@@ -208,13 +270,12 @@
       <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

-      <DisableLanguageExtensions>true</DisableLanguageExtensions>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <CompileAsManaged>false</CompileAsManaged>

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

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

     </ClCompile>

@@ -223,7 +284,6 @@
       <Culture>0x0409</Culture>

     </ResourceCompile>

     <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

       <TargetMachine>MachineX64</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

@@ -235,7 +295,6 @@
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

       <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <StringPooling>true</StringPooling>

       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <DisableLanguageExtensions>true</DisableLanguageExtensions>

@@ -243,31 +302,48 @@
       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <WholeProgramOptimization>false</WholeProgramOptimization>

       <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>

-      <FloatingPointExceptions>false</FloatingPointExceptions>

-      <CreateHotpatchableImage>false</CreateHotpatchableImage>

-      <CompileAsManaged>false</CompileAsManaged>

-      <ProgramDataBaseFileName>

-      </ProgramDataBaseFileName>

-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>

-      <DebugInformationFormat>

-      </DebugInformationFormat>

       <IntrinsicFunctions>true</IntrinsicFunctions>

-      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>

-      <OmitFramePointers>true</OmitFramePointers>

     </ClCompile>

     <ResourceCompile>

       <PreprocessorDefinitions>NDEBUG;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <Culture>0x0409</Culture>

     </ResourceCompile>

-    <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

-      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>

+    <Link>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

       <TargetMachine>MachineX86</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

-    </Lib>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">

+    <ClCompile>

+      <Optimization>MaxSpeed</Optimization>

+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

+      <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <DisableLanguageExtensions>true</DisableLanguageExtensions>

+      <WarningLevel>Level4</WarningLevel>

+      <CompileAs>Default</CompileAs>

+      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <MultiProcessorCompilation>true</MultiProcessorCompilation>

+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+    </ClCompile>

+    <ResourceCompile>

+      <PreprocessorDefinitions>NDEBUG;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <Culture>0x0409</Culture>

+    </ResourceCompile>

+    <Link>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <TargetMachine>MachineARM64</TargetMachine>

+      <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

+    </Link>

   </ItemDefinitionGroup>

   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

     <ClCompile>

@@ -275,7 +351,6 @@
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

       <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <StringPooling>true</StringPooling>

       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <DisableLanguageExtensions>true</DisableLanguageExtensions>

@@ -283,31 +358,19 @@
       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <WholeProgramOptimization>false</WholeProgramOptimization>

-      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>

-      <FloatingPointExceptions>false</FloatingPointExceptions>

-      <CreateHotpatchableImage>false</CreateHotpatchableImage>

-      <CompileAsManaged>false</CompileAsManaged>

-      <ProgramDataBaseFileName>

-      </ProgramDataBaseFileName>

-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>

-      <DebugInformationFormat>

-      </DebugInformationFormat>

       <IntrinsicFunctions>true</IntrinsicFunctions>

-      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>

-      <OmitFramePointers>true</OmitFramePointers>

     </ClCompile>

     <ResourceCompile>

       <PreprocessorDefinitions>NDEBUG;DLL_EXPORT;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <Culture>0x0409</Culture>

     </ResourceCompile>

-    <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

-      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>

+    <Link>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

       <TargetMachine>MachineX64</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

-    </Lib>

+    </Link>

   </ItemDefinitionGroup>

   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">

     <ClCompile>

@@ -315,7 +378,6 @@
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

       <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <StringPooling>true</StringPooling>

       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <DisableLanguageExtensions>true</DisableLanguageExtensions>

@@ -323,40 +385,51 @@
       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <WholeProgramOptimization>false</WholeProgramOptimization>

       <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>

-      <FloatingPointExceptions>false</FloatingPointExceptions>

-      <CreateHotpatchableImage>false</CreateHotpatchableImage>

-      <RuntimeTypeInfo>false</RuntimeTypeInfo>

-      <CompileAsManaged>false</CompileAsManaged>

-      <ProgramDataBaseFileName>

-      </ProgramDataBaseFileName>

-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>

-      <DebugInformationFormat>

-      </DebugInformationFormat>

       <IntrinsicFunctions>true</IntrinsicFunctions>

-      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>

-      <OmitFramePointers>true</OmitFramePointers>

     </ClCompile>

     <ResourceCompile>

       <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <Culture>0x0409</Culture>

     </ResourceCompile>

     <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

-      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>

       <TargetMachine>MachineX86</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

     </Lib>

   </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|ARM64'">

+    <ClCompile>

+      <Optimization>MaxSpeed</Optimization>

+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

+      <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <DisableLanguageExtensions>true</DisableLanguageExtensions>

+      <WarningLevel>Level4</WarningLevel>

+      <CompileAs>Default</CompileAs>

+      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <MultiProcessorCompilation>true</MultiProcessorCompilation>

+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+    </ClCompile>

+    <ResourceCompile>

+      <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <Culture>0x0409</Culture>

+    </ResourceCompile>

+    <Lib>

+      <TargetMachine>MachineARM64</TargetMachine>

+      <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

+    </Lib>

+  </ItemDefinitionGroup>

   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'">

     <ClCompile>

       <Optimization>MaxSpeed</Optimization>

       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>

       <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <StringPooling>true</StringPooling>

       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <DisableLanguageExtensions>true</DisableLanguageExtensions>

@@ -364,28 +437,13 @@
       <CompileAs>Default</CompileAs>

       <DisableSpecificWarnings>4001</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

-      <WholeProgramOptimization>false</WholeProgramOptimization>

-      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>

-      <FloatingPointExceptions>false</FloatingPointExceptions>

-      <CreateHotpatchableImage>false</CreateHotpatchableImage>

-      <RuntimeTypeInfo>false</RuntimeTypeInfo>

-      <CompileAsManaged>false</CompileAsManaged>

-      <ProgramDataBaseFileName>

-      </ProgramDataBaseFileName>

-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>

-      <DebugInformationFormat>

-      </DebugInformationFormat>

       <IntrinsicFunctions>true</IntrinsicFunctions>

-      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>

-      <OmitFramePointers>true</OmitFramePointers>

     </ClCompile>

     <ResourceCompile>

       <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>

       <Culture>0x0409</Culture>

     </ResourceCompile>

     <Lib>

-      <SuppressStartupBanner>true</SuppressStartupBanner>

-      <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>

       <TargetMachine>MachineX64</TargetMachine>

       <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

       <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>

@@ -409,13 +467,13 @@
     <ClCompile Include="..\..\..\src\base\ftpfr.c" />

     <ClCompile Include="..\..\..\src\base\ftstroke.c" />

     <ClCompile Include="..\..\..\src\base\ftsynth.c" />

-    <ClCompile Include="..\..\..\src\base\ftsystem.c" />

     <ClCompile Include="..\..\..\src\base\fttype1.c" />

     <ClCompile Include="..\..\..\src\base\ftwinfnt.c" />

     <ClCompile Include="..\..\..\src\bdf\bdf.c" />

     <ClCompile Include="..\..\..\src\cache\ftcache.c" />

     <ClCompile Include="..\..\..\src\cff\cff.c" />

     <ClCompile Include="..\..\..\src\cid\type1cid.c" />

+    <ClCompile Include="..\..\..\src\dlg\dlgwrap.c" />

     <ClCompile Include="..\..\..\src\gzip\ftgzip.c" />

     <ClCompile Include="..\..\..\src\lzw\ftlzw.c" />

     <ClCompile Include="..\..\..\src\pcf\pcf.c" />

@@ -426,6 +484,8 @@
     <ClCompile Include="..\..\..\src\raster\raster.c" />

     <ClCompile Include="..\..\..\src\sfnt\sfnt.c" />

     <ClCompile Include="..\..\..\src\smooth\smooth.c" />

+    <ClCompile Include="..\..\..\src\sdf\sdf.c" />

+    <ClCompile Include="..\..\..\src\svg\svg.c" />

     <ClCompile Include="..\..\..\src\truetype\truetype.c" />

     <ClCompile Include="..\..\..\src\type1\type1.c" />

     <ClCompile Include="..\..\..\src\type42\type42.c" />

@@ -433,12 +493,33 @@
     <ClCompile Include="..\ftdebug.c">

       <DisableLanguageExtensions>false</DisableLanguageExtensions>

     </ClCompile>

+    <ClCompile Include="..\ftsystem.c">

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

+    </ClCompile>

     <ResourceCompile Include="..\..\..\src\base\ftver.rc" />

   </ItemGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

   <ImportGroup Label="ExtensionTargets">

   </ImportGroup>

+  <ItemGroup Condition="Exists('..\..\..\subprojects\dlg\.git')">

+    <DlgSrc Include="..\..\..\subprojects\dlg\include\dlg\output.h">

+      <DlgDst>..\..\..\include\dlg\output.h</DlgDst>

+    </DlgSrc>

+    <DlgSrc Include="..\..\..\subprojects\dlg\include\dlg\dlg.h">

+      <DlgDst>..\..\..\include\dlg\dlg.h</DlgDst>

+    </DlgSrc>

+    <DlgSrc Include="..\..\..\subprojects\dlg\src\dlg\dlg.c">

+      <DlgDst>..\..\..\src\dlg\dlg.c</DlgDst>

+    </DlgSrc>

+  </ItemGroup>

+  <Target Name="DlgCopy" Inputs="@(DlgSrc)" Outputs="@(DlgSrc->'%(DlgDst)')" Condition="Exists('..\..\..\subprojects\dlg\.git')">

+    <Copy SourceFiles="@(DlgSrc)" DestinationFiles="@(DlgSrc->'%(DlgDst)')" />

+  </Target>

   <Target Name="AfterBuild">

-    <Copy SourceFiles="$(TargetPath)" DestinationFolder="..\..\..\objs" />

+    <ItemGroup>

+      <TargetFiles Include="$(TargetDir)$(TargetName).*" />

+    </ItemGroup>

+    <Copy SourceFiles="@(TargetFiles)" DestinationFolder="..\..\..\objs" />

+    <Copy SourceFiles="$(TargetDir)$(TargetFileName)" DestinationFolder="..\..\..\..\freetype-demos\bin" Condition="'$(TargetExt)'=='.dll'" />

   </Target>

 </Project>

diff --git a/builds/windows/vc2010/freetype.vcxproj.filters b/builds/windows/vc2010/freetype.vcxproj.filters
index 345e1f1..4085f6c 100644
--- a/builds/windows/vc2010/freetype.vcxproj.filters
+++ b/builds/windows/vc2010/freetype.vcxproj.filters
@@ -23,9 +23,6 @@
     <ClCompile Include="..\..\..\src\base\ftinit.c">

       <Filter>Source Files</Filter>

     </ClCompile>

-    <ClCompile Include="..\..\..\src\base\ftsystem.c">

-      <Filter>Source Files</Filter>

-    </ClCompile>

     <ClCompile Include="..\..\..\src\bdf\bdf.c">

       <Filter>Source Files</Filter>

     </ClCompile>

@@ -65,9 +62,15 @@
     <ClCompile Include="..\..\..\src\sfnt\sfnt.c">

       <Filter>Source Files</Filter>

     </ClCompile>

+    <ClCompile Include="..\..\..\src\sdf\sdf.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

     <ClCompile Include="..\..\..\src\smooth\smooth.c">

       <Filter>Source Files</Filter>

     </ClCompile>

+    <ClCompile Include="..\..\..\src\svg\svg.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

     <ClCompile Include="..\..\..\src\truetype\truetype.c">

       <Filter>Source Files</Filter>

     </ClCompile>

@@ -131,10 +134,16 @@
     <ClCompile Include="..\..\..\src\base\ftwinfnt.c">

       <Filter>Source Files\FT_MODULES</Filter>

     </ClCompile>

+    <ClCompile Include="..\..\..\src\dlg\dlgwrap.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\ftsystem.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

   </ItemGroup>

   <ItemGroup>

     <ResourceCompile Include="..\..\..\src\base\ftver.rc">

       <Filter>Source Files</Filter>

     </ResourceCompile>

   </ItemGroup>

-</Project>
\ No newline at end of file
+</Project>

diff --git a/builds/windows/vc2010/index.html b/builds/windows/vc2010/index.html
index 634ea93..c03be77 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.9.1 sources:</p>
+from the FreeType 2.13.0 sources:</p>
 
 <ul>
   <li>freetype.dll using 'Release' or 'Debug' configurations</li>
@@ -30,7 +30,7 @@
 <p>To configure library dependencies like <em>zlib</em> and <em>libpng</em>,
 edit the <tt>freetype.users.props</tt> file in this directory.  It also
 simplifies automated (command-line) builds using <a
-href="http://msdn.microsoft.com/library/dd393574%28v=vs.100%29.aspx">msbuild</a>.</p>
+href="https://msdn.microsoft.com/library/dd393574%28v=vs.100%29.aspx">msbuild</a>.</p>
 
 <p>To link your executable with FreeType DLL, you may want to define
 DLL_IMPORT so that the imported functions are appropriately
diff --git a/builds/windows/visualc/freetype.dsp b/builds/windows/visualc/freetype.dsp
index dac3d25..540f5b9 100644
--- a/builds/windows/visualc/freetype.dsp
+++ b/builds/windows/visualc/freetype.dsp
@@ -2,9 +2,10 @@
 # Microsoft Developer Studio Generated Build File, Format Version 6.00

 # ** DO NOT EDIT **

 

+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102

 # TARGTYPE "Win32 (x86) Static Library" 0x0104

 

-CFG=freetype - Win32 Debug Singlethreaded

+CFG=freetype - Win32 Release

 !MESSAGE This is not a valid makefile. To build this project using NMAKE,

 !MESSAGE use the Export Makefile command and run

 !MESSAGE

@@ -13,24 +14,20 @@
 !MESSAGE You can specify a configuration when running NMAKE

 !MESSAGE by defining the macro CFG on the command line. For example:

 !MESSAGE

-!MESSAGE NMAKE /f "freetype.mak" CFG="freetype - Win32 Debug Singlethreaded"

+!MESSAGE NMAKE /f "freetype.mak" CFG="freetype - Win32 Release"

 !MESSAGE

 !MESSAGE Possible choices for configuration are:

 !MESSAGE

-!MESSAGE "freetype - Win32 Release" (based on "Win32 (x86) Static Library")

-!MESSAGE "freetype - Win32 Debug" (based on "Win32 (x86) Static Library")

-!MESSAGE "freetype - Win32 Debug Multithreaded" (based on "Win32 (x86) Static Library")

-!MESSAGE "freetype - Win32 Release Multithreaded" (based on "Win32 (x86) Static Library")

-!MESSAGE "freetype - Win32 Release Singlethreaded" (based on "Win32 (x86) Static Library")

-!MESSAGE "freetype - Win32 Debug Singlethreaded" (based on "Win32 (x86) Static Library")

+!MESSAGE "freetype - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")

+!MESSAGE "freetype - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")

+!MESSAGE "freetype - Win32 Release Static" (based on "Win32 (x86) Static Library")

+!MESSAGE "freetype - Win32 Debug Static" (based on "Win32 (x86) Static Library")

 !MESSAGE

 

 # Begin Project

 # PROP AllowPerConfigDependencies 0

 # PROP Scc_ProjName ""

 # PROP Scc_LocalPath ""

-CPP=cl.exe

-RSC=rc.exe

 

 !IF  "$(CFG)" == "freetype - Win32 Release"

 

@@ -41,20 +38,27 @@
 # PROP BASE Target_Dir ""

 # PROP Use_MFC 0

 # PROP Use_Debug_Libraries 0

-# PROP Output_Dir "..\..\..\objs\release"

-# PROP Intermediate_Dir "..\..\..\objs\release"

+# PROP Output_Dir "..\..\..\objs\Win32\Release"

+# PROP Intermediate_Dir "..\..\..\objs\Win32\Release"

+# PROP Ignore_Export_Lib 0

 # PROP Target_Dir ""

-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c

-# ADD CPP /MD /Za /W4 /GX /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT2_BUILD_LIBRARY" /FD /c

-# SUBTRACT CPP /nologo /Z<none> /YX

+CPP=cl.exe

+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c

+# SUBTRACT BASE CPP /YX /Yc /Yu

+# ADD CPP /nologo /Za /MD /W3 /O2 /Oi /D "WIN32" /I "..\..\..\include" /D "_CRT_SECURE_NO_WARNINGS" /D "NDEBUG" /D "FT2_BUILD_LIBRARY" /D "DLL_EXPORT" /FD /c

+# SUBTRACT CPP /YX /Yc /Yu

+MTL=midl.exe

+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32

+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32

+RSC=rc.exe

 # ADD BASE RSC /l 0x409 /d "NDEBUG"

-# ADD RSC /l 0x409 /d "NDEBUG"

+# ADD RSC /l 0x409 /d "NDEBUG" /d "DLL_EXPORT"

 BSC32=bscmake.exe

 # ADD BASE BSC32 /nologo

 # ADD BSC32 /nologo

-LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291.lib"

+LINK32=link.exe

+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386

+# ADD LINK32 /nologo /dll /machine:I386 /opt:REF,ICF /out:"$(OutDir)\freetype.dll"

 

 !ELSEIF  "$(CFG)" == "freetype - Win32 Debug"

 

@@ -65,12 +69,73 @@
 # PROP BASE Target_Dir ""

 # PROP Use_MFC 0

 # PROP Use_Debug_Libraries 1

-# PROP Output_Dir "..\..\..\objs\debug"

-# PROP Intermediate_Dir "..\..\..\objs\debug"

+# PROP Output_Dir "..\..\..\objs\Win32\Debug"

+# PROP Intermediate_Dir "..\..\..\objs\Win32\Debug"

+# PROP Ignore_Export_Lib 0

 # PROP Target_Dir ""

-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c

-# ADD CPP /MDd /Za /W4 /GX /Z7 /Od /I "..\..\..\include" /D "_DEBUG" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT2_BUILD_LIBRARY" /FD /GZ /c

-# SUBTRACT CPP /nologo /X /YX

+CPP=cl.exe

+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c

+# SUBTRACT BASE CPP /YX /Yc /Yu

+# ADD CPP /nologo /Za /MDd /W3 /Gm /ZI /Od /I "..\..\..\include" /D "WIN32" /D "_CRT_SECURE_NO_WARNINGS" /D "_DEBUG" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /D "FT2_BUILD_LIBRARY" /D "DLL_EXPORT" /FR /FD /GZ /c

+# SUBTRACT CPP /YX /Yc /Yu

+MTL=midl.exe

+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32

+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32

+RSC=rc.exe

+# ADD BASE RSC /l 0x409 /d "_DEBUG"

+# ADD RSC /l 0x409 /d "_DEBUG" /d "DLL_EXPORT"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LINK32=link.exe

+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept

+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"$(OutDir)\freetype.dll" /pdbtype:sept

+

+!ELSEIF  "$(CFG)" == "freetype - Win32 Release Static"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 0

+# PROP BASE Output_Dir "Release Static"

+# PROP BASE Intermediate_Dir "Release Static"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 0

+# PROP Output_Dir "..\..\..\objs\Win32\Release Static"

+# PROP Intermediate_Dir "..\..\..\objs\Win32\Release Static"

+# PROP Target_Dir ""

+CPP=cl.exe

+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c

+# SUBTRACT BASE CPP /YX /Yc /Yu

+# ADD CPP /nologo /Za /MD /W3 /O2 /Oi /D "WIN32" /I "..\..\..\include" /D "_CRT_SECURE_NO_WARNINGS" /D "NDEBUG" /D "FT2_BUILD_LIBRARY" /FD /c

+# SUBTRACT CPP /YX /Yc /Yu

+RSC=rc.exe

+# ADD BASE RSC /l 0x409 /d "NDEBUG"

+# ADD RSC /l 0x409 /d "NDEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LIB32=link.exe -lib

+# ADD BASE LIB32 /nologo

+# ADD LIB32 /nologo /out:"$(OutDir)\freetype.lib"

+

+!ELSEIF  "$(CFG)" == "freetype - Win32 Debug Static"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 1

+# PROP BASE Output_Dir "Debug Static"

+# PROP BASE Intermediate_Dir "Debug Static"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 1

+# PROP Output_Dir "..\..\..\objs\Win32\Debug Static"

+# PROP Intermediate_Dir "..\..\..\objs\Win32\Debug Static"

+# PROP Target_Dir ""

+CPP=cl.exe

+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c

+# SUBTRACT BASE CPP /YX /Yc /Yu

+# ADD CPP /nologo /Za /MDd /W3 /Gm /ZI /Od /I "..\..\..\include" /D "WIN32" /D "_CRT_SECURE_NO_WARNINGS" /D "_DEBUG" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /D "FT2_BUILD_LIBRARY" /FR /FD /GZ /c

+# SUBTRACT CPP /YX /Yc /Yu

+RSC=rc.exe

 # ADD BASE RSC /l 0x409 /d "_DEBUG"

 # ADD RSC /l 0x409 /d "_DEBUG"

 BSC32=bscmake.exe

@@ -78,107 +143,7 @@
 # ADD BSC32 /nologo

 LIB32=link.exe -lib

 # ADD BASE LIB32 /nologo

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291_D.lib"

-

-!ELSEIF  "$(CFG)" == "freetype - Win32 Debug Multithreaded"

-

-# PROP BASE Use_MFC 0

-# PROP BASE Use_Debug_Libraries 1

-# PROP BASE Output_Dir "freetype___Win32_Debug_Multithreaded"

-# PROP BASE Intermediate_Dir "freetype___Win32_Debug_Multithreaded"

-# PROP BASE Target_Dir ""

-# PROP Use_MFC 0

-# PROP Use_Debug_Libraries 1

-# PROP Output_Dir "..\..\..\objs\debug_mt"

-# PROP Intermediate_Dir "..\..\..\objs\debug_mt"

-# PROP Target_Dir ""

-# ADD BASE CPP /nologo /Za /W3 /Gm /GX /ZI /Od /I "..\include\\" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_FLAT_COMPILE" /YX /FD /GZ /c

-# SUBTRACT BASE CPP /X

-# ADD CPP /MTd /Za /W4 /GX /Z7 /Od /I "..\..\..\include" /D "_DEBUG" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT2_BUILD_LIBRARY" /FD /GZ /c

-# SUBTRACT CPP /nologo /X /YX

-# ADD BASE RSC /l 0x409 /d "_DEBUG"

-# ADD RSC /l 0x409 /d "_DEBUG"

-BSC32=bscmake.exe

-# ADD BASE BSC32 /nologo

-# ADD BSC32 /nologo

-LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"lib\freetype291_D.lib"

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291MT_D.lib"

-

-!ELSEIF  "$(CFG)" == "freetype - Win32 Release Multithreaded"

-

-# PROP BASE Use_MFC 0

-# PROP BASE Use_Debug_Libraries 0

-# PROP BASE Output_Dir "freetype___Win32_Release_Multithreaded"

-# PROP BASE Intermediate_Dir "freetype___Win32_Release_Multithreaded"

-# PROP BASE Target_Dir ""

-# PROP Use_MFC 0

-# PROP Use_Debug_Libraries 0

-# PROP Output_Dir "..\..\..\objs\release_mt"

-# PROP Intermediate_Dir "..\..\..\objs\release_mt"

-# PROP Target_Dir ""

-# ADD BASE CPP /nologo /Za /W3 /GX /O2 /I "..\include\\" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_FLAT_COMPILE" /YX /FD /c

-# ADD CPP /MT /Za /W4 /GX /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT2_BUILD_LIBRARY" /FD /c

-# SUBTRACT CPP /nologo /Z<none> /YX

-# ADD BASE RSC /l 0x409 /d "NDEBUG"

-# ADD RSC /l 0x409 /d "NDEBUG"

-BSC32=bscmake.exe

-# ADD BASE BSC32 /nologo

-# ADD BSC32 /nologo

-LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"lib\freetype291.lib"

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291MT.lib"

-

-!ELSEIF  "$(CFG)" == "freetype - Win32 Release Singlethreaded"

-

-# PROP BASE Use_MFC 0

-# PROP BASE Use_Debug_Libraries 0

-# PROP BASE Output_Dir "freetype___Win32_Release_Singlethreaded"

-# PROP BASE Intermediate_Dir "freetype___Win32_Release_Singlethreaded"

-# PROP BASE Target_Dir ""

-# PROP Use_MFC 0

-# PROP Use_Debug_Libraries 0

-# PROP Output_Dir "..\..\..\objs\release_st"

-# PROP Intermediate_Dir "..\..\..\objs\release_st"

-# PROP Target_Dir ""

-# ADD BASE CPP /nologo /MD /Za /W4 /GX /Zi /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /c

-# SUBTRACT BASE CPP /YX

-# ADD CPP /Za /W4 /GX /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT2_BUILD_LIBRARY" /FD /c

-# SUBTRACT CPP /nologo /Z<none> /YX

-# ADD BASE RSC /l 0x409 /d "NDEBUG"

-# ADD RSC /l 0x409 /d "NDEBUG"

-BSC32=bscmake.exe

-# ADD BASE BSC32 /nologo

-# ADD BSC32 /nologo

-LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype291.lib"

-# ADD LIB32 /out:"..\..\..\objs\freetype291ST.lib"

-# SUBTRACT LIB32 /nologo

-

-!ELSEIF  "$(CFG)" == "freetype - Win32 Debug Singlethreaded"

-

-# PROP BASE Use_MFC 0

-# PROP BASE Use_Debug_Libraries 1

-# PROP BASE Output_Dir "freetype___Win32_Debug_Singlethreaded"

-# PROP BASE Intermediate_Dir "freetype___Win32_Debug_Singlethreaded"

-# PROP BASE Target_Dir ""

-# PROP Use_MFC 0

-# PROP Use_Debug_Libraries 1

-# PROP Output_Dir "..\..\..\objs\debug_st"

-# PROP Intermediate_Dir "..\..\..\objs\debug_st"

-# PROP Target_Dir ""

-# ADD BASE CPP /nologo /MDd /Za /W4 /Gm /GX /Zi /Od /I "..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /FD /GZ /c

-# SUBTRACT BASE CPP /X /YX

-# ADD CPP /Za /W4 /GX /Z7 /Od /I "..\..\..\include" /D "_DEBUG" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT2_BUILD_LIBRARY" /FD /GZ /c

-# SUBTRACT CPP /nologo /X /YX

-# ADD BASE RSC /l 0x409 /d "_DEBUG"

-# ADD RSC /l 0x409 /d "_DEBUG"

-BSC32=bscmake.exe

-# ADD BASE BSC32 /nologo

-# ADD BSC32 /nologo

-LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype291_D.lib"

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291ST_D.lib"

+# ADD LIB32 /nologo /out:"$(OutDir)\freetype.lib"

 

 !ENDIF

 

@@ -186,10 +151,8 @@
 

 # Name "freetype - Win32 Release"

 # Name "freetype - Win32 Debug"

-# Name "freetype - Win32 Debug Multithreaded"

-# Name "freetype - Win32 Release Multithreaded"

-# Name "freetype - Win32 Release Singlethreaded"

-# Name "freetype - Win32 Debug Singlethreaded"

+# Name "freetype - Win32 Release Static"

+# Name "freetype - Win32 Debug Static"

 # Begin Group "Source Files"

 

 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

@@ -379,5 +342,13 @@
 SOURCE=..\..\..\include\freetype\config\ftstdlib.h

 # End Source File

 # End Group

+# Begin Group "Resource Files"

+

+# PROP Default_Filter "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+# Begin Source File

+

+SOURCE=..\..\..\src\base\ftver.rc

+# End Source File

+# End Group

 # End Target

 # End Project

diff --git a/builds/windows/visualc/freetype.sln b/builds/windows/visualc/freetype.sln
index 1f64be2..9054d0a 100644
--- a/builds/windows/visualc/freetype.sln
+++ b/builds/windows/visualc/freetype.sln
@@ -1,27 +1,21 @@
-Microsoft Visual Studio Solution File, Format Version 9.00

-# Visual Studio 2005

+Microsoft Visual Studio Solution File, Format Version 7.00

+# Visual C++ 2002-2008

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "freetype.vcproj", "{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"

 EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

-		Debug Multithreaded|Win32 = Debug Multithreaded|Win32

-		Debug Singlethreaded|Win32 = Debug Singlethreaded|Win32

+		Debug Static|Win32 = Debug Static|Win32

 		Debug|Win32 = Debug|Win32

-		Release Multithreaded|Win32 = Release Multithreaded|Win32

-		Release Singlethreaded|Win32 = Release Singlethreaded|Win32

+		Release Static|Win32 = Release Static|Win32

 		Release|Win32 = Release|Win32

 	EndGlobalSection

 	GlobalSection(ProjectConfigurationPlatforms) = postSolution

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Multithreaded|Win32.ActiveCfg = Debug Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Multithreaded|Win32.Build.0 = Debug Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Singlethreaded|Win32.ActiveCfg = Debug Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Singlethreaded|Win32.Build.0 = Debug Singlethreaded|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.ActiveCfg = Debug Static|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.Build.0 = Debug Static|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.ActiveCfg = Debug|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.Build.0 = Debug|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Multithreaded|Win32.ActiveCfg = Release Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Multithreaded|Win32.Build.0 = Release Multithreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Singlethreaded|Win32.ActiveCfg = Release Singlethreaded|Win32

-		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Singlethreaded|Win32.Build.0 = Release Singlethreaded|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.ActiveCfg = Release Static|Win32

+		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.Build.0 = Release Static|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.ActiveCfg = Release|Win32

 		{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.Build.0 = Release|Win32

 	EndGlobalSection

diff --git a/builds/windows/visualc/freetype.vcproj b/builds/windows/visualc/freetype.vcproj
index dd0c418..a16782c 100644
--- a/builds/windows/visualc/freetype.vcproj
+++ b/builds/windows/visualc/freetype.vcproj
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="Windows-1252"?>

 <VisualStudioProject

 	ProjectType="Visual C++"

-	Version="8.00"

 	Name="freetype"

 	ProjectGUID="{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"

 	>

@@ -15,13 +14,12 @@
 	<Configurations>

 		<Configuration

 			Name="Release|Win32"

-			OutputDirectory=".\..\..\..\objs\release"

-			IntermediateDirectory=".\..\..\..\objs\release"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			OutputDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

+			IntermediateDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

+			ConfigurationType="2"

 			UseOfMFC="0"

 			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

+			CharacterSet="0"

 			>

 			<Tool

 				Name="VCPreBuildEventTool"

@@ -42,40 +40,42 @@
 				Name="VCCLCompilerTool"

 				Optimization="2"

 				InlineFunctionExpansion="1"

+				EnableIntrinsicFunctions="true"

 				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;FT2_BUILD_LIBRARY"

+				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;DLL_EXPORT"

 				StringPooling="true"

 				RuntimeLibrary="2"

+				EnableEnhancedInstructionSet="2"

 				EnableFunctionLevelLinking="true"

 				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\release/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\release/"

-				ObjectFile=".\..\..\..\objs\release/"

-				ProgramDataBaseFileName=".\..\..\..\objs\release/"

 				WarningLevel="4"

 				DebugInformationFormat="0"

 				CompileAs="0"

+				DisableSpecificWarnings="4001"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

 			/>

 			<Tool

 				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="NDEBUG"

+				PreprocessorDefinitions="NDEBUG;DLL_EXPORT"

 				Culture="1033"

 			/>

 			<Tool

 				Name="VCPreLinkEventTool"

 			/>

 			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

-				SuppressStartupBanner="true"

+				Name="VCLinkerTool"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

 			/>

 			<Tool

 				Name="VCALinkTool"

 			/>

 			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

 				Name="VCXDCMakeTool"

 			/>

 			<Tool

@@ -85,18 +85,20 @@
 				Name="VCFxCopTool"

 			/>

 			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

 		<Configuration

-			Name="Release Multithreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\release_mt"

-			IntermediateDirectory=".\..\..\..\objs\release_mt"

+			Name="Release Static|Win32"

+			OutputDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

+			IntermediateDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

 			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

 			UseOfMFC="0"

 			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

+			CharacterSet="0"

 			>

 			<Tool

 				Name="VCPreBuildEventTool"

@@ -117,19 +119,18 @@
 				Name="VCCLCompilerTool"

 				Optimization="2"

 				InlineFunctionExpansion="1"

+				EnableIntrinsicFunctions="true"

 				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;FT2_BUILD_LIBRARY"

+				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY"

 				StringPooling="true"

 				RuntimeLibrary="0"

+				EnableEnhancedInstructionSet="2"

 				EnableFunctionLevelLinking="true"

 				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\release_mt/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\release_mt/"

-				ObjectFile=".\..\..\..\objs\release_mt/"

-				ProgramDataBaseFileName=".\..\..\..\objs\release_mt/"

 				WarningLevel="4"

 				DebugInformationFormat="0"

 				CompileAs="0"

+				DisableSpecificWarnings="4001"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

@@ -144,82 +145,6 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Release Singlethreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\release_st"

-			IntermediateDirectory=".\..\..\..\objs\release_st"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="2"

-				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;FT2_BUILD_LIBRARY"

-				StringPooling="true"

-				RuntimeLibrary="0"

-				EnableFunctionLevelLinking="true"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\release_st/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\release_st/"

-				ObjectFile=".\..\..\..\objs\release_st/"

-				ProgramDataBaseFileName=".\..\..\..\objs\release_st/"

-				WarningLevel="4"

-				DebugInformationFormat="0"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="NDEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -239,13 +164,12 @@
 		</Configuration>

 		<Configuration

 			Name="Debug|Win32"

-			OutputDirectory=".\..\..\..\objs\debug"

-			IntermediateDirectory=".\..\..\..\objs\debug"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			OutputDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

+			IntermediateDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

+			ConfigurationType="2"

 			UseOfMFC="0"

 			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

+			CharacterSet="0"

 			>

 			<Tool

 				Name="VCPreBuildEventTool"

@@ -266,38 +190,36 @@
 				Name="VCCLCompilerTool"

 				Optimization="0"

 				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY"

+				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;DLL_EXPORT"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="3"

 				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\debug/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\debug/"

-				ObjectFile=".\..\..\..\objs\debug/"

-				ProgramDataBaseFileName=".\..\..\..\objs\debug/"

 				WarningLevel="4"

 				DebugInformationFormat="3"

 				CompileAs="0"

+				DisableSpecificWarnings="4001"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

 			/>

 			<Tool

 				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="_DEBUG"

+				PreprocessorDefinitions="_DEBUG;DLL_EXPORT"

 				Culture="1033"

 			/>

 			<Tool

 				Name="VCPreLinkEventTool"

 			/>

 			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

-				SuppressStartupBanner="true"

+				Name="VCLinkerTool"

 			/>

 			<Tool

 				Name="VCALinkTool"

 			/>

 			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

 				Name="VCXDCMakeTool"

 			/>

 			<Tool

@@ -307,18 +229,20 @@
 				Name="VCFxCopTool"

 			/>

 			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

 		<Configuration

-			Name="Debug Singlethreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\debug_st"

-			IntermediateDirectory=".\..\..\..\objs\debug_st"

+			Name="Debug Static|Win32"

+			OutputDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

+			IntermediateDirectory="..\..\..\objs\$(PlatformName)\$(ConfigurationName)\"

 			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

 			UseOfMFC="0"

 			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

+			CharacterSet="0"

 			>

 			<Tool

 				Name="VCPreBuildEventTool"

@@ -339,17 +263,14 @@
 				Name="VCCLCompilerTool"

 				Optimization="0"

 				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY"

+				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="1"

 				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\debug_st/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\debug_st/"

-				ObjectFile=".\..\..\..\objs\debug_st/"

-				ProgramDataBaseFileName=".\..\..\..\objs\debug_st/"

 				WarningLevel="4"

 				DebugInformationFormat="3"

 				CompileAs="0"

+				DisableSpecificWarnings="4001"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

@@ -364,82 +285,6 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

-				SuppressStartupBanner="true"

-			/>

-			<Tool

-				Name="VCALinkTool"

-			/>

-			<Tool

-				Name="VCXDCMakeTool"

-			/>

-			<Tool

-				Name="VCBscMakeTool"

-			/>

-			<Tool

-				Name="VCFxCopTool"

-			/>

-			<Tool

-				Name="VCPostBuildEventTool"

-			/>

-		</Configuration>

-		<Configuration

-			Name="Debug Multithreaded|Win32"

-			OutputDirectory=".\..\..\..\objs\debug_mt"

-			IntermediateDirectory=".\..\..\..\objs\debug_mt"

-			ConfigurationType="4"

-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

-			UseOfMFC="0"

-			ATLMinimizesCRunTimeLibraryUsage="false"

-			CharacterSet="2"

-			>

-			<Tool

-				Name="VCPreBuildEventTool"

-			/>

-			<Tool

-				Name="VCCustomBuildTool"

-			/>

-			<Tool

-				Name="VCXMLDataGeneratorTool"

-			/>

-			<Tool

-				Name="VCWebServiceProxyGeneratorTool"

-			/>

-			<Tool

-				Name="VCMIDLTool"

-			/>

-			<Tool

-				Name="VCCLCompilerTool"

-				Optimization="0"

-				AdditionalIncludeDirectories="..\..\..\include"

-				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE"

-				GeneratePreprocessedFile="0"

-				BasicRuntimeChecks="3"

-				RuntimeLibrary="1"

-				DisableLanguageExtensions="true"

-				PrecompiledHeaderFile=".\..\..\..\objs\debug_mt/freetype.pch"

-				AssemblerListingLocation=".\..\..\..\objs\debug_mt/"

-				ObjectFile=".\..\..\..\objs\debug_mt/"

-				ProgramDataBaseFileName=".\..\..\..\objs\debug_mt/"

-				WarningLevel="4"

-				DebugInformationFormat="3"

-				CompileAs="0"

-			/>

-			<Tool

-				Name="VCManagedResourceCompilerTool"

-			/>

-			<Tool

-				Name="VCResourceCompilerTool"

-				PreprocessorDefinitions="_DEBUG"

-				Culture="1033"

-			/>

-			<Tool

-				Name="VCPreLinkEventTool"

-			/>

-			<Tool

-				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

-				SuppressStartupBanner="true"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -486,26 +331,52 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\..\src\base\ftfstype.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\src\base\ftgasp.c"

-				>

-			</File>

-			<File

 				RelativePath="..\..\..\src\cache\ftcache.c"

 				>

 			</File>

 			<File

 				RelativePath="..\ftdebug.c"

 				>

-				<FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

 					<Tool

 						Name="VCCLCompilerTool"

 						DisableLanguageExtensions="false"

 					/>

 				</FileConfiguration>

+				<FileConfiguration

+					Name="Release Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\..\..\src\base\ftfstype.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\..\src\base\ftgasp.c"

+				>

 			</File>

 			<File

 				RelativePath="..\..\..\src\base\ftglyph.c"

@@ -528,13 +399,53 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\..\src\base\ftsystem.c"

+				RelativePath="..\ftsystem.c"

+				>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug Static|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						DisableLanguageExtensions="false"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\..\..\src\sdf\sdf.c"

 				>

 			</File>

 			<File

 				RelativePath="..\..\..\src\smooth\smooth.c"

 				>

 			</File>

+			<File

+				RelativePath="..\..\..\src\svg\svg.c"

+				>

+			</File>

 			<Filter

 				Name="FT_MODULES"

 				>

@@ -551,10 +462,22 @@
 					>

 				</File>

 				<File

+					RelativePath="..\..\..\src\base\ftgxval.c"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\src\base\ftmm.c"

 					>

 				</File>

 				<File

+					RelativePath="..\..\..\src\base\ftotval.c"

+					>

+				</File>

+				<File

+					RelativePath="..\..\..\src\base\ftpatent.c"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\src\base\ftpfr.c"

 					>

 				</File>

@@ -571,18 +494,6 @@
 					>

 				</File>

 				<File

-					RelativePath="..\..\..\src\base\ftgxval.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftotval.c"

-					>

-				</File>

-				<File

-					RelativePath="..\..\..\src\base\ftpatent.c"

-					>

-				</File>

-				<File

 					RelativePath="..\..\..\src\pcf\pcf.c"

 					>

 				</File>

@@ -661,6 +572,15 @@
 				>

 			</File>

 		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			>

+			<File

+				RelativePath="..\..\..\src\base\ftver.rc"

+				>

+			</File>

+		</Filter>

 	</Files>

 	<Globals>

 	</Globals>

diff --git a/builds/windows/visualc/index.html b/builds/windows/visualc/index.html
index c0611d2..6a70b34 100644
--- a/builds/windows/visualc/index.html
+++ b/builds/windows/visualc/index.html
@@ -1,31 +1,32 @@
 <html>
 <header>
 <title>
-  FreeType&nbsp;2 Project Files for Visual&nbsp;C++ and VS.NET&nbsp;2005
+  FreeType&nbsp;2 Project Files for Visual&nbsp;C++ 6.0 and 2002-2008
 </title>
 
 <body>
 <h1>
-  FreeType&nbsp;2 Project Files for Visual&nbsp;C++ and VS.NET&nbsp;2005
+  FreeType&nbsp;2 Project Files for Visual&nbsp;C++ 6.0 and 2002-2008
 </h1>
 
-<p>This directory contains project files for Visual C++, named
-<tt>freetype.dsp</tt>, and Visual Studio, called <tt>freetype.sln</tt>.  It
-compiles the following libraries from the FreeType 2.9.1 sources:</p>
+<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>
 
 <ul>
-  <pre>
-    freetype291.lib     - release build; single threaded
-    freetype291_D.lib   - debug build;   single threaded
-    freetype291MT.lib   - release build; multi-threaded
-    freetype291MT_D.lib - debug build;   multi-threaded</pre>
+  <li>freetype.dll using 'Release' or 'Debug' configurations</li>
+  <li>freetype.lib using 'Release Static' or 'Debug Static' configurations</li>
 </ul>
 
+<p>Build directories and target files are placed in the top-level
+<tt>objs</tt> directory.</p>
+
 <p>Be sure to extract the files with the Windows (CR+LF) line endings.  ZIP
 archives are already stored this way, so no further action is required.  If
 you use some <tt>.tar.*z</tt> archives, be sure to configure your extracting
 tool to convert the line endings.  For example, with <a
-href="http://www.winzip.com">WinZip</a>, you should activate the <em>TAR
+href="https://www.winzip.com">WinZip</a>, you should activate the <em>TAR
 file smart CR/LF Conversion</em> option.  Alternatively, you may consider
 using the <tt>unix2dos</tt> or <tt>u2d</tt> utilities that are floating
 around, which specifically deal with this particular problem.
diff --git a/builds/windows/visualce/freetype.dsp b/builds/windows/visualce/freetype.dsp
index 5fe2b5a..714c422 100644
--- a/builds/windows/visualce/freetype.dsp
+++ b/builds/windows/visualce/freetype.dsp
@@ -54,7 +54,7 @@
 # ADD BSC32 /nologo

 LIB32=link.exe -lib

 # ADD BASE LIB32 /nologo

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291.lib"

+# ADD LIB32 /nologo /out:"..\..\..\objs\freetype.lib"

 

 !ELSEIF  "$(CFG)" == "freetype - Win32 Debug"

 

@@ -78,7 +78,7 @@
 # ADD BSC32 /nologo

 LIB32=link.exe -lib

 # ADD BASE LIB32 /nologo

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291_D.lib"

+# ADD LIB32 /nologo /out:"..\..\..\objs\freetype_D.lib"

 

 !ELSEIF  "$(CFG)" == "freetype - Win32 Debug Multithreaded"

 

@@ -102,8 +102,8 @@
 # ADD BASE BSC32 /nologo

 # ADD BSC32 /nologo

 LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"lib\freetype291_D.lib"

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291MT_D.lib"

+# ADD BASE LIB32 /nologo /out:"lib\freetype_D.lib"

+# ADD LIB32 /nologo /out:"..\..\..\objs\freetypeMT_D.lib"

 

 !ELSEIF  "$(CFG)" == "freetype - Win32 Release Multithreaded"

 

@@ -126,8 +126,8 @@
 # ADD BASE BSC32 /nologo

 # ADD BSC32 /nologo

 LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"lib\freetype291.lib"

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291MT.lib"

+# ADD BASE LIB32 /nologo /out:"lib\freetype.lib"

+# ADD LIB32 /nologo /out:"..\..\..\objs\freetypeMT.lib"

 

 !ELSEIF  "$(CFG)" == "freetype - Win32 Release Singlethreaded"

 

@@ -151,8 +151,8 @@
 # ADD BASE BSC32 /nologo

 # ADD BSC32 /nologo

 LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype291.lib"

-# ADD LIB32 /out:"..\..\..\objs\freetype291ST.lib"

+# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype.lib"

+# ADD LIB32 /out:"..\..\..\objs\freetypeST.lib"

 # SUBTRACT LIB32 /nologo

 

 !ELSEIF  "$(CFG)" == "freetype - Win32 Debug Singlethreaded"

@@ -177,8 +177,8 @@
 # ADD BASE BSC32 /nologo

 # ADD BSC32 /nologo

 LIB32=link.exe -lib

-# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype291_D.lib"

-# ADD LIB32 /nologo /out:"..\..\..\objs\freetype291ST_D.lib"

+# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype_D.lib"

+# ADD LIB32 /nologo /out:"..\..\..\objs\freetypeST_D.lib"

 

 !ENDIF

 

@@ -379,5 +379,13 @@
 SOURCE=..\..\..\include\freetype\config\ftstdlib.h

 # End Source File

 # End Group

+# Begin Group "Resource Files"

+

+# PROP Default_Filter "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+# Begin Source File

+

+SOURCE=..\..\..\src\base\ftver.rc

+# End Source File

+# End Group

 # End Target

 # End Project

diff --git a/builds/windows/visualce/freetype.vcproj b/builds/windows/visualce/freetype.vcproj
index b797311..e271462 100644
--- a/builds/windows/visualce/freetype.vcproj
+++ b/builds/windows/visualce/freetype.vcproj
@@ -87,7 +87,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -162,7 +162,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -237,7 +237,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -309,7 +309,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -382,7 +382,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -456,7 +456,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -534,7 +534,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -619,7 +619,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -704,7 +704,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -785,7 +785,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -867,7 +867,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -950,7 +950,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1036,7 +1036,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1121,7 +1121,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1206,7 +1206,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1287,7 +1287,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1369,7 +1369,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1452,7 +1452,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1538,7 +1538,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1623,7 +1623,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1708,7 +1708,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -1789,7 +1789,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1871,7 +1871,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -1954,7 +1954,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2040,7 +2040,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2125,7 +2125,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2210,7 +2210,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -2291,7 +2291,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2373,7 +2373,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2456,7 +2456,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2542,7 +2542,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2627,7 +2627,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2712,7 +2712,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -2793,7 +2793,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2875,7 +2875,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -2958,7 +2958,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3044,7 +3044,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291.lib"

+				OutputFile="..\..\..\objs\freetype.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3129,7 +3129,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT.lib"

+				OutputFile="..\..\..\objs\freetypeMT.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3214,7 +3214,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST.lib"

+				OutputFile="..\..\..\objs\freetypeST.lib"

 			/>

 			<Tool

 				Name="VCALinkTool"

@@ -3295,7 +3295,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291_D.lib"

+				OutputFile="..\..\..\objs\freetype_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3377,7 +3377,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291ST_D.lib"

+				OutputFile="..\..\..\objs\freetypeST_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3460,7 +3460,7 @@
 			/>

 			<Tool

 				Name="VCLibrarianTool"

-				OutputFile="..\..\..\objs\freetype291MT_D.lib"

+				OutputFile="..\..\..\objs\freetypeMT_D.lib"

 				SuppressStartupBanner="true"

 			/>

 			<Tool

@@ -3691,6 +3691,15 @@
 				>

 			</File>

 		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			>

+			<File

+				RelativePath="..\..\..\src\base\ftver.rc"

+				>

+			</File>

+		</Filter>

 	</Files>

 	<Globals>

 	</Globals>

diff --git a/builds/windows/visualce/index.html b/builds/windows/visualce/index.html
index d5a3ca3..cebab29 100644
--- a/builds/windows/visualce/index.html
+++ b/builds/windows/visualce/index.html
@@ -21,21 +21,21 @@
   <li>PPC/SP WM6 (Windows Mobile 6)</li>
 </ul>
 
-It compiles the following libraries from the FreeType 2.9.1 sources:</p>
+It compiles the following libraries from the FreeType 2.13.0 sources:</p>
 
 <ul>
   <pre>
-    freetype291.lib     - release build; single threaded
-    freetype291_D.lib   - debug build;   single threaded
-    freetype291MT.lib   - release build; multi-threaded
-    freetype291MT_D.lib - debug build;   multi-threaded</pre>
+    freetype.lib     - release build; single threaded
+    freetype_D.lib   - debug build;   single threaded
+    freetypeMT.lib   - release build; multi-threaded
+    freetypeMT_D.lib - debug build;   multi-threaded</pre>
 </ul>
 
 <p>Be sure to extract the files with the Windows (CR+LF) line endings.  ZIP
 archives are already stored this way, so no further action is required.  If
 you use some <tt>.tar.*z</tt> archives, be sure to configure your extracting
 tool to convert the line endings.  For example, with <a
-href="http://www.winzip.com">WinZip</a>, you should activate the <em>TAR
+href="https://www.winzip.com">WinZip</a>, you should activate the <em>TAR
 file smart CR/LF Conversion</em> option.  Alternatively, you may consider
 using the <tt>unix2dos</tt> or <tt>u2d</tt> utilities that are floating
 around, which specifically deal with this particular problem.
diff --git a/builds/windows/w32-bcc.mk b/builds/windows/w32-bcc.mk
index 01aab1c..e7cf668 100644
--- a/builds/windows/w32-bcc.mk
+++ b/builds/windows/w32-bcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-bccd.mk b/builds/windows/w32-bccd.mk
index 2c14d6c..64dafdb 100644
--- a/builds/windows/w32-bccd.mk
+++ b/builds/windows/w32-bccd.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-dev.mk b/builds/windows/w32-dev.mk
index 279d5f9..7c89ad2 100644
--- a/builds/windows/w32-dev.mk
+++ b/builds/windows/w32-dev.mk
@@ -5,7 +5,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-gcc.mk b/builds/windows/w32-gcc.mk
index 9e3476b..f37c185 100644
--- a/builds/windows/w32-gcc.mk
+++ b/builds/windows/w32-gcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-icc.mk b/builds/windows/w32-icc.mk
index e695c12..cf51cce 100644
--- a/builds/windows/w32-icc.mk
+++ b/builds/windows/w32-icc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-intl.mk b/builds/windows/w32-intl.mk
index 1e36662..0c16b4c 100644
--- a/builds/windows/w32-intl.mk
+++ b/builds/windows/w32-intl.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-lcc.mk b/builds/windows/w32-lcc.mk
index 5729d36..0dd740e 100644
--- a/builds/windows/w32-lcc.mk
+++ b/builds/windows/w32-lcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-mingw32.mk b/builds/windows/w32-mingw32.mk
index b3a210d..dc323bd 100644
--- a/builds/windows/w32-mingw32.mk
+++ b/builds/windows/w32-mingw32.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-vcc.mk b/builds/windows/w32-vcc.mk
index 342c8aa..eea7db8 100644
--- a/builds/windows/w32-vcc.mk
+++ b/builds/windows/w32-vcc.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/w32-wat.mk b/builds/windows/w32-wat.mk
index 37ecc88..5392d2a 100644
--- a/builds/windows/w32-wat.mk
+++ b/builds/windows/w32-wat.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/builds/windows/win32-def.mk b/builds/windows/win32-def.mk
index f83d444..3242651 100644
--- a/builds/windows/win32-def.mk
+++ b/builds/windows/win32-def.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -13,11 +13,15 @@
 # fully.
 
 
-DELETE    := del
-CAT       := type
-SEP       := $(strip \ )
-BUILD_DIR := $(TOP_DIR)/builds/windows
-PLATFORM  := windows
+DELETE       := del
+CAT          := type
+SEP          := $(strip \ )
+PLATFORM_DIR := $(TOP_DIR)/builds/windows
+PLATFORM     := windows
+
+# This is used for `make refdoc' and `make refdoc-venv'
+#
+BIN := Scripts
 
 # The executable file extension (for tools). NOTE: WE INCLUDE THE DOT HERE !!
 #
diff --git a/configure b/configure
index f9d2186..75f8b7b 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -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 | egrep 'GNU|makepp'`" = x; then
+    if test "x`make -v 2>/dev/null | grep -E 'GNU|makepp'`" = x; then
       MAKE=gmake
     else
       MAKE=make
@@ -28,7 +28,7 @@
   MAKE=$GNUMAKE
 fi
 
-if test "x`$MAKE -v 2>/dev/null | egrep 'GNU|makepp'`" = x; then
+if test "x`$MAKE -v 2>/dev/null | grep -E 'GNU|makepp'`" = x; then
   echo "GNU make (>= 3.81) or makepp (>= 2.0) is required to build FreeType2." >&2
   echo "Please try" >&2
   echo >&2
@@ -93,9 +93,11 @@
 inode_src=`ls -id $abs_ft2_dir | awk '{print $1}'`
 inode_dst=`ls -id $abs_curr_dir | awk '{print $1}'`
 
-if test $inode_src -ne $inode_dst; then
-  if test ! -d reference; then
-    mkdir reference
+if test $inode_src != $inode_dst; then
+  if test ! -d docs; then
+    mkdir docs
+    echo "Copying documentation assets"
+    cp -R $abs_ft2_dir/docs/markdown $abs_curr_dir/docs
   fi
   if test ! -r $abs_curr_dir/modules.cfg; then
     echo "Copying \`modules.cfg'"
@@ -105,7 +107,7 @@
   echo "TOP_DIR        := $abs_ft2_dir"           > Makefile
   echo "OBJ_DIR        := $abs_curr_dir"         >> Makefile
   echo "OBJ_BUILD      := \$(OBJ_DIR)"           >> Makefile
-  echo "DOC_DIR        := \$(OBJ_DIR)/reference" >> Makefile
+  echo "DOC_DIR        := \$(OBJ_DIR)/docs"      >> Makefile
   echo "FT_LIBTOOL_DIR := \$(OBJ_DIR)"           >> Makefile
   echo "ifndef FT2DEMOS"                         >> Makefile
   echo "  include \$(TOP_DIR)/Makefile"          >> Makefile
diff --git a/devel-teeui/OWNERS b/devel-teeui/OWNERS
new file mode 100644
index 0000000..205025e
--- /dev/null
+++ b/devel-teeui/OWNERS
@@ -0,0 +1,4 @@
+jdanis@google.com
+mmaurer@google.com
+trong@google.com
+ncbray@google.com
diff --git a/devel-teeui/README.md b/devel-teeui/README.md
new file mode 100644
index 0000000..a1608e6
--- /dev/null
+++ b/devel-teeui/README.md
@@ -0,0 +1,17 @@
+# TEEUI build rules
+
+This directory holds build rules for building a minimal freetype library
+for teeui. Teeui (Android system/teeui) provides minimal layout and
+UI rendering facilities for restricted runtime environments. It is used
+by the confirmationui trusted app for Trusty.
+
+## rules.mk
+
+This defines a freetype module for Trusty.
+
+## rules.json
+
+This is a generic json representation of the files and include paths
+required to build the teeui freetype library. Sufficiently generic
+build systems may be able to include this file directly, or it can be
+used to generate build rules for other build systems.
diff --git a/devel-teeui/ft2build.h b/devel-teeui/ft2build.h
new file mode 100644
index 0000000..e672252
--- /dev/null
+++ b/devel-teeui/ft2build.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ *
+ * ft2build.h
+ *
+ *   FreeType 2 build and setup macros (development version).
+ *
+ * Copyright (C) 1996-2019 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Google Inc.
+ *
+ * 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.
+ *
+ */
+
+#pragma once
+
+#define FT_CONFIG_OPTIONS_H  <ftoption.h>
+#define FT_CONFIG_MODULES_H  <ftmodule.h>
+
+
+/*
+ * Undefine PROJECT defined by the LK build system, because it would clash with freetype's
+ * definition in ttinterp.c.
+ */
+#undef PROJECT
+
+#include <freetype/config/ftheader.h>
diff --git a/devel-teeui/ftmodule.h b/devel-teeui/ftmodule.h
new file mode 100644
index 0000000..912d253
--- /dev/null
+++ b/devel-teeui/ftmodule.h
@@ -0,0 +1,8 @@
+
+FT_USE_MODULE( FT_Module_Class, autofit_module_class )
+FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
+FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
+
+/* EOF */
diff --git a/devel-teeui/ftoption.h b/devel-teeui/ftoption.h
new file mode 100644
index 0000000..ce767c5
--- /dev/null
+++ b/devel-teeui/ftoption.h
@@ -0,0 +1,969 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftoption.h                                                             */
+/*                                                                         */
+/*    User-selectable configuration macros (specification only).           */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#pragma once
+
+#include <ft2build.h>
+
+
+FT_BEGIN_HEADER
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* This file contains the default configuration macro definitions for    */
+  /* a standard build of the FreeType library.  There are three ways to    */
+  /* use this file to build project-specific versions of the library:      */
+  /*                                                                       */
+  /*  - You can modify this file by hand, but this is not recommended in   */
+  /*    cases where you would like to build several versions of the        */
+  /*    library from a single source directory.                            */
+  /*                                                                       */
+  /*  - You can put a copy of this file in your build directory, more      */
+  /*    precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'   */
+  /*    is the name of a directory that is included _before_ the FreeType  */
+  /*    include path during compilation.                                   */
+  /*                                                                       */
+  /*    The default FreeType Makefiles and Jamfiles use the build          */
+  /*    directory `builds/<system>' by default, but you can easily change  */
+  /*    that for your own projects.                                        */
+  /*                                                                       */
+  /*  - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it    */
+  /*    slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to       */
+  /*    locate this file during the build.  For example,                   */
+  /*                                                                       */
+  /*      #define FT_CONFIG_OPTIONS_H  <myftoptions.h>                     */
+  /*      #include <freetype/config/ftheader.h>                            */
+  /*                                                                       */
+  /*    will use `$BUILD/myftoptions.h' instead of this file for macro     */
+  /*    definitions.                                                       */
+  /*                                                                       */
+  /*    Note also that you can similarly pre-define the macro              */
+  /*    FT_CONFIG_MODULES_H used to locate the file listing of the modules */
+  /*    that are statically linked to the library at compile time.  By     */
+  /*    default, this file is <freetype/config/ftmodule.h>.                */
+  /*                                                                       */
+  /* We highly recommend using the third method whenever possible.         */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /**** G E N E R A L   F R E E T Y P E   2   C O N F I G U R A T I O N ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*#***********************************************************************/
+  /*                                                                       */
+  /* If you enable this configuration option, FreeType recognizes an       */
+  /* environment variable called `FREETYPE_PROPERTIES', which can be used  */
+  /* to control the various font drivers and modules.  The controllable    */
+  /* properties are listed in the section @properties.                     */
+  /*                                                                       */
+  /* You have to undefine this configuration option on platforms that lack */
+  /* the concept of environment variables (and thus don't have the         */
+  /* `getenv' function), for example Windows CE.                           */
+  /*                                                                       */
+  /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
+  /* multiple lines for better readability).                               */
+  /*                                                                       */
+  /* {                                                                     */
+  /*   <optional whitespace>                                               */
+  /*   <module-name1> ':'                                                  */
+  /*   <property-name1> '=' <property-value1>                              */
+  /*   <whitespace>                                                        */
+  /*   <module-name2> ':'                                                  */
+  /*   <property-name2> '=' <property-value2>                              */
+  /*   ...                                                                 */
+  /* }                                                                     */
+  /*                                                                       */
+  /* Example:                                                              */
+  /*                                                                       */
+  /*   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \               */
+  /*                       cff:no-stem-darkening=1 \                       */
+  /*                       autofitter:warping=1                            */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Uncomment the line below if you want to activate LCD rendering        */
+  /* technology similar to ClearType in this build of the library.  This   */
+  /* technology triples the resolution in the direction color subpixels.   */
+  /* To mitigate color fringes inherent to this technology, you also need  */
+  /* to explicitly set up LCD filtering.                                   */
+  /*                                                                       */
+  /* Note that this feature is covered by several Microsoft patents        */
+  /* and should not be activated in any default build of the library.      */
+  /* When this macro is not defined, FreeType offers alternative LCD       */
+  /* rendering technology that produces excellent output without LCD       */
+  /* filtering.                                                            */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Many compilers provide a non-ANSI 64-bit data type that can be used   */
+  /* by FreeType to speed up some computations.  However, this will create */
+  /* some problems when compiling the library in strict ANSI mode.         */
+  /*                                                                       */
+  /* For this reason, the use of 64-bit integers is normally disabled when */
+  /* the __STDC__ macro is defined.  You can however disable this by       */
+  /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.                 */
+  /*                                                                       */
+  /* For most compilers, this will only create compilation warnings when   */
+  /* building the library.                                                 */
+  /*                                                                       */
+  /* ObNote: The compiler-specific 64-bit integers are detected in the     */
+  /*         file `ftconfig.h' either statically or through the            */
+  /*         `configure' script on supported platforms.                    */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_FORCE_INT64
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* If this macro is defined, do not try to use an assembler version of   */
+  /* performance-critical functions (e.g. FT_MulFix).  You should only do  */
+  /* that to verify that the assembler function works properly, or to      */
+  /* execute benchmark tests of the various implementations.               */
+/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* If this macro is defined, try to use an inlined assembler version of  */
+  /* the `FT_MulFix' function, which is a `hotspot' when loading and       */
+  /* hinting glyphs, and which should be executed as fast as possible.     */
+  /*                                                                       */
+  /* Note that if your compiler or CPU is not supported, this will default */
+  /* to the standard and portable implementation found in `ftcalc.c'.      */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_INLINE_MULFIX
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* LZW-compressed file support.                                          */
+  /*                                                                       */
+  /*   FreeType now handles font files that have been compressed with the  */
+  /*   `compress' program.  This is mostly used to parse many of the PCF   */
+  /*   files that come with various X11 distributions.  The implementation */
+  /*   uses NetBSD's `zopen' to partially uncompress the file on the fly   */
+  /*   (see src/lzw/ftgzip.c).                                             */
+  /*                                                                       */
+  /*   Define this macro if you want to enable this `feature'.             */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_USE_LZW */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Gzip-compressed file support.                                         */
+  /*                                                                       */
+  /*   FreeType now handles font files that have been compressed with the  */
+  /*   `gzip' program.  This is mostly used to parse many of the PCF files */
+  /*   that come with XFree86.  The implementation uses `zlib' to          */
+  /*   partially uncompress the file on the fly (see src/gzip/ftgzip.c).   */
+  /*                                                                       */
+  /*   Define this macro if you want to enable this `feature'.  See also   */
+  /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_USE_ZLIB */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ZLib library selection                                                */
+  /*                                                                       */
+  /*   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.  */
+  /*   It allows FreeType's `ftgzip' component to link to the system's     */
+  /*   installation of the ZLib library.  This is useful on systems like   */
+  /*   Unix or VMS where it generally is already available.                */
+  /*                                                                       */
+  /*   If you let it undefined, the component will use its own copy        */
+  /*   of the zlib sources instead.  These have been modified to be        */
+  /*   included directly within the component and *not* export external    */
+  /*   function names.  This allows you to link any program with FreeType  */
+  /*   _and_ ZLib without linking conflicts.                               */
+  /*                                                                       */
+  /*   Do not #undef this macro here since the build system might define   */
+  /*   it for certain configurations only.                                 */
+  /*                                                                       */
+  /*   If you use a build system like cmake or the `configure' script,     */
+  /*   options set by those programs have precendence, overwriting the     */
+  /*   value here with the configured one.                                 */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Bzip2-compressed file support.                                        */
+  /*                                                                       */
+  /*   FreeType now handles font files that have been compressed with the  */
+  /*   `bzip2' program.  This is mostly used to parse many of the PCF      */
+  /*   files that come with XFree86.  The implementation uses `libbz2' to  */
+  /*   partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */
+  /*   Contrary to gzip, bzip2 currently is not included and need to use   */
+  /*   the system available bzip2 implementation.                          */
+  /*                                                                       */
+  /*   Define this macro if you want to enable this `feature'.             */
+  /*                                                                       */
+  /*   If you use a build system like cmake or the `configure' script,     */
+  /*   options set by those programs have precendence, overwriting the     */
+  /*   value here with the configured one.                                 */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_USE_BZIP2 */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define to disable the use of file stream functions and types, FILE,   */
+  /* fopen() etc.  Enables the use of smaller system libraries on embedded */
+  /* systems that have multiple system libraries, some with or without     */
+  /* file stream support, in the cases where file stream support is not    */
+  /* necessary such as memory loading of font files.                       */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* PNG bitmap support.                                                   */
+  /*                                                                       */
+  /*   FreeType now handles loading color bitmap glyphs in the PNG format. */
+  /*   This requires help from the external libpng library.  Uncompressed  */
+  /*   color bitmaps do not need any external libraries and will be        */
+  /*   supported regardless of this configuration.                         */
+  /*                                                                       */
+  /*   Define this macro if you want to enable this `feature'.             */
+  /*                                                                       */
+  /*   If you use a build system like cmake or the `configure' script,     */
+  /*   options set by those programs have precendence, overwriting the     */
+  /*   value here with the configured one.                                 */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_USE_PNG */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* HarfBuzz support.                                                     */
+  /*                                                                       */
+  /*   FreeType uses the HarfBuzz library to improve auto-hinting of       */
+  /*   OpenType fonts.  If available, many glyphs not directly addressable */
+  /*   by a font's character map will be hinted also.                      */
+  /*                                                                       */
+  /*   Define this macro if you want to enable this `feature'.             */
+  /*                                                                       */
+  /*   If you use a build system like cmake or the `configure' script,     */
+  /*   options set by those programs have precendence, overwriting the     */
+  /*   value here with the configured one.                                 */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Glyph Postscript Names handling                                       */
+  /*                                                                       */
+  /*   By default, FreeType 2 is compiled with the `psnames' module.  This */
+  /*   module is in charge of converting a glyph name string into a        */
+  /*   Unicode value, or return a Macintosh standard glyph name for the    */
+  /*   use with the TrueType `post' table.                                 */
+  /*                                                                       */
+  /*   Undefine this macro if you do not want `psnames' compiled in your   */
+  /*   build of FreeType.  This has the following effects:                 */
+  /*                                                                       */
+  /*   - The TrueType driver will provide its own set of glyph names,      */
+  /*     if you build it to support postscript names in the TrueType       */
+  /*     `post' table, but will not synthesize a missing Unicode charmap.  */
+  /*                                                                       */
+  /*   - The Type 1 driver will not be able to synthesize a Unicode        */
+  /*     charmap out of the glyphs found in the fonts.                     */
+  /*                                                                       */
+  /*   You would normally undefine this configuration macro when building  */
+  /*   a version of FreeType that doesn't contain a Type 1 or CFF driver.  */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Postscript Names to Unicode Values support                            */
+  /*                                                                       */
+  /*   By default, FreeType 2 is built with the `PSNames' module compiled  */
+  /*   in.  Among other things, the module is used to convert a glyph name */
+  /*   into a Unicode value.  This is especially useful in order to        */
+  /*   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver  */
+  /*   through a big table named the `Adobe Glyph List' (AGL).             */
+  /*                                                                       */
+  /*   Undefine this macro if you do not want the Adobe Glyph List         */
+  /*   compiled in your `PSNames' module.  The Type 1 driver will not be   */
+  /*   able to synthesize a Unicode charmap out of the glyphs found in the */
+  /*   fonts.                                                              */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Support for Mac fonts                                                 */
+  /*                                                                       */
+  /*   Define this macro if you want support for outline fonts in Mac      */
+  /*   format (mac dfont, mac resource, macbinary containing a mac         */
+  /*   resource) on non-Mac platforms.                                     */
+  /*                                                                       */
+  /*   Note that the `FOND' resource isn't checked.                        */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_MAC_FONTS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Guessing methods to access embedded resource forks                    */
+  /*                                                                       */
+  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */
+  /*   GNU/Linux).                                                         */
+  /*                                                                       */
+  /*   Resource forks which include fonts data are stored sometimes in     */
+  /*   locations which users or developers don't expected.  In some cases, */
+  /*   resource forks start with some offset from the head of a file.  In  */
+  /*   other cases, the actual resource fork is stored in file different   */
+  /*   from what the user specifies.  If this option is activated,         */
+  /*   FreeType tries to guess whether such offsets or different file      */
+  /*   names must be used.                                                 */
+  /*                                                                       */
+  /*   Note that normal, direct access of resource forks is controlled via */
+  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */
+  /*                                                                       */
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
+#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Allow the use of FT_Incremental_Interface to load typefaces that      */
+  /* contain no glyph data, but supply it via a callback function.         */
+  /* This is required by clients supporting document formats which         */
+  /* supply font data incrementally as the document is parsed, such        */
+  /* as the Ghostscript interpreter for the PostScript language.           */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_INCREMENTAL
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The size in bytes of the render pool used by the scan-line converter  */
+  /* to do all of its work.                                                */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE  16384L
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_MAX_MODULES                                                        */
+  /*                                                                       */
+  /*   The maximum number of modules that can be registered in a single    */
+  /*   FreeType library object.  32 is the default.                        */
+  /*                                                                       */
+#define FT_MAX_MODULES  32
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode!      */
+  /*                                                                       */
+  /*   Do not #undef these macros here since the build system might define */
+  /*   them for certain configurations only.                               */
+  /*                                                                       */
+/* #define FT_DEBUG_LEVEL_ERROR */
+/* #define FT_DEBUG_LEVEL_TRACE */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Autofitter debugging                                                  */
+  /*                                                                       */
+  /*   If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to     */
+  /*   control the autofitter behaviour for debugging purposes with global */
+  /*   boolean variables (consequently, you should *never* enable this     */
+  /*   while compiling in `release' mode):                                 */
+  /*                                                                       */
+  /*     _af_debug_disable_horz_hints                                      */
+  /*     _af_debug_disable_vert_hints                                      */
+  /*     _af_debug_disable_blue_hints                                      */
+  /*                                                                       */
+  /*   Additionally, the following functions provide dumps of various      */
+  /*   internal autofit structures to stdout (using `printf'):             */
+  /*                                                                       */
+  /*     af_glyph_hints_dump_points                                        */
+  /*     af_glyph_hints_dump_segments                                      */
+  /*     af_glyph_hints_dump_edges                                         */
+  /*     af_glyph_hints_get_num_segments                                   */
+  /*     af_glyph_hints_get_segment_offset                                 */
+  /*                                                                       */
+  /*   As an argument, they use another global variable:                   */
+  /*                                                                       */
+  /*     _af_debug_hints                                                   */
+  /*                                                                       */
+  /*   Please have a look at the `ftgrid' demo program to see how those    */
+  /*   variables and macros should be used.                                */
+  /*                                                                       */
+  /*   Do not #undef these macros here since the build system might define */
+  /*   them for certain configurations only.                               */
+  /*                                                                       */
+/* #define FT_DEBUG_AUTOFIT */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Memory Debugging                                                      */
+  /*                                                                       */
+  /*   FreeType now comes with an integrated memory debugger that is       */
+  /*   capable of detecting simple errors like memory leaks or double      */
+  /*   deletes.  To compile it within your build of the library, you       */
+  /*   should define FT_DEBUG_MEMORY here.                                 */
+  /*                                                                       */
+  /*   Note that the memory debugger is only activated at runtime when     */
+  /*   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */
+  /*                                                                       */
+  /*   Do not #undef this macro here since the build system might define   */
+  /*   it for certain configurations only.                                 */
+  /*                                                                       */
+/* #define FT_DEBUG_MEMORY */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Module errors                                                         */
+  /*                                                                       */
+  /*   If this macro is set (which is _not_ the default), the higher byte  */
+  /*   of an error code gives the module in which the error has occurred,  */
+  /*   while the lower byte is the real error code.                        */
+  /*                                                                       */
+  /*   Setting this macro makes sense for debugging purposes only, since   */
+  /*   it would break source compatibility of certain programs that use    */
+  /*   FreeType 2.                                                         */
+  /*                                                                       */
+  /*   More details can be found in the files ftmoderr.h and fterrors.h.   */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Position Independent Code                                             */
+  /*                                                                       */
+  /*   If this macro is set (which is _not_ the default), FreeType2 will   */
+  /*   avoid creating constants that require address fixups.  Instead the  */
+  /*   constants will be moved into a struct and additional intialization  */
+  /*   code will be used.                                                  */
+  /*                                                                       */
+  /*   Setting this macro is needed for systems that prohibit address      */
+  /*   fixups, such as BREW.  [Note that standard compilers like gcc or    */
+  /*   clang handle PIC generation automatically; you don't have to set    */
+  /*   FT_CONFIG_OPTION_PIC, which is only necessary for very special      */
+  /*   compilers.]                                                         */
+  /*                                                                       */
+  /*   Note that FT_CONFIG_OPTION_PIC support is not available for all     */
+  /*   modules (see `modules.cfg' for a complete list).  For building with */
+  /*   FT_CONFIG_OPTION_PIC support, do the following.                     */
+  /*                                                                       */
+  /*     0. Clone the repository.                                          */
+  /*     1. Define FT_CONFIG_OPTION_PIC.                                   */
+  /*     2. Remove all subdirectories in `src' that don't have             */
+  /*        FT_CONFIG_OPTION_PIC support.                                  */
+  /*     3. Comment out the corresponding modules in `modules.cfg'.        */
+  /*     4. Compile.                                                       */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_PIC */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****        S F N T   D R I V E R    C O N F I G U R A T I O N       ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
+  /* embedded bitmaps in all formats using the SFNT module (namely         */
+  /* TrueType & OpenType).                                                 */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */
+  /* load and enumerate the glyph Postscript names in a TrueType or        */
+  /* OpenType file.                                                        */
+  /*                                                                       */
+  /* Note that when you do not compile the `PSNames' module by undefining  */
+  /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will   */
+  /* contain additional code used to read the PS Names table from a font.  */
+  /*                                                                       */
+  /* (By default, the module uses `PSNames' to extract glyph names.)       */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to       */
+  /* access the internal name table in a SFNT-based format like TrueType   */
+  /* or OpenType.  The name table contains various strings used to         */
+  /* describe the font, like family name, copyright, version, etc.  It     */
+  /* does not contain any glyph name though.                               */
+  /*                                                                       */
+  /* Accessing SFNT names is done through the functions declared in        */
+  /* `ftsnames.h'.                                                         */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_SFNT_NAMES
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* TrueType CMap support                                                 */
+  /*                                                                       */
+  /*   Here you can fine-tune which TrueType CMap table format shall be    */
+  /*   supported.                                                          */
+#define TT_CONFIG_CMAP_FORMAT_0
+#define TT_CONFIG_CMAP_FORMAT_2
+#define TT_CONFIG_CMAP_FORMAT_4
+#define TT_CONFIG_CMAP_FORMAT_6
+#define TT_CONFIG_CMAP_FORMAT_8
+#define TT_CONFIG_CMAP_FORMAT_10
+#define TT_CONFIG_CMAP_FORMAT_12
+#define TT_CONFIG_CMAP_FORMAT_13
+#define TT_CONFIG_CMAP_FORMAT_14
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****    T R U E T Y P E   D R I V E R    C O N F I G U R A T I O N   ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile   */
+  /* a bytecode interpreter in the TrueType driver.                        */
+  /*                                                                       */
+  /* By undefining this, you will only compile the code necessary to load  */
+  /* TrueType glyphs without hinting.                                      */
+  /*                                                                       */
+  /*   Do not #undef this macro here, since the build system might         */
+  /*   define it for certain configurations only.                          */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile       */
+  /* subpixel hinting support into the TrueType driver.  This modifies the */
+  /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is   */
+  /* requested.                                                            */
+  /*                                                                       */
+  /* In particular, it modifies the bytecode interpreter to interpret (or  */
+  /* not) instructions in a certain way so that all TrueType fonts look    */
+  /* like they do in a Windows ClearType (DirectWrite) environment.  See   */
+  /* [1] for a technical overview on what this means.  See `ttinterp.h'    */
+  /* for more details on the LEAN option.                                  */
+  /*                                                                       */
+  /* 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).                                                          */
+  /*                                                                       */
+  /* By undefining these, you get rendering behavior like on Windows       */
+  /* without ClearType, i.e., Windows XP without ClearType enabled and     */
+  /* Win9x (interpreter version v35).  Or not, depending on how much       */
+  /* hinting blood and testing tears the font designer put into a given    */
+  /* font.  If you define one or both subpixel hinting options, you can    */
+  /* switch between between v35 and the ones you define (using             */
+  /* `FT_Property_Set').                                                   */
+  /*                                                                       */
+  /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be      */
+  /* defined.                                                              */
+  /*                                                                       */
+  /* [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_COMPONENT_OFFSET_SCALED to compile the        */
+  /* TrueType glyph loader to use Apple's definition of how to handle      */
+  /* component offsets in composite glyphs.                                */
+  /*                                                                       */
+  /* Apple and MS disagree on the default behavior of component offsets    */
+  /* in composites.  Apple says that they should be scaled by the scaling  */
+  /* factors in the transformation matrix (roughly, it's more complex)     */
+  /* while MS says they should not.  OpenType defines two bits in the      */
+  /* composite flags array which can be used to disambiguate, but old      */
+  /* fonts will not have them.                                             */
+  /*                                                                       */
+  /*   https://www.microsoft.com/typography/otspec/glyf.htm                */
+  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */
+  /*                                                                       */
+#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include         */
+  /* support for Apple's distortable font technology (fvar, gvar, cvar,    */
+  /* and avar tables).  This has many similarities to Type 1 Multiple      */
+  /* Masters support.                                                      */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
+  /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_BDF
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum     */
+  /* number of bytecode instructions executed for a single run of the      */
+  /* bytecode interpreter, needed to prevent infinite loops.  You don't    */
+  /* want to change this except for very special situations (e.g., making  */
+  /* a library fuzzer spend less time to handle broken fonts).             */
+  /*                                                                       */
+  /* It is not expected that this value is ever modified by a configuring  */
+  /* script; instead, it gets surrounded with #ifndef ... #endif so that   */
+  /* the value can be set as a preprocessor option on the compiler's       */
+  /* command line.                                                         */
+  /*                                                                       */
+#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
+#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES  1000000L
+#endif
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and       */
+  /* arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is        */
+  /* required.                                                             */
+  /*                                                                       */
+#define T1_MAX_DICT_DEPTH  5
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */
+  /* calls during glyph loading.                                           */
+  /*                                                                       */
+#define T1_MAX_SUBRS_CALLS  16
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */
+  /* minimum of 16 is required.                                            */
+  /*                                                                       */
+  /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */
+  /*                                                                       */
+#define T1_MAX_CHARSTRINGS_OPERANDS  256
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro if you want to prevent the            */
+  /* compilation of `t1afm', which is in charge of reading Type 1 AFM      */
+  /* files into an existing face.  Note that if set, the T1 driver will be */
+  /* unable to produce kerning distances.                                  */
+  /*                                                                       */
+#undef T1_CONFIG_OPTION_NO_AFM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro if you want to prevent the            */
+  /* compilation of the Multiple Masters font support in the Type 1        */
+  /* driver.                                                               */
+  /*                                                                       */
+#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1     */
+  /* engine gets compiled into FreeType.  If defined, it is possible to    */
+  /* switch between the two engines using the `hinting-engine' property of */
+  /* the type1 driver module.                                              */
+  /*                                                                       */
+/* #define T1_CONFIG_OPTION_OLD_ENGINE */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****         C F F   D R I V E R    C O N F I G U R A T I O N        ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is      */
+  /* possible to set up the default values of the four control points that */
+  /* define the stem darkening behaviour of the (new) CFF engine.  For     */
+  /* more details please read the documentation of the                     */
+  /* `darkening-parameters' property (file `ftdriver.h'), which allows the */
+  /* control at run-time.                                                  */
+  /*                                                                       */
+  /* Do *not* undefine these macros!                                       */
+  /*                                                                       */
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1   500
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1   400
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2  1000
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2   275
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3  1667
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3   275
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4  2333
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4     0
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF       */
+  /* engine gets compiled into FreeType.  If defined, it is possible to    */
+  /* switch between the two engines using the `hinting-engine' property of */
+  /* the cff driver module.                                                */
+  /*                                                                       */
+/* #define CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****         P C F   D R I V E R    C O N F I G U R A T I O N        ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* There are many PCF fonts just called `Fixed' which look completely    */
+  /* different, and which have nothing to do with each other.  When        */
+  /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */
+  /* random, the style changes often if one changes the size and one       */
+  /* cannot select some fonts at all.  This option makes the PCF module    */
+  /* prepend the foundry name (plus a space) to the family name.           */
+  /*                                                                       */
+  /* We also check whether we have `wide' characters; all put together, we */
+  /* get family names like `Sony Fixed' or `Misc Fixed Wide'.              */
+  /*                                                                       */
+  /* If this option is activated, it can be controlled with the            */
+  /* `no-long-family-names' property of the pcf driver module.             */
+  /*                                                                       */
+/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compile autofit module with CJK (Chinese, Japanese, Korean) script    */
+  /* support.                                                              */
+  /*                                                                       */
+#define AF_CONFIG_OPTION_CJK
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compile autofit module with fallback Indic script support, covering   */
+  /* some scripts that the `latin' submodule of the autofit module doesn't */
+  /* (yet) handle.                                                         */
+  /*                                                                       */
+#define AF_CONFIG_OPTION_INDIC
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compile autofit module with warp hinting.  The idea of the warping    */
+  /* code is to slightly scale and shift a glyph within a single dimension */
+  /* so that as much of its segments are aligned (more or less) on the     */
+  /* grid.  To find out the optimal scaling and shifting value, various    */
+  /* parameter combinations are tried and scored.                          */
+  /*                                                                       */
+  /* This experimental option is active only if the rendering mode is      */
+  /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the      */
+  /* `warping' property of the auto-hinter (see file `ftdriver.h' for more */
+  /* information; by default it is switched off).                          */
+  /*                                                                       */
+#define AF_CONFIG_OPTION_USE_WARPER
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Use TrueType-like size metrics for `light' auto-hinting.              */
+  /*                                                                       */
+  /* It is strongly recommended to avoid this option, which exists only to */
+  /* help some legacy applications retain its appearance and behaviour     */
+  /* with respect to auto-hinted TrueType fonts.                           */
+  /*                                                                       */
+  /* The very reason this option exists at all are GNU/Linux distributions */
+  /* like Fedora that did not un-patch the following change (which was     */
+  /* present in FreeType between versions 2.4.6 and 2.7.1, inclusive).     */
+  /*                                                                       */
+  /*   2011-07-16  Steven Chu  <steven.f.chu@gmail.com>                    */
+  /*                                                                       */
+  /*     [truetype] Fix metrics on size request for scalable fonts.        */
+  /*                                                                       */
+  /* This problematic commit is now reverted (more or less).               */
+  /*                                                                       */
+/* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */
+
+  /* */
+
+
+  /*
+   * This macro is obsolete.  Support has been removed in FreeType
+   * version 2.5.
+   */
+/* #define FT_CONFIG_OPTION_OLD_INTERNALS */
+
+
+  /*
+   * This macro is defined if native TrueType hinting is requested by the
+   * definitions above.
+   */
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#define  TT_USE_BYTECODE_INTERPRETER
+
+#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
+
+
+  /*
+   * Check CFF darkening parameters.  The checks are the same as in function
+   * `cff_property_set' in file `cffdrivr.c'.
+   */
+#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0   || \
+                                                      \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0   || \
+                                                      \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 >        \
+      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2     || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 >        \
+      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3     || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 >        \
+      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4     || \
+                                                      \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500
+#error "Invalid CFF darkening parameters!"
+#endif
+
+FT_END_HEADER
diff --git a/devel-teeui/rules.json b/devel-teeui/rules.json
new file mode 100644
index 0000000..c6e68ea
--- /dev/null
+++ b/devel-teeui/rules.json
@@ -0,0 +1,24 @@
+{
+"includes": [
+    "../devel-teeui",
+    "../include"
+],
+"sources": [
+    "../src/base/ftsystem.c",
+    "../src/base/ftinit.c",
+    "../src/base/ftdebug.c",
+    "../src/base/ftbase.c",
+    "../src/base/ftbbox.c",
+    "../src/base/ftglyph.c",
+    "../src/base/ftbitmap.c",
+    "../src/sfnt/sfnt.c",
+    "../src/truetype/truetype.c",
+    "../src/raster/raster.c",
+    "../src/smooth/smooth.c",
+    "../src/autofit/autofit.c",
+    "../src/gzip/ftgzip.c"
+],
+"cflags": [
+    "-DFT2_BUILD_LIBRARY"
+    ]
+}
diff --git a/devel-teeui/rules.mk b/devel-teeui/rules.mk
new file mode 100644
index 0000000..b834ce7
--- /dev/null
+++ b/devel-teeui/rules.mk
@@ -0,0 +1,32 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+FREETYPE_ROOT := $(TRUSTY_TOP)/external/freetype
+
+MODULE_SRCS += \
+	$(FREETYPE_ROOT)/src/base/ftsystem.c \
+	$(FREETYPE_ROOT)/src/base/ftinit.c \
+	$(FREETYPE_ROOT)/src/base/ftdebug.c \
+	$(FREETYPE_ROOT)/src/base/ftbase.c \
+	$(FREETYPE_ROOT)/src/base/ftbbox.c \
+	$(FREETYPE_ROOT)/src/base/ftglyph.c \
+	$(FREETYPE_ROOT)/src/base/ftbitmap.c \
+	$(FREETYPE_ROOT)/src/sfnt/sfnt.c \
+	$(FREETYPE_ROOT)/src/truetype/truetype.c \
+	$(FREETYPE_ROOT)/src/raster/raster.c \
+	$(FREETYPE_ROOT)/src/smooth/smooth.c \
+	$(FREETYPE_ROOT)/src/autofit/autofit.c \
+	$(FREETYPE_ROOT)/src/gzip/ftgzip.c \
+
+MODULE_EXPORT_INCLUDES += \
+	$(LOCAL_DIR) \
+	$(FREETYPE_ROOT)/include \
+
+MODULE_COMPILEFLAGS := -U__ANDROID__ -DFT2_BUILD_LIBRARY
+MODULE_COMPILEFLAGS += -Wno-implicit-fallthrough
+
+MODULE_LIBRARY_DEPS += \
+	trusty/user/base/lib/libc-trusty \
+
+include make/library.mk
diff --git a/devel/ft2build.h b/devel/ft2build.h
index bd4dddb..82fdb30 100644
--- a/devel/ft2build.h
+++ b/devel/ft2build.h
@@ -4,7 +4,7 @@
  *
  *   FreeType 2 build and setup macros (development version).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -30,6 +30,7 @@
 #ifndef FT2BUILD_H_
 #define FT2BUILD_H_
 
+#define FT_CONFIG_MODULES_H  <ftmodule.h>
 #define FT_CONFIG_OPTIONS_H  <ftoption.h>
 
 #include <freetype/config/ftheader.h>
diff --git a/devel/ftoption.h b/devel/ftoption.h
index c434ac1..1ae9b1a 100644
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -4,7 +4,7 @@
  *
  *   User-selectable configuration macros (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -29,39 +29,39 @@
    *
    *                USER-SELECTABLE CONFIGURATION MACROS
    *
-   * This file contains the default configuration macro definitions for
-   * a standard build of the FreeType library.  There are three ways to
-   * use this file to build project-specific versions of the library:
+   * This file contains the default configuration macro definitions for a
+   * standard build of the FreeType library.  There are three ways to use
+   * this file to build project-specific versions of the library:
    *
    * - You can modify this file by hand, but this is not recommended in
-   *   cases where you would like to build several versions of the
-   *   library from a single source directory.
+   *   cases where you would like to build several versions of the library
+   *   from a single source directory.
    *
    * - You can put a copy of this file in your build directory, more
-   *   precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'
-   *   is the name of a directory that is included _before_ the FreeType
-   *   include path during compilation.
+   *   precisely in `$BUILD/freetype/config/ftoption.h`, where `$BUILD` is
+   *   the name of a directory that is included _before_ the FreeType include
+   *   path during compilation.
    *
-   *   The default FreeType Makefiles and Jamfiles use the build
-   *   directory `builds/<system>' by default, but you can easily change
-   *   that for your own projects.
+   *   The default FreeType Makefiles use the build directory
+   *   `builds/<system>` by default, but you can easily change that for your
+   *   own projects.
    *
-   * - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it
-   *   slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to
-   *   locate this file during the build.  For example,
+   * - Copy the file <ft2build.h> to `$BUILD/ft2build.h` and modify it
+   *   slightly to pre-define the macro `FT_CONFIG_OPTIONS_H` used to locate
+   *   this file during the build.  For example,
    *
-   *   {
+   *   ```
    *     #define FT_CONFIG_OPTIONS_H  <myftoptions.h>
    *     #include <freetype/config/ftheader.h>
-   *   }
+   *   ```
    *
-   *   will use `$BUILD/myftoptions.h' instead of this file for macro
+   *   will use `$BUILD/myftoptions.h` instead of this file for macro
    *   definitions.
    *
    *   Note also that you can similarly pre-define the macro
-   *   FT_CONFIG_MODULES_H used to locate the file listing of the modules
+   *   `FT_CONFIG_MODULES_H` used to locate the file listing of the modules
    *   that are statically linked to the library at compile time.  By
-   *   default, this file is <freetype/config/ftmodule.h>.
+   *   default, this file is `<freetype/config/ftmodule.h>`.
    *
    * We highly recommend using the third method whenever possible.
    *
@@ -80,18 +80,18 @@
   /*#************************************************************************
    *
    * If you enable this configuration option, FreeType recognizes an
-   * environment variable called `FREETYPE_PROPERTIES', which can be used to
+   * environment variable called `FREETYPE_PROPERTIES`, which can be used to
    * control the various font drivers and modules.  The controllable
    * properties are listed in the section @properties.
    *
    * You have to undefine this configuration option on platforms that lack
-   * the concept of environment variables (and thus don't have the `getenv'
+   * the concept of environment variables (and thus don't have the `getenv`
    * function), for example Windows CE.
    *
-   * `FREETYPE_PROPERTIES' has the following syntax form (broken here into
+   * `FREETYPE_PROPERTIES` has the following syntax form (broken here into
    * multiple lines for better readability).
    *
-   * {
+   * ```
    *   <optional whitespace>
    *   <module-name1> ':'
    *   <property-name1> '=' <property-value1>
@@ -99,15 +99,14 @@
    *   <module-name2> ':'
    *   <property-name2> '=' <property-value2>
    *   ...
-   * }
+   * ```
    *
    * Example:
    *
-   * {
+   * ```
    *   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
-   *                       cff:no-stem-darkening=1 \
-   *                       autofitter:warping=1
-   * }
+   *                       cff:no-stem-darkening=1
+   * ```
    *
    */
 #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
@@ -117,35 +116,32 @@
    *
    * Uncomment the line below if you want to activate LCD rendering
    * technology similar to ClearType in this build of the library.  This
-   * technology triples the resolution in the direction color subpixels.
-   * To mitigate color fringes inherent to this technology, you also need
-   * to explicitly set up LCD filtering.
+   * technology triples the resolution in the direction color subpixels.  To
+   * mitigate color fringes inherent to this technology, you also need to
+   * explicitly set up LCD filtering.
    *
-   * Note that this feature is covered by several Microsoft patents
-   * and should not be activated in any default build of the library.
    * When this macro is not defined, FreeType offers alternative LCD
-   * rendering technology that produces excellent output without LCD
-   * filtering.
+   * rendering technology that produces excellent output.
    */
 /* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
 
 
   /**************************************************************************
    *
-   * Many compilers provide a non-ANSI 64-bit data type that can be used
-   * by FreeType to speed up some computations.  However, this will create
-   * some problems when compiling the library in strict ANSI mode.
+   * Many compilers provide a non-ANSI 64-bit data type that can be used by
+   * FreeType to speed up some computations.  However, this will create some
+   * problems when compiling the library in strict ANSI mode.
    *
    * For this reason, the use of 64-bit integers is normally disabled when
-   * the __STDC__ macro is defined.  You can however disable this by
-   * defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.
+   * the `__STDC__` macro is defined.  You can however disable this by
+   * defining the macro `FT_CONFIG_OPTION_FORCE_INT64` here.
    *
    * For most compilers, this will only create compilation warnings when
    * building the library.
    *
    * ObNote: The compiler-specific 64-bit integers are detected in the
-   *         file `ftconfig.h' either statically or through the
-   *         `configure' script on supported platforms.
+   *         file `ftconfig.h` either statically or through the `configure`
+   *         script on supported platforms.
    */
 #undef FT_CONFIG_OPTION_FORCE_INT64
 
@@ -153,21 +149,21 @@
   /**************************************************************************
    *
    * If this macro is defined, do not try to use an assembler version of
-   * performance-critical functions (e.g. FT_MulFix).  You should only do
-   * that to verify that the assembler function works properly, or to
-   * execute benchmark tests of the various implementations.
+   * performance-critical functions (e.g., @FT_MulFix).  You should only do
+   * that to verify that the assembler function works properly, or to execute
+   * benchmark tests of the various implementations.
    */
 /* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
 
 
   /**************************************************************************
    *
-   * If this macro is defined, try to use an inlined assembler version of
-   * the `FT_MulFix' function, which is a `hotspot' when loading and
-   * hinting glyphs, and which should be executed as fast as possible.
+   * If this macro is defined, try to use an inlined assembler version of the
+   * @FT_MulFix function, which is a 'hotspot' when loading and hinting
+   * glyphs, and which should be executed as fast as possible.
    *
-   * Note that if your compiler or CPU is not supported, this will default
-   * to the standard and portable implementation found in `ftcalc.c'.
+   * Note that if your compiler or CPU is not supported, this will default to
+   * the standard and portable implementation found in `ftcalc.c`.
    */
 #define FT_CONFIG_OPTION_INLINE_MULFIX
 
@@ -177,12 +173,12 @@
    * LZW-compressed file support.
    *
    *   FreeType now handles font files that have been compressed with the
-   *   `compress' program.  This is mostly used to parse many of the PCF
+   *   `compress` program.  This is mostly used to parse many of the PCF
    *   files that come with various X11 distributions.  The implementation
-   *   uses NetBSD's `zopen' to partially uncompress the file on the fly
-   *   (see src/lzw/ftgzip.c).
+   *   uses NetBSD's `zopen` to partially uncompress the file on the fly (see
+   *   `src/lzw/ftgzip.c`).
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    */
 #define FT_CONFIG_OPTION_USE_LZW
 
@@ -192,12 +188,12 @@
    * Gzip-compressed file support.
    *
    *   FreeType now handles font files that have been compressed with the
-   *   `gzip' program.  This is mostly used to parse many of the PCF files
-   *   that come with XFree86.  The implementation uses `zlib' to
-   *   partially uncompress the file on the fly (see src/gzip/ftgzip.c).
+   *   `gzip` program.  This is mostly used to parse many of the PCF files
+   *   that come with XFree86.  The implementation uses 'zlib' to partially
+   *   uncompress the file on the fly (see `src/gzip/ftgzip.c`).
    *
-   *   Define this macro if you want to enable this `feature'.  See also
-   *   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.
+   *   Define this macro if you want to enable this 'feature'.  See also the
+   *   macro `FT_CONFIG_OPTION_SYSTEM_ZLIB` below.
    */
 #define FT_CONFIG_OPTION_USE_ZLIB
 
@@ -206,23 +202,27 @@
    *
    * ZLib library selection
    *
-   *   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.
-   *   It allows FreeType's `ftgzip' component to link to the system's
+   *   This macro is only used when `FT_CONFIG_OPTION_USE_ZLIB` is defined.
+   *   It allows FreeType's 'ftgzip' component to link to the system's
    *   installation of the ZLib library.  This is useful on systems like
    *   Unix or VMS where it generally is already available.
    *
-   *   If you let it undefined, the component will use its own copy
-   *   of the zlib sources instead.  These have been modified to be
-   *   included directly within the component and *not* export external
-   *   function names.  This allows you to link any program with FreeType
-   *   _and_ ZLib without linking conflicts.
+   *   If you let it undefined, the component will use its own copy of the
+   *   zlib sources instead.  These have been modified to be included
+   *   directly within the component and **not** export external function
+   *   names.  This allows you to link any program with FreeType _and_ ZLib
+   *   without linking conflicts.
    *
-   *   Do not #undef this macro here since the build system might define
+   *   Do not `#undef` this macro here since the build system might define
    *   it for certain configurations only.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
+   *
+   *   If you use the GNU make build system directly (that is, without the
+   *   `configure` script) and you define this macro, you also have to pass
+   *   `SYSTEM_ZLIB=yes` as an argument to make.
    */
 /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
 
@@ -232,28 +232,28 @@
    * Bzip2-compressed file support.
    *
    *   FreeType now handles font files that have been compressed with the
-   *   `bzip2' program.  This is mostly used to parse many of the PCF
-   *   files that come with XFree86.  The implementation uses `libbz2' to
-   *   partially uncompress the file on the fly (see src/bzip2/ftbzip2.c).
-   *   Contrary to gzip, bzip2 currently is not included and need to use
-   *   the system available bzip2 implementation.
+   *   `bzip2` program.  This is mostly used to parse many of the PCF files
+   *   that come with XFree86.  The implementation uses `libbz2` to partially
+   *   uncompress the file on the fly (see `src/bzip2/ftbzip2.c`).  Contrary
+   *   to gzip, bzip2 currently is not included and need to use the system
+   *   available bzip2 implementation.
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
    */
 #define FT_CONFIG_OPTION_USE_BZIP2
 
 
   /**************************************************************************
    *
-   * Define to disable the use of file stream functions and types, FILE,
-   * fopen() etc.  Enables the use of smaller system libraries on embedded
-   * systems that have multiple system libraries, some with or without
-   * file stream support, in the cases where file stream support is not
-   * necessary such as memory loading of font files.
+   * Define to disable the use of file stream functions and types, `FILE`,
+   * `fopen`, etc.  Enables the use of smaller system libraries on embedded
+   * systems that have multiple system libraries, some with or without file
+   * stream support, in the cases where file stream support is not necessary
+   * such as memory loading of font files.
    */
 /* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
 
@@ -264,14 +264,14 @@
    *
    *   FreeType now handles loading color bitmap glyphs in the PNG format.
    *   This requires help from the external libpng library.  Uncompressed
-   *   color bitmaps do not need any external libraries and will be
-   *   supported regardless of this configuration.
+   *   color bitmaps do not need any external libraries and will be supported
+   *   regardless of this configuration.
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
    */
 #define FT_CONFIG_OPTION_USE_PNG
 
@@ -280,40 +280,56 @@
    *
    * HarfBuzz support.
    *
-   *   FreeType uses the HarfBuzz library to improve auto-hinting of
-   *   OpenType fonts.  If available, many glyphs not directly addressable
-   *   by a font's character map will be hinted also.
+   *   FreeType uses the HarfBuzz library to improve auto-hinting of OpenType
+   *   fonts.  If available, many glyphs not directly addressable by a font's
+   *   character map will be hinted also.
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
    */
 #define FT_CONFIG_OPTION_USE_HARFBUZZ
 
 
   /**************************************************************************
    *
+   * Brotli support.
+   *
+   *   FreeType uses the Brotli library to provide support for decompressing
+   *   WOFF2 streams.
+   *
+   *   Define this macro if you want to enable this 'feature'.
+   *
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
+   */
+#define FT_CONFIG_OPTION_USE_BROTLI
+
+
+  /**************************************************************************
+   *
    * Glyph Postscript Names handling
    *
-   *   By default, FreeType 2 is compiled with the `psnames' module.  This
-   *   module is in charge of converting a glyph name string into a
-   *   Unicode value, or return a Macintosh standard glyph name for the
-   *   use with the TrueType `post' table.
+   *   By default, FreeType 2 is compiled with the 'psnames' module.  This
+   *   module is in charge of converting a glyph name string into a Unicode
+   *   value, or return a Macintosh standard glyph name for the use with the
+   *   TrueType 'post' table.
    *
-   *   Undefine this macro if you do not want `psnames' compiled in your
+   *   Undefine this macro if you do not want 'psnames' compiled in your
    *   build of FreeType.  This has the following effects:
    *
-   *   - The TrueType driver will provide its own set of glyph names,
-   *     if you build it to support postscript names in the TrueType
-   *     `post' table, but will not synthesize a missing Unicode charmap.
+   *   - The TrueType driver will provide its own set of glyph names, if you
+   *     build it to support postscript names in the TrueType 'post' table,
+   *     but will not synthesize a missing Unicode charmap.
    *
-   *   - The Type 1 driver will not be able to synthesize a Unicode
-   *     charmap out of the glyphs found in the fonts.
+   *   - The Type~1 driver will not be able to synthesize a Unicode charmap
+   *     out of the glyphs found in the fonts.
    *
-   *   You would normally undefine this configuration macro when building
-   *   a version of FreeType that doesn't contain a Type 1 or CFF driver.
+   *   You would normally undefine this configuration macro when building a
+   *   version of FreeType that doesn't contain a Type~1 or CFF driver.
    */
 #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
@@ -322,16 +338,15 @@
    *
    * Postscript Names to Unicode Values support
    *
-   *   By default, FreeType 2 is built with the `PSNames' module compiled
-   *   in.  Among other things, the module is used to convert a glyph name
-   *   into a Unicode value.  This is especially useful in order to
-   *   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver
-   *   through a big table named the `Adobe Glyph List' (AGL).
+   *   By default, FreeType~2 is built with the 'psnames' module compiled in.
+   *   Among other things, the module is used to convert a glyph name into a
+   *   Unicode value.  This is especially useful in order to synthesize on
+   *   the fly a Unicode charmap from the CFF/Type~1 driver through a big
+   *   table named the 'Adobe Glyph List' (AGL).
    *
-   *   Undefine this macro if you do not want the Adobe Glyph List
-   *   compiled in your `PSNames' module.  The Type 1 driver will not be
-   *   able to synthesize a Unicode charmap out of the glyphs found in the
-   *   fonts.
+   *   Undefine this macro if you do not want the Adobe Glyph List compiled
+   *   in your 'psnames' module.  The Type~1 driver will not be able to
+   *   synthesize a Unicode charmap out of the glyphs found in the fonts.
    */
 #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
 
@@ -340,11 +355,11 @@
    *
    * Support for Mac fonts
    *
-   *   Define this macro if you want support for outline fonts in Mac
-   *   format (mac dfont, mac resource, macbinary containing a mac
-   *   resource) on non-Mac platforms.
+   *   Define this macro if you want support for outline fonts in Mac format
+   *   (mac dfont, mac resource, macbinary containing a mac resource) on
+   *   non-Mac platforms.
    *
-   *   Note that the `FOND' resource isn't checked.
+   *   Note that the 'FOND' resource isn't checked.
    */
 #define FT_CONFIG_OPTION_MAC_FONTS
 
@@ -358,13 +373,12 @@
    *   Resource forks which include fonts data are stored sometimes in
    *   locations which users or developers don't expected.  In some cases,
    *   resource forks start with some offset from the head of a file.  In
-   *   other cases, the actual resource fork is stored in file different
-   *   from what the user specifies.  If this option is activated,
-   *   FreeType tries to guess whether such offsets or different file
-   *   names must be used.
+   *   other cases, the actual resource fork is stored in file different from
+   *   what the user specifies.  If this option is activated, FreeType tries
+   *   to guess whether such offsets or different file names must be used.
    *
    *   Note that normal, direct access of resource forks is controlled via
-   *   the FT_CONFIG_OPTION_MAC_FONTS option.
+   *   the `FT_CONFIG_OPTION_MAC_FONTS` option.
    */
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
 #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
@@ -373,19 +387,19 @@
 
   /**************************************************************************
    *
-   * Allow the use of FT_Incremental_Interface to load typefaces that
-   * contain no glyph data, but supply it via a callback function.
-   * This is required by clients supporting document formats which
-   * supply font data incrementally as the document is parsed, such
-   * as the Ghostscript interpreter for the PostScript language.
+   * Allow the use of `FT_Incremental_Interface` to load typefaces that
+   * contain no glyph data, but supply it via a callback function.  This is
+   * required by clients supporting document formats which supply font data
+   * incrementally as the document is parsed, such as the Ghostscript
+   * interpreter for the PostScript language.
    */
 #define FT_CONFIG_OPTION_INCREMENTAL
 
 
   /**************************************************************************
    *
-   * The size in bytes of the render pool used by the scan-line converter
-   * to do all of its work.
+   * The size in bytes of the render pool used by the scan-line converter to
+   * do all of its work.
    */
 #define FT_RENDER_POOL_SIZE  16384L
 
@@ -395,7 +409,7 @@
    * FT_MAX_MODULES
    *
    *   The maximum number of modules that can be registered in a single
-   *   FreeType library object.  32 is the default.
+   *   FreeType library object.  32~is the default.
    */
 #define FT_MAX_MODULES  32
 
@@ -405,16 +419,15 @@
    * Debug level
    *
    *   FreeType can be compiled in debug or trace mode.  In debug mode,
-   *   errors are reported through the `ftdebug' component.  In trace
-   *   mode, additional messages are sent to the standard output during
-   *   execution.
+   *   errors are reported through the 'ftdebug' component.  In trace mode,
+   *   additional messages are sent to the standard output during execution.
    *
-   *   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.
-   *   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.
+   *   Define `FT_DEBUG_LEVEL_ERROR` to build the library in debug mode.
+   *   Define `FT_DEBUG_LEVEL_TRACE` to build it in trace mode.
    *
-   *   Don't define any of these macros to compile in `release' mode!
+   *   Don't define any of these macros to compile in 'release' mode!
    *
-   *   Do not #undef these macros here since the build system might define
+   *   Do not `#undef` these macros here since the build system might define
    *   them for certain configurations only.
    */
 #define FT_DEBUG_LEVEL_ERROR
@@ -423,40 +436,57 @@
 
   /**************************************************************************
    *
+   * Logging
+   *
+   *   Compiling FreeType in debug or trace mode makes FreeType write error
+   *   and trace log messages to `stderr`.  Enabling this macro
+   *   automatically forces the `FT_DEBUG_LEVEL_ERROR` and
+   *   `FT_DEBUG_LEVEL_TRACE` macros and allows FreeType to write error and
+   *   trace log messages to a file instead of `stderr`.  For writing logs
+   *   to a file, FreeType uses an the external `dlg` library (the source
+   *   code is in `src/dlg`).
+   *
+   *   This option needs a C99 compiler.
+   */
+#define FT_DEBUG_LOGGING
+
+
+  /**************************************************************************
+   *
    * Autofitter debugging
    *
-   *   If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to
+   *   If `FT_DEBUG_AUTOFIT` is defined, FreeType provides some means to
    *   control the autofitter behaviour for debugging purposes with global
-   *   boolean variables (consequently, you should *never* enable this
-   *   while compiling in `release' mode):
+   *   boolean variables (consequently, you should **never** enable this
+   *   while compiling in 'release' mode):
    *
-   *   {
-   *     _af_debug_disable_horz_hints
-   *     _af_debug_disable_vert_hints
-   *     _af_debug_disable_blue_hints
-   *   }
+   *   ```
+   *     af_debug_disable_horz_hints_
+   *     af_debug_disable_vert_hints_
+   *     af_debug_disable_blue_hints_
+   *   ```
    *
    *   Additionally, the following functions provide dumps of various
-   *   internal autofit structures to stdout (using `printf'):
+   *   internal autofit structures to stdout (using `printf`):
    *
-   *   {
+   *   ```
    *     af_glyph_hints_dump_points
    *     af_glyph_hints_dump_segments
    *     af_glyph_hints_dump_edges
    *     af_glyph_hints_get_num_segments
    *     af_glyph_hints_get_segment_offset
-   *   }
+   *   ```
    *
    *   As an argument, they use another global variable:
    *
-   *   {
-   *     _af_debug_hints
-   *   }
+   *   ```
+   *     af_debug_hints_
+   *   ```
    *
-   *   Please have a look at the `ftgrid' demo program to see how those
+   *   Please have a look at the `ftgrid` demo program to see how those
    *   variables and macros should be used.
    *
-   *   Do not #undef these macros here since the build system might define
+   *   Do not `#undef` these macros here since the build system might define
    *   them for certain configurations only.
    */
 #define FT_DEBUG_AUTOFIT
@@ -466,16 +496,16 @@
    *
    * Memory Debugging
    *
-   *   FreeType now comes with an integrated memory debugger that is
-   *   capable of detecting simple errors like memory leaks or double
-   *   deletes.  To compile it within your build of the library, you
-   *   should define FT_DEBUG_MEMORY here.
+   *   FreeType now comes with an integrated memory debugger that is capable
+   *   of detecting simple errors like memory leaks or double deletes.  To
+   *   compile it within your build of the library, you should define
+   *   `FT_DEBUG_MEMORY` here.
    *
-   *   Note that the memory debugger is only activated at runtime when
-   *   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also!
+   *   Note that the memory debugger is only activated at runtime when when
+   *   the _environment_ variable `FT2_DEBUG_MEMORY` is defined also!
    *
-   *   Do not #undef this macro here since the build system might define
-   *   it for certain configurations only.
+   *   Do not `#undef` this macro here since the build system might define it
+   *   for certain configurations only.
    */
 #define FT_DEBUG_MEMORY
 
@@ -484,19 +514,46 @@
    *
    * Module errors
    *
-   *   If this macro is set (which is _not_ the default), the higher byte
-   *   of an error code gives the module in which the error has occurred,
-   *   while the lower byte is the real error code.
+   *   If this macro is set (which is _not_ the default), the higher byte of
+   *   an error code gives the module in which the error has occurred, while
+   *   the lower byte is the real error code.
    *
-   *   Setting this macro makes sense for debugging purposes only, since
-   *   it would break source compatibility of certain programs that use
-   *   FreeType 2.
+   *   Setting this macro makes sense for debugging purposes only, since it
+   *   would break source compatibility of certain programs that use
+   *   FreeType~2.
    *
-   *   More details can be found in the files ftmoderr.h and fterrors.h.
+   *   More details can be found in the files `ftmoderr.h` and `fterrors.h`.
    */
 #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
 
 
+  /**************************************************************************
+   *
+   * OpenType SVG Glyph Support
+   *
+   *   Setting this macro enables support for OpenType SVG glyphs.  By
+   *   default, FreeType can only fetch SVG documents.  However, it can also
+   *   render them if external rendering hook functions are plugged in at
+   *   runtime.
+   *
+   *   More details on the hooks can be found in file `otsvg.h`.
+   */
+#define FT_CONFIG_OPTION_SVG
+
+
+  /**************************************************************************
+   *
+   * Error Strings
+   *
+   *   If this macro is set, `FT_Error_String` will return meaningful
+   *   descriptions.  This is not enabled by default to reduce the overall
+   *   size of FreeType.
+   *
+   *   More details can be found in the file `fterrors.h`.
+   */
+/* #define FT_CONFIG_OPTION_ERROR_STRINGS */
+
+
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
@@ -508,47 +565,47 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support
-   * embedded bitmaps in all formats using the SFNT module (namely
-   * TrueType & OpenType).
+   * Define `TT_CONFIG_OPTION_EMBEDDED_BITMAPS` if you want to support
+   * embedded bitmaps in all formats using the 'sfnt' module (namely
+   * TrueType~& OpenType).
    */
 #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_COLOR_LAYERS if you want to support coloured
-   * outlines (from the COLR/CPAL tables) in all formats using the SFNT
-   * module (namely TrueType & OpenType).
+   * Define `TT_CONFIG_OPTION_COLOR_LAYERS` if you want to support colored
+   * outlines (from the 'COLR'/'CPAL' tables) in all formats using the 'sfnt'
+   * module (namely TrueType~& OpenType).
    */
 #define TT_CONFIG_OPTION_COLOR_LAYERS
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to
-   * load and enumerate the glyph Postscript names in a TrueType or
-   * OpenType file.
+   * Define `TT_CONFIG_OPTION_POSTSCRIPT_NAMES` if you want to be able to
+   * load and enumerate Postscript names of glyphs in a TrueType or OpenType
+   * file.
    *
-   * Note that when you do not compile the `PSNames' module by undefining
-   * the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will
-   * contain additional code used to read the PS Names table from a font.
+   * Note that if you do not compile the 'psnames' module by undefining the
+   * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` macro, the 'sfnt' module will
+   * contain additional code to read the PostScript name table from a font.
    *
-   * (By default, the module uses `PSNames' to extract glyph names.)
+   * (By default, the module uses 'psnames' to extract glyph names.)
    */
 #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to
-   * access the internal name table in a SFNT-based format like TrueType
-   * or OpenType.  The name table contains various strings used to
-   * describe the font, like family name, copyright, version, etc.  It
-   * does not contain any glyph name though.
+   * Define `TT_CONFIG_OPTION_SFNT_NAMES` if your applications need to access
+   * the internal name table in a SFNT-based format like TrueType or
+   * OpenType.  The name table contains various strings used to describe the
+   * font, like family name, copyright, version, etc.  It does not contain
+   * any glyph name though.
    *
    * Accessing SFNT names is done through the functions declared in
-   * `ftsnames.h'.
+   * `ftsnames.h`.
    */
 #define TT_CONFIG_OPTION_SFNT_NAMES
 
@@ -581,54 +638,53 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile
-   * a bytecode interpreter in the TrueType driver.
+   * Define `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` if you want to compile a
+   * bytecode interpreter in the TrueType driver.
    *
    * By undefining this, you will only compile the code necessary to load
    * TrueType glyphs without hinting.
    *
-   *   Do not #undef this macro here, since the build system might
-   *   define it for certain configurations only.
+   * Do not `#undef` this macro here, since the build system might define it
+   * for certain configurations only.
    */
 #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile
+   * Define `TT_CONFIG_OPTION_SUBPIXEL_HINTING` if you want to compile
    * subpixel hinting support into the TrueType driver.  This modifies the
-   * TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is
+   * TrueType hinting mechanism when anything but `FT_RENDER_MODE_MONO` is
    * requested.
    *
    * In particular, it modifies the bytecode interpreter to interpret (or
-   * not) instructions in a certain way so that all TrueType fonts look
-   * like they do in a Windows ClearType (DirectWrite) environment.  See
-   * [1] for a technical overview on what this means.  See `ttinterp.h'
-   * for more details on the LEAN option.
+   * 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.
    *
    * 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.
+   *   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.
+   *   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.
    *
@@ -636,18 +692,18 @@
    *   Compile both, making both v38 and v40 available (the latter is the
    *   default).
    *
-   * By undefining these, you get rendering behavior like on Windows
-   * without ClearType, i.e., Windows XP without ClearType enabled and
-   * Win9x (interpreter version v35).  Or not, depending on how much
-   * hinting blood and testing tears the font designer put into a given
-   * font.  If you define one or both subpixel hinting options, you can
-   * switch between between v35 and the ones you define (using
-   * `FT_Property_Set').
+   * By undefining these, you get rendering behavior like on Windows without
+   * ClearType, i.e., Windows XP without ClearType enabled and Win9x
+   * (interpreter version v35).  Or not, depending on how much hinting blood
+   * and testing tears the font designer put into a given font.  If you
+   * define one or both subpixel hinting options, you can switch between
+   * between v35 and the ones you define (using `FT_Property_Set`).
    *
-   * This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be
+   * This option requires `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` to be
    * defined.
    *
-   * [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
+   * [1]
+   * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
    */
 /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1     */
 /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2     */
@@ -656,16 +712,16 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the
+   * Define `TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED` to compile the
    * TrueType glyph loader to use Apple's definition of how to handle
    * component offsets in composite glyphs.
    *
-   * Apple and MS disagree on the default behavior of component offsets
-   * in composites.  Apple says that they should be scaled by the scaling
-   * factors in the transformation matrix (roughly, it's more complex)
-   * while MS says they should not.  OpenType defines two bits in the
-   * composite flags array which can be used to disambiguate, but old
-   * fonts will not have them.
+   * Apple and MS disagree on the default behavior of component offsets in
+   * composites.  Apple says that they should be scaled by the scaling
+   * factors in the transformation matrix (roughly, it's more complex) while
+   * MS says they should not.  OpenType defines two bits in the composite
+   * flags array which can be used to disambiguate, but old fonts will not
+   * have them.
    *
    *   https://www.microsoft.com/typography/otspec/glyf.htm
    *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html
@@ -675,34 +731,52 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include
-   * support for Apple's distortable font technology (fvar, gvar, cvar,
-   * and avar tables).  This has many similarities to Type 1 Multiple
-   * Masters support.
+   * Define `TT_CONFIG_OPTION_GX_VAR_SUPPORT` if you want to include support
+   * for Apple's distortable font technology ('fvar', 'gvar', 'cvar', and
+   * 'avar' tables).  Tagged 'Font Variations', this is now part of OpenType
+   * also.  This has many similarities to Type~1 Multiple Masters support.
    */
 #define TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_BDF if you want to include support for
-   * an embedded `BDF ' table within SFNT-based bitmap formats.
+   * Define `TT_CONFIG_OPTION_NO_BORING_EXPANSION` if you want to exclude
+   * support for 'boring' OpenType specification expansions.
+   *
+   *   https://github.com/harfbuzz/boring-expansion-spec
+   *
+   * Right now, the following features are covered:
+   *
+   *   - 'avar' version 2.0
+   *
+   * Most likely, this is a temporary configuration option to be removed in
+   * the near future, since it is assumed that eventually those features are
+   * added to the OpenType standard.
+   */
+/* #define TT_CONFIG_OPTION_NO_BORING_EXPANSION */
+
+
+  /**************************************************************************
+   *
+   * Define `TT_CONFIG_OPTION_BDF` if you want to include support for an
+   * embedded 'BDF~' table within SFNT-based bitmap formats.
    */
 #define TT_CONFIG_OPTION_BDF
 
 
   /**************************************************************************
    *
-   * Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum
+   * Option `TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES` controls the maximum
    * number of bytecode instructions executed for a single run of the
-   * bytecode interpreter, needed to prevent infinite loops.  You don't
-   * want to change this except for very special situations (e.g., making
-   * a library fuzzer spend less time to handle broken fonts).
+   * bytecode interpreter, needed to prevent infinite loops.  You don't want
+   * to change this except for very special situations (e.g., making a
+   * library fuzzer spend less time to handle broken fonts).
    *
    * It is not expected that this value is ever modified by a configuring
-   * script; instead, it gets surrounded with #ifndef ... #endif so that
-   * the value can be set as a preprocessor option on the compiler's
-   * command line.
+   * script; instead, it gets surrounded with `#ifndef ... #endif` so that
+   * the value can be set as a preprocessor option on the compiler's command
+   * line.
    */
 #ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
 #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES  1000000L
@@ -720,16 +794,15 @@
 
   /**************************************************************************
    *
-   * T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and
-   * arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is
-   * required.
+   * `T1_MAX_DICT_DEPTH` is the maximum depth of nest dictionaries and arrays
+   * in the Type~1 stream (see `t1load.c`).  A minimum of~4 is required.
    */
 #define T1_MAX_DICT_DEPTH  5
 
 
   /**************************************************************************
    *
-   * T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine
+   * `T1_MAX_SUBRS_CALLS` details the maximum number of nested sub-routine
    * calls during glyph loading.
    */
 #define T1_MAX_SUBRS_CALLS  16
@@ -737,19 +810,20 @@
 
   /**************************************************************************
    *
-   * T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A
-   * minimum of 16 is required.
+   * `T1_MAX_CHARSTRING_OPERANDS` is the charstring stack's capacity.  A
+   * minimum of~16 is required.
    *
-   * The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256.
+   * The Chinese font 'MingTiEG-Medium' (covering the CNS 11643 character
+   * set) needs 256.
    */
 #define T1_MAX_CHARSTRINGS_OPERANDS  256
 
 
   /**************************************************************************
    *
-   * Define this configuration macro if you want to prevent the
-   * compilation of `t1afm', which is in charge of reading Type 1 AFM
-   * files into an existing face.  Note that if set, the T1 driver will be
+   * Define this configuration macro if you want to prevent the compilation
+   * of the 't1afm' module, which is in charge of reading Type~1 AFM files
+   * into an existing face.  Note that if set, the Type~1 driver will be
    * unable to produce kerning distances.
    */
 #undef T1_CONFIG_OPTION_NO_AFM
@@ -757,19 +831,18 @@
 
   /**************************************************************************
    *
-   * Define this configuration macro if you want to prevent the
-   * compilation of the Multiple Masters font support in the Type 1
-   * driver.
+   * Define this configuration macro if you want to prevent the compilation
+   * of the Multiple Masters font support in the Type~1 driver.
    */
 #undef T1_CONFIG_OPTION_NO_MM_SUPPORT
 
 
   /**************************************************************************
    *
-   * T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1
+   * `T1_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe Type~1
    * engine gets compiled into FreeType.  If defined, it is possible to
-   * switch between the two engines using the `hinting-engine' property of
-   * the type1 driver module.
+   * switch between the two engines using the `hinting-engine` property of
+   * the 'type1' driver module.
    */
 #define T1_CONFIG_OPTION_OLD_ENGINE
 
@@ -785,14 +858,13 @@
 
   /**************************************************************************
    *
-   * Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is
+   * Using `CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4}` it is
    * possible to set up the default values of the four control points that
-   * define the stem darkening behaviour of the (new) CFF engine.  For
-   * more details please read the documentation of the
-   * `darkening-parameters' property (file `ftdriver.h'), which allows the
-   * control at run-time.
+   * define the stem darkening behaviour of the (new) CFF engine.  For more
+   * details please read the documentation of the `darkening-parameters`
+   * property (file `ftdriver.h`), which allows the control at run-time.
    *
-   * Do *not* undefine these macros!
+   * Do **not** undefine these macros!
    */
 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1   500
 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1   400
@@ -809,10 +881,10 @@
 
   /**************************************************************************
    *
-   * CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF
-   * engine gets compiled into FreeType.  If defined, it is possible to
-   * switch between the two engines using the `hinting-engine' property of
-   * the cff driver module.
+   * `CFF_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe CFF engine
+   * gets compiled into FreeType.  If defined, it is possible to switch
+   * between the two engines using the `hinting-engine` property of the 'cff'
+   * driver module.
    */
 #define CFF_CONFIG_OPTION_OLD_ENGINE
 
@@ -828,18 +900,18 @@
 
   /**************************************************************************
    *
-   * There are many PCF fonts just called `Fixed' which look completely
-   * different, and which have nothing to do with each other.  When
-   * selecting `Fixed' in KDE or Gnome one gets results that appear rather
-   * random, the style changes often if one changes the size and one
-   * cannot select some fonts at all.  This option makes the PCF module
-   * prepend the foundry name (plus a space) to the family name.
+   * There are many PCF fonts just called 'Fixed' which look completely
+   * different, and which have nothing to do with each other.  When selecting
+   * 'Fixed' in KDE or Gnome one gets results that appear rather random, the
+   * style changes often if one changes the size and one cannot select some
+   * fonts at all.  This option makes the 'pcf' module prepend the foundry
+   * name (plus a space) to the family name.
    *
-   * We also check whether we have `wide' characters; all put together, we
-   * get family names like `Sony Fixed' or `Misc Fixed Wide'.
+   * We also check whether we have 'wide' characters; all put together, we
+   * get family names like 'Sony Fixed' or 'Misc Fixed Wide'.
    *
    * If this option is activated, it can be controlled with the
-   * `no-long-family-names' property of the pcf driver module.
+   * `no-long-family-names` property of the 'pcf' driver module.
    */
 #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
 
@@ -855,51 +927,40 @@
 
   /**************************************************************************
    *
-   * Compile autofit module with CJK (Chinese, Japanese, Korean) script
+   * Compile 'autofit' module with CJK (Chinese, Japanese, Korean) script
    * support.
    */
 #define AF_CONFIG_OPTION_CJK
 
+
   /**************************************************************************
    *
-   * Compile autofit module with fallback Indic script support, covering
-   * some scripts that the `latin' submodule of the autofit module doesn't
-   * (yet) handle.
+   * Compile 'autofit' module with fallback Indic script support, covering
+   * some scripts that the 'latin' submodule of the 'autofit' module doesn't
+   * (yet) handle.  Currently, this needs option `AF_CONFIG_OPTION_CJK`.
    */
+#ifdef AF_CONFIG_OPTION_CJK
 #define AF_CONFIG_OPTION_INDIC
+#endif
+
 
   /**************************************************************************
    *
-   * Compile autofit module with warp hinting.  The idea of the warping
-   * code is to slightly scale and shift a glyph within a single dimension
-   * so that as much of its segments are aligned (more or less) on the
-   * grid.  To find out the optimal scaling and shifting value, various
-   * parameter combinations are tried and scored.
-   *
-   * This experimental option is active only if the rendering mode is
-   * FT_RENDER_MODE_LIGHT; you can switch warping on and off with the
-   * `warping' property of the auto-hinter (see file `ftdriver.h' for more
-   * information; by default it is switched off).
-   */
-#define AF_CONFIG_OPTION_USE_WARPER
-
-  /**************************************************************************
-   *
-   * Use TrueType-like size metrics for `light' auto-hinting.
+   * Use TrueType-like size metrics for 'light' auto-hinting.
    *
    * It is strongly recommended to avoid this option, which exists only to
-   * help some legacy applications retain its appearance and behaviour
-   * with respect to auto-hinted TrueType fonts.
+   * help some legacy applications retain its appearance and behaviour with
+   * respect to auto-hinted TrueType fonts.
    *
    * The very reason this option exists at all are GNU/Linux distributions
    * like Fedora that did not un-patch the following change (which was
    * present in FreeType between versions 2.4.6 and 2.7.1, inclusive).
    *
-   * {
+   * ```
    *   2011-07-16  Steven Chu  <steven.f.chu@gmail.com>
    *
    *     [truetype] Fix metrics on size request for scalable fonts.
-   * }
+   * ```
    *
    * This problematic commit is now reverted (more or less).
    */
@@ -909,15 +970,15 @@
 
 
   /*
-   * This macro is obsolete.  Support has been removed in FreeType
-   * version 2.5.
+   * This macro is obsolete.  Support has been removed in FreeType version
+   * 2.5.
    */
 /* #define FT_CONFIG_OPTION_OLD_INTERNALS */
 
 
   /*
-   * This macro is defined if native TrueType hinting is requested by the
-   * definitions above.
+   * The next three 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
@@ -935,8 +996,23 @@
 
 
   /*
+   * The TT_SUPPORT_COLRV1 macro is defined to indicate to clients that this
+   * version of FreeType has support for 'COLR' v1 API.  This definition is
+   * useful to FreeType clients that want to build in support for 'COLR' v1
+   * depending on a tip-of-tree checkout before it is officially released in
+   * FreeType, and while the feature cannot yet be tested against using
+   * version macros.  Don't change this macro.  This may be removed once the
+   * feature is in a FreeType release version and version macros can be used
+   * to test for availability.
+   */
+#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
+#define  TT_SUPPORT_COLRV1
+#endif
+
+
+  /*
    * Check CFF darkening parameters.  The checks are the same as in function
-   * `cff_property_set' in file `cffdrivr.c'.
+   * `cff_property_set` in file `cffdrivr.c`.
    */
 #if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0   || \
     CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0   || \
@@ -962,8 +1038,8 @@
 #error "Invalid CFF darkening parameters!"
 #endif
 
-FT_END_HEADER
 
+FT_END_HEADER
 
 #endif /* FTOPTION_H_ */
 
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..b8d05d1
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,12 @@
+# Static site folder
+reference/
+
+# HTML and Markdown files
+*.html
+*.md
+
+# MkDocs Config file
+mkdocs.yml
+
+# Python virtualenv
+env/
diff --git a/docs/CHANGES b/docs/CHANGES
index a6d088a..3c6a877 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,4 +1,597 @@
-CHANGES BETWEEN 2.9 and 2.9.1
+CHANGES BETWEEN 2.12.1 and 2.13.0 (2023-Feb-09)
+
+  I. IMPORTANT CHANGES
+
+  - The demo program `ftinspect` has  been completely updated and much
+    enhanced.  It now  combines the functionality of  almost all other
+    graphical FreeType  demo programs into a  single application based
+    on the Qt framework.  This was Charlie Jiang's GSoC 2022 project.
+
+  - The 'COLR' v1 API is now considered as stable.
+
+      https://learn.microsoft.com/en-us/typography/opentype/spec/colr
+
+
+  III. MISCELLANEOUS
+
+  - For  OpenType  Variable Fonts,  `avar`  table  format 2.0  is  now
+    supported.  The code was contributed by Behdad Esfahbod.
+
+    Note that this is an extension supported on recent Apple platforms
+    and by HarfBuzz, but not yet in the OpenType standard!  See
+
+      https://github.com/harfbuzz/boring-expansion-spec/blob/main/avar2.md
+
+    for the specification.  To deactivate it, define the configuration
+    macro 'TT_CONFIG_OPTION_NO_BORING_EXPANSION'.
+
+  - A new API  `FT_GlyphSlot_Slant` to slant a glyph by  a given angle
+    has been added.   Note that this function is  part of `ftsynth.h`,
+    which is still considered to be in alpha stage.
+
+  - TrueType interpreter version 38  (also known as 'Infinality') that
+    was first introduced about 10 years  ago in FreeType 2.4.11 is now
+    deprecated and slated to be removed in the next version.  TrueType
+    interpreter version 40 has been FreeType's default version for six
+    years now and provides an excellent alternative.  This is the last
+    FreeType     version     with    TT_INTERPRETER_VERSION_38     and
+    TT_INTERPRETER_VERSION_40 treated differently.
+
+  - The  only  referenced  but never  documented  configuration  macro
+    `FT_CONFIG_OPTION_NO_GLYPH_NAMES` has been removed.
+
+  - The `ftbench` demo  program got a new command line  option `-e` to
+    set a charmap index.
+
+  - Specifying  a point  size is  now optional  for the  demo programs
+    `ftgrid`, `ftmulti`,  `ftstring`, and  `ftview`.  If not  given, a
+    default size is used.
+
+  - For  `ftgrid`,  `ftstring`, and  `ftview`,  option  `-e` now  also
+    accepts a numeric value to set a charmap index.
+
+  - In  `ftstring`, it  is  now  possible to  set  the displayed  text
+    interactively by pressing the 'Enter' key.
+
+  - `ftmulti` can now handle up to 16 design axes.
+
+  - To  avoid  reserved identifiers  that  are  globally defined,  the
+    auto-hinter  debugging   macros  (which  are  only   available  if
+    `FT_DEBUG_AUTOFIT` is defined)
+
+    ```
+    _af_debug_disable_horz_hints
+    _af_debug_disable_vert_hints
+    _af_debug_disable_blue_hints
+    _af_debug_hints
+    ```
+
+    have been renamed to
+
+    ```
+    af_debug_disable_horz_hints_
+    af_debug_disable_vert_hints_
+    af_debug_disable_blue_hints_
+    af_debug_hints_
+    ```
+
+
+======================================================================
+
+CHANGES BETWEEN 2.12.0 and 2.12.1 (2022-May-01)
+
+  I. IMPORTANT BUG FIXES
+
+  - Loading CFF fonts sometimes made FreeType crash (bug introduced in
+    version 2.12.0)
+
+  - Loading  a fully  hinted  TrueType glyph  a  second time  (without
+    caching) sometimes yielded different rendering results if TrueType
+    hinting was active (bug introduced in version 2.12.0).
+
+  - The generation of the pkg-config file `freetype2.pc` was broken if
+    the build was done with cmake (bug introduced in version 2.12.0).
+
+
+  II. MISCELLANEOUS
+
+  - New option `--with-librsvg` for  the `configure` script for better
+    FreeType demo support.
+
+  - The  meson  build  no  longer enforces  both  static  and  dynamic
+    versions of the library by default.
+
+  - The internal  zlib library was  updated to version  1.2.12.  Note,
+    however, that  FreeType is *not* affected  by CVE-2018-25032 since
+    it only does decompression.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.11.1 and 2.12.0 (2022-Mar-30)
+
+  I. IMPORTANT CHANGES
+
+  - FreeType  now   handles  OT-SVG  fonts,  to   be  controlled  with
+    `FT_CONFIG_OPTION_SVG`  configuration macro.   By default,  it can
+    only load the 'SVG ' table of an OpenType font.  However, by using
+    the `svg-hooks` property of the new 'ot-svg' module it is possible
+    to register an  external SVG rendering engine.   The FreeType demo
+    programs  have been  set  up  to use  'librsvg'  as the  rendering
+    library.
+
+    This work was Moazin Khatti's GSoC 2019 project.
+
+
+  II. MISCELLANEOUS
+
+  - The handling of fonts with an 'sbix' table has been improved.
+
+    - Corrected bitmap offsets.
+
+    - A  new tag  `FT_PARAM_TAG_IGNORE_SBIX` for  `FT_Open_Face` makes
+      FreeType ignore an 'sbix' table in a font, allowing applications
+      to access the font's outline glyphs.
+
+    - `FT_FACE_FLAG_SBIX`  and   `FT_FACE_FLAG_SBIX_OVERLAY`  together
+      with their  corresponding preprocessor macros  `FT_HAS_SBIX` and
+      `FT_HAS_SBIX_OVERLAY` enable applications to treat 'sbix' tables
+      as described in the OpenType specification.
+
+  - The internal 'zlib'  code has been updated to be  in sync with the
+    current 'zlib' version (1.2.11).
+
+  - The  previously internal  load  flag  `FT_LOAD_SBITS_ONLY` is  now
+    public.
+
+  - Some  minor improvements  of the  building systems,  in particular
+    handling of the 'zlib' library (internal vs. external).
+
+  - Support for non-desktop Universal Windows Platform.
+
+  - Various other minor bug and documentation fixes.
+
+  - The `ftdump` demo  program shows more information  for Type1 fonts
+    if option `-n` is given.
+
+  - `ftgrid` can now display embedded bitmap strikes.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.11.0 and 2.11.1 (2021-Dec-01)
+
+  I. IMPORTANT CHANGES
+
+    - Some  fields  in  the  `CID_FaceDictRec`, `CID_FaceInfoRec`, and
+      `FT_Data` structures  have been changed  from signed to unsigned
+      type,  which  better reflects  the actual usage.  It is also  an
+      additional means to protect against malformed input.
+
+
+  II. MISCELLANEOUS
+
+    - Cmake support  has been  further improved.   To do  that various
+      backward-incompatible  changes were  necessary; please  see file
+      `CMakeLists.txt` for more details.
+
+    - Since version  2.11.0, a  C99 compiler  is necessary  to compile
+      FreeType.
+
+    - The experimental  'COLR' v1 API  has been updated to  the latest
+      OpenType standard 1.9.
+
+    - The `apinames` tool got a new  option `-wV` to output an OpenVMS
+      Linker Option File.
+
+    - VMS support was updated.
+
+    - MS Visual Studio support was added to build the demo programs.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.10.4 and 2.11.0 (2021-Jul-18)
+
+  I. IMPORTANT CHANGES
+
+  - A  new rendering  module has  been  added to  create 8-bit  Signed
+    Distance Field (SDF)  bitmaps for both outline  and bitmap glyphs.
+    The new  rendering mode is called  `FT_RENDER_MODE_SDF`, the pixel
+    mode is  `FT_PIXEL_MODE_GRAY8`, and the corresponding  raster flag
+    is `FT_RASTER_FLAG_SDF`.
+
+    This work was Anuj Verma's GSoC 2020 project.
+
+  - A new, experimental API is  now available for surfacing properties
+    of 'COLR' v1  color fonts (as the name says,  this is an extension
+    to  the  'COLR' table  for  outline  color  fonts using  the  SFNT
+    container  format).   'COLR'  v1  fonts are  a  recently  proposed
+    addition to OFF and OpenType; specification work currently happens
+    in
+
+      https://github.com/googlefonts/colr-gradients-spec/
+
+    'COLR'  v1  is  expected  to   be  merged  to  OpenType;  the  ISO
+    standardisation process  for adding 'COLR'  v1 as an  amendment to
+    OFF is underway.
+
+    Functions similar  to the  already existing  'COLR' API  have been
+    added to access the corresponding data.
+
+      FT_Get_Color_Glyph_Paint
+        Retrieve the root paint for a given glyph ID.
+
+      FT_Get_Paint_Layers
+        Access the layers of a `PaintColrLayers` table.
+
+      FT_Get_Colorline_Stops
+        Retrieve the  'color stops' on a  color line.  As an  input, a
+        color stop iterator gets used, which in turn is retrieved from
+        a paint.
+
+      FT_Get_Paint
+        Dereference  an  `FT_OpaquePaint`   object  and  retrieve  the
+        corresponding `FT_COLR_Paint`  object, which  contains details
+        on how to draw the respective 'COLR' v1 `Paint` table.
+
+
+  II. MISCELLANEOUS
+
+  - FreeType has moved its infrastructure to
+
+      https://gitlab.freedesktop.org/freetype
+
+    A  side  effect  is  that  the git  repositories  are  now  called
+    `freetype.git` and  `freetype-demos.git`, which by  default expand
+    to the directories  `freetype` and `freetype-demos`, respectively.
+    The documentation has been updated accordingly.
+
+    FreeType's Savannah  repositories will stay; they  are now mirrors
+    of the 'freedesktop.org' repositories.
+
+  - A  new  function  `FT_Get_Transform`  returns  the  values set  by
+    `FT_Set_Transform`.
+
+  - A  new configuration  macro `FT_DEBUG_LOGGING`  is available.   It
+    provides extended debugging capabilities for FreeType, for example
+    showing a time stamp or displaying the component a tracing message
+    comes from.  See file `docs/DEBUG` for more information.
+
+    This work was Priyesh Kumar's GSoC 2020 project.
+
+  - The legacy Type 1 and CFF  engines are further demoted due to lack
+    of CFF2 charstring support.  You now need to use `FT_Property_Set`
+    to  enable  them  besides  the  `T1_CONFIG_OPTION_OLD_ENGINE`  and
+    `CFF_CONFIG_OPTION_OLD_ENGINE` options, respectively.
+
+  - The experimental 'warp' mode (AF_CONFIG_OPTION_USE_WARPER) for the
+    auto-hinter has been removed.
+
+  - The smooth rasterizer performance has been improved by >10%.  Note
+    that  due to  necessary code  changes there  might be  very subtle
+    differences  in  rendering.  They  are  not  visible by  the  eye,
+    however.
+
+  - PCF bitmap fonts compressed with LZW (these are usually files with
+    the extension `.pcf.Z`) are now handled correctly.
+
+  - Improved  Meson  build  files,  including  support  to  build  the
+    FreeType demo programs.
+
+  - A new demo program `ftsdf` is available to display Signed Distance
+    Fields of glyphs.
+
+  - The `ftlint` demo program has been  extended to do more testing of
+    its input.  In particular, it  can display horizontal and vertical
+    acutances  for quality  assessment,  together  with computing  MD5
+    checksums of rendered glyphs.
+
+    [The acutance measures  how sharply the pixel  coverage changes at
+     glyph edges.  For monochrome bitmaps,  it is always 2.0 in either
+     X or  Y direction.  For  anti-aliased bitmaps, it depends  on the
+     hinting and the shape of a glyph and might approach or even reach
+     value 2.0  for glyphs like 'I',  'L', '+', '-', or  '=', while it
+     might be lower for glyphs like 'O', 'S', or 'W'.]
+
+  - The `ttdebug`  demo program didn't show  changed point coordinates
+    (bug introduced in version 2.10.3).
+
+  - It is now possible to adjust the axis increment for variable fonts
+    in the `ftmulti` demo program.
+
+  - It is now possible to change  the hinting engine in the `ftstring`
+    demo program.
+
+  - The graphical demo programs work  better now in native color depth
+    on win32 and x11.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.10.3 and 2.10.4 (2020-Oct-20)
+
+  I. IMPORTANT BUG FIXES
+
+  - A heap buffer overflow has been found  in the handling of embedded
+    PNG bitmaps, introduced in FreeType version 2.6.
+
+      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15999
+
+    If you  use option  FT_CONFIG_OPTION_USE_PNG  you  should  upgrade
+    immediately.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.10.2 and 2.10.3 (2020-Oct-10)
+
+  I. IMPORTANT CHANGES
+
+  - New flag `FT_OUTLINE_OVERLAP'.  If set, make the smooth rasterizer
+    do  4x4 oversampling  to  mitigate artifacts  in pixels  partially
+    covered  by  overlapping  contours.    Note  that  this  at  least
+    quadruples the rendering time.
+
+    If  a  glyph  in  a  TrueType font  has  the  `OVERLAP_SIMPLE'  or
+    `OVERLAP_COMPOUND'  bit set,  FreeType automatically  selects this
+    rendering mode.
+
+
+  II. MISCELLANEOUS
+
+  - Using the  arcane method of  including FreeType header  files with
+    macros like  `FT_FREETYPE_H' is no longer  mandatory (but retained
+    as an optional feature for backward compatibility).
+
+  - Support for  building the library  with Meson.  Building  the demo
+    programs with Meson will follow in a forthcoming release.
+
+  - Minor improvements to the B/W rasterizer.
+
+  - Auto-hinter support for Medefaidrin script.
+
+  - Fix various  memory leaks (mainly  for CFF) and other  issues that
+    might cause crashes in rare circumstances.
+
+  - Jam support has been removed.
+
+  - In  `ftview', custom  LCD  filter values  are  now normalized  and
+    balanced.  Unorthodox filters are still available through the `-L'
+    command line option.
+
+  - The GUI demo programs can now be resized.
+
+  - Demo programs that accept command  line option `-k' can now handle
+    function keys, too.  The  corresponding character codes start with
+    0xF1.  As  an example, the  POSIX shell syntax (accepted  by bash,
+    ksh, and zsh)
+
+      -k $'\xF3q'
+
+    emulates the pressing of function key `F3' followed by key `q'.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.10.1 and 2.10.2 (2020-May-09)
+
+  I. IMPORTANT CHANGES
+
+  - Support  of  WOFF2  fonts.   This  code  contribution  was  Nikhil
+    Ramakrishnan's GSoC 2019 project.
+
+
+  II. MISCELLANEOUS
+
+  - Function  `FT_Get_Var_Axis_Flags' returned random data for  Type 1
+    MM fonts.
+
+  - Type 1 fonts with non-integer metrics are now supported by the new
+    (CFF) engine introduced in FreeType 2.9.
+
+  - Drop  support  for Python 2 in Freetype's API reference  generator
+    `docwriter'  (Python >= 3.5 is required for targets  `make refdoc'
+    and `make refdoc-venv').
+
+  - Auto-hinter support for Hanifi Rohingya.
+
+  - Document the `FT2_KEEP_ALIVE' debugging environment variable.
+
+  - The Visual C++ (and Visual C)  project files for Windows builds no
+    longer generate libraries that contain the FreeType version in its
+    filenames.   Instead,  a  resource  file gets  used  to  make  the
+    libraries contain the corresponding information.
+
+  - The next release will remove Jam build support.
+
+  - The  `ftbench'  demo  program  has  a new  test  for  testing  the
+    `FT_Glyph_Stroke' functionality.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.10.0 and 2.10.1 (2019-Jul-01)
+
+  I. IMPORTANT BUG FIXES
+
+  - The bytecode hinting of OpenType variation fonts was flawed, since
+    the data in the `CVAR' table wasn't correctly applied.
+
+
+  II. MISCELLANEOUS
+
+  - Auto-hinter support for Mongolian.
+
+  - For distribution,  `.tar.bz2' packages are replaced with `.tar.xz'
+    bundles.
+
+  - The handling of  the default character in PCF fonts as  introduced
+    in version 2.10.0 was partially broken, causing premature abortion
+    of charmap iteration for many fonts.
+
+  - If  `FT_Set_Named_Instance' was  called  with  the same  arguments
+    twice in a row, the function  returned an incorrect error code the
+    second time.
+
+  - Direct   rendering   using  FT_RASTER_FLAG_DIRECT   crashed   (bug
+    introduced in version 2.10.0).
+
+  - Increased  precision  while  computing  OpenType  font   variation
+    instances.
+
+  - The  flattening  algorithm of  cubic  Bezier  curves was  slightly
+    changed to make  it faster.  This can cause  very subtle rendering
+    changes, which aren't noticeable by the eye, however.
+
+  - The  auto-hinter  now  disables hinting  if there  are blue  zones
+    defined for a `style' (i.e., a certain combination of a script and
+    its related typographic features) but the font doesn't contain any
+    characters needed to set up at least one blue zone.
+
+  - The `ftmulti' demo program now  supports multiple hidden axes with
+    the same name tag.
+
+  - `ftview', `ftstring', and `ftgrid' got  a `-k' command line option
+    to emulate a sequence of keystrokes at start-up.
+
+  - `ftview', `ftstring', and `ftgrid' now support screen dumping to a
+    PNG file.
+
+  - The bytecode debugger, `ttdebug',  now supports variation TrueType
+    fonts; a variation font instance can be selected with the new `-d'
+    command line option.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.9.1 and 2.10.0 (2019-Mar-15)
+
+  I. IMPORTANT CHANGES
+
+    - A bunch  of new functions has  been added to access  and process
+      COLR/CPAL data of OpenType fonts with color-layered glyphs.
+
+        FT_Palette_Data_Get
+          Retrieve color palette data.
+        FT_Palette_Select
+          Select and activate a color palette for color-layered
+          glyphs.
+        FT_Palette_Set_Foreground_Color
+          Set text foreground color for palette index 0xFFFF.
+
+        FT_Get_Color_Glyph_Layer
+          Get color layers for a given glyph (using an interator
+          object).
+
+        FT_Bitmap_Blend
+          Blend one bitmap onto another with a given color.
+
+    - An   experimental  feature   is   the  new   behaviour  of   the
+      `FT_LOAD_COLOR' load  flag for color-layered  glyphs: Internally
+      it  sets a  flag so  that  if `FT_Render_Glyph'  is called  with
+      `FT_RENDER_MODE_NORMAL'      (or       `FT_Load_Glyph'      with
+      `FT_LOAD_RENDER'), a default blending  of the color glyph layers
+      will happen automatically for convenience.
+
+    - As  a   GSoC  2018   project,  Nikhil   Ramakrishnan  completely
+      overhauled and modernized the API reference.
+
+
+  II. MISCELLANEOUS
+
+    - The  logic for  computing  the global  ascender, descender,  and
+      height  of  OpenType  fonts   has  been  slightly  adjusted  for
+      consistency.
+
+      . If the `useTypoMetrics' flag (i.e., bit 7 in the `fsSelection'
+        field) in the  `OS/2' table is set, use the  `sTypo' fields in
+        `OS/2' unconditionally.
+      . Otherwise use  the metrics data from the `hhea'  table (if not
+        zero).
+      . Otherwise use the `sTypo' fields from the `OS/2' table (if not
+        zero).
+      . Otherwise use the `usWin' data from the `OS/2' table as a last
+        resort.
+
+      Variable fonts will apply the `MVAR' deltas to whichever metrics
+      were picked.
+
+    - `TT_Set_MM_Blend' could  fail if  call repeatedly with  the same
+      arguments.
+
+    - The precision  of handling  deltas in  Variation Fonts  has been
+      increased.  The  problem did only show  up with multidimensional
+      designspaces.
+
+    - New function `FT_Library_SetLcdGeometry' to  set up the geometry
+      of LCD subpixels.
+
+    - FreeType now uses the `defaultChar' property of PCF fonts to set
+      the  glyph for  the undefined  character  at glyph  index 0  (as
+      FreeType already does for all other supported font formats).  As
+      a consequence,  the order of  glyphs of  a PCF font  if accessed
+      with  FreeType  can  be   different  now  compared  to  previous
+      versions.
+
+      This change doesn't affect PCF font access with cmaps.
+
+    - `FT_Select_Charmap' has  been changed  to allow  parameter value
+      `FT_ENCODING_NONE', which is valid for BDF, PCF, and Windows FNT
+      formats to  access built-in cmaps  that don't have  a predefined
+      `FT_Encoding' value.
+
+    - A previously  reserved field in the  `FT_GlyphSlotRec' structure
+      now holds the glyph index.
+
+    - On Win32 platforms,  the use of `_DLL' to build  the library has
+      been replaced with `DLL_EXPORT' and `DLL_IMPORT'.
+
+    - The usual round  of fuzzer bug fixes to  better reject malformed
+      fonts.
+
+    - `FT_Outline_New_Internal'  and  `FT_Outline_Done_Internal'  have
+      been removed.  These two functions were public by oversight only
+      and were never documented.
+
+    - A new  function `FT_Error_String' returns descriptions  of error
+      codes if  configuration macro  FT_CONFIG_OPTION_ERROR_STRINGS is
+      defined.
+
+    - `FT_Set_MM_WeightVector'  and  `FT_Get_MM_WeightVector' are  new
+      functions limited to Adobe MultiMaster fonts to directly set and
+      get the weight vector.
+
+    - Support for Position Independent Code as needed by  systems that
+      prohibit  automatic  address  fixups,  such  as BREW,  has  been
+      removed.  [Compilation with modern compilers that use flags like
+      `-fPIC' or `-fPIE' is not affected.]
+
+    - The  `ftdump' demo  program has  new  options `-c'  and `-C'  to
+      display charmaps  in compact and detailed  format, respectively.
+      Option `-V' has been removed.
+
+    - The `ftview', `ftstring',  and `ftgrid' demo programs  use a new
+      command line option `-d' to  specify the program window's width,
+      height, and color depth.
+
+    - The `ftview' demo program now  displays red boxes for zero-width
+      glyphs.
+
+    - `ftglyph'   has   limited   support  to   display   fonts   with
+      color-layered glyphs.  This will be improved later on.
+
+    - `ftgrid' can now display bitmap fonts also.
+
+    - The `ttdebug'  demo program has  a new  option `-f' to  select a
+      member of a TrueType collection (TTC).
+
+    - Other various improvements to the demo programs.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.9 and 2.9.1 (2019-May-01)
 
   I. IMPORTANT BUG FIXES
 
@@ -8,7 +601,7 @@
     - CVE-2018-6942: Older  FreeType versions  can crash  with certain
       malformed variation fonts.
 
-        http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-6942
+        https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-6942
 
 
   II. MISCELLANEOUS
@@ -28,7 +621,7 @@
       use the `pkg-config' interface.
 
       The `configure'  script no longer installs  `freetype-config' by
-      default.  For  backwards compatibility,  a new  configure option
+      default.  For  backward  compatibility,  a new  configure option
       `--enable-freetype-config'   is  provided   that  reverts   this
       decision.
 
@@ -46,7 +639,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.8.1 and 2.9
+CHANGES BETWEEN 2.8.1 and 2.9 (2018-Jan-08)
 
   I. IMPORTANT BUG FIXES
 
@@ -136,7 +729,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.8 and 2.8.1
+CHANGES BETWEEN 2.8 and 2.8.1 (2017-Sep-16)
 
   I. IMPORTANT BUG FIXES
 
@@ -219,7 +812,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.7.1 and 2.8
+CHANGES BETWEEN 2.7.1 and 2.8 (2017-May-13)
 
   I. IMPORTANT CHANGES
 
@@ -232,7 +825,7 @@
       following properties can be  handled: stem darkening, LCD filter
       weights, and the random seed for the `random' CFF operator.
 
-    - The PCF change to show more `colourful' family names (introduced
+    - The PCF change to show more `colorful'  family names (introduced
       in version 2.7.1) was too radical; it can now be configured with
       PCF_CONFIG_OPTION_LONG_FAMILY_NAMES   at   compile   time.    If
       activated, it can  be switched off at run time  with the new pcf
@@ -340,7 +933,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.7 and 2.7.1
+CHANGES BETWEEN 2.7 and 2.7.1 (2016-Dec-30)
 
   I. IMPORTANT CHANGES
 
@@ -383,7 +976,7 @@
       and the number of CVT entries.  Please report if you encounter a
       font where the selected values are not adequate.
 
-    - PCF family names are made more `colourful'; they now include the
+    - PCF family names are made more `colorful';  they now include the
       foundry  and information  whether they contain  wide characters.
       For example,  you no longer get `Fixed' but  rather `Sony Fixed'
       or `Misc Fixed Wide'.
@@ -417,7 +1010,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.6.5 and 2.7
+CHANGES BETWEEN 2.6.5 and 2.7 (2016-Sep-08)
 
   I. IMPORTANT CHANGES
 
@@ -481,7 +1074,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.6.4 and 2.6.5
+CHANGES BETWEEN 2.6.4 and 2.6.5 (2016-Jul-12)
 
   I. IMPORTANT BUG FIXES
 
@@ -501,7 +1094,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.6.3 and 2.6.4
+CHANGES BETWEEN 2.6.3 and 2.6.4 (2016-Jul-05)
 
   I. IMPORTANT CHANGES
 
@@ -567,7 +1160,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.6.2 and 2.6.3
+CHANGES BETWEEN 2.6.2 and 2.6.3 (2016-Feb-08)
 
   I. IMPORTANT CHANGES
 
@@ -616,7 +1209,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.6.1 and 2.6.2
+CHANGES BETWEEN 2.6.1 and 2.6.2 (2015-Nov-28)
 
   I. IMPORTANT CHANGES
 
@@ -667,8 +1260,8 @@
     - The `ftstring' demo program now supports subpixel rendering; use
       key `l' to cycle through the LCD modes.
 
-    - The `ftstring'  demo program now supports  colour rendering; use
-      the `space' key to cycle through various colour combinations.
+    - The `ftstring'  demo program now supports  color rendering;  use
+      the `space' key to cycle through various color combinations.
 
     - The graphical demo programs now use a default gamma value of 1.8
       (instead of 1.2).
@@ -676,7 +1269,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.6 and 2.6.1
+CHANGES BETWEEN 2.6 and 2.6.1 (2015-Oct-04)
 
   I. IMPORTANT BUG FIXES
 
@@ -757,7 +1350,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.5.5 and 2.6
+CHANGES BETWEEN 2.5.5 and 2.6 (2015-Jun-07)
 
   I. IMPORTANT CHANGES
 
@@ -863,7 +1456,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.5.4 and 2.5.5
+CHANGES BETWEEN 2.5.4 and 2.5.5 (2014-Dec-30)
 
   I. IMPORTANT BUG FIXES
 
@@ -873,7 +1466,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.5.3 and 2.5.4
+CHANGES BETWEEN 2.5.3 and 2.5.4 (2014-Dec-06)
 
   I. IMPORTANT BUG FIXES
 
@@ -944,7 +1537,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.5.2 and 2.5.3
+CHANGES BETWEEN 2.5.2 and 2.5.3 (2014-Mar-06)
 
   I. IMPORTANT BUG FIXES
 
@@ -1012,7 +1605,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.5.1 and 2.5.2
+CHANGES BETWEEN 2.5.1 and 2.5.2 (2013-Dec-08)
 
   I. IMPORTANT BUG FIXES
 
@@ -1036,7 +1629,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.5 and 2.5.1
+CHANGES BETWEEN 2.5 and 2.5.1 (2013-Nov-25)
 
   I. IMPORTANT BUG FIXES
 
@@ -1140,7 +1733,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.12 and 2.5
+CHANGES BETWEEN 2.4.12 and 2.5 (2013-Jun-19)
 
   I. IMPORTANT BUG FIXES
 
@@ -1220,7 +1813,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.11 and 2.4.12
+CHANGES BETWEEN 2.4.11 and 2.4.12 (2013-May-08)
 
     - We have another CFF parsing and hinting engine!  Written by Dave
       Arnold <darnold@adobe.com>,  this work  has been  contributed by
@@ -1308,7 +1901,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.10 and 2.4.11
+CHANGES BETWEEN 2.4.10 and 2.4.11 (2012-Dec-20)
 
   I. IMPORTANT BUG FIXES
 
@@ -1325,7 +1918,7 @@
 
       Originally, it was a separate patch available from
 
-        http://www.infinality.net/blog/
+        https://web.archive.org/web/20150710073951/http://www.infinality.net:80/blog/
 
       and which has been integrated.
 
@@ -1368,7 +1961,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.9 and 2.4.10
+CHANGES BETWEEN 2.4.9 and 2.4.10 (2012-Jun-15)
 
   I. IMPORTANT BUG FIXES
 
@@ -1393,7 +1986,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.8 and 2.4.9
+CHANGES BETWEEN 2.4.8 and 2.4.9 (2012-Mar-08)
 
   I. IMPORTANT BUG FIXES
 
@@ -1421,7 +2014,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.7 and 2.4.8
+CHANGES BETWEEN 2.4.7 and 2.4.8 (2011-Nov-14)
 
   I. IMPORTANT BUG FIXES
 
@@ -1437,7 +2030,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.6 and 2.4.7
+CHANGES BETWEEN 2.4.6 and 2.4.7 (2011-Oct-18)
 
   I. IMPORTANT BUG FIXES
 
@@ -1454,7 +2047,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.5 and 2.4.6
+CHANGES BETWEEN 2.4.5 and 2.4.6 (2011-Jul-29)
 
   I. IMPORTANT BUG FIXES
 
@@ -1493,7 +2086,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.4 and 2.4.5
+CHANGES BETWEEN 2.4.4 and 2.4.5 (2011-Jun-25)
 
   I. IMPORTANT BUG FIXES
 
@@ -1540,7 +2133,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.3 and 2.4.4
+CHANGES BETWEEN 2.4.3 and 2.4.4 (2010-Nov-28)
 
   I. IMPORTANT BUG FIXES
 
@@ -1565,7 +2158,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.2 and 2.4.3
+CHANGES BETWEEN 2.4.2 and 2.4.3 (2010-Oct-03)
 
   I. IMPORTANT BUG FIXES
 
@@ -1584,7 +2177,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.1 and 2.4.2
+CHANGES BETWEEN 2.4.1 and 2.4.2 (2010-Aug-06)
 
   I. IMPORTANT BUG FIXES
 
@@ -1608,7 +2201,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.4.0 and 2.4.1
+CHANGES BETWEEN 2.4.0 and 2.4.1 (2010-Jul-18)
 
   I. IMPORTANT CHANGES
 
@@ -1618,7 +2211,7 @@
 
 ======================================================================
 
-CHANGES BETWEEN 2.3.12 and 2.4.0
+CHANGES BETWEEN 2.3.12 and 2.4.0 (2010-Jul-12)
 
   I. IMPORTANT CHANGES
 
@@ -4047,7 +4640,7 @@
     untested for now.
 
   - Updated `docs/docmaker.py', a draft  API reference is available at
-    http://www.freetype.org/ft2api.html.
+    https://web.archive.org/web/20001215173400/http://www.freetype.org:80/ft2api.html.
 
   - Changed `type1' to use `psaux'.
 
@@ -5017,7 +5610,7 @@
 
 ------------------------------------------------------------------------
 
-Copyright 2000-2018 by
+Copyright (C) 2000-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file  is  part  of the  FreeType  project, and may  only be  used,
diff --git a/docs/CUSTOMIZE b/docs/CUSTOMIZE
index 916be32..80527db 100644
--- a/docs/CUSTOMIZE
+++ b/docs/CUSTOMIZE
@@ -139,7 +139,7 @@
 
 ----------------------------------------------------------------------
 
-Copyright 2003-2018 by
+Copyright (C) 2003-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/docs/DEBUG b/docs/DEBUG
index 751eaf0..4a5ac3a 100644
--- a/docs/DEBUG
+++ b/docs/DEBUG
@@ -11,20 +11,20 @@
 
   FT_DEBUG_LEVEL_ERROR
 
-    #define this macro if you want to compile the FT_ERROR macro calls
-    to print error  messages during program execution.   This will not
-    stop  the  program.  Very  useful  to  spot invalid  fonts  during
+    #define this  macro if  you want to  compile the  `FT_ERROR' macro
+    calls to print error messages during program execution.  This does
+    not stop  the program.  Very  useful to spot invalid  fonts during
     development and to code workarounds for them.
 
   FT_DEBUG_LEVEL_TRACE
 
-    #define this macro if you want to compile both macros FT_ERROR and
-    FT_TRACE.  This  also includes the variants  FT_TRACE0, FT_TRACE1,
-    FT_TRACE2, ..., FT_TRACE7.
+    #define this macro  if you want to compile  both macros `FT_ERROR'
+    and  `FT_TRACE'.  This  also  includes  the variants  `FT_TRACE0',
+    `FT_TRACE1', `FT_TRACE2', ..., `FT_TRACE7'.
 
     The  trace macros  are used  to  send debugging  messages when  an
     appropriate  `debug level'  is configured  at runtime  through the
-    FT2_DEBUG environment variable (more on this later).
+    `FT2_DEBUG' environment variable (more on this later).
 
   FT_DEBUG_MEMORY
 
@@ -32,18 +32,33 @@
     small  but  effective debugging  memory  manager  that tracks  all
     allocations and frees that are performed within the font engine.
 
-    When  the  FT2_DEBUG_MEMORY  environment variable  is  defined  at
-    runtime, a  call to FT_Done_FreeType will  dump memory statistics,
-    including  the  list  of  leaked memory  blocks  with  the  source
-    locations where  these were allocated.   It is always a  very good
-    idea to define this in  development builds.  This works with _any_
-    program linked to FreeType, but requires a big deal of memory (the
-    debugging memory  manager never  frees the blocks  to the  heap in
-    order to detect double frees).
+    When  the `FT2_DEBUG_MEMORY'  environment variable  is defined  at
+    runtime,  a call  to `FT_Done_FreeType'  dumps memory  statistics,
+    including the list of leaked memory blocks and optionally with the
+    source locations where these were  allocated.  It is always a very
+    good idea to  define this in development builds.   This works with
+    _any_  program linked  to FreeType,  but  requires a  big deal  of
+    memory (the debugging memory manager never frees the blocks to the
+    heap in order to detect double frees).
 
-    When  FT2_DEBUG_MEMORY isn't  defined  at  runtime, the  debugging
+    When `FT2_DEBUG_MEMORY'  isn't defined  at runtime,  the debugging
     memory manager is ignored, and performance is unaffected.
 
+  FT_DEBUG_LOGGING
+
+    #define this macro for enhanced logging support; it automatically
+    sets `FT_DEBUG_LEVEL_TRACE' and `FT_DEBUG_LEVEL_ERROR'.
+
+    If  defined,  `FT_TRACE'  and  `FT_ERROR'  can  send  tracing  and
+    debugging messages to a file.  The location of the log file has to
+    be set  with the  `FT_LOGGING_FILE' environment variable  (more on
+    this later).
+
+    The main enhancements are the  possibility of logging the time and
+    the name  of the `FT_COMPONENT'  macro together with  the affected
+    `FT_TRACE' or `FT_ERROR' calls.  See below how to activate this in
+    the `FT2_DEBUG' environment variable.
+
 
 II. Debugging macros
 --------------------
@@ -55,10 +70,10 @@
   1. FT_ERROR(( ... ))
 
     This macro is used to send debug messages that indicate relatively
-    serious errors  (like broken  font files), but  will not  stop the
+    serious  errors  (like broken  font  files)  without stopping  the
     execution of the running program.   Its code is compiled only when
-    either FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined in
-    `ftoption.h'.
+    either   `FT_DEBUG_LEVEL_ERROR'   or  `FT_DEBUG_LEVEL_TRACE'   are
+    defined in `ftoption.h'.
 
     Note that you have to use a printf-like signature, but with double
     parentheses, like in
@@ -69,54 +84,53 @@
   2. FT_ASSERT( condition )
 
     This macro is used to check  strong assertions at runtime.  If its
-    condition isn't TRUE, the program will abort with a panic message.
-    Its  code   is  compiled   when  either   FT_DEBUG_LEVEL_ERROR  or
-    FT_DEBUG_LEVEL_TRACE   are  defined.    You   don't  need   double
-    parentheses here.  For example
+    condition isn't  TRUE, the  program aborts  with a  panic message.
+    Its  code  is  compiled   when  either  `FT_DEBUG_LEVEL_ERROR'  or
+    `FT_DEBUG_LEVEL_TRACE'  are   defined.   You  don't   need  double
+    parentheses here.  Example:
 
       FT_ASSERT( ptr != NULL );
 
 
   3. FT_TRACE( level, (message...) )
 
-    The  FT_TRACE  macro is  used  to  send general-purpose  debugging
+    The  `FT_TRACE' macro  is used  to send  general-purpose debugging
     messages during program execution.   This macro uses an *implicit*
-    macro  named  FT_COMPONENT  used  to  name  the  current  FreeType
+    macro  named  `FT_COMPONENT',  which names  the  current  FreeType
     component being run.
 
-    The developer  should always  define FT_COMPONENT  as appropriate,
+    The developer should always  define `FT_COMPONENT' as appropriate,
     for example as in
 
       #undef  FT_COMPONENT
-      #define FT_COMPONENT  trace_io
+      #define FT_COMPONENT  io
 
-    The  value  of the  FT_COMPONENT  macro  is an  enumeration  named
-    `trace_XXXX' where `XXXX' is one of the component names defined in
-    the internal  file `internal/fttrace.h'.   If you  modify FreeType
-    source and insert new `trace_XXXX'  macro, you must register it in
-    `fttrace.h'. If  you insert or  remove many trace macros,  you can
-    check   the    undefined   or   the   unused    trace   macro   by
-    `src/tools/chktrcmp.py'.
+    The  value of  the `FT_COMPONENT'  macro is  one of  the component
+    names defined  in the internal file  `internal/fttrace.h'.  If you
+    modify the  FreeType source code  and insert a  new `FT_COMPONENT'
+    macro,  you must  register it  in `fttrace.h'.   If you  insert or
+    remove many  trace macros,  you can test  for undefined  or unused
+    trace macros with the script `src/tools/chktrcmp.py'.
 
-    Each such component is assigned a `debug level', ranging from 0 to
-    7,  through   the  use  of  the   FT2_DEBUG  environment  variable
-    (described below) when a program linked with FreeType starts.
+    Each  such component  is assigned  a `debug  level', ranging  from
+    value  0 to  7, through  the  use of  the `FT2_DEBUG'  environment
+    variable  (described below)  when a  program linked  with FreeType
+    starts.
 
-    When FT_TRACE is  called, its level is compared to  the one of the
+    When `FT_TRACE' is called, its level is compared to the one of the
     corresponding component.  Messages with trace levels *higher* than
-    the corresponding component level are filtered and never printed.
+    the  corresponding  component level  are  filtered  out and  never
+    printed.  This means  that trace messages with level  0 are always
+    printed, those  with level 2  are only printed when  the component
+    level is *at least* 2, etc.
 
-    This means  that trace messages  with level 0 are  always printed,
-    those with  level 2 are only  printed when the component  level is
-    *at least* 2.
-
-    The  second parameter  to  FT_TRACE must  contain parentheses  and
-    correspond to a printf-like call, as in
+    The second  parameter to  `FT_TRACE' must contain  parentheses and
+    corresponds to a printf-like call, as in
 
       FT_TRACE( 2, ( "your %s is not %s\n", "foo", "bar" ) )
 
-    The   shortcut  macros   FT_TRACE0,  FT_TRACE1,   FT_TRACE2,  ...,
-    FT_TRACE7 can  be used with  constant level indices, and  are much
+    The  shortcut macros  `FT_TRACE0', `FT_TRACE1',  `FT_TRACE2', ...,
+    `FT_TRACE7' can be used with  constant level indices, and are much
     cleaner to use, as in
 
       FT_TRACE2(( "your %s is not %s\n", "foo", "bar" ));
@@ -132,66 +146,158 @@
   FT2_DEBUG
 
     This  variable   is  only  used   when  FreeType  is   built  with
-    FT_DEBUG_LEVEL_TRACE  defined.  It  contains a  list of  component
+    `FT_DEBUG_LEVEL_TRACE' defined.   It contains a list  of component
     level definitions, following this format:
 
       component1:level1 component2:level2 component3:level3 ...
 
     where `componentX' is the name  of a tracing component, as defined
-    in `fttrace.h', but without the  `trace_' prefix.  `levelX' is the
-    corresponding level to use at runtime.
+    in `fttrace.h'.  `levelX' is  the corresponding level  to  use  at
+    runtime.
 
-    `any'  is a  special component  name that  will be  interpreted as
-    `any/all components'.  For example, the following definitions
+    `any' is a special component  name that is interpreted as `any/all
+    components'.  For example, the following definitions
 
       set FT2_DEBUG=any:2 memory:5 io:4        (on Windows)
       export FT2_DEBUG="any:2 memory:5 io:4"   (on Linux with bash)
 
     both stipulate that all components should have level 2, except for
-    the memory and  io components which will be set  to trace levels 5
+    the memory and io components, which  are set to the trace levels 5
     and 4, respectively.
 
+    If `FT_DEBUG_LOGGING' is defined, two more options are available.
+
+    * -v: Print also  the name of FreeType's component  from which the
+          current log is produced, together with the tracing level.
+
+    * -t: Print also the time.
+
+    Here are some examples how the output might look like.
+
+      FT2_DEBUG="any:7 memory:5 -vt"
+
+        => [20:32:02:44969 ttload:2]    table directory loaded
+
+      FT2_DEBUG="any:7 memory:5 -t"
+
+        => [20:32:02:44969]    table directory loaded
+
+      FT2_DEBUG="any:7 memory:5 -v"
+
+        => [ttload:2]    table directory loaded
+
+
+  FT_LOGGING_FILE
+
+    This  variable  is  only  used  if  FreeType  is  built  with  the
+    `FT_DEBUG_LOGGING'  macro defined.   It contains  the path  to the
+    file where the user wants to put  his log file.  If it is not set,
+    FreeType uses stderr.
+
+    Examples:
+
+      On UNIX-like systems with bash:
+      export FT_LOGGING_FILE="/tmp/freetype2.log"
+
+      On Windows:
+      set FT_LOGGING_FILE=C:\Users\AppData\Local\Temp\freetype2.log
+
 
   FT2_DEBUG_MEMORY
 
     This environment variable,  when defined, tells FreeType  to use a
-    debugging memory manager that will  track leaking memory blocks as
-    well as other common errors like double frees.  It is also capable
-    of  reporting _where_  the  leaking blocks  were allocated,  which
+    debugging memory manager that tracks leaking memory blocks as well
+    as other common  errors like double frees.  It is  also capable of
+    reporting  _where_  the  leaking   blocks  were  allocated,  which
     considerably  saves  time  when  debugging new  additions  to  the
     library.
 
     This  code  is only  compiled  when  FreeType  is built  with  the
-    FT_DEBUG_MEMORY macro #defined in  `ftoption.h' though, it will be
+    `FT_DEBUG_MEMORY'  macro #defined  in `ftoption.h'  though, it  is
     ignored in other builds.
 
 
   FT2_ALLOC_TOTAL_MAX
 
-    This variable is  ignored if FT2_DEBUG_MEMORY is  not defined.  It
+    This variable is ignored if `FT2_DEBUG_MEMORY' is not defined.  It
     allows  you  to  specify  a  maximum  heap  size  for  all  memory
     allocations performed  by FreeType.  This  is very useful  to test
     the robustness  of the  font engine  and programs  that use  it in
     tight memory conditions.
 
-    If it is undefined, or if its value is not strictly positive, then
-    no allocation bounds are checked at runtime.
+    If it is  undefined, or if its value is  not strictly positive, no
+    allocation bounds are checked at runtime.
 
 
   FT2_ALLOC_COUNT_MAX
 
-    This variable is  ignored if FT2_DEBUG_MEMORY is  not defined.  It
+    This variable is ignored if `FT2_DEBUG_MEMORY' is not defined.  It
     allows  you to  specify  a maximum  number  of memory  allocations
     performed    by    FreeType    before    returning    the    error
-    FT_Err_Out_Of_Memory.  This  is useful  for debugging  and testing
+    `FT_Err_Out_Of_Memory'.  This is useful  for debugging and testing
     the engine's robustness.
 
-    If it is undefined, or if its value is not strictly positive, then
-    no allocation bounds are checked at runtime.
+    If it is  undefined, or if its value is  not strictly positive, no
+    allocation bounds are checked at runtime.
+
+
+  FT2_KEEP_ALIVE
+
+    This  variable is  ignored if  `FT2_DEBUG_MEMORY' is  not defined.
+    `Keep alive' means that freed  blocks aren't released to the heap.
+    This is  useful to detect  double-frees or weird  heap corruption,
+    reporting the source code location  of the original allocation and
+    deallocation  in case  of a  problem.   It uses  large amounts  of
+    memory, however.
+
+    If it  is undefined,  or if  its value  is not  strictly positive,
+    freed blocks are released at runtime.
+
+
+IV. Additional Capabilities with `FT_DEBUG_LOGGING'
+---------------------------------------------------
+
+If `FT_DEBUG_LOGGING' is  defined, four APIs are  available to provide
+additional debugging support.  Use
+
+  #include <freetype/ftlogging.h>
+
+to access them.
+
+  FT_Trace_Set_Level( const char*  level )
+
+    By  default,  FreeType   uses  the  tracing  levels   set  in  the
+    `FT2_DEBUG' environment  variable.  Use this function  to override
+    the value with `level'.  Use value `NULL' to disable tracing.
+
+  FT_Trace_Set_Default_Level():
+
+    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 ):
+
+    Use `handler' as a custom handler for formatting tracing and error
+    messages.  The  `ft_custom_log_handler' typedef has  the following
+    prototype.
+
+      void
+      (*ft_custom_log_handler)( const char*  ft_component,
+                                const char*  fmt,
+                                va_list      args );
+
+   `ft_component' is the current component like `ttload', `fmt' is the
+   first argument  of `FT_TRACE' or  `FT_ERROR', and `args'  holds the
+   remaining arguments.
+
+  FT_Set_Default_Log_Handler():
+
+    Reset the log handler to the default version.
+
 
 ------------------------------------------------------------------------
 
-Copyright 2002-2018 by
+Copyright (C) 2002-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part  of the  FreeType  project, and  may  only be  used,
diff --git a/docs/DOCGUIDE b/docs/DOCGUIDE
new file mode 100644
index 0000000..b46b7bd
--- /dev/null
+++ b/docs/DOCGUIDE
@@ -0,0 +1,298 @@
+Introduction
+------------
+
+Documentation is an extremely important part of any project, and it
+helps a lot if it uses consistent syntax and layout.
+
+The documentation for the FreeType library is maintained in header
+files in the `include/` directory in the form of code comments.  These
+comments are extracted and organized by 'docwriter' (previously
+'docmaker').  The generated docs can be viewed in the
+`docs/reference/site/` directory after running `make refdoc`.
+
+Documentation comments follow a specific structure and format as
+described below.
+
+
+Documentation Structure
+-----------------------
+
+The documentation is divided into multiple chapters, which contain
+sections relevant to it.  The chapter details and sections contained
+in them are listed in `include/freetype/ftchapters.h`.  Any unlisted
+section is added to the 'Miscellaneous' chapter.
+
+Sections may contain sub-sections which consist of properties,
+enumerations, and other data types.
+
+
+Comment Blocks
+--------------
+
+Documentation blocks follow a specific format:
+
+    /***************************** (should end on column 77)
+     *
+     *                             (1 asterisk, 1 space, then content)
+     *
+     */                            (end of block)
+
+To make 'docwriter' recognize a comment block, there must be at least
+two asterisks in the first line.  As a consequence, you should change
+the second asterisk to something else if you want to prevent a comment
+block being handled by 'docwriter' (for example, change `/****/` to
+`/*#**/`).
+
+
+Markup Tags
+-----------
+
+Markup tags are used to indicate what comes next.  The syntax for a
+tag is:
+
+    @foo:
+
+An `@`, followed by the tag, and then `:`.
+
+
+Reserved Tags
+-------------
+
+There are some keywords that have a special meaning to docwriter.
+As a convention, all keywords are written in lowercase.
+
+* `chapter`: Defines a chapter.  Usually the title with underscores.
+* `sections`: List of sections in the chapter, in order.
+* `section`: Defines the start or continuation of a section.
+* `title`: Title for a chapter or section.  May contain spaces.
+* `abstract`: The abstract for a section, visible in the Table of
+              Contents (TOC).
+* `description`: Detailed description of a tag (except chapters),
+                 shown as synopsis.
+* `values`: A list of 'values' for the tag.  These values are used for
+            cross-referencing.
+
+
+Other Tags
+----------
+
+Except the ones given above, any other tags will be added as a part of
+a subsection.  All tags are lowercase by convention.
+
+
+Public Header Definitions
+-------------------------
+
+The public headers for FreeType have their names defined in
+`include/freetype/config/ftheader.h`.  Any new public header file must
+be defined in this file, in the following format:
+
+    #define FT_NEWNAME_H  <freetype/newname.h>
+
+Where `newname` is the name of the header file.
+
+This macro is combined with the file location of a sub-section and
+printed with the object.
+
+
+Note on code blocks captured after comments
+-------------------------------------------
+
+All non-documentation lines after a documentation comment block are
+captured to be displayed as the code for the sub-section.  To stop
+collection, a line with `/* */` should be added.
+
+
+General Formatting Conventions
+------------------------------
+
+* Use two spaces after a full stop ending a sentence.
+* Use appropriate uppercasing in titles.  Refer
+
+  https://english.stackexchange.com/a/34
+
+  for more information.
+* Do not add trailing parentheses when citing a C function.
+
+
+Markdown Usage
+--------------
+
+All tags, except the ones that define the name and title for a block
+support markdown in them.  Docwriter uses a markdown parser that
+follows rules given in John Gruber's markdown guide:
+
+  https://daringfireball.net/projects/markdown/syntax
+
+with a few exceptions and extensions, detailed below.  This may also
+be referred to as the **FreeType Flavored Markdown**.
+
+
+Headers
+-------
+
+Markdown headers should not be used directly, because these are added
+based on section titles, sub-section names, and tags.  However, if a
+header needs to be added, note the following correspondence to HTML tags:
+
+* Section title on top of the page is `H1`.
+* Sub-section titles are `H2`.
+* Parts of sub-sections are `H4`.
+* Any header added will be visible in the Table of Contents (TOC) of
+  the page.
+
+
+Emphasis
+--------
+
+* Use `_underscores_` for italics.
+* Use `**double asterisks**` for bold.
+
+Although the other notations (double underscore for bold, single
+asterisk for italics) are supported, it is recommended to use the
+above for consistency.
+
+Note that there may be cases where having two asterisks or underscores
+in a line may lead to text being picked up as italics or bold.
+Although unintentional, this is correct markdown behavior.
+
+For inline code, wrap the sequence with backticks (see below).  This
+renders symbols correctly without modifications.  If a symbol is
+absolutely required outside of an inline code block or code sequence,
+escape it with a backslash (like `\*` or `\_`).
+
+
+Lists
+-----
+
+Unordered lists can be created with asterisks:
+
+    * Unordered list items can use asterisks.
+    * Another list item.
+
+Ordered lists start with numbers:
+
+    1. This is an ordered list item.
+    2. Brackets after numbers won't work.
+
+To continue a list over multiple paragraphs, indent them with at least
+four spaces.  For example:
+
+    1.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+        Aliquam hendrerit mi posuere lectus.  Vestibulum enim wisi,
+        viverra nec, fringilla in, laoreet vitae, risus.
+
+        Donec sit amet nisl.  Aliquam semper ipsum sit amet velit.
+        Suspendisse id sem consectetuer libero luctus adipiscing.
+
+    2.  This is the second list item.
+
+    This paragraph is not a part of the list.
+
+More information on lists in markdown is available at
+
+  https://daringfireball.net/projects/markdown/syntax#list
+
+
+Cross-references
+----------------
+
+Other sub-sections can be linked with the `@` symbol:
+
+    @description:
+      While FreeType's CFF driver doesn't expose API functions by
+      itself, it is possible to control its behaviour with
+      @FT_Property_Set and @FT_Property_Get.
+
+If a field in the `values` table of another sub-section is linked, the
+link leads to its parent sub-section.
+
+
+Links and Images
+----------------
+
+All URLs are converted to links in the HTML documentation.
+
+Markdown syntax for links and images are fully supported.
+
+
+Inline Code
+-----------
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``):
+
+    Use the `printf()` function.
+
+Cross-references, markdown, and html styling do not work in inline code
+sequences.
+
+
+Code and Syntax Highlighting
+----------------------------
+
+Blocks of code are fenced by lines with three back-ticks `` ``` ``
+followed by the language name, if any (used for syntax highlighting),
+as demonstrated in the following example.
+
+    ```c
+      x = y + z;
+      if ( zookoo == 2 )
+      {
+        foobar();
+      }
+    ```
+
+Note that the indentation of the opening line and the closing line
+must be exactly the same.  The code sequence itself should have a
+larger indentation than the surrounding back-ticks.
+
+Like inline code, markdown and html styling is *not* supported inside
+code blocks.
+
+
+Tables
+------
+
+Tables are used to list values, input, and other fields.  The FreeType
+Flavored Markdown adopts a simple approach to tables with two columns,
+or field definition tables.
+
+Field definition names may contain alphanumeric, underscore, and the
+`.` characters.  This is followed by `::`.  The following lines are
+the second column of the table.  A field definition ends with the
+start of another field definition, or a markup tag.
+
+    @Input:
+      pathname ::
+        A path to the font file.
+
+      face_index ::
+        See @FT_Open_Face for a detailed description of this
+        parameter.
+
+
+Non-breaking Space
+------------------
+
+A tilde can be used to create a non-breaking space.  The example
+
+    The encoding value~0 is reserved.
+
+is converted to
+
+    The encoding value&nbsp;0 is reserved.
+
+
+----------------------------------------------------------------------
+
+Copyright (C) 2018-2023 by
+Nikhil Ramakrishnan, 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.
+
+
+--- end of DOCGUIDE ---
diff --git a/docs/INSTALL b/docs/INSTALL
index 71d4a05..49ab112 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -4,65 +4,89 @@
 overview of the documentation available:
 
 
-I. Normal installation and upgrades
-===================================
+I. Prerequisites and dependencies
+=================================
 
-  1. Unix Systems (including Mac OS X, Cygwin, and MSys on Windows)
+  FreeType is a low level C library  that only depends on the standard
+  C library with very few platform-dependent optimizations utilized at
+  build time.  Any  C99-compliant compiler  should be able  to compile
+  FreeType.  System libraries,  such as  zlib,  Gzip,  bzip2,  Brotli,
+  and libpng,  might  be  used  to handle  compressed fonts  or decode
+  embedded PNG glyphs.
 
-    Please read `INSTALL.UNIX' to install or upgrade FreeType  2 on  a
+  FreeType  auto-configuration scripts  should be  able to detect  the
+  prerequisites if the necessary headers are available  at the default
+  locations.  Otherwise,  modify  `include/freetype/config/ftoption.h`
+  to control how the FreeType library gets built.  Normally, you don't
+  need to change anything.
+
+  Applications have very limited control over FreeType's behaviour  at
+  run-time;  look at the documentation of function `FT_Property_Set`.
+
+
+II. Normal installation and upgrades
+====================================
+
+  1. Unix and Unix-like systems
+
+    This also includes MacOS, Cygwin, MinGW + MSYS, Mingw-w64 + MSYS2,
+    and possibly other, similar environments.
+
+    Please read `INSTALL.UNIX` to install or upgrade FreeType  2 on  a
     Unix system.   Note  that  you  *need*  GNU  Make   for  automatic
     compilation,  since other make tools won't work (this includes BSD
     Make).
 
     GNU Make VERSION 3.81 OR NEWER IS NEEDED!
 
-    [For `cmake' see below.]
+
+  2. Other systems using GNU Make
+
+    On some  non-Unix platforms, it  is possible to build  the library
+    using only  the GNU Make utility.   Note that *NO OTHER  MAKE TOOL
+    WILL  WORK*[1]!   This  methods   supports  several  compilers  on
+    Windows, OS/2, and BeOS,  including MinGW* (without MSYS*), Visual
+    C++, Borland C++, and more.
+
+    Instructions are provided in the file `INSTALL.GNU`.
 
 
-  2. On VMS with the `mms' build tool
+  3. Other build tools and platforms.
 
-    See `INSTALL.VMS' for installation instructions on this platform.
+    A few other tools  can be used  to build FreeType.  You  can  find
+    the  corresponding instruction files  in  the FreeType root folder
+    or the builds/ sub-folder.
 
-
-  3. Other systems using GNU Make
-
-    On non-Unix platforms,  it is possible to build  the library using
-    GNU Make  utility.  Note that  *NO OTHER MAKE TOOL  WILL WORK*[1]!
-    This  methods supports  several  compilers on  Windows, OS/2,  and
-    BeOS, including MinGW, Visual C++, Borland C++, and more.
-
-    Instructions are provided in the file `INSTALL.GNU'.
+      CMake   :: see `CMakeLists.txt` for more information
+      Meson   :: see `meson.build` for more information
+      MSBuild :: see `builds/windows/vc2010/freetype.vcxproj`
+      MMS     :: see `vms_make.com` and `docs/INSTALL.VMS`
 
 
   4. With an IDE Project File (e.g., for Visual Studio or CodeWarrior)
 
-    We provide a  small number of `project files'  for various IDEs to
+    We provide a  small number of 'project files'  for various IDEs to
     automatically build  the library as  well.  Note that  these files
-    are  not supported  and only  sporadically maintained  by FreeType
-    developers, so don't expect them to work in each release.
+    are not actively supported by FreeType developers,  they can break
+    or become obsolete.
 
-    To find them, have a  look at the content of the `builds/<system>'
+    To find them, have a  look at the content of the `builds/<system>`
     directory, where <system> stands for your OS or environment.
 
 
-  5. Using cmake
-
-    See the top-level `CMakeLists.txt' file for more information.
-
-
-  6. From you own IDE, or own Makefiles
+  5. From you own IDE, or own Makefiles
 
     If  you  want  to  create   your  own  project  file,  follow  the
-    instructions   given  in  the   `INSTALL.ANY'  document   of  this
+    instructions   given  in  the   `INSTALL.ANY`  document   of  this
     directory.
 
 
-II. Custom builds of the library
-================================
+III. Custom builds of the library
+=================================
 
   Customizing the compilation  of FreeType is easy, and  allows you to
   select only the components of  the font engine that you really need.
-  For more details read the file `CUSTOMIZE'.
+  For more details read the file `CUSTOMIZE`.
 
 
 ----------------------------------------------------------------------
@@ -70,14 +94,14 @@
 [1] make++, a make tool written in Perl, has sufficient support of GNU
     make extensions to build FreeType.  See
 
-      http://makepp.sourceforge.net
+      https://makepp.sourceforge.net
 
     for more information;  you need version 2.0 or newer, and you must
-    pass option `--norc-substitution'.
+    pass option `--norc-substitution`.
 
 ----------------------------------------------------------------------
 
-Copyright 2000-2018 by
+Copyright (C) 2000-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/docs/INSTALL.ANY b/docs/INSTALL.ANY
index fddac9a..bb77b1b 100644
--- a/docs/INSTALL.ANY
+++ b/docs/INSTALL.ANY
@@ -8,20 +8,22 @@
 I. Standard procedure
 ---------------------
 
-  * DISABLE PRE-COMPILED  HEADERS!  This is very  important for Visual
-    C++, because FreeType uses lines like:
+  * If you use macro names  for FreeType header files (while mandatory
+    in earlier versions,  this is now optional  since FreeType version
+    2.6.1) it  is necessary to  disable pre-compiled headers.  This is
+    very important for Visual C++, because lines like
 
       #include FT_FREETYPE_H
 
-    which are not correctly supported by this compiler while being ISO
-    C compliant!
+    are not  correctly supported  by this compiler  while being  ISO C
+    compliant!
 
   * You need to add the directory `include' to your  include path when
     compiling the library.
 
-  * FreeType 2 is made of  several components; each of them is located
-    in    a   subdirectory    of   `freetype2/src'.     For   example,
-    `freetype2/src/truetype/' contains the TrueType font driver.
+  * FreeType 2 is made of several  components; each of them is located
+    in    a   subdirectory    of    `freetype/src'.    For    example,
+    `freetype/src/truetype/' contains the TrueType font driver.
 
   * DO NOT COMPILE ALL C FILES!  Rather, compile the following ones.
 
@@ -71,6 +73,7 @@
        formats)
 
       src/raster/raster.c     -- monochrome rasterizer
+      src/sdf/sdf.c           -- Signed Distance Field driver
       src/smooth/smooth.c     -- anti-aliasing rasterizer
 
     -- auxiliary modules (optional)
@@ -123,9 +126,9 @@
 
   1. Copy all files in current directory
 
-      cp freetype2/src/base/*.[hc] .
-      cp freetype2/src/raster1/*.[hc] .
-      cp freetype2/src/smooth/*.[hc] .
+      cp freetype/src/base/*.[hc] .
+      cp freetype/src/raster1/*.[hc] .
+      cp freetype/src/smooth/*.[hc] .
       etc.
 
   2. Compile sources
@@ -141,7 +144,7 @@
 
 ----------------------------------------------------------------------
 
-Copyright 2003-2018 by
+Copyright (C) 2003-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/docs/INSTALL.CROSS b/docs/INSTALL.CROSS
index 239e1a9..21f4c31 100644
--- a/docs/INSTALL.CROSS
+++ b/docs/INSTALL.CROSS
@@ -163,7 +163,7 @@
 
 ----------------------------------------------------------------------
 
-Copyright 2006-2018 by
+Copyright (C) 2006-2023 by
 suzuki toshiya, David Turner, Robert Wilhelm, and Werner Lemberg.
 
 
diff --git a/docs/INSTALL.GNU b/docs/INSTALL.GNU
index e314ecf..7517d9c 100644
--- a/docs/INSTALL.GNU
+++ b/docs/INSTALL.GNU
@@ -11,9 +11,6 @@
   1. Install GNU Make
   -------------------
 
-    Because  GNU Make  is  the  only Make  tool  supported to  compile
-    FreeType 2, you should install it on your machine.
-
     The FreeType 2 build system relies on many features special to GNU
     Make.
 
@@ -23,7 +20,7 @@
     Note that  make++, a  make tool written  in Perl,  supports enough
     features of GNU make to compile FreeType.  See
 
-      http://makepp.sourceforge.net
+      https://makepp.sourceforge.net
 
     for more information;  you need version 2.0 or newer, and you must
     pass option `--norc-substitution'.
@@ -63,7 +60,7 @@
 
       Otherwise, simply type 'make' again to build the library
       or 'make refdoc' to build the API reference (the latter needs
-      python).
+      Python >= 3.5).
       =============================================================
 
 
@@ -100,6 +97,28 @@
     step 5.
 
 
+  3a. Use clang instead of gcc
+  ----------------------------
+
+    The `clang'  compiler can  use FreeType's setup  for `gcc';  it is
+    sufficient to set the `CC' variable, for example
+
+      make CC=clang
+
+
+  3b. Compiling with a C++ compiler
+  ---------------------------------
+
+    FreeType can be built with a C++ compiler, for example
+
+      make CC="g++"
+
+    If `clang++' should  be used it is necessary to  also override the
+    `ANSIFLAGS' variable:
+
+      make CC="clang++" ANSIFLAGS=""
+
+
   4. Configure the build system for an unknown platform/compiler
   --------------------------------------------------------------
 
@@ -133,7 +152,8 @@
 
     To  launch  the build,  simply  invoke  GNU  Make again:  The  top
     Makefile will detect the configuration file and run the build with
-    it.
+    it.  If you have used variables in  step 3, you must use  the same
+    variables here, too.
 
 
   Final note
@@ -148,7 +168,7 @@
 
 ----------------------------------------------------------------------
 
-Copyright 2003-2018 by
+Copyright (C) 2003-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/docs/INSTALL.UNIX b/docs/INSTALL.UNIX
index f92d828..659f3a2 100644
--- a/docs/INSTALL.UNIX
+++ b/docs/INSTALL.UNIX
@@ -44,14 +44,23 @@
 
       sh autogen.sh
 
-    In case of problems, you  may need to install or upgrade Automake,
-    Autoconf or  Libtool.  See  README.git in the  top-level directory
+    In case of problems, you may  need to install or upgrade Automake,
+    Autoconf or Libtool.  See  `README.git' in the top-level directory
     for more information.
 
 
   3. Build and install the library
   --------------------------------
 
+    Say
+
+      ./configure --help
+
+    to see  the list of  possible configuration options  and important
+    environment  variables.  The ./configure script  will detect  some
+    prerequisite  system  libraries  (libpng, brotli, etc.)  if  their
+    headers are available at the default locations.
+
     The following  should work  on all Unix  systems where  the `make'
     command invokes GNU Make:
 
@@ -75,6 +84,18 @@
     If  this still doesn't  work, there  must be  a problem  with your
     system (e.g., you are using a very old version of GNU Make).
 
+    For library identification, FreeType's `configure' script uses the
+    `pkg-config' interface: Assuming it  needs library `foo', it calls
+    the  `pkg-config' program  to find  information on  library `foo',
+    which in turn  looks for a `foo.pc' file installed  at the system.
+    Some platforms,  however, don't come with  `pkg-support'; you then
+    have  to  use environment  variables  as  described by  `configure
+    --help'.  Example:
+
+      LIBPNG_CFLAGS="-I/path/to/libpng/include/directory" \
+      LIBPNG_LIBS="-L/path/to/libpng/lib/directory" \
+      configure ...
+
     It  is possible  to  compile FreeType  in  a different  directory.
     Assuming the FreeType source  files in directory `/src/freetype' a
     compilation in directory `foo' works as follows:
@@ -105,7 +126,7 @@
 
 ----------------------------------------------------------------------
 
-Copyright 2003-2018 by
+Copyright (C) 2003-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/docs/INSTALL.VMS b/docs/INSTALL.VMS
index c1d30e0..4ed4016 100644
--- a/docs/INSTALL.VMS
+++ b/docs/INSTALL.VMS
@@ -49,7 +49,7 @@
 
 ------------------------------------------------------------------------
 
-Copyright 2000-2018 by
+Copyright (C) 2000-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file  is  part  of the  FreeType  project, and may  only be  used,
diff --git a/docs/LICENSE.TXT b/docs/LICENSE.TXT
deleted file mode 100644
index af5a1c5..0000000
--- a/docs/LICENSE.TXT
+++ /dev/null
@@ -1,39 +0,0 @@
-
-The  FreeType 2  font  engine is  copyrighted  work and  cannot be  used
-legally  without a  software license.   In  order to  make this  project
-usable  to a vast  majority of  developers, we  distribute it  under two
-mutually exclusive open-source licenses.
-
-This means  that *you* must choose  *one* of the  two licenses described
-below, then obey  all its terms and conditions when  using FreeType 2 in
-any of your projects or products.
-
-  - The FreeType License, found in  the file `FTL.TXT', which is similar
-    to the original BSD license *with* an advertising clause that forces
-    you  to  explicitly cite  the  FreeType  project  in your  product's
-    documentation.  All  details are in the license  file.  This license
-    is  suited  to products  which  don't  use  the GNU  General  Public
-    License.
-
-    Note that  this license  is  compatible  to the  GNU General  Public
-    License version 3, but not version 2.
-
-  - The GNU General Public License version 2, found in  `GPLv2.TXT' (any
-    later version can be used  also), for programs which already use the
-    GPL.  Note  that the  FTL is  incompatible  with  GPLv2 due  to  its
-    advertisement clause.
-
-The contributed BDF and PCF drivers  come with a license similar to that
-of the X Window System.  It is compatible to the above two licenses (see
-file src/bdf/README and  src/pcf/README).  The same holds  for the files
-`fthash.c' and  `fthash.h'; their  code was  part of  the BDF  driver in
-earlier FreeType versions.
-
-The gzip module uses the zlib license (see src/gzip/zlib.h) which too is
-compatible to the above two licenses.
-
-The MD5 checksum support (only used for debugging in development builds)
-is in the public domain.
-
-
---- end of LICENSE.TXT ---
diff --git a/docs/MAKEPP b/docs/MAKEPP
index a4d44b7..4450e47 100644
--- a/docs/MAKEPP
+++ b/docs/MAKEPP
@@ -1,5 +1,5 @@
 As a special  exception, FreeType can also be  built with the 'makepp'
-build tool, available from http://makepp.sourceforge.net.
+build tool, available from https://makepp.sourceforge.net.
 
 Note, however,  that  you will need at least version 2.0  and pass the
 option --norc-substitution to have it work correctly.
diff --git a/docs/README b/docs/README
new file mode 100644
index 0000000..d71fd37
--- /dev/null
+++ b/docs/README
@@ -0,0 +1,35 @@
+After saying `make refdoc' or `make refdoc-venv' the `reference/' directory
+contains the FreeType API reference.  You need Python >= 3.5 and pip to make
+this target.
+
+There are two ways to generate the documentation:
+
+1. Using `make refdoc':
+
+    - Ensure `python' and `pip' are available.
+    - Install pip package `docwriter' with `pip install --user docwriter'.
+    - Make target with `make refdoc'.
+    - This target can be run offline once required packages are installed.
+
+2. Using `make refdoc-venv' (requires internet access):
+
+    - Ensure `python', `pip' and Python package `virtualenv' are available.
+    - Make target with `make refdoc-venv'.
+    - 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
+may include bug fixes.
+
+* `Docwriter' does not support Python 2.  Ensure that Python >= 3.5 is
+installed and available as `python3'/`python'.
+
+* Ensure that `docwriter' is installed in the same Python target that
+`make refdoc' uses (python3/python).
+
+* If none of this works, send a mail to `freetype-devel@nongnu.org' or file
+an issue at `https://github.com/freetype/docwriter/issues'.
diff --git a/docs/TODO b/docs/TODO
index 1a443a2..d340880 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -27,7 +27,7 @@
 
 ------------------------------------------------------------------------
 
-Copyright 2001-2018 by
+Copyright (C) 2001-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file  is  part  of the  FreeType  project, and may  only be  used,
diff --git a/docs/VERSIONS.TXT b/docs/VERSIONS.TXT
index 3774157..92f6a8c 100644
--- a/docs/VERSIONS.TXT
+++ b/docs/VERSIONS.TXT
@@ -1,36 +1,44 @@
-Due  to our  use of  `libtool' to  generate and  install the  FreeType 2
-libraries on  Unix systems, as  well as  other historical events,  it is
-generally very  difficult to  know precisely which  release of  the font
+Due to  our use of  `libtool' to generate  and install the  FreeType 2
+libraries on Unix  systems, as well as other historical  events, it is
+generally very difficult  to know precisely which release  of the font
 engine is installed on a given system.
 
-This file tries  to explain why and to document  ways to properly detect
+This file tries to explain why and to document ways to properly detect
 FreeType on Unix.
 
 
 1. Version and Release numbers
 ------------------------------
 
-For each new  public release of FreeType 2, there  are generally *three*
+For each new public release of FreeType 2, there are generally *three*
 distinct `version' numbers to consider:
 
-  * The official FreeType 2 release number, like 2.3.1 or 2.4.10.
+  * The official FreeType 2 release number, like 2.7.0 or 2.10.2.
 
-  * The libtool (and  Unix) specific version number,  like 13.0.7.  This
-    is what `freetype-config --version' returns.
+  * The  libtool (and  Unix)  specific version  number, like  23.2.17.
+    This is what
 
-  * The platform-specific  shared object  number, used for  example when
-    the library is installed as `/usr/lib/libfreetype.so.6.7.1'.
+      pkg-config freetype2 --modversion
 
-The platform-specific  number is, unsurprisingly,  platform-specific and
-varies  with the  operating system  you are  using (several  variants of
-Linux, FreeBSD,  Solaris, etc.).  You  should thus _never_ use  it, even
+    or
+
+      freetype-config --version
+
+    returns.
+
+  * The platform-specific shared object  number, used for example when
+    the library is installed as `/usr/lib/libfreetype.so.6.17.2'.
+
+The platform-specific number is, unsurprisingly, platform-specific and
+varies with  the operating system  you are using (several  variants of
+Linux, FreeBSD, Solaris, etc.).  You  should thus _never_ use it, even
 for simple tests.
 
-The libtool-specific  number does  not equal the  release number  but is
+The libtool-specific number  does not equal the release  number but is
 tied to it.
 
-The release number is available  at *compile* time through the following
-macros defined in FT_FREETYPE_H:
+The  release  number  is  available  at  *compile*  time  through  the
+following macros defined in `freetype.h':
 
   - FREETYPE_MAJOR: major release number
   - FREETYPE_MINOR: minor release number
@@ -38,20 +46,30 @@
 
 See below for a small autoconf fragment.
 
-The  release  number   is  also  available  at   *runtime*  through  the
+The  release  number  is  also  available  at  *runtime*  through  the
 `FT_Library_Version' API.
 
 
 2. History
 ----------
 
-The  following   table  gives,  for   all  releases  since   2.4.0,  the
-corresponding libtool number, as well  as the shared object number found
-on _most_ systems, but not all of them:
+The  following  table  gives,  for   all  releases  since  2.5.0,  the
+corresponding  libtool number,  as well  as the  shared object  number
+found on _most_ systems, but not all of them:
 
 
     release     libtool     so
   -------------------------------
+     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
+     2.11.1     24.1.18   6.18.1
+     2.11.0     24.0.18   6.18.0
+     2.10.4     23.4.17   6.17.4
+     2.10.3     23.3.17   6.17.3
+     2.10.2     23.2.17   6.17.2
+     2.10.1     23.1.17   6.17.1
+     2.10.0     23.0.17   6.17.0
      2.9.1      22.1.16   6.16.1
      2.9.0      22.0.16   6.16.0
      2.8.1      21.0.15   6.15.0
@@ -70,58 +88,48 @@
      2.5.2      17.1.11   6.11.1
      2.5.1      17.0.11   6.11.0
      2.5.0      16.2.10   6.10.2
-     2.4.12     16.1.10   6.10.1
-     2.4.11     16.0.10   6.10.0
-     2.4.10     15.0.9    6.9.0
-     2.4.9      14.1.8    6.8.1
-     2.4.8      14.0.8    6.8.0
-     2.4.7      13.2.7    6.7.2
-     2.4.6      13.1.7    6.7.1
-     2.4.5      13.0.7    6.7.0
-     2.4.4      12.2.6    6.6.2
-     2.4.3      12.1.6    6.6.1
-     2.4.2      12.0.6    6.6.0
-     2.4.1      11.1.5    6.5.1
-     2.4.0      11.0.5    6.5.0
 
 
 3. Autoconf Code Fragment
 -------------------------
 
-Lars Clausen contributed the following autoconf fragment to detect which
-version of  FreeType is  installed on  a system.  This  one tests  for a
-version that  is at least 2.0.9;  you should change it  to check against
+Lars  Clausen contributed  the  following autoconf  fragment to  check
+which version of FreeType is installed on a system (now updated to use
+`pkg-config'  instead of  `freetype-config').   This one  tests for  a
+version that is at least 2.10.2; you should change it to check against
 other release numbers.
 
 
-  AC_MSG_CHECKING([whether FreeType version is 2.0.9 or higher])
+  AC_MSG_CHECKING([whether FreeType version is 2.10.2 or higher])
   old_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS=`freetype-config --cflags`
+  CPPFLAGS=`pkg-config freetype2 --cflags`
   AC_TRY_CPP([
 
 #include <ft2build.h>
-#include FT_FREETYPE_H
-#if (FREETYPE_MAJOR*1000 + FREETYPE_MINOR)*1000 + FREETYPE_PATCH < 2000009
-#error FreeType version too low.
+#include <freetype/freetype.h>
+
+#if FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH < 21002
+#  error FreeType version too low.
 #endif
+
   ],
   [AC_MSG_RESULT(yes)
-   FREETYPE_LIBS=`freetype-config --libs`
+   FREETYPE_LIBS=`pkg-config freetype2 --libs`
    AC_SUBST(FREETYPE_LIBS)
    AC_DEFINE(HAVE_FREETYPE,1,[Define if you have the FreeType2 library])
    CPPFLAGS="$old_CPPFLAGS"],
-  [AC_MSG_ERROR([Need FreeType library version 2.0.9 or higher])])
+  [AC_MSG_ERROR([Need FreeType library version 2.10.2 or higher])])
 
-------------------------------------------------------------------------
+----------------------------------------------------------------------
 
-Copyright 2002-2018 by
+Copyright (C) 2002-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.
+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.
 
 
 --- end of VERSIONS.TXT ---
diff --git a/docs/formats.txt b/docs/formats.txt
index 75aba92..7a4bae0 100644
--- a/docs/formats.txt
+++ b/docs/formats.txt
@@ -79,8 +79,7 @@
 
   SFNT    PS      TYPE_1  ---        type1    Type 1 GX Font Format
                                               (for the Mac) [3]
-  SFNT    PS      TYPE_1  CID        cid      5180.sfnt.pdf (for the Mac)
-                                              [3]
+  SFNT    PS      TYPE_1  CID        cid      5180.sfnt.pdf (for the Mac) [3]
   SFNT    PS      CFF     ---        cff      OT spec, 5176.CFF.pdf
                                               (`OTTO' format)
   SFNT    PS      CFF     CID        cff      OT spec, 5176.CFF.pdf
@@ -97,6 +96,12 @@
                                               (`?var' + `?VAR' tables)
 
 
+  WOFF    ---     ---     ---        cff,     Compressed SFNT, ver. 1.0 [6]
+                                     truetype
+  WOFF2   ---     ---     ---        cff,     Compressed SFNT, ver. 2.0 [6]
+                                     truetype
+
+
   ---     PS      TYPE_1  ---        type1    T1_SPEC.pdf
                                               (PFA, Type 1 font resource)
   PFB     PS      TYPE_1  ---        type1    T1_SPEC.pdf,
@@ -165,8 +170,8 @@
     partially defined in MHP 1.0.3 (also called ETSI TS 101812 V1.3.1)
     section 7.4.
 
-      http://www.etsi.org/
-      http://webapp.etsi.org/workprogram/Report_WorkItem.asp?WKI_ID=18799
+      https://www.etsi.org/
+      https://webapp.etsi.org/workprogram/Report_WorkItem.asp?WKI_ID=18799
 
 [3] Support  is rudimentary  currently; some  tables or  data are  not
     loaded yet.
@@ -185,13 +190,17 @@
 
       https://fontforge.github.io/pcf-format.html
 
-[5] This is from MS Windows 3; see Microsoft's Knowledge Base article at
+[5] This is from MS Windows 3;  see Microsoft's Knowledge Base article
+    at
 
       https://support.microsoft.com/kb/65123
 
+[6] Supported  font  formats  are   TrueType  and  OpenType  fonts  as
+    defined in the OpenType specification 1.6 and newer.
+
 ------------------------------------------------------------------------
 
-Copyright 2004-2018 by
+Copyright (C) 2004-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part  of the  FreeType  project, and  may  only be  used,
diff --git a/docs/freetype-config.1 b/docs/freetype-config.1
index 164b8ff..6459431 100644
--- a/docs/freetype-config.1
+++ b/docs/freetype-config.1
@@ -1,4 +1,4 @@
-.TH FREETYPE-CONFIG 1 "May 2018" "FreeType 2.9.1"
+.TH FREETYPE-CONFIG 1 "February 2023" "FreeType 2.13.0"
 .
 .
 .SH NAME
diff --git a/docs/markdown/images/favico.ico b/docs/markdown/images/favico.ico
new file mode 100644
index 0000000..8464e77
--- /dev/null
+++ b/docs/markdown/images/favico.ico
Binary files differ
diff --git a/docs/markdown/javascripts/extra.js b/docs/markdown/javascripts/extra.js
new file mode 100644
index 0000000..00f1670
--- /dev/null
+++ b/docs/markdown/javascripts/extra.js
@@ -0,0 +1,54 @@
+/*
+Internal link topbar offest adjust Javascript
+Code provided by @makshh on GitHub
+
+Bug report on material-mkdocs
+  https://github.com/squidfunk/mkdocs-material/issues/791
+*/
+
+// Offset top helper
+function offsetY(elem) {
+    if(!elem) elem = this;
+    var y = elem.offsetTop;
+    while (elem = elem.offsetParent) {
+        y += elem.offsetTop;
+    }
+    return y;
+}
+
+// If a link on the same page is clicked, calculate the
+// correct offset and scroll to that part of the page.
+//
+var links = document.getElementsByTagName('a');
+for(var i = 0; i < links.length; i++) {
+    links[i].onclick = function (event) {
+        if (this.pathname == window.location.pathname &&
+            this.protocol == window.location.protocol &&
+            this.host == window.location.host) {
+                event.preventDefault();
+                if(this.hash.substr(1)){
+                    var o = document.getElementById(this.hash.substr(1));
+                    var sT = offsetY(o) - document.getElementsByClassName('md-header')[0].clientHeight;
+                    window.location.hash = this.hash;
+                    window.scrollTo(0, sT);
+                }
+        }
+    }
+}
+
+// Slugify supplied text
+function slugify(text){
+    text = text.toLowerCase();
+    text = text.replace(" ", "-");
+    return text;
+}
+
+// If there is a hash in the url, slugify it
+// and replace
+if(window.location.hash) {
+    // Fragment exists
+    slug = slugify(window.location.hash);
+    history.replaceState(undefined, undefined, slug)
+    //window.location.hash = slug;
+    document.location.replace(window.location.href);
+}
diff --git a/docs/markdown/stylesheets/extra.css b/docs/markdown/stylesheets/extra.css
new file mode 100644
index 0000000..5d999ed
--- /dev/null
+++ b/docs/markdown/stylesheets/extra.css
@@ -0,0 +1,177 @@
+/* Body and page */
+.md-grid {
+    max-width: 90%;
+}
+p {
+    text-align: justify;
+}
+
+/* code blocks */
+pre.colored {
+    color: blue;
+}
+pre>code {
+    font-family: monospace;
+    background-color: #D6E8FF;
+    padding: 2ex 0 2ex 1%;
+    overflow-x:auto;
+}
+span.keyword {
+    font-family: monospace;
+    text-align: left;
+    white-space: pre;
+    color: #d73a49;
+}
+.md-typeset pre>code {
+    white-space: pre;
+}
+/* H4 Heading */
+h4 {
+    background-color: #EEEEFF;
+    font-size: medium;
+    font-style: oblique;
+    font-weight: bold;
+    padding: 0.3em 0 0.3em 1%;
+}
+
+/* Fields table */
+table.fields {
+    width: 90%;
+    margin: 1.5ex 0 1.5ex 10%;
+}
+table.fields td.val {
+    font-weight: bold;
+    text-align: right;
+    width: 30%;
+    vertical-align: baseline;
+    padding: 1em 1em 0 0;
+}
+table.fields td.desc {
+    vertical-align: baseline;
+    padding: 1ex 0 0 1em;
+}
+table.fields td.desc p:first-child {
+    margin: 0;
+}
+
+table.fields td.desc p {
+    margin: 1.5ex 0 0 0;
+}
+
+/* Define 'long' tables */
+table.long {
+    display: block;
+    width: 93%;
+}
+table.long thead,
+table.long tbody,
+table.long th,
+table.long td,
+table.long tr {
+    display: block;
+}
+/* Hide table headers (but not display: none;
+, for accessibility) */
+table.long thead tr {
+    position: absolute;
+    top: -9999px;
+    left: -9999px;
+}
+table.long tr {
+    border: 0;
+}
+table.long {
+    margin: 1.5ex 3% 1.5ex 3%;
+}
+table.long td.val {
+    text-align: left;
+}
+table.long td {
+   /* Behave like a "row" */
+    border: none;
+    border-bottom: 0;
+    position: relative;
+    padding-left: 50%;
+}
+table.long td:before {
+   /* Now like a table header */
+    position: absolute;
+   /* Top/left values mimic padding */
+    top: 6px;
+    left: 6px;
+    width: 45%;
+    padding-right: 10px;
+    white-space: nowrap;
+}
+/* End 'long' table definition */
+
+/* toc table */
+table.toc {
+    width: 95%;
+    margin: 1.5ex 0 1.5ex 5%;
+}
+table.toc td.link {
+    width: 30%;
+    text-align: right;
+    vertical-align: baseline;
+    padding: 1ex 1em 1ex 0;
+}
+table.toc td.desc {
+    vertical-align: baseline;
+    padding: 1ex 0 1ex 1em;
+    text-align: left;
+}
+table.toc td.desc p:first-child {
+    margin: 0;
+    text-align: left;
+}
+table.toc td.desc p {
+    margin: 1.5ex 0 0 0;
+    text-align: left;
+}
+div.timestamp {
+    font-size: small;
+}
+
+/* Change table layout for smaller screens. This query will take effect for any screen smaller than
+   760px and also iPads specifically. */
+@media only screen and (max-width: 760px), (min-device-width: 768px) and (max-device-width: 1024px) {
+   /* Force table to not be like tables anymore */
+    table, thead, tbody, th, td, tr {
+        display: block;
+   }
+   /* Hide table headers (but not display: none;
+    , for accessibility) */
+    thead tr {
+        position: absolute;
+        top: -9999px;
+        left: -9999px;
+   }
+    tr {
+        border: 0;
+   }
+    table.fields {
+        width: 93%;
+        margin: 1.5ex 3% 1.5ex 3%;
+   }
+    table.fields td.val {
+        text-align: left;
+   }
+    td {
+       /* Behave like a "row" */
+        border: none;
+        border-bottom: 0;
+        position: relative;
+        padding-left: 50%;
+   }
+    td:before {
+       /* Now like a table header */
+        position: absolute;
+       /* Top/left values mimic padding */
+        top: 6px;
+        left: 6px;
+        width: 45%;
+        padding-right: 10px;
+        white-space: nowrap;
+   }
+}
diff --git a/ChangeLog.20 b/docs/oldlogs/ChangeLog.20
similarity index 99%
rename from ChangeLog.20
rename to docs/oldlogs/ChangeLog.20
index 63e3116..0993728 100644
--- a/ChangeLog.20
+++ b/docs/oldlogs/ChangeLog.20
@@ -1688,7 +1688,7 @@
 
 2001-04-03  Werner Lemberg  <wl@gnu.org>
 
-	* src/*/Jamfile: Slight changes	to make files more cryptic.
+	* src/*/Jamfile: Slight changes to make files more cryptic.
 
 2001-04-03  Werner Lemberg  <wl@gnu.org>
 
@@ -1928,7 +1928,7 @@
 
 	* src/autohint/ahtypes.h (AH_Hinter): Add elements
 	`disable_horz_edges', `disable_vert_edges'.
-	* src/autohint/ahhint.c	(ah_hint_edges_3, ah_hinter_hint_edges): Use
+	* src/autohint/ahhint.c (ah_hint_edges_3, ah_hinter_hint_edges): Use
 	them (and remove static variables with the same names).
 	* src/pcf/pcfutil.c (BitOrderInvert): Add `const'.
 	* docs/glnames.py: Updated to latest pstables.h changes.
@@ -2109,7 +2109,7 @@
 	* include/freetype/internal/t2types.h: This file was merged with
 	cfftypes.h and is no longer necessary.
 
-	* include/freetype/internal/t2errors.h:	Renamed to cfferrs.h.
+	* include/freetype/internal/t2errors.h: Renamed to cfferrs.h.
 
 	* src/cff/cffobjs.c, src/cff/cffobjs.h, src/cff/cffparse.c,
 	src/cff/cffdrivr.c, src/cff/cff.c, src/cff/cffload.c,
@@ -2184,11 +2184,11 @@
 
 2000-12-24  Tom Kacvinsky  <tkacvins@freetype.org>
 
-	* src/cff/t2gload.c (T2_Load_Glyph): Added code	so that the font
+	* src/cff/t2gload.c (T2_Load_Glyph): Added code so that the font
 	transform is applied.
 
 	* src/cff/cffparse.c (cff_parse_font_matrix): Added code so that
-	the font matrix numbers	are scaled by 1/(matrix->yy).  Also, the
+	the font matrix numbers are scaled by 1/(matrix->yy).  Also, the
 	offset vector now contains integer values instead of 16.16 fixed
 	numbers.
 
@@ -2597,7 +2597,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2000-2018 by
+Copyright (C) 2000-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog.21 b/docs/oldlogs/ChangeLog.21
similarity index 99%
rename from ChangeLog.21
rename to docs/oldlogs/ChangeLog.21
index 1adc817..b331257 100644
--- a/ChangeLog.21
+++ b/docs/oldlogs/ChangeLog.21
@@ -553,7 +553,7 @@
 	(T1_New_Parser): Use it to check font header before allocating
 	anything on the heap.
 
-	* src/type42/t42parse.c	(t42_parser_init): Modify functions to check
+	* src/type42/t42parse.c (t42_parser_init): Modify functions to check
 	the font header before allocating anything on the heap.
 
 	* include/freetype/internal/ftmemory.h (FT_ARRAY_MAX,
@@ -4799,11 +4799,11 @@
 	(chapter_inter, chapter_footer): Add <li> and use special <ul>
 	class.
 	Use double quotes around table widths given in percent.
-	(keyword_prefix, keyword_suffix): Don't change font colour directly
+	(keyword_prefix, keyword_suffix): Don't change font color directly
 	but use a new <span> class.
 	(section_synopsis_header, section_synopsis_footer): Don't change
-	colour.
-	(code_header, code_footer): Don't change font colour directly but
+	color.
+	(code_header, code_footer): Don't change font color directly but
 	use a special <pre> class.
 	(print_html_field): <tr> gets the `valign' attribute, not <table>.
 	(print_html_field_list): Ditto.
@@ -9422,7 +9422,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2002-2018 by
+Copyright (C) 2002-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/docs/oldlogs/ChangeLog.210 b/docs/oldlogs/ChangeLog.210
new file mode 100644
index 0000000..adb23d5
--- /dev/null
+++ b/docs/oldlogs/ChangeLog.210
@@ -0,0 +1,7815 @@
+2021-07-18  Werner Lemberg  <wl@gnu.org>
+
+	* Version 2.11.0 released.
+	==========================
+
+
+	Tag sources with `VER-2-11-0'.
+
+	* docs/VERSION.TXT: Add entry for version 2.11.0.
+	* docs/CHANGES: Updated.
+
+	* README, src/base/ftver.rc, builds/windows/vc2010/index.html,
+	builds/windows/visualc/index.html,
+	builds/windows/visualce/index.html,
+	builds/wince/vc2005-ce/index.html,
+	builds/wince/vc2008-ce/index.html, docs/freetype-config.1:
+	s/2.10.4/2.11.0/, s/2104/2110/.
+
+	* include/freetype/freetype.h (FREETYPE_MINOR): Set to 11.
+	(FREETYPE_PATCH): Set to 0.
+
+	* builds/unix/configure.raw (version_info): Set to 24:0:18.
+	* CMakeLists.txt (VERSION_MINOR): Set to 11.
+	(VERSION_PATCH): Set to 0.
+
+	* builds/toplevel.mk (dist): Ignore more git-related files.
+
+2021-07-17  David Turner  <david@freetype.org>
+
+	* src/smooth/ftgrays.c: Fix compilation if `FT_LONG64` is undefined.
+
+	The code assumed that if `__SSE2__` is defined, then 64-bit integer
+	types are available.  This is not the case apparently for certain
+	multilib compiler targets like 'x86_32.x86' used by Gentoo.
+
+	This patch fixes the issue by disabling the special code path when
+	64-bit integer types are not available.
+
+	Fixes #1071.
+
+2021-07-16  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
+
+	[tests] Allow arbitrary build directories.
+
+	* tests/issue-1063/main.c (main): I am building with a build
+	directory that is not directly inside the source tree, so the path
+	`../tests/data/As.I.Lay.Dying.ttf` does not resolve to the test
+	input file.  This change passes the test data directory as an
+	environment variable to allow arbitrary build directories.
+
+	* tests/meson.build: Updated.
+
+2021-07-16  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
+
+	* tests/issue-1063/main.c (main): Fix uninitialized variable.
+
+	I tried running `meson test` but the test just crashed and gdb
+	reported that the face argument to `FT_Get_Char_Index` was nonsense.
+	With this change the test prints 'Could not open file: ' as it
+	should.
+
+2021-07-16  Werner Lemberg  <wl@gnu.org>
+
+	[smooth] Minor fixes.
+
+	* src/smooth/ftgrays.c (gray_render_conic): Move variable and
+	structure declarations to beginning of function.  In spite of C99
+	compliance we still do this for the sake of backward compatibility.
+	This also avoids a shadowing declaration of `count`.
+	(gray_convert_glyph_inner): Fix typo.
+
+2021-07-15  Ben Wagner  <bungeman@chromium.org>
+
+	* src/smooth/ftgrays.c: Guard inclusion of `emmintrin.h`.
+
+	Guard inclusion of `emmintrin.h` with `#ifdef __SSE2__`.  The gcc
+	version of this header, `xmmintrin.h`, and `mmintrin.h` check that
+	the appropriate defines are set before defining anything (are
+	internally guarded).  However, the clang versions of these includes
+	are not internally guarded.  As a result of this, externally guard
+	the inclusion of these headers.
+
+2021-07-15  David Turner  <david@freetype.org>
+
+	[smooth] Implement Bézier quadratic arc flattening with DDA.
+
+	Benchmarking shows that this provides a very slighty performance
+	boost when rendering fonts with lots of quadratic Bézier arcs,
+	compared to the recursive arc splitting, but only when SSE2 is
+	available, or on 64-bit CPUs.
+
+	On a 2017 Core i5-7300U CPU on Linux/x86_64:
+
+	  ftbench -p -s10 -t5 -cb DroidSansFallbackFull.ttf
+
+	  Before: 4.033 us/op  (best of 5 runs for all numbers)
+	  After:  3.876 us/op
+
+	  ftbench -p -s60 -t5 -cb DroidSansFallbackFull.ttf
+
+	  Before: 13.467 us/op
+	  After:  13.385 us/op
+
+	* src/smooth/ftgrays.c (gray_render_conic): New implementation
+	based on DDA and optionally SSE2.
+
+2021-07-15  David Turner  <david@freetype.org>
+
+	[smooth] Minor speedup to smooth rasterizer.
+
+	This speeds up the smooth rasterizer by avoiding conditional
+	branches in the hot path.
+
+	- Define a fixed 'null cell', which will be pointed to whenever the
+	  current cell is outside of the current target region.  This avoids
+	  a `ras.cell != NULL` check in the `FT_INTEGRATE` macro.
+
+	- Also use the null cell as a sentinel at the end of all `ycells`
+	  linked-lists, by setting its x coordinate to `INT_MAX`.  This
+	  avoids a `if (!cell)` check in `gray_set_cell` as well.
+
+	- Slightly change the worker struct fields to perform a little less
+	  operations during rendering.
+
+	Example results (on a 2013 Corei5-3337U CPU)
+
+	  out/ftbench -p -s10 -t5 -bc DroidSansFallbackFull.ttf
+
+	  Before: 5.472 us/op
+	  After:  5.275 us/op
+
+	  out/ftbench -p -s60 -t5 -bc DroidSansFallbackFull.ttf
+
+	  Before: 17.988 us/op
+	  After:  17.389 us/op
+
+	* src/smooth/ftgrays.c (gray_TWorker): Replace `num_cells` field with
+	`cell_free` and `cell_limit`.
+	(NULL_CELL_PTR, CELL_MAX_X_VALUE, CELL_IS_NULL): New macros.
+	(gray_dump_cells, gray_set_cell, gray_sweep, gray_sweep_direct,
+	gray_convert_glyph_inner, gray_convert_glyph): Updated.
+
+2021-07-15  David Turner  <david@freetype.org>
+
+	[tests] Rewrite download script in Python3.
+
+	This commit replaces the bash script with a Python script that does
+	the same work, plus avoiding to download anything if the files are
+	already installed with the right content.
+
+	We now use the first 8 bytes of each file's sha256 hash for the
+	digest.
+
+	* tests/scripts/download-test-fonts.sh: Removed.
+	* tests/scripts/download-test-fonts.py: New script.
+	* tests/README.md: Updated.
+
+2021-07-15  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
+
+	Support architectures where `long` is smaller than pointers.
+
+	I am currently trying to compile FreeType for CHERI-extended ISAs
+	(CHERI-RISC-V and Arm's Morello), but I am getting compiler warnings
+	from the `FT_UINT_TO_POINTER` macro.  When compiling with the CHERI
+	Clang compiler, not using `uinptr_t` for casts between integers an
+	pointers results in the following `-Werror` build failures:
+
+	```
+	In file included from .../src/truetype/truetype.c:22:
+	  .../src/truetype/ttgload.c:1925:22: error:
+	    cast from provenance-free integer type to pointer type will
+	    give pointer that can not be dereferenced
+	    [-Werror,-Wcheri-capability-misuse]
+	  node->data = FT_UINT_TO_POINTER( glyph_index );
+	               ^
+	  .../include/freetype/internal/compiler-macros.h:79:34: note:
+	    expanded from macro 'FT_UINT_TO_POINTER'
+	```
+
+	* include/freetype/internal/compiler-macros.h (FT_UINT_TO_POINTER):
+	The ISO C standard compliant fix for this would be to use
+	`uintptr_t` from `stdint.h`, but I am not sure if this is supported
+	by the minimum compiler version.  Therefore, use the
+	compiler-defined `__UINTPTR_TYPE__` macro (supported in GCC 4.6+ and
+	Clang since about 3.0) before checking for `_WIN64` and falling back
+	to `unsigned long`.
+
+2021-07-13  Oleg Oshmyan  <chortos@inbox.lv>
+
+	[base] Fix `FT_Open_Face`'s handling of user-supplied streams.
+
+	This was already true (though undocumented) most of the time, but
+	not if `FT_NEW` inside `FT_Stream_New` failed or if the
+	`FT_OPEN_XXX` flags were bad.
+
+	Normally, `FT_Open_Face` calls `FT_Stream_New`, which returns the
+	user-supplied stream unchanged, and in case of any subsequent error
+	in `FT_Open_Face`, the stream is closed via `FT_Stream_Free`.
+
+	Up to now, however, `FT_Stream_New` allocates a new stream even if
+	it is already given one by the user.  If this allocation fails, the
+	user-supplied stream is not returned to `FT_Open_Face` and never
+	closed.  Moreover, the user cannot detect this situation: all they
+	see is that `FT_Open_Face` returns `FT_Err_Out_Of_Memory`, but that
+	can also happen after a different allocation fails within the main
+	body of `FT_Open_Face`, when the user's stream has already been
+	closed by `FT_Open_Face`.  It is plausible that the user stream's
+	`close` method frees memory allocated for the stream object itself,
+	so the user cannot defensively free it upon `FT_Open_Face` failure
+	lest it ends up doubly freed.  All in all, this ends up leaking the
+	memory/resources used by user's stream.
+
+	Furthermore, `FT_Stream_New` simply returns an error if the
+	`FT_OPEN_XXX` flags are unsupported, which can mean either an
+	invalid combination of flags or a perfectly innocent
+	`FT_OPEN_STREAM` on a FreeType build that lacks stream support.
+	With this patch, the user-supplied stream is closed even in these
+	cases, so the user can be sure that if `FT_Open_Face` failed, the
+	stream is definitely closed.
+
+	* src/base/ftobjs.c (FT_Stream_New): Don't allocate a buffer
+	unnecessarily.
+	Move error-handling code to make the control flow more obvious.
+	Close user-supplied stream if the flags are unsupported.
+	`FT_Stream_Open` always sets `pathname.pointer`, so remove the
+	redundant (re)assignment.  None of the `FT_Stream_Open...` functions
+	uses `stream->memory`, so keep just one assignment at the end,
+	shared among all possible control flow paths.
+	('Unsupported flags' that may need a stream closure can be either an
+	invalid combination of multiple `FT_OPEN_XXX` mode flags or a clean
+	`FT_OPEN_STREAM` flag on a FreeType build that lacks stream
+	support.)
+
+2021-07-13  Oleg Oshmyan  <chortos@inbox.lv>
+
+	[base] Reject combinations of incompatible `FT_OPEN_XXX` flags.
+
+	The three modes are mutually exclusive, and the documentation of the
+	`FT_OPEN_XXX` constants notes this.  However, there was no check to
+	validate this in the code, and the documentation on `FT_Open_Args`
+	claimed that the corresponding bits were checked in a well-defined
+	order, implying it was valid (if useless) to specify more than one.
+	Ironically, this documented order did not agree with the actual
+	code, so it could not be relied upon; hopefully, nobody did this and
+	nobody will be hurt by the new validation.
+
+	Even if multiple mode bits were allowed, they could cause memory
+	leaks: if both `FT_OPEN_STREAM` and `stream` are set along with
+	either `FT_OPEN_MEMORY` or `FT_OPEN_PATHNAME`, then `FT_Stream_New`
+	allocated a new stream but `FT_Open_Face` marked it as an 'external'
+	stream, so the stream object was never released.
+
+	* src/base/ftobjs.c (FT_Stream_New): Reject incompatible
+	`FT_OPEN_XXX` flags.
+
+2021-07-12  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
+
+	* meson.build: Fix build for other UNIX systems (e.g., FreeBSD).
+
+	Without this change the build of `unix/ftsystem.c` fails because the
+	`ftconfig.h` header that defines macros such as `HAVE_UNISTD_H` and
+	`HAVE_FCNTL_H` is only being generated for Linux, macOS, and Cygwin
+	systems:
+
+	```
+	.../builds/unix/ftsystem.c:258:32: error:
+	    use of undeclared identifier 'O_RDONLY'
+	file = open( filepathname, O_RDONLY );
+	```
+
+	Instead of hardcoding a list of operating systems for this check,
+	update the logic that decides whether to build the file and set a
+	boolean flag that can be checked instead.
+
+2021-07-12  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] More clean-ups.
+
+	* src/autofit/afhints.h (AF_GlyphHintsRec): Remove the no longer
+	needed fields `xmin_delta` and `xmax_delta`.
+
+	* src/autofit/afhints.c (af_glyph_hints_reload),
+	src/autofit/afloader.c (af_loader_load_glyph): Updated.
+
+2021-07-12  Werner Lemberg  <wl@gnu.org>
+
+	Small clean-ups for the last few commits.
+
+	* include/freetype/fttrace.h (afwarp): Removed.
+
+2021-07-12  David Turner  <david@freetype.org>
+
+	Remove obsolete `AF_Angle` type and related sources.
+
+	* src/autofit/afangles.c: File removed.  Functions related to
+	sorting moved to...
+	* src/autofit/afhints.c (af_sort_pos, af_sort_and_quantize_widths):
+	This file.
+	* src/autofit/afangles.h: File removed.
+	* src/autofit/aftypes.h: Updated.
+	* src/autofit/autofit.c: Updated.
+
+	* src/autofit/rules.mk (AUTOF_DRV_SRC): Updated.
+
+2021-07-12  David Turner  <david@freetype.org>
+
+	Remove experimental auto-hinting 'warp' mode.
+
+	This feature was always experimental, and probably never worked
+	properly.  This patch completely removes it from the source code,
+	except for a documentation block describing it for historical
+	purposes.
+
+	* devel/ftoption.h, include/freetype/config/ftoption.h: Remove
+	`AF_CONFIG_OPTION_USE_WARPER`.
+
+	* include/freetype/ftdriver.h: Document 'warping' property as
+	obsolete.
+
+	* src/autofit/afwarp.c, src/autofit/afwarp.h: Files removed.
+	* src/autofit/*: Remove any code related to warp mode.
+
+2021-07-12  David Turner  <david@freetype.org>
+
+	Remove experimental 'Latin2' writing system (`FT_OPTION_AUTOFIT2`).
+
+	This code has always been experimental and was never compiled anyway
+	(`FT_OPTION_AUTOFIT2` does not appear in `ftoption.h` or even any of
+	our build files).
+
+	* include/freetype/internal/fttrace.h (aflatin2): Removed.
+	* src/autofit/aflatin2.h, src/autofit/aflatin2.c: Files removed.
+	* src/autofit/afloader.c: Remove undocumented hook to activate
+	Latin2 system.
+	* src/autofit/afstyles.h: Remove `ltn2_dflt` style definition.
+	* src/autofit/afwrtsys.h: Remove `LATIN2` writing system definition.
+	* src/autofit/autofit.c: Updated.
+
+2021-07-05  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftlcdfil.c (FT_Library_SetLcdGeometry): Fix argument.
+
+	Reported by Hin-Tak.
+
+2021-07-03  Werner Lemberg  <wl@gnu.org>
+
+	* meson_options.txt: Sort alphabetically; no final full stops.
+
+2021-07-01  Ben Wagner  <bungeman@chromium.org>
+
+	* src/truetype/ttgxvar.c (tt_set_mm_blend): Test `coords`.
+
+	It is undefined behavior to pass `NULL` to `memcpy`.  `coords' is
+	passed to `memcpy` but `TT_Get_MM_Blend` and `TT_Get_Var_Design`
+	explicitly call `tt_set_mm_blend` with `coords` as `NULL`.  In
+	addition, `TT_Set_MM_Blend` has a similar possible issue.
+
+2021-06-30  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Support PaintScale in 'COLR' v1 parsing.
+
+	* include/freetype/ftcolor.h (FT_PaintFormat): Renumber values, add
+	`FT_COLR_PAINTFORMAT_SCALE`.
+	(FT_PaintScale): New structure to represent 'PaintScale*' tables.
+	(FT_COLR_Paint): Updated.
+
+	* src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration.
+	(read_paint): Parse 'PaintScale' and friends.
+
+2021-06-30  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Handle fonts without layer list in 'COLR' v1.
+
+	'COLR' v1 fonts do not necessarily need to have a layer list; for
+	this reason, 'fontTools' recently started generating fonts in a way
+	that drops the layer list if there are no layers in it.  This
+	results in the layer list offset becoming zero, which FreeType
+	treated as an invalid table.  Fix that and handle the case for layer
+	list offset being 0.  This slightly changes how we need to calculate
+	the starting offset for paints.
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr): Handle case of layer list
+	offset being zero without outright rejecting table.
+
+2021-06-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/raster/ftraster.c (Render_Single_Pass): Simplify `band_stack'.
+
+2021-06-29  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Do not skip the second pass without dropout control.
+
+	The second pass also fixes horizontal lines through the pixel centers.
+
+	* src/raster/ftraster.c (black_TWorker): Do not use `second_pass'.
+	(Render_Glyph): Skip the second pass only with the appropriate flag.
+
+2021-06-29  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Handle sub-band stack locally.
+
+	* src/raster/ftraster.c (black_TWorker): Move `band_stack' from here..
+	(Render_Single_Pass): ... to here and accept limit arguments.
+	(Render_Glyph): Updated.
+
+2021-06-25  Anurag Thakur  <anuthadev@gmail.com>
+
+	[CI] Introduce linux CI and refactor job names.
+
+	* .gitlab-ci.yml: Added jobs for building freetype on linux.
+
+2021-06-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Handle Bézier stack locally.
+
+	* src/raster/ftraster.c (black_TWorker): Move `arcs' from here...
+	(Conic_To, Cubic_To): ... to here to tighten their scope.
+	(Bezier_Up, Bezier_Down): ... Take the current `arc' argument.
+
+2021-06-28  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Improve paint limit checks
+
+	Paint tables can appear before the `base_glyphs_v1` offset if the
+	font is produced with the layer list before the base glyph list.  In
+	this case paint tables can occur after the layer list but before the
+	base glyph list.  Checks in the 'COLR' v1 code were rejecting fonts
+	with this layout.  Improve these checks by calculating a minimum
+	offset after which paint tables can occur and use that in safety
+	checks.
+
+	* src/sfnt/ttcolr.c (Colr, tt_face_load_colr): Declare
+	`paint_start_v1` and calculate that as the minimum of the end of
+	layer list and base glyph list.
+	(get_child_table_pointer, read_paint, tt_face_get_paint_layers):
+	Use that in safety checks.
+
+2021-06-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Clean up vertical sweep.
+
+	* src/raster/ftraster.c (black_TWorker): Replace the current line
+	offset with the pointer and drop the increment.
+	(Function_Sweep_Init): Take values as arguments instead of pointers.
+	(Vertical_Sweep_*, Horizontal_Sweep_Init, Draw_Sweep): Updated.
+
+2021-06-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Make `band_top' local variable.
+
+	* src/raster/ftraster.c (black_TWorker): Move `band_top' from here...
+	(Render_Single_Pass): ... to here, and refactor.
+	(Render_Glyph): Updated.
+
+2021-06-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Adjust sub-band bisecting limits.
+
+	We can bisect a band until it is just a single scan line.  This might
+	be slow and cause time-outs but if we need to impose limits it should
+	be elsewhere.
+
+	* src/raster/ftraster.c (Render_Single_Pass): Tweak sub-banding.
+
+2021-06-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/raster/ftraster.c (Render_Single_Pass): Remove dead code.
+
+2021-06-25  Werner Lemberg  <wl@gnu.org>
+
+	[base] Add trace level to logging output.
+
+	Some practical debugging work has shown that displaying level X of
+	an `FT_TRACEX` macro in the output of `FT2_DEBUG="...  -v"` would be
+	very helpful to find out which trace level should be selected.  As
+	an example, we now get output like
+
+	```
+	[ttobjs:2]    TTF driver
+	[ttobjs:2]      SFNT driver
+	[sfobjs:2]      not a font using the SFNT container format
+	[t1objs:2]    Type 1 driver
+	[stream:7]    FT_Stream_EnterFrame: 14 bytes
+	```
+
+	* include/freetype/internal/ftdebug.h (FT_LOGGING_TAGX): New macro.
+	(FT_LOG): Use it to add the trace level to the logging tag.
+
+	* include/freetype/internal/fttrace.h (FT_MAX_TRACE_LEVEL_LENGTH):
+	Adjust.
+
+	* docs/DEBUG: Updated.
+
+2021-06-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth, raster] Fix up and align error codes.
+
+	FT_Render_Glyph picked up FAILURE or 1 returned from the raster
+	function, which became a confusing error code. Instead, return
+	Raster_Overflow in the unlikely event that banding does not help or
+	another meaningful error.
+
+	* src/smooth/ftgrays.c (gray_convert_glyph_inner, gray_convert_glyph):
+	Use Raster_Overflow when the rendering pool is exhausted and return it
+	if banding does not help.
+	(gray_raster_render): Use Smooth_Err_Ok.
+
+	* src/raster/ftraster.c (Render_Single_Pass): Return Raster_Overflow
+	if banding does not help or another error code.
+
+2021-06-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth, raster] Remove synonymous error macros.
+
+	* src/smooth/ftgays.c [STANDALONE_]: s/ErrRaster_/Smooth_Err_/.
+	(gray_convert_glyph_inner): Updated accordingly.
+
+	* src/raster/ftraster.c [STANDALONE_]: Do not abbreviate error macros.
+	(New_Profile, End_Profile, Insert_Y_Turn, Line_Up, Bezier_Up,
+	Decompose_Curve, Draw_Sweep, Render_Single_Pass, ft_black_render):
+	Updated accordingly.
+
+2021-06-22  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] s/PaintTransformed/PaintTransform/, s/transformed/transform/.
+
+	* include/freetype/ftcolor.h (FT_PaintTransformed, FT_PaintFormat,
+	FT_COLR_Paint): Do it to make it harmonize with other names such as
+	'PaintTranslate'.
+
+	* src/sfnt/ttcolr.c (read_paint, tt_face_get_paint): Ditto.
+
+2021-06-22  Dominik Röttsches  <drott@chromium.org>
+
+	Move 'COLR' API to `ftcolor.h`.
+
+	* include/freetype/freetype.h: Cut section layer management
+	containing 'COLR' v0 and v1 API and move it to `ftcolor.h` as
+	requested by Werner on freetype-devel.
+	* include/freetype/ftcolor.h: Paste that section.
+
+2021-06-19  Werner Lemberg  <david@freetype.org>
+
+	[truetype] Fix integer overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35312
+
+	* src/truetype/ttinterp.c (Ins_JMPR): Use `ADD_LONG`.
+
+2021-06-19  Werner Lemberg  <david@freetype.org>
+
+	[autofit] Prevent hinting if there are too many segments.
+
+	This speeds up handling of broken glyphs.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35309
+
+	* src/autofit/aflatin.c (af_latin_hints_compute_segments): Implement
+	it.
+
+2021-06-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sdf/ftsdfrend.c (ft_(b)sdf_render): Do not FT_ERROR routinely.
+
+2021-06-16  David Turner  <david@freetype.org>
+
+	[autofit] Fix return value of `FT_Load_Glyph`.
+
+	* src/autofit/afglobal.c (af_face_globals_get_metrics): The issue is
+	that `style_metrics_init` sometimes returns -1 without clearing
+	`error`.  While looping to `Again`, the next operation is
+	successful, but -1 is still returned by the function.  The fix is to
+	set `error` to 0 appropriately.
+
+	Fixes #1063.
+
+2021-06-15  David Turner  <david@freetype.org>
+
+	[meson] Add first regression test to FreeType.
+
+	* tests/README.md: New file that explains how to build and run the
+	tests with the Meson build.
+
+	* tests/scripts/download-test-fonts.sh: New bash script to download
+	test font files to the `tests/data` folder.
+
+	* meson.build, meson_options.txt: Add 'tests' option to enable
+	building and running the test programs (disabled by default).
+
+	* tests/meson.build: New file.
+
+	* tests/issue-1063/main.c: Simple regression test to exhibit issue
+	1063.
+
+	* .gitignore: Ignore the content of the `tests/data` folder for
+	now.
+
+2021-06-12  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[type42] Fix new memory leak.
+
+	We need to inverse inheritance of FT_GlyphSlot_Internal so that we
+	have a chance to free the rendered bitmap from the parent slot.
+
+	* src/type42/t42objs.c (T42_GlyphSlot_Init): Remove the internal parts
+	of the child `ttslot' and replace it with the parent structure.
+	(T42_GlyphSlot_Done): Updated accordingly.
+
+2021-06-12  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix another assertion.
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString)
+	<cf2_escCALLOTHERSUBR>: Convert assertion into error, since the
+	problem can happen with invalid user input.
+
+	Test case is file
+
+	  fuzzing/corpora/legacy/oss-fuzz/5754332360212480-unknown-read
+
+	in the `freetype2-testing` repository.
+
+2021-06-12  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix assertions.
+
+	* src/psaux/pshints.c (cf2_hintmap_adjustHints): Check for overflow
+	before emitting an assertion error.
+
+	Test case is file
+
+	 fuzzing/corpora/legacy/oss-fuzz/4594115297673216-integer-overflow
+
+	in the `freetype2-testing` repository.
+
+2021-06-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttinterp.c (TT_RunIns): Optimize tracing.
+
+2021-06-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sdf] Fix SDF positioning.
+
+	* src/sdf/ftsdfrend.c (ft_sdf_render, ft_bsdf_render): Add padding to
+	`bitmap_top' and `bitmap_left'.
+
+	* sdf/sdf/ftsdf.c (sdf_generate_with_overlaps): Fix VC++ warning.
+
+2021-06-08  Werner Lemberg  <wl@gnu.org>
+
+	Fix 'devel' build for 'COLR' v1.
+
+	* devel/ftoption.h: Synchronize with
+	  `include/freetype/config/ftoption.h`.
+
+2021-06-08  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Sanitize cmap4 table better.
+
+	Fixes #1062.
+
+	* src/sfnt/ttcmap.c (tt_cmap4_validate): Handle a too-small value of
+	`length` gracefully.
+
+2021-06-08  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Pointer validity check when reading 'COLR' v1 layers
+
+	* src/sfnt/ttcolr.c (tt_face_get_paint_layers): In addition to the
+	existing sanity checks, ensure that the pointer to the layer to be
+	read is within the 'COLR' v1 table.
+
+2021-06-08  Werner Lemberg  <wl@gnu.org>
+
+	* src/sdf/ftsdfcommon.c: Fix inclusion of header files.
+
+2021-06-08  Werner Lemberg  <wl@gnu.org>
+
+	[sdf] Make `make multi` work.
+
+	* src/sdf/ftsdf.c: Include `ftbitmap.h`.
+
+	* src/sdf/ftsdfcommon.h: Move function bodies to `ftsdfcommon.c`.
+	Include `ftobjs.h` to get definitions of `FT_LOCAL` and friends.
+
+	* src/sdf/ftsdfcommon.c: New file.
+
+	* src/sdf/rules.mk, src/sdf/sdf.c: Updated.
+
+2021-06-08  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Use 8 bits for final SDF output instead of 16bits.
+
+	Since 8-bits is enough to represent SDF data we no longer require
+	16-bits for this purpose.  Also, we now normalize the output data
+	to use the entire 8-bit range efficiently.  For example: if we use
+	3.5 format with a spread of 1 we basically only use the starting
+	5-bits.  By normalizing we can use the entire 8-bit range.
+
+	* include/freetype/freetype.h (FT_Render_Mode): Updated description
+	for `FT_RENDER_MODE_SDF` regarding this change.
+
+	* include/freetype/ftimage.h (FT_Pixel_Mode): Removed
+	`FT_PIXEL_MODE_GRAY16` since no longer required.
+
+	* include/freetype/fttypes.h (FT_F6Dot10): Removed since no longer
+	required.
+
+	* src/sdf/ftsdfrend.c (ft_sdf_render, ft_bsdf_render): Allocate 8-bit
+	bitmap instead of 16-bit buffer.
+
+	* src/sdf/ftsdfcommon.h (map_fixed_to_sdf): Added function to convert
+	16.16 distance value to our desired format.
+
+	* src/sdf/ftsdf.c (sdf_generate_with_overlaps,
+	sdf_generate_bounding_box): Use the new `map_fixed_to_sdf` function
+	and also use 8-bit output buffer.
+
+	* src/sdf/ftbsdf.c (finalize_sdf): Output to a 8-bit buffer instead
+	of 16-bit buffer.
+
+2021-06-02  Ben Wagner  <bungeman@chromium.org>
+	    Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix fallout from 2021-05-29 change.
+
+	* src/sfnt/ttcolr.c (find_base_glyph_record,
+	find_base_glyph_v1_record): Adjust binary search.
+
+	Needs to be updated with change to unsigned.
+
+2021-06-02  Werner Lemberg  <wl@gnu.org>
+
+	* src/autofit/aflatin.c (af_latin_metrics_scale_dim): Fix tracing.
+
+	Problem reported by Alexei.
+
+2021-06-02  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix MSVC compiler warnings.
+
+	* src/psaux/afmparse.c (afm_parse_track_kern, afm_parse_kern_pairs):
+	Add cast.
+
+2021-05-29  Werner Lemberg  <wl@gnu.org>
+
+	Fix compilation errors and (some) warnings for clang++.
+
+	* src/autofit/afmodule.c (AF_GlyphHintsRec): Make it static.
+
+	* src/cache/ftcache.c (FTC_Cache_NewNode), src/cache/ftcsbits.c
+	(ftc_snode_compare): Remove semicolon.
+
+	* src/cff/cffparse.c (cff_parser_run): Add `break` statement.
+
+	* src/cid/cidload.c (cid_hex_to_binary): Add cast.
+
+	* src/sdf/ftbsdf.c (CHECK_NEIGHBOR): Use `do {} while(0)` loop.
+	(bsdf_init_distance_map, finalize_sdf, bsdf_raster_render): Add
+	casts.
+	* src/sdf/ftsdf.c (sdf_generate_bounding_box,
+	sdf_generate_with_overlaps): Ditto.
+	* src/sdf/ftsdfcommon.h (square_root): Ditto.
+	* src/sdf/ftsdfrend.c (sdf_property_get, ft_sdf_render,
+	ft_bsdf_render): Ditto.
+
+	* src/sfnt/ttcolr.c (find_base_glyph_record,
+	find_base_glyph_v1_record): Fix variable signedness.
+	(read_color_line): Add cast.
+	(read_paint): Add casts.
+	Fix signedness issue.
+	(tt_face_get_colorline_stops) Fix signedness issues.
+
+	* src/sfnt/ttpost.c (load_format_20): Add casts.
+
+	* src/truetype/ttsubpix.c (TWEAK_RULES, TWEAK_RULES_EXCEPTIONS):
+	Remove final semicolons.
+
+2021-05-29  Werner Lemberg  <wl@gnu.org>
+
+	[build] Allow overriding of `ANSIFLAGS` for GNU make build.
+
+	* builds/*: Implement it.
+
+2021-05-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[type42] Fix auto-hinting.
+
+	The autohinter could not access the base (unscaled) outline in the
+	child TrueType glyph slot. We now share the internal parts between
+	the parent and child glyph slots. Fixes #1057.
+
+	* src/type42/t42objs.c (T42_GlyphSlot_Init): Remove the internal parts
+	of `T42_GlyphSlot' and replace it with the child TrueType structure.
+	(T42_GlyphSlot_Done): Updated accordingly.
+
+2021-05-25  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Guard and trace AFM kern data allocation.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=31543
+
+	* include/freetype/internal/fttrace.h: Add 'afmparse' trace
+	component.
+
+	* src/psaux/afmparse.c (FT_COMPONENT): Define.
+	(afm_parse_track_kern, afm_parse_kern_pairs): Protect against
+	allocations bombs.
+	Add tracing.
+	(afm_parse_kern_data): Don't allow multiple kern data sections.
+
+2021-05-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* meson.build (ft2_public_headers): Add missing `ftcid.h'.
+
+	Fixes #1058.
+
+2021-05-20  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[type42] Avoid some memory zeroing.
+
+	* src/type42/t42objs.c (T42_Open_Face): Tweak allocation macro.
+	* src/type42/t42parse.c (t42_parse_sfnts): Ditto.
+
+2021-05-19  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	[CMake] Update dependency finders.
+
+	1. Fixes CMake using any found HarfBuzz version lower than the minimum
+	required. This is based on HALX99's merge request at
+	https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests/31
+	2. Update FindHarfBuzz.cmake from
+	https://github.com/WebKit/WebKit/blob/1ce32454/Source/cmake/FindHarfBuzz.cmake
+	and guard post-CMake-3.1 features to keep the minimum version unchanged
+	3. Update FindBrotliDec.cmake to stop the warnings, based on what
+	https://github.com/google/woff2/blob/a0d0ed7d/cmake/FindBrotliDec.cmake
+	is doing
+
+	* CMakeLists.txt, builds/cmake/FindHarfBuzz.cmake: Implement 1 and 2.
+	* builds/cmake/FindBrotliDec.cmake: Implement 3.
+
+2021-05-19  Ben Wagner  <bungeman@chromium.org>
+
+	[gzip] Use exact type for `ft_gzip_alloc` and `ft_gzip_free`.
+
+	While a function pointer may be cast to another function pointer
+	type, it is required to cast the function pointer back to the
+	original function pointer type before calling it.  If a parameter is
+	a pointer the exact pointer type is required.  Using a pointer to a
+	different underlying type is technically undefined behavior.  The
+	wrapper functions `ft_gzip_alloc` and `ft_gzip_free` took
+	`FT_Memory` (a `FT_MemoryRec_*`) instead of `voidpf` (`void*`), so
+	when gzip calls these callbacks through `alloc_func` or `free_func`
+	it invokes undefined behavior.  On most platforms this works out as
+	expected, but newer undefined behavior detectors and targets like
+	wasm can detect this and will produce an error.
+
+	* src/gzip/ftgzip.c (ft_gzip_alloc, ft_gzip_free): Update signatures
+	to exactly match `alloc_func` and `free_func`, respectively.
+	Internally, cast the `void*` opaque pointer to `FT_Memory`.
+
+2021-05-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Prioritize the anti-aliasing renderer module.
+
+	* modules.cfg: Reorder the renderers.
+	* include/freetype/config/ftmodule.h: Ditto.
+
+2021-05-16  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sfnt] Additional guards on the POST table.
+
+	Fixes timeout (#1055) analyzed by Ben Wagner, reported as
+
+	  https://crbug.com/1194092
+
+	* src/sfnt/ttload.c (tt_face_load_post): Check POST format.
+	* src/sfnt/sfobjs.c (sfnt_load_face): Synthesize the missing unicode
+	charmap only if the glyph names exist.
+	* src/psnames/psmodule.c (ps_unicode_value): Short cut ".notdef" and
+	".null".
+
+2021-05-13  Daniel McArdle  <dmcardle@chromium.org>
+
+	[psaux] Use doubling allocation strategy for CF2_ArrStack.
+
+	Fixes timeout reported as
+
+	  https://crbug.com/1206181
+
+	* src/psaux/psarrst.c (cf2_arrstack_{push,init}): Implement it.
+	* src/psaux/psarrst.h (CF2_ArrStackiRec): Drop `chunk'.
+
+2021-05-12  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (FT_MAX_GRAY_SPANS): Increase from 10 to 16.
+
+	Ten was barely enough for two slanted stems. Sixteen can actually fit
+	a bit more complicated scanlines.
+
+2021-05-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (FT_GRAY_SET): Adjust for better code.
+
+2021-05-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Faster bitmap sweeping.
+
+	Selecting the fill rule or checking the direct mode each time we call
+	`gray_hline' is sub-optimal.  This effectively splits the direct mode
+	into a separate code path while inlining `gray_hline' and saving 5-7%
+	of rendering time.
+
+	* src/smooth/ftgrays.c (gray_hline): Eliminated in favor of...
+	(FT_FILL_RULE, FT_GRAY_SET): ... these new macros...
+	(gray_sweep): ... inlined here.
+	(gray_sweep_direct): New function that handles the direct span buffer.
+	(gray_TWorker): Remove the span buffer.
+	(gray_raster_render, gray_convert_glyph): Updated.
+
+2021-05-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (gray_hline): Simplify even-odd computations.
+
+	It is too bad the even-odd rule is not used much.
+
+2021-05-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[type1] Avoid MM memory zeroing.
+
+	* src/type1/t1load.c (t1_allocate_blend, parse_blend_design_map):
+	Tweak allocation macros.
+	* src/type1/t1objs.c (T1_Face_Done): Minor.
+
+2021-05-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/bdf/bdflib.c (_bdf_list_ensure): Tweak allocation macro.
+
+2021-05-06  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/psaux/psobjs.c (ps_parser_load_field): Tweak allocation macro.
+
+2021-05-06  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/sfobjs.c (sfnt_load_face): Tweak allocation macro.
+
+2021-05-06  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/cid/cidload.c (cid_read_subrs): Tweak allocation macro.
+
+2021-05-06  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Tweak allocation.
+
+2021-05-05  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cff,psaux] Avoid memory zeroing (contd.).
+
+	* src/cff/cffload.c (cff_blend_doBlend, cff_blend_build_vector): Tweak
+	allocation macros.
+	* src/psaux/psarrst.c (cf2_arrstack_setNumElements): Ditto.
+	* src/psaux/psstack.c (cf2_stack_init): Ditto.
+
+2021-05-04  Ben Wagner  <bungeman@chromium.org>
+
+	* src/cid/cidload.c (cid_hex_to_binary): Improve return value.
+
+	Add argument to return the actual number of bytes that were decoded.
+	The actual number of bytes decoded can be quite variable depending
+	on the number of ignored 'whitespace' bytes or early termination
+	with `>`.
+	(cid_face_open): Updated to use this calculated value.  This avoids
+	trusting `parser->binary_length` is always be correct and reading
+	uninitialized bits if fewer are actually decoded.
+
+	First reported as
+
+	  https://crbug.com/1203240
+
+2021-05-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sfnt] Streamline POST format 2.0 handing.
+
+	To reduce memory allocations, we read an entire Pascal-string buffer
+	and convert it to a C-string buffer.  We also reject tables with
+	Postscript glyph names exceeding 63 bytes.
+
+	* src/sfnt/ttpost.c (load_format20): Implement it.
+	(load_post_names): Check the minimal POST table size.
+	(load_format25, tt_face_free_ps_names): Updated accordingly.
+
+2021-05-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf,pcf] Avoid memory zeroing (contd.).
+
+	* src/bdf/bdflib.c (bdf_create_property, _bdf_add_comment,
+	_bdf_add_property, bdf_load_font): Tweak allocation macros.
+	* src/pcf/pcfread.c (pcf_get_properties, pcf_get_metrics): Ditto.
+
+2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/cid/cidload.c (cid_read_subrs): Tweak allocation macro.
+
+2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sfnt] Avoid some memory zeroing.
+
+	* src/sfnt/sfobjs.c (sfnt_open_font, sfnt_init_face,
+	tt_name_ascii_from_{utf16,other}): Tweak allocation macros.
+	* src/sfnt/ttload.c (tt_face_load_name): Ditto.
+
+2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/ttpost.c (load_format_{20,25}): Tweak allocation macros.
+
+2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/pngshim.c (Load_SBit_Png): Tweak allocation macro.
+
+2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[truetype] Avoid some memory zeroing.
+
+	* src/truetype/ttinterp.c (Init_Context): Tweak allocation macro.
+	* src/truetype/ttpload.c (tt_face_load_cvt): Ditto.
+
+2021-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[woff2] Avoid some memory zeroing.
+
+	* src/sfnt/sfwoff2.c (store_loca, woff2_open_font): Tweak macros.
+
+2021-04-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/gzip/ftgzip.c (ft_gzip_alloc): Zero out memory again.
+
+2021-04-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[lzw] Preserve decompression stack when relocating to heap.
+
+	* src/lzw/ftzopen.c (ft_lzwstate_stack_grow): Copy stack when
+	relocating to heap.
+
+2021-04-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/cid/cidgload.c (cid_load_glyph): Restore the glyph_length check.
+
+2021-04-27  Werner Lemberg  <wl@gnu.org>
+
+	* src/psmodule.c (ps_unicodes_init): Ignore empty glyph names.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33637
+
+2021-04-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/sfobjs.c (sfnt_init_face): Revert macro change.
+
+2021-04-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cff] Avoid some memory zeroing.
+
+	* src/cff/cffparse.c (cff_parser_init): Tweak memory macro.
+	* src/cff/cffload.c (cff_index_load_offsets, cff_index_get_pointers,
+	cff_charset_load, cff_vstore_load): Ditto.
+
+2021-04-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pfr] Avoid some memory zeroing.
+
+	* src/pfr/pfrobjs.c (pfr_face_init) : Tweak memory macro.
+	* src/pfr/pfrload.c (pfr_extra_item_load_stem_snaps,
+	pfr_phy_font_load): Ditto.
+
+2021-04-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/winfonts/winfnt.c (FNT_Face_Init): Tweak memory macro.
+
+2021-04-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[psaux,psnames] Avoid some memory zeroing.
+
+	* src/psaux/psstack.c (cf2_stack_init): Tweak memory macro.
+	* src/psnames/psmodule.c (ps_unicodes_init): Ditto.
+
+2021-04-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] Avoid some memory zeroing.
+
+	* src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Use FT_QNEW_ARRAY.
+	* src/base/ftsnames.c (FT_Get_Sfnt_{Name,LangTag}): Ditto.
+
+2021-04-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf,pcf] Avoid some memory zeroing.
+
+	* src/pcf/pcfread.c (pcf_read_TOC, pcf_get_properties, pcf_load_font):
+	Tweak memory macros.
+	* src/bdf/bdfdrivr.c (BDF_Face_Init): Ditto.
+	* src/bdf/bdflib.c (_bdf_readstreami, bdf_create_property,
+	_bdf_parse_glyphs, _bdf_parse_start): Ditto.
+	(_bdf_add_property): Do not handle zero size.
+
+2021-04-25  Issam E. Maghni  <issam.e.maghni@mailbox.org>
+
+	* builds/meson/process_ftoption_h.py: Add LF at EOF.
+
+	This fixes
+
+	  .../ftoption.h:1030:10: error:
+	    no newline at end of file [-Werror,-Wnewline-eof]
+
+	for the generated `ftoption.h` file.
+
+2021-04-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/cff/cffload.c (cff_index_get_pointers): s/FT_QALLOC/FT_ALLOC/.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (Mac_Read_POST_Resource): s/FT_ALLOC/FT_QALLOC/.
+	* builds/mac/ftmac.c (FT_New_Face_From_SFNT, read_lwfn): Ditto.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sdf/ftsdf.c (sdf_{edge,contour,shape}_new): Use FT_QALLOC.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sfnt] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/sfnt/sfdriver.c (get_win_string, get_apple_string,
+	sfnt_get_var_ps_name): Do not zero out the buffer.
+	* src/sfnt/sfobjs.c (sfnt_init_face): Ditto.
+	* src/sfnt/sfwoff.c (woff_open_font): Ditto.
+	* src/sfnt/sfwoff2.c (woff2_open_font): Ditto.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cff,type1,type42] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/cff/cffload.c (cff_index_get_pointers, cff_index_get_name):
+	Do not zero out the buffer.
+	* src/cff/cffdrivr.c (cff_ps_get_font_info): Ditto.
+	* src/type1/t1load.c (parse_subrs, parse_charstrings,
+	parse_blend_axis_types): Ditto.
+	* src/type1/t1parse.c (T1_New_Parser, T1_Get_Private_Dict): Ditto.
+	* src/type42/t42parse.c (t42_parser_init): Ditto.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cid] s/FT_ALLOC/FT_QALLOC/ and clean up.
+
+	* src/cid/cidgload.c (cid_load_glyph): Do not zero out the buffer.
+	* src/cid/cidload.c (cid_face_open, cid_read_subrs): Ditto.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pfr] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/pfr/pfrload.c (pfr_extra_item_load_font_id, pfr_aux_name_load):
+	Do not zero out the buffer.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bzip2,gzip] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/bzip2/ftbzip2.c (ft_bzip2_alloc): Do not zero out the buffer.
+	* src/gzip/ftgzip.c (ft_gzip_alloc, FT_Stream_OpenGzip): Ditto.
+
+2021-04-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf,bdf,winfonts] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/pcf/pcfread.c (pcf_interpret_style): Do not zero out the buffer.
+	* src/bdf/bdfdrivr.c (bdf_interpret_style): Ditto.
+	* src/winfonts/winfnt.c (FNT_Face_Init, FNT_Load_Glyph): Ditto.
+
+2021-04-22  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cache] Optimize SBit copying.
+
+	* src/cache/ftcsbits.c (ftc_snode_load): Do not initialize the buffer.
+	(ftc_sbit_copy_bitmap): Accept zero size, s/FT_ALLOC/FT_QALLOC/.
+
+2021-04-22  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[gxvalid,otvalid] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/gxvalid/gxvmod.c (gxv_load_table): Do not zero out the buffer.
+	* src/otvalid/otvmod.c (otv_load_table): Ditto.
+
+2021-04-22  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[psaux] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/psaux/psobjs.c (ps_table_done, ps_parser_load_field): Do not
+	zero out the buffer.
+
+2021-04-22  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] s/FT_ALLOC/FT_QALLOC/ for initialized buffers.
+
+	* src/base/ftobjs.c (open_face_PS_from_sfnt_stream,
+	Mac_Read_sfnt_Resource): Do not zero out the buffer.
+	* src/base/ftmac.c (FT_New_Face_From_SFNT, read_lwfn): Ditto.
+	* src/base/ftrfork.c (raccess_make_file_name,
+	raccess_guess_darwin_hfsplus, raccess_guess_darwin_newvfs): Ditto.
+
+2021-04-20  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cache] Restore SBit copying for unowned (BDF) bitmaps.
+
+	* src/cache/ftcsbits.c (ftc_sbit_copy_bitmap): Restore.
+	(ftc_snode_load): Check ownership and copy unowned bitmaps.
+
+2021-04-19  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Return in 'COLR' v1 when layer pointer outside table
+
+	* src/sfnt/ttcolr.c (tt_face_get_paint_layers): Add missing return
+	when paint pointer outside table.
+	(read_paint): Add missing return when paint pointer outside table.
+
+2021-04-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cache] Switch to lazy SBit setting.
+
+	* src/cache/ftcsbits.c (ftc_sbit_copy_bitmap): Removed.
+	(ftc_snode_load): Take the bitmap ownership instead of copying.
+
+2021-04-16  Daniel Welty  <@danielwelty>
+
+	* src/cache/ftcsbits.c (ftc_snode_load): Properly handle short pitch.
+
+2021-04-16  Werner Lemberg  <wl@gnu.org>
+
+	* builds/unix/freetype2.m4: Fix help string formatting.
+
+	The indented `dnl` macros inserted unwanted horizontal space.
+
+	Problem reported by Ozkan Sezer <sezeroz@gmail.com>.
+
+2021-04-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Safeguard 'COLR' v1 layer extraction
+
+	* src/sfnt/ttcolr.c (tt_face_get_paint_layers): Do not output
+	layer pointer to iterator if it is outside the 'COLR' table.
+	(read_paint): Do not attempt to read layers that are outside the
+	table.
+
+2021-04-02  Ben Wagner  <bungeman@chromium.org>
+
+	[base] Complete `ft_glyphslot_clear`.
+
+	* src/base/ftobjs.c (ft_glyphslot_clear): This function is intended
+	to reset all the values of a glyph slot.  However, it was not
+	resetting the values of the advances and `glyph_index`.  Reset the
+	advances and `glyph_index` to zero.
+
+2021-04-02  Ben Wagner  <bungeman@chromium.org>
+
+	[truetype] Prevent glyph program state from persisting.
+
+	`FDEF` instructions are specified as allowed only in 'prep' or
+	'fpgm'.  FreeType has attempted to prevent their use in the glyph
+	program, but they were still allowed in glyph programs if defined in
+	a function defined in 'prep' or 'fpgm' and called from the glyph
+	program.
+
+	Similarly, `IDEF` instructions are specified not to be able to
+	modify any existing instruction.  FreeType has attempted to prevent
+	their use in the glyph program, but they can still be used like
+	`FDEF`.
+
+	This change stores the initial bytecode range type and disallows the
+	use of `FDEF` and `IDEF` while running the glyph program.
+
+	Most other state is copied from the `TT_Size` into the execution
+	context.  However, it is possible for a glyph program to use `WS` to
+	write to the storage area or `WCVTP`, `WCVTF`, and `DELTAC[123]` to
+	write to the control value table.
+
+	Allowing any change to the global state from the glyph program is
+	problematic as the outlines of any given glyph may change based on
+	the order the glyphs are loaded or even how many times they are
+	loaded.  There exist fonts that write to the storage area or the
+	control value table in the glyph program, so their use should not be
+	an error.
+
+	Possible solutions to using these in the glyph program are
+
+	  * ignore the writes;
+	  * value-level copy on write, discard modified values when finished;
+	  * array-level copy on write, discard the copy when finished;
+	  * array-level copy up-front.
+
+	Ignoring the writes may break otherwise good uses.  A full copy
+	up-front was implemented, but was quite heavy as even well behaved
+	fonts required a full copy and the memory management that goes along
+	with it.  Value-level copy on write could use less memory but
+	requires a great deal more record keeping and complexity.  This
+	change implements array-level copy on write.  If any attempt is made
+	to write to the control value table or the storage area when the
+	initial bytecode range was in a glyph program, the relevant array
+	will be copied to a designated storage area and the copy used for
+	the rest of the glyph program's execution.
+
+	* src/truetype/ttinterp.h (TT_ExecContextRec): New fields
+	`iniRange`, `glyfCvtSize`, `glyfCvt`, `origCvt`, `glyfStoreSize`,
+	`glyfStorage`, and `origStorage`.
+
+	* src/truetype/ttinterp.c (Modify_CVT_Check): New function to handle
+	`exc->glyfCvt`.
+	(Write_CVT, Write_CVT_Stretched, Move_CVT, Move_CVT_Stretched): Use
+	it.
+	(Ins_WS): Handle `exc->glyfStorage`.
+	(Ins_FDEF, Ins_IDEF): Updated.
+	(TT_RunIns): Updated.
+	(TT_Done_Context): Free 'glyf' CVT working and storage area.
+	(TT_Load_Context): Fix/add casts.
+
+	* src/truetype/ttgload.c (TT_Load_Simple_Glyph): Fix cast.
+
+2021-03-30  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Check validity of pointer location of `read_color_line`.
+
+	* src/sfnt/ttcolr.c (get_child_table_pointer): New function to fetch
+	child table pointer early for all paint formats that compute a child
+	table pointer.
+	(read_color_line, read_paint): Updated.
+	(tt_face_get_colorline_stops): Check `colr->table`.
+
+2021-03-28  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[docs] Update docwriter stylesheet for 1.3.1.
+
+	This change is required to support docwriter 1.3.1.
+
+	See
+
+	  https://gitlab.freedesktop.org/freetype/docwriter/-/merge_requests/101
+
+	for more information.
+
+	* docs/markdown/stylesheets/extra.css:
+	(.wy-nav-content, .md-sidebar--secondary): Remove.
+
+2021-03-16  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/pngshim.c (Load_SBit_Png): Free `rows` once later.
+
+2021-03-16  Ben Wagner  <bungeman@google.com>
+
+	[sfnt] Fix memory leak in png loading.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/chromium/issues/detail?id=1182552
+
+	Memory is allocated and the pointer assigned to `rows` inside a
+	'setjmp' scope.  This memory must be freed outside the 'setjmp'
+	scope after a 'longjmp'.  Since `rows` is a local and modified
+	inside the 'setjmp' scope it must be marked volatile or it will have
+	an indeterminate value after the 'longjmp'.
+
+	* src/sfnt/pngshim.c (Load_SBit_Png): Fix memory leak of `rows`.
+
+2021-03-16  Christopher Degawa  <ccom@randomderp.com>
+
+	* CMakeLists.txt: Don't limit generation of 'pkg-config' file to UNIX.
+
+	mingw-w64 uses the 'pkg-config' files but does not set UNIX.
+
+2021-03-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (gray_set_cell): Refactor to fix VC++ warning.
+
+2021-03-13  Werner Lemberg  <wl@gnu.org>
+
+	Handle various VC++ compiler warnings.
+
+	Fixes #1039.
+
+	* src/base/ftstroke.c (ft_stroker_inside, ft_stroker_outside):
+	Initialize `sigma`.
+
+	* src/sdf/ftsdf.c (sdf_generate_with_overlaps): Exit immediately if
+	function arguments are invalid.
+	* src/sdf/ftsdfrend.c (sdf_property_set) <"overlaps">: Fix cast.
+
+	* src/sfnt/sfwoff2.c (woff2_decompress)
+	[!FT_CONFIG_OPTION_USE_BROTLI]: Use `FT_UNUSED`.
+
+	* src/truetype/ttgxvar.c (TT_Get_MM_Var): Initialize `fvar_head`.
+
+2021-03-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Reduce copying during integration phase.
+
+	We now record `cover' and `area' directly into the linked list. This
+	makes rendering faster by 10% or even more at larger sizes.
+
+	* src/smooth/ftgrays.c (FT_INTEGRATE): Write directly.
+	(gray_TWorker): Add direct cell reference and remove unused fields.
+	(gray_set_cell): Consolidate the linked list management and pointers.
+	(gray_convert_glyph, gray_convert_glyph_inner): Updated.
+
+2021-03-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (FT_INTEGRATE): New convenience macro.
+	(gray_render_line, gray_render_scanline): Use it.
+
+2021-03-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (gray_render_line): Rearrange conditionals.
+
+	These produce faster or more optimizable code.
+
+2021-03-08  Tim-Philipp Müller  <tim@centricular.com>
+
+	[meson] Fix 'mmap' handling on Windows.
+
+	* meson.build (ft2_sources): Always use `windows/ftsystem.c` on
+	Windows unless mmap has been disabled.
+
+	  https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests/5#note_829289
+
+2021-03-07  Tim-Philipp Müller  <tim@centricular.com>
+
+	[ci] Add basic support for Meson builds with MSVC on Windows.
+
+	This adds meson jobs for VS2017 (x86 and x86_64).
+
+	* .gitlab-ci.yml: New file.
+
+2021-03-07  Tim-Philipp Müller  <tim@centricular.com>
+
+	[meson] Add subproject fallbacks for 'libpng' and 'zlib'.
+
+	* subprojects/libpng.wrap, subprojects/zlib.wrap: New files.
+
+	* meson.build: Updated.
+
+2021-03-07  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	[meson] Make it work with Windows.
+
+	* meson.build: Do not process `ftconfig.h` when not using
+	`ftconfig.h.in`.
+
+	Fixes #1029.
+
+2021-02-25  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix memory leak.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28148
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Reject fonts that have
+	multiple tables with the same tag.  While not explicitly forbidden
+	in the OpenType specification, it is implicitly forbidden by
+	describing a binary search algorithm for tables that only works
+	reliably if table tags are unique.
+
+2021-02-22  Werner Lemberg  <wl@gnu.org>
+
+	* CMakeLists.txt: Update location of `LICENSE.TXT`.
+
+	Fixes #1035.
+
+2021-02-19  Werner Lemberg  <wl@gnu.org>
+
+	* builds/unix/ax_pthread.m4: Update from 'autoconf-archive'.
+
+	A bunch of fixes were added recently to its git repository.
+
+2021-02-17  Werner Lemberg  <wl@gnu.org>
+
+	[unix] Updates for autoconf 2.71.
+
+	This fixes warnings reported by autoupdate.
+
+	* builds/unix/ax_pthread.m4: Replace `as_echo` with `AS_ECHO`.
+
+	* builds/unix/configure.raw: Remove obsolete `AC_HEADER_STDC`.
+	Don't escape back quotes in messages for `AC_MSG_WARN`.
+
+2021-02-16  Werner Lemberg  <wl@gnu.org>
+
+	* builds/toplevel.mk: Fix previous commit.
+
+	<top_level>: Use `TOP_DIR` in `wildcard` function.
+	(check_out_submodule, copy_submodule): Move down to come after
+	definition of `all` rule.
+	Call `mkdir` conditionally.
+
+2021-02-16  Werner Lemberg  <wl@gnu.org>
+
+	* builds/toplevel.mk: Use rules for handling 'dlg'.
+
+	Suggested by Alexei.
+
+	(check_out_submodule, copy_submodule): New targets.
+	<top-level>: Replace calls to `shell` with rules.
+
+2021-02-16  Werner Lemberg  <wl@gnu.org>
+
+	* builds/toplevel.mk: Avoid side effects of `shell`.
+
+	We use a dummy variable to catch its output.  Otherwise the `make`
+	program is going to interpret the return value of `shell`; this can
+	cause obscure warning or error messages or even be harmful.
+
+2021-02-16  Werner Lemberg  <wl@gnu.org>
+
+	Move 'dlg' submodule to `subprojects` directory.
+
+	This is for future changes with Meson, which doesn't allow a
+	different name for its `subprojects` directory.  Having both a
+	`submodules` and a `subprojects` directory is confusing.
+
+	* .gitmodules, autogen.sh (copy_submodule_files, DLG_INC_DIR,
+	DLG_SRC_DIR): Updated.
+
+	* builds/toplevel.mk (<top-level>, do-dist),
+	builds/windows/vc2010/script.bat: Updated.
+
+	* src/tools/no-copyright: Updated.
+
+2021-02-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Update paint format values to support non-variable paints.
+
+	* freetype.h (FT_PaintFormat): Update paint format identifiers after
+	a specification change.  The specification was updated to have
+	sibling formats, variable and non-variable variants for each.
+	Reflect that here.
+
+	* sfnt/ttcolr.c (read_paint): Remove parsing of variable indices as
+	the non-variable formats no longer have them.
+
+2021-02-15  Daniel E  <daniel.engberg.lists@pyret.net>
+
+	* CMakeLists.txt: Improve 'bz2' support.
+
+	Not all distributions such as FreeBSD provide a `.pc` file for
+	'(lib)bz2' so follow autotools and add it to `Libs.private` instead.
+
+2021-02-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/tools/update-copyright-year: Fix single-year entry handling.
+
+	The fix from 2021-01-17 didn't cover the case where the year to be
+	updated is identical to the current year.
+
+2021-02-13  Werner Lemberg  <wl@gnu.org>
+
+	Add new function `FT_Get_Transform`.
+
+	See
+
+	  https://github.com/harfbuzz/harfbuzz/issues/2428
+
+	for some reasons to introduce this function.
+
+	* include/freetype/freetype.h, src/base/ftobjs.c (FT_Get_Transform):
+	Implement it.
+
+2021-02-12  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Decorate `qsort` callbacks with `cdecl`.
+
+	* include/freetype/internal/compiler-macros.h (FT_COMPARE_DEF):
+	Add new macro.
+
+	* src/base/ftrfork.c, src/bdf/bdflib.c, src/gxvalid/gxvcommn.c,
+	src/psaux/afmparse.c, src/psnames/psmodule.c, src/type1/t1afm.c,
+	src/sfnt/sfwoff.c, src/sfnt/sfwoff2.c: Update `qsort` callbacks.
+
+	Fixes #1026 when compiling FreeType with an unusual calling
+	convention while the C library function `qsort` still expects
+	`cdecl`.
+
+2021-02-10  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Implement 'COLR' v1 sweep gradients.
+
+	* freetype.h (FT_PaintSweepGradient): Add `FT_PaintSweepGradient` to
+	represent a 'COLR' v1 sweep gradient.
+	Update format.
+	(FT_PaintFormat): Update shifted paint formats.
+	Sync with spec.
+	* sfnt/ttcolr.c (read_paint): Logic to parse sweep gradients.
+	Fix struct access in radial gradient implementation.
+
+2021-02-09  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Provide optional root transform for 'COLR' v1 glyph graph.
+
+	* include/freetype/freetype.h (FT_Get_Color_Glyph_Paint):
+	Additional function argument `root_transform` to control whether
+	root transform should be returned.
+	(FT_OpaquePaint): Additional tracking field to denote whether
+	root transform is to be returned.
+	* include/freetype/internal/sfnt.h
+	(TT_Get_Color_Glyph_Paint_Func): Propagate additional argument.
+	* src/base/ftobjs.c (FT_Get_Color_Glyph_Paint): Ditto.
+	* src/sfnt/ttcolr.c (tt_face_get_colr_glyph_paint): Return root
+	transform reflecting the size and tranform configured on
+	`FT_Face`.
+	(read_paint): Initialize and track status of insert_root_transform
+	flag.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	* meson.build: s/freetype2_dep/freetype_dep/.
+
+	Many projects (e.g., fontconfig, cairo) hardcode the `freetype_dep`
+	variable name to use FreeType as subproject because that was the
+	variable name in Centricular's Meson port of FreeType.  While they
+	should stop hardcoding that variable name, it does not cost us
+	anything to keep using that name to ease transition.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	[meson] Fix handling of HarfBuzz library.
+
+	* meson.build (harfbuzz_dep): Do not fall back to HarfBuzz by
+	default.
+
+	Otherwise it causes a dependency cycle:
+
+	  cairo => fontconfig => freetype2 => harfbuzz => cairo
+
+	Meson will still fall back to HarfBuzz subprojects if the `harfbuzz`
+	option is set to `enabled` instead of `auto` and a
+	`subprojects/harfbuzz.wrap` file is present.  In that case it is the
+	responsibility of the main project to set the proper options on each
+	subproject to break the dependency cycle.
+
+	Fixes: #1028.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	[meson] Fix dependency lookup and generate `ftconfig.h`.
+
+	- zlib: If not found on the system, meson can build it as a
+	  subproject.  We thus never use the (outdated) zlib support that
+	  comes with FreeType.  Doing so has the additional advantage that
+	  the zlib code can be shared with other projects like GLib if both
+	  are subprojects of an application.
+	- harfbuzz: Build as a subproject if not found on the system.
+	- 'QUESTION: What if the compiler doesn't support `-D` but uses `/D`
+	  instead as on Windows?'  Answer: Meson translate arguments for us.
+	- visibility: Replace self-made code with meson-specific solution.
+
+	* meson.build (ft2_defines): Rewrite logic to set and handle it.
+	(process_header_command): New variable, previously called
+	`ftoption_command`.
+	(ftoption_command, ftconfig_command): New variables.
+	(zlib_option): Removed.
+	(zlib_dep): New variable.
+	(ft2_deps): Updated.
+	(harfbuzz_dep): Updated.
+	(ftconfig_h_in, ftconfig_h): New variables.
+	(ft2_sources): Updated.
+	(ft2_lib): Updated, handle visibility.
+	(summary): Updted.
+
+	* meson_options.txt (zlib): Updated.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	* meson.build: Fix resource compilation on Windows.
+
+	This is copied from GStreamer's meson port of FreeType.
+
+	(ft2_sources): Add both debug and resource file (the latter for
+	Windows only).
+	(ft2_debug_src): Removed.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	* meson.build: s/ft2_libtool_version/ft2_pkgconfig_version/.
+
+	(freetype2_dep): Use it.
+
+	`ft2_libtool_version` would be the shared library version, not the
+	one we should use in file `freetype2.pc`.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	* meson.build: Use `meson.override_dependency`.
+
+	This is a new meson mechanism to avoid other projects to hard-code
+	the `freetype2_dep` variable name in their build definition.  It
+	also ensures that meson does not mix system and subproject versions
+	of FreeType inside of the same project.
+
+	Also remove outdated TODO because `declare_dependency` was already
+	there.
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	* meson.build (bzip2_dep): Simplify.
+
+	We remove `static:false` from `find_library('bz2')`.
+
+	I don't know whether the previous code was a workaround for an old
+	meson bug, but at least with version >=0.55.0 (which FreeType uses)
+	it picks the shared library when both are available.
+
+	File `freetype2.pc` still contains the full path to file `libbz2.so`
+	instead of `-lbz2` – that we need to do this is a meson bug even
+	present in the current version (0.57.0).
+
+2021-02-09  Xavier Claessens  <xavier.claessens@collabora.com>
+
+	* meson.build: Set project version.
+
+2021-02-04  Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix Netpbm tracing message.
+
+	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Don't emit Netpbm
+	warning if there is nothing to output.
+
+2021-02-04  Werner Lemberg  <wl@gnu.org>
+
+	* src/*: Don't use more than one '\n' in `FT_TRACE` and `FT_ERROR`.
+
+	This ensures good logging output, with all lines having a proper
+	prefix (if requested).
+
+	This is a continuation of a similar patch from 2020-12-02, which
+	missed some locations.
+
+2021-02-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/unix/configure.raw [mmap]: Restore default path.
+
+	Fixes #1023.
+
+2021-02-03  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix integer overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30154
+
+	* src/psaux/psblues.c (cf2_blues_capture): Use `SUB_INT32`.
+
+2021-02-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/unix/configure.raw [mmap support]: Explicitly handle Windows.
+
+	Fixes #1024.
+
+2021-01-31  Werner Lemberg  <wl@gnu.org>
+
+	* builds/unix/configure.raw [mmap support]: Correctly handle Windows.
+
+	Fixes #1024.
+
+2021-01-31  Werner Lemberg  <wl@gnu.org>
+
+	* builds/windows/ftdebug.c: Synchronize with `src/base/ftdebug.c`.
+
+2021-01-31  Werner Lemberg  <wl@gnu.org>
+
+	Always provide logging API.
+
+	It's easier to have stubs if FT_DEBUG_LOGGING is undefined than to
+	modify `ftexport.sym` conditionally.
+
+	Problem reported by Alexei.
+
+	* src/base/ftdebug.c: Include `ftlogging.h`.
+	(FT_Trace_Set_Level, FT_Trace_Set_Default_Level, FT_Set_Log_Handler,
+	FT_Set_Default_Log_Handler) [!FT_DEBUG_LOGGING]: Provide stubs.
+
+2021-01-31  Werner Lemberg  <wl@gnu.org>
+
+	* builds/unix/configure.raw: Fix typo.
+
+	Bug introduced in Vincent's last commit bb33f03.
+
+	Fixes issue #1021.
+
+2021-01-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftstroke.c (FT_Stroker_EndSubPath): Ignore tiny gaps.
+
+	Fixes bug #1020.
+
+2021-01-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[stroker] Minor clean-up.
+
+	* src/base/ftstroke.c (FT_Stroker_{ConicTo,CubicTo}): Reset the last
+	line length.
+	(FT_Stroker_EndSubPath): Call `ft_stroker_process_corner'.
+
+2021-01-27  Vincent Torri  <vincent.torri@gmail.com>
+
+	* builds/windows/ftsystem.c: Add shared memory support on Windows.
+
+	* CMakeLists.txt (BASE_SRCS), builds/unix/configure.raw (FTSYS_SRC),
+	builds/windows/vc2010/freetype.vcxproj,
+	builds/windows/visualc/freetype.vcproj, meson.build (ft2_sources):
+	Add it (conditionally).
+
+2021-01-23  Werner Lemberg  <wl@gnu.org>
+
+	Require HarfBuzz 2.0.0.
+
+	This is needed to make commit f1f9705f9 work.
+
+	* CMakeLists.txt (HARFBUZZ_MIN_VERSION), builds/unix/configure.raw
+	(harfbuzz_pkg), meson.build (harfbuzz_dep): Updated.
+
+2021-01-22  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* autogen.sh: Absorb `version.sed'.
+	* version.sed: Removed.
+
+2021-01-19  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* srd/base/ftlcdfil.c (FT_Library_SetLcdGeometry): Fix return value.
+
+2021-01-15  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	[afshaper] Fix hb_ot_tags_from_script deprecation warning.
+
+	* autofit/afshaper.c (af_shaper_get_coverage): Copy the source code
+	of the function as suggested in
+	https://github.com/harfbuzz/harfbuzz/issues/2737 and adjust to handle
+	at most three tags.
+
+2021-01-17  Werner Lemberg  <wl@gnu.org>
+
+	* src/tools/update-copyright-year: Fix single-year entry handling.
+
+2021-01-16  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/unix/unixddef.mk: Remove the second DEVEL_DIR definition.
+
+2021-01-14  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Additional checks for 'colr' table presence.
+
+	* sfnt/ttcolr.c (tt_face_get_colr_glyph_paint,
+	tt_face_get_colorline_stops, tt_face_get_paint): Additional checks
+	for whether colr table is present.  Prevents crashes when these
+	methods are called on non-COLR fonts.
+
+2021-01-13  Dominik Röttsches  <drott@chromium.org>
+
+	Add config option to test for 'COLR' v1 support in headers.
+
+	* include/freetype/config/ftoption.h (TT_SUPPORT_COLRV1): New macro
+	so that clients can test whether the FreeType checkout that they are
+	building against supports the 'COLR' v1 API.  This is intended to be
+	a temporary solution until 'COLR' v1 support is released in a
+	FreeType version and such a check can be made by using the version
+	number instead.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	[base] Fill 'COLR' v1 API templates to make them work (#59703).
+
+	* src/base/ftobjs.c (FT_Get_Color_Glyph_Paint, FT_Get_Paint_Layers,
+	FT_Get_Paint, FT_Get_Colorline_Stops): Add basic sanity checks,
+	check for existence of `FT_Face`, check arguments and delegate calls
+	for the respective 'COLR' v1 API to the SFNT driver.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Register 'COLR' v1 API in driver (#59703).
+
+	* include/freetype/internal/sfnt.h (TT_Get_Color_Glyph_Paint_Func,
+	TT_Get_Paint_Layers_Func, TT_Get_Colorline_Stops_Func,
+	TT_Get_Paint_Func): New function pointer types.
+	(SFNT_Interface): Add them.
+	(FT_DEFINE_SFNT_INTERFACE): Updated.
+
+	* src/sfnt/sfdriver.c (PUT_COLOR_LAYERS_V1): New macro.
+	(sfnt_interface): Add new function pointers.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Add 'COLR' v1 API to retrieve color layers (#59703).
+
+	* src/sfnt/ttcolr.c (tt_face_get_paint_layers): New function to get
+	the layers of a `PaintColrLayers` table in the font, using an
+	`FT_LayerIterator` from an `FT_PaintColrLayers` object retrieved via
+	`tt_face_get_paint`.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Add 'COLR' v1 API to iterate color stops (#59703).
+
+	* src/sfnt/ttcolr.c (tt_face_get_colorline_stops): New function to
+	return the current `FT_ColorStop` object from `FT_ColorStopIterator`.
+	Also increment the iterator.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Add API to get actual paint from `FT_OpaquePaint` (#59703).
+
+	* src/sfnt/ttcolr.c (tt_face_get_paint): New function to resolve an
+	`FT_OpaquePaint` paint reference into an `FT_COLR_Paint` object of a
+	certain format, which contains the detailed information stored in a
+	paint of the respective format.
+	(read_paint): New function to provide the format specific parsing
+	and to populate the data members of each specific `FT_COLR_Paint`
+	subtype.
+	(read_color_line): New function to parse retrieved color line
+	information into an `FT_ColorLine` object, which has information
+	about the color line extend mode as well as an
+	`FT_ColorStopIterator` object.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Add API to retrieve 'COLR' v1 root paint (#59703).
+
+	* src/sfnt/ttcolr.c (BaseGlyphV1Record): New structure.
+	(tt_face_load_colr): Handle version 1 table header.
+	(find_base_glyph_v1_record): New auxiliary function.
+	(tt_face_get_colr_glyph_paint): New function to find the root
+	`FT_OpaquePaint` object for a given glyph ID.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	Add new methods required for 'COLR' v1 to public API (#59703).
+
+	* include/freetype/freetype.h (FT_Get_Color_Glyph_Paint): New method
+	for retrieving the root paint object for a color glyph by specifying
+	a glyph ID.
+	(FT_Get_Paint_Layers): New method for retrieving the layers of a
+	`PaintColorGlyph`.
+	(FT_Get_ColorLine_Stops): New method for retrieving the stops of a
+	color.
+	(FT_Get_Paint): New method for resolving an `FT_OpaquePaint` into an
+	`FT_COLR_Paint` object.
+
+2020-12-16  Dominik Röttsches  <drott@chromium.org>
+
+	Add types required for 'COLR' v1 to public API (#59703).
+
+	* include/freetype/freetype.h (FT_PaintFormat, FT_ColorStopIterator,
+	FT_ColorIndex, FT_ColorStop, FT_PaintExtend, FT_ColorLine,
+	FT_Affine23, FT_CompositeMode, FT_OpaquePaint, FT_PaintColrLayers,
+	FT_PaintSolid, FT_PaintLinearGradient, FT_PaintRadialGradient,
+	FT_PaintGlyph, FT_PaintColrGlyph, FT_PaintTransformed,
+	FT_PaintTranslate, FT_PaintRotate, FT_PaintSkew, FT_PaintComposite,
+	FT_COLR_Paint): Adding structs and enum to represent paint format,
+	color stop information, gradient extend information, structs to
+	reference paint offsets, and to define transforms and compositions.
+	Adding a union type to represent the union of the structs,
+	distinguished by `FT_PaintFormat`.
+
+2021-01-10  Werner Lemberg  <wl@gnu.org>
+
+	* builds/*: s/BUILD_DIR/PLATFORM_DIR/.
+
+	The old variable name caused confusion.
+
+2021-01-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds] Revert `FTMODULE_H' changes.
+
+	* builds/toplevel.mk, builds/freetype.mk: Revert changes.
+
+2021-01-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds/windows] Fix up DLG build with VC++.
+
+	* builds/windows/vc2010/script.bat: Copy headers to include/.
+	* builds/windows/vc2010/freetype.vcxproj: Remove DLG paths.
+
+2021-01-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds] Relocate `FTMODULE_H'.
+
+	* builds/toplevel.mk: Place `FTMODULE_H' in include/.
+	* builds/freetype.mk: Simplify included path.
+
+2021-01-07  Werner Lemberg  <wl@gnu.org>
+
+	Fix ABI incompatibility.
+
+	* include/freetype/ftimage.h (FT_Pixel_Mode): Don't insert
+	`FT_PIXEL_MODE_GRAY16' but append it.
+
+	* src/base/ftobjs.c (pixel_modes): Updated.
+
+2021-01-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[dlg] Move the headers to include/dlg to simplify their use.
+
+	* autogen.sh, builds/toplevel.mk: Copy headers to include/dlg.
+	* builds/freetype.mk, builds/windows/vc2010/freetype.vcxproj:
+	Simplify included path.
+	* include/freetype/internal/ftdebug.h: Simplify #include.
+	* src/dlg/rules.mk, .gitignore: Updated.
+
+2021-01-06  Werner Lemberg  <wl@gnu.org>
+
+	* meson.build: Add summary.
+
+	Based on a patch from Vincent Torri <vincent.torri@gmail.com>.
+
+2021-01-06  Torsten Hilbrich  <emacs.nolkaf@hilbrich.tk>
+
+	* meson.build: Fix 'png' build option (#59458).
+
+	Without this patch, 'png' is always required.
+
+2021-01-04  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds/windows] Add SDF to VC2010 project.
+
+	* builds/windows/vc2010/freetype.vcxproj: Updated;
+	AfterBuild conveniences.
+
+2020-12-26  Werner Lemberg  <wl@gnu.org>
+
+	[sdf] Use 'counter-clockwise', not 'anti-clockwise'.
+
+	We prefer US nomenclature.
+
+	* src/sdf/ftsdf.c (SDF_Contour_Orientation):
+	s/SDF_ORIENTATION-ACW/SDF_ORIENTATION_CCW/.
+	Update all users.
+
+2020-12-26  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftobjs.c (pixel_modes): Updated.
+
+2020-12-26  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Remove custom memory tracker.
+
+	The internal FreeType memory tracker is sufficient.
+
+	* src/sdf/ftsdf.c (FT_DEBUG_INNER, FT_ASSIGNP_INNER, SDF_MemoryUser,
+	sdf_alloc, sdf_free, SDF_ALLOC, SDF_FREE,
+	SDF_MEMORY_TRACKER_DECLARE, SDF_MEMORY_TRACKER_SETUP,
+	SDF_MEMORY_TRACKER_DONE): Removed.
+
+	s/SDF_ALLOC/FT_ALLOC/.
+	s/SDF_FREE/FT_FREE/.
+
+	Other updates.
+
+2020-12-24  Werner Lemberg  <wl@gnu.org>
+
+	[sdf] Fix `make multi`.
+
+	* src/sdf/ftsdf.c: Include `ftoutln.h`.
+
+2020-12-24  Werner Lemberg  <wl@gnu.org>
+
+	[sdf] Fix tracing.
+
+	* include/freetype/internal.fttrace.h: Add 'bsdf' component.
+
+	* src/sdf/ftbsdf.c, src/sdf/ftsdf.c (FT_COMPONENT): Define.
+
+2020-08-21  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add debugging function.
+
+	* src/sdf/ftsdf.c (sdf_shape_dump): New function.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add 'bsdf' renderer to 'sdf' module.
+
+	* src/sdf/ftsdfrend.c (ft_bsdf_render): New function.
+
+	(ft_bitmap_sdf_renderer_class): New structure.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add interface functions for the 'bsdf' rasterizer.
+
+	* src/sdf/ftsdf.c (bsdf_raster_new, bsdf_raster_reset,
+	bsdf_raster_set_mode, bsdf_raster_render, bsdf_raster_done): New
+	functions.
+
+	(ft_bitmap_sdf_raster): New variable.
+
+	* src/sdf/ftsdf.h: Updated.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add function to copy SDF data into output bitmap.
+
+	* src/sdf/ftbsdf.c (finalize_sdf): New function.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add '8-point sequential Euclidean distance mapping' algorithm.
+
+	* src/sdf/ftbsdf.c (compare_neighbor, first_pass, second_pass,
+	edt8): New functions.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add function to copy source bitmap to distance map.
+
+	* src/sdf/ftbsdf.c (bsdf_init_distance_map): New function.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add functions to compute pixel edge distances.
+
+	* src/sdf/ftbsdf.c (compute_edge_distance, bsdf_approximate_edge):
+	New functions.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add function to find edge pixels in a grid of alpha values.
+
+	* src/sdf/ftbsdf.c (bsdf_is_edge): New function.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add essential structures for the 'bsdf' rasterizer.
+
+	* src/sdf/ftbsdf.c (ONE): New macro.
+	(BSDF_TRaster, ED, BSDF_Worker): New structures.
+	(zero_ed): New constant.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add 'sdf' module to non-gnumake build systems.
+
+	* include/freetype/config/ftmodule.h: Add both the 'sdf' and 'bsdf'
+	renderers to the list of modules.
+
+	* CMakeLists.txt (BASE_SRCS): Add 'sdf' single-object module.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Added basic overlapping contour support.
+
+	* src/sdf/ftsdf.c (sdf_generate_with_overlaps): New function.
+	(sdf_raster_render): Enable it.
+
+2020-08-19  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add build infrastructure.
+
+	* src/sdf/module.mk, src/sdf/rules.mk: New files.
+
+	* src/sdf/ftsdf.h (ft_sdf_raster): New forward declaration.
+
+	* include/freetype/ftmoderr.h (FT_MODERRDEF): Add error definition
+	for the 'sdf' module.
+
+	* include/freetype/internal/fttrace.h (FT_TRACE_DEF): Add trace
+	definition for the `sdf' module.
+
+	* modules.cfg (RASTER_MODULES): Add the `sdf' module to the list of
+	rasterizers.
+
+2020-08-19  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add interface functions for the 'sdf' rasterizer.
+
+	* src/sdf/ftsdf.c (sdf_raster_new, sdf_raster_reset,
+	sdf_raster_set_mode, sdf_raster_render, sdf_raster_done): New
+	functions.
+	(ft_sdf_raster): New structure.
+
+2020-08-19  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add subdivision and bounding box optimization.
+
+	* src/sdf/ftsdf.c (sdf_generate_bounding_box): New function, which
+	is an optimized version of `sdf_generate`.
+	(sdf_generate_subdivision): New function.
+
+2020-08-19  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add function to generate SDF.
+
+	* src/sdf/ftsdf.c (sdf_generate): New function, currently disabled.
+	This is a proof-of-concept implementation: It doesn't use any
+	optimization, it simply checks all grid points against all contours.
+
+2020-08-19  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add functions to get shortest distance from any edge/contour.
+
+	* src/sdf/ftsdf.c (sdf_edge_get_min_distance): New function.
+	(sdf_contour_get_min_distance): New function, currently disabled.
+
+2020-08-18  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add shortest distance finding functions.
+
+	* src/sdf/ftsdf.c (get_min_distance_line, get_min_distance_conic,
+	get_min_distance_cubic): New functions.  Note that
+	`get_min_distance_conic` comes with two implementations (using an
+	analytical and an iterative method, to be controlled with the
+	`USE_NEWTON_FOR_CONIC` macro).
+
+2020-08-18  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add function to resolve corner distances.
+
+	* src/sdf/ftsdf.c (resolve_corner): New function.
+
+2020-08-18  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add essential math functions.
+
+	* src/sdf/ftsdf.c (cube_root, arc_cos) [!USE_NEWTON_FOR_CONIC]: New
+	auxiliary functions.
+
+	* src/sdf/ftsdf.c (solve_quadratic_equation, solve_cubic_equation)
+	[!USE_NEWTON_FOR_CONIC]: New functions.
+
+2020-08-18  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add utility functions for contours.
+
+	* src/sdf/ftsdf.c (get_control_box, get_contour_orientation): New
+	functions.
+	(split_conic, split_cubic, split_sdf_conic, split_sdf_cubic,
+	split_sdf_shape): New functions.
+
+2020-08-17  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add functions to decompose `FT_Outline`.
+
+	* src/sdf/ftsdf.c (sdf_move_to, sdf_line_to, sdf_conic_to,
+	sdf_cubic_to): New auxiliary decomposition functions.
+	(sdf_compose_funcs): New structure.
+	(sdf_outline_decompose): New function.
+
+2020-08-17  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Structs, enums, macros, and functions for 'sdf' rasterizer.
+
+	* src/sdf/ftsdf.c (FT_DEBUG_INNER, FT_ASSIGNP_INNER)
+	[FT_DEBUG_LEVEL_TRACE && FT_DEBUG_MEMORY]: New macros.
+	(SDF_MemoryUser) [FT_DEBUG_LEVEL_TRACE && FT_DEBUG_MEMORY]: New
+	struct for memory usage tracing.
+	(sdf_alloc, sdf_free) [FT_DEBUG_LEVEL_TRACE && FT_DEBUG_MEMORY]: New
+	functions for memory usage tracing.
+
+	(SDF_ALLOC, SDF_FREE): New macros for memory management.
+	(SDF_MEMORY_TRACKER_DECLARE, SDF_MEMORY_TRACKER_SETUP,
+	SDF_MEMORY_TRACKER_DONE): New macros to set up memory usage tracing.
+
+	(USE_NEWTON_FOR_CONIC, MAX_NEWTON_DIVISIONS, MAX_NEWTON_STEPS,
+	CORNER_CHECK_EPSILON, CG_DIMEN): New configuration macros for
+	controlling the process of finding the shortest distance.
+
+	(MUL_26D6, VEC_26D6_DOT): New auxiliary macros.
+
+	(SDF_TRaster, SDF_Edge, SDF_Contour, SDF_Shape, SDF_Signed_Distance,
+	SDF_Params): New structs for setting up SDF data.
+	(SDF_Edge_Type, SDF_Contour_Orientation): New enums for SDF data.
+
+	(zero_vector, null_edge, null_contour, null_shape, max_sdf): Useful
+	constants.
+
+	(sdf_edge_new, sdf_edge_done, sdf_contour_new, sdf_contour_done,
+	sdf_shape_new, sdf_shape_done): New constructors and destructors.
+
+2020-08-17  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add raster parameters structure.
+
+	* src/sdf/ftsdf.h (SDF_Raster_Params): New structure.
+
+	* src/sdf/sdf.c: Include source files in order to make a single
+	object of the module.
+
+2020-08-17  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add 'sdf' renderer.
+
+	* src/sdf/ftsdf.c: Add 'sdf' renderer along with its interface
+	functions.
+	Also add functions to set and get properties.
+
+2020-08-17  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add common elements for 'sdf' and 'bsdf' renderers.
+
+	* src/sdf/ftsdfrend.h (SDF_Rendere_Module, ft_sdf_renderer_class,
+	ft_bitmap_sdf_renderer_class): New structures.
+
+	* src/sdf/ftsdfcommon.h (DEFAULT_SPREAD, MIN_SPREAD_MAX_SPREAD,
+	USE_SQUARED_DISTANCES): New macros.
+	(FT_INT_26D6, FT_INT_16D16, FT_26D6_16D16): New macros.
+	(FT_CALL, VECTOR_LENGTH_16D16): New macros.
+	(FT_26D6_Vec, FT_16D16_Vec, FT_16D16, FT_26D6, FT_6D10, FT_CBox):
+	New typedefs.
+	(square_root): New macro.
+
+	* src/sdf/ftsdferrs.h: Add module error setup.
+
+2020-08-16  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[sdf] Add files for new 'sdf' module.
+
+	Here is a breakdown of what the files will contain.
+
+	* src/sdf/ftsdfrend.c, src/sdf/ftsdfrend.h: The 'sdf' and 'bsdf'
+	renderers.
+
+	* src/sdf/ftsdf.c, src/sdf/ftsdf.h: The rasterizer for the 'sdf'
+	renderer.
+	* src/sdf/ftbsdf.c, src/sdf/ftbsdf.h: The rasterizer for the 'bsdf'
+	renderer.
+
+	* src/sdf/ftsdfcommon.h: Common properties and functions for both
+	rasterizers.
+	* src/sdf/ftsdferrs.h: Common error defines.
+
+	* src/sdf/sdf.c: For building a single object of the entire module.
+
+2020-08-16  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[base] Allow renderers of different formats.
+
+	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Do not return if the
+	glyph's slot format is `FT_GLYPH_FORMAT_BITMAP`.  The forthcoming
+	'bsdf' renderer will require bitmaps for processing.
+
+	* src/base/ftobjs.c (ft_add_renderer, ft_remove_renderer): Remove
+	renderer's glyph format check before adding and removing them.  The
+	'bsdf' renderer will have a format `FT_GLYPH_FORMAT_BITMAP`.
+
+2020-08-16  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	Add data types required for the forthcoming 'sdf' module.
+
+	* include/freetype/freetype.h (FT_Render_Mode): Add new render mode
+	`FT_RENDER_MODE_SDF`, which will be used to generate SDF.
+
+	* include/freetype/ftimage.h (FT_Pixel_Mode): Add new pixel mode
+	`FT_PIXEL_MODE_GRAY16`, which will be the output of the 'sdf'
+	module.
+	(FT_RASTER_FLAG_SDF): New raster flag to be used internally by the
+	'sdf' module.
+
+	* include/freetype/fttypes.h (FT_F6Dot10): New data type.
+
+2020-08-16  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	[base] Allow renderers of different formats.
+
+	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Do not return if the
+	glyph's slot format is `FT_GLYPH_FORMAT_BITMAP`.  The forthcoming
+	'bsdf' renderer will require bitmaps for processing.
+
+	* src/base/ftobjs.c (ft_add_renderer, ft_remove_renderer): Remove
+	renderer's glyph format check before adding and removing them.  The
+	'bsdf' renderer will have a format `FT_GLYPH_FORMAT_BITMAP`.
+
+2020-12-23  Werner Lemberg  <wl@gnu.org>
+
+	* builds/windows/detect.mk (COPY): Make it work with `shell`.
+
+	Without this patch, we get the error
+
+	  builds/toplevel.mk:127: *** missing separator.  Stop.
+
+	Reported by Anuj, with a solution from Alexei.
+
+2020-12-23  Ignacio Casal Quinteiro  <qignacio@amazon.com>
+
+	* meson.build (ft2_defines): Fix builds on Windows.
+
+2020-12-18  Tatsuyuki Ishi  <ishitatsuyuki@gmail.com>
+
+	[autofit] Fix double division in stem darkening.
+
+	The old code used to divide the darkening amount by em_ratio twice,
+	leading to unnecessarily bold stems on certain fonts with higher
+	units per em (e.g. Inter). This patch fixes it.
+
+	The return value of af_loader_compute_darkening was also changed to
+	use 16.16 fixed-point to get rid of a redundant truncation operation.
+	This should slightly improve the precision, although it's still
+	bottlenecked by the emboldening function, which uses 26.6 fixed-point.
+
+	* src/autofit/afloader.[ch]
+	(af_loader_compute_darkening): Return FT_Fixed.
+	(af_loader_embolden_glyph_in_slot): Revise calculations.
+
+2020-12-17  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* include/freetype/ftmodapi.h (FT_FACE_DRIVER_NAME): New public macro.
+
+	The driver name is needed for `FT_Property_Set' and `FT_Property_Get'.
+
+2020-12-16  Chris Liddell  <chris.liddell@artifex.com>
+
+	[truetype] Fix incremental metrics (#59503).
+
+	* src/truetype/ttgload.c (tt_get_metrics, load_truetype_glyph):
+	Previously, the code would populate the phantom points before
+	calling the `get_glyph_metrics` callback.  For formats like PCL XL
+	format 1, class 2 downloaded fonts (where metrics are removed from
+	the TTF header), this causes problems when the hinting program uses
+	the phantom points (misplaced and distorted glyphs) due to the
+	metrics being unset (all zeros).
+	(tt_get_metrics_incr_overrides): Renamed to...
+	(tt_get_metrics_incremental): ... this.  Updated caller
+
+	* include/freetype/ftincrem.h: Update the documentation to make it
+	clearer that `get_glyph_metrics` is to retrieve metrics from a
+	non-standard source, but *not* for the purpose of imposing custom
+	metrics.
+
+2020-12-14  Werner Lemberg  <wl@gnu.org>
+
+	[type42] Pacify static analysis tools (#59682).
+
+	* src/type42/t42objs.c (T42_Size_Init, T42_GlyphSlot_Init): Avoid
+	warnings about uninitialized variables.
+
+2020-12-07  Werner Lemberg  <wl@gnu.org>
+
+	* builds/unix/configure.raw: Don't set `FT_DEBUG_LOGGING`.
+
+	All debug options are handled exclusively in `ftoption.h`.
+
+2020-12-07  Werner Lemberg  <wl@gnu.org>
+
+	* src/*: More fixes for using a '\n' in `FT_TRACE` and `FT_ERROR`.
+
+2020-12-07  Werner Lemberg  <wl@gnu.org>
+
+	*/*: s/FT_LOGGING/FT_DEBUG_LOGGING/.
+
+2020-12-05  Werner Lemberg  <wl@gnu.org>
+
+	* builds/toplevel.mk (do-dist): Remove `submodules` directory.
+
+2020-12-02  Werner Lemberg  <wl@gnu.org>
+
+	* src/*: Don't use more than one '\n' in `FT_TRACE` and `FT_ERROR`.
+
+	This ensures good logging output, with all lines having a proper
+	prefix (if requested).
+
+2020-12-02  Werner Lemberg  <wl@gnu.org>
+
+	[base] Don't close 'stderr' after logging.
+
+	* src/base/ftdebug.c, builds/windows/ftdebug.c (ft_logging_deinit):
+	Fix it.
+
+2020-12-02  Werner Lemberg  <wl@gnu.org>
+
+	* submodules/dlg: Updated to commit 9f0c8b22.
+
+2020-12-02  Werner Lemberg  <wl@gnu.org>
+
+	* src/bdf/bdflib.c: Fix `-Wformat` warning.
+
+2020-12-02  Werner Lemberg  <wl@gnu.org>
+
+	Improve setup for 'dlg' library.
+
+	* autogen.sh (copy_submodule_file), builds/toplevel.mk: Redirect
+	stderr to `/dev/null`.
+
+	* builds/toplevel.mk: Move code block to handle 'dlg' stuff into
+	`check_platform` conditional.
+	Also fix wildcard expressions for guarding `git submodule` commands.
+	Also make file copying work with non-Unix platforms (untested).
+
+2020-12-01  Werner Lemberg  <wl@gnu.org>
+
+	[build] Use gcc (and clang) in C99 mode.
+
+	Other compilers are unchanged.
+
+	* builds/compiler/gcc-dev.mk, builds/compiler/gcc.mk (ANSIFLAGS):
+	s/-ansi/-std=c99/.
+
+	* builds/freetype.mk (FT_CFLAGS): Remove `-std=c99`.
+
+	* builds/unix/configure.raw: Handle C99.
+	Remove no longer needed test for gcc 4.6 and earlier.
+
+2020-12-01  Werner Lemberg  <wl@gnu.org>
+
+	[dlg] Fix compiler warnings.
+
+	* src/dlg/dlgwrap.c: Duplicate some feature test macros from
+	`dlg.c`, which must come first before loading standard headers.  For
+	example, `freetype.h` loads `stdio.h` if compiled in debug mode.
+
+2020-12-01  Werner Lemberg  <wl@gnu.org>
+
+	* src/type42/t42parse.c: Fix `-Wformat` warnings.
+
+2020-12-01  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[builds/unix] Check for 'pthread' library.
+
+	* builds/unix/ax_pthread.m4: New file, taken from 'autoconf-archive'
+	git repository.
+
+	* builds/unix/configure.raw: Check for 'pthread'; also check whether
+	it works.
+
+2020-12-01  Werner Lemberg  <wl@gnu.org>
+
+	[base] Implement vertical alignment of log printing.
+
+	Based on a patch by Priyesh.
+
+	* include/freetype/internal/fttrace.h (FT_MAX_TRACE_LEVEL_LENGTH):
+	New macro.
+
+	* src/base/ftdebug.c, builds/windows/ftdebug.c (ft_log_handler):
+	Print logs after a fixed width to handle different lengths of
+	`FT_COMPONENT` entries.
+	Use `ft_strrchr` to check for final newline character.
+
+2020-11-30  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	Update logging related documentation.
+
+	* docs/DEBUG: Updates related to `FT_LOGGING`.
+
+	* README.git: Updates related to logging.
+
+2020-11-30  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	* src/*: Fix `-Wformat` warnings.
+
+2020-11-30  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[builds/windows] Changes to build 'dlg' with FreeType on Windows.
+
+	We only support Visual C++ 2010 and newer.
+
+	* builds/windows/vc2010/script.bat: New windows batch file to copy
+	necessary 'dlg' files from `submodules/dlg` to `src/dlg`.  This file
+	is used as a pre-built event in Visual C++.
+
+	* builds/windows/ftdebug.c: Synchronize with `src/base/ftdebug.c`.
+
+	* builds/windows/vc2010/freetype.vcxproj.filters: Add
+	`src/dlgwrap.c`.
+
+	* builds/windows/vc2010/freetype.vcxproj
+	(AdditionalIncludeDirectories): Add include files of dlg for 'Debug'
+	and 'Debug Static' configurations on both 'x64' and 'win32'
+	platforms.
+	(PreprocessorDefinitions): Add `FT_LOGGING` for 'Debug' and 'Debug
+	Static' configurations on both 'x64' and 'win32' platforms.
+	Add `DLG_STATIC' for 'Debug' configuration on 'x64' and 'win32'
+	platforms.
+	(DisableLanguageExtensions): We need to disable the `/Za` option
+	when building 'dlg' with FreeType as 'dlg' strictly follows the C99
+	standard.  Visual C++ produces behaves unexpectedly when
+	compiling a C99 file with `/Za` option enabled.
+
+2020-11-30  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[base] Add public API to change log handling function.
+
+	* include/freetype/ftlogging.h (FT_Custom_Log_Handler): New function
+	typedef to store the custom callback logging function.
+	(FT_Set_Log_Handler, FT_Set_Default_Log_Handler): New functions to
+	set and reset custom log handler.
+
+	* include/freetype/internal/ftdebug.h (custom_output_handler): New
+	variable to support a custom callback logging function.
+	(FT_Logging_Callback): A new function typedef to print log using
+	custom callback logging function, which is set using
+	`FT_Set_Log_Handler`.
+	(FT_Log): Use it.
+
+	* src/base/ftdebug.c (FT_Set_Log_Handler,
+	FT_Set_Default_Log_Handler, FT_Logging_Callback): Add function
+	definitions.
+
+2020-11-28  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[base] Add public API to change the levels of tracing components.
+
+	* include/freetype/ftlogging.h: New header file.
+
+	* include/freetype/internal/ftdebug.h [FT_LOGGING]: Include
+	`ftlogging.h`.
+
+	* src/base/ftdebug.c (ft_custom_trace_level): New variable.
+	(ft_debug_init): Update to support change of levels of tracing
+	components of FreeType at run-time.
+	(FT_Trace_Set_Level): New function to change the levels of tracing
+	components at run-time.
+	(FT_Trace_Set_Default_Level): New function to reset the levels of
+	tracing components back to default.
+
+2020-11-28  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[base] Updates to print timestamp and name of `FT_COMPONENT` in logs.
+
+	* include/freetype/internal/ftdebug.h (FT_LOGGING_TAG,
+	FT_LOGGING_TAG_): New macros to resolve the value of `FT_COMPONENT'
+	into a string.
+	(ft_add_tag, ft_remove_tag): New functions to add and remove dlg tags.
+
+	* src/base/ftdebug.c: Add new variables to control the logging of
+	timestamp and name of `FT_COMPONENT` along with actual logs.
+	(ft_add_tag, ft_remove_tag): Add function definitions.
+	(ft_log_handler): Updates to print timestamp and name of
+	`FT_COMPONENT`.
+	(ft_debug_init) [FT_LOGGING]: Users can now control the logging of
+	timestamp and name of `FT_COMPONENT` by adding tags in the
+	`FT2_DEBUG` environment variable.
+
+2020-11-27  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[base] Add functions and variables to print logs to a file.
+
+	* include/freetype/internal/ftdebug.h: Added dlg's header files.
+	(FT_LOG): New macro to redirect trace logs to dlg's API's whenever
+	`FT_LOGGING' is defined.
+	(ft_logging_init, ft_logging_deinit): New functions to handle
+	initialization and uninitialization of logging related variables.
+	(ft_log_handler): New function to handle logs of FreeType.
+
+	* src/base/ftdebug.c: Add necessary logging related variables.
+	(ft_logging_init, ft_logging_deinit, ft_log_handler): Add function
+	definitions.
+
+	* src/base/ftinit.c (FT_Init_FreeType) [FT_LOGGING]: Call
+	`ft_logging_init`.
+	(FT_Done_FreeType) [FT_LOGGING]: Call `ft_logging_deinit`.
+
+	* src/base/ftobjs.c (FT_New_Library): Call `ft_debug_init` only if
+	`FT_LOGGING` is not defined.
+
+2020-11-27  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	[builds] Necessary changes to make 'dlg' compile.
+
+	* autogen.sh (copy_submodule_files): New script to copy all the
+	necessary source and include files from `submodules/dlg` to
+	`src/dlg`.
+
+	* src/dlg/dlgwrap.c: New wrapper file for `src/dlg.c`.  It enables
+	the build of 'dlg' if the `FT_LOGGING` macro is defined.
+
+	* src/dlg/rules.mk: New sub-Makefile.
+
+	* builds/freetype.mk (DLG_DIR): New variable to include the
+	header files of the 'dlg' library.
+	(INCLUDES): Add `DLG_DIR`.
+	(FT_CFLAGS): Add `-std=c99' flag.
+	Include `src/dlg/rules.mk` file to build 'dlg' library.
+	(OBJ_S, OBJ_M): Add `DLG_OBJS_M` and `DLG_OBJS_S`.
+
+	* builds/toplevel.mk: For builds directly from the git repository
+	we need to copy files from `submodule/dlg` to `src/dlg`.
+
+	* include/freetype/config/ftoption.h, devel/ftoption.h (FT_LOGGING):
+	New macro to enable or disable the logging facility in FreeType.
+
+2020-11-27  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	* .gitmodules: Add 'dlg' library's git repository as submodule.
+
+2020-12-01  Werner Lemberg  <wl@gnu.org>
+
+	* src/tools/chktrcmp.py (trace_use_pat): Update to current use.
+
+2020-11-20  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[cff,cid,type1] Demote old engine for lack of CFF2.
+
+	* src/cff/cffobjs.c (cff_driver_init): Always default to Adobe engine.
+	* src/cid/cidobjs.c (cid_driver_init): Ditto.
+	* src/type1/t1objs.c (T1_Driver_Init): Ditto.
+
+2020-11-09  Werner Lemberg  <wl@gnu.org>
+
+	* src/type42/t42parse.c (t42_parse_sfnts): More tracing messages.
+
+2020-11-04  Werner Lemberg  <wl@gnu.org>
+
+	* meson.build: Fix .pc file generation.
+
+	For backwards compatibility we need the libtool version, not the .so
+	number.
+
+	Reported by Nikolaus.
+
+2020-10-28  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Minor update to forthcoming OpenType 1.8.4 standard.
+
+	* src/truetype/ttgxvar.c (ft_var_load_item_variation_store): Limit
+	size of `regionCount`.
+
+2020-10-26  Werner Lemberg  <wl@gnu.org>
+
+	* meson.build: Fix 'harfbuzz' and 'brotli' build options (#59347).
+
+	Without this patch, 'harfbuzz' and 'brotli' are always required.
+
+	Patch submitted anonymously in Savannah bug report.
+
+2020-10-23  Ben Wagner  <bungeman@google.com>
+
+	* src/sfnt/pngshim.c (Load_SBit_Png): Fix memory leak (#59322).
+
+	The issue is that `rows` is allocated but will not be freed in the
+	event that the call to `png_read_image` fails and calls `longjmp`.
+
+2020-10-20  Werner Lemberg  <wl@gnu.org>
+
+	* Version 2.10.4 released.
+	==========================
+
+
+	Tag sources with `VER-2-10-4'.
+
+	* docs/VERSION.TXT: Add entry for version 2.10.4.
+	* docs/CHANGES: Updated.
+
+	* README, src/base/ftver.rc, builds/windows/vc2010/index.html,
+	builds/windows/visualc/index.html,
+	builds/windows/visualce/index.html,
+	builds/wince/vc2005-ce/index.html,
+	builds/wince/vc2008-ce/index.html, docs/freetype-config.1:
+	s/2.10.3/2.10.4/, s/2103/2104/.
+
+	* include/freetype/freetype.h (FREETYPE_PATCH): Set to 4.
+
+	* builds/unix/configure.raw (version_info): Set to 23:4:17.
+	* CMakeLists.txt (VERSION_PATCH): Set to 4.
+
+2020-10-19  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix heap buffer overflow (#59308).
+
+	This is CVE-2020-15999.
+
+	* src/sfnt/pngshim.c (Load_SBit_Png): Test bitmap size earlier.
+
+2020-10-17  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/tt{colr,cpal}.c: Fix signedness warnings from VC++.
+
+2020-10-17  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/sfwoff2.c (Read255UShort): Tweak types to please VC++.
+
+2020-10-10  Werner Lemberg  <wl@gnu.org>
+
+	* Version 2.10.3 released.
+	==========================
+
+
+	Tag sources with `VER-2-10-3'.
+
+	* docs/VERSION.TXT: Add entry for version 2.10.3.
+
+	* README, src/base/ftver.rc, builds/windows/vc2010/index.html,
+	builds/windows/visualc/index.html,
+	builds/windows/visualce/index.html,
+	builds/wince/vc2005-ce/index.html,
+	builds/wince/vc2008-ce/index.html, docs/freetype-config.1:
+	s/2.10.2/2.10.3/, s/2102/2103/.
+
+	* include/freetype/freetype.h (FREETYPE_PATCH): Set to 3.
+
+	* builds/unix/configure.raw (version_info): Set to 23:3:17.
+	* CMakeLists.txt (VERSION_PATCH): Set to 3.
+
+2020-09-25  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Synchronize with ttfautohint.
+
+	This corresponds to the following commits in the ttfautohint git
+	repository:
+
+	  bb6842bd3bd437b7b4a7921b0376c860f5e73d18  Typo, formatting.
+	  d5c91ddb1cb310257a3dfe9a8e20e1fc51335faa  Add Medefaidrin script.
+
+	* src/autofit/afblue.dat: Add blue zone data for Medefaidrin.
+	* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+	* src/autofit/afscript.h: Add Medefaidrin standard characters.
+
+	* src/autofit/afranges.c, src/autofit/afstyles.h: Add Medefaidrin
+	data.
+
+2020-09-25  Werner Lemberg  <wl@gnu.org>
+
+	Move `scripts/make_distribution_archives.py` to `src/tools`.
+
+	* scr/tools/scripts/make_distribution_archives.py: (_TOP_DIR,
+	_SCRIPT_DIR): Updated to new location.
+	(main): s/shutils.copyfile/shutils.copy/ to preserve file
+	permissions.
+	(main): Prefix source file paths with `git_dir` while copying files
+	to allow calls of the script from other places than the top-level
+	directory.
+
+2020-09-24  Werner Lemberg  <wl@gnu.org>
+
+	* src/cff/cffgload.c (cff_slot_load): Scale `vertBearingY`.
+
+	Towards the end of the the function there is a call to
+	`FT_Outline_Get_CBox` that retrieves the glyph bbox in scaled units.
+	That sets `horiBearing{X,Y}` and `vertBearingX` but `vertBearingY`
+	is left alone, and is not scaled.
+
+	Patch from Eric Muller <emuller@amazon.com>.
+
+2020-09-24  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Trace glyph metrics.
+
+2020-09-22  Werner Lemberg  <wl@gnu.org>
+
+	[meson] Move auxiliary scripts to `builds/meson`.
+
+	Suggested by Alexei.
+
+	* scripts/*.py: Move meson scripts to...
+	* builds/meson/*.py: ... this new location.
+
+	* meson.build: Updated.
+
+2020-09-21  David Turner  <david@freetype.org>
+
+	Add python script for building tarballs.
+
+	* scripts/make_distribution_archives.py: New file.
+
+	This standalone Python script should be equivalent to running `make
+	dist` with the Make-based build system, with the following minor
+	differences:
+
+	- Since `make distclean` doesn't always clean up `objs/` properly,
+	  `make dist` archives may contain some stale binaries like
+	  `objs/.libs/libfreetype.so.6` or others.
+
+	- `config.guess` and `config.sub` are not updated unless option
+	  `--gnu-config-dir=DIR` is used to specify the location of these
+	  files.
+
+	- Some bits of the auto-generated reference documentation may
+	  appear in slightly different order, probably due to issues related
+	  to mkdocs and docwriter.
+
+	As an example, the call
+
+	  scripts/make_distribution_archives.py /tmp/freetype2-dist
+
+	creates the following files under `/tmp/freetype2-dist`:
+
+	  freetype-<version>.tar.gz
+	  freetype-<version>.tar.xz
+	  ft<winversion>.zip
+
+2020-09-21  Werner Lemberg  <wl@gnu.org>
+
+	* scripts/extract_freetype_version.py: Fix regex typos.
+
+2020-09-21  David Turner  <david@freetype.org>
+
+	Add Meson build project file.
+
+	Example usage:
+
+	  # Configure Meson build in directory `build-meson` to generate
+	  # release binaries comparable to to the ones from the
+	  # autotools/make build system.
+	  meson setup build-meson \
+	        --prefix=/usr/local \
+	        --buildtype=debugoptimized \
+	        --strip \
+	        -Db_ndebug=true
+
+	  # After configuring the Meson build with the above command,
+	  # compile and install to `/usr/local/`; this includes a pkg-config
+	  # file.
+	  ninja -C build-meson install
+
+	  # Alternatively, compile and install to `/tmp/aa/usr/local/...`
+	  # for packaging.
+	  DESTDIR=/tmp/aa ninja -C build-meson install
+
+	  # Generate documentation under `build-meson/docs`.
+	  ninja -C build-meson docs
+
+	Library size comparison for stripped `libfreetype.so` generated by
+	all three build systems:
+
+	  - Default build (autotools + libtool): 712 KiB
+	  - CMake build (RelWithDebInfo):        712 KiB
+	  - Meson build:                         712 KiB
+
+
+	* meson.build: New top-level Meson build file for the library.
+
+	* meson_options.txt: New file.  It holds user-selectable options for
+	the build, which can be printed with `meson configure`, and selected
+	at `meson setup` or `meson --reconfigure` time with
+	`-D<option>=<value>`.
+
+	* scripts/parse_modules_cfg.py: A script invoked by `meson.build` to
+	parse `modules.cfg` and extract important information out of it
+	(i.e., the list of modules).
+
+	* scripts/process_ftoption_h.py: New script invoked by `meson.build`
+	to process the original `ftoption.h` file.  It enables or disables
+	configuration macro variables based on the available dependencies.
+	This is similar to what other build systems are using (i.e., Meson's
+	`configure_file()` command is not used here).
+
+	* scripts/extract_freetype_version.py: New script invoked by
+	`meson.build` to extract the FreeType version number from
+	`<freetype/freetype.h>`.
+
+	* scripts/extract_libtool_version.py: New script invoked by
+	`meson.build` to extract the libtool `revision_info` data from
+	`builds/unix/configure.raw`, and to generate the corresponding
+	shared library suffix.
+
+	* scripts/generate_reference_docs.py: New script invoked by
+	`meson.build` to generate the FreeType 2 reference documentation
+	(using the `docwriter` and `mkdocs` packages, which must be already
+	installed).
+
+2020-09-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Improve the second pass (#58373).
+
+	Besides dropout control the second horizontal sweep is supposed to
+	clean up straight horizontal edges that are mishandled by the first
+	vertical sweep when a line passes through pixel centers.  This line
+	would present as perfectly aligned span edges in the second sweep.
+
+	* src/raster/ftraster.c (Horizontal_Sweep_Span): Replace the old
+	implementation with a better one focusing on aligned span edges only.
+
+2020-09-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Tune SMART macro (#58352).
+
+	Windows seems to perform smart dropout control at 26.6 precision.
+	To mimick Windows independent of increased precision, we need to tweak
+	the macro so that some close calls break down rather than up.
+
+	* src/raster/ftraster.c (SMART): Tweak the macro.
+
+2020-09-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Introduce SMART macro.
+
+	* src/raster/ftraster.c (SMART): New macro for smart dropout rounding.
+	(Verstical_Sweep_Drop, Horizontal_Sweep_Drop): Use it.
+
+2020-09-03  Boris Dalstein  <dalboris@gmail.com>
+
+	[build] Make CMake install basic version information.
+
+	* CMakeLists.txt: Do it.
+
+2020-09-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[truetype] Reduce Infinality footprint (cont'd).
+
+	* src/truetype/ttinterp.c (Ins_DELTAP): Shrink variable scope.
+	(Ins_SHPIX, Ins_MIRP): Revise if-logic.
+
+2020-09-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[truetype] Reduce Infinality footprint.
+
+	* src/truetype/ttinterp.c (Ins_SHPIX, Ins_MSIRP, Ins_MIAP, Ins_MDRP,
+	Ins_MIRP): Shrink variable scopes and consolidate ifdefs.
+
+2020-09-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[truetype] Refactor compensation color.
+
+	* src/truetype/ttinterp.h (TT_Round_Func): Change the last argument.
+	* src/truetype/ttinterp.c (Ins_ROUND, Ins_NROUND, Ins_MDAP, Ins_MIAP,
+	Ins_MDRP, Ins_MIRP): Move compensation retrieval from here...
+	(Round_*): ... to here.
+	* src/truetype/ttobjs.c (tt_size_init_bytecode): Reserve zero
+	compensation at color index 3.
+
+2020-08-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Don't set target in direct mode.
+
+	* src/smooth/ftsmooth.c (ft_smooth_raster_overlap): Remove assignment.
+	(ft_smooth_raster_lcd) [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Ditto.
+
+2020-08-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftsmooth.c (ft_smooth_raster_overlap): Limit width.
+
+	Segmentation fault reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24729
+
+2020-08-22  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgload.c (TT_Get_VMetrics): Add tracing message.
+
+2020-08-05  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[truetype] Retain OVERLAP_SIMPLE and OVERLAP_COMPOUND.
+
+	For glyphs with OVERLAP_SIMPLE or OVERLAP_COMPOUND, set
+	FT_OUTLINE_OVERLAP to render them with direct oversampling, which
+	mitigates artifacts (see 3bb512bc9f62).
+
+	* include/freetype/ftimage.h (FT_OUTLINE_OVERLAP): Redefine to rhyme
+	with OVERLAP_SIMPLE.
+	* src/base/ftgloadr.c (FT_GlyphLoader_Rewind): Reset outline flags.
+	* src/truetype/ttgload.c
+	(TT_Load_Simple_Glyph): Retain OVERLAP_SIMPLE.
+	(load_truetype_glyph): Retain OVERLAP_COMPOUND.
+
+2020-08-04  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttgload.c (TT_Load_Glyph): More tracing.
+
+2020-07-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Hide internal functions with SunPro.
+
+	* include/freetype/internal/compiler-macros.h
+	(FT_INTERNAL_FUNCTION_ATTRIBUTE) <__SUNPRO_C>: Define as __hidden.
+
+2020-07-28  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+	Fix static compilation with Visual C.
+
+	* include/freetype/internal/compiler-macros.h
+	(FT_INTERNAL_FUNCTION_ATTRIBUTE) <_WIN32>: Define as empty.
+
+2020-07-28  Priyesh Kumar  <priyeshkkumar@gmail.com>
+
+	Fix `-Wformat' compiler warnings.
+
+	* src/*: Fix format specifiers.
+
+	* builds/unix/ftsystem.c (FT_Stream_Open): Ditto.
+
+2020-07-25  Werner Lemberg  <wl@gnu.org>
+
+	Fix `-Wformat' compiler warnings.
+
+	Problem reported by Priyesh kumar <priyeshkkumar@gmail.com>
+
+	* src/base/ftoutln.c (FT_Outline_Decompose): Fix number of arguments
+	to tracing macro.
+
+	* src/bdf/bdfdrivr.c (bdf_cmap_char_next, bdf_get_bdf_property):
+	Ditto.
+
+	* src/cache/ftcbasic.c (ftc_basic_family_get_count): Ditto.
+	Reformulate message.
+
+	* src/pcf/pcfdrivr.c (pcf_get_bdf_property): Ditto.
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Ditto.
+	Trace table offset, too.
+
+	* src/truetype/ttgxvar.c (ft_var_apply_tuple): Ditto.
+
+2020-07-23  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_decompress): Fix compiler warning.
+
+	Reported by Hin-Tak.
+
+2020-07-12  Werner Lemberg  <wl@gnu.org>
+
+	* builds/unix/configure.raw: Fix inclusion of `ftoption.h'.
+
+2020-07-07  Werner Lemberg  <wl@gnu.org>
+
+	Fix clang warnings.
+
+	* include/freetype/internal/autohint.h
+	(FT_DECLARE_AUTOHINTER_INTERFACE): New macro.
+	* src/autofit/afmodule.h: Use it to declare
+	`af_autofitter_interface'.
+
+	* include/freetype/internal/ftobjs.h (FT_DECLARE_GLYPH): New macro.
+	* src/base/ftbase.h: Use it to declare `ft_bitmap_glyph_class' and
+	`ft_outline_glyph_class'.
+
+	* src/base/ftglyph.c: Include `ftbase.h'.
+
+	* src/cff/cffparse.c (cff_parser_run): Fix type of `t2_size'.
+
+	* src/pcf/pcfdrivr.c (pcf_cmap_char_next): Fix type of `result'.
+
+	* src/psaux/psauxmod.c (psaux_module_class): Use `FT_DEFINE_MODULE'.
+	* src/psaux/psauxmod.h: Declare `afm_parser_funcs',
+	`t1_cmap_classes', `cff_decoder_funcs', and `psaux_module_class'.
+
+	* src/pshinter/pshmod.c: Include `pshmod.h'.
+
+	* src/sfnt/sfwoff2.c (ROUND4, WRITE_SHORT): Fix implicit sign
+	conversion.
+	(compute_ULong_sum): Fix return type.
+	Fix implicit sign conversion.
+	(store_points): Fix type of `last_flag', `repeat_count', and `flag'.
+	Use casts to avoid warnings.
+	(reconstruct_glyf): Fix implicit sign conversion.
+	Use cast to avoid warning.
+	(get_x_mins): Fix implicit sign conversion.
+	* src/sfnt/ttcmap.c: Undef `TTCMAPCITEM'.
+	* src/sfnt/ttcmap.h: Define `TTCMAPCITEM' and include `ttcmapc.h' to
+	declare cmap classes.
+
+	* src/smooth/ftsmooth.c (ft_smooth_overlap_spans): Use cast.
+
+	* src/truetype/ttinterp.c (Ins_MIAP): Fix typo.
+
+2020-07-07  David Turner  <david@freetype.org>
+
+	[build] Really fix multi and C++ builds.
+
+	The following builds were still failing due to previous changes:
+
+	  make multi
+	  make multi CC="c++"
+	  make CC="c++"
+
+	This patch fixes the issues, which were missing includes to get the
+	right macro definitions in multi-build mode.
+
+	Also, `FT_UNUSED' is actually used by third-party code, so move it
+	back to `public-macros.h' to avoid breaking it.
+
+	* include/freetype/config/public-macros.h (FT_EXPORT): Remove
+	special definition for C++.
+	(FT_UNUSED): Define here instead of...
+	* include/freetype/config/compiler-macros.h: ... here.
+	(FT_FUNCTION_DECLARATION): Remove special definition for C++.
+	(FT_LOCAL_ARRAY_DEF): Fix definition.
+
+	* src/cache/ftccback.h, src/lzw/ftzopen.h, src/gxvalid/gxvmort.h,
+	src/gxvalid/gxvmorx.h: Add `FT_BEGIN_HEADER' and `FT_END_HEADER'.
+
+2020-07-06  David Turner  <david@freetype.org>
+
+	[build] Fix multi and C++ builds.
+
+	The following builds were failing due to previous changes:
+
+	  make multi
+	  make multi CC="c++"
+
+	* include/freetype/config/ftconfig.h: Remove `FT_END_HEADER'.
+
+	* include/freetype/config/ftheader.h (FT_BEGIN_HEADER,
+	FT_END_HEADER): Protect against redefinition.
+
+	* src/cache/ftccache.h, src/cache/ftcmru.h, src/pcf/pcfutil.h,
+	src/psaux/pserror.h, src/psaux/psft.h, src/psaux/psstack.h,
+	src/sfnt/woff2tags.h: Include `compiler-macros.h'.
+
+	* src/sfnt/woff2tags.c: Include `woff2tags.h'.
+
+2020-07-06  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Improve `t1_decoder_parse_metrics' (#58646).
+
+	* src/psaux/t1decode.c (t1_decoder_parse_metrics): Copy
+	corresponding code from old engine's `t1_decoder_parse_charstrings'
+	function to handle `op_callsubr' and `op_return'.
+
+2020-07-05  David Turner  <david@freetype.org>
+
+	[build] Improve visibility support of library function names.
+
+	* include/freetype/config/public-macros.h
+	(FT_PUBLIC_FUNCTION_ATTRIBUTE): New macro to tag functions as
+	public (and thus exportable).
+	(FT_EXPORT): Use it.
+
+	* include/freetype/config/compiler-macros.h
+	(FT_INTERNAL_FUNCTION_ATTRIBUTE): New macro to tag functions as
+	internal to the library (and thus hidden).  Note that on ELF
+	systems, all internal functions have hidden visibility, which avoids
+	the need to enforce this when invoking the compiler (e.g., with an
+	option like `-fvisibility=hidden').
+
+	(FT_FUNCTION_DECLARATION, FT_FUNCTION_DEFINITION): New base macros
+	to deal with C and C++ linkage issues at the same time.
+
+	(FT_LOCAL, FT_LOCAL_DEF, FT_LOCAL_ARRAY, FT_LOCAL_ARRAY_DEF,
+	FT_BASE, FT_BASE_DEF, FT_EXPORT_VAR, FT_BASE_CALLBACK,
+	FT_BASE_CALLBACK_DEF): Redefined using new macros.
+
+2020-07-05  David Turner  <david@freetype.org>
+
+	[build] Split off more stuff from `ftconfig.h'.
+
+	* builds/unix/ftconfig.h.in, builds/vms/ftconfig.h,
+	include/freetype/config/ftconfig.h: Split off macro definitions
+	required by the FreeType API headers to...
+	* include/freetype/config/public-macros.h: ...this new file.
+
+	* builds/unix/ftconfig.h.in, builds/vms/ftconfig.h,
+	include/freetype/config/ftconfig.h: Split off macro definitions used
+	by the library but not to be exposed to clients to...
+	* include/freetype/config/compiler-macros.h: ...this new file.
+
+	* include/freetype/internal/*.h, src/raster/ftraster.h: Include
+	`compiler-macros.h' where needed.
+
+2020-07-05  David Turner  <david@freetype.org>
+
+	[build] Move mac support code to `mac-support.h'.
+
+	* builds/unix/ftconfig.h.in, builds/vms/ftconfig.h,
+	include/freetype/config/ftconfig.h: Split off mac-specific stuff
+	to...
+	* include/freetype/config/mac-support.h: ...this new file.
+
+	* CMakeLists.txt, builds/unix/configure.raw: Remove `/undef ->
+	#undef' string replacement; the affected code is no longer part of
+	the `ftconfig.h' template.
+
+2020-07-05  David Turner  <david@freetype.org>
+
+	[build] Put integer type definitions into `integer-types.h'.
+
+	Refactor some of the `ftconfig.h' headers and template to move the
+	definition of the FreeType integer types (e.g., `FT_Int16') to a
+	common header file `freetype/config/integer-types.h'.
+
+	* builds/unix/ftconfig.h.in, builds/vms/ftconfig.h,
+	include/freetype/config/ftconfig.h: Split off integer type
+	definition stuff to...
+	* include/freetype/config/integer-types.h: ...this new file.
+
+	* builds/unix/ftconfig.h.in: Control the definition of
+	`FT_SIZEOF_INT' and `FT_SIZEOF_LONG' with macro
+	`FT_USE_AUTOCONF_SIZEOF_TYPES'.  If these are not defined, auto
+	detection happens in `integer-types.h' as usual based on `INTXX_MAX'
+	values.  Otherwise the autoconf-detected values are used.
+
+	* builds/unix/configure.raw (CPPFLAGS): Don't include path to
+	`config' directory.  Instead, ...
+	(FT_CONFIG_STANDARD_LIBRARY_H): Use complete path.
+
+2020-07-05  David Turner  <david@freetype.org>
+
+	[build] Rename `build/unix/ftconfig.in' to `ftconfig.h.in'.
+
+	Since we are no longer limited to 8.3 file names, it is simpler to
+	follow the usual conventions for template files.
+
+	* builds/unix/ftconfig.in: Renamed to...
+	* builds/unix/ftconfig.h.in: ...this.
+
+	* CMakeLists.txt, builds/unix/configure.raw: Updated.
+
+2020-07-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Introduce direct oversampling for overlaps.
+
+	This implements oversampling to mitigate artifacts in pixels partially
+	covered by overlapping contours.  It turns out that the 4x4
+	oversampling is sufficient but, at least, quadruples the rendering
+	time.  The outline has to set FT_OUTLINE_OVERLAP to use this method.
+
+	* include/freetype/ftimage.h (FT_OUTLINE_OVERLAP): New flag.
+	* src/smooth/ftsmooth.c (ft_smooth_render): Check it to...
+	(ft_smooth_raster_overlap): ... inflate outline and set up direct
+	rendering for oversampling with...
+	(ft_smooth_overlap_spans): ... new span function that integrates them.
+
+2020-07-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Use direct rendering mode in Harmony.
+
+	Instead of rendering 3 bitmaps side by side and reshuffling, we use
+	direct rendering to deliver the bitmaps on each third byte.
+
+	* src/smooth/ftsmooth.c (ft_smooth_raster_lcd)
+	[!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Set up direct mode with...
+	(ft_smooth_lcd_spans): ... new span function.
+
+2020-07-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Separate LCD paths from gray rendering.
+
+	This makes `ft_smooth_render' a lot smaller and easier to follow. It
+	also cleanly separates Harmony and ClearType-style LCD rendering
+	algorithms. Now I only wish to move LCD filtering and geometry from
+	FT_Library to FT_Renderer.
+
+	* src/smooth/ftsmooth.c (ft_smooth_render): Move LCD code from here...
+	(ft_smooth_raster_lcd, ft_smooth_raster_lcdv): ... to here.
+	[FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Reorganize #ifdef's.
+
+2020-06-20  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[cff] Fix handling of `style_name == NULL' (#58630).
+
+	* src/cff/cffobjs.c (cff_face_init): If a call to `cff_strcpy' fails
+	by returning NULL in `cff_face_init', `remove_style' is still
+	called.  This means that the NULL pointer is dereferenced, causing a
+	crash.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[cff] Fix another two memory leaks (#58629).
+
+	* src/cff/cffobjs.c (cff_size_init): If a call to `funcs->create'
+	fails to allocate one of the `internal->subfont' variables, make
+	sure to free `internal->topfont' and any successfully allocated
+	subfonts.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[psaux] Fix memory leak (#58626).
+
+	* src/psaux/psstack.c (cf2_stack_init): If `cf2_stack_init' fails to
+	allocate the stack, return error early.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[base] Fix memory leak (#58624).
+
+	* src/base/ftobjs.c (FT_New_Size): Avoid trying to free
+	`size->internal' unless `size' has been allocated.  This mistake
+	appeared in the fix for issue #58611.
+
+2020-06-19  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] Rework d1180b5f9598 until further notice.
+
+	* src/base/ftoutln.c (FT_Outline_Get_Orientation): Reject large
+	outlines.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[cff, cid] Fix segfaults in case of error (#58621).
+
+	* src/cff/cffobjs.c (cff_slot_done), src/cid/cidobjs.c
+	(cid_slot_done): If `ft_glyphslot_init' fails to allocate
+	`internal', then the class' `done_slot' callback (called by
+	`ft_glyphslot_done') must not dereference the pointer to `internal'.
+
+2020-06-19  Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix UBSAN error.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23166
+
+	* src/base/ftoutln.c (FT_Outline_Get_Orientation): Avoid values
+	larger than 32 bits.
+
+2020-06-19  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix segfault.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23402
+
+	* src/sfnt/sfwoff2.c (get_x_mins): Check whether `loca' table
+	exists.
+
+2020-06-19  Stephen McDowell  <svenevs.dev@gmail.com>
+
+	[sfnt] Support Intel compilers.
+
+	* src/sfnt/pngshim.c (premultiply_data): Intel compilers do not
+	currently support `__builtin_shuffle'.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[base] Fix memory leak (#58611).
+
+	* src/base/ftobjs.c (FT_New_Size): When the call to `clazz->init_size'
+	fails, make sure to free `size->internal'.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[cff] Fix memory leak (#58610).
+
+	* src/cff/cffobjs.c (cff_size_init): When the call to
+	`funcs->create' fails, make sure to free `internal'.
+
+2020-06-19  Werner Lemberg  <wl@gnu.org>
+
+	* src/cff/cffload.c (cff_index_get_pointers): Rename `t' to `tbl'.
+
+2020-06-19  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[cff] Free table upon error allocating other data (#58609).
+
+	* src/cff/cffload.c (cff_index_get_pointers): When new_bytes fails
+	to allocate, make sure to free the table.  Do the same for both
+	allocations if there is a later error.
+
+2020-06-13  Werner Lemberg  <wl@gnu.org>
+
+	Remove redundant inclusion of `ft2build.h'.
+
+	* */*: Remove `#include <ft2build.h>' where possible.
+
+	* include/freetype/freetype.h: Remove cpp error about missing
+	inclusion of `ft2build.h'.
+
+2020-06-08  David Turner  <david@freetype.org>
+
+	Make macros for header file names optional.
+
+	We no longer have to take care of the 8.3 file name limit; this
+	allows us (a) to introduce longer, meaningful file names, and (b) to
+	avoid macro names in `#include' lines altogether since some
+	compilers (most notably Visual C++) doesn't support this properly.
+
+	*/*: Replace
+
+	   #include FOO_H
+
+	with
+
+	   #include <freetype/foo.h>
+
+	or something similar.  Also update the documentation.
+
+2020-06-02  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/ttcmap.c (tt_face_build_cmaps): Trace number of cmaps.
+
+2020-05-18  David Turner  <david@freetype.org>
+
+	Remove obsolete HAVE_STDINT_H probing macro.
+
+	This macro was updated by the unix configure script and the
+	`CMakeLists.txt' one, but is never used in the source tree (nor is
+	<stdint.h> included anywhere).
+
+	* CMakeLists.txt, builds/unix/ftconfig.in: Don't handle
+	`HAVE_STDINT_H'.
+
+2020-05-18  David Turner  <david@freetype.org>
+
+	Remove Jamfile files from the tree.
+
+	These have not been used in a very, very long time, so better remove
+	them.  A corresponding patch will be submitted to the
+	`freetype2-demos' repository.
+
+	* src/Jamfile, src/*/Jamfile, Jamrules: Delete.
+
+2020-05-12  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Turn on LCD filtering during FreeType initialization.
+
+	* src/smooth/ftsmooth.c (ft_smooth_init): Enable LCD filtering.
+
+	* include/freetype/ftlcdfil.h: Document it, remove patent warnings.
+	* include/freetype/freetype.h (FT_Render_Mode): Updated.
+	* include/freetype/config/ftoption.h, devel/ftoption.h
+	[FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Do not mention patents.
+
+2020-05-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Stop using dedicated LCD modules and classes.
+
+	The LCD modules were never truly independent. They mostly served as
+	a way to disable patented LCD rendering, which is no longer necessary.
+	The `smooth' module now handles LCD modes as well.
+
+	* src/smooth/ftsmooth.c (ft_smooth_lcd_renderer_class.
+	ft_smooth_lcdv_renderer_class): Deleted.
+	(ft_render_smooth): Reworked from `ft_render_smooth_generic'.
+	* src/smooth/ftsmooth.h: Remove dedicated LCD classes.
+	* src/smooth/module.mk: Remove dedicated LCD modules.
+	* include/freetype/config/ftmodule.h: Ditto.
+	* builds/amiga/include/config/ftmodule.h: Ditto.
+	* include/freetype/ftmodapi.h: Do not mention LCD modules.
+
+2020-05-09  Werner Lemberg  <wl@gnu.org>
+
+	* Version 2.10.2 released.
+	==========================
+
+
+	Tag sources with `VER-2-10-2'.
+
+	* docs/VERSION.TXT: Add entry for version 2.10.2.
+
+	* README, Jamfile (RefDoc), src/base/ftver.rc,
+	builds/windows/vc2010/index.html, builds/windows/visualc/index.html,
+	builds/windows/visualce/index.html,
+	builds/wince/vc2005-ce/index.html,
+	builds/wince/vc2008-ce/index.html, docs/freetype-config.1:
+	s/2.10.1/2.10.2/, s/2101/2102/.
+
+	* include/freetype/freetype.h (FREETYPE_PATCH): Set to 2.
+
+	* builds/unix/configure.raw (version_info): Set to 23:2:17.
+	* CMakeLists.txt (VERSION_PATCH): Set to 2.
+
+	* docs/CHANGES: Updated.
+
+2020-05-08  Jakub Alba  <jalba@vewd.com>
+
+	* src/truetype/ttinterp.c (TT_RunIns): Adjust loop counter (#58319).
+
+	The font that exceeds the old limit is Icono Regular, version
+	1.00000.
+
+2020-05-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/freetype.mk: Refactor for readability.
+
+2020-05-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds] Clean up Windows CE project files.
+
+	Remove version from filenames that caused a lot of pollution in the
+	release process. Use VERSIONINFO resource instead.
+
+	* builds/wince/vc2005-ce/freetype.vcproj,
+	builds/wince/vc2008-ce/freetype.vcproj,
+	builds/windows/visualce/freetype.vcproj,
+	builds/windows/visualce/freetype.dsp: s/2101//g, but add `ftver.rc'.
+	* builds/wince/vc2008-ce/index.html,
+	builds/wince/vc2005-ce/index.html,
+	builds/windows/visualce/index.html: s/2101//g.
+
+2020-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* devel/ft2build.h: Override FT_CONFIG_MODULES_H here as well.
+
+2020-05-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds/unix] Consolidate marco overrides (for the demos to see them).
+
+	* builds/unix/unix-cc.in (FT_CONFIG_MODULES_H, FT_CONFIG_OPTIONS_H):
+	Override them here...
+	* builds/freetype.mk: ... instead of here.
+
+2020-04-08  Werner Lemberg  <wl@gnu.org>
+
+	Allow setting `CC' in Unix build (#58051).
+
+	* builds/unix/unix-cc.in (CC): Use `override'.  The command line
+	  value of `CC' (if any) is stored already in `CCraw'.
+
+2020-04-04  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Return if single stream operation fails.
+
+	* src/sfnt/sfwoff2.c (get_x_mins): Do it.
+
+	* src/sfnt/woff2tags.c: Remove unused include.
+
+2020-03-22  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[docs] Fix building docs if `srcdir' != `builddir'.
+
+	`docs/reference/*' was moved one directory up in commit 237fed6.
+
+	* builds/unix/unix-def.in (PIP): Remove variable.
+
+	* configure: Create `docs' directory and copy assets from
+	`docs/markdown'.
+
+	* docs/README: Output directory is `reference'.
+
+2020-03-21  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[docwriter] Drop support for Python < 3.5.
+
+	Python versions < 3.5 have reached end-of-life and as such, no
+	security or bug fixes will be provided for those versions.  See
+
+	  https://devguide.python.org/#status-of-python-branches
+
+	for more information.
+
+	* Jamfile (RefDoc): Add `site' parameter.
+
+	* builds/detect.mk (std_setup): Update Python version requirement.
+
+	* builds/freetype.mk (refdoc-venv): Use pip as `python -m pip'.
+
+	* builds/unix/ax_compare_version.m4,
+	builds/unix/ax_prog_python_version.m4: Macros to detect Python
+	version.  New files.
+
+	* builds/unix/configure.raw: Check for Python >= 3.5 and remove
+	check for `pip'.
+
+	* docs/CHANGES, docs/INSTALL.GNU, docs/README: Updated.
+
+2020-03-02  Moazin Khatti  <moazinkhatri@gmail.com>
+
+	[gzip] Support `gzip' encoded header conditionally.
+
+	In order to support `gzip' encoded header the call to
+	`inflateInit2' was modified in commit 6a92b1fadde26477a9179.
+	However, this code breaks with the outdated internal version
+	of zlib.  This is a temporary fix to conditionally support
+	`gzip' encoded header whenever a system installation of zlib
+	is being used.
+
+	Problem report in
+
+	  https://lists.nongnu.org/archive/html/freetype-devel/2020-02/msg00023.html
+
+	* src/gzip/ftgzip.c (FT_Gzip_Uncompress): Change the the call to
+	`inflateInit2' depending on whether the system installation is
+	being used or the internal copy.
+
+2020-02-29  Ben Wagner  <bungeman@google.com>
+
+	[truetype] Fix state of `FT_Face' for buggy `gvar' tables (#57923).
+
+	By resetting the blend as implemented with this commit fonts with
+	invalid `gvar' tables may keep calling into `ft_var_load_gvar' from
+	`tt_set_mm_blend' and failing, but the font was invalid anyway and
+	we want to keep seeing the failure in `tt_set_mm_blend'.
+
+	* src/truetype/ttgxvar.c (ft_var_load_gvar): Calculate length of
+	offset array once.
+	Allocate arrays after `FT_FRAME_ENTER' (extra check before
+	allocating and avoid needing to free array later if error entering
+	frame).
+	Always call `FT_FRAME_EXIT'.
+	Consistently set counts immediately after array initialized.
+	Reset the blend (particularly `blend->glyphoffsets') on failure.
+
+2020-03-01  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[docs] Update docwriter stylesheet.
+
+	This change is required to support docwriter 1.2.1.
+
+	See
+
+	  https://github.com/freetype/docwriter/issues/36
+
+	for more information.
+
+	* docs/markdown/stylesheets/extra.css:
+	(.md-typeset code) -> (.md-typeset pre>code)
+	(pre) -> (pre>code)
+	(p, .md-typeset p, h4): Remove commented styles.
+	(table.index): Remove unused styles.
+
+2020-02-28  Ben Wagner  <bungeman@google.com>
+
+	[truetype] Add better checks for loading `gvar' table (#57905).
+
+	* src/truetype/ttgxvar.c (ft_var_load_gvar): Delay settings of any
+	`blend->xxxcount' values until the corresponding data has been
+	checked.
+	Also do some sanitizing to avoid a too early exit.
+
+	(TT_Vary_Apply_Glyph_Deltas): Improve tracing message.
+
+2020-02-27  Werner Lemberg  <wl@gnu.org>
+
+	Make `FT_HAS_*' and `FT_IS_*' really return true (#57906).
+
+	* include/freetype/freetype.h (FT_HAS_*, FT_IS_*): Implement it.
+
+2020-02-25  Dominik Röttsches  <drott@chromium.org>
+
+	Fix for CFF space glyph regression (#57541).
+
+	* src/psaux/psft.c (cf2_decoder_parse_substrings): Replace early-out
+	  with FT_OFFSET.
+
+2020-02-22  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix font table access.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20778
+
+	* src/sfnt/sfwoff2.c (get_x_mins): Explicitly check for presence of
+	`head' table, which might not have been processed yet.
+
+2020-02-21  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Make `t1_decoder_parse_metrics' handle `op_div' (#57519).
+
+	* src/psaux/t1decode.c (t1_decoder_parse_metrics): Copy
+	corresponding code from old engine's `t1_decoder_parse_charstrings'
+	function.
+
+2020-02-19  Nikolaus Waxweiler  <nikolaus.waxweiler@daltonmaag.com>
+
+	[autofit] Add support for Hanifi Rohingya script.
+
+	* src/autofit/afblue.dat: Add blue zone data for Hanifi Rohingya.
+	* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+	* src/autofit/afscript.h: Add Hanifi Rohingya standard character.
+
+	* src/autofit/afranges.c, src/autofit/afstyles.h: Add Hanifi
+	  Rohingya data.
+
+2020-02-19  Werner Lemberg  <wl@gnu.org>
+
+	Require HarfBuzz 1.8.
+
+	* builds/unix/configure.raw, CMakeLists.txt: Request HarfBuzz 1.8.0
+	or newer.
+
+	We are going to add auto-hinter support for Hanifi Rohingya, which
+	was introduced in Unicode 11.0.
+
+2020-02-12  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/ttcmap.c (tt_face_build_cmaps): Ignore version (#57708).
+
+2020-02-04  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttinterp.c (TT_RunIns): Adjust loop counter (#57732).
+
+	The font that exceeds the old limit is Constantine, version 1.001.
+
+2020-01-04  Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix `FREETYPE_PROPERTIES=type1:hinting-engine=adobe`.
+
+	* src/base/ftpsprop.c (ps_property_set) [hinting-engine]: Avoid an
+	incorrect return value that caused a warning.  The function did the
+	right thing, though.
+
+2020-01-03  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix memory leaks and a runtime warning.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19773
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18101
+
+	* src/sfnt/sfwoff2.c (compute_ULong_sum): Add missing cast.
+	(reconstruct_hmtx): Add missing deallocation calls.
+
+2020-01-02  Dominik Röttsches  <drott@chromium.org>
+
+	[truetype] Fix UBSan warning on offset to nullptr (#57501).
+
+	* src/truetype/ttinterp.c (Ins_CALL): Fail if `exc->FDefs' is null.
+
+2019-12-31  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Allow bitmap-only fonts (#57394).
+
+	* src/sfnt/sfwoff2.c (reconstruct_font): Fix test for `glyf' and
+	`loca' tables.
+
+2019-12-21  Hugh McMaster  <hugh.mcmaster@outlook.com>
+
+	[docs] (2/2) Fix generation of API documentation (#56745).
+
+	Creating the API Reference in the (new) `reference' sub-directory is
+	consistent with other documentation sub-topics, such as `design',
+	`glyphs' and `tutorial'.
+
+	This patch fixes broken hyperlinks in the documentation pointing to
+	and from the API Reference.  It also allows web assets to load from
+	their relative paths.
+
+	* builds/freetype.mk (DOC_DIR): Adjust.
+	(refdoc, refdoc-venv): Add `--site' argument.
+
+	* builds/toplevel.mk (do-dist): Updated.
+
+2019-12-21  Hugh McMaster  <hugh.mcmaster@outlook.com>
+
+	[docs] (1/2) Move static web assets (#56745).
+
+	* docs/reference/*: Move ...
+	* docs: ... one directory up.
+
+2019-12-21  Dominik Röttsches  <drott@chromium.org>
+
+	Fix more UBSan warnings on adding offset to nullptr (#57432).
+
+	* src/truetype/ttinterp.c (Ins_LOOPCALL), src/psaux/psft.c
+	(cf2_initLocalRegionBuffer): Use `FT_OFFSET'.
+
+2019-12-16  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Fix UBSan warnings on adding offsets to nullptr.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/chromium/issues/detail?id=1032152
+
+	* src/truetype/ttinterp.c (Ins_FDEF, Ins_IDEF): Use `FT_OFFSET'.
+
+2019-12-14  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Fix integer overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19305
+
+	* src/truetype/ttinterp.c (Ins_MIRP): Use `ADD_LONG'.
+
+2019-12-13  Werner Lemberg  <wl@gnu.org>
+
+	Another bunch of UBSan warnings on adding offsets to nullptr.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19427
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19433
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19441
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19451
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19452
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19457
+
+	* src/autofit/aflatin.c (af_latin_hints_compute_segments,
+	af_latin_hints_compute_edges): Use `FT_OFFSET'.
+
+	* src/base/ftstream.c (FT_Stream_EnterFrame): Use `FT_OFFSET'.
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings): Exit early
+	if there is no charstring.
+
+	* src/psaux/psobjs.c (t1_decrypt): Use `FT_OFFSET'.
+
+	* src/smooth/ftsmooth.c (ft_smooth_render_generic): Exit early for
+	zero bitmap dimensions.
+
+2019-12-09  Dominik Röttsches  <drott@chromium.org>
+
+	Fix more UBSan warnings on adding offset to nullptr (#57384).
+
+	* src/smooth/ftsmooth.c (ft_smooth_render_generic),
+	src/psaux/psobjs.c (ps_table_add): Use `FT_OFFSET'.
+
+2019-12-05  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttinterp.c (TT_RunIns): Use `FT_OFFSET'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/chromium/issues/detail?id=1030614
+
+2019-12-03  Werner Lemberg  <wl@gnu.org>
+
+	More nullptr offset UBSan warnings (#57331, #57347).
+
+	* src/autofit/afcjk.c (af_cjk_hints_compute_segments),
+	src/psaux/psft.c (cf2_getSeacComponent), src/truetype/ttinterp.c
+	(Ins_UNKNOWN): Use `FT_OFFSET'.
+
+2019-11-29  Dominik Röttsches  <drott@chromium.org>
+
+	Avoid more nullptr offset UBSan warnings (#57316).
+
+	* src/base/ftoutln.c (FT_Outline_Transform): Bail on empty points.
+	* src/cff/cffload.c (cff_subfont_load): Use `FT_OFFSET'.
+	* src/psaux/psft.c (cf2_decoder_parse_substrings): Early out if
+	`charstring_base' or `charstring_len' are null.
+	* src/sfnt/ttload.c (tt_face_load_name): Use `FT_OFFSET'.
+
+2019-11-23  John Stracke  <jstracke@Google.com>
+
+	[base] Really fix #57194.
+
+	Apply accidentally missed second part of patch.
+
+	* src/base/ftgloadr.c (FT_GlyphLoader_CheckPoints): Call
+	`FT_GlyphLoader_CreateExtra'.
+
+2019-11-23  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Avoid sanitizer warning (#57289).
+
+	* src/truetype/ttpload.c (tt_face_get_device_metrics): Use
+	`FT_OFFSET'.
+
+2019-11-23  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[truetype] Fix integer overflow (#57287).
+
+	* src/truetype/ttgload.c (compute_glyph_metrics): Use `SUB_LONG'.
+
+2019-11-23  Ben Wagner  <bungeman@google.com>
+
+	[sfnt] Avoid sanitizer warning (#57286).
+
+	* src/sfnt/ttcmap.c (tt_face_build_cmaps): Avoid possible `NULL +
+	offset' computation.
+	Tag `table' as `const'.
+
+2019-11-23  John Stracke  <jstracke@Google.com>
+            Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix `NULL + offset' sanitizer warnings (#57194).
+
+	* src/base/ftgloadr.c (FT_GlyphLoader_Adjust_Points,
+	FT_GlyphLoader_Adjust_Subglyphs): Use `FT_OFFSET'.
+	(FT_GlyphLoader_CreateExtra): Add short cut if some values are zero.
+
+2019-11-23  Werner Lemberg  <wl@gnu.org>
+
+	* include/freetype/internal/ftmemory.h (FT_OFFSET): New macro.
+
+	Use this for `base + offset' pointer calculations where `base' can
+	be NULL (triggering a sanitizer warning even if the resulting
+	pointer gets never dereferenced since it is undefined behaviour
+	in C).
+
+	Suggested by Ben Wagner.
+
+2019-11-23  Ben Wagner  <bungeman@google.com>
+
+	[sfnt] Ensure OTTO fonts have tables (#57285).
+
+	* src/sfnt/ttload.c (tt_face_load_font_dir): Add test.
+
+2019-11-23  Behdad Esfahbod  <behdad@behdad.org>
+
+	Minor fixes for recent compilers.
+
+	* src/gzip/infutil.h (inflate_mask): Add `const'.
+
+	* src/autofit/aflatin2.c: Include `ft2build.h'.
+
+2019-11-07  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	* CMakeLists.txt: Minor additions to the notes, compile
+	  builds/unix/ftsystem.c instead of src/base/ftsystem.c on UNIX.
+
+	The latter change is based on the code proposed by rim in #55235.
+
+2019-10-25  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Check `num_fonts' for TTCs.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18494
+
+2019-10-22  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Avoid undefined shift.
+
+	Also improve tracing.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18390
+
+2019-10-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/pngshim.c (premultiply_data): Optimize for __SSE__ only.
+
+2019-10-10  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (reconstruct_glyf): Check `triplet_size'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18108
+
+2019-10-09  John Tytgat  <John.Tytgat@esko.com>
+
+	[cff] Fix FT_FACE_FLAG_GLYPH_NAMES for CFF2 based fonts (#57023).
+
+	* src/cff/cffobjs.c (cff_face_init): Don't set
+	FT_FACE_FLAG_GLYPH_NAMES for CFF2 based fonts.
+
+2019-10-08  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix SFNT table checks.
+
+	Also reduce number of SFNT table lookups.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18065
+
+	* include/freetype/internal/wofftypes.h (WOFF2_InfoRec): Add fields
+	`glyf_table', `loca_table', and `head_table'.
+
+	* src/sfnt/sfwoff2.c (reconstruct_glyf): Update signature.
+	Use table pointers in `info' parameter.
+	(get_x_mins): Check `maxp_table'
+	Use table pointers in `info' parameter.
+	(reconstruct_font):  Use and set table pointers in `info' parameter.
+	Fix check for `glyf' and `loca' tables.
+	Update call to `reconstruct_glyf'.
+	(woff2_open_font): Updated.
+
+2019-10-06  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (reconstruct_glyf): Fix reallocation.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18046
+
+2019-10-06  Werner Lemberg  <wl@gnu.org>
+
+	Improve memory debugging.
+
+	* include/freetype/internal/ftmemory.h (FT_MEM_FREE): Use
+	`FT_DEBUG_INNER' to set source code file name and line.
+
+	* src/base/ftdbgmem.c (ft_mem_table_remove): Better formatting of
+	tracing message.
+
+2019-10-03  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2 (reconstruct_font): Fix reallocation.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17966
+
+2019-10-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftstroke.c (ft_stroker_inside): Speed up.
+
+2019-10-01  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2 (woff2_open_font): Initialize `woff2.ttc_fonts'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17804
+
+2019-09-30  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (reconstruct_font): Fix memory leak.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17812
+
+2019-09-30  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Reject fonts without `head' table.
+
+	Also fix memory deallocation in case of error.
+
+	`head' problem reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17820
+
+	* src/sfnt/sfwoff2.c (reconstruct_glyf): Don't use `stream_close'.
+	Abort if `head_table' is NULL.
+	Don't free `transformed_buf' in case of error.
+	(woff2_open_font): Don't set `uncompressed_buf' to NULL.
+
+2019-09-29  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix compiler warnings.
+
+	Problem reported by Alexei.
+
+	* src/sfnt/sfwoff2.c (reconstruct_glyf): Initialize `x_min'.
+	(reconstruct_font): Initialize `num_hmetrics'.
+	(woff2_open_font): Initialize `info'.
+
+2019-09-28  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Fix sanity check.
+
+	Correct thinkos in patch from 2019-09-01.
+
+2019-09-28  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix memory leaks.
+
+	One of them reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17766
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Free `info->x_mins' and
+	`woff2->ttc_fonts'.
+
+	(reconstruct_glyf): Initialize `info->x_mins'.
+
+2019-09-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftstroke.c (ft_stroker_cap): Speed up caps.
+
+2019-09-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftstroke.c (ft_stroker_outside): Speed up clipped miter.
+	* include/freetype/ftstroke.h: Wordsmith miter docs.
+
+2019-09-25  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Check (sum of) table sizes.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17684
+
+2019-09-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftstroke.c (ft_stroke_border_arcto): Speed up calculations.
+
+2019-09-20  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Fix memory leaks.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16896
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Fix error handling.
+	Free `uncompressed_buf'.
+	(reconstruct_font): Free `transformed_buf'.
+
+2019-09-17  Werner Lemberg  <wl@gnu.org>
+
+	* src/otvalid/otvcommon.c (otv_Coverage_get_last): Guard `count'.
+
+	Problem reported by Marc Schönefeld <marc.schoenefeld@gmx.org>.
+
+2019-09-17  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Check table index.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17100
+
+2019-09-15  Avi Halachmi (:avih)  <avihpit@yahoo.com>
+
+	[cmake] Don't fail if brotli is missing (#56894).
+
+	The libs which cmake controls are commented out at
+
+	  include/freetype/config/ftoption.h
+
+	and cmake un-comment each enabled library, but the brotli option was
+	not commented out, therefore `FT_CONFIG_OPTION_USE_BROTLI' remained
+	defined even if brotli was missing/disabled/etc.
+
+	Comment it such that cmake can control it, which means leaving it
+	undefined if brotli is missing.
+
+	* include/freetype/config/ftoption.h: Fix typo.
+
+2019-09-05  Werner Lemberg  <wl@gnu.org>
+
+	[cmake] Add brotli support.
+
+	* CMakeLists.txt (FT_WITH_BROTLI): New option.
+
+	* builds/cmake/FindBrotliDec.cmake: New file.
+
+2019-09-05  Werner Lemberg  <wl@gnu.org>
+
+	Fix handling of `AF_CONFIG_OPTION_INDIC'.
+
+	* devel/ftoption.h, include/freetype/config/ftoption.h:
+	`AF_CONFIG_OPTION_INDIC' needs `AF_CONFIG_OPTION_CJK'.
+
+2019-09-05  Werner Lemberg  <wl@gnu.org>
+
+	CMakeLists.txt: Fix generation of DLL related stuff (#56852).
+
+	Extract `version_info' variable from `builds/unix/configure.raw' and
+	use the data to correctly set `LIBRARY_VERSION' and
+	`LIBRARY_SOVERSION'.
+
+	Also use the data to set `ft_version' field in `freetype2.pc'.
+	Also fix the needed minimum version of HarfBuzz in `freetype2.pc'.
+
+2019-09-03  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (compute_ULong_sum): Fix undefined shift.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16933
+
+2019-09-01  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Add sanity check.
+
+	Don't trust `totalSfntSize' unconditionally.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16893
+
+2019-08-27  Dominik Röttsches  <drott@chromium.org>
+
+	[woff2] Don't use `FT_UInt64' (#56815).
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Use `FT_UInt32' for
+	`file_offset'.  This fixes builds on platforms where `FT_LONG64' is
+	not defined while still being sufficient to store a file offset.
+
+2019-08-27  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Prevent crash in `TT_Set_Named_Instance' (#56813).
+
+	* src/truetype/ttgxvar.c (TT_Set_Named_Instance): Fix error
+	handling.
+
+2019-08-27  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Fix compiler warnings.
+
+	* src/sfnt/sfwoff2.c (read_num_hmetrics): Remove unused argument
+	`table_len'.
+	Update caller.
+	(triplet_decode, compute_bbox, store_loca, reconstruct_glyf): Make
+	`i' variable unsigned.
+	(reconstruct_glyph): Remove condition which is always false.
+	(reconstruct_html): Removed unused argument `transformed_size'.
+	Update caller.
+
+	* src/sfnt/woff2tags.c (woff2_known_tags): Remove condition which is
+	always false.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Check whether known tag is in array bounds.
+
+	If table tag is not 0x3f, we expect a value between 0 and 62.  If
+	this is not the case, exit with errors.
+
+	* src/sfnt/sfwoff2/c: Check whether table tag makes sense.
+
+	* src/sfnt/woff2tags.c: Return 0 if tag is out of bounds.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	* src/sfnt/sfwoff2.c: Improve trace comments.
+
+	Adjust tracing levels for comments, and more formatting.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Support `hmtx' reconstruction when `glyf' is untransformed.
+
+	`reconstruct_hmtx' requires `info->x_mins' and `info->num_glyphs' to
+	reconstruct the hmtx table.  In case glyf is not transformed, we
+	call `get_x_mins' which does the necessary work.
+
+	* src/sfnt/sfwoff2.c (get_x_mins): New function.
+	(reconstruct_font): Call get_x_mins.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[sfnt] Support `face->num_faces' for WOFF2 fonts.
+
+	Set correct value of `face->num_faces' for WOFF2 fonts.  This is
+	being handled separately because we only load the tables for the
+	requested font face in `woff2_open_font' and create a single-face
+	sfnt stream.
+
+	The full discussion is at:
+
+	  https://lists.gnu.org/archive/html/freetype-devel/2019-08/msg00000.html
+
+	* src/sfnt/sfobjs.c (sfnt_open_font): Add parameter
+	`woff2_num_faces'.
+	(sfnt_init_face): Introduce variable `woff2_num_faces', and change
+	`face->root.num_faces' if `woff2_num_faces' is set.
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Validate requested face
+	index and handle negative face indices.
+
+	* src/sfnt/sfwoff2.h (woff2_open_font): Add parameter `num_faces' to
+	declaration.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Improve memory and error handling.
+
+	Free up memory after use, and improve error handling.
+
+	* src/sfnt/sfwoff2.c (reconstruct_font, woff2_open_font): Implement
+	changes.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Avoid too many calls to `FT_REALLOC'.
+
+	We do this by using `totalSfntSize' as an initial reference, and
+	extending the buffer when required.  This reduces rendering time
+	considerably.
+
+	* include/freetype/internal/wofftypes.h (WOFF2_HeaderRec): Add
+	`totalSfntSize', rename `total_sfnt_size' to `actual_sfnt_size'.
+
+	* src/sfnt/sfwoff2.c (write_buf): Add parameter `dst_size' to keep
+	track of and update total size of stream.
+
+	(WRITE_SFNT_BUF, WRITE_SFNT_BUF_AT): Modify macros accordingly.
+
+	(pad4, store_loca, reconstruct_glyf, reconstruct_hmtx,
+	reconstruct_font): Update parameters to accept `sfnt_size'.
+
+	(woff2_open_font): Add variable `sfnt_size'.  Use WOFF2 header field
+	`totalSfntSize' as initial reference (if value makes sense) and
+	allocate `totalSfntSize' bytes for the sfnt stream.  `write_buf'
+	handles reallocation if and when required.  Also resize the stream
+	to `actual_sfnt_size' after reconstruction.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Reconstruct `loca', `hmtx', and swap out stream.
+
+	Add necessary functions to reconstruct loca and hmtx tables (the two
+	remaining tables that can have a transform).  `woff2_open_font' is
+	now capable of loading a woff2 font face.  This code may still need
+	more refining and better memory management.
+
+	* include/freetype/internal/wofftypes.h (WOFF2_HeaderRec): Add total
+	(final) size of sfnt stream.
+
+	(WOFF2_InfoRec): Add header checksum value.
+
+	* src/sfnt/sfobjs.c (sfnt_open_font): Change `face_instance_index'
+	parameter to its pointer so its value can be modified by
+	`woff2_open_font'.
+
+	* src/sfnt/sfwoff2.c: (WRITE_SFNT_BUF_AT): New macro to write into
+	sfnt buffer at given position.
+
+	(write_buf): Add parameter `extend_buf' which allows caller to
+	specify whether buffer should be reallocated before copying data.
+
+	(WRITE_SFNT_BUF): Updated.
+
+	(pad4, store_loca, reconstruct_htmx): New functions.
+
+	(reconstruct_glyf): Calculate loca values and store them.
+
+	(reconstruct_font): Call `reconstruct_hmtx', write table record
+	entries, and calculate table checksums.  Also calculate font
+	checksum and update `checksumAdjustment' entry in head table.
+
+	(woff2_open_font): Open stream for sfnt buffer, swap out input
+	stream and return.
+
+	* src/sfnt/sfwoff2.h (woff2_open_font): Modify parameter to accept
+	pointer to `face_index'.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Reconstruct transformed `glyf' table.
+
+	Reconstruct `glyf' table if it is transformed in the uncompressed
+	table stream.  Also add necessary structures, macros and functions.
+
+	* include/freetype/internal/wofftypes.h (WOFF2_InfoRec,
+	WOFF2_SubstreamRec, WOFF2_PointRec): New structures.
+	(WOFF2_TableRec): s/OrigLength/dst_length/.
+
+	* src/sfnt/sfwoff2.c (READ_255USHORT, READ_BASE128): Use
+	`FT_SET_ERROR' to set implicit `error' variable.
+
+	(WRITE_SHORT): New macro.
+
+	(N_CONTOUR_STREAM, N_POINTS_STREAM, FLAG_STREAM, GLYPH_STREAM,
+	COMPOSITE_STREAM, BBOX_STREAM, INSTRUCTION_STREAM): New macros to
+	refer to substreams of the transformed `glyf' tables.
+
+	(Read255UShort, ReadBase128): Return errors set by `FT_READ_XXX'
+	macros.
+
+	(with_sign, safe_int_addition): New functions to add sign to values
+	based on a flag and perform safe addition respectively.
+
+	(triplet_decode): Decode variable-length (flag, xCoordinate,
+	yCoordinate) triplet for a simple glyph.   See
+
+	  https://www.w3.org/TR/WOFF2/#triplet_decoding
+
+	(store_points, compute_bbox, composteGlyph_size, reconstruct_glyf):
+	New functions.
+
+	(reconstruct_font): Call `reconstruct_glyf'.
+
+	* src/sfnt/sfwoff2.h: Add required constants.
+
+	* src/sfnt/woff2tags.h: Move out constants to `sfwoff2.h'.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Copy un-transformed tables to sfnt stream.
+
+	Copy un-transformed tables to the sfnt stream.
+
+	* src/sfnt/sfwoff2.c: (WRITE_SFNT_BUF): New macro.
+	(write_buf): New function.  Extend memory of `dst' buffer and copy
+	bytes from `src'.
+	(compute_ULong_sum): New function.  Calculate checksum of table.
+	(reconstruct_font): Change `FT_Byte* sfnt' to `FT_Byte**
+	sfnt_bytes'.  This has been done because we reallocate memory to
+	`sfnt' multiple times, which may change the pointer value of `sfnt'.
+	This new pointer must be propagated back to the caller.  Same reason
+	for using a double pointer in `write_buf'.
+
+	* src/sfnt/woff2tags.h (WOFF2_DEFAULT_MAX_SIZE): New macro used for
+	overflow checking.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Create stream for uncompressed buffer.
+
+	Uncompressed buffer is now an `FT_Stream'.
+
+	Perform basic checks and start iterating over tables.
+
+	* src/sfnt/sfwoff2.c (stream_close, find_table, read_num_hmetrics):
+	New functions.
+	(reconstruct_font): Modify parameters and iterate over tables.
+	(woff2_open_font): Updated.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Handle TTCs and start reconstructing font.
+
+	We `handle' TTCs by modifying the `indices' array to point to only
+	those tables that are part of the requested `face_index'.
+
+	Set and use `num_tables' in `WOFF2_TtcFont'.
+
+	* src/sfnt/sfwoff2.c (reconstruct_font): New function.
+	(woff2_open_font): Start reconstruction of font.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Get known tags from function.
+
+	Change `KnownTags' to a function (`woff2_known_tags').  This avoids
+	introducing a global constant array.  This function returns the
+	specified index without *any* checks.  The caller must ensure that
+	`index' is within array limits.
+
+	* src/sfnt/sfwoff2.c (woff2_open_font): Change `KnownTags[...]'
+	notation to `woff2_known_tags( ...  )'.
+
+	* src/sfnt/woff2tags.c: Perform changes.
+
+	* src/sfnt/woff2tags.h: Update definitions.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Minor.
+
+	* src/sfnt/sfwoff2.c (woff2_uncompress): Add error message
+	(woff2_open_font): Free `uncompressed_buf'.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Uncompress Brotli streams and `face_index' support.
+
+	WOFF2 compressed stream is now uncompressed if Brotli is available.
+	This data is stored in a separate buffer (uncompressed_buf) because
+	it does not contain direct table data.  Certain tables have
+	transformations applied to them, and they must be reconstructed
+	before we can write those tables to the SFNT stream.
+
+	`face_index' is now being passed as a parameter to
+	`woff2_open_font'.
+
+	* src/sfnt/sfobjs.c (sfnt_open_font): Add parameter
+	`face_instance_index'.
+
+	* src/sfnt/sfwoff2.c (woff2_uncompress): New function.
+	(woff2_open_font): Call `woff2_uncompress'.
+	(compute_first_table_offset): Fix return type.
+
+	* src/sfnt/sfwoff2.h (woff2_open_font): Modify declaration.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	* builds/unix/configure.raw: Change argument name to `brotli'.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	Add Brotli dependency and required checks.
+
+	Brotli is required for decompressing WOFF2 font directory streams.
+	The library is thus being added as an optional dependency for
+	FreeType.
+
+	* builds/unix/configure.raw: Add checks for `libbrotlidec'.
+	(REQUIRES_PRIVATE, LIBS_PRIVATE, LIBSSTATIC_CONFIG): Updated.
+
+	* devel/ftoption.h, include/freetype/config/ftoption.h
+	(FT_CONFIG_OPTION_USE_BROTLI): New macro.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Write SFNT Offset table.
+
+	* src/sfnt/sfwoff2.c (WRITE_USHORT, WRITE_ULONG): New macros.
+	(compare_tags): New function.
+	(woff2_open_font): Implement it.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	* src/sfnt/sfwoff2.c: #undef macros.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[woff2] Read table and collection directory.
+
+	* include/freetype/internal/wofftypes.h (WOFF2_TtcFontRec): New
+	structure.
+	(WOFF2_HeaderRec): Add more fields.
+
+	* src/sfnt/sfwoff2.c (READ_255USHORT, READ_BASE128, ROUND4): New
+	macros.
+	(Read255UShort, CollectionHeaderSize, compute_first_table_offset):
+	New functions.
+	(ReadBase128): Use `FT_READ_BYTE'.
+	(woff2_open_font): Add functionality to read table directory and
+	collection directory (if present).
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[sfnt] Include `woff2tags.c' for building.
+
+	* src/sfnt/rules.mk (SFNT_DRV_SRC): Add `woff2tags.c'.
+
+	* src/sfnt/sfnt.c: Include `woff2tags.c'.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[sfnt] Add WOFF2 constants.
+
+	Add constants required for WOFF2, and known table tags as defined in
+	the specification.  See
+
+	  https://www.w3.org/TR/WOFF2/#table_dir_format
+
+	for details.
+
+	* src/sfnt/woff2tags.c, src/sfnt/woff2tags.h: New files.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[sfnt] Read WOFF 2 header.
+
+	Check for WOFF2 tag, call `woff2_open_font', and implement it to read
+	header according to specification.
+
+	* include/freetype/internal/fttrace.h: Add `sfwoff2.c'.
+
+	* src/sfnt/rules.mk (SFNT_DRV_SRC): Add `sfwoff2.c'.
+
+	* src/sfnt/sfnt.c: Include `sfwoff2.c'.
+
+	* src/sfnt/sfobjs.c (sfnt_open_font): Check for `wOF2' tag and call
+	`woff2_open_font'.
+
+	* src/sfnt/sfwoff2.c, src/sfnt/sfwoff2.h: New files.
+
+2019-08-27  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	Add structures for WOFF2.
+
+	Add structures and macro for WOFF 2 header and table directory.
+
+	* include/freetype/internal/wofftypes.h (WOFF2_HeaderRec,
+	WOFF2_TableRec_): New structures.
+
+	* include/freetype/tttags.h (TTAG_wOF2): New macro.
+
+2019-08-26  Werner Lemberg  <wl@gnu.org>
+
+	* src/psaux/cffdecode.c (cff_operator_seac): Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16470
+
+2019-08-26  Werner Lemberg  <wl@gnu.org>
+
+	[type1] Fix `FT_Get_Var_Axis_Flags' (#56804).
+
+	* src/type1/t1load.c (T1_Get_MM_Var): Allocate space for axis flags.
+	Also remove redundant assignment.
+
+2019-07-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftbbox.c (cubic_peak): Sanitize left shift (#56586).
+
+2019-07-22  Weiyi Wu  <w1w2y3@gmail.com>
+
+	* src/cid/cidload.c (cid_hex_to_binary): Fix typo (#56653).
+
+2019-07-12  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt, winfonts] Avoid memory leaks in case of error (#56587).
+
+	* src/sfnt/sfwoff.c (woff_open_font): Call `FT_FRAME_EXIT' in case
+	of error.
+
+	* src/winfonts/winfnt.c (fnt_face_get_dll_font): Ditto.
+
+2019-07-12  Ben Wagner  <bungeman@google.com>
+
+	Properly handle phantom points for variation fonts (#56601).
+
+	* src/truetype/ttgload.c (TT_Process_Simple_Glyph): Scale phantom
+	points if HVAR and/or VVAR is present.
+
+2019-07-04  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] (2/2) Handle fonts that use SEAC for ligatures (#56580).
+
+	The same as previous commit but for the old engine.
+
+	* src/psaux/t1decode.c (t1operator_seac): Implement it.
+
+2019-07-04  Chris Liddell <chris.liddell@artifex.com>
+
+	[psaux] (1/2) Handle fonts that use SEAC for ligatures (#56580).
+
+	As originally intended, a Type 1 SEAC charstring would be used for
+	an accented glyph (like `acaron' or `uumlaut'), where the advance
+	width of the SEAC glyph is the same as that of the `base' glyph
+	(like `a' or `u').  In this case it is not uncommon for the SEAC
+	glyph to not use an (H)SBW opcode of its own but to rely on the
+	value from the base glyph.
+
+	However, out-of-spec fonts also use SEAC glyphs for ligatures (like
+	`oe' or `fi'), and in those cases the overall advance width is
+	greater than that of the `base' glyph.  For this reason we have to
+	allow that the SEAC glyph can have an (H)SBW value of its own, and
+	if it has, retain this value, rather than the one from the base
+	glyph.
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_escSEAC>:
+	Implement it.
+
+2019-07-01  Werner Lemberg  <wl@gnu.org>
+
+	* Version 2.10.1 released.
+	==========================
+
+
+	Tag sources with `VER-2-10-1'.
+
+	* docs/VERSION.TXT: Add entry for version 2.10.1.
+
+	* README, Jamfile (RefDoc), src/base/ftver.rc,
+	builds/windows/vc2010/freetype.vcxproj,
+	builds/windows/vc2010/index.html,
+	builds/windows/visualc/freetype.dsp,
+	builds/windows/visualc/freetype.vcproj,
+	builds/windows/visualc/index.html,
+	builds/windows/visualce/freetype.dsp,
+	builds/windows/visualce/freetype.vcproj,
+	builds/windows/visualce/index.html,
+	builds/wince/vc2005-ce/freetype.vcproj,
+	builds/wince/vc2005-ce/index.html,
+	builds/wince/vc2008-ce/freetype.vcproj,
+	builds/wince/vc2008-ce/index.html: s/2.10.0/2.10.1/, s/2100/2101/.
+
+	* include/freetype/freetype.h (FREETYPE_PATCH): Set to 1.
+
+	* builds/unix/configure.raw (version_info): Set to 23:1:17.
+	* CMakeLists.txt (VERSION_PATCH): Set to 1.
+
+	* include/freetype/fterrors.h (FT_Error_String): Fix C++ compilation.
+
+2019-06-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/bdf/bdfdrivr.c (bdf_cmap_char_{index,next}): Fix inequality.
+
+	Reported by Armin Hasitzka.
+
+2019-06-16  Werner Lemberg  <wl@gnu.org>
+
+	* src/tools/apinames.c: Formatting, minor edits.
+
+2019-06-16  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Disable hinting if no blue zones are available (#56450).
+
+	* src/autofit/afglobal.c (af_face_global_get_metrics): Start again
+	(with dummy hinter module) if no blue zones are present.
+
+	* src/autofit/aflatin.c (af_latin_metrics_init_blues): Change
+	signature to return error code.
+	If no blue zones are found, update `glyph_styles' array to hold
+	AF_STYLE_NONE_DFLT instead of the current style.
+	(af_latin_metrics_init): Return internal error code if no blue zones
+	are found.
+
+2019-06-16  Werner Lemberg  <wl@gnu.org>
+
+	Towards better VMS support.
+
+	More to come.
+
+	* builds/vms/LIBS.OPT_IA64, builds/vms/_LINK.OPT_IA64,
+	builds/vms/vmslib.dat: New files provided by Jouk Jansen
+	<joukj@hrem.nano.tudelft.nl>.
+
+	* builds/vms/ftconfig.h: Update, also from Jouk.
+
+2019-06-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/autofit/aflatin.c (af_latin_metrics_init_widths): Minor.
+
+2019-06-13  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Restore the span buffering for direct mode only.
+
+	The buffer size FT_MAX_GRAY_SPANS is set to 10 spans, which should be
+	enough to cover the entire scanline for simple glyphs in most cases:
+	each slightly slanted edge needs up to two spans, plus a filling span
+	in-between.  This is not new, we used to do it before cb4388783cecc.
+
+	* src/smooth/ftgrays.c (gray_TWorker): Add `spans' and `num_spans'.
+	(gray_hline, gray_sweep): Implement the span buffering.
+	(gray_raster_render): Use negative `num_spans' to avoid the direct
+	mode.
+
+2019-06-12  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* include/freetype/ftmodapi.h (FT_DebugHook_Func): Return error.
+
+	Fix a warning by adding a return value as in `TT_RunIns',
+	which should not be a compatibility issue.
+
+2019-06-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttobjs.c (tt_check_trickyness_family): Add `const'.
+
+2019-06-11  Moazin Khatti  <moazinkhatri@gmail.com>
+
+	[gzip] Add support for `gzip' encoded header.
+
+	* src/gzip/ftgzip.c (FT_Gzip_Uncompress): Modify the the call to
+	`inflateInit2' to enable support for `gzip' encoded headers.
+
+2019-06-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[type1,type42] Use `const' for string literals.
+
+	* include/freetype/internal/psaux.h (PS_Table_FuncsRec): Updated.
+	* include/freetype/internal/t1types.h (T1_EncodingRec): Updated.
+	* src/psaux/psobjs.[ch] (ps_table_add): Updated.
+	* src/type1/t1load.c (T1_Open_Face, parse_encoding): Updated.
+	* src/type42/t42objs.c (T42_Open_Face): Updated.
+	* src/type42/t42parse.c (t42_parse_encoding): Updated.
+
+	* src/cff/cffobjs.c (cff_face_init): Minor.
+
+2019-06-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf,pcf] Use `const' for string literals.
+
+	* src/bdf/bdf.h (bdf_property_t): Updated `name'.
+	* src/bdf/bdflib.c (_bdf_list_split,bdf_create_property,
+	_bdf_add_property,_bdf_ato*): Updated.
+	* src/bdf/bdfdrivr.c (bdf_interpret_style): Updated.
+	* src/pcf/pcfread.c (pcf_intrpret_style): Ditto.
+
+2019-06-07  Philip Race  <philip.race@oracle.com>
+
+	* src/base/ftinit.c (FT_Set_Default_Properties): Fix crash.
+
+	Terminate loop at end of environment.
+
+2019-05-31  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Solidify VC2005 builds.
+
+	* include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Explicitly
+	declare `_BitScanReverse' intrinsic.
+	* builds/windows/visualc/freetype.vcproj [Debug]: Disable intrinsics.
+
+2019-05-30  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[sfnt] Separate WOFF sources and headers.
+
+	Move WOFF sources and headers to separate files.
+
+	* include/freetype/internal/wofftypes.h, src/sfnt/sfwoff.c,
+	src/sfnt/sfwoff.h: New files.
+
+	* include/freetype/internal/fttrace.h: Register `sfwoff.c'.
+
+	* include/freetype/internal/internal.h: Define
+	FT_INTERNAL_WOFF_TYPES_H.
+
+	* include/freetype/internal/sfnt.h: Include FT_INTERNAL_WOFF_TYPES_H.
+
+	* include/freetype/internal/tttypes.h: Move out WOFF structures.
+
+	* src/sfnt/rules.mk: Add `sfwoff.c'.
+
+	* src/sfnt/sfnt.c: Include `sfwoff.c'.
+
+	* src/sfnt/sfobjs.c: Include `sfwoff.h', move out WOFF sources.
+
+2019-05-30  Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix `make multi'.
+
+	Reported by Nikhil.
+
+	* src/base/fterrors.c: Include FT_INTERNAL_DEBUG_H.
+
+2019-05-29  Ben Wagner  <bungeman@google.com>
+
+	[truetype] Fix copy-and-paste error (#56409).
+
+	* src/truetype/ttgload.c (load_truetype_glyph): Use correct indices
+	into `unrounded' array for phantom points.
+
+2019-05-29  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Fix 32bit builds (#56404).
+
+	Patch suggested by Ben Wagner <bungeman@google.com>.
+
+	* src/truetype/ttgxvar.c (FT_fixedToInt, FT_fixedToFdot6): Remove
+	harmful cast to unsigned type.
+
+2019-05-26  Ben Wagner  <bungeman@google.com>
+
+	* src/truetype/ttgload.c (TT_Process_Simple_Glyph): Improve accuracy.
+
+2019-05-23  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Draw glyphs without deltas in variation font (#56374).
+
+	* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Always fill
+	`unrounded' array.
+
+2019-05-21  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttinterp.c (opcode_name): Improve mnemonics.
+
+2019-05-16  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Actually scale varied CVT values.
+
+	Up to now, only the unscaled CVT values were varied; in other words,
+	the `CVAR' data was never used for bytecode hinting.
+
+	* src/truetype/ttgxvar.c (tt_cvt_ready_iterator): New auxiliary
+	function.
+	(tt_face_vary_cvt): Use it to trigger rescaling of CVT values.
+
+2019-05-16  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Use 26.6 format for storing unscaled CVT values.
+
+	If `CVAR' data is applied to variation fonts, fractional values are
+	possible.
+
+	* include/freetype/internal/tttypes.h (TT_FaceRec): Change type of
+	`cvt' from `FT_Short' to `FT_Int32'.
+
+	* src/truetype/ttgxvar.c (FT_fdot6ToFixed): New macro.
+	(tt_face_vary_cvt): Use it to update code to 26.6 format.
+
+	* src/truetype/ttobjs.c (tt_size_run_prep): Update code to 26.6
+	format.
+
+	* src/truetype/ttpload.c (tt_face_load_cvt): Stora data in 26.6
+	format.
+
+2019-05-16  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgload.c (load_truetype_glyph): Init `unrounded'.
+
+	This fixes linear advance width values for spacing glyphs.  Bug
+	introduced 2019-05-09.
+
+2019-05-16  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Avoid code duplication.
+
+	* src/truetype/ttobjs.c (tt_size_run_prep): Scale CVT values in this
+	function.
+	(tt_size_ready_bytecode): Updated.
+	* src/truetype/ttgload.c (tt_loader_init): Updated.
+
+2019-05-13  Jouk Jansen  <joukj@hrem.nano.tudelft.nl>
+
+	* vms_make.com: Updated.  Handle `bzip2' directory, too.
+
+2019-05-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/psaux/psfont.c (cf2_font_setup): Fix compiler warning.
+
+2019-05-12  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Doh.  Fix last commit to make it work.
+
+	Very embarrassing :-)
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14701
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14705
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14710
+
+	* src/truetype/ttgload.c (IS_DEFAULT_INSTANCE): Move up and add
+	argument; update all callers.
+	(TT_Process_Simple_Glyph): Use it.  The `unrounded' array is active
+	for variation fonts only, thus also enclose related code with
+	`#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT ...  #endif' where
+	necessary.
+	Revert commit a113e5d from 2019-05-09, and don't use `extra_points2'
+	but allocate a temporary array.
+	Speed up the scaling of the `unrounded' array.
+
+	* src/truetype/ttgxvar.c (FT_fixedToInt, FT_FixedToFdot6): Fix type
+	conversions and rounding.  The unsigned type must have more or equal
+	bits to the signed type.
+
+2019-05-09  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Increase precision of font variation (#54371).
+
+	This patch makes FreeType use font units in 26.6 format internally
+	instead of integers.
+
+	* src/truetype/ttgxvar.c (FT_fixedToFdot6): New macro.
+	(TT_Vary_Apply_Glyph_Deltas): Add argument to output unrounded font
+	coordinates.
+	* src/truetype/ttgxvar.h: Updated.
+
+	* src/truetype/ttgload.c (TT_Process_Simple_Glyph): Use
+	`extra_points2' array to temporarily hold unrounded point
+	coordinates; use them to compute scaled coordinates and linear
+	advance width and height.
+	(load_truetype_code): Adjust similarly.
+
+2019-05-09  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgload.c (TT_Process_Simple_Glyph): Minor.
+
+2019-05-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Faster fractions.
+
+	* src/smooth/ftgrays.c (SUBPIXELS): Replace with...
+	(FRACT): A fractional coordinate macro to use in...
+	(gray_render_line, gray_render_scanline): ... here.
+
+2019-05-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/raster/ftraster.c (Draw_Sweep): Unbreak.
+
+2019-05-05  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/raster/ftraster.c: Clean-ups.
+
+2019-05-05  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgxvar.c: More use of `FT_fdot14ToFixed'.
+
+2019-05-04  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/smooth/ftgrays.c (gray_render_line): Small shortcut.
+
+2019-05-04  Werner Lemberg  <wl@gnu.org>
+
+	Various clang 8.0 static analyzer fixes.
+
+	Reported by Sender Ghost <lightside@gmx.com>.
+
+	* src/autofit/afcjk.c (af_cjk_hints_compute_edges): Catch a corner
+	case where `edge->first' could be NULL.
+
+	* src/pfr/pfrobjs.c (pfr_slot_load): Remove unnecessary test of
+	`size'.
+
+	* src/raster/ftraster.c (Draw_Sweep): Catch a corner case where
+	`draw_right' might be NULL.
+
+	* src/sfnt/ttmtx.c (tt_face_get_metrics): Fix limit test for
+	`aadvance'.
+	Ensure `abearing' always hold a meaningful result.
+
+	* src/truetype/ttgload.c (load_truetype_glyph): Ensure `subglyph' is
+	not NULL before accessing it.
+	* src/truetype/ttgxvar.c (TT_Set_Named_Instance): Remove unnecessary
+	test of `namedstyle'.
+
+	* src/type42/t42parse.c (t42_parser_done): Ensure
+	`parser->root.funcs.done' is not NULL before accessing it.
+
+2019-05-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Miscellaneous macro updates.
+
+	* src/base/ftoutln.c (SCALED): Updated.
+	* src/smooth/ftgrays.c (SCALED): Ditto.
+	(FLOOR, ROUND, CEILING): Removed.
+	* src/psaux/psfixed.h (cf2_fracToFixed): Updated.
+
+2019-05-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Tweak LCD filtering.
+
+	* src/base/ftlcdfil.c (ft_lcd_filter_fir, _ft_lcd_filter_legacy):
+	Choose direction from bitmap's pixel_mode.
+	* include/freetype/internal/ftobjs.c (FT_Bitmap_LcdFilterFunc):
+	Updated.
+	* src/smooth/ftsmooth.c (ft_smooth_render_generic): Updated.
+
+2019-05-02  Werner Lemberg  <wl@gnu.org>
+
+	* vms_make.com: Updated (#56253).
+
+	Remove no longer existing directories (`autohint', `otlayout').
+	Update used base extensions.
+	Activate `autofit' module.
+	Add `gxvalid' module.
+	Update copyright notices.
+
+2019-04-29  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Simplify cubic Bézier flattening.
+
+	The previous implementation is correct but it is too complex.
+	The revised algorithm is based on the fact that each split moves
+	the control points closer to the trisection points on the chord.
+	The corresponding distances are good surrogates for the curve
+	deviation from the straight line.
+
+	This cubic flattening algorithm is somewhat similar to the conic
+	algorithm based the distance from the control point to the middle of
+	the chord.  The cubic distances, however, decrease less predictably
+	but are easy enough to calculate on each step.
+
+	The new algorithm produces slightly larger number of splits, which is
+	compensated by its simplicity.  The overall rendering performance is
+	improved by 1-2%.  The larger number of splits does not necessarily
+	result in higher quality, which stays comparable.
+
+	* src/smooth/ftgrays.c (gray_render_cubic): Replace the split
+	condition.
+
+2019-04-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Bithacks and cosmetics.
+
+	* src/smooth/ftgrays.c (gray_record_cell, gray_set_cell, gray_hline,
+	gray_render_conic, gray_convert_glyph_inner): Updated.
+
+2019-04-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Optimize Bézier bisections.
+
+	This change makes bisections faster by 20-30%. When inlined into
+	`gray_render_cubic', this makes the function faster by 10% and is
+	noticeable in the overall rendering performance.
+
+	* src/raster/ftraster.c (Split_Conic, Split_Cubic): Use shifts and
+	refactor.
+	* src/smooth/ftgrays.c (gray_split_conic, gray_split_cubic): Ditto.
+	* src/base/ftstroke.c (ft_conic_split, ft_cubic_split): Ditto.
+	* src/base/ftbbox.c (cubic_peak): Use shifts.
+
+2019-04-23  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/ttcmap.c (tt_cmap12_next): Remove dead code.
+
+	Found by clang 8.0's static analyzer and reported by Sender Ghost
+	<lightside@gmx.com>.
+
+2019-04-23  Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix thinko in previous commit.
+
+	* src/base/ftbitmap.c (FT_Bitmap_Blend): Check final width, not
+	target pitch.
+
+	Problem reported by Sender Ghost <lightside@gmx.com>.
+
+2019-04-22  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftbitmap.c (FT_Bitmap_Blend): Check target pitch.
+
+	Problem reported by Sender Ghost <lightside@gmx.com>.
+
+2019-04-22  Werner Lemberg  <wl@gnu.org>
+
+	Fix return value of `FT_Set_Named_Instance' (#56186).
+
+	* src/truetype/ttgxvar.c (TT_Set_Named_Instance): Correctly handle
+	internal return value -1 of `TT_Set_Var_Design'.
+
+2019-04-18  Werner Lemberg  <wl@gnu.org>
+
+	[pcf] Fix handling of undefined glyph (#56067).
+
+	This commit fixes the changes from 2018-07-21, which broke charmap
+	iteration.  We now add the default character as a new glyph with
+	index 0, thus increasing the number of glyphs by one (as before).
+
+	* src/pcf/pcfread.c (pcf_get_metrics): Adjust to new artificial
+	glyph with index 0.
+	Limit number of elements to 65534.
+	(pcf_get_bitmaps): Ditto.
+	Unify two loops into one; this avoids allocation of an intermediate
+	array.
+	(pcf_get_encodings): Don't flip indices but copy glyph metrics of
+	default character to index 0.
+	Also handle invalid default character.
+
+	* docs/CHANGES: Updated.
+
+2019-04-15  Minmin Gong  <gongminmin@msn.com>
+
+	* CMakeLists.txt: Avoid rewriting of unchanged configuration files.
+
+	Reported as
+
+	  https://savannah.nongnu.org/patch/index.php?9755
+
+2019-04-15  JDG  <JonathanG@iQmetrix.com>
+
+	* src/tools/apinames.c (main): Fix error message.
+
+	Reported as
+
+	  https://savannah.nongnu.org/patch/?9796
+
+2019-04-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Fix segfault in direct mode (#56092).
+
+	* src/base/ftoutln.c (FT_Outline_Render): Set missing clip_box for
+	direct mode.
+	* src/smooth/ftgrays.c (gray_raster_render): Use it.
+
+2019-04-06  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/ttcmap.c (tt_get_glyph_name): Pacify compiler (#56061).
+
+	This is for Visual Studio 2019 on ARM.
+
+2019-04-06  Werner Lemberg  <wl@gnu.org>
+
+	For distribution, replace `.tar.bz2' with `.tar.xz' bundles.
+
+	* builds/toplevel.mk (build): Do it.
+
+	* README, docs/CHANGES, docs/release: Updated.
+
+2019-04-06  Antony Lee  <anntzer.lee@gmail.com>
+
+	Make `glyph_name' parameter to `FT_Get_Name_Index' a `const'.
+
+	* include/freetype/freetype.h (FT_Get_Name_Index),
+	include/freetype/internal/ftobjs.h (FT_Face_GetGlyphNameIndexFunc),
+	include/freetype/internal/services/svgldict.h
+	(FT_GlyphDict_NameIndexFunc), src/base/ftobjs.c (FT_Get_Name_Index),
+	src/cff/cffdrivr.c (cff_get_name_index), src/sfnt/sfdriver.c
+	(sfnt_get_name_index), src/type1/t1driver.c (t1_get_name_index),
+	src/type42/t42drivr.c (t42_get_name_index): Add `const' to second
+	argument.
+
+2019-03-31  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[cff] Fix boundary checks.
+
+	642bc7590c701c8cd35a9f60fa899cfa518b17ff introduced dynamically
+	allocated memory when parsing CFF files with the "old" engine.  Bounds
+	checks have never been updated, however, leading to pointless
+	comparisons of pointers in some cases.  This commit presents a
+	solution for bounds checks in the CFF module with an extended logic
+	for the "old" engine while staying as concise as possible for the
+	"new" one.
+
+	* src/cff/cffparse.h: Introduce the struct `CFF_T2_StringRec' and
+	the additional field `t2_strings' within `CFF_ParserRec'.
+
+	* src/cff/cffparse.c (cff_parser_within_limits): Move all boundary
+	checks into this new function and update the rest of `cffparse.c' to
+	use it.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12137
+
+2019-03-20  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Fix Mongolian blue zone characters.
+
+	* src/autofit/afblue.dat: Use U+200D (ZERO-WIDTH JOINER) characters
+	to get medial forms for some Mongolian characters.
+	* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+2019-03-19  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Add support for Mongolian script.
+
+	As a de-facto standard, layouts using this script are constructed
+	horizontally line by line, then the lines are rotated clockwise for
+	vertical display.
+
+	* src/autofit/afblue.dat: Add blue zone data for Mongolian.
+	* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
+
+	* src/autofit/afscript.h: Add Mongolian standard characters.
+
+	* src/autofit/afranges.c, src/autofit/afstyles.h: Add Mongolian
+	data.
+
+2019-03-15  Werner Lemberg  <wl@gnu.org>
+
+	* Version 2.10.0 released.
+	==========================
+
+
+	Tag sources with `VER-2-10-0'.
+
+	* docs/VERSION.TXT: Add entry for version 2.10.0.
+	* docs/CHANGES: Updated.
+
+	* README, Jamfile (RefDoc), src/base/ftver.rc,
+	builds/windows/vc2010/freetype.vcxproj,
+	builds/windows/vc2010/index.html,
+	builds/windows/visualc/freetype.dsp,
+	builds/windows/visualc/freetype.vcproj,
+	builds/windows/visualc/index.html,
+	builds/windows/visualce/freetype.dsp,
+	builds/windows/visualce/freetype.vcproj,
+	builds/windows/visualce/index.html,
+	builds/wince/vc2005-ce/freetype.vcproj,
+	builds/wince/vc2005-ce/index.html,
+	builds/wince/vc2008-ce/freetype.vcproj,
+	builds/wince/vc2008-ce/index.html: s/2.9.1/2.10.0/, s/291/2100/.
+
+	* include/freetype/freetype.h (FREETYPE_MINOR): Set to 10.
+	(FREETYPE_PATCH): Set to 0.
+
+	* builds/unix/configure.raw (version_info): Set to 23:0:17.
+	* CMakeLists.txt (VERSION_MINOR): Set to 10.
+	(VERSION_PATCH): Set to 0.
+
+	* builds/toplevel.mk (version, winversion): Since the minor version
+	number has two digits now, never omit the patch number.  We would
+	get ambiguous zip file names otherwise.
+	(dist): Remove remnants of `docmaker' tool.
+	(do-dist): Remove unused intermediate files.
+
+	* src/cff/cffparse.c (destruct_c2s_item): Guard function with
+	CFF_CONFIG_OPTION_OLD_ENGINE macro.
+
+2019-03-07  Andrei Alexeyev  <0x416b617269@gmail.com>
+            Werner Lemberg  <wl@gnu.org>
+
+	Fix invalid function pointer casts.
+
+	This change should allow Freetype to work on WASM/Emscripten without
+	needing `-s EMULATE_FUNCTION_POINTER_CASTS=1'.
+
+	* src/autofit/afdummy.c (af_dummy_hints_apply): Fix signature.
+
+	* src/cid/cidload.c (cid_parse_font_matrix, parse_fd_array,
+	parse_expansion_factor, parse_font_name): Return `void', not
+	`FT_Error'.
+
+	* include/freetype/internal/ftobjs.h (FT_CMap_CharVarIsDefaultFunc):
+	Fix signature.
+
+2019-03-05  Werner Lemberg  <wl@gnu.org>
+
+	[base] Handle numeric overflow (#55827).
+
+	* src/base/ftglyph.c (FT_Glyph_Get_CBox): Use `FT_PIX_CEIL_LONG'.
+
+2019-03-05  Sebastian Rasmussen  <sebras@gmail.com>
+
+	[psaux] Fix use of uninitialized memory (#55832).
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString): The call to
+	`cf2_arrstack_setCount' may fail because the allocator ran out of
+	memory.  When this happens the stack is still written to before the
+	error condition is checked.  This means that FreeType writes outside
+	of allocated memory.  This commit moves the error check prior to the
+	stack assignment, hence the function now properly returns with an
+	error condition.
+
+2019-02-23  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftbitmap.c (FT_Bitmap_Blend): No fractional offsets.
+
+	The function only provided a framework without an actual
+	implementation, which this commit removes.
+
+2019-02-23  Werner Lemberg  <wl@gnu.org>
+
+	* src/tools/update-copyright-year: Insert `(C)'.
+
+2019-02-21  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[truetype] Mask numeric overflows.
+
+	* src/truetype/ttinterp.c (Move_CVT, Move_CVT_Stretched, Ins_MIRP):
+	Mask numeric overflows.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11681
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11734
+
+2019-02-21  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[psaux] Mask numeric overflow.
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings): Mask numeric
+	overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13041
+
+2019-02-16  Wink Saville  <wink@saville.com>
+
+	* src/autofit/afwarp.h (af_warper_compute): Fix declaration.
+
+2019-02-02  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	[truetype] Apply MVAR hasc, hdsc and hlgp metrics to current FT_Face metrics.
+
+	Instead of setting typo or win metrics as the new `FT_Face' metrics
+	indiscriminately, apply only typo deltas to the currently active
+	`FT_Face' metrics.  This prevents line height differences when the
+	default outlines were used as the regular face and instances for
+	everything else, for example.
+
+	* src/truetype/ttgxvar.c (tt_apply_mvar): Implement.
+
+2019-02-02  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	[sfnt] Use typo metrics if OS/2 fsSelection USE_TYPO_METRICS bit is set.
+
+	If the `OS/2' table exists and `fsSelection' bit 7
+	(USE_TYPO_METRICS) is set, use the `sTypo*' set of values to compute
+	the `FT_Face's ascender, descender, and height.  Otherwise, fall
+	back to old behavior.
+
+	* src/sfnt/sfobjs.c (sfnt_load_face): Implement.
+
+2019-01-18  John Tytgat  <John.Tytgat@esko.com>
+
+	[sfnt] Handle TT fonts having two PostScript font names (#55471).
+
+	* src/sfnt/sfdriver.c (sfnt_get_name_id): Prefer English over any
+	other language found for PostScript font names.
+
+2019-01-08  Chris Liddell <chris.liddell@artifex.com>
+
+	[psaux] Fix closepath (#55414).
+
+	All of the Type 1 path building is done with code common to the
+	revised CFF engine, with the exception of closepath, which was still
+	calling ps_builder_close_contour(), thus previously cached segments
+	were not always written to the path, and glyph corruption, or even
+	invalid outlines were possible.
+
+	* src/psauc/psinterp.c (cf2_interpT2CharString) <cf2_cmdCLOSEPATH>:
+	Switch to calling `cf2_glyphpath_closeOpenPath'.
+
+2018-12-29  Werner Lemberg  <wl@gnu.org>
+
+	* src/autofit/aflatin2.c: Some fixes from `aflatin.c' (#55310).
+
+2018-12-25  Werner Lemberg  <wl@gnu.org>
+
+	* src/psaux/cffdecode.c (cff_operaor_seac): Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11915
+
+2018-12-12  Werner Lemberg  <wl@gnu.org>
+
+	[gxvalid] Fix compiler warnings.
+
+	* src/gxvalid/gxvjust.c (gxv_just_check_max_gid),
+	src/gxvalid/gxvmort.c (gxv_mort_coverage_validate): Use `FT_UNUSED'.
+
+2018-12-11  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgload.c (TT_Hint_Glyph): Remove useless test.
+
+	`control_len' only gets its value from `n_ins' (and vice versa),
+	which is always read as `unsigned short' and thus can't be larger
+	than 0xFFFF.
+
+2018-12-04  Werner Lemberg  <wl@gnu.org>
+
+	[bdf] Ignore data after `ENDFONT'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10798
+
+	* src/bdf/bdflib.c (_bdf_parse_end): New function.
+	(_bdf_parse_glyphs): Switch to `_bdf_parse_end' after `ENDFONT' has
+	been encountered.
+
+2018-12-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/windows/visualc/freetype.dsp: Dust off.
+
+2018-11-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/windows/vc2010/freetype.vcxproj: Simplify.
+
+2018-11-27  Chris Liddell  <chris.liddell@artifex.com>
+
+	[type1,cff] Add FT_{Set,Get}_MM_WeightVector API calls.
+
+	For multiple master fonts, common usage (in Postscript) is to modify
+	the WeightVector of an existing font instance, this addition
+	supports that use.
+
+	* include/freetype/ftmm.h, src/base/ftmm.c (FT_Set_MM_WeightVector,
+	FT_Get_MM_WeightVector): New API functions.
+
+	* include/freetype/internalservices/svmm.h
+	(FT_Set_MM_WeightVector_Func, FT_Get_MM_WeightVector_Func): New
+	function types.
+	(MultiMasters): Add `set_mm_weightvector' and `get_mm_weightvector'
+	members.
+	(FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated.
+
+	* src/cff/cffdrivr.c (cff_set_mm_weightvector,
+	cff_get_mm_weightvector): New functions.
+	(cff_service_multi_masters): Register them.
+
+	* src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated.
+	This driver doesn't use the new interface.
+
+	* src/type1/t1load.c (T1_Set_MM_WeightVector,
+	T1_Get_MM_WeightVector): New functions.
+	* src/type1/t1driver.c (t1_service_multi_masters): Register them.
+	* src/type1/t1load.h: Updated.
+
+2018-11-27  Ben Wagner  <bungeman@google.com>
+
+	[cff] Fix compiler warning (#55105).
+
+	* src/cff/cffparse.c (cff_parser_run): Guard label only used if
+	CFF_CONFIG_OPTION_OLD_ENGINE is active.
+
+2018-11-27  Ben Wagner  <bungeman@google.com>
+
+	[truetype] Fix numeric overflow (#55103).
+
+	* src/truetype/ttgload.c (compute_glyph_metrics): Use `SUB_LONG'.
+
+2018-11-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[builds] Belated DLL support with vc2002-vc2008.
+
+	The solution and project files should be automatically upgraded for
+	the appropriate Visual C++ version.
+
+	* builds/windows/visualc/freetype.{sln,vcproj}: Major upgrades.
+	* builds/windows/visualc/index.html: Document the change.
+	* builds/windows/vc2005, builds/windows/vc2008: Removed as redundant.
+
+2018-11-22  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	* src/cff/cffparse.c: Please the compiler.
+
+2018-11-22  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[cff] Fix memory overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9869
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10869
+
+	* src/cff/cffparse.c (destruct_t2s_item, cff_parser_run): Store
+	evaluated T2 charstrings in separately allocated memory.
+
+2018-11-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/windows/{visualc,vc2005,vc2008}/freetype.vcproj: Fix it.
+
+2018-11-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Placeholder only for library-enabled LCD filtering.
+
+	* src/smooth/ftsmooth.c (ft_smooth_init): Add disabled
+	`FT_Library_SetLcdFilter' call.
+
+2018-11-09  Young Xiao  <yangx92@hotmail.com>
+
+	[psaux] Add safety guard (#54985).
+
+	* src/psaux/psobjs.c (cff_builder_close_contour): Do it.
+
+2018-11-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* builds/unix/configure.raw: Require `windows.h' for windres.
+
+2018-11-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[ftstroke] Fix unpredictable failures (#54986).
+
+	* src/base/ftstroke.c (ft_sroke_border_lineto): Fix lineto check.
+
+2018-11-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[ftstroke] Fix unpredictable failures (#54976).
+
+	* src/base/ftstroke.c (ft_sroke_border_close): Set the start tags.
+
+2018-11-07  Ben Wagner  <bungeman@google.com>
+
+	[truetype] Fix VF check from 2018-09-12 (#54973).
+
+	* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Use correct
+	offsets for estimates.
+
+2018-11-06  Werner Lemberg  <wl@gnu.org>
+
+	[pshinter] Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11242
+
+	* src/pshinter/pshrec.c (ps_dimension_add_t1stem): Implement it.
+
+2018-11-06  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix timeout in old CFF engine.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11260
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings)
+	<cff_op_sqrt> [CFF_CONFIG_OPTION_OLD_ENGINE]: Fix potential endless
+	loop.
+
+2018-11-04  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttgxvar.c: Use enum definitions.
+
+2018-11-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttgxvar.c (ft_var_apply_tuple): Adjust condition.
+
+2018-11-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttgxvar.c (ft_var_apply_tuple): Tracing tweaks.
+
+2018-11-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Revert due to specs: [truetype] Speed up variation IUP.
+
+2018-11-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttgxvar.c (ft_var_get_item_delta): Fixed logic.
+
+	Reported and tested by Behdad.
+
+2018-11-02  Shailesh Mistry  <shailesh.mistry@hotmail.co.uk>
+
+	[autofit] Prevent SEGV.
+
+	See
+
+	  https://bugs.ghostscript.com/show_bug.cgi?id=697545
+
+	for more details on how the bug was found.
+
+	* src/autofit/afloader.c (af_loader_load_glyph): Propagate error
+	code.
+
+2018-10-31  Alexei Podtelezhnikov <apodtele@gmail.com>
+
+	[truetype] Speed up variation IUP.
+
+	* src/truetype/ttgxvar.c (tt_delta_interpolate): Separate trivial
+	snapping to the same position from true interpolation.
+
+2018-10-31  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/type1/t1load.c (t1_set_mm_blend): Optimized.
+
+2018-10-31  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/truetype/ttgxvar.c (ft_var_get_item_delta): Optimized.
+
+2018-10-29  Werner Lemberg  <wl@gnu.org>
+
+	[base] Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11080
+
+	* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use `MUL_LONG'.
+
+2018-10-29  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10988
+
+	* src/cff/cffparse.c (cff_parser_run)
+	[CFF_CONFIG_OPTION_OLD_ENGINE]: Use `NEG_LONG'.
+
+2018-10-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[sfnt] Make `head' timestamps unsigned.
+
+	It's been more than 2^31 seconds since 1904.
+
+	* include/freetype/tttables.h (TT_Header): Change field types.
+	* src/sfnt/ttload.c (tt_face_load_generic_header): Updated.
+
+2018-10-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Revert: Align FreeType with standard C memory management.
+
+2018-10-27  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix numeric overflow.
+
+	Triggered by
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11157
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings) <cff_op_blend>
+	[CFF_CONFIG_OPTION_OLD_ENGINE]: Fix integer overflow.
+
+2018-10-20  Werner Lemberg  <wl@gnu.org>
+
+	Avoid endless loop while tracing (#54858).
+
+	* src/type1/t1load.c (parse_buildchar): Guard tracing stuff with
+	FT_DEBUG_LEVEL_TRACE.
+
+2018-10-17  David Demelier  <markand@malikania.fr>
+
+	* CMakeLists.txt: Specify `RUNTIME DESTINATION'.
+
+	This is needed for DLL builds.
+
+2018-10-07  Werner Lemberg  <wl@gnu.org>
+
+	A missing Unicode cmap is not a fatal error.
+
+	This is a follow-up to the previous commit.
+
+	* src/cff/cffobjs.c (cff_face_init), src/sfnt/sfobjs.c
+	(sfnt_load_face), src/type1/t1objs.c (T1_Face_Init),
+	src/type42/t42objs.c (T42_Face_Init): Implement it.
+
+2018-10-07  Werner Lemberg  <wl@gnu.org>
+
+	Fix handling of FT_CONFIG_OPTION_ADOBE_GLYPH_LIST (#54794).
+
+	* src/cff/cffcmap.c (cff_cmap_unicode_init), src/psaux/t1cmap.c
+	(t1_cmap_unicode_init), src/sfnt/ttcmap.c (tt_cmap_unicode_init):
+	Check `unicodes_init' field.
+
+2018-10-03  Werner Lemberg  <wl@gnu.org>
+
+	[ftgrays] Fix typo in stand-alone mode (#54771).
+
+	* src/smooth/ftgrays.c (FT_THROW) [STANDALONE_ &&
+	FT_DEBUG_LEVEL_TRACE]: Fix call to `FT_ERR_CAT'.
+
+2018-10-02  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix segfault.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10768
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings)
+	<cff_op_callothersubr> [CFF_CONFIG_OPTION_OLD_ENGINE]: Check
+	argument.
+
+2018-10-02  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10740
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings) <cff_op_roll>
+	[CFF_CONFIG_OPTION_OLD_ENGINE]: Use NEG_INT.
+
+2018-10-02  Werner Lemberg  <wl@gnu.org>
+
+	[pshinter] Handle numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10550
+
+	* src/pshinter/pshglob.c (psh_blues_snap_stem): Mask numeric
+	overflow.
+
+2018-09-27  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Align FreeType with standard C memory management.
+
+	* include/freetype/ftsystem.h: Include FT_TYPES_H.
+	(*FT_Alloc_Func, *FT_Realloc_Func): Use size_t for the size arguments.
+	* src/raster/ftmisc.h: Ditto.
+
+	* builds/amiga/src/base/ftsystem.c, builds/unix/ftsystem.c,
+	* builds/vms/ftsystem.c, src/base/ftsystem.c (ft_alloc, ft_realloc):
+	Use size_t for the size arguments.
+
+	* src/base/ftdbgmem.c (ft_mem_debug_alloc, ft_mem_debug_realloc): Use
+	FT_Offset, aka size_t, for the size arguments.
+
+2018-09-25  Werner Lemberg  <wl@gnu.org>
+
+	Fix handling of `FT_Bool'.
+
+	Before this commit we had code like
+
+	  (FT_Bool)( globals->glyph_styles[gindex] & 0x8000)
+
+	Since `FT_Bool' is defined to be an `unsigned char', the code
+	evaluated to something like
+
+	  (unsigned char)( 0x8532 & 0x8000)
+
+	which in turn expanded to
+
+	  (unsigned char)( 0x8000)
+
+	and finally yielded 0x00 – i.e., false – not as expected.
+
+	Problem reported and analyzed by Tony Smith <tony.smith@macro4.com>.
+
+	* include/freetype/fttypes.h (FT_BOOL): Add a comparison against
+	zero so that we always have a Boolean expression.
+
+	*/*: Replace castings to `FT_Bool' with calls to `FT_BOOL' where
+	possible.
+
+2018-09-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf] Speed up charmap access.
+
+	This makes FT_Get_Char_Index and FT_Get_Next_Char 4-5 times faster.
+
+	* src/bdf/bdfdrivr.c (bdf_cmap_char_{index,next}): Help binary search
+	with continuous prediction.
+
+2018-09-22  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bimap): Another tweak.
+
+	This one should be clearer. When the rounded monochrome bbox collapses
+	we add a pixel that covers most if not all original cbox.
+
+2018-09-21  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bimap): Further tweak.
+
+2018-09-21  Ben Wagner  <bungeman@google.com>
+
+	Improve auto-hinter handling of bitmap fonts (#54681).
+
+	For bitmap fonts, `FT_Load_Glyph' should either return an error or
+	not set the format to `FT_GLYPH_FORMAT_OUTLINE'.  However, in this
+	case `FT_Load_Glyph' calls into the auto-hinter which calls back
+	into `FT_Load_Glyph' with `FT_LOAD_NO_SCALE' in the flags, which
+	marks the glyph as `FT_GLYPH_FORMAT_OUTLINE' with an empty path
+	(even though it doesn't have any path).  It appears that the
+	auto-hinter should not be called when the face doesn't have
+	outlines.  The current test for using the auto-hinter in
+	`FT_Load_Glyph' checks whether the driver supports scalable
+	outlines, but not if the face supports scalable outlines.
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Directly check whether we have
+	scalable outlines.
+
+2018-09-21  Werner Lemberg  <wl@gnu.org>
+
+	[raster] Fix disappearing vertical lines (#54589).
+
+	* src/raster/ftraster.c (Vertical_Sweep_Span): Handle special case
+	where both left and right outline exactly pass pixel centers.
+
+2018-09-20  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bimap): Tiny rounding tweak.
+
+	This adds pixels in case a contour goes through the center
+	and they need to be turned on in the b/w rasterizer.
+
+2018-09-20  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Replace charmap implementation.
+
+	PCF comes with charmap lookup table, aka PCF encodings.  Using it
+	directly makes FT_Get_Char_Index and FT_Get_Next_Char 4-5 times
+	faster than the original BDF-like binary searches.
+
+	* src/pcf/pcf.h (PCF_EncodingRec): Removed.
+	(PCF_FaceRec): Remove `nencodings' and `encodings'.
+	* src/pcf/pcfdrivr.c (pcf_cmap_char_{index,next}): Replaced.
+	* src/pcf/pcfread.c (pcf_get_encodings): Store data differently.
+
+2018-09-20  Werner Lemberg  <wl@gnu.org>
+
+	[base] Remove unused function `FT_GlyphLoader_CopyPoints'.
+
+	* include/freetype/internal/ftgloadr.h, src/base/ftgloadr.c
+	(FT_GlyphLoader_CopyPoints): Do it.
+
+2018-09-19  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Prepare to replace charmap implementation.
+
+	* src/pcf/pcf.h (PCF_FaceRec): Updated to include...
+	(PCF_EncRec): ... this new structure to store charmap geometry.
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Store charmap geometry.
+
+2018-09-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Remove unused fields.
+
+	* src/pcf.h (PCF_FaceRec): Remove `charmap' and `charmap_handle'.
+	* src/bdfdrivr.h (BDF_FaceRec): Ditto.
+	* src/winfonts/winfnt.h (FNT_FaceRec): Ditto.
+
+2018-09-17  Werner Lemberg  <wl@gnu.org>
+
+	[pshinter] Handle numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10396
+
+	* src/pshinter/pshglob.c: Include FT_INTERNAL_CALC_H.
+	(psh_blues_snap_stem): Mask numeric overflow.
+
+2018-09-13  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Some fixes for VF checks.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10317
+
+	* src/truetype/ttgxvar.c (ft_var_load_gvar): Properly exit memory
+	frame if we have invalid glyph variation data offsets.
+	(tt_face_vary_cvt): Protect against missing `tuplecoords' array.
+	Fix typo.
+
+2018-09-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfdriver.c (sfnt_get_var_ps_name): Fix last commit.
+
+2018-09-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/sfdriver.c (sfnt_get_var_ps_name): Check `result'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10316
+
+2018-09-12  John Tytgat  <John.Tytgat@esko.com>
+
+	[sfnt] Better PS name handling (#54629).
+
+	* src/sfnt/sfdriver (IS_WIN, IS_APPLE): Omit language ID checks.
+	(get_win_string, get_apple_string): Return NULL when the PostScript
+	font name characters is not according to specification.
+	(get_win_string): Make trace output work if the high byte if
+	non-zero.
+	(sfnt_get_var_ps_name, sfnt_get_ps_name): Previously we preferred
+	Win PS name (when there is also an Apple PS name); change this into
+	a fallback to Apple PS name in case the Win PS name is invalid.
+
+2018-09-12  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Improve VF check.
+
+	Triggered by
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10255
+
+	* src/truetype/ttgxvar.c (ft_var_load_gvar): Use better limit check
+	for `tupleCount'.
+
+2018-09-12  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgxvar.c (ft_var_load_gvar): Check `glyphoffsets'.
+
+2018-09-10  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	* src/pshinter/pshrec.c (t2_hints_stems): Mask numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10215
+
+2018-09-09  Ben Wagner  <bungeman@google.com>
+
+	* builds/freetype.mk (refdoc-venv): Ensure python version (#54631).
+
+2018-09-07  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Fix assertion failure.
+
+	Triggered by
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10212
+
+	* src/truetype/ttgload.c (load_truetype_glyph): Reintroduce
+	`opened_frame' (removed in a change from 2018-08-26) to handle
+	deallocation of the second frame.
+
+2018-09-05  Werner Lemberg  <wl@gnu.org>
+
+	Synchronize `ftdebug.c' files.
+
+	* builds/amiga/src/base/ftdebug.c, builds/wince/ftdebug.c,
+	builds/windows/ftdebug.c: Synchronize with `src/base/ftdebug.c'.
+
+2018-09-05  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	Add documentation guidelines file.
+
+	* docs/DOCGUIDE: New file.
+
+2018-09-04  Werner Lemberg  <wl@gnu.org>
+
+	* devel/ftoption.h: Synchronize with master `ftoption.h'.
+
+2018-09-03  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[docwriter] Don't break code snippets accross lines.
+
+	Reported as
+
+	  https://lists.nongnu.org/archive/html/freetype-devel/2018-08/msg00124.html
+
+	* docs/reference/markdown/stylesheets/extra.css (.md-typeset code):
+	Add rule `white-space'.
+
+2018-09-03  Werner Lemberg  <wl@gnu.org>
+
+	*/*: s/PSNames/psnames/.
+
+	Only tracing messages are affected.
+
+2018-09-03  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix heap buffer overflow in CPAL handling.
+
+	* src/sfnt/ttcpal.c (tt_face_palette_set): Fix boundary test.
+	(tt_face_load_cpal): Updated.
+
+2018-09-01  Werner Lemberg  <wl@gnu.org>
+
+	Remove `FT_Outline_{New,Done}_Internal'.
+
+	These public API functions(!) were always undocumented and have
+	escaped all clean-up efforts until now.
+
+	* include/freetype/ftoutln.h (FT_Outline_New_Internal,
+	FT_Outline_Done_Internal): Removed.
+
+	* src/base/ftoutln.h (FT_Outline_New_Internal,
+	FT_Outline_Done_Internal): Merge into...
+	(FT_Outline_New, FT_Outline_Done): ... these functions.
+
+	* docs/README: Updated.
+
+2018-08-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Check glyph format.
+
+2018-08-31  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[errors] Refine the macro logic surrounding `FT_Error_String'.
+
+	* include/freetype/fterrors.h (FT_INCLUDE_ERR_PROTOS,
+	FT_ERR_PROTOS_DEFINED): Undefine `FT_INCLUDE_ERR_PROTOS' after
+	checking it and introduce a new macro that takes proper care of
+	multiple-inclusion protection.
+
+2018-08-31  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftdebug.c (FT_Throw): Restore missing `FT_UNUSED' calls.
+
+2018-08-31  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftdebug.c (FT_Throw): Reduce chattiness.
+
+2018-08-31  Werner Lemberg  <wl@gnu.org>
+
+	* src/autofit/afhints.c (af_glyph_hints_reload): Add initialization.
+
+2018-08-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	Consolidate bitmap presetting and size assessment.
+
+	* include/freetype/internal/ftobjs.h (ft_glyphslot_preset_bitmap):
+	Change return type.
+	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Return the bitmap
+	size assessment.
+
+	* src/raster/ftrend1.c (ft_raster1_render): Use it to refuse the
+	rendering of enourmous or far-fetched outlines.
+	* src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto.
+
+2018-08-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Correct mono.
+
+2018-08-30  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[errors] Introduce a macro to control `FT_Error_String'.
+
+	* devel/ftoption.h (FT_CONFIG_OPTION_ERROR_STRINGS),
+	include/freetype/config/ftoption.h (FT_CONFIG_OPTION_ERROR_STRINGS):
+	New macro.
+
+2018-08-30  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[errors] Introduce `FT_Error_String'.
+
+	* include/freetype/fterrors.h (FT_Error_String),
+	src/base/fterrors.c (FT_Error_String): Implement `FT_Error_String'.
+
+	* src/base/ftbase.c, src/base/Jamfile (_source),
+	src/base/rules.mk (BASE_SRC): Add `fterrors.c' to the build logic.
+
+	* src/base/ftdebug.c (FT_Throw): Use `FT_Error_String'.
+
+2018-08-30  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Trace `before' and `after' edges of strong points.
+
+	* src/autofit/afhints.h (AF_PointRec) [FT_DEBUG_AUTOFIT]: New arrays
+	`before' and `after'.
+
+	* src/autofit/afhints.c (af_get_strong_edge_index): New auxiliary
+	function.
+	(af_glyph_hints_dump_points): Trace `before' and `after' edges.
+	(af_glyph_hints_align_strong_points) [FT_DEBUG_AUTOFIT]: Set
+	`before' and `after' information.
+
+2018-08-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] Overflow-resistant bitmap presetting.
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Implement it.
+
+2018-08-29  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	Fix numeric overflows.
+
+	* src/pshint/pshalgo.c (psh_hint_align, psh_hint_align_light,
+	psh_hint_table_find_strong_points): Fix numeric overflows.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10083
+
+2018-08-29  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix handling of `roll' op in old engine.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10080
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings) <cff_op_roll>
+	[CFF_CONFIG_OPTION_OLD_ENGINE]: Use modulo for loop count, as
+	documented in the specification.
+
+2018-08-26  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttobjs.c (tt_size_read_bytecode): Trace CVT values.
+
+2018-08-26  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	* configure: Copy assets required by docwriter.
+
+	Copy directory `docs/reference/markdown' when FreeType is compiled in a
+	different directory.
+
+	Fixes `make refdoc' if builddir != srcdir.
+
+	Reported as
+
+	  https://lists.nongnu.org/archive/html/freetype-devel/2018-08/msg00083.html
+
+2018-08-26  Werner Lemberg  <wl@gnu.org>
+
+	* src/pshint/pshalgo.c (psh_hint_overlap): Fix numeric overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10057
+
+2018-08-26  Werner Lemberg  <wl@gnu.org>
+
+	Minor tracing adjustments.
+
+	* src/base/ftstream.c (FT_Stream_EnterFrame, FT_Stream_ExitFrame):
+	Trace.
+
+	* src/truetype/ttgload.c (TT_Access_Glyph_Frame): Remove tracing.
+
+2018-08-26  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Avoid nested frames.
+
+	Triggered by
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10054
+
+	* src/truetype/ttgload.c (load_truetype_glyph): Don't use variable
+	`opened_frame' to trace whether a frame must be closed at the end of
+	function: This fails because `TT_Vary_Apply_Glyph_Deltas' (which
+	gets called for space glyphs) uses a frame by itself.  Instead,
+	close the frame after loading the header, then use another frame for
+	the remaining part of the glyph later on.
+
+	Also avoid calling `tt_get_metrics' twice under some circumstances.
+
+2018-08-26  Werner Lemberg  <wl@gnu.org>
+
+	Various minor clean-ups.
+
+	* src/base/ftapi.c: Remove.  Unused.
+	* src/base/Jamfile (_sources): Updated.
+
+	* src/base/ftstream.c (FT_Stream_ReleaseFrame): Remove redundant
+	code.
+
+2018-08-25  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	Convert documentation markup to Markdown.
+
+	It is the result of a GSoC 2018 project; this separate ChangeLog
+	commit covers the last four commits
+
+	  ae5d1a4cec37557f31aec270332cfe886a62f9a0
+	  53c69ce04faed3dcc68ca0f54cb8d703d8babf69
+	  195728d5ba38f34fb2c2c20807c01656f2f59b66
+	  c962db28ea59225f0105c03d907d4a9b71765687
+
+	* docs/reference/markdown/images/favico.ico,
+	docs/reference/markdown/javascripts/extra.js,
+	docs/reference/markdown/stylesheets/extra.css: New files.
+
+	* docs/reference/.gitignore, docs/reference/README: Updated.
+
+	* src/tools/docmaker/*: Removed.  It has been replaced with
+	`docwriter', a python package available at
+
+	  https://pypi.org/project/docwriter/
+
+	* Jamfile: Updated.
+	* builds/ansi/ansi-def.mk, builds/beos/beos-def.mk,
+	builds/dos/dos-def.mk, builds/os2/os2-def.mk (BIN),
+	builds/unix/unixddef.mk, builds/windows/win32-def.mk: New variable.
+
+	* builds/unix/configure.raw: Check for `python' and `pip'.
+	If not present, warn that `make refdoc' will fail.
+	* builds/unix/unix-def.in (PYTHON, PIP, BIN): New variables.
+
+	* builds/freetype.mk (PYTHON, PIP, VENV_NAME, VENV_DIR, ENV_PYTHON,
+	ENV_PIP): New variables.
+	(refdoc): Updated.
+	(refdoc-venv): New target.
+	(.PHONY): Updated.
+
+2018-08-23  Werner Lemberg  <wl@gnu.org>
+
+	Add macros for handling over-/underflowing `FT_Int64' values.
+
+	* include/freetype/internal/ftcalc.h (ADD_INT64, SUB_INT64,
+	MUL_INT64, DIV_INT64) [FT_LONG64]: New macros.
+
+	* src/base/ftcalc.c (ft_corner_orientation) [FT_LONG64]: Use
+	`SUB_INT64' and `MUL_INT64'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10028
+
+2018-08-22  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Improve legibility of `glyf' parsing.
+
+	* src/truetype/ttgload.c (ON_CURVE_POINT, X_SHORT_VECTOR,
+	Y_SHORT_VECTOR, REPEAT_FLAG, X_POSITIVE, SAME_X, Y_POSITIVE, SAME_Y,
+	OVERLAP_SIMPLE): New macros.
+	(TT_Load_Simple_Glyph): Use new macros to make code more readable.
+	Remove useless adjustment of `outline->tags' elements.
+
+2018-08-21  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/ttcpal.c (tt_face_load_cpal): Add missing safety check.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9981
+
+2018-08-18  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Avoid slow PS font parsing in case of error.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9955
+
+	* src/psaux/psobjs.c (ps_parser_to_bytes): Set `parser->cursor' even
+	in case of error to avoid potential re-scanning.
+
+2018-08-18  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix heap buffer overflow in old engine.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9967
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings)
+	<cff_op_blend> [CFF_CONFIG_OPTION_OLD_ENGINE]: `num_designs' must be
+	non-zero.
+
+2018-08-16  Young Xiao  <yangx92@hotmail.com>
+
+	* builds/mac/ftmac.c (parse_fond): Fix buffer overrun.
+
+	Reported as bug #54515, duplicate of #43540.
+
+2018-08-16  Werner Lemberg  <wl@gnu.org>
+
+	* builds/*/ftsystem.c (FT_COMPONENT): Updated also.
+
+2018-08-15  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf] Don't track duplicate encodings.
+
+	There is no harm except some umbiguity in broken fonts with duplicate
+	encodings.
+
+	* src/bdf/bdflib.c (_bdf_parse_glyphs): Remove duplicate tracking.
+	(_bdf_parse_t): Remove large `have' bitfield.
+
+2018-08-15  Werner Lemberg  <wl@gnu.org>
+
+	Don't use `trace_' prefix for FT_COMPONENT arguments.
+
+	* include/freetype/internal/ftdebug.h (FT_TRACE_COMP,
+	FT_TRACE_COMP_): New auxiliary macros to add `trace_' prefix.
+	(FT_TRACE): Use `FT_TRACE_COMP'.
+
+	*/* (FT_COMPONENT): Updated.
+
+2018-08-14  Werner Lemberg  <wl@gnu.org>
+
+	Use formatting string in FT_TRACEX calls for non-simple arguments.
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings)
+	<cff_op_hstem, cff_op_hintmask, cff_op_hlineto, cff_op_vhcurveto>:
+	Do it.
+
+	* src/psaux/pshints.c (cf2_hintmap_build): Ditto.
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_cmdHSTEM,
+	cf2_cmdVSTEM, cf2_cmdHLINETO, cf2_cmdRRCURVETO, cf2_cmdCALLSUBR,
+	cf2_escHSTEM3, cf2_cmdHINTMASK, cf2_cmdHVCURVETO>: Ditto.
+
+	* src/truetype/ttinterp.c (TT_RunIns): Ditto.
+
+2018-08-14  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf] Remove unused fields.
+
+	* src/bdf/bdf.h (bdf_font_t): Remove `nmod', `umod', and `modified',
+	which were set but never used.
+	* src/bdf/bdflib.c (_bdf_parse_{glyphs,properties}, bdf_load_font):
+	Updated accordingly.
+
+2018-08-14  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix another segv in old engine.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9872
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings)
+	[CFF_CONFIG_OPTION_OLD_ENGINE]: Disallow invalid T1 opcodes in
+	dictionaries.
+
+2018-08-14  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix missing error handling.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9865
+
+	* src/psaux/cffparse.c (cff_parser_run)
+	[CFF_CONFIG_OPTION_OLD_ENGINE]: Don't ignore return value of
+	`parse_charstrings_old'.
+
+2018-08-14  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf] Remove unused overflow storage.
+
+	* src/bdf/bdf.h (bdf_glyphlist_t): Remove this type.
+	(bdf_font_t): Remove `overflow' field.
+	* src/bdf/bdflib.c (bdf_free_font): Remove `overflow' freeing.
+
+2018-08-14  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix segv in old engine.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9864
+
+	* src/psaux/cffdecode.c (cff_decoder_parse_charstrings)
+	<cff_op_random> [CFF_CONFIG_OPTION_OLD_ENGINE]: Use top dict's
+	`random' field directly if parsing dictionaries.
+
+2018-08-13  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[bdf] Use unsigned types.
+
+	* src/bdf/bdf.h (bdf_glyph_t): Unsign `encoding'.
+	(bdf_font_t): Unsign `default_char'.
+	* src/bdf/bdfdrivr.h (BDF_encoding_el): Unsign `enc'.
+
+	* src/bdf/bdflib.c (_bdf_add_property, _bdf_parse_glyphs,
+	_bdf_parse_start): Updated accordingly.
+	* src/bdf/bdfdrivr.c (bdf_cmap_char_{index,next}): Ditto.
+
+2018-08-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/type42/t42parse.c (t42_parse_sfnts): One more format check.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9832
+
+2018-08-11  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftcalc.c (FT_Matrix_Check): Fix integer overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9811
+
+2018-08-10  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/sfnt/ttsbit.c (tt_sbit_decoder_load_compound): Follow specs.
+
+2018-08-10  Ben Wagner  <bungeman@google.com>
+
+	* src/sfnt/sfobjs.c (sfnt_done_face): Fix memory leak (#54435).
+
+2018-08-10  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Improve tracing.
+
+2018-08-10  Werner Lemberg  <wl@gnu.org>
+
+	Fix clang warnings.
+
+	* src/base/ftdebug.c (ft_trace_level_enabled,
+	ft_trace_level_disabled): Add `static' keyword.
+
+2018-08-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster, smooth] Reinstate bitmap size limits.
+
+	This again moves outline and bitmap size checks one level up.
+
+	* src/base/ftoutln.c (FT_Outline_Render): Explicitly reject enormous
+	outlines.
+	* src/raster/ftrend1.c (ft_raster1_render): Reject enormous bitmaps
+	and, therefore, outlines that require them.
+	* src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto.
+
+	* src/raster/ftraster.c (ft_black_render): Remove outline size checks.
+	* src/smooth/ftgrays.c (gray_raster_render): Ditto.
+	[STANDALONE]: Remove `FT_Outline_Get_CBox' copy.
+
+2018-08-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Revert massive unsigning.
+
+2018-08-08  Werner Lemberg  <wl@gnu.org>
+
+	[smooth] Improve tracing.
+
+	* src/smooth/ftgrays.c (gray_convert_glyph_inner): Only use tracing
+	if called the first time.
+	(gray_convert_glyph): Updated.
+
+2018-08-08  Werner Lemberg  <wl@gnu.org>
+
+	Add internal functions `FT_Trace_Disable' and `FT_Trace_Enable'.
+
+	It sometimes makes sense to suppress tracing informations, for
+	example, if it outputs identical messages again and again.
+
+	* include/freetype/internal/ftdebug.h: Make `ft_trace_levels' a
+	pointer.
+	(FT_Trace_Disable, FT_Trace_Enable): New declarations.
+
+	* src/base/ftdebug.c (ft_trace_levels): Rename to...
+	(ft_trace_levels_enabled): ... this.
+	(ft_trace_levels_disabled): New array.
+	(ft_trace_levels): New pointer.
+	(FT_Trace_Disable, FT_Trace_Enable): Implement.
+	(ft_debug_init): Updated.
+
+2018-08-08  Werner Lemberg  <wl@gnu.org>
+
+	Debugging improvements.
+
+	* src/base/ftobjs.c (pixel_modes): Move this array to top level
+	from ...
+	(FT_Load_Glyph): ... here.
+	(FT_Render_Glyph_Internal): Use `width' x `height' in trace message.
+	Use `pixel_modes'.
+
+2018-08-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Massive unsigning (part 2).
+
+	Treat all size related properties as unsigned values.
+
+	* src/pcf/pcf.h (PCF_ParsePropertyRec): Use unsigned `name' and
+	`value'.
+	* src/pcf/pcfread.c (pcf_get_properties, pcf_load_font): Updated
+	parsing code and handling of AVERAGE_WIDTH, POINT_SIZE, PIXEL_SIZE,
+	RESOLUTION_X and RESOLUTION_Y.
+
+2018-08-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Massive unsigning (part 1).
+
+	Unofficial specifications hesitate to use unsigned 32-bit integers.
+	Negative values caused a lot of trouble in the past and it is safer
+	and easier to treat some properties as unsigned.
+
+	* src/pcf/pcf.h (PCF_AccelRec): Use unsigned values for `fontAscent',
+	`fontDescent', and `maxOverlap'.
+	* src/pcf/pcfread.c (pcf_load_font, pcf_get_accel): Updated.
+	* src/pcf/pcfdrivr.c (PCF_Glyph_Load, PCF_Size_Select,
+	PCF_Size_Request): Updated.
+
+2018-08-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/pcf/pcfread.c (pcf_get_bitmaps): Unsign `offsets' and
+	`bitmapSizes'.
+
+2018-08-06  Werner Lemberg  <wl@gnu.org>
+
+	* devel/ftoption.h: Synchronize with main `ftoption.h'.
+
+2018-08-06  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[pcf] Use unsigned types.
+
+	* src/pcf/pcf.h (PCF_Encoding): Use unsigned `enc'.
+	* src/pcf/pcfdrivr.c (pcf_cmap_char_{index,next}): Ditto.
+	* src/pcf/pcfread.c (pcf_get_encodings): Use unsigned types.
+
+2018-08-05  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgload.c (compute_glyph_metrics): Fix overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/chromium/issues/detail?id=777151
+
+2018-08-04  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttinterp.c (opcode_name): Fix typos.
+
+2018-08-04  Werner Lemberg  <wl@gnu.org>
+
+	Fix clang warnings.
+
+	* src/base/ftoutln.c (FT_Outline_EmboldenXY): Fix type of
+	`orientation'.
+
+	* src/gxvalid/gxvcommn.c (gx_lookup_value_read): Fix signature.
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Fix type of some variables.
+	Add cast.
+
+	* src/type1/t1load.c (parse_weight_vector): Fix cast.
+
+2018-07-31  Werner Lemberg  <wl@gnu.org>
+
+	* src/cid/cidtoken.h: Handle `XUID' keyword.
+
+2018-07-31  Werner Lemberg  <wl@gnu.org>
+
+	[cid] Trace PostScript dictionaries.
+
+	* src/cid/cidload.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H.
+	(cid_load_keyword, cid_parse_font_matrix, parse_fd_array,
+	parse_expansion_factor, cid_parse_dict): Add tracing calls.
+	(parse_font_name): New function to trace `/FontName' keywords in
+	/FDArray dict.
+	(cid_field_records): Register `parse_font_name'.
+
+2018-07-30  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Fix typo.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9409
+
+	* src/cff/cffdrivr.c (cff_get_cid_from_glyph_index): Fix boundary
+	check.
+
+2018-07-29  Werner Lemberg  <wl@gnu.org>
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Another thinko.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9608
+
+2018-07-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Fix Harmony memory management.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9501
+
+	* src/smooth/ftgrays.c (ft_smooth_render_generic): Restore buffer
+	after each rendering in case of failure.
+
+2018-07-28  Werner Lemberg  <wl@gnu.org>
+
+	[type1] Avoid segfaults with `FT_Get_PS_Font_Value'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9610
+
+	* src/type1/t1driver.c (t1_ps_get_font_value): Protect against NULL.
+
+2018-07-27  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Make `TT_Set_MM_Blend' idempotent (#54388).
+
+	* src/truetype/ttgxvar.c (tt_set_mm_blend): Correctly set
+	`face->doblend' if the current call to the function yields the same
+	blend coordinates as the previous call.
+
+2018-07-27  Werner Lemberg  <wl@gnu.org>
+
+	[psaux, type1]: More tracing improvements.
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString): Trace skipped
+	outline commands.
+
+	* src/psaux/t1decode.c (t1_decoder_parse_charstring): Fix
+	missing case.
+	(t1_decoder_parse_metrics): Make tracing output more compact.
+
+	* src/type1/t1gload.c (T1_Compute_Max_Advance): Be less verbose.
+	(T1_Get_Advances): Add tracing.
+
+2018-07-25  Werner Lemberg  <wl@gnu.org>
+
+	[psaux, type1] Trace PostScript dictionaries and other things.
+
+	The tracing of /Encoding, /Subrs, and /Charstrings is rudimentary
+	right now.
+
+	* src/psaux/psobjs.c (ps_parser_load_field,
+	ps_parser_load_field_table): Add tracing calls.
+
+	* src/psaux/t1decode.c (t1_decoder_parse_charstrings): Make tracing
+	output more compact.
+
+	* src/type1/t1gload.c (T1_Compute_Max_Advance, T1_Get_Advances): Add
+	tracing messages.
+
+	* src/type1/t1load.c (parse_blend_axis_types,
+	parse_blend_design_positions, parse_blend_design_map,
+	parse_weight_vector, t1_load_keyword, t1_parse_font_matrix,
+	parse_encoding, parse_subrs, parse_charstrings, T1_Open_Face): Add
+	tracing calls.
+
+	* src/type1/t1objs.c (T1_Face_Init): Add tracing call.
+
+	* src/sfnt/sfobjs.c (sfnt_init_face): Make tracing message more
+	verbose.
+
+2018-07-25  Werner Lemberg  <wl@gnu.org>
+
+	Fix minor ASAN run-time warnings.
+
+	* src/base/ftutil.c (ft_mem_alloc, ft_mem_realloc): Only call
+	`FT_MEM_ZERO' if we actually have a buffer.
+	(ft_mem_dup): Only call `ft_memcpy' if we actually have a buffer.
+
+2018-07-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[build] Fortify dllexport/dllimport attributes (#53969,#54330).
+
+	We no longer use predefined _DLL, which can be defined for static
+	builds too with /MD. We use DLL_EXPORT and DLL_IMPORT instead,
+	following libtool convention.
+
+	* CMakeLists.txt [WIN32], builds/windows/vc2010/freetype.vcxproj:
+	Define DLL_EXPORT manually.
+
+	* include/freetype/config/ftconfig.h, builds/unix/ftconfig.in,
+	builds/vms/ftconfig.h, builds/windows/vc2010/index.html,
+	src/base/ftver.rc: /_DLL/d, s/FT2_DLLIMPORT/DLL_IMPORT/.
+
+2018-07-24  Werner Lemberg  <wl@gnu.org>
+
+	[type1] Check relationship between number of axes and designs.
+
+	For Multiple Masters fonts we don't support intermediate designs;
+	this implies that
+
+	  number_of_designs == 2 ^^ number_of_axes
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9557
+
+	* src/type1/t1load.c (T1_Open_Face): Ensure above constraint.
+	(T1_Get_MM_Var): Remove now redundant test.
+
+2018-07-24  Hin-Tak Leung  <htl10@users.sourceforge.net>
+
+	[truetype] Match ttdebug's naming of instruction mnemonics.
+
+	* src/truetype/ttinterp.c: The form used in ttdebug,
+	"MDRP[G,B,W,?]", etc., is slightly more readable than
+	"MDRP[00,01,02,03]".
+
+2018-07-24  Werner Lemberg  <wl@gnu.org>
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Thinko.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9561
+
+2018-07-22  Werner Lemberg  <wl@gnu.org>
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Check index of defaultChar.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9527
+
+2018-07-22  Werner Lemberg  <wl@gnu.org>
+
+	* src/pcf/pcfread.c (pcf_load_font): Fix number of glyphs.
+
+	This is an oversight of the module change 2018-07-21.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9524
+
+2018-07-22  Werner Lemberg  <wl@gnu.org>
+
+	[cid] Sanitize `BlueShift' and `BlueFuzz'.
+
+	This code is taken from the type1 module.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9510
+
+	* src/cid/cidload.c (parse_fd_array): Set some private dict default
+	values.
+	(cid_face_open): Do the sanitizing.
+	Fix some tracing messages.
+
+2018-07-21  Werner Lemberg  <wl@gnu.org>
+
+	[pcf] Fix handling of the undefined glyph.
+
+	This change makes the driver use the `defaultChar' property of PCF
+	files.
+
+	* src/pcf/pcf.h (PCF_FaceRec): Change type of `defaultChar' to
+	unsigned.
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Read `defaultChar' as
+	unsigned.
+	Validate `defaultChar'.
+	If `defaultChar' doesn't point to glyph index zero, swap glyphs with
+	index zero and index `defaultChar' and adjust the encodings
+	accordingly.
+
+	* src/pcf/pcfdrivr.c (pcf_cmap_char_index, pcf_cmap_char_next,
+	PCF_Glyph_Load): Undo change from 2002-06-16 which always enforced
+	the first character in the font to be the default character.
+
+2018-07-20  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	Move the legacy fuzz target to the `freetype-testing' repository.
+
+	It can now be found at
+
+	  https://github.com/freetype/freetype2-testing/tree/master/fuzzing/src/legacy
+
+	* src/tools/ftfuzzer: Remove this folder and its contents from the
+	repository.
+
+2018-07-20  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Avoid left-shift of negative numbers (#54322).
+
+	* src/cff/cffgload.c (cff_slot_load): Use multiplication.
+
+2018-07-17  Werner Lemberg  <wl@gnu.org>
+
+	Allow FT_ENCODING_NONE for `FT_Select_Charmap'.
+
+	This is a valid encoding tag for BDF, PCF, and Windows FNT, and
+	there is no reason to disallow it for these formats.
+
+	* src/base/ftobjs.c (FT_Select_Charmap): Implement it.
+
+2018-07-17  Werner Lemberg  <wl@gnu.org>
+
+	* src/pcf/pcfread.c (pcf_get_encodings): Trace `defaultChar'.
+
+2018-07-16  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	* include/freetype/internal/ftcalc.h: Add macros for handling
+	harmless over-/underflowing `FT_Int' values.
+
+	* src/sfnt/sfdriver.c (fixed2float): Fix negation of
+	`(int)(-2147483648)'.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9423
+
+2018-07-16  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgxvar.c (tt_set_mm_blend): Fix off-by-one error.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9412
+
+2018-07-12  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftoutln.c (FT_Outline_Get_Orientation): Init `cbox'.
+
+	Taken from patch #9667, written by Steve Langasek
+	<vorlon@debian.org>.
+
+	This fixes a build failure (most probably a bug in gcc) on ppc64el
+	when building with -O3.
+
+2018-07-05  Werner Lemberg  <wl@gnu.org>
+
+	Fix typo (#54238).
+
+	* src/base/ftcolor.c (FT_Palette_Set_Foreground_Color)
+	[!TT_CONFIG_OPTION_COLOR_LAYERS]: Add return value.
+
+2018-07-05  Werner Lemberg  <wl@gnu.org>
+
+	Adjust table size comparisons (#54242).
+
+	* src/sfnt/ttcpal.c (tt_face_load_cpal): Implement it.
+
+2018-07-05  Werner Lemberg  <wl@gnu.org>
+
+	Fix more 32bit issues (#54208).
+
+	* src/cff/cffload.c (cff_blend_build_vector): Convert assertion into
+	run-time error.
+
+	* src/truetype/ttgxvar.c (ft_var_to_normalized): Protect against
+	numeric overflow.
+
+2018-07-04  Werner Lemberg  <wl@gnu.org>
+
+	Fix 32bit build warnings (#54239).
+
+	* src/base/ftbitmap.c (FT_Bitmap_Blend): Add casts to avoid signed
+	vs. unsigned comparisons.
+
+	* srb/sfnt/ttcolr.c (tt_face_get_colr_layer): Ditto.
+
+2018-07-02  Jeff Carey  <Jeff.Carey@monotype.com>
+
+	* src/psnames/psmodule.c (ps_unicodes_init): Fix alloc debugging.
+
+2018-07-02  Werner Lemberg  <wl@gnu.org>
+
+	s/palette_types/palette_flags/.
+
+	Suggested by Behdad.
+
+2018-07-02  Werner Lemberg  <wl@gnu.org>
+
+	Make `FT_Get_Color_Glyph_Layer' return FT_Bool.
+
+	* include/freetype/freetype.h, src/base/ftobjs.c
+	(FT_Get_Color_Glyph_Layer, FT_Render_Glyph_Internal): Updated.
+
+	* include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func),
+	src/sfnt/ttcolr.h, src/sfnt/ttcolr.c (tt_face_get_colr_layer):
+	Updated.
+
+2018-07-01  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Guard SFNT function.
+
+	Reported by Behdad.
+
+2018-06-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/fttrigon.c (FT_Tan): Improve accuracy.
+	(FT_Vector_Rotate): Simplify.
+
+2018-06-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* src/base/ftobjs.c (FT_Set_Charmap): Robustify.
+
+2018-06-25  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Fix memory leak.
+
+	* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Add initializers.
+	Fix typo in `goto' destination.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9071
+
+2018-06-25  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgxvar.c (tt_face_vary_cvt): Add initializers.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9070
+
+2018-06-24  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Increase precision while applying VF deltas.
+
+	It turned out that we incorrectly round CVT and glyph point deltas
+	before accumulation, leading to severe positioning errors if there
+	are many delta values to sum up.
+
+	Problem reported by Akiem Helmling <akiem@underware.nl> and analyzed
+	by Behdad.
+
+	* src/truetype/ttgxvar.c (ft_var_readpackeddelta): Return deltas in
+	16.16 format.
+	(tt_face_var_cvt): Collect deltas in `cvt_deltas', which is a 16.16
+	format array, and add the accumulated values to the CVT at the end
+	of the function.
+	(TT_Vary_Apply_Glyph_Deltas): Store data in `points_org' and
+	`points_out' in 16.16 format.
+	Collect deltas in `point_deltas_x' and `point_deltas_y', which are
+	16.16 format arrays, and add the accumulated values to the glyph
+	coordinates at the end of the function.
+
+2018-06-24  Werner Lemberg  <wl@gnu.org>
+
+	New base function `FT_Matrix_Check' (#54019).
+
+	* src/base/ftcalc.c (FT_Matrix_Check): New base function to properly
+	reject degenerate font matrices.
+
+	* include/freetype/internal/ftcalc.h: Updated.
+
+	* src/cff/cffparse.c (cff_parse_font_matrix), src/cid/cidload.c
+	(cid_parse_font_matrix), src/type1/t1load.c (t1_parse_font_matrix),
+	src/type42/t42parse.c (t42_parse_font_matrix): Use
+	`FT_Matrix_Check'.
+
+2018-06-23  Werner Lemberg  <wl@gnu.org>
+
+	Fix typo.
+
+	Reported by Behdad.
+
+	* src/base/ftcolor.c (FT_Palette_Data_Get)
+	[!TT_CONFIG_OPTION_COLOR_LAYERS]: s/apalette/apalette_data/.
+
+2018-06-21  Werner Lemberg  <wl@gnu.org>
+
+	s/FT_PALETTE_USABLE_WITH_/FT_PALETTE_FOR_/.
+
+	* include/freetype/ftcolor.h, include/freetype/internal/sfnt.h,
+	src/sfnt/ttcolr.c: Do it.
+
+2018-06-19  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix CPAL heap buffer overflow.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8968
+
+	* src/sfnt/ttcpal.c (tt_face_load_cpal): Guard CPAL version 1
+	offsets.
+
+2018-06-19  Werner Lemberg  <wl@gnu.org>
+
+	Doh.  Don't use CPAL or COLR data if tables are missing.
+
+	Reported by Alexei.
+
+	* src/sfnt/ttcolr.c (tt_face_get_colr_layer): Return immediately if
+	`colr' is NULL.
+
+	* src/sfnt/ttcpal.c (tt_face_palette_set): Return immediately, if
+	`cpal' is NULL.
+
+2018-06-17  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] Introduce `FT_New_Glyph'.
+
+	This function facilitates access to full capabilities of FreeType
+	rendering engine for custom glyphs. This can be quite useful for
+	consistent rendering of mathematical and chemical formulas, e.g.
+
+	  https://bugs.chromium.org/p/chromium/issues/detail?id=757078
+
+	* include/freetype/ftglyph.h, src/base/ftglyph.c (FT_New_Glyph): New
+	function.
+
+2018-06-17  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	[bdf] Fix underflow of an unsigned value.
+
+	bdflib.c:1562 could be reached with `font->glyphs_used == 0'.  That
+	caused an underflow of the unsigned value which results in undefined
+	behaviour.
+
+	* src/bdf/bdflib.c (_bdf_parse_glyphs): Bail out earlier than before
+	if the `ENCODING' keyword cannot be found.
+
+2018-06-17  Werner Lemberg  <wl@gnu.org>
+
+	[base] Add tracing for `FT_Bitmap_Blend'.
+
+	* include/freetype/internal/fttrace.h (trace_bitmap): New
+	enumeration.
+
+	* src/base/ftbitmap.c (FT_COMPONENT): Define.
+	(FT_Bitmap_Blend): Add `FT_TRACE5' calls.
+
+2018-06-17  Werner Lemberg  <wl@gnu.org>
+
+	s/trace_bitmap/trace_checksum/.
+
+	* include/freetype/internal/fttrace.h: s/bitmap/checksum/.
+
+	* src/base/ftobjs.c (FT_COMPONENT): s/trace_bitmap/trace_checksum/.
+	Adjust code.
+
+2018-06-16  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix color glyph layer loading.
+
+	* src/sfnt/ttcolr.c (Colr): Add `table_size' field.
+	(tt_face_load_colr): Set it.
+	(tt_face_get_colr_layer): Check pointer limit for layer entries.
+
+2018-06-16  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix color palette loading.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8933
+
+	* src/sfnt/ttcpal.c (Cpal): Add `table_size' field.
+	(tt_face_load_cpal): Set it.
+	(tt_face_palette_set): Check pointer limit for color entries.
+
+2018-06-16  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftbitmap.c (FT_Bitmap_Blend): Avoid integer overflow.
+
+2018-06-16  Werner Lemberg  <wl@gnu.org>
+
+	Add `FT_Bitmap_Blend' API.
+
+	Still missing: Support for negative bitmap pitch and subpixel offset
+	of source bitmap.
+
+	* include/freetype/ftbitmap.h, src/base/ftbitmap.c
+	(FT_Bitmap_Blend): New function.
+
+2018-06-14  Werner Lemberg  <wl@gnu.org>
+
+	Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'.
+
+	This avoids any additional allocation of COLR related structures in
+	a glyph slot.
+
+	* include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec,
+	FT_Get_GlyphLayers): Removed.
+
+	* include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed.
+	(FT_Slot_InternalRec): Remove `color_layers'.
+
+	* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func):
+	Removed.
+	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove
+	`load_colr_layer'.
+
+	* src/base/ftobjs.c (ft_glyph_slot_done): Updated.
+	(FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'.
+	(FT_Get_GlyphLayers): Removed.
+
+	* src/sfnt/sfdriver.c (sfnt_interface): Updated.
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed.
+	* src/sfnt/ttcolr.h: Updated.
+
+	* src/truetype/ttgload.c (TT_Load_Glyph): Updated.
+
+2018-06-14  Werner Lemberg  <wl@gnu.org>
+
+	Provide iterative API to access `COLR' data.
+
+	This solution doesn't store any data in an `FT_GlyphSlot' object.
+
+	* include/freetype/freetype.h (FT_LayerIterator): New structure.
+	(FT_Get_Color_Glyph_Layer): New function.
+
+	* include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func): New
+	function type.
+	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it.
+
+	* src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Implement it.
+
+	* src/sfnt/ttcolr.c (tt_face_get_colr_layer): New function.
+	* src/sfnt/ttcolr.h: Updated.
+
+	* src/sfnt/sfdriver.c (sfnt_interface): Updated.
+
+2018-06-14  Werner Lemberg  <wl@gnu.org>
+
+	Add glyph index and glyph load flags to glyph slot.
+
+	* include/freetype/freetype.h (FT_GlyphSlotRec): Rename unused
+	`reserved' field to `glyph_index'.
+
+	* include/freetype/internal/ftobjs.h (FT_Slot_InternalRec): Add
+	`load_flags' field.
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Set new fields.
+
+2018-06-14  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Move `CPAL' stuff into separate files.
+
+	* src/sfnt/sfdriver.c: Include `ttcpal.h'.
+	* src/sfnt/sfnt.c: Include `ttcpal.c'.
+
+	* src/sfnt/ttcolr.c, src/sfnt/ttcolr.h: Move CPAL stuff to ...
+	* src/sfnt/ttcpal.c, src/sfnt/ttcpal.c: ... these new files.
+
+	* src/sfnt/Jamfile (_sources), src/sfnt/rules.mk (SFNT_DRV_SRC):
+	Updated.
+
+	* include/freetype/internal/fttrace.h: Add support for `colr' and
+	`cpal'.
+	Sort entries.
+
+2018-06-13  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Separate `CPAL' and `COLR' table handling.
+
+	Later on we want to support the `SVG' table also, which needs `CPAL'
+	(but not `COLR').
+
+	* include/freetype/internal/sfnt.h (SFNT_Interface): Add `load_cpal'
+	and `free_cpal' fields.
+	(FT_DEFINE_SFNT_INTERFACE): Updated.
+
+	* include/freetype/internal/tttypes.h (TT_FaceRec): Replace
+	`colr_and_cpal' fields with `cpal' and `colr'.
+
+	* src/sfnt/sfdriver.c (sfnt_interface): Updated.
+
+	* src/sfnt/sfobjs.c (sfnt_load_face, sfnt_done_face): Updated.
+
+	* src/sfnt/ttcolr.c (Colr, Cpal): Add `table' field.
+	(ColrCpal): Removed.
+	(tt_face_load_colr): Split off CPAL handling into...
+	(tt_face_load_cpal): ... this new function.
+	(tt_face_free_colr): Split off CPAL handling into...
+	(tt_face_free_cpal): ... this new function.
+	(tt_face_load_colr_layers, tt_face_palette_set): Updated.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+	* src/truetype/ttgload.c (TT_Load_Glyph): Updated.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix `sizeof' thinko.
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr, tt_face_palette_set): Don't
+	use `sizeof' for computing array limit.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
+	Finish CPAL/COLR support (4/4).
+
+	* src/sfnt/ttcolr.c (tt_face_find_color): Removed.
+	(tt_face_colr_blend_layer): Use `face->palette' instead of calling
+	`tt_face_find_color'.
+	Use and set text foreground color.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
+	Finish CPAL/COLR support (3/4).
+
+	* src/base/ftcolor.c: Include FT_INTERNAL_SFNT_H.
+	(FT_Palette_Select, FT_Palette_Set_Foreground_Color): Implement
+	functions.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
+	Finish CPAL/COLR support (2/4).
+
+	* src/sfnt/ttcolr.c (tt_face_palette_set): New function.
+	(tt_face_load_colr): Allocate `face->palette' and call
+	`tt_face_palette_set'.
+	Adjust return error code in case of error.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+	* include/freetype/internal/sfnt.h (TT_Set_Palette_Func): New
+	function type.
+	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it.
+
+	* src/sfnt/sfdriver.c (sfnt_interface), src/sfnt/sfobjs.c
+	(sfnt_done_face): Updated.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
+	Finish CPAL/COLR support (1/4).
+
+	* include/freetype/internal/tttypes.h (TT_FaceRec): New fields
+	`palette_index', `palette', `have_foreground_color' and
+	`foreground_color'.
+
+2018-06-12  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Minor.
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr_layers):
+	s/palette_index/palette_entry_index/ for consistency.
+	Adjust return error code in case of error.
+
+2018-06-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Clean up.
+
+	* src/raster/ftraster.c (black_TWorker, SCALED, Set_High_Precision):
+	Clean up after 5-level gray removal (8dc8635874).
+	(Vertical_Sweep_Span): Be brief.
+
+2018-06-10  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix compiler warnings.
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr, tt_face_load_colr_layers,
+	tt_face_colr_blend_layer): Add `NULL' initializers.
+
+2018-06-10  Werner Lemberg  <wl@gnu.org>
+
+	s/FT_Palette/FT_Palette_Data/, s/palette/palette_data/.
+
+	* include/freetype/ftcolor.h, include/freetype/internal/tttypes.h,
+	src/base/ftcolor.c, src/sfnt/sfobjs.c, src/sfnt/ttcolr.c: Updated.
+
+2018-06-10  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	CMakeLists: also accept IOS_PLATFORM=SIMULATOR64
+
+	This might be needed to build FreeType for the iOS simulator. See
+	https://savannah.nongnu.org/bugs/index.php?54048. Patch contributed
+	by Steve Robinson.
+
+	* CMakeLists.txt: Accept IOS_PLATFORM=SIMULATOR64
+
+2018-06-10  Werner Lemberg  <wl@gnu.org>
+
+	Implement `FT_Palette_Get'.
+
+	* src/base/ftcolor.c: New file.
+
+	* src/base/Jamefile (_sources), src/base/rules.mk (BASE_SRC),
+	src/base/ftbase.c: Add `ftcolor.c'.
+
+2018-06-10  Werner Lemberg  <wl@gnu.org>
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr): Improve overflow checks.
+
+2018-06-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[raster] Deal with pitch sign earlier.
+
+	* src/raster/ftraster.c (black_TWorker): Remove unused `traceG',
+	s/bTarget/bOrigin/.
+	(Render_Glyph): Set `ras.bOrigin' at the bottom-left corner.
+	(Vertical_Sweep_Init, {Vertical,Horizontal}_Sweep_{Span,Drop}):
+	Updated accordingly.
+
+2018-06-09  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Read `CPAL' version 1 tables.
+
+	* include/freetype/internal.tttypes.h: Include FT_COLOR_H.
+	(TT_FaceRec): Add `palette' field.
+
+	* src/sfnt/ttcolr.c: Include FT_COLOR_H.
+	(Cpal): Remove all data covered by the new `palette' field in
+	`TT_FaceRec'.
+	(tt_face_load_colr): Updated.
+	Read `CPAL' version 1 data.
+	(tt_face_load_colr_layers, tt_face_find_color): Updated.
+
+	* src/sfnt/sfobjs.c (sfnt_done_face): Free glyph color palette data.
+
+2018-06-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] API for Harmony LCD rendering.
+
+	This introduces `FT_Library_SetLcdGeometry' for setting up arbitrary
+	LCD subpixel geometry including non-striped patterns.
+
+	* src/base/ftlcdfil.c (FT_Library_SetLcdGeometry): New function.
+	* include/freetype/ftlcdfil.h: Document it.
+	* include/freetype/freetype.h: Minor.
+	* include/freetype/ftchapters.h: Minor.
+
+2018-06-06  Werner Lemberg  <wl@gnu.org>
+
+	ftcolor.h: Redesign API.
+
+	While going to implement it I noticed that I need access to most of
+	the `CPAL' elements; I thus plan to add a `cpal' field to
+	`TT_FaceRec', which makes most of the previously suggested API
+	functions obsolete because the fields will be directly accessible.
+
+2018-06-06  Parth Wazurkar  <parthwazurkar@gmail.com>
+
+	[bdf, pcf] Remove deprecated FT_FACE_FLAG_FAST_GLYPHS flag.
+
+	* src/bdf/bdfdrivr.c (BDF_Face_Init): Remove deprecated
+	FT_FACE_FLAG_FAST_GLYPHS flag.
+
+	* src/pcf/pcfread.c (pcf_load_font): Remove deprecated
+	FT_FACE_FLAG_FAST_GLYPHS flag.
+
+2018-06-06  Werner Lemberg  <wl@gnu.org>
+
+	[smooth, raster] Limit bitmap size (#54019).
+
+	* src/raster/ftraster.c [STANDALONE] (FT_Outline_Get_CBox): Add
+	function.
+	[!STANDALONE]: Include FT_OUTLINE_H.
+	(ft_black_render): Compute CBox and reject glyphs larger than
+	0xFFFF x 0xFFFF.
+
+	* src/smooth/ftgrays.c (gray_raster_render): Reject glyphs larger
+	than 0xFFFF x 0xFFFF.
+
+2018-06-03  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	* src/smooth/ftgrays.c (gray_convert_glyph): Remove unused variables.
+
+2018-06-03  Werner Lemberg  <wl@gnu.org>
+
+	* src/tools/glnames.py (main): Emit header in `light' comment style.
+
+2018-06-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Attempt to mitigate bug #54019.
+
+	The robust rendering of estra large glyphs came with unbearable cost.
+	The old way of bisecting should fail but fail faster.
+
+	* src/smooth/ftgrays.c (gray_convert_glyph): Switch back to bisecting
+	in y-direction.
+
+2018-06-02  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttinterp.c (Ins_MIRP): Use SUB_LONG; avoid FT_ABS.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8706
+
+2018-06-02  Werner Lemberg  <wl@gnu.org>
+
+	* src/autofit/afwarp.h: Use AF_CONFIG_OPTION_USE_WARPER (#54033).
+
+2018-05-31  Werner Lemberg  <wl@gnu.org>
+
+	* src/raster/ftraster.c (black_TWorker_): Remove `gTarget' field.
+
+	This is no longer used.
+
+2018-05-31  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Get colors from `CPAL' table in right order (#54015).
+
+	* src/sfnt/ttcolr.c (tt_face_find_color): Fix it.
+
+2018-05-30  Werner Lemberg  <wl@gnu.org>
+
+	ftcolor.h: Improve API design, fix typos (#54011, #54014).
+
+	* include/freetype/ftcolor.h (FT_Palette_Get_Names): Replace with...
+	(FT_Palette_Get_Name_IDs): ... this function.
+	(FT_Palette_Get_Entry_Names): Replace with...
+	(FT_Palette_Get_Entry_Name_IDs): ... this function
+	s/FT_Palette_Set_Foreground_COlor/FT_Palette_Set_Foreground_Color/.
+
+2018-05-30  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	Beautify a3cfed5e87232c933bdc64f43e8ebebcfd18b41b.
+
+	* src/autofit/afloader.c (af_loader_load_glyph): Move the
+	initialisationand declaration of variables into the if-block.
+
+2018-05-30  Armin Hasitzka  <prince.cherusker@gmail.com>
+
+	Fix pointer underflow.
+
+	The declaration of `edge2' can be reached with `edge1 == NULL' and
+	`axis->edges == 0' which results in undefined behaviour.
+
+	* src/autofit/afloader.c (af_loader_load_glyph): Initialise `edge2'
+	after checking `axis->num_edges > 1'.  `edge1 != NULL' can be assumed.
+
+2018-05-30  Werner Lemberg  <wl@gnu.org>
+
+	Various minor color fixes.
+
+	* include/freetype/config/ftheader.h (FT_COLOR_H): New macro.
+
+	* include/freetype/internal/ftobjs.h (FT_Colr_Internal): Change
+	type of `load_flags' to `FT_Int32'.
+
+	* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): Change
+	type of `idx' to `FT_UInt'.
+	(TT_Blend_Colr_Func): Change type of `color_index' to `FT_UInt'.
+
+	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Change type of
+	`load_flags' to `FT_Int32'.
+
+	* src/sfnt/ttcolr.c (find_base_glyph_record,
+	tt_face_load_colr_layers): Change type of `glyph_id' to `FT_UInt'.
+	(tt_face_find_color, tt_face_colr_blend_layer): Change type of
+	`color_index' to `FT_UInt'.
+	Fix signedness and type issues.
+
+	* src/sfnt/ttcolr.h: Updated.
+
+2018-05-25  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
+
+	[docmaker] Fix missing `Defined in (...)' under Windows/Cygwin.
+
+	This platform uses backslashes for paths, which docmaker didn't
+	understand correctly.
+
+	* src/tools/docmaker/tohtml.py (HtmlFormatter::blockEnter): Use
+	`os.path.normpath' to normalize the path for the platform being
+	used.
+
+2018-05-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Formalize Harmony LCD rendering.
+
+	This generalizes magic outline shifts that make Harmony LCD
+	rendering work in terms of precise two-dimensional RGB subpixel
+	positions. These coordinates are now set in time of the `smooth'
+	module initialization and later used to shift a glyph outline for
+	rendering. FT_RENDER_MODE_LCD and FT_RENDER_MODE_LCD_V use the same
+	coordinates. The letter, however, rotates them before using.
+	The LCD bitmap padding is also calculated using these coordinates.
+
+	* include/freetype/internal/ftobjs.h (FT_LibraryRec): New array field
+	`lcd_geometry'.
+	* src/base/ftlcdfil.c (ft_lcd_padding): Reworked.
+	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Updated accordingly.
+
+	* src/smooth/ftsmooth.c [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]
+	(ft_smooth_init): Initialize `lcd_geometry'.
+	(ft_smooth_render_generic): Formalize outline shifts.
+
+2018-05-22  Werner Lemberg  <wl@gnu.org>
+
+	[truetype] Reject elements of composites with invalid glyph indices.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8413
+
+	* src/truetype/ttgload.c (TT_Load_Composite_Glyph): Implement it.
+
+2018-05-22  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgload.c (TT_Load_Simple_Glyph): Trace # of points.
+
+2018-05-20  Werner Lemberg  <wl@gnu.org>
+
+	* include/freetype/ftcolor.h: New file.
+
+	This is an interface to the `CPAL' OpenType table.  No
+	implementation yet.
+
+2018-05-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	* include/freetype/internal/ftcalc.h (FT_MSB): Verified `_MSC_VER'.
+
+	Actually `_BitScanReverse' is available since VS2005.
+
+2018-05-18  Werner Lemberg  <wl@gnu.org>
+
+	* include/freetype/internal/ftcalc.h (FT_MSB): Use `_MSC_VER' value.
+
+	Older VC versions don't provide `_BitScanReverse'.  We test for VC
+	2013.
+
+	Reported by John Emmas <john@creativepost.co.uk>.
+
+2018-05-17  Werner Lemberg  <wl@gnu.org>
+
+	s/inline/__inline/ for MSVC.
+
+	Reported by John Emmas <john@creativepost.co.uk>.
+
+	* include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Do it.
+
+2018-05-16  Werner Lemberg  <wl@gnu.org>
+
+	Add function `FT_Get_GlyphLayers' to access `COLR' table data.
+
+	* include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec): Move this
+	structure to...
+	* include/freetype/freetype.h (FT_Glyph_LayerRec): ... this
+	header file.
+	(FT_Glyph_Layer): New typedef.
+	Update code to use it where appropriate.
+
+	* src/base/ftobjs.c (FT_Get_GlyphLayers): New function.
+
+2018-05-15  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[base] Fix mono bitmap presetting (#53896).
+
+	It is rather fundamental to set monochrome bitmap based on rounded
+	CBox because the b/w rasterizer turns on pixels when their centers are
+	inside the glyph outline. The dropout control is unpredictable and can
+	distort narrow glyphs if the bitmap is too wide.
+
+	Reported by Chris Liddell.
+
+	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): If BBox boundaries
+	are too close, adjust them before rounding.
+
+2018-05-15  Werner Lemberg  <wl@gnu.org>
+
+	[psaux] Fix compiler warning (#53915).
+
+	* src/psaux/psft.c (cf2_freeT1SeacComponent): Do it.
+
+2018-05-15  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Fix memory leak in handling `COLR' data.
+
+	* src/truetype/ttgload.c (TT_Load_Glyph): Free old `layers' array
+	before reassigning allocated memory.
+	Only allocate `color_layers' if we don't have one already.
+
+2018-05-15  Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] If `COLR' is present, don't assume that all glyphs use it.
+
+	* src/sfnt/ttcolr.c (tt_face_load_colr_layers): Return FT_Err_Ok if
+	current glyph is not a `COLR' base glyph.
+
+	* src/truetype/ttgload.c (TT_Load_Glyph): Don't allocate
+	`color_layers' if there are no color layers.
+
+2018-05-14  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Fix signature of `pixel_modes'.
+
+2018-05-14  Werner Lemberg  <wl@gnu.org>
+
+	Provide dummy functions if `TT_CONFIG_OPTION_SFNT_NAMES' is not set.
+
+	* src/base/ftsnames.c [!TT_CONFIG_OPTION_SFNT_NAMES]: Implement it.
+
+2018-05-13  Werner Lemberg  <wl@gnu.org>
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Improve tracing.
+
+2018-05-13  Shao Yu Zhang  <shaozhang@fb.com>
+	    Werner Lemberg  <wl@gnu.org>
+
+	[sfnt] Preliminary support of colored layer outlines (#44689).
+
+	This commit enables OpenType's COLR/CPAL table handling; a typical
+	application are color emojis that can be scaled to any size.
+
+	If the color palette does not exist or is invalid, the rendering
+	step rasterizes the outline instead.  The current implementation
+	assumes that the foreground is black.
+
+	Enable this by defining option TT_CONFIG_OPTION_COLOR_LAYERS.
+
+	There are still some issues with metrics; additionally, an API to
+	fetch color layers is missing.
+
+	* devel/ftoption.h, include/freetype/config/ftoption.h
+	(TT_CONFIG_OPTION_COLOR_LAYERS): New macro.
+
+	* include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec,
+	FT_Colr_InternalRec): New structures.
+	(FT_Slot_InternalRec): Add `color_layers' field.
+
+	* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func,
+	TT_Blend_Colr_Func): New function types.
+	(SFNT_Interface): Add `load_colr', `free_colr', `load_colr_layer',
+	and `colr_blend' fields.
+
+	* include/freetype/internal/tttypes.h (TT_FaceRec): Add
+	`colr_and_cpal' field.
+
+	* include/freetype/internal/tttags. (TTAG_COLR, TTAG_CPAL): New
+	macros.
+
+	* src/sfnt/ttcolr.c, src/sfnt/ttcolr.h: New files.
+
+	* src/base/ftobjs.c (ft_glyphslot_done, FT_Render_Glyph_Internal):
+	Handle glyph color layers.
+
+	* src/sfnt/Jamfile (_sources), src/sfnt/rules.mk (SFNT_DRV_SRC): Add
+	`ttcolr.c'.
+
+	* src/sfnt/sfdriver.c: Include `ttcolr.h'.
+	(PUT_COLOR_LAYERS): New macro.
+	Update call to `FT_DEFINE_SFNT_INTERFACE'.
+
+	* src/sfnt/sfnt.c: Include `ttcolr.c'.
+
+	* src/sfnt/sfobjs.c (sfnt_load_face): Load `COLR' and `CPAL' tables.
+	(sfnt_done_face): Updated.
+
+	* src/truetype/ttgload.c (TT_Load_Glyph): Handle color layers.
+
+2018-05-12  Arkady Shapkin  <arkady.shapkin@gmail.com>
+
+	Use MS VC++'s _BitScanReverse to calculate MSB (patch #9636).
+
+	* include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Implement
+	it.
+
+2018-05-10  Alan Coopersmith  <alan.coopersmith@oracle.com>
+
+	Fix DLL compilation on Solaris.
+
+	AC_COMPILE_IFELSE only tries to compile a `*.c' to a `*.o'.  The
+	Solaris Studio 12.1 through 12.5 compilers see the
+	`-fvisibility=hidden' flag, but ignore it with a warning of:
+
+	  cc: Warning: Option -fvisibility=hidden passed to ld,
+	               if ld is invoked, ignored otherwise
+
+	AC_LINK_IFELSE does the compile and then tries to link the result,
+	at which point the Solaris linker will issue an error:
+
+	  ld: fatal: option '-fvisibility=hidden' is incompatible with
+	      building a dynamic executable
+
+	If we don't use AC_LINK_IFELSE to catch the error, then configure
+	will fail further tests which attempt to link, such as those testing
+	dependencies like `libbz2'.
+
+	Also, don't try adding `-fvisibility' if we have already added
+	`-xldscope', just use one of them, since Sun Studio 12 and earlier
+	compilers only issue a warning, and don't try passing through to the
+	linker to generate an error, so AC_LINK_IFELSE doesn't catch them.
+
+	Tested on Solaris 11.4 beta with compiler versions:
+
+	  Sun Studio 8 (Sun C 5.5)
+	  Sun Studio 10 (Sun C 5.7)
+	  Sun Studio 11 (Sun C 5.8)
+	  Sun Studio 12 (Sun C 5.9)
+	  Sun Studio 12.1 (Sun C 5.10)
+	  Oracle Solaris Studio 12.2 (Sun C 5.11)
+	  Oracle Solaris Studio 12.3 (Sun C 5.12)
+	  Oracle Solaris Studio 12.4 (Sun C 5.13)
+	  Oracle Developer Studio 12.5 (Sun C 5.14)
+	  Oracle Developer Studio 12.6 (Sun C 5.15)
+	  gcc 5.5.0
+	  gcc 7.3.0
+
+	and verified the libfreetype.so.6 generated by each of those
+	compilers exported the same set of symbols.
+
+	* builds/unix/configure.raw: Implement it.
+
+2018-05-08  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Avoid potential SEGV if running out of memory.
+
+	Problem reported by Shailesh Mistry <shailesh.mistry@hotmail.co.uk>.
+
+	* src/autofit/afshaper.c (af_shaper_buf_create,
+	af_shaper_buf_destroy) [!FT_CONFIG_OPTION_USE_HARFBUZZ]: Don't
+	allocate and free a four-byte buffer.  Instead, make those functions
+	no-ops; the calling functions will provide a pointer to a buffer
+	instead.
+
+	* src/autofit/afcjk.c (af_cjk_metrics_init_widths,
+	af_cjk_metrics_init_blues, af_cjk_metrics_check_digits),
+	src/autofit/aflatin.c (af_latin_metrics_init_widths,
+	af_latin_metrics_init_blues, af_latin_metrics_check_digits)
+	[!FT_CONFIG_OPTION_USE_HARFBUZZ]: Use pointer to local variable for
+	`shaper_buf'.
+
+2018-05-07  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	[cmake] Allow using project as subfolder in other project.
+
+	* CMakeLists.txt: Test for CMake build directory being different
+	from source directory.  Provide other parts of the build system
+	access the full include directory.
+
+2018-05-07  Werner Lemberg  <wl@gnu.org>
+
+	[build] Suppress configure's `nothing to be done' message.
+
+	This is due to calling the configure script via `make' (within the
+	top-level `configure' wrapper script).  The same can happen for all
+	other secondary make targets that are used to only modify the
+	primary one, e.g., `make setup devel'.
+
+	* builds/dos/detect.mk (emx, turboc, watcom, borlandc, borlandc16),
+	builds/os2/detect (visualage, watcom, borlandc, devel),
+	builds/unix/detect.mk (devel, lcc, unix), builds/windows/detect.mk
+	(visualc, watcom, visualage, lcc, mingw32, bcc32, devel-bcc,
+	devel-gcc): Use no-op recipe.
+
+2018-05-04  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
+
+	Support symbol visibility features of Sun / Oracle C compilers.
+
+	Reported by Kiyoshi Kanazawa:
+	https://lists.gnu.org/archive/html/freetype-devel/2018-05/msg00008.html
+	Thanks to the suggestions by Alexei and Alan Coopersmith.
+
+	* builds/unix/configure.raw: Check if "-xldscope=hidden" is
+	accepted, and if so, it is added to CFLAGS.  This is the option
+	making Sun / Oracle C compilers hide the symbols from global
+	scope.
+	* include/freetype/config/ftconfig.h: Use "__global" prefix
+	for FT_EXPORT() macro, if SunPro C is newer than Sun ONE
+	Studio 8 (2003).
+	* builds/unix/ftconfig.in: Ditto.
+	* builds/vms/ftconfig.h: Ditto.
+
+2018-05-02  Nikolaus Waxweiler  <madigens@gmail.com>
+
+	Unbreak CMake Windows installation
+
+	* CMakeLists.txt: Generate ftconfig.h on non-UNIX.
+
+2018-05-02  Werner Lemberg  <wl@gnu.org>
+
+	Remove FT_CONFIG_OPTION_PIC and related code.
+
+	*/* [FT_CONFIG_OPTION_PIC]: Remove all code guarded by this
+	preprocessor symbol.
+
+	*/*: Replace `XXX_GET' macros (which could be either a function in
+	PIC mode or an array in non-PIC mode) with `xxx' arrays.
+
+	* include/freetype/internal/ftpic.h, src/autofit/afpic.c,
+	src/autofit/afpic.h, src/base/basepic.c, src/base/basepic.h,
+	src/base/ftpic.c, src/cff/cffpic.c, src/cff/cffpic.h,
+	src/pshinter/pshpic.c, src/pshinter/pshpic.h, src/psnames/pspic.c,
+	src/psnames/pspic.h, src/raster/rastpic.c, src/raster/rastpic.h,
+	src/sfnt/sfntpic.c, src/sfnt/sfntpic.h, src/smooth/ftspic.c,
+	src/smooth/ftspic.h, src/truetype/ttpic.c, src/truetype/ttpic.h:
+	Removed.
+
+
+----------------------------------------------------------------------------
+
+Copyright (C) 2018-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.
+
+
+Local Variables:
+version-control: never
+coding: utf-8
+End:
diff --git a/ChangeLog.22 b/docs/oldlogs/ChangeLog.22
similarity index 99%
rename from ChangeLog.22
rename to docs/oldlogs/ChangeLog.22
index 4517c32..b06d645 100644
--- a/ChangeLog.22
+++ b/docs/oldlogs/ChangeLog.22
@@ -2821,7 +2821,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2005-2018 by
+Copyright (C) 2005-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog.23 b/docs/oldlogs/ChangeLog.23
similarity index 99%
rename from ChangeLog.23
rename to docs/oldlogs/ChangeLog.23
index 85253f1..a8a69dd 100644
--- a/ChangeLog.23
+++ b/docs/oldlogs/ChangeLog.23
@@ -750,7 +750,7 @@
 2009-07-31  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
 
 	sfnt: Cast a charcode to 32-bit in cmap format 14 parser.
-	
+
 	* src/sfnt/ttcmap.c (tt_cmap14_char_var_index,
 	tt_cmap14_char_var_isdefault, tt_cmap14_char_variants,
 	tt_cmap14_variant_chars): Correct mismatches from
@@ -1344,24 +1344,24 @@
 	* include/freetype/config/ftstdlib.h: Introduce
 	FT_INT_MIN, to use in signed integer overflow in
 	16-bit and 64-bit platforms.
-	
+
 	* include/freetype/internal/fttrace.h: Add a tracer
 	to ftsynth.c.
-	
+
 	* src/base/ftbitmap.c (FT_Bitmap_Embolden): Check
 	invalid strength causing integer overflow on 16-bit
 	platform.
-	
+
 	* src/base/ftcalc.c (ft_corner_orientation): Change
 	the internal calculation from FT_Int to FT_Long, to
 	avoid an overflow on 16-bit platforms.  The caller of
 	this function should use only the sign of result,
 	so the cast to FT_Int is acceptable.
-	
+
 	* src/base/ftsynth.c: Introduce a tracer for synth module.
 	(FT_GlyphSlot_Embolden): Check invalid strength causing
 	integer overflow on 16-bit platform.
-	
+
 	* src/bdf/bdfdrivr.c (BDF_Face_Init): The glyph index
 	in FT2 API is typed as FT_UInt, although BDF driver
 	can handle unsigned long glyph index internally.  To
@@ -1372,25 +1372,25 @@
 	glyph pitch internally.  To avoid integer overflow on
 	16-bit platform, too large glyph pitch should not be
 	returned.
-	
+
 	* src/pfr/pfrsbit.c (pfr_slot_load_bitmap): The glyph
 	pitch in FT2 is typed as FT_UInt, although PFR font
 	format can include huge bitmap glyph with 24-bit pitch
 	(however, a glyph spends 16.7 pixel, it's not realistic).
 	To avoid integer overflow on 16-bit platform, huge
 	bitmap glyph should be excluded.
-	
+
 	* src/smooth/ftgrays.c (gray_hline): As FT_Span.x is
 	truncated to fit its type (16-bit short), FT_Span.y
 	should be truncated to fit its type (FT_Int).
-	
+
 	* src/cff/cffdrivr.c (cff_get_ros): CFF specification
 	defines the supplement in ROS as a real number.
 	Truncate it to fit public FT2 API.
-	
+
 	* src/cff/cffparse.c (cff_parse_cid_ros): Warn the
 	supplement if it is truncated or rounded in cff_get_ros().
-	
+
 	* src/cff/cfftypes.h: Change the type of internal variable
 	`supplement' from FT_Long to FT_ULong to fit the signedness
 	to the type in public API.
@@ -1653,7 +1653,7 @@
 
 	cff: Fix some data types mismatching with their sources.
 
-	* src/cff/cffgload.c (cff_slot_load): The types of	
+	* src/cff/cffgload.c (cff_slot_load): The types of
 	`top_upm' and `sub_upm' are matched with
 	CFF_FontRecDict->units_per_em.
 
@@ -1811,56 +1811,56 @@
 	gxv_XClassTable_lookupval_validate,
 	gxv_XClassTable_lookupfmt4_transit):
 	Update from GXV_LookupValueDesc to GXV_LookupValueCPtr.
-	
+
 	* src/gxvalid/gxvbsln.c (gxv_bsln_LookupValue_validate,
 	gxv_bsln_LookupFmt4_transit): Ditto.
-	
+
 	* src/gxvalid/gxvjust.c
 	(gxv_just_pcTable_LookupValue_entry_validate,
 	gxv_just_classTable_entry_validate,
 	gxv_just_wdcTable_LookupValue_validate): Ditto.
-	
+
 	* src/gxvalid/gxvkern.c
 	(gxv_kern_subtable_fmt1_entry_validate): Ditto.
-	
+
 	* src/gxvalid/gxvlcar.c (gxv_lcar_LookupValue_validate,
 	gxv_lcar_LookupFmt4_transit): Ditto.
-	
+
 	* src/gxvalid/gxvopbd.c (gxv_opbd_LookupValue_validate,
 	gxv_opbd_LookupFmt4_transit): Ditto.
-	
+
 	* src/gxvalid/gxvprop.c (gxv_prop_LookupValue_validate,
 	gxv_prop_LookupFmt4_transit): Ditto.
-	
+
 	* src/gxvalid/gxvmort4.c
 	(gxv_mort_subtable_type4_lookupval_validate): Ditto.
-	
+
 	* src/gxvalid/gxvmort0.c
 	(gxv_mort_subtable_type0_entry_validate): Update
 	from GXV_StateTable_GlyphOffsetDesc
 	to GXV_StateTable_GlyphOffsetCPtr.
-	
+
 	* src/gxvalid/gxvmort1.c
 	(gxv_mort_subtable_type1_entry_validate): Ditto.
-	
+
 	* src/gxvalid/gxvmort2.c
 	(gxv_mort_subtable_type2_entry_validate): Ditto.
-	
+
 	* src/gxvalid/gxvmort5.c
 	(gxv_mort_subtable_type5_entry_validate): Ditto.
-	
+
 	* src/gxvalid/gxvmorx2.c
 	(gxv_morx_subtable_type2_entry_validate): Ditto.
-	
+
 	* src/gxvalid/gxvmorx5.c
 	(gxv_morx_subtable_type5_entry_validate): Ditto.
-	
+
 	* src/gxvalid/gxvmorx1.c
 	(gxv_morx_subtable_type1_entry_validate): Ditto.
 	(gxv_morx_subtable_type1_LookupValue_validate,
 	gxv_morx_subtable_type1_LookupFmt4_transit):
 	Update from GXV_LookupValueDesc to GXV_LookupValueCPtr.
-	
+
 	* src/gxvalid/gxvmorx0.c
 	(gxv_morx_subtable_type0_entry_validate): Update
 	from GXV_XStateTable_GlyphOffsetDesc
@@ -1976,7 +1976,7 @@
 	Prevent the overflows by a glyph with too many points or contours.
 	The bug is reported by Boris Letocha <b.letocha@gmc.net>.  See
 	https://lists.gnu.org/archive/html/freetype-devel/2009-06/msg00031.html
-	https://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00002.html	
+	https://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00002.html
 
 	* include/freetype/ftimage.h (FT_OUTLINE_CONTOURS_MAX,
 	FT_OUTLINE_POINTS_MAX): New macros to declare the maximum
@@ -6948,7 +6948,7 @@
 
 2006-11-25  David Turner  <david@freetype.org>
 
-	* src/autofit/afhints.c	(af_glyph_hints_dump_points,
+	* src/autofit/afhints.c (af_glyph_hints_dump_points,
 	af_glyph_hints_dump_segments, af_glyph_hints_dumpedges) [!AF_DEBUG]:
 	Add stubs to link the `ftgrid' test program when debugging is
 	disabled in the auto-hinter.
@@ -7932,7 +7932,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2006-2018 by
+Copyright (C) 2006-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog.24 b/docs/oldlogs/ChangeLog.24
similarity index 99%
rename from ChangeLog.24
rename to docs/oldlogs/ChangeLog.24
index 44abc40..0dbb2ac 100644
--- a/ChangeLog.24
+++ b/docs/oldlogs/ChangeLog.24
@@ -231,7 +231,7 @@
 
 	* src/base/md5.c, src/base/md5.h: New files, taken from
 
-	  http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+	  https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
 
 	* include/freetype/internal/fttrace.h: Add `bitmap'.
 
@@ -707,7 +707,7 @@
 	[base] Fix integer overflow.
 
 	* src/base/ftoutln.c (FT_Outline_EmboldenXY): Normalize incoming and
-	outgoing vectors and use fixed point arithmetic.
+	outgoing vectors and use fixed-point arithmetic.
 
 2013-01-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
@@ -774,7 +774,7 @@
 
 	(Font_Class): Rename to...
 	(SPH_Font_Class): This.  Decorate with `const' where appropriate.
-	
+
 	* src/truetype/ttsubpix.h (scale_test_tweak, sph_test_tweak):
 	Decorate arguments with `const' where appropriate.
 
@@ -1271,7 +1271,7 @@
 	* src/autofit/afcjk.c (af_cjk_metrics_init_widths): Use it.
 	(af_cjk_metrics_init, af_cjk_script_class): Updated.
 
-	* src/autofit/afindic.c	(af_indic_metrics_init,
+	* src/autofit/afindic.c (af_indic_metrics_init,
 	af_indic_script_class): Updated.
 
 	* src/autofit/afcjk.h, src/autofit/aflatin.h: Updated.
@@ -6344,7 +6344,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2010-2018 by
+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,
diff --git a/ChangeLog.25 b/docs/oldlogs/ChangeLog.25
similarity index 99%
rename from ChangeLog.25
rename to docs/oldlogs/ChangeLog.25
index 59cf2bf..31d5111 100644
--- a/ChangeLog.25
+++ b/docs/oldlogs/ChangeLog.25
@@ -3405,7 +3405,7 @@
 
 	The canonical URL to get updates for this file is
 
-	  http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/popa3d/popa3d/md5/
+	  https://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/popa3d/popa3d/md5/
 
 	as the author told me in private communication.
 
@@ -4837,7 +4837,7 @@
 
 	Apply fixes for cppcheck nitpicks.
 
-	  http://cppcheck.sourceforge.net/
+	  https://cppcheck.sourceforge.net/
 
 	The call was (from the top-level of the FreeType tree):
 
@@ -5145,7 +5145,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2013-2018 by
+Copyright (C) 2013-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog.26 b/docs/oldlogs/ChangeLog.26
similarity index 99%
rename from ChangeLog.26
rename to docs/oldlogs/ChangeLog.26
index ea89e91..528345e 100644
--- a/ChangeLog.26
+++ b/docs/oldlogs/ChangeLog.26
@@ -2393,7 +2393,7 @@
 
 	* src/autofit/afcjk.c (af_cjk_get_standard_width): New function.
 	(af_cjk_writing_system_class): Updated.
-	* src/autofit/afdummy.c	(af_dummy_writing_system_class): Updated.
+	* src/autofit/afdummy.c (af_dummy_writing_system_class): Updated.
 	* src/autofit/afindic.c (af_cjk_get_standard_width): New function.
 	(af_indic_writing_system_class): Updated.
 	* src/autofit/aflatin.c (af_latin_get_standard_width): New function.
@@ -5695,7 +5695,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2015-2018 by
+Copyright (C) 2015-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog.27 b/docs/oldlogs/ChangeLog.27
similarity index 99%
rename from ChangeLog.27
rename to docs/oldlogs/ChangeLog.27
index 0e82b2f..6510e45 100644
--- a/ChangeLog.27
+++ b/docs/oldlogs/ChangeLog.27
@@ -2090,7 +2090,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2016-2018 by
+Copyright (C) 2016-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog.28 b/docs/oldlogs/ChangeLog.28
similarity index 99%
rename from ChangeLog.28
rename to docs/oldlogs/ChangeLog.28
index ca1ff38..603fc61 100644
--- a/ChangeLog.28
+++ b/docs/oldlogs/ChangeLog.28
@@ -2489,8 +2489,8 @@
 
 	Based on ideas taken from
 
-	  http://pkgs.fedoraproject.org/cgit/rpms/freetype.git/tree/freetype-multilib.patch
-	  http://pkgs.fedoraproject.org/cgit/rpms/freetype.git/tree/freetype-2.5.3-freetype-config-prefix.patch
+	  https://pkgs.fedoraproject.org/cgit/rpms/freetype.git/tree/freetype-multilib.patch
+	  https://pkgs.fedoraproject.org/cgit/rpms/freetype.git/tree/freetype-2.5.3-freetype-config-prefix.patch
 
 	* builds/unix/freetype-config.in: Rewritten.  Use `pkg-config' to
 	set output variables if program is available.
@@ -3120,7 +3120,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2016-2018 by
+Copyright (C) 2016-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/ChangeLog b/docs/oldlogs/ChangeLog.29
similarity index 63%
rename from ChangeLog
rename to docs/oldlogs/ChangeLog.29
index b6cb46b..3d73d47 100644
--- a/ChangeLog
+++ b/docs/oldlogs/ChangeLog.29
@@ -1,1362 +1,3 @@
-2018-08-10  Ben Wagner  <bungeman@google.com>
-
-	* src/sfnt/sfobjs.c (sfnt_done_face): Fix memory leak (#54435).
-
-2018-08-10  Werner Lemberg  <wl@gnu.org>
-
-	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Improve tracing.
-
-2018-08-10  Werner Lemberg  <wl@gnu.org>
-
-	Fix clang warnings.
-
-	* src/base/ftdebug.c (ft_trace_level_enabled,
-	ft_trace_level_disabled): Add `static' keyword.
-
-2018-08-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[raster, smooth] Reinstate bitmap size limits.
-
-	This again moves outline and bitmap size checks one level up.
-
-	* src/base/ftoutln.c (FT_Outline_Render): Explicitly reject enormous
-	outlines.
-	* src/raster/ftrend1.c (ft_raster1_render): Reject enormous bitmaps
-	and, therefore, outlines that require them.
-	* src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto.
-
-	* src/raster/ftraster.c (ft_black_render): Remove outline size checks.
-	* src/smooth/ftgrays.c (gray_raster_render): Ditto.
-	[STANDALONE]: Remove `FT_Outline_Get_CBox' copy.
-
-2018-08-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[pcf] Revert massive unsigning.
-
-2018-08-08  Werner Lemberg  <wl@gnu.org>
-
-	[smooth] Improve tracing.
-
-	* src/smooth/ftgrays.c (gray_convert_glyph_inner): Only use tracing
-	if called the first time.
-	(gray_convert_glyph): Updated.
-
-2018-08-08  Werner Lemberg  <wl@gnu.org>
-
-	Add internal functions `FT_Trace_Disable' and `FT_Trace_Enable'.
-
-	It sometimes makes sense to suppress tracing informations, for
-	example, if it outputs identical messages again and again.
-
-	* include/freetype/internal/ftdebug.h: Make `ft_trace_levels' a
-	pointer.
-	(FT_Trace_Disable, FT_Trace_Enable): New declarations.
-
-	* src/base/ftdebug.c (ft_trace_levels): Rename to...
-	(ft_trace_levels_enabled): ... this.
-	(ft_trace_levels_disabled): New array.
-	(ft_trace_levels): New pointer.
-	(FT_Trace_Disable, FT_Trace_Enable): Implement.
-	(ft_debug_init): Updated.
-
-2018-08-08  Werner Lemberg  <wl@gnu.org>
-
-	Debugging improvements.
-
-	* src/base/ftobjs.c (pixel_modes): Move this array to top level
-	from ...
-	(FT_Load_Glyph): ... here.
-	(FT_Render_Glyph_Internal): Use `width' x `height' in trace message.
-	Use `pixel_modes'.
-
-2018-08-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[pcf] Massive unsigning (part 2).
-
-	Treat all size related properties as unsigned values.
-
-	* src/pcf/pcf.h (PCF_ParsePropertyRec): Use unsigned `name' and
-	`value'.
-	* src/pcf/pcfread.c (pcf_get_propeerties, pcf_load_font): Updated
-	parsing code and handling of AVERAGE_WIDTH, POINT_SIZE, PIXEL_SIZE,
-	RESOLUTION_X and RESOLUTION_Y.
-
-2018-08-08  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[pcf] Massive unsigning (part 1).
-
-	Unofficial specifications hesitate to use unsigned 32-bit integers.
-	Negative values caused a lot of trouble in the past and it is safer
-	and easier to treat some properties as unsigned.
-
-	* src/pcf/pcf.h (PCF_AccelRec): Use unsigned values for `fontAscent',
-	`fontDescent', and `maxOverlap'.
-	* src/pcf/pcfread.c (pcf_load_font, pcf_get_accel): Updated.
-	* src/pcf/pcfdrivr.c (PCF_Glyph_Load, PCF_Size_Select,
-	PCF_Size_Request): Updated.
-
-2018-08-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	* src/pcf/pcfread.c (pcf_get_bitmaps): Unsign `offsets' and
-	`bitmapSizes'.
-
-2018-08-06  Werner Lemberg  <wl@gnu.org>
-
-	* devel/ftoption.h: Synchronize with main `ftoption.h'.
-
-2018-08-06  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[pcf] Use unsigned types.
-
-	* src/pcf/pcf.h (PCF_Encoding): Use unsigned `enc'.
-	* src/pcf/pcfdrivr.c (pcf_cmap_char_{index,next}): Ditto.
-	* src/pcf/pcfread.c (pcf_get_encodings): Use unsigned types.
-
-2018-08-05  Werner Lemberg  <wl@gnu.org>
-
-	* src/truetype/ttgload.c (compute_glyph_metrics): Fix overflow.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/chromium/issues/detail?id=777151
-
-2018-08-04  Werner Lemberg  <wl@gnu.org>
-
-	* src/truetype/ttinterp.c (opcode_name): Fix typos.
-
-2018-08-04  Werner Lemberg  <wl@gnu.org>
-
-	Fix clang warnings.
-
-	* src/base/ftoutln.c (FT_Outline_EmboldenXY): Fix type of
-	`orientation'.
-
-	* src/gxvalid/gxvcommn.c (gx_lookup_value_read): Fix signature.
-
-	* src/pcf/pcfread.c (pcf_get_encodings): Fix type of some variables.
-	Add cast.
-
-	* src/type1/t1load.c (parse_weight_vector): Fix cast.
-
-2018-07-31  Werner Lemberg  <wl@gnu.org>
-
-	* src/cid/cidtoken.h: Handle `XUID' keyword.
-
-2018-07-31  Werner Lemberg  <wl@gnu.org>
-
-	[cid] Trace PostScript dictionaries.
-
-	* src/cid/cidload.c: Include FT_INTERNAL_POSTSCRIPT_AUX_H
-	(cid_load_keyword, cid_parse_font_matrix, parse_fd_array,
-	parse_expansion_factor, cid_parse_dict): Add tracing calls.
-	(parse_font_name): New function to trace `/FontName' keywords in
-	/FDArray dict.
-	(cid_field_records): Register `parse_font_name'.
-
-2018-07-30  Werner Lemberg  <wl@gnu.org>
-
-	[cff] Fix typo.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9409
-
-	* src/cff/cffdrivr.c (cff_get_cid_from_glyph_index): Fix boundary
-	check.
-
-2018-07-29  Werner Lemberg  <wl@gnu.org>
-
-	* src/pcf/pcfread.c (pcf_get_encodings): Another thinko.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9608
-
-2018-07-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[smooth] Fix Harmony memory management.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9501
-
-	* src/smooth/ftgrays.c (ft_smooth_render_generic): Restore buffer
-	after each rendering in case of failure. 
-
-2018-07-28  Werner Lemberg  <wl@gnu.org>
-
-	[type1] Avoid segfaults with `FT_Get_PS_Font_Value'.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9610
-
-	* src/type1/t1driver.c (t1_ps_get_font_value): Protect against NULL.
-
-2018-07-27  Werner Lemberg  <wl@gnu.org>
-
-	[truetype] Make `TT_Set_MM_Blend' idempotent (#54388).
-
-	* src/truetype/ttgxvar.c (tt_set_mm_blend): Correctly set
-	`face->doblend' if the current call to the function yields the same
-	blend coordinates as the previous call.
-
-2018-07-27  Werner Lemberg  <wl@gnu.org>
-
-	[psaux, type1]: More tracing improvements.
-
-	* src/psaux/psintrp.c (cf2_interpT2CharString): Trace skipped
-	outline commands.
-
-	* src/psaux/t1decode.c (t1_decoder_parse_charstring): Fix
-	missing case.
-	(t1_decoder_parse_metrics): Make tracing output more compact.
-
-	* src/type1/t1gload.c (T1_Compute_Max_Advance): Be less verbose.
-	(T1_Get_Advances): Add tracing.
-
-2018-07-25  Werner Lemberg  <wl@gnu.org>
-
-	[psaux, type1] Trace PostScript dictionaries and other things.
-
-	The tracing of /Encoding, /Subrs, and /Charstrings is rudimentary
-	right now.
-
-	* src/psaux/psobjs.c (ps_parser_load_field,
-	ps_parser_load_field_table): Add tracing calls.
-
-	* src/psaux/t1decode.c (t1_decoder_parse_charstrings): Make tracing
-	output more compact.
-
-	* src/type1/t1gload.c (T1_Compute_Max_Advance, T1_Get_Advances): Add
-	tracing messages.
-
-	* src/type1/t1load.c (parse_blend_axis_types,
-	parse_blend_design_positions, parse_blend_design_map,
-	parse_weight_vector, t1_load_keyword, t1_parse_font_matrix,
-	parse_encoding, parse_subrs, parse_charstrings, T1_Open_Face): Add
-	tracing calls.
-
-	* src/type1/t1objs.c (T1_Face_Init): Add tracing call.
-
-	* src/sfnt/sfobjs.c (sfnt_init_face): Make tracing message more
-	verbose.
-
-2018-07-25  Werner Lemberg  <wl@gnu.org>
-
-	Fix minor ASAN run-time warnings.
-
-	* src/base/ftutil.c (ft_mem_alloc, ft_mem_realloc): Only call
-	`FT_MEM_ZERO' if we actually have a buffer.
-	(ft_mem_dup): Only call `ft_memcpy' if we actually have a buffer.
-
-2018-07-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[build] Fortify dllexport/dllimport attributes (#53969,#54330).
-
-	We no longer use predefined _DLL, which can be defined for static
-	builds too with /MD. We use DLL_EXPORT and DLL_IMPORT instead,
-	following libtool convention.
-
-	* CMakeLists.txt [WIN32], builds/windows/vc2010/freetype.vcxproj:
-	Define DLL_EXPORT manually.
-
-	* include/freetype/config/ftconfig.h, builds/unix/ftconfig.in,
-	builds/vms/ftconfig.h, builds/windows/vc2010/index.html,
-	src/base/ftver.rc: /_DLL/d, s/FT2_DLLIMPORT/DLL_IMPORT/.
-
-2018-07-24  Werner Lemberg  <wl@gnu.org>
-
-	[type1] Check relationship between number of axes and designs.
-
-	For Multiple Masters fonts We don't support intermediate designs;
-	this implies that
-
-	  number_of_designs == 2 ^^ number_of_axes
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9557
-
-	* src/type1/t1load.c (T1_Open_Face): Ensure above constraint.
-	(T1_Get_MM_Var): Remove now redundant test.
-
-2018-07-24  Hin-Tak Leung  <htl10@users.sourceforge.net>
-
-	[truetype] Match ttdebug's naming of instruction mnemonics.
-
-	* src/truetype/ttinterp.c: The form used in ttdebug,
-	"MDRP[G,B,W,?]", etc., is slightly more readable than
-	"MDRP[00,01,02,03]".
-
-2018-07-24  Werner Lemberg  <wl@gnu.org>
-
-	* src/pcf/pcfread.c (pcf_get_encodings): Thinko.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9561
-
-2018-07-22  Werner Lemberg  <wl@gnu.org>
-
-	* src/pcf/pcfread.c (pcf_get_encodings): Check index of defaultChar.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9527
-
-2018-07-22  Werner Lemberg  <wl@gnu.org>
-
-	* src/pcf/pcfread.c (pcf_load_font): Fix number of glyphs.
-
-	This is an oversight of the module change 2018-07-21.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9524
-
-2018-07-22  Werner Lemberg  <wl@gnu.org>
-
-	[cid] Sanitize `BlueShift' and `BlueFuzz'.
-
-	This code is taken from the type1 module.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9510
-
-	* src/cid/cidload.c (parse_fd_array): Set some private dict default
-	values.
-	(cid_face_open): Do the sanitizing.
-	Fix some tracing messages.
-
-2018-07-21  Werner Lemberg  <wl@gnu.org>
-
-	[pcf] Fix handling of the undefined glyph.
-
-	This change makes the driver use the `defaultChar' property of PCF
-	files.
-
-	* src/pcf/pcf.h (PCF_FaceRec): Change type of `defaultChar' to
-	unsigned.
-
-	* src/pcf/pcfread.c (pcf_get_encodings): Read `defaultChar' as
-	unsigned.
-	Validate `defaultChar'.
-	If `defaultChar' doesn't point to glyph index zero, swap glyphs with
-	index zero and index `defaultChar' and adjust the encodings
-	accordingly.
-
-	* src/pcf/pcfdrivr.c (pcf_cmap_char_index, pcf_cmap_char_next,
-	PCF_Glyph_Load): Undo change from 2002-06-16 which always enforced
-	the first character in the font to be the default character.
-
-2018-07-20  Armin Hasitzka  <prince.cherusker@gmail.com>
-
-	Move the legacy fuzz target to the `freetype-testing' repository.
-
-	It can now be found at
-
-	  https://github.com/freetype/freetype2-testing/tree/master/fuzzing/src/legacy
-
-	* src/tools/ftfuzzer: Remove this folder and its contents from the
-	repository.
-
-2018-07-20  Werner Lemberg  <wl@gnu.org>
-
-	[cff] Avoid left-shift of negative numbers (#54322).
-
-	* src/cff/cffgload.c (cff_slot_load): Use multiplication.
-
-2018-07-17  Werner Lemberg  <wl@gnu.org>
-
-	Allow FT_ENCODING_NONE for `FT_Select_Charmap'.
-
-	This is a valid encoding tag for BDF, PCF, and Windows FNT, and
-	there is no reason to disallow it for these formats.
-
-	* src/base/ftobjs.c (FT_Select_Charmap): Implement it.
-
-2018-07-17  Werner Lemberg  <wl@gnu.org>
-
-	* src/pcf/pcfread.c (pcf_get_encodings): Trace `defaultChar'.
-
-2018-07-16  Armin Hasitzka  <prince.cherusker@gmail.com>
-
-	* include/freetype/internal/ftcalc.h: Add macros for handling
-	harmless over-/underflowing `FT_Int' values.
-
-	* src/sfnt/sfdriver.c (fixed2float): Fix negation of
-	`(int)(-2147483648)'.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9423
-
-2018-07-16  Werner Lemberg  <wl@gnu.org>
-
-	* src/truetype/ttgxvar.c (tt_set_mm_blend): Fix off-by-one error.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9412
-
-2018-07-12  Werner Lemberg  <wl@gnu.org>
-
-	* src/base/ftoutln.c (FT_Outline_Get_Orientation): Init `cbox'.
-
-	Taken from patch #9667, written by Steve Langasek
-	<vorlon@debian.org>.
-
-	This fixes a build failure (most probably a bug in gcc) on ppc64el
-	when building with -O3.
-
-2018-07-05  Werner Lemberg  <wl@gnu.org>
-
-	Fix typo (#54238).
-
-	* src/base/ftcolor.c (FT_Palette_Set_Foreground_Color)
-	[!TT_CONFIG_OPTION_COLOR_LAYERS]: Add return value.
-
-2018-07-05  Werner Lemberg  <wl@gnu.org>
-
-	Adjust table size comparisons (#54242).
-
-	* src/sfnt/ttcpal.c (tt_face_load_cpal): Implement it.
-
-2018-07-05  Werner Lemberg  <wl@gnu.org>
-
-	Fix more 32bit issues (#54208).
-
-	* src/cff/cffload.c (cff_blend_build_vector): Convert assertion into
-	run-time error.
-
-	* src/truetype/ttgxvar.c (ft_var_to_normalized): Protect against
-	numeric overflow.
-
-2018-07-04  Werner Lemberg  <wl@gnu.org>
-
-	Fix 32bit build warnings (#54239).
-
-	* src/base/ftbitmap.c (FT_Bitmap_Blend): Add casts to avoid signed
-	vs. unsigned comparisons.
-
-	* srb/sfnt/ttcolr.c (tt_face_get_colr_layer): Ditto.
-
-2018-07-02  Jeff Carey  <Jeff.Carey@monotype.com>
-
-	* src/psnames/psmodule.c (ps_unicodes_init): Fix alloc debugging.
-
-2018-07-02  Werner Lemberg  <wl@gnu.org>
-
-	s/palette_types/palette_flags/.
-
-	Suggested by Behdad.
-
-2018-07-02  Werner Lemberg  <wl@gnu.org>
-
-	Make `FT_Get_Color_Glyph_Layer' return FT_Bool.
-
-	* include/freetype/freetype.h, src/base/ftobjs.c
-	(FT_Get_Color_Glyph_Layer, FT_Render_Glyph_Internal): Updated.
-
-	* include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func),
-	src/sfnt/ttcolr.h, src/sfnt/ttcolr.c (tt_face_get_colr_layer):
-	Updated.
-
-2018-07-01  Werner Lemberg  <wl@gnu.org>
-
-	* src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Guard SFNT function.
-
-	Reported by Behdad.
-
-2018-06-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	* src/base/fttrigon.c (FT_Tan): Improve accuracy.
-	(FT_Vector_Rotate): Simplify.
-
-2018-06-28  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	* src/base/ftobjs.c (FT_Set_Charmap): Robustify.
-
-2018-06-25  Werner Lemberg  <wl@gnu.org>
-
-	[truetype] Fix memory leak.
-
-	* src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Add initializers.
-	Fix typo in `goto' destination.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9071
-
-2018-06-25  Werner Lemberg  <wl@gnu.org>
-
-	* src/truetype/ttgxvar.c (tt_face_vary_cvt): Add initializers.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9070
-
-2018-06-24  Werner Lemberg  <wl@gnu.org>
-
-	[truetype] Increase precision while applying VF deltas.
-
-	It turned out that we incorrectly round CVT and glyph point deltas
-	before accumulation, leading to severe positioning errors if there
-	are many delta values to sum up.
-
-	Problem reported by Akiem Helmling <akiem@underware.nl> and analyzed
-	by Behdad.
-
-	* src/truetype/ttgxvar.c (ft_var_readpackeddelta): Return deltas in
-	16.16 format.
-	(tt_face_var_cvt): Collect deltas in `cvt_deltas', which is a 16.16
-	format array, and add the accumulated values to the CVT at the end
-	of the function.
-	(TT_Vary_Apply_Glyph_Deltas): Store data in `points_org' and
-	`points_out' in 16.16 format.
-	Collect deltas in `point_deltas_x' and `point_deltas_y', which are
-	16.16 format arrays, and add the accumulated values to the glyph
-	coordinates at the end of the function.
-
-2018-06-24  Werner Lemberg  <wl@gnu.org>
-
-	New base function `FT_Matrix_Check' (#54019).
-
-	* src/base/ftcalc.c (FT_Matrix_Check): New base function to properly
-	reject degenerate font matrices.
-
-	* include/freetype/internal/ftcalc.h: Updated.
-
-	* src/cff/cffparse.c (cff_parse_font_matrix), src/cid/cidload.c
-	(cid_parse_font_matrix), src/type1/t1load.c (t1_parse_font_matrix),
-	src/type42/t42parse.c (t42_parse_font_matrix): Use
-	`FT_Matrix_Check'.
-
-2018-06-23  Werner Lemberg  <wl@gnu.org>
-
-	Fix typo.
-
-	Reported by Behdad.
-
-	* src/base/ftcolor.c (FT_Palette_Data_Get)
-	[!TT_CONFIG_OPTION_COLOR_LAYERS]: s/apalette/apalette_data/.
-
-2018-06-21  Werner Lemberg  <wl@gnu.org>
-
-	s/FT_PALETTE_USABLE_WITH_/FT_PALETTE_FOR_/.
-
-	* include/freetype/ftcolor.h, include/freetype/internal/sfnt.h,
-	src/sfnt/ttcolr.c: Do it.
-
-2018-06-19  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Fix CPAL heap buffer overflow.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8968
-
-	* src/sfnt/ttcpal.c (tt_face_load_cpal): Guard CPAL version 1
-	offsets.
-
-2018-06-19  Werner Lemberg  <wl@gnu.org>
-
-	Doh.  Don't use CPAL or COLR data if tables are missing.
-
-	Reported by Alexei.
-
-	* src/sfnt/ttcolr.c (tt_face_get_colr_layer): Return immediately if
-	`colr' is NULL.
-
-	* src/sfnt/ttcpal.c (tt_face_palette_set): Return immediately, if
-	`cpal' is NULL.
-
-2018-06-17  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[base] Introduce `FT_New_Glyph'.
-
-	This function facilitates access to full capabilities of FreeType
-	rendering engine for custom glyphs. This can be quite useful for
-	consistent rendering of mathematical and chemical formulas, e.g.
-
-	  https://bugs.chromium.org/p/chromium/issues/detail?id=757078
-
-	* include/freetype/ftglyph.h, src/base/ftglyph.c (FT_New_Glyph): New
-	function.
-
-2018-06-17  Armin Hasitzka  <prince.cherusker@gmail.com>
-
-	[bdf] Fix underflow of an unsigned value.
-
-	bdflib.c:1562 could be reached with `font->glyphs_used == 0'.  That
-	caused an underflow of the unsigned value which results in undefined
-	behaviour.
-
-	* src/bdf/bdflib.c (_bdf_parse_glyphs): Bail out earlier than before
-	if the `ENCODING' keyword cannot be found.
-
-2018-06-17  Werner Lemberg  <wl@gnu.org>
-
-	[base] Add tracing for `FT_Bitmap_Blend'.
-
-	* include/freetype/internal/fttrace.h (trace_bitmap): New
-	enumeration.
-
-	* src/base/ftbitmap.c (FT_COMPONENT): Define.
-	(FT_Bitmap_Blend): Add `FT_TRACE5' calls.
-
-2018-06-17  Werner Lemberg  <wl@gnu.org>
-
-	s/trace_bitmap/trace_checksum/.
-
-	* include/freetype/internal/fttrace.h: s/bitmap/checksum/.
-
-	* src/base/ftobjs.c (FT_COMPONENT): s/trace_bitmap/trace_checksum/.
-	Adjust code.
-
-2018-06-16  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Fix color glyph layer loading.
-
-	* src/sfnt/ttcolr.c (Colr): Add `table_size' field.
-	(tt_face_load_colr): Set it.
-	(tt_face_get_colr_layer): Check pointer limit for layer entries.
-
-2018-06-16  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Fix color palette loading.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8933
-
-	* src/sfnt/ttcpal.c (Cpal): Add `table_size' field.
-	(tt_face_load_cpal): Set it.
-	(tt_face_palette_set): Check pointer limit for color entries.
-
-2018-06-16  Werner Lemberg  <wl@gnu.org>
-
-	* src/base/ftbitmap.c (FT_Bitmap_Blend): Avoid integer overflow.
-
-2018-06-16  Werner Lemberg  <wl@gnu.org>
-
-	Add `FT_Bitmap_Blend' API.
-
-	Still missing: Support for negative bitmap pitch and subpixel offset
-	of source bitmap.
-
-	* include/freetype/ftbitmap.h, src/base/ftbitmap.c
-	(FT_Bitmap_Blend): New function.
-
-2018-06-14  Werner Lemberg  <wl@gnu.org>
-
-	Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'.
-
-	This avoids any additional allocation of COLR related structures in
-	a glyph slot.
-
-	* include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec,
-	FT_Get_GlyphLayers): Removed.
-
-	* include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed.
-	(FT_Slot_InternalRec): Remove `color_layers'.
-
-	* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func):
-	Removed.
-	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove
-	`load_colr_layer'.
-
-	* src/base/ftobjs.c (ft_glyph_slot_done): Updated.
-	(FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'.
-	(FT_Get_GlyphLayers): Removed.
-
-	* src/sfnt/sfdriver.c (sfnt_interface): Updated.
-
-	* src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed.
-	* src/sfnt/ttcolr.h: Updated.
-
-	* src/truetype/ttgload.c (TT_Load_Glyph): Updated.
-
-2018-06-14  Werner Lemberg  <wl@gnu.org>
-
-	Provide iterative API to access `COLR' data.
-
-	This solution doesn't store any data in an `FT_GlyphSlot' object.
-
-	* include/freetype/freetype.h (FT_LayerIterator): New structure.
-	(FT_Get_Color_Glyph_Layer): New function.
-
-	* include/freetype/internal/sfnt.h (TT_Get_Colr_Layer_Func): New
-	function type.
-	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it.
-
-	* src/base/ftobjs.c (FT_Get_Color_Glyph_Layer): Implement it.
-
-	* src/sfnt/ttcolr.c (tt_face_get_colr_layer): New function.
-	* src/sfnt/ttcolr.h: Updated.
-
-	* src/sfnt/sfdriver.c (sfnt_interface): Updated.
-
-2018-06-14  Werner Lemberg  <wl@gnu.org>
-
-	Add glyph index and glyph load flags to glyph slot.
-
-	* include/freetype/freetype.h (FT_GlyphSlotRec): Rename unused
-	`reserved' field to `glyph_index'.
-
-	* include/freetype/internal/ftobjs.h (FT_Slot_InternalRec): Add
-	`load_flags' field.
-
-	* src/base/ftobjs.c (FT_Load_Glyph): Set new fields.
-
-2018-06-14  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Move `CPAL' stuff into separate files.
-
-	* src/sfnt/sfdriver.c: Include `ttcpal.h'.
-	* src/sfnt/sfnt.c: Include `ttcpal.c'.
-
-	* src/sfnt/ttcolr.c, src/sfnt/ttcolr.h: Move CPAL stuff to ...
-	* src/sfnt/ttcpal.c, src/sfnt/ttcpal.c: ... these new files.
-
-	* src/sfnt/Jamfile (_sources), src/sfnt/rules.mk (SFNT_DRV_SRC):
-	Updated.
-
-	* include/freetype/internal/fttrace.h: Add support for `colr' and
-	`cpal'.
-	Sort entries.
-
-2018-06-13  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Separate `CPAL' and `COLR' table handling.
-
-	Later on we want to support the `SVG' table also, which needs `CPAL'
-	(but not `COLR').
-
-	* include/freetype/internal/sfnt.h (SFNT_Interface): Add `load_cpal'
-	and `free_cpal' fields.
-	(FT_DEFINE_SFNT_INTERFACE): Updated.
-
-	* include/freetype/internal/tttypes.h (TT_FaceRec): Replace
-	`colr_and_cpal' fields with `cpal' and `colr'.
-
-	* src/sfnt/sfdriver.c (sfnt_interface): Updated.
-
-	* src/sfnt/sfobjs.c (sfnt_load_face, sfnt_done_face): Updated.
-
-	* src/sfnt/ttcolr.c (Colr, Cpal): Add `table' field.
-	(ColrCpal): Removed.
-	(tt_face_load_colr): Split off CPAL handling into...
-	(tt_face_load_cpal): ... this new function.
-	(tt_face_free_colr): Split off CPAL handling into...
-	(tt_face_free_cpal): ... this new function.
-	(tt_face_load_colr_layers, tt_face_palette_set): Updated.
-
-	* src/sfnt/ttcolr.h: Updated.
-
-	* src/truetype/ttgload.c (TT_Load_Glyph): Updated.
-
-2018-06-12  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Fix `sizeof' thinko.
-
-	* src/sfnt/ttcolr.c (tt_face_load_colr, tt_face_palette_set): Don't
-	use `sizeof' for computing array limit.
-
-2018-06-12  Werner Lemberg  <wl@gnu.org>
-
-	Finish CPAL/COLR support (4/4).
-
-	* src/sfnt/ttcolr.c (tt_face_find_color): Removed.
-	(tt_face_colr_blend_layer): Use `face->palette' instead of calling
-	`tt_face_find_color'.
-	Use and set text foreground color.
-
-2018-06-12  Werner Lemberg  <wl@gnu.org>
-
-	Finish CPAL/COLR support (3/4).
-
-	* src/base/ftcolor.c: Include FT_INTERNAL_SFNT_H.
-	(FT_Palette_Select, FT_Palette_Set_Foreground_Color): Implement
-	functions.
-
-2018-06-12  Werner Lemberg  <wl@gnu.org>
-
-	Finish CPAL/COLR support (2/4).
-
-	* src/sfnt/ttcolr.c (tt_face_palette_set): New function.
-	(tt_face_load_colr): Allocate `face->palette' and call
-	`tt_face_palette_set'.
-	Adjust return error code in case of error.
-
-	* src/sfnt/ttcolr.h: Updated.
-
-	* include/freetype/internal/sfnt.h (TT_Set_Palette_Func): New
-	function type.
-	(SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it.
-
-	* src/sfnt/sfdriver.c (sfnt_interface), src/sfnt/sfobjs.c
-	(sfnt_done_face): Updated.
-
-2018-06-12  Werner Lemberg  <wl@gnu.org>
-
-	Finish CPAL/COLR support (1/4).
-
-	* include/freetype/internal/tttypes.h (TT_FaceRec): New fields
-	`palette_index', `palette', `have_foreground_color' and
-	`foreground_color'.
-
-2018-06-12  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Minor.
-
-	* src/sfnt/ttcolr.c (tt_face_load_colr_layers):
-	s/palette_index/palette_entry_index/ for consistency.
-	Adjust return error code in case of error.
-
-2018-06-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[raster] Clean up.
-
-	* src/raster/ftraster.c (black_TWorker, SCALED, Set_High_Precision):
-	Clean up after 5-level gray removal (8dc8635874).
-	(Vertical_Sweep_Span): Be brief.
-
-2018-06-10  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Fix compiler warnings.
-
-	* src/sfnt/ttcolr.c (tt_face_load_colr, tt_face_load_colr_layers,
-	tt_face_colr_blend_layer): Add `NULL' initializers.
-
-2018-06-10  Werner Lemberg  <wl@gnu.org>
-
-	s/FT_Palette/FT_Palette_Data/, s/palette/palette_data/.
-
-	* include/freetype/ftcolor.h, include/freetype/internal/tttypes.h,
-	src/base/ftcolor.c, src/sfnt/sfobjs.c, src/sfnt/ttcolr.c: Updated.
-
-2018-06-10  Nikolaus Waxweiler  <madigens@gmail.com>
-
-	CMakeLists: also accept IOS_PLATFORM=SIMULATOR64
-
-	This might be needed to build FreeType for the iOS simulator. See
-	https://savannah.nongnu.org/bugs/index.php?54048. Patch contributed
-	by Steve Robinson.
-
-	* CMakeLists.txt: Accept IOS_PLATFORM=SIMULATOR64
-
-2018-06-10  Werner Lemberg  <wl@gnu.org>
-
-	Implement `FT_Palette_Get'.
-
-	* src/base/ftcolor.c: New file.
-
-	* src/base/Jamefile (_sources), src/base/rules.mk (BASE_SRC),
-	src/base/ftbase.c: Add `ftcolor.c'.
-
-2018-06-10  Werner Lemberg  <wl@gnu.org>
-
-	* src/sfnt/ttcolr.c (tt_face_load_colr): Improve overflow checks.
-
-2018-06-09  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[raster] Deal with pitch sign earlier.
-
-	* src/raster/ftraster.c (black_TWorker): Remove unused `traceG',
-	s/bTarget/bOrigin/.
-	(Render_Glyph): Set `ras.bOrigin' at the bottom-left corner.
-	(Vertical_Sweep_Init, {Vertical,Horizontal}_Sweep_{Span,Drop}):
-	Updated accordingly.
-
-2018-06-09  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Read `CPAL' version 1 tables.
-
-	* include/freetype/internal.tttypes.h: Include FT_COLOR_H.
-	(TT_FaceRec): Add `palette' field.
-
-	* src/sfnt/ttcolr.c: Include FT_COLOR_H.
-	(Cpal): Remove all data covered by the new `palette' field in
-	`TT_FaceRec'.
-	(tt_face_load_colr): Updated.
-	Read `CPAL' version 1 data.
-	(tt_face_load_colr_layers, tt_face_find_color): Updated.
-
-	* src/sfnt/sfobjs.c (sfnt_done_face): Free glyph color palette data.
-
-2018-06-07  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[base] API for Harmony LCD rendering.
-
-	This introduces `FT_Library_SetLcdGeometry' for setting up arbitrary
-	LCD subpixel geometry including non-striped patterns.
-
-	* src/base/ftlcdfil.c (FT_Library_SetLcdGeometry): New function.
-	* include/freetype/ftlcdfil.h: Document it.
-	* include/freetype/freetype.h: Minor.
-	* include/freetype/ftchapters.h: Minor.
-
-2018-06-06  Werner Lemberg  <wl@gnu.org>
-
-	ftcolor.h: Redesign API.
-
-	While going to implement it I noticed that I need access to most of
-	the `CPAL' elements; I thus plan to add a `cpal' field to
-	`TT_FaceRec', which makes most of the previously suggested API
-	functions obsolete because the fields will be directly accessible.
-
-2018-06-06  Parth Wazurkar  <parthwazurkar@gmail.com>
-
-	[bdf, pcf] Remove deprecated FT_FACE_FLAG_FAST_GLYPHS flag.
-
-	* src/bdf/bdfdrivr.c (BDF_Face_Init): Remove deprecated
-	FT_FACE_FLAG_FAST_GLYPHS flag.
-
-	* src/pcf/pcfread.c (pcf_load_font): Remove deprecated
-	FT_FACE_FLAG_FAST_GLYPHS flag.
-
-2018-06-06  Werner Lemberg  <wl@gnu.org>
-
-	[smooth, raster] Limit bitmap size (#54019).
-
-	* src/raster/ftraster.c [STANDALONE] (FT_Outline_Get_CBox): Add
-	function.
-	[!STANDALONE]: Include FT_OUTLINE_H.
-	(ft_black_render): Compute CBox and reject glyphs larger than
-	0xFFFF x 0xFFFF.
-
-	* src/smooth/ftgrays.c (gray_raster_render): Reject glyphs larger
-	than 0xFFFF x 0xFFFF.
-
-2018-06-03  Armin Hasitzka  <prince.cherusker@gmail.com>
-
-	* src/smooth/ftgrays.c (gray_convert_glyph): Remove unused variables.
-
-2018-06-03  Werner Lemberg  <wl@gnu.org>
-
-	* src/tools/glnames.py (main): Emit header in `light' comment style.
-
-2018-06-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[smooth] Attempt to mitigate bug #54019.
-
-	The robust rendering of estra large glyphs came with unbearable cost.
-	The old way of bisecting should fail but fail faster.
-
-	* src/smooth/ftgrays.c (gray_convert_glyph): Switch back to bisecting
-	in y-direction.
-
-2018-06-02  Werner Lemberg  <wl@gnu.org>
-
-	* src/truetype/ttinterp.c (Ins_MIRP): Use SUB_LONG; avoid FT_ABS.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8706
-
-2018-06-02  Werner Lemberg  <wl@gnu.org>
-
-	* src/autofit/afwarp.h: Use AF_CONFIG_OPTION_USE_WARPER (#54033).
-
-2018-05-31  Werner Lemberg  <wl@gnu.org>
-
-	* src/raster/ftraster.c (black_TWorker_): Remove `gTarget' field.
-
-	This is no longer used.
-
-2018-05-31  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Get colors from `CPAL' table in right order (#54015).
-
-	* src/sfnt/ttcolr.c (tt_face_find_color): Fix it.
-
-2018-05-30  Werner Lemberg  <wl@gnu.org>
-
-	ftcolor.h: Improve API design, fix typos (#54011, #54014).
-
-	* include/freetype/ftcolor.h (FT_Palette_Get_Names): Replace with...
-	(FT_Palette_Get_Name_IDs): ... this function.
-	(FT_Palette_Get_Entry_Names): Replace with...
-	(FT_Palette_Get_Entry_Name_IDs): ... this function
-	s/FT_Palette_Set_Foreground_COlor/FT_Palette_Set_Foreground_Color/.
-
-2018-05-30  Armin Hasitzka  <prince.cherusker@gmail.com>
-
-	Beautify a3cfed5e87232c933bdc64f43e8ebebcfd18b41b.
-
-	* src/autofit/afloader.c (af_loader_load_glyph): Move the
-	initialisationand declaration of variables into the if-block.
-
-2018-05-30  Armin Hasitzka  <prince.cherusker@gmail.com>
-
-	Fix pointer underflow.
-
-	The declaration of `edge2' can be reached with `edge1 == NULL' and
-	`axis->edges == 0' which results in undefined behaviour.
-
-	* src/autofit/afloader.c (af_loader_load_glyph): Initialise `edge2'
-	after checking `axis->num_edges > 1'.  `edge1 != NULL' can be assumed.
-
-2018-05-30  Werner Lemberg  <wl@gnu.org>
-
-	Various minor color fixes.
-
-	* include/freetype/config/ftheader.h (FT_COLOR_H): New macro.
-
-	* include/freetype/internal/ftobjs.h (FT_Colr_Internal): Change
-	type of `load_flags' to `FT_Int32'.
-
-	* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): Change
-	type of `idx' to `FT_UInt'.
-	(TT_Blend_Colr_Func): Change type of `color_index' to `FT_UInt'.
-
-	* src/base/ftobjs.c (FT_Render_Glyph_Internal): Change type of
-	`load_flags' to `FT_Int32'.
-
-	* src/sfnt/ttcolr.c (find_base_glyph_record,
-	tt_face_load_colr_layers): Change type of `glyph_id' to `FT_UInt'.
-	(tt_face_find_color, tt_face_colr_blend_layer): Change type of
-	`color_index' to `FT_UInt'.
-	Fix signedness and type issues.
-
-	* src/sfnt/ttcolr.h: Updated.
-
-2018-05-25  Nikhil Ramakrishnan  <ramakrishnan.nikhil@gmail.com>
-
-	[docmaker] Fix missing `Defined in (...)' under Windows/Cygwin.
-
-	This platform uses backslashes for paths, which docmaker didn't
-	understand correctly.
-
-	* src/tools/docmaker/tohtml.py (HtmlFormatter::blockEnter): Use
-	`os.path.normpath' to normalize the path for the platform being
-	used.
-
-2018-05-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[smooth] Formalize Harmony LCD rendering.
-
-	This generalizes magic outline shifts that make Harmony LCD
-	rendering work in terms of precise two-dimensional RGB subpixel
-	positions. These coordinates are now set in time of the `smooth'
-	module initialization and later used to shift a glyph outline for
-	rendering. FT_RENDER_MODE_LCD and FT_RENDER_MODE_LCD_V use the same
-	coordinates. The letter, however, rotates them before using.
-	The LCD bitmap padding is also calculated using these coordinates.
-
-	* include/freetype/internal/ftobjs.h (FT_LibraryRec): New array field
-	`lcd_geometry'.
-	* src/base/ftlcdfil.c (ft_lcd_padding): Reworked.
-	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Updated accordingly.
-
-	* src/smooth/ftsmooth.c [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]
-	(ft_smooth_init): Initialize `lcd_geometry'.
-	(ft_smooth_render_generic): Formalize outline shifts.
-
-2018-05-22  Werner Lemberg  <wl@gnu.org>
-
-	[truetype] Reject elements of composites with invalid glyph indices.
-
-	Reported as
-
-	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8413
-
-	* src/truetype/ttgload.c (TT_Load_Composite_Glyph): Implement it.
-
-2018-05-22  Werner Lemberg  <wl@gnu.org>
-
-	* src/truetype/ttgload.c (TT_Load_Simple_Glyph): Trace # of points.
-
-2018-05-20  Werner Lemberg  <wl@gnu.org>
-
-	* include/freetype/ftcolor.h: New file.
-
-	This is an interface to the `CPAL' OpenType table.  No
-	implementation yet.
-
-2018-05-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	* include/freetype/internal/ftcalc.h (FT_MSB): Verified `_MSC_VER'.
-
-	Actually `_BitScanReverse' is available since VS2005.
-
-2018-05-18  Werner Lemberg  <wl@gnu.org>
-
-	* include/freetype/internal/ftcalc.h (FT_MSB): Use `_MSC_VER' value.
-
-	Older VC versions don't provide `_BitScanReverse'.  We test for VC
-	2013.
-
-	Reported by John Emmas <john@creativepost.co.uk>.
-
-2018-05-17  Werner Lemberg  <wl@gnu.org>
-
-	s/inline/__inline/ for MSVC.
-
-	Reported by John Emmas <john@creativepost.co.uk>.
-
-	* include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Do it.
-
-2018-05-16  Werner Lemberg  <wl@gnu.org>
-
-	Add function `FT_Get_GlyphLayers' to access `COLR' table data.
-
-	* include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec): Move this
-	structure to...
-	* include/freetype/freetype.h (FT_Glyph_LayerRec): ... this
-	header file.
-	(FT_Glyph_Layer): New typedef.
-	Update code to use it where appropriate.
-
-	* src/base/ftobjs.c (FT_Get_GlyphLayers): New function.
-
-2018-05-15  Alexei Podtelezhnikov  <apodtele@gmail.com>
-
-	[base] Fix mono bitmap presetting (#53896).
-
-	It is rather fundamental to set monochrome bitmap based on rounded
-	CBox because the b/w rasterizer turns on pixels when their centers are
-	inside the glyph outline. The dropout control is unpredictable and can
-	distort narrow glyphs if the bitmap is too wide.
-
-	Reported by Chris Liddell.
-
-	* src/base/ftobjs.c (ft_glyphslot_preset_bitmap): If BBox boundaries
-	are too close, adjust them before rounding.
-
-2018-05-15  Werner Lemberg  <wl@gnu.org>
-
-	[psaux] Fix compiler warning (#53915).
-
-	* src/psaux/psft.c (cf2_freeT1SeacComponent): Do it.
-
-2018-05-15  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Fix memory leak in handling `COLR' data.
-
-	* src/truetype/ttgload.c (TT_Load_Glyph): Free old `layers' array
-	before reassigning allocated memory.
-	Only allocate `color_layers' if we don't have one already.
-
-2018-05-15  Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] If `COLR' is present, don't assume that all glyphs use it.
-
-	* src/sfnt/ttcolr.c (tt_face_load_colr_layers): Return FT_Err_Ok if
-	current glyph is not a `COLR' base glyph.
-
-	* src/truetype/ttgload.c (TT_Load_Glyph): Don't allocate
-	`color_layers' if there are no color layers.
-
-2018-05-14  Werner Lemberg  <wl@gnu.org>
-
-	* src/base/ftobjs.c (FT_Load_Glyph): Fix signature of `pixel_modes'.
-
-2018-05-14  Werner Lemberg  <wl@gnu.org>
-
-	Provide dummy functions if `TT_CONFIG_OPTION_SFNT_NAMES' is not set.
-
-	* src/base/ftsnames.c [!TT_CONFIG_OPTION_SFNT_NAMES]: Implement it.
-
-2018-05-13  Werner Lemberg  <wl@gnu.org>
-
-	* src/base/ftobjs.c (FT_Load_Glyph): Improve tracing.
-
-2018-05-13  Shao Yu Zhang  <shaozhang@fb.com>
-	    Werner Lemberg  <wl@gnu.org>
-
-	[sfnt] Preliminary support of coloured layer outlines (#44689).
-
-	This commit enables OpenType's COLR/CPAL table handling; a typical
-	application are color emojis that can be scaled to any size.
-
-	If the color palette does not exist or is invalid, the rendering
-	step rasterizes the outline instead.  The current implementation
-	assumes that the foreground is black.
-
-	Enable this by defining option TT_CONFIG_OPTION_COLOR_LAYERS.
-
-	There are still some issues with metrics; additionally, an API to
-	fetch color layers is missing.
-
-	* devel/ftoption.h, include/freetype/config/ftoption.h
-	(TT_CONFIG_OPTION_COLOR_LAYERS): New macro.
-
-	* include/freetype/internal/ftobjs.h (FT_Glyph_LayerRec,
-	FT_Colr_InternalRec): New structures.
-	(FT_Slot_InternalRec): Add `color_layers' field.
-
-	* include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func,
-	TT_Blend_Colr_Func): New function types.
-	(SFNT_Interface): Add `load_colr', `free_colr', `load_colr_layer',
-	and `colr_blend' fields.
-
-	* include/freetype/internal/tttypes.h (TT_FaceRec): Add
-	`colr_and_cpal' field.
-
-	* include/freetype/internal/tttags. (TTAG_COLR, TTAG_CPAL): New
-	macros.
-
-	* src/sfnt/ttcolr.c, src/sfnt/ttcolr.h: New files.
-
-	* src/base/ftobjs.c (ft_glyphslot_done, FT_Render_Glyph_Internal):
-	Handle glyph color layers.
-
-	* src/sfnt/Jamfile (_sources), src/sfnt/rules.mk (SFNT_DRV_SRC): Add
-	`ttcolr.c'.
-
-	* src/sfnt/sfdriver.c: Include `ttcolr.h'.
-	(PUT_COLOR_LAYERS): New macro.
-	Update call to `FT_DEFINE_SFNT_INTERFACE'.
-
-	* src/sfnt/sfnt.c: Include `ttcolr.c'.
-
-	* src/sfnt/sfobjs.c (sfnt_load_face): Load `COLR' and `CPAL' tables.
-	(sfnt_done_face): Updated.
-
-	* src/truetype/ttgload.c (TT_Load_Glyph): Handle color layers.
-
-2018-05-12  Arkady Shapkin  <arkady.shapkin@gmail.com>
-
-	Use MS VC++'s _BitScanReverse to calculate MSB (patch #9636).
-
-	* include/freetype/internal/ftcalc.h (FT_MSB) [_MSC_VER]: Implement
-	it.
-
-2018-05-10  Alan Coopersmith  <alan.coopersmith@oracle.com>
-
-	Fix DLL compilation on Solaris.
-
-	AC_COMPILE_IFELSE only tries to compile a `*.c' to a `*.o'.  The
-	Solaris Studio 12.1 through 12.5 compilers see the
-	`-fvisibility=hidden' flag, but ignore it with a warning of:
-
-	  cc: Warning: Option -fvisibility=hidden passed to ld,
-	               if ld is invoked, ignored otherwise
-
-	AC_LINK_IFELSE does the compile and then tries to link the result,
-	at which point the Solaris linker will issue an error:
-
-	  ld: fatal: option '-fvisibility=hidden' is incompatible with
-	      building a dynamic executable
-
-	If we don't use AC_LINK_IFELSE to catch the error, then configure
-	will fail further tests which attempt to link, such as those testing
-	dependencies like `libbz2'.
-
-	Also, don't try adding `-fvisibility' if we have already added
-	`-xldscope', just use one of them, since Sun Studio 12 and earlier
-	compilers only issue a warning, and don't try passing through to the
-	linker to generate an error, so AC_LINK_IFELSE doesn't catch them.
-
-	Tested on Solaris 11.4 beta with compiler versions:
-
-	  Sun Studio 8 (Sun C 5.5)
-	  Sun Studio 10 (Sun C 5.7)
-	  Sun Studio 11 (Sun C 5.8)
-	  Sun Studio 12 (Sun C 5.9)
-	  Sun Studio 12.1 (Sun C 5.10)
-	  Oracle Solaris Studio 12.2 (Sun C 5.11)
-	  Oracle Solaris Studio 12.3 (Sun C 5.12)
-	  Oracle Solaris Studio 12.4 (Sun C 5.13)
-	  Oracle Developer Studio 12.5 (Sun C 5.14)
-	  Oracle Developer Studio 12.6 (Sun C 5.15)
-	  gcc 5.5.0
-	  gcc 7.3.0
-
-	and verified the libfreetype.so.6 generated by each of those
-	compilers exported the same set of symbols.
-
-	* builds/unix/configure.raw: Implement it.
-
-2018-05-08  Werner Lemberg  <wl@gnu.org>
-
-	[autofit] Avoid potential SEGV if running out of memory.
-
-	Problem reported by Shailesh Mistry <shailesh.mistry@hotmail.co.uk>.
-
-	* src/autofit/afshaper.c (af_shaper_buf_create,
-	af_shaper_buf_destroy) [!FT_CONFIG_OPTION_USE_HARFBUZZ]: Don't
-	allocate and free a four-byte buffer.  Instead, make those functions
-	no-ops; the calling functions will provide a pointer to a buffer
-	instead.
-
-	* src/autofit/afcjk.c (af_cjk_metrics_init_widths,
-	af_cjk_metrics_init_blues, af_cjk_metrics_check_digits),
-	src/autofit/aflatin.c (af_latin_metrics_init_widths,
-	af_latin_metrics_init_blues, af_latin_metrics_check_digits)
-	[!FT_CONFIG_OPTION_USE_HARFBUZZ]: Use pointer to local variable for
-	`shaper_buf'.
-
-2018-05-07  Nikolaus Waxweiler  <madigens@gmail.com>
-
-	[cmake] Allow using project as subfolder in other project.
-
-	* CMakeLists.txt: Test for CMake build directory being different
-	from source directory.  Provide other parts of the build system
-	access the full include directory.
-
-2018-05-07  Werner Lemberg  <wl@gnu.org>
-
-	[build] Suppress configure's `nothing to be done' message.
-
-	This is due to calling the configure script via `make' (within the
-	top-level `configure' wrapper script).  The same can happen for all
-	other secondary make targets that are used to only modify the
-	primary one, e.g., `make setup devel'.
-
-	* builds/dos/detect.mk (emx, turboc, watcom, borlandc, borlandc16),
-	builds/os2/detect (visualage, watcom, borlandc, devel),
-	builds/unix/detect.mk (devel, lcc, unix), builds/windows/detect.mk
-	(visualc, watcom, visualage, lcc, mingw32, bcc32, devel-bcc,
-	devel-gcc): Use no-op recipe.
-
-2018-05-04  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
-
-	Support symbol visibility features of Sun / Oracle C compilers.
-
-	Reported by Kiyoshi Kanazawa:
-	https://lists.gnu.org/archive/html/freetype-devel/2018-05/msg00008.html
-	Thanks to the suggestions by Alexei and Alan Coopersmith.
-
-	* builds/unix/configure.raw: Check if "-xldscope=hidden" is
-	accepted, and if so, it is added to CFLAGS.  This is the option
-	making Sun / Oracle C compilers hide the symbols from global
-	scope.
-	* include/freetype/config/ftconfig.h: Use "__global" prefix
-	for FT_EXPORT() macro, if SunPro C is newer than Sun ONE
-	Studio 8 (2003).
-	* builds/unix/ftconfig.in: Ditto.
-	* builds/vms/ftconfig.h: Ditto.
-
-2018-05-02  Nikolaus Waxweiler  <madigens@gmail.com>
-
-	Unbreak CMake Windows installation
-
-	* CMakeLists.txt: Generate ftconfig.h on non-UNIX.
-
-2018-05-02  Werner Lemberg  <wl@gnu.org>
-
-	Remove FT_CONFIG_OPTION_PIC and related code.
-
-	*/* [FT_CONFIG_OPTION_PIC]: Remove all code guarded by this
-	preprocessor symbol.
-
-	*/*: Replace `XXX_GET' macros (which could be either a function in
-	PIC mode or an array in non-PIC mode) with `xxx' arrays.
-
-	* include/freetype/internal/ftpic.h, src/autofit/afpic.c,
-	src/autofit/afpic.h, src/base/basepic.c, src/base/basepic.h,
-	src/base/ftpic.c, src/cff/cffpic.c, src/cff/cffpic.h,
-	src/pshinter/pshpic.c, src/pshinter/pshpic.h, src/psnames/pspic.c,
-	src/psnames/pspic.h, src/raster/rastpic.c, src/raster/rastpic.h,
-	src/sfnt/sfntpic.c, src/sfnt/sfntpic.h, src/smooth/ftspic.c,
-	src/smooth/ftspic.h, src/truetype/ttpic.c, src/truetype/ttpic.h:
-	Removed.
-
 2018-05-01  Werner Lemberg  <wl@gnu.org>
 
 	* Version 2.9.1 released.
@@ -3695,7 +2336,7 @@
 
 ----------------------------------------------------------------------------
 
-Copyright 2017-2018 by
+Copyright (C) 2017-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This file is part of the FreeType project, and may only be used, modified,
diff --git a/docs/raster.txt b/docs/raster.txt
index 8ef466e..1642a81 100644
--- a/docs/raster.txt
+++ b/docs/raster.txt
@@ -63,7 +63,7 @@
     `26.6' means  that 26 bits  are used for  the integer part  of a
     value   and  6   bits  are   used  for   the   fractional  part.
     Consequently, the `distance'  between two neighbouring pixels is
-    64 `units' (1 unit = 1/64th of a pixel).
+    64 `units' (1 unit = 1/64 of a pixel).
 
     Note  that, for  the rasterizer,  pixel centers  are  located at
     integer   coordinates.   The   TrueType   bytecode  interpreter,
@@ -618,7 +618,7 @@
 
 ------------------------------------------------------------------------
 
-Copyright 2003-2018 by
+Copyright (C) 2003-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file  is  part  of the  FreeType  project, and may  only be  used,
diff --git a/docs/reference/.gitignore b/docs/reference/.gitignore
deleted file mode 100644
index 2d19fc7..0000000
--- a/docs/reference/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.html
diff --git a/docs/reference/README b/docs/reference/README
deleted file mode 100644
index 51b04d6..0000000
--- a/docs/reference/README
+++ /dev/null
@@ -1,5 +0,0 @@
-After saying `make refdoc' this directory contains the FreeType API
-reference.  You need python to make this target.
-
-This also works with Jam: Just type `jam refdoc' in the main directory.
-
diff --git a/docs/release b/docs/release
index 44b4cb1..fec91e8 100644
--- a/docs/release
+++ b/docs/release
@@ -1,26 +1,23 @@
 How to prepare a new release
 ----------------------------
 
-. include/freetype/freetype.h:  Update FREETYPE_MAJOR, FREETYPE_MINOR,
-  and FREETYPE_PATCH.
+. include/freetype/freetype.h: Update `FREETYPE_MAJOR`,
+  `FREETYPE_MINOR`, and `FREETYPE_PATCH`.
 
 . Update version numbers in all files where necessary (for example, do
-  a grep for both `2.3.1' and `231' for release 2.3.1).
+  a grep for both '2.10.4' and '2104' for release 2.10.4).
 
-. builds/unix/configure.raw: Update `version_info'.
+. builds/unix/configure.raw: Update `version_info`.
 
 . docs/CHANGES: Document differences to last release.
 
 . README: Update.
 
-. docs/VERSIONS.TXT: Document changed `version_info'.
-
-. ChangeLog:   Announce  new  release   (both  in  the  freetype2  and
-  freetype2-demos modules).
+. docs/VERSIONS.TXT: Document changed `version_info`.
 
 . Clone the git archive to another directory with
 
-    git clone -l -s . ../freetype2.test
+    git clone -l -s . ../freetype.test
 
   or something like this and run
 
@@ -30,19 +27,23 @@
     make distclean; make devel CC=g++; make multi CC=g++
 
     sh autogen.sh
-    make distclean; ./configure; make
     make distclean; ./configure CC=g++; make
 
   in the cloned repository to test compilation with both gcc and g++.
 
-. Test C++ compilation  for freetype2-demos too  (using `git clone' as
+  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
+  every commit.
+
+. Test C++ compilation for 'freetype-demos' too (using `git clone` as
   above).
 
-. Run  src/tools/chktrcmp.py  and check  that there  are no  undefined
-  trace_XXXX macros.
+. Run `src/tools/chktrcmp.py` and check that there are no undefined
+  `trace_XXXX` macros.
 
-. After pushing the new release,  tag the git repositories (freetype2,
-  freetype2-demos) with
+. After pushing the new release, tag the git repositories ('freetype',
+  'freetype-demos') with
 
     git tag VER-<version> -m "" -u <committer>
 
@@ -54,46 +55,47 @@
 
     git clean -ndx
 
-  that the git directory is really clean  (and remove extraneous files
+  that the git directory is really clean (and remove extraneous files
   if necessary).
 
-. Say `make  dist' in both the  freetype2 and freetype2-demos  modules
-  to generate the .tar.gz, .tar.bz2, and .zip files.
+. Say `make dist` in both the 'freetype' and 'freetype-demos'
+  repositories to generate the `.tar.gz`, `.tar.xz`, and `.zip` files.
 
-. Create     the     doc    bundles    (freetype-doc-<version>.tar.gz,
-  freetype-doc-<version>.tar.bz2,    ftdoc<version>.zip).    This   is
+. Create the doc bundles (`freetype-doc-<version>.tar.gz`,
+  `freetype-doc-<version>.tar.xz`, `ftdoc<version>.zip`).  This is
   everything in
 
     <freetype-web git repository>/freetype2/docs
 
-  except the `reference' subdirectory.   Do *not* use option `-l' from
+  except the `reference` subdirectory.  Do *not* use option `-l` from
   zip!
 
-. Run the following script (with updated `$VERSION', `$SAVANNAH_USER',
-  and $SOURCEFORGE_USER  variables) to sign and upload the  bundles to
+. Run the following script (with updated `$VERSION`, `$SAVANNAH_USER`,
+  and `$SOURCEFORGE_USER` variables) to sign and upload the bundles to
   both Savannah and SourceForge.  The signing code has been taken from
-  the `gnupload' script (part of the automake bundle).
+  the `gnupload` script (part of the 'automake' bundle).
 
     #!/bin/sh
 
-    VERSION=2.5.1
+    VERSION=2.12.0
     SAVANNAH_USER=wl
     SOURCEFORGE_USER=wlemb
+    GPG_KEY_ID=BE6C3AAC63AD8E3F
 
     #####################################################################
 
-    GPG='/usr/bin/gpg --batch --no-tty'
+    GPG="/usr/bin/gpg --batch --no-tty --local-user $GPG_KEY_ID"
 
     version=`echo $VERSION | sed "s/\\.//g"`
 
     FREETYPE_PACKAGES="freetype-$VERSION.tar.gz \
-                       freetype-$VERSION.tar.bz2 \
+                       freetype-$VERSION.tar.xz \
                        ft$version.zip"
     FT2DEMOS_PACKAGES="ft2demos-$VERSION.tar.gz \
-                       ft2demos-$VERSION.tar.bz2 \
+                       ft2demos-$VERSION.tar.xz \
                        ftdmo$version.zip"
     FTDOC_PACKAGES="freetype-doc-$VERSION.tar.gz \
-                    freetype-doc-$VERSION.tar.bz2 \
+                    freetype-doc-$VERSION.tar.xz \
                     ftdoc$version.zip"
 
     PACKAGE_LIST="$FREETYPE_PACKAGES \
@@ -155,12 +157,13 @@
 
     # EOF
 
-. Prepare a  README for SourceForge  and upload it  with the following
-  script (with updated `$VERSION' and $SOURCEFORGE_USER variables).
+. Prepare a `README` file for SourceForge and upload it with the
+  following script (with updated `$VERSION` and `$SOURCEFORGE_USER`
+  variables).
 
     #!/bin/sh
 
-    VERSION=2.5.1
+    VERSION=2.10.4
     SOURCEFORGE_USER=wlemb
 
     #####################################################################
@@ -170,26 +173,24 @@
 
     # EOF
 
-. On   SourceForge,   tag   the    just   uploaded   `ftXXX.zip'   and
-  `freetype-XXX.tar.bz2'  files as the  default files to  download for
-  `Windows' and `Others', respectively.
+. On SourceForge, tag the just uploaded `ftXXX.zip` and
+  `freetype-XXX.tar.xz` files as the default files to download for
+  'Windows' and 'Others', respectively.
 
-. Copy the reference files (generated by `make dist') to
+. Trigger the automatic generation of the online API reference by
+  updating the `FT_VERSION` variable in file `.gitlab-ci.yml` of the
+  'freetype-web' repository.
 
-    <freetype-web git repository>/freetype2/docs/reference
+. Announce new release on 'freetype-announce@nongnu.org' and to
+  relevant newsgroups.  The text should include
 
-. Update the `freetype-web' repository.  `git push' then automatically
-  triggers an update  of the public web pages  within ten minutes, due
-  to a cron script (on wl@freedesktop.org) that rsyncs with
-
-    freedesktop.org://srv/freetype.freedesktop.org/www
-
-. Announce new release on freetype-announce@nongnu.org and to relevant
-  newsgroups.
+  - SHA256 checksums of all files,
+  - instructions how to verify the bundles using the `.sig` file data,
+  - the PGP public key used to sign the archives.
 
 ----------------------------------------------------------------------
 
-Copyright 2003-2018 by
+Copyright (C) 2003-2023 by
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
 This  file is  part of  the FreeType  project, and  may only  be used,
diff --git a/generate_notice.py b/generate_notice.py
new file mode 100644
index 0000000..26d3939
--- /dev/null
+++ b/generate_notice.py
@@ -0,0 +1,606 @@
+#!/usr/bin/env python3
+
+from enum import Enum
+from pathlib import Path
+from typing import Sequence
+from typing import Tuple
+import argparse
+import os
+import re
+import sys
+
+# list of specific files to be ignored.
+IGNORE_FILE_NAME = [
+  # Exclude myself
+  "generate_notice.py",
+
+  # License files
+  "LICENSE",
+  "LICENSE.TXT",
+  "LICENSE_APACHE2.TXT",
+  "LICENSE_BSD_3_CLAUSE.TXT",
+  "LICENSE_FSFAP.TXT",
+  "LICENSE_MIT.TXT",
+  "LICENSE_MIT_MODERN_VARIANT.TXT",
+  "MODULE_LICENSE_BSD_LIKE",
+  "NOTICE",
+  "builds/unix/LICENSE_GPLv2_WITH_AUTOCONF_EXCEPTION.TXT",
+  "builds/unix/LICENSE_GPLv3_WITH_AUTOCONF_EXCEPTION.TXT",
+  "docs/FTL.TXT",
+  "docs/GPLv2.TXT",
+  "src/gzip/LICENSE_ZLIB.TXT",
+
+  # The patch file contains copyright line as a diff. Use it if Copyright is not
+  # in a unified diff line.
+  "src/gzip/patches/freetype-zlib.diff",
+]
+
+NO_COPYRIGHT_FILES = [
+  ".clang-format",
+  ".gitignore",
+  ".gitlab-ci.yml",
+  ".mailmap",
+  "Android.bp",
+  "METADATA",
+  "OWNERS",
+  "README.android",
+  "TEST_MAPPING",
+  "builds/atari/ATARI.H",
+  "builds/atari/FNames.SIC",
+  "builds/atari/FREETYPE.PRJ",
+  "builds/atari/README.TXT",
+  "builds/atari/deflinejoiner.awk",
+  "builds/atari/gen-purec-patch.sh",
+  "builds/mac/FreeType.m68k_cfm.make.txt",
+  "builds/mac/FreeType.m68k_far.make.txt",
+  "builds/mac/FreeType.ppc_carbon.make.txt",
+  "builds/mac/FreeType.ppc_classic.make.txt",
+  "builds/mac/README",
+  "builds/mac/ascii2mpw.py",
+  "builds/mac/freetype-Info.plist",
+  "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/wince/vc2005-ce/freetype.sln",
+  "builds/wince/vc2005-ce/freetype.vcproj",
+  "builds/wince/vc2005-ce/index.html",
+  "builds/wince/vc2008-ce/freetype.sln",
+  "builds/wince/vc2008-ce/freetype.vcproj",
+  "builds/wince/vc2008-ce/index.html",
+  "builds/windows/.gitignore",
+  "builds/windows/vc2010/freetype.sln",
+  "builds/windows/vc2010/freetype.user.props",
+  "builds/windows/vc2010/freetype.vcxproj",
+  "builds/windows/vc2010/freetype.vcxproj.filters",
+  "builds/windows/vc2010/index.html",
+  "builds/windows/visualc/freetype.dsp",
+  "builds/windows/visualc/freetype.dsw",
+  "builds/windows/visualc/freetype.sln",
+  "builds/windows/visualc/freetype.vcproj",
+  "builds/windows/visualc/index.html",
+  "builds/windows/visualce/freetype.dsp",
+  "builds/windows/visualce/freetype.dsw",
+  "builds/windows/visualce/freetype.vcproj",
+  "builds/windows/visualce/index.html",
+  "devel-teeui/OWNERS",
+  "devel-teeui/README.md",
+  "devel-teeui/ftmodule.h",
+  "devel-teeui/rules.json",
+  "devel-teeui/rules.mk",
+  "docs/.gitignore",
+  "docs/CMAKE",
+  "docs/INSTALL.MAC",
+  "docs/MAKEPP",
+  "docs/PROBLEMS",
+  "docs/README",
+  "docs/freetype-config.1",
+  "docs/markdown/images/favico.ico",
+  "docs/markdown/javascripts/extra.js",
+  "docs/markdown/stylesheets/extra.css",
+  "include/freetype/config/ftmodule.h",
+  "include/freetype/ftchapters.h",
+  "libft2.map.txt",
+  "objs/.gitignore",
+  "objs/README",
+  "src/gzip/README.freetype",
+  "src/gzip/crc32.h",
+  "src/gzip/inffixed.h",
+  "src/tools/apinames.c",
+  "src/tools/chktrcmp.py",
+  "src/tools/cordic.py",
+  "src/tools/ftrandom/Makefile",
+  "src/tools/ftrandom/README",
+  "src/tools/make_distribution_archives.py",
+  "src/tools/no-copyright",
+  "src/tools/test_afm.c",
+  "src/tools/test_bbox.c",
+  "src/tools/test_trig.c",
+  "src/tools/update-copyright",
+  "subprojects/harfbuzz.wrap",
+  "subprojects/libpng.wrap",
+  "subprojects/zlib.wrap",
+  "tests/README.md",
+  "tests/issue-1063/main.c",
+  "tests/meson.build",
+  "tests/scripts/download-test-fonts.py",
+]
+
+class CommentType(Enum):
+  C_STYLE_BLOCK = 1  # /* ... */
+  C_STYLE_BLOCK_AS_LINE = 2  # /* ... */ but uses multiple lines of block comments.
+  C_STYLE_LINE = 3 # // ...
+  SCRIPT_STYLE_HASH = 4 #  # ...
+  SCRIPT_STYLE_DOLLER = 5 # $! ...
+  DOC_STYLE = 6 # no comment escape
+  UNKNOWN = 10000
+
+
+# Helper function of showing error message and immediate exit.
+def fatal(msg: str):
+  sys.stderr.write(msg)
+  sys.stderr.write("\n")
+  sys.exit(1)
+
+
+def warn(msg: str):
+  sys.stderr.write(msg)
+  sys.stderr.write("\n")
+
+
+def cleanup_and_join(out_lines: Sequence[str]):
+  while not out_lines[-1].strip():
+    out_lines.pop(-1)
+
+  # If all lines starts from empty space, strip it out.
+  while all([len(x) == 0 or x[0] == ' ' for x in out_lines]):
+    out_lines = [x[1:] for x in out_lines]
+
+  if not out_lines:
+    fatal("Failed to get copyright info")
+  return "\n".join(out_lines)
+
+
+def get_comment_type(copyright_line: str, path: str) -> CommentType:
+  # vms_make.com contains multiple copyright header as a string constants.
+  if path.endswith("/vms_make.com"):
+    return CommentType.SCRIPT_STYLE_DOLLER
+
+  if "docs/" in path or "README" in path:
+    return CommentType.DOC_STYLE
+
+  if copyright_line.startswith("#"):
+    return CommentType.SCRIPT_STYLE_HASH
+  if copyright_line.startswith("//"):
+    return CommentType.C_STYLE_LINE
+  if copyright_line.startswith("$!"):
+    return CommentType.SCRIPT_STYLE_DOLLER
+
+  if "/*" in copyright_line and "*/" in copyright_line:
+    # ftrandom.c uses single line block comment for the first Copyright line,
+    # and following license notice is wrapped with single block comment.
+    # This file can be handled by C_STYLE_BLOCK parser.
+    if path.endswith("src/tools/ftrandom/ftrandom.c"):
+      return CommentType.C_STYLE_BLOCK
+    else:
+      return CommentType.C_STYLE_BLOCK_AS_LINE
+  else:
+    return CommentType.C_STYLE_BLOCK
+
+
+# Extract copyright notice and returns next index.
+def extract_copyright_at(lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+  commentType = get_comment_type(lines[i], path)
+
+  if commentType == CommentType.C_STYLE_BLOCK:
+    return extract_from_c_style_block_at(lines, i, path)
+  if commentType == CommentType.C_STYLE_BLOCK_AS_LINE:
+    return extract_from_c_style_block_as_line_at(lines, i, path)
+  elif commentType == CommentType.C_STYLE_LINE:
+    return extract_from_c_style_lines_at(lines, i, path)
+  elif commentType == CommentType.SCRIPT_STYLE_HASH:
+    return extract_from_script_hash_at(lines, i, path)
+  elif commentType == CommentType.SCRIPT_STYLE_DOLLER:
+    return extract_from_script_doller_at(lines, i, path)
+  elif commentType == CommentType.DOC_STYLE:
+    return extract_from_doc_style_at(lines, i, path)
+  else:
+    fatal("Uknown comment style: %s" % lines[i])
+
+
+def extract_from_doc_style_at(
+    lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+  if not lines[i].startswith("Copyright"):
+    return (None, i + 1)
+
+  def is_copyright_end(lines: str, start: int, i: int) -> bool:
+    # treat double spacing as end of license header
+    if i - start > 4 and lines[i] == "" and lines[i + 1] == "":
+      return True
+    return False
+
+  start = i
+  while i < len(lines):
+    if is_copyright_end(lines, start, i):
+      break
+    i += 1
+  end = i
+
+  if start == end:
+    fatal("Failed to get copyright info")
+  out_lines = lines[start:end]
+
+  return (cleanup_and_join(out_lines), i + 1)
+
+
+def extract_from_c_style_lines_at(
+    lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+  def is_copyright_end(line):
+    if line.startswith("//"):
+      return False
+    else:
+      return True
+  start = i
+  while i < len(lines):
+    if is_copyright_end(lines[i]):
+      break
+    i += 1
+  end = i
+
+  if start == end:
+    fatal("Failed to get copyright info")
+
+  out_lines = []
+  for line in lines[start:end]:
+    if line.startswith("// "):
+      out_lines.append(line[3:])
+    elif line == "//":
+      out_lines.append(line[2:])
+    else:
+      out_lines.append(line)
+
+  return (cleanup_and_join(out_lines), i + 1)
+
+
+def extract_from_script_hash_at(
+    lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+  if lines[i].strip()[0] != "#":
+    return (None, i + 1)
+  def is_copyright_end(lines: str, i: int) -> bool:
+    if "#" not in lines[i]:
+      return True
+    # treat double spacing as end of license header
+    if lines[i] == "#" and lines[i+1] == "#":
+      return True
+    return False
+
+  start = i
+  while i < len(lines):
+    if is_copyright_end(lines, i):
+      break
+    i += 1
+  end = i
+
+  if start == end:
+    fatal("Failed to get copyright info")
+
+  out_lines = []
+  for line in lines[start:end]:
+    if line.startswith("# "):
+      out_lines.append(line[2:])
+    elif line == "#":
+      out_lines.append(line[1:])
+    else:
+      out_lines.append(line)
+
+  return (cleanup_and_join(out_lines), i + 1)
+
+
+def extract_from_script_doller_at(
+    lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+  if not lines[i].strip().startswith("$!"):
+    return (None, i + 1)
+  def is_copyright_end(lines: str, i: int) -> bool:
+    if "$!" not in lines[i]:
+      return True
+    # treat double spacing as end of license header
+    if lines[i] == "$!" and lines[i+1] == "$!":
+      return True
+    return False
+
+  start = i
+  while i < len(lines):
+    if is_copyright_end(lines, i):
+      break
+    i += 1
+  end = i + 1
+
+  if start == end:
+    fatal("Failed to get copyright info")
+
+  out_lines = []
+  for line in lines[start:end]:
+    if line.startswith("$! "):
+      out_lines.append(line[3:])
+    elif line == "$!":
+      out_lines.append(line[2:])
+    else:
+      out_lines.append(line)
+
+  return (cleanup_and_join(out_lines), i + 1)
+
+
+def extract_from_c_style_block_at(
+    lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+
+  def is_copyright_end(lines: str, i: int) -> bool:
+    if "*/" in lines[i]:
+      return True
+    if "understand and accept it fully." in lines[i]:
+      return True
+    if "see copyright notice in zlib.h" in lines[i]:
+      return True
+    if lines[i] == " *" and lines[i + 1] == " *":
+      return True
+    if lines[i] == "" and lines[i + 1] == "":
+      return True
+    return False
+
+  start = i
+  i += 1 # include at least one line
+  while i < len(lines):
+    if is_copyright_end(lines, i):
+      break
+    i += 1
+  end = i + 1
+
+  out_lines = []
+  for line in lines[start:end]:
+    clean_line = line
+
+    # Strip begining "/*" chars
+    if clean_line.startswith("/* "):
+      clean_line = clean_line[3:]
+    if clean_line == "/*":
+      clean_line = clean_line[2:]
+
+    # Strip ending "*/" chars
+    if clean_line.endswith(" */"):
+      clean_line = clean_line[:-3]
+    if clean_line.endswith("*/"):
+      clean_line = clean_line[:-2]
+
+    # Strip starting " *" chars
+    if clean_line.startswith(" * "):
+      clean_line = clean_line[3:]
+    if clean_line == " *":
+      clean_line = line[2:]
+
+    # Strip trailing spaces
+    clean_line = clean_line.rstrip()
+
+    out_lines.append(clean_line)
+
+  return (cleanup_and_join(out_lines), i + 1)
+
+
+def extract_from_c_style_block_as_line_at(
+    lines: Sequence[str], i: int, path: str) -> Tuple[str, int]:
+
+  def is_copyright_end(line: str) -> bool:
+    if "*/" in line:
+      return False
+    if re.match(r'/\*+/', line.strip()):
+      return False
+    return True
+
+  start = i
+  i += 1 # include at least one line
+  while i < len(lines):
+    if is_copyright_end(lines[i]):
+      break
+    i += 1
+  end = i + 1
+
+  out_lines = []
+  for line in lines[start:end]:
+    clean_line = line
+
+    if re.match(r'/\*+/', line.strip()):
+      continue
+
+    # Strip begining "/*" chars
+    if clean_line.startswith("/* "):
+      clean_line = clean_line[3:]
+    if clean_line == "/*":
+      clean_line = clean_line[2:]
+
+    # Strip ending "*/" chars
+    if clean_line.endswith(" */"):
+      clean_line = clean_line[:-3]
+    if clean_line.endswith("*/"):
+      clean_line = clean_line[:-2]
+
+    # Strip starting " *" chars
+    if clean_line.startswith(" * "):
+      clean_line = clean_line[3:]
+    if clean_line == " *":
+      clean_line = line[2:]
+
+    # Strip trailing spaces
+    clean_line = clean_line.rstrip()
+
+    out_lines.append(clean_line)
+
+  return (cleanup_and_join(out_lines), i + 1)
+
+# Returns true if the line shows the start of copyright notice.
+def is_copyright_line(line: str, path: str) -> bool:
+  if "Copyright" not in line:
+    return False
+
+  # For avoiding unexpected mismatches, exclude quoted Copyright string.
+  if "`Copyright'" in line: # For src/psaux/psobjs.c
+    return False
+  if "\"Copyright\"" in line:  # For src/cff/cfftoken.h
+    return False
+
+  if (path.endswith("src/tools/update-copyright-year") or
+      path.endswith("src/tools/glnames.py")):
+    # The comment contains string of Copyright. Use only immediate Copyright
+    # string followed by "# ".
+    return line.startswith("# Copyright ")
+
+  if path.endswith("src/gzip/inftrees.c"):
+    # The unused string constant contains word of Copyright. Use only immediate
+    # Copyright string followed by " * ".
+    return line.startswith(" * Copyright ")
+
+  if path.endswith("src/base/ftver.rc"):
+    # Copyright string matches with LegalCopyright key in the RC file.
+    return not "LegalCopyright" in line
+
+  return True
+
+
+# Extract the copyright notice and put it into copyrights arg.
+def do_file(path: str, copyrights: set, no_copyright_files: set):
+  raw = Path(path).read_bytes()
+  try:
+    content = raw.decode("utf-8")
+  except UnicodeDecodeError:
+    content = raw.decode("iso-8859-1")
+
+  lines = content.splitlines()
+
+  if not "Copyright" in content:
+    if path in no_copyright_files:
+      no_copyright_files.remove(path)
+    else:
+      fatal("%s does not contain Copyright line" % path)
+    return
+
+  i = 0
+  license_found = False
+  while i < len(lines):
+    if is_copyright_line(lines[i], path):
+      (notice, nexti) = extract_copyright_at(lines, i, path)
+      if notice:
+        if not notice in copyrights:
+          copyrights[notice] = []
+        copyrights[notice].append(path)
+        license_found = True
+
+      i = nexti
+    else:
+      i += 1
+
+  if not license_found:
+    fatal("License header could not found: %s" % path)
+
+def do_check(path, format):
+  if not path.endswith('/'): # make sure the path ends with slash
+    path = path + '/'
+
+  file_to_ignore = set([os.path.join(path, x) for x in IGNORE_FILE_NAME])
+  no_copyright_files = set([os.path.join(path, x) for x in NO_COPYRIGHT_FILES])
+  copyrights = {}
+
+  for directory, sub_directories,  filenames in os.walk(path):
+    # skip .git directory
+    if ".git" in sub_directories:
+      sub_directories.remove(".git")
+
+    for fname in filenames:
+      fpath = os.path.join(directory, fname)
+      if fpath in file_to_ignore:
+        file_to_ignore.remove(fpath)
+        continue
+      do_file(fpath, copyrights, no_copyright_files)
+
+  if len(file_to_ignore) != 0:
+    fatal("Following files are listed in IGNORE_FILE_NAME but doesn't exists,.\n"
+          + "\n".join(file_to_ignore))
+
+  if len(no_copyright_files) != 0:
+    fatal("Following files are listed in NO_COPYRIGHT_FILES but doesn't exists.\n"
+          + "\n".join(no_copyright_files))
+
+  if format == Format.notice:
+    print_notice(copyrights, False)
+  elif format == Format.notice_with_filename:
+    print_notice(copyrights, True)
+  elif format == Format.html:
+    print_html(copyrights)
+
+def print_html(copyrights):
+  print('<html>')
+  print("""
+  <head>
+    <style>
+      table {
+        font-family: monospace
+      }
+
+      table tr td {
+        padding: 10px 10px 10px 10px
+      }
+    </style>
+  </head>
+  """)
+  print('<body>')
+  print('<table border="1" style="border-collapse:collapse">')
+  for notice in sorted(copyrights.keys()):
+    files = sorted(copyrights[notice])
+
+    print('<tr>')
+    print('<td>')
+    print('<ul>')
+    for file in files:
+      print('<li>%s</li>' % file)
+    print('</ul>')
+    print('</td>')
+    print('<td>')
+    print('<p>%s</p>' % notice.replace('\n', '<br>'))
+    print('</td>')
+
+    print('</tr>')
+
+
+  print('</table>')
+  print('</body></html>')
+
+def print_notice(copyrights, print_file):
+  # print the copyright in sorted order for stable output.
+  for notice in sorted(copyrights.keys()):
+    if print_file:
+      files = sorted(copyrights[notice])
+      print("\n".join(files))
+      print()
+    print(notice)
+    print()
+    print("-" * 67)
+    print()
+
+class Format(Enum):
+  notice = 'notice'
+  notice_with_filename = 'notice_with_filename'
+  html = 'html'
+
+  def __str__(self):
+    return self.value
+
+def main():
+  parser = argparse.ArgumentParser(description="Collect notice headers.")
+  parser.add_argument("--format", dest="format", type=Format, choices=list(Format),
+                      default=Format.notice, help="print filename before the license notice")
+  parser.add_argument("--target", dest="target", action='store',
+                      required=True, help="target directory to collect notice headers")
+  res = parser.parse_args()
+  do_check(res.target, res.format)
+
+if __name__ == "__main__":
+  main()
+
diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h
index 3d127f8..a851516 100644
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -4,7 +4,7 @@
  *
  *   ANSI-specific configuration file (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,20 +18,19 @@
 
   /**************************************************************************
    *
-   * This header file contains a number of macro definitions that are used
-   * by the rest of the engine.  Most of the macros here are automatically
-   * determined at compile time, and you should not need to change it to
-   * port FreeType, except to compile the library with a non-ANSI
-   * compiler.
+   * This header file contains a number of macro definitions that are used by
+   * the rest of the engine.  Most of the macros here are automatically
+   * determined at compile time, and you should not need to change it to port
+   * FreeType, except to compile the library with a non-ANSI compiler.
    *
-   * Note however that if some specific modifications are needed, we
-   * advise you to place a modified copy in your build directory.
+   * Note however that if some specific modifications are needed, we advise
+   * you to place a modified copy in your build directory.
    *
-   * The build directory is usually `builds/<system>', and contains
-   * system-specific files that are always included first when building
-   * the library.
+   * The build directory is usually `builds/<system>`, and contains
+   * system-specific files that are always included first when building the
+   * library.
    *
-   * This ANSI version should stay in `include/config/'.
+   * This ANSI version should stay in `include/config/`.
    *
    */
 
@@ -42,530 +41,9 @@
 #include FT_CONFIG_OPTIONS_H
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
-
-FT_BEGIN_HEADER
-
-
-  /**************************************************************************
-   *
-   *              PLATFORM-SPECIFIC CONFIGURATION MACROS
-   *
-   * These macros can be toggled to suit a specific system.  The current
-   * ones are defaults used to compile FreeType in an ANSI C environment
-   * (16bit compilers are also supported).  Copy this file to your own
-   * `builds/<system>' directory, and edit it to port the engine.
-   *
-   */
-
-
-  /* There are systems (like the Texas Instruments 'C54x) where a `char' */
-  /* has 16 bits.  ANSI C says that sizeof(char) is always 1.  Since an  */
-  /* `int' has 16 bits also for this system, sizeof(int) gives 1 which   */
-  /* is probably unexpected.                                             */
-  /*                                                                     */
-  /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a      */
-  /* `char' type.                                                        */
-
-#ifndef FT_CHAR_BIT
-#define FT_CHAR_BIT  CHAR_BIT
-#endif
-
-
-  /* The size of an `int' type.  */
-#if                                 FT_UINT_MAX == 0xFFFFUL
-#define FT_SIZEOF_INT  ( 16 / FT_CHAR_BIT )
-#elif                               FT_UINT_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_INT  ( 32 / FT_CHAR_BIT )
-#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_INT  ( 64 / FT_CHAR_BIT )
-#else
-#error "Unsupported size of `int' type!"
-#endif
-
-  /* The size of a `long' type.  A five-byte `long' (as used e.g. on the */
-  /* DM642) is recognized but avoided.                                   */
-#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_LONG  ( 32 / FT_CHAR_BIT )
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  ( 32 / FT_CHAR_BIT )
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  ( 64 / FT_CHAR_BIT )
-#else
-#error "Unsupported size of `long' type!"
-#endif
-
-
-  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */
-  /* used -- this is only used to get rid of unpleasant compiler warnings */
-#ifndef FT_UNUSED
-#define FT_UNUSED( arg )  ( (arg) = (arg) )
-#endif
-
-
-  /**************************************************************************
-   *
-   *                    AUTOMATIC CONFIGURATION MACROS
-   *
-   * These macros are computed from the ones defined above.  Don't touch
-   * their definition, unless you know precisely what you are doing.  No
-   * porter should need to mess with them.
-   *
-   */
-
-
-  /**************************************************************************
-   *
-   * Mac support
-   *
-   *   This is the only necessary change, so it is defined here instead
-   *   providing a new configuration file.
-   */
-#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
-  /* no Carbon frameworks for 64bit 10.4.x */
-  /* AvailabilityMacros.h is available since Mac OS X 10.2,        */
-  /* so guess the system version by maximum errno before inclusion */
-#include <errno.h>
-#ifdef ECANCELED /* defined since 10.2 */
-#include "AvailabilityMacros.h"
-#endif
-#if defined( __LP64__ ) && \
-    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
-#undef FT_MACINTOSH
-#endif
-
-#elif defined( __SC__ ) || defined( __MRC__ )
-  /* Classic MacOS compilers */
-#include "ConditionalMacros.h"
-#if TARGET_OS_MAC
-#define FT_MACINTOSH 1
-#endif
-
-#endif
-
-
-  /* Fix compiler warning with sgi compiler */
-#if defined( __sgi ) && !defined( __GNUC__ )
-#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
-#pragma set woff 3505
-#endif
-#endif
-
-
-  /**************************************************************************
-   *
-   * @section:
-   *   basic_types
-   *
-   */
-
-
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_Int16
-   *
-   * @description:
-   *   A typedef for a 16bit signed integer type.
-   */
-  typedef signed short  FT_Int16;
-
-
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_UInt16
-   *
-   * @description:
-   *   A typedef for a 16bit unsigned integer type.
-   */
-  typedef unsigned short  FT_UInt16;
-
-  /* */
-
-
-  /* this #if 0 ... #endif clause is for documentation purposes */
-#if 0
-
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_Int32
-   *
-   * @description:
-   *   A typedef for a 32bit signed integer type.  The size depends on
-   *   the configuration.
-   */
-  typedef signed XXX  FT_Int32;
-
-
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_UInt32
-   *
-   *   A typedef for a 32bit unsigned integer type.  The size depends on
-   *   the configuration.
-   */
-  typedef unsigned XXX  FT_UInt32;
-
-
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_Int64
-   *
-   *   A typedef for a 64bit signed integer type.  The size depends on
-   *   the configuration.  Only defined if there is real 64bit support;
-   *   otherwise, it gets emulated with a structure (if necessary).
-   */
-  typedef signed XXX  FT_Int64;
-
-
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_UInt64
-   *
-   *   A typedef for a 64bit unsigned integer type.  The size depends on
-   *   the configuration.  Only defined if there is real 64bit support;
-   *   otherwise, it gets emulated with a structure (if necessary).
-   */
-  typedef unsigned XXX  FT_UInt64;
-
-  /* */
-
-#endif
-
-#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
-
-  typedef signed int      FT_Int32;
-  typedef unsigned int    FT_UInt32;
-
-#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
-
-  typedef signed long     FT_Int32;
-  typedef unsigned long   FT_UInt32;
-
-#else
-#error "no 32bit type found -- please check your configuration files"
-#endif
-
-
-  /* look up an integer type that is at least 32 bits */
-#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
-
-  typedef int            FT_Fast;
-  typedef unsigned int   FT_UFast;
-
-#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
-
-  typedef long           FT_Fast;
-  typedef unsigned long  FT_UFast;
-
-#endif
-
-
-  /* determine whether we have a 64-bit int type for platforms without */
-  /* Autoconf                                                          */
-#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
-
-  /* FT_LONG64 must be defined if a 64-bit type is available */
-#define FT_LONG64
-#define FT_INT64   long
-#define FT_UINT64  unsigned long
-
-  /**************************************************************************
-   *
-   * A 64-bit data type may create compilation problems if you compile
-   * in strict ANSI mode.  To avoid them, we disable other 64-bit data
-   * types if __STDC__ is defined.  You can however ignore this rule
-   * by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro.
-   */
-#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
-
-#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __BORLANDC__ )  /* Borland C++ */
-
-  /* XXXX: We should probably check the value of __BORLANDC__ in order */
-  /*       to test the compiler version.                               */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __WATCOMC__ )   /* Watcom C++ */
-
-  /* Watcom doesn't provide 64-bit data types */
-
-#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( __GNUC__ )
-
-  /* GCC provides the `long long' type */
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#endif /* __STDC_VERSION__ >= 199901L */
-
-#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
-
-#ifdef FT_LONG64
-  typedef FT_INT64   FT_Int64;
-  typedef FT_UINT64  FT_UInt64;
-#endif
-
-
-#ifdef _WIN64
-  /* only 64bit Windows uses the LLP64 data model, i.e., */
-  /* 32bit integers, 64bit pointers                      */
-#define FT_UINT_TO_POINTER( x ) (void*)(unsigned __int64)(x)
-#else
-#define FT_UINT_TO_POINTER( x ) (void*)(unsigned long)(x)
-#endif
-
-
-  /**************************************************************************
-   *
-   * miscellaneous
-   *
-   */
-
-
-#define FT_BEGIN_STMNT  do {
-#define FT_END_STMNT    } while ( 0 )
-#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
-
-
-  /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
-      ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
-        defined( __IBM__TYPEOF__ ) )                                 || \
-      ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  ( __typeof__ ( type ) )
-#else
-#define FT_TYPEOF( type )  /* empty */
-#endif
-
-
-  /* Use FT_LOCAL and FT_LOCAL_DEF to declare and define, respectively, */
-  /* a function that gets used only within the scope of a module.       */
-  /* Normally, both the header and source code files for such a         */
-  /* function are within a single module directory.                     */
-  /*                                                                    */
-  /* Intra-module arrays should be tagged with FT_LOCAL_ARRAY and       */
-  /* FT_LOCAL_ARRAY_DEF.                                                */
-  /*                                                                    */
-#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
-
-#define FT_LOCAL( x )      static  x
-#define FT_LOCAL_DEF( x )  static  x
-
-#else
-
-#ifdef __cplusplus
-#define FT_LOCAL( x )      extern "C"  x
-#define FT_LOCAL_DEF( x )  extern "C"  x
-#else
-#define FT_LOCAL( x )      extern  x
-#define FT_LOCAL_DEF( x )  x
-#endif
-
-#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
-
-#define FT_LOCAL_ARRAY( x )      extern const  x
-#define FT_LOCAL_ARRAY_DEF( x )  const  x
-
-
-  /* Use FT_BASE and FT_BASE_DEF to declare and define, respectively, */
-  /* functions that are used in more than a single module.  In the    */
-  /* current setup this implies that the declaration is in a header   */
-  /* file in the `include/freetype/internal' directory, and the       */
-  /* function body is in a file in `src/base'.                        */
-  /*                                                                  */
-#ifndef FT_BASE
-
-#ifdef __cplusplus
-#define FT_BASE( x )  extern "C"  x
-#else
-#define FT_BASE( x )  extern  x
-#endif
-
-#endif /* !FT_BASE */
-
-
-#ifndef FT_BASE_DEF
-
-#ifdef __cplusplus
-#define FT_BASE_DEF( x )  x
-#else
-#define FT_BASE_DEF( x )  x
-#endif
-
-#endif /* !FT_BASE_DEF */
-
-
-  /*   When compiling FreeType as a DLL or DSO with hidden visibility      */
-  /*   some systems/compilers need a special attribute in front OR after   */
-  /*   the return type of function declarations.                           */
-  /*                                                                       */
-  /*   Two macros are used within the FreeType source code to define       */
-  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
-  /*                                                                       */
-  /*     FT_EXPORT( return_type )                                          */
-  /*                                                                       */
-  /*       is used in a function declaration, as in                        */
-  /*                                                                       */
-  /*         FT_EXPORT( FT_Error )                                         */
-  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */
-  /*                                                                       */
-  /*                                                                       */
-  /*     FT_EXPORT_DEF( return_type )                                      */
-  /*                                                                       */
-  /*       is used in a function definition, as in                         */
-  /*                                                                       */
-  /*         FT_EXPORT_DEF( FT_Error )                                     */
-  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */
-  /*         {                                                             */
-  /*           ... some code ...                                           */
-  /*           return FT_Err_Ok;                                           */
-  /*         }                                                             */
-  /*                                                                       */
-  /*   You can provide your own implementation of FT_EXPORT and            */
-  /*   FT_EXPORT_DEF here if you want.                                     */
-  /*                                                                       */
-  /*   To export a variable, use FT_EXPORT_VAR.                            */
-  /*                                                                       */
-#ifndef FT_EXPORT
-
-#ifdef FT2_BUILD_LIBRARY
-
-#if defined( _WIN32 ) && defined( DLL_EXPORT )
-#define FT_EXPORT( x )  __declspec( dllexport )  x
-#elif defined( __GNUC__ ) && __GNUC__ >= 4
-#define FT_EXPORT( x )  __attribute__(( visibility( "default" ) ))  x
-#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
-#define FT_EXPORT( x )  __global  x
-#elif defined( __cplusplus )
-#define FT_EXPORT( x )  extern "C"  x
-#else
-#define FT_EXPORT( x )  extern  x
-#endif
-
-#else
-
-#if defined( _WIN32 ) && defined( DLL_IMPORT )
-#define FT_EXPORT( x )  __declspec( dllimport )  x
-#elif defined( __cplusplus )
-#define FT_EXPORT( x )  extern "C"  x
-#else
-#define FT_EXPORT( x )  extern  x
-#endif
-
-#endif
-
-#endif /* !FT_EXPORT */
-
-
-#ifndef FT_EXPORT_DEF
-
-#ifdef __cplusplus
-#define FT_EXPORT_DEF( x )  extern "C"  x
-#else
-#define FT_EXPORT_DEF( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_DEF */
-
-
-#ifndef FT_EXPORT_VAR
-
-#ifdef __cplusplus
-#define FT_EXPORT_VAR( x )  extern "C"  x
-#else
-#define FT_EXPORT_VAR( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_VAR */
-
-
-  /* The following macros are needed to compile the library with a   */
-  /* C++ compiler and with 16bit compilers.                          */
-  /*                                                                 */
-
-  /* This is special.  Within C++, you must specify `extern "C"' for */
-  /* functions which are used via function pointers, and you also    */
-  /* must do that for structures which contain function pointers to  */
-  /* assure C linkage -- it's not possible to have (local) anonymous */
-  /* functions which are accessed by (global) function pointers.     */
-  /*                                                                 */
-  /*                                                                 */
-  /* FT_CALLBACK_DEF is used to _define_ a callback function,        */
-  /* located in the same source code file as the structure that uses */
-  /* it.                                                             */
-  /*                                                                 */
-  /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare   */
-  /* and define a callback function, respectively, in a similar way  */
-  /* as FT_BASE and FT_BASE_DEF work.                                */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
-  /* contains pointers to callback functions.                        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
-  /* that contains pointers to callback functions.                   */
-  /*                                                                 */
-  /*                                                                 */
-  /* Some 16bit compilers have to redefine these macros to insert    */
-  /* the infamous `_cdecl' or `__fastcall' declarations.             */
-  /*                                                                 */
-#ifndef FT_CALLBACK_DEF
-#ifdef __cplusplus
-#define FT_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_CALLBACK_DEF( x )  static  x
-#endif
-#endif /* FT_CALLBACK_DEF */
-
-#ifndef FT_BASE_CALLBACK
-#ifdef __cplusplus
-#define FT_BASE_CALLBACK( x )      extern "C"  x
-#define FT_BASE_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_BASE_CALLBACK( x )      extern  x
-#define FT_BASE_CALLBACK_DEF( x )  x
-#endif
-#endif /* FT_BASE_CALLBACK */
-
-#ifndef FT_CALLBACK_TABLE
-#ifdef __cplusplus
-#define FT_CALLBACK_TABLE      extern "C"
-#define FT_CALLBACK_TABLE_DEF  extern "C"
-#else
-#define FT_CALLBACK_TABLE      extern
-#define FT_CALLBACK_TABLE_DEF  /* nothing */
-#endif
-#endif /* FT_CALLBACK_TABLE */
-
-
-FT_END_HEADER
-
+#include <freetype/config/integer-types.h>
+#include <freetype/config/public-macros.h>
+#include <freetype/config/mac-support.h>
 
 #endif /* FTCONFIG_H_ */
 
diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h
index bb96837..e607bce 100644
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -4,7 +4,7 @@
  *
  *   Build macros of the FreeType 2 library.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -27,13 +27,15 @@
   /* <Description>                                                         */
   /*    This macro is used in association with @FT_END_HEADER in header    */
   /*    files to ensure that the declarations within are properly          */
-  /*    encapsulated in an `extern "C" { .. }' block when included from a  */
+  /*    encapsulated in an `extern "C" { .. }` block when included from a  */
   /*    C++ compiler.                                                      */
   /*                                                                       */
-#ifdef __cplusplus
-#define FT_BEGIN_HEADER  extern "C" {
-#else
-#define FT_BEGIN_HEADER  /* nothing */
+#ifndef FT_BEGIN_HEADER
+#  ifdef __cplusplus
+#    define FT_BEGIN_HEADER  extern "C" {
+#  else
+#  define FT_BEGIN_HEADER  /* nothing */
+#  endif
 #endif
 
 
@@ -45,13 +47,15 @@
   /* <Description>                                                         */
   /*    This macro is used in association with @FT_BEGIN_HEADER in header  */
   /*    files to ensure that the declarations within are properly          */
-  /*    encapsulated in an `extern "C" { .. }' block when included from a  */
+  /*    encapsulated in an `extern "C" { .. }` block when included from a  */
   /*    C++ compiler.                                                      */
   /*                                                                       */
-#ifdef __cplusplus
-#define FT_END_HEADER  }
-#else
-#define FT_END_HEADER  /* nothing */
+#ifndef FT_END_HEADER
+#  ifdef __cplusplus
+#    define FT_END_HEADER  }
+#  else
+#   define FT_END_HEADER  /* nothing */
+#  endif
 #endif
 
 
@@ -70,39 +74,42 @@
    *   Header File Macros
    *
    * @abstract:
-   *   Macro definitions used to #include specific header files.
+   *   Macro definitions used to `#include` specific header files.
    *
    * @description:
-   *   The following macros are defined to the name of specific
-   *   FreeType~2 header files.  They can be used directly in #include
-   *   statements as in:
+   *   In addition to the normal scheme of including header files like
    *
-   *   {
+   *   ```
+   *     #include <freetype/freetype.h>
+   *     #include <freetype/ftmm.h>
+   *     #include <freetype/ftglyph.h>
+   *   ```
+   *
+   *   it is possible to used named macros instead.  They can be used
+   *   directly in `#include` statements as in
+   *
+   *   ```
    *     #include FT_FREETYPE_H
    *     #include FT_MULTIPLE_MASTERS_H
    *     #include FT_GLYPH_H
-   *   }
+   *   ```
    *
-   *   There are several reasons why we are now using macros to name
-   *   public header files.  The first one is that such macros are not
-   *   limited to the infamous 8.3~naming rule required by DOS (and
-   *   `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h').
-   *
-   *   The second reason is that it allows for more flexibility in the
-   *   way FreeType~2 is installed on a given system.
+   *   These macros were introduced to overcome the infamous 8.3~naming rule
+   *   required by DOS (and `FT_MULTIPLE_MASTERS_H` is a lot more meaningful
+   *   than `ftmm.h`).
    *
    */
 
 
   /* configuration files */
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CONFIG_CONFIG_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   FreeType~2 configuration data.
    *
    */
@@ -111,13 +118,13 @@
 #endif
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CONFIG_STANDARD_LIBRARY_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   FreeType~2 interface to the standard C library functions.
    *
    */
@@ -126,13 +133,13 @@
 #endif
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CONFIG_OPTIONS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   FreeType~2 project-specific configuration options.
    *
    */
@@ -141,13 +148,13 @@
 #endif
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CONFIG_MODULES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   list of FreeType~2 modules that are statically linked to new library
    *   instances in @FT_Init_FreeType.
    *
@@ -160,26 +167,26 @@
 
   /* public headers */
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_FREETYPE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   base FreeType~2 API.
    *
    */
 #define FT_FREETYPE_H  <freetype/freetype.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_ERRORS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   list of FreeType~2 error codes (and messages).
    *
    *   It is included by @FT_FREETYPE_H.
@@ -188,26 +195,26 @@
 #define FT_ERRORS_H  <freetype/fterrors.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_MODULE_ERRORS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   list of FreeType~2 module error offsets (and messages).
    *
    */
 #define FT_MODULE_ERRORS_H  <freetype/ftmoderr.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_SYSTEM_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 interface to low-level operations (i.e., memory management
    *   and stream i/o).
    *
@@ -217,13 +224,13 @@
 #define FT_SYSTEM_H  <freetype/ftsystem.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IMAGE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing type
+   *   A macro used in `#include` statements to name the file containing type
    *   definitions related to glyph images (i.e., bitmaps, outlines,
    *   scan-converter parameters).
    *
@@ -233,13 +240,13 @@
 #define FT_IMAGE_H  <freetype/ftimage.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TYPES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   basic data types defined by FreeType~2.
    *
    *   It is included by @FT_FREETYPE_H.
@@ -248,13 +255,13 @@
 #define FT_TYPES_H  <freetype/fttypes.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_LIST_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   list management API of FreeType~2.
    *
    *   (Most applications will never need to include this file.)
@@ -263,151 +270,151 @@
 #define FT_LIST_H  <freetype/ftlist.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_OUTLINE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   scalable outline management API of FreeType~2.
    *
    */
 #define FT_OUTLINE_H  <freetype/ftoutln.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_SIZES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   API which manages multiple @FT_Size objects per face.
    *
    */
 #define FT_SIZES_H  <freetype/ftsizes.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_MODULE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   module management API of FreeType~2.
    *
    */
 #define FT_MODULE_H  <freetype/ftmodapi.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_RENDER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   renderer module management API of FreeType~2.
    *
    */
 #define FT_RENDER_H  <freetype/ftrender.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_DRIVER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   structures and macros related to the driver modules.
    *
    */
 #define FT_DRIVER_H  <freetype/ftdriver.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_AUTOHINTER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   structures and macros related to the auto-hinting module.
    *
-   *   Deprecated since version 2.9; use @FT_DRIVER_H instead.
+   *   Deprecated since version~2.9; use @FT_DRIVER_H instead.
    *
    */
 #define FT_AUTOHINTER_H  FT_DRIVER_H
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CFF_DRIVER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   structures and macros related to the CFF driver module.
    *
-   *   Deprecated since version 2.9; use @FT_DRIVER_H instead.
+   *   Deprecated since version~2.9; use @FT_DRIVER_H instead.
    *
    */
 #define FT_CFF_DRIVER_H  FT_DRIVER_H
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TRUETYPE_DRIVER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   structures and macros related to the TrueType driver module.
    *
-   *   Deprecated since version 2.9; use @FT_DRIVER_H instead.
+   *   Deprecated since version~2.9; use @FT_DRIVER_H instead.
    *
    */
 #define FT_TRUETYPE_DRIVER_H  FT_DRIVER_H
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_PCF_DRIVER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing
+   *   A macro used in `#include` statements to name the file containing
    *   structures and macros related to the PCF driver module.
    *
-   *   Deprecated since version 2.9; use @FT_DRIVER_H instead.
+   *   Deprecated since version~2.9; use @FT_DRIVER_H instead.
    *
    */
 #define FT_PCF_DRIVER_H  FT_DRIVER_H
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TYPE1_TABLES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   types and API specific to the Type~1 format.
    *
    */
 #define FT_TYPE1_TABLES_H  <freetype/t1tables.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TRUETYPE_IDS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   enumeration values which identify name strings, languages, encodings,
    *   etc.  This file really contains a _large_ set of constant macro
    *   definitions, taken from the TrueType and OpenType specifications.
@@ -416,174 +423,172 @@
 #define FT_TRUETYPE_IDS_H  <freetype/ttnameid.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TRUETYPE_TABLES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   types and API specific to the TrueType (as well as OpenType) format.
    *
    */
 #define FT_TRUETYPE_TABLES_H  <freetype/tttables.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TRUETYPE_TAGS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   definitions of TrueType four-byte `tags' which identify blocks in
+   *   A macro used in `#include` statements to name the file containing the
+   *   definitions of TrueType four-byte 'tags' which identify blocks in
    *   SFNT-based font formats (i.e., TrueType and OpenType).
    *
    */
 #define FT_TRUETYPE_TAGS_H  <freetype/tttags.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_BDF_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   definitions of an API which accesses BDF-specific strings from a
-   *   face.
+   *   A macro used in `#include` statements to name the file containing the
+   *   definitions of an API which accesses BDF-specific strings from a face.
    *
    */
 #define FT_BDF_H  <freetype/ftbdf.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CID_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   definitions of an API which access CID font information from a
-   *   face.
+   *   A macro used in `#include` statements to name the file containing the
+   *   definitions of an API which access CID font information from a face.
    *
    */
 #define FT_CID_H  <freetype/ftcid.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_GZIP_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   definitions of an API which supports gzip-compressed files.
    *
    */
 #define FT_GZIP_H  <freetype/ftgzip.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_LZW_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   definitions of an API which supports LZW-compressed files.
    *
    */
 #define FT_LZW_H  <freetype/ftlzw.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_BZIP2_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   definitions of an API which supports bzip2-compressed files.
    *
    */
 #define FT_BZIP2_H  <freetype/ftbzip2.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_WINFONTS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   definitions of an API which supports Windows FNT files.
    *
    */
 #define FT_WINFONTS_H   <freetype/ftwinfnt.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_GLYPH_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   API of the optional glyph management component.
    *
    */
 #define FT_GLYPH_H  <freetype/ftglyph.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_BITMAP_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   API of the optional bitmap conversion component.
    *
    */
 #define FT_BITMAP_H  <freetype/ftbitmap.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_BBOX_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   API of the optional exact bounding box computation routines.
    *
    */
 #define FT_BBOX_H  <freetype/ftbbox.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_CACHE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   API of the optional FreeType~2 cache sub-system.
    *
    */
 #define FT_CACHE_H  <freetype/ftcache.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_MAC_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   Macintosh-specific FreeType~2 API.  The latter is used to access
-   *   fonts embedded in resource forks.
+   *   A macro used in `#include` statements to name the file containing the
+   *   Macintosh-specific FreeType~2 API.  The latter is used to access fonts
+   *   embedded in resource forks.
    *
    *   This header file must be explicitly included by client applications
    *   compiled on the Mac (note that the base API still works though).
@@ -592,105 +597,105 @@
 #define FT_MAC_H  <freetype/ftmac.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_MULTIPLE_MASTERS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   optional multiple-masters management API of FreeType~2.
    *
    */
 #define FT_MULTIPLE_MASTERS_H  <freetype/ftmm.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_SFNT_NAMES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   optional FreeType~2 API which accesses embedded `name' strings in
+   *   A macro used in `#include` statements to name the file containing the
+   *   optional FreeType~2 API which accesses embedded 'name' strings in
    *   SFNT-based font formats (i.e., TrueType and OpenType).
    *
    */
 #define FT_SFNT_NAMES_H  <freetype/ftsnames.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_OPENTYPE_VALIDATE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   optional FreeType~2 API which validates OpenType tables (BASE, GDEF,
-   *   GPOS, GSUB, JSTF).
+   *   A macro used in `#include` statements to name the file containing the
+   *   optional FreeType~2 API which validates OpenType tables ('BASE',
+   *   'GDEF', 'GPOS', 'GSUB', 'JSTF').
    *
    */
 #define FT_OPENTYPE_VALIDATE_H  <freetype/ftotval.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_GX_VALIDATE_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat,
-   *   mort, morx, bsln, just, kern, opbd, trak, prop).
+   *   A macro used in `#include` statements to name the file containing the
+   *   optional FreeType~2 API which validates TrueTypeGX/AAT tables ('feat',
+   *   'mort', 'morx', 'bsln', 'just', 'kern', 'opbd', 'trak', 'prop').
    *
    */
 #define FT_GX_VALIDATE_H  <freetype/ftgxval.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_PFR_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which accesses PFR-specific data.
    *
    */
 #define FT_PFR_H  <freetype/ftpfr.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_STROKER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which provides functions to stroke outline paths.
    */
 #define FT_STROKER_H  <freetype/ftstroke.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_SYNTHESIS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which performs artificial obliquing and emboldening.
    */
 #define FT_SYNTHESIS_H  <freetype/ftsynth.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_FONT_FORMATS_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which provides functions specific to font formats.
    */
 #define FT_FONT_FORMATS_H  <freetype/ftfntfmt.h>
@@ -699,79 +704,91 @@
 #define FT_XFREE86_H  FT_FONT_FORMATS_H
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_TRIGONOMETRY_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which performs trigonometric computations (e.g.,
    *   cosines and arc tangents).
    */
 #define FT_TRIGONOMETRY_H  <freetype/fttrigon.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_LCD_FILTER_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which performs color filtering for subpixel rendering.
    */
 #define FT_LCD_FILTER_H  <freetype/ftlcdfil.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_INCREMENTAL_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which performs incremental glyph loading.
    */
 #define FT_INCREMENTAL_H  <freetype/ftincrem.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_GASP_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which returns entries from the TrueType GASP table.
    */
 #define FT_GASP_H  <freetype/ftgasp.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_ADVANCES_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
+   *   A macro used in `#include` statements to name the file containing the
    *   FreeType~2 API which returns individual and ranged glyph advances.
    */
 #define FT_ADVANCES_H  <freetype/ftadvanc.h>
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_COLOR_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   FreeType~2 API which handles the OpenType CPAL table.
+   *   A macro used in `#include` statements to name the file containing the
+   *   FreeType~2 API which handles the OpenType 'CPAL' table.
    */
 #define FT_COLOR_H  <freetype/ftcolor.h>
 
 
+  /**************************************************************************
+   *
+   * @macro:
+   *   FT_OTSVG_H
+   *
+   * @description:
+   *   A macro used in `#include` statements to name the file containing the
+   *   FreeType~2 API which handles the OpenType 'SVG~' glyphs.
+   */
+#define FT_OTSVG_H  <freetype/otsvg.h>
+
+
   /* */
 
   /* These header files don't need to be included by the user. */
@@ -782,14 +799,14 @@
 #define FT_UNPATENTED_HINTING_H   <freetype/ftparams.h>
 #define FT_TRUETYPE_UNPATENTED_H  <freetype/ftparams.h>
 
-  /* FT_CACHE_H is the only header file needed for the cache subsystem. */
+  /* `FT_CACHE_H` is the only header file needed for the cache subsystem. */
 #define FT_CACHE_IMAGE_H          FT_CACHE_H
 #define FT_CACHE_SMALL_BITMAPS_H  FT_CACHE_H
 #define FT_CACHE_CHARMAP_H        FT_CACHE_H
 
   /* The internals of the cache sub-system are no longer exposed.  We */
-  /* default to FT_CACHE_H at the moment just in case, but we know of */
-  /* no rogue client that uses them.                                  */
+  /* default to `FT_CACHE_H` at the moment just in case, but we know  */
+  /* of no rogue client that uses them.                               */
   /*                                                                  */
 #define FT_CACHE_MANAGER_H           FT_CACHE_H
 #define FT_CACHE_INTERNAL_MRU_H      FT_CACHE_H
@@ -799,16 +816,19 @@
 #define FT_CACHE_INTERNAL_IMAGE_H    FT_CACHE_H
 #define FT_CACHE_INTERNAL_SBITS_H    FT_CACHE_H
 
-
-  /*
-   * Include internal headers definitions from <internal/...>
-   * only when building the library.
-   */
+/* TODO(david): Move this section below to a different header */
 #ifdef FT2_BUILD_LIBRARY
-#define  FT_INTERNAL_INTERNAL_H  <freetype/internal/internal.h>
-#include FT_INTERNAL_INTERNAL_H
-#endif /* FT2_BUILD_LIBRARY */
+#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
 
+  /* We disable the warning `conditional expression is constant' here */
+  /* in order to compile cleanly with the maximum level of warnings.  */
+  /* In particular, the warning complains about stuff like `while(0)' */
+  /* which is very useful in macro definitions.  There is no benefit  */
+  /* in having it enabled.                                            */
+#pragma warning( disable : 4127 )
+
+#endif /* _MSC_VER */
+#endif /* FT2_BUILD_LIBRARY */
 
 #endif /* FTHEADER_H_ */
 
diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h
index e751509..4afb148 100644
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -2,10 +2,10 @@
  * This file registers the FreeType modules compiled into the library.
  *
  * If you use GNU make, this file IS NOT USED!  Instead, it is created in
- * the objects directory (normally `<topdir>/objs/') based on information
- * from `<topdir>/modules.cfg'.
+ * the objects directory (normally `<topdir>/objs/`) based on information
+ * from `<topdir>/modules.cfg`.
  *
- * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile
+ * Please read `docs/INSTALL.ANY` and `docs/CUSTOMIZE` how to compile
  * FreeType without GNU make.
  *
  */
@@ -19,14 +19,15 @@
 //FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
 //FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
 //FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
+//FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
 FT_USE_MODULE( FT_Module_Class, psaux_module_class )
 FT_USE_MODULE( FT_Module_Class, psnames_module_class )
 FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
 FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
-//FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class )
 
 /* EOF */
diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
index b2e6685..9a12bab 100644
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -4,7 +4,7 @@
  *
  *   User-selectable configuration macros (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -29,39 +29,39 @@
    *
    *                USER-SELECTABLE CONFIGURATION MACROS
    *
-   * This file contains the default configuration macro definitions for
-   * a standard build of the FreeType library.  There are three ways to
-   * use this file to build project-specific versions of the library:
+   * This file contains the default configuration macro definitions for a
+   * standard build of the FreeType library.  There are three ways to use
+   * this file to build project-specific versions of the library:
    *
    * - You can modify this file by hand, but this is not recommended in
-   *   cases where you would like to build several versions of the
-   *   library from a single source directory.
+   *   cases where you would like to build several versions of the library
+   *   from a single source directory.
    *
    * - You can put a copy of this file in your build directory, more
-   *   precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'
-   *   is the name of a directory that is included _before_ the FreeType
-   *   include path during compilation.
+   *   precisely in `$BUILD/freetype/config/ftoption.h`, where `$BUILD` is
+   *   the name of a directory that is included _before_ the FreeType include
+   *   path during compilation.
    *
-   *   The default FreeType Makefiles and Jamfiles use the build
-   *   directory `builds/<system>' by default, but you can easily change
-   *   that for your own projects.
+   *   The default FreeType Makefiles use the build directory
+   *   `builds/<system>` by default, but you can easily change that for your
+   *   own projects.
    *
-   * - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it
-   *   slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to
-   *   locate this file during the build.  For example,
+   * - Copy the file <ft2build.h> to `$BUILD/ft2build.h` and modify it
+   *   slightly to pre-define the macro `FT_CONFIG_OPTIONS_H` used to locate
+   *   this file during the build.  For example,
    *
-   *   {
+   *   ```
    *     #define FT_CONFIG_OPTIONS_H  <myftoptions.h>
    *     #include <freetype/config/ftheader.h>
-   *   }
+   *   ```
    *
-   *   will use `$BUILD/myftoptions.h' instead of this file for macro
+   *   will use `$BUILD/myftoptions.h` instead of this file for macro
    *   definitions.
    *
    *   Note also that you can similarly pre-define the macro
-   *   FT_CONFIG_MODULES_H used to locate the file listing of the modules
+   *   `FT_CONFIG_MODULES_H` used to locate the file listing of the modules
    *   that are statically linked to the library at compile time.  By
-   *   default, this file is <freetype/config/ftmodule.h>.
+   *   default, this file is `<freetype/config/ftmodule.h>`.
    *
    * We highly recommend using the third method whenever possible.
    *
@@ -80,18 +80,18 @@
   /*#************************************************************************
    *
    * If you enable this configuration option, FreeType recognizes an
-   * environment variable called `FREETYPE_PROPERTIES', which can be used to
+   * environment variable called `FREETYPE_PROPERTIES`, which can be used to
    * control the various font drivers and modules.  The controllable
    * properties are listed in the section @properties.
    *
    * You have to undefine this configuration option on platforms that lack
-   * the concept of environment variables (and thus don't have the `getenv'
+   * the concept of environment variables (and thus don't have the `getenv`
    * function), for example Windows CE.
    *
-   * `FREETYPE_PROPERTIES' has the following syntax form (broken here into
+   * `FREETYPE_PROPERTIES` has the following syntax form (broken here into
    * multiple lines for better readability).
    *
-   * {
+   * ```
    *   <optional whitespace>
    *   <module-name1> ':'
    *   <property-name1> '=' <property-value1>
@@ -99,15 +99,14 @@
    *   <module-name2> ':'
    *   <property-name2> '=' <property-value2>
    *   ...
-   * }
+   * ```
    *
    * Example:
    *
-   * {
+   * ```
    *   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
-   *                       cff:no-stem-darkening=1 \
-   *                       autofitter:warping=1
-   * }
+   *                       cff:no-stem-darkening=1
+   * ```
    *
    */
 /* ANDROID: disabled */
@@ -118,35 +117,32 @@
    *
    * Uncomment the line below if you want to activate LCD rendering
    * technology similar to ClearType in this build of the library.  This
-   * technology triples the resolution in the direction color subpixels.
-   * To mitigate color fringes inherent to this technology, you also need
-   * to explicitly set up LCD filtering.
+   * technology triples the resolution in the direction color subpixels.  To
+   * mitigate color fringes inherent to this technology, you also need to
+   * explicitly set up LCD filtering.
    *
-   * Note that this feature is covered by several Microsoft patents
-   * and should not be activated in any default build of the library.
    * When this macro is not defined, FreeType offers alternative LCD
-   * rendering technology that produces excellent output without LCD
-   * filtering.
+   * rendering technology that produces excellent output.
    */
 /* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
 
 
   /**************************************************************************
    *
-   * Many compilers provide a non-ANSI 64-bit data type that can be used
-   * by FreeType to speed up some computations.  However, this will create
-   * some problems when compiling the library in strict ANSI mode.
+   * Many compilers provide a non-ANSI 64-bit data type that can be used by
+   * FreeType to speed up some computations.  However, this will create some
+   * problems when compiling the library in strict ANSI mode.
    *
    * For this reason, the use of 64-bit integers is normally disabled when
-   * the __STDC__ macro is defined.  You can however disable this by
-   * defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.
+   * the `__STDC__` macro is defined.  You can however disable this by
+   * defining the macro `FT_CONFIG_OPTION_FORCE_INT64` here.
    *
    * For most compilers, this will only create compilation warnings when
    * building the library.
    *
    * ObNote: The compiler-specific 64-bit integers are detected in the
-   *         file `ftconfig.h' either statically or through the
-   *         `configure' script on supported platforms.
+   *         file `ftconfig.h` either statically or through the `configure`
+   *         script on supported platforms.
    */
 #undef FT_CONFIG_OPTION_FORCE_INT64
 
@@ -154,21 +150,21 @@
   /**************************************************************************
    *
    * If this macro is defined, do not try to use an assembler version of
-   * performance-critical functions (e.g. FT_MulFix).  You should only do
-   * that to verify that the assembler function works properly, or to
-   * execute benchmark tests of the various implementations.
+   * performance-critical functions (e.g., @FT_MulFix).  You should only do
+   * that to verify that the assembler function works properly, or to execute
+   * benchmark tests of the various implementations.
    */
 /* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
 
 
   /**************************************************************************
    *
-   * If this macro is defined, try to use an inlined assembler version of
-   * the `FT_MulFix' function, which is a `hotspot' when loading and
-   * hinting glyphs, and which should be executed as fast as possible.
+   * If this macro is defined, try to use an inlined assembler version of the
+   * @FT_MulFix function, which is a 'hotspot' when loading and hinting
+   * glyphs, and which should be executed as fast as possible.
    *
-   * Note that if your compiler or CPU is not supported, this will default
-   * to the standard and portable implementation found in `ftcalc.c'.
+   * Note that if your compiler or CPU is not supported, this will default to
+   * the standard and portable implementation found in `ftcalc.c`.
    */
 #define FT_CONFIG_OPTION_INLINE_MULFIX
 
@@ -178,12 +174,12 @@
    * LZW-compressed file support.
    *
    *   FreeType now handles font files that have been compressed with the
-   *   `compress' program.  This is mostly used to parse many of the PCF
+   *   `compress` program.  This is mostly used to parse many of the PCF
    *   files that come with various X11 distributions.  The implementation
-   *   uses NetBSD's `zopen' to partially uncompress the file on the fly
-   *   (see src/lzw/ftgzip.c).
+   *   uses NetBSD's `zopen` to partially uncompress the file on the fly (see
+   *   `src/lzw/ftgzip.c`).
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    */
 #define FT_CONFIG_OPTION_USE_LZW
 
@@ -193,37 +189,41 @@
    * Gzip-compressed file support.
    *
    *   FreeType now handles font files that have been compressed with the
-   *   `gzip' program.  This is mostly used to parse many of the PCF files
-   *   that come with XFree86.  The implementation uses `zlib' to
-   *   partially uncompress the file on the fly (see src/gzip/ftgzip.c).
+   *   `gzip` program.  This is mostly used to parse many of the PCF files
+   *   that come with XFree86.  The implementation uses 'zlib' to partially
+   *   uncompress the file on the fly (see `src/gzip/ftgzip.c`).
    *
-   *   Define this macro if you want to enable this `feature'.  See also
-   *   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.
+   *   Define this macro if you want to enable this 'feature'.  See also the
+   *   macro `FT_CONFIG_OPTION_SYSTEM_ZLIB` below.
    */
-#define FT_CONFIG_OPTION_USE_ZLIB
+/* #define FT_CONFIG_OPTION_USE_ZLIB */
 
 
   /**************************************************************************
    *
    * ZLib library selection
    *
-   *   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.
-   *   It allows FreeType's `ftgzip' component to link to the system's
+   *   This macro is only used when `FT_CONFIG_OPTION_USE_ZLIB` is defined.
+   *   It allows FreeType's 'ftgzip' component to link to the system's
    *   installation of the ZLib library.  This is useful on systems like
    *   Unix or VMS where it generally is already available.
    *
-   *   If you let it undefined, the component will use its own copy
-   *   of the zlib sources instead.  These have been modified to be
-   *   included directly within the component and *not* export external
-   *   function names.  This allows you to link any program with FreeType
-   *   _and_ ZLib without linking conflicts.
+   *   If you let it undefined, the component will use its own copy of the
+   *   zlib sources instead.  These have been modified to be included
+   *   directly within the component and **not** export external function
+   *   names.  This allows you to link any program with FreeType _and_ ZLib
+   *   without linking conflicts.
    *
-   *   Do not #undef this macro here since the build system might define
+   *   Do not `#undef` this macro here since the build system might define
    *   it for certain configurations only.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
+   *
+   *   If you use the GNU make build system directly (that is, without the
+   *   `configure` script) and you define this macro, you also have to pass
+   *   `SYSTEM_ZLIB=yes` as an argument to make.
    */
 /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
 
@@ -233,28 +233,28 @@
    * Bzip2-compressed file support.
    *
    *   FreeType now handles font files that have been compressed with the
-   *   `bzip2' program.  This is mostly used to parse many of the PCF
-   *   files that come with XFree86.  The implementation uses `libbz2' to
-   *   partially uncompress the file on the fly (see src/bzip2/ftbzip2.c).
-   *   Contrary to gzip, bzip2 currently is not included and need to use
-   *   the system available bzip2 implementation.
+   *   `bzip2` program.  This is mostly used to parse many of the PCF files
+   *   that come with XFree86.  The implementation uses `libbz2` to partially
+   *   uncompress the file on the fly (see `src/bzip2/ftbzip2.c`).  Contrary
+   *   to gzip, bzip2 currently is not included and need to use the system
+   *   available bzip2 implementation.
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
    */
 /* #define FT_CONFIG_OPTION_USE_BZIP2 */
 
 
   /**************************************************************************
    *
-   * Define to disable the use of file stream functions and types, FILE,
-   * fopen() etc.  Enables the use of smaller system libraries on embedded
-   * systems that have multiple system libraries, some with or without
-   * file stream support, in the cases where file stream support is not
-   * necessary such as memory loading of font files.
+   * Define to disable the use of file stream functions and types, `FILE`,
+   * `fopen`, etc.  Enables the use of smaller system libraries on embedded
+   * systems that have multiple system libraries, some with or without file
+   * stream support, in the cases where file stream support is not necessary
+   * such as memory loading of font files.
    */
 /* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
 
@@ -265,57 +265,73 @@
    *
    *   FreeType now handles loading color bitmap glyphs in the PNG format.
    *   This requires help from the external libpng library.  Uncompressed
-   *   color bitmaps do not need any external libraries and will be
-   *   supported regardless of this configuration.
+   *   color bitmaps do not need any external libraries and will be supported
+   *   regardless of this configuration.
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
    */
   /* ANDROID: enabled */
-#define FT_CONFIG_OPTION_USE_PNG
+/* #define FT_CONFIG_OPTION_USE_PNG */
 
 
   /**************************************************************************
    *
    * HarfBuzz support.
    *
-   *   FreeType uses the HarfBuzz library to improve auto-hinting of
-   *   OpenType fonts.  If available, many glyphs not directly addressable
-   *   by a font's character map will be hinted also.
+   *   FreeType uses the HarfBuzz library to improve auto-hinting of OpenType
+   *   fonts.  If available, many glyphs not directly addressable by a font's
+   *   character map will be hinted also.
    *
-   *   Define this macro if you want to enable this `feature'.
+   *   Define this macro if you want to enable this 'feature'.
    *
-   *   If you use a build system like cmake or the `configure' script,
-   *   options set by those programs have precendence, overwriting the
-   *   value here with the configured one.
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
    */
 /* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
 
 
   /**************************************************************************
    *
+   * Brotli support.
+   *
+   *   FreeType uses the Brotli library to provide support for decompressing
+   *   WOFF2 streams.
+   *
+   *   Define this macro if you want to enable this 'feature'.
+   *
+   *   If you use a build system like cmake or the `configure` script,
+   *   options set by those programs have precedence, overwriting the value
+   *   here with the configured one.
+   */
+/* #define FT_CONFIG_OPTION_USE_BROTLI */
+
+
+  /**************************************************************************
+   *
    * Glyph Postscript Names handling
    *
-   *   By default, FreeType 2 is compiled with the `psnames' module.  This
-   *   module is in charge of converting a glyph name string into a
-   *   Unicode value, or return a Macintosh standard glyph name for the
-   *   use with the TrueType `post' table.
+   *   By default, FreeType 2 is compiled with the 'psnames' module.  This
+   *   module is in charge of converting a glyph name string into a Unicode
+   *   value, or return a Macintosh standard glyph name for the use with the
+   *   TrueType 'post' table.
    *
-   *   Undefine this macro if you do not want `psnames' compiled in your
+   *   Undefine this macro if you do not want 'psnames' compiled in your
    *   build of FreeType.  This has the following effects:
    *
-   *   - The TrueType driver will provide its own set of glyph names,
-   *     if you build it to support postscript names in the TrueType
-   *     `post' table, but will not synthesize a missing Unicode charmap.
+   *   - The TrueType driver will provide its own set of glyph names, if you
+   *     build it to support postscript names in the TrueType 'post' table,
+   *     but will not synthesize a missing Unicode charmap.
    *
-   *   - The Type 1 driver will not be able to synthesize a Unicode
-   *     charmap out of the glyphs found in the fonts.
+   *   - The Type~1 driver will not be able to synthesize a Unicode charmap
+   *     out of the glyphs found in the fonts.
    *
-   *   You would normally undefine this configuration macro when building
-   *   a version of FreeType that doesn't contain a Type 1 or CFF driver.
+   *   You would normally undefine this configuration macro when building a
+   *   version of FreeType that doesn't contain a Type~1 or CFF driver.
    */
 #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
@@ -324,16 +340,15 @@
    *
    * Postscript Names to Unicode Values support
    *
-   *   By default, FreeType 2 is built with the `PSNames' module compiled
-   *   in.  Among other things, the module is used to convert a glyph name
-   *   into a Unicode value.  This is especially useful in order to
-   *   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver
-   *   through a big table named the `Adobe Glyph List' (AGL).
+   *   By default, FreeType~2 is built with the 'psnames' module compiled in.
+   *   Among other things, the module is used to convert a glyph name into a
+   *   Unicode value.  This is especially useful in order to synthesize on
+   *   the fly a Unicode charmap from the CFF/Type~1 driver through a big
+   *   table named the 'Adobe Glyph List' (AGL).
    *
-   *   Undefine this macro if you do not want the Adobe Glyph List
-   *   compiled in your `PSNames' module.  The Type 1 driver will not be
-   *   able to synthesize a Unicode charmap out of the glyphs found in the
-   *   fonts.
+   *   Undefine this macro if you do not want the Adobe Glyph List compiled
+   *   in your 'psnames' module.  The Type~1 driver will not be able to
+   *   synthesize a Unicode charmap out of the glyphs found in the fonts.
    */
 #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
 
@@ -342,11 +357,11 @@
    *
    * Support for Mac fonts
    *
-   *   Define this macro if you want support for outline fonts in Mac
-   *   format (mac dfont, mac resource, macbinary containing a mac
-   *   resource) on non-Mac platforms.
+   *   Define this macro if you want support for outline fonts in Mac format
+   *   (mac dfont, mac resource, macbinary containing a mac resource) on
+   *   non-Mac platforms.
    *
-   *   Note that the `FOND' resource isn't checked.
+   *   Note that the 'FOND' resource isn't checked.
    */
 #define FT_CONFIG_OPTION_MAC_FONTS
 
@@ -360,13 +375,12 @@
    *   Resource forks which include fonts data are stored sometimes in
    *   locations which users or developers don't expected.  In some cases,
    *   resource forks start with some offset from the head of a file.  In
-   *   other cases, the actual resource fork is stored in file different
-   *   from what the user specifies.  If this option is activated,
-   *   FreeType tries to guess whether such offsets or different file
-   *   names must be used.
+   *   other cases, the actual resource fork is stored in file different from
+   *   what the user specifies.  If this option is activated, FreeType tries
+   *   to guess whether such offsets or different file names must be used.
    *
    *   Note that normal, direct access of resource forks is controlled via
-   *   the FT_CONFIG_OPTION_MAC_FONTS option.
+   *   the `FT_CONFIG_OPTION_MAC_FONTS` option.
    */
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
 #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
@@ -375,11 +389,11 @@
 
   /**************************************************************************
    *
-   * Allow the use of FT_Incremental_Interface to load typefaces that
-   * contain no glyph data, but supply it via a callback function.
-   * This is required by clients supporting document formats which
-   * supply font data incrementally as the document is parsed, such
-   * as the Ghostscript interpreter for the PostScript language.
+   * Allow the use of `FT_Incremental_Interface` to load typefaces that
+   * contain no glyph data, but supply it via a callback function.  This is
+   * required by clients supporting document formats which supply font data
+   * incrementally as the document is parsed, such as the Ghostscript
+   * interpreter for the PostScript language.
    */
 /* ANDROID: disabled */
 /* #define FT_CONFIG_OPTION_INCREMENTAL                                  */
@@ -387,8 +401,8 @@
 
   /**************************************************************************
    *
-   * The size in bytes of the render pool used by the scan-line converter
-   * to do all of its work.
+   * The size in bytes of the render pool used by the scan-line converter to
+   * do all of its work.
    */
 #define FT_RENDER_POOL_SIZE  16384L
 
@@ -398,7 +412,7 @@
    * FT_MAX_MODULES
    *
    *   The maximum number of modules that can be registered in a single
-   *   FreeType library object.  32 is the default.
+   *   FreeType library object.  32~is the default.
    */
 #define FT_MAX_MODULES  32
 
@@ -408,16 +422,15 @@
    * Debug level
    *
    *   FreeType can be compiled in debug or trace mode.  In debug mode,
-   *   errors are reported through the `ftdebug' component.  In trace
-   *   mode, additional messages are sent to the standard output during
-   *   execution.
+   *   errors are reported through the 'ftdebug' component.  In trace mode,
+   *   additional messages are sent to the standard output during execution.
    *
-   *   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.
-   *   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.
+   *   Define `FT_DEBUG_LEVEL_ERROR` to build the library in debug mode.
+   *   Define `FT_DEBUG_LEVEL_TRACE` to build it in trace mode.
    *
-   *   Don't define any of these macros to compile in `release' mode!
+   *   Don't define any of these macros to compile in 'release' mode!
    *
-   *   Do not #undef these macros here since the build system might define
+   *   Do not `#undef` these macros here since the build system might define
    *   them for certain configurations only.
    */
 /* #define FT_DEBUG_LEVEL_ERROR */
@@ -426,40 +439,57 @@
 
   /**************************************************************************
    *
+   * Logging
+   *
+   *   Compiling FreeType in debug or trace mode makes FreeType write error
+   *   and trace log messages to `stderr`.  Enabling this macro
+   *   automatically forces the `FT_DEBUG_LEVEL_ERROR` and
+   *   `FT_DEBUG_LEVEL_TRACE` macros and allows FreeType to write error and
+   *   trace log messages to a file instead of `stderr`.  For writing logs
+   *   to a file, FreeType uses an the external `dlg` library (the source
+   *   code is in `src/dlg`).
+   *
+   *   This option needs a C99 compiler.
+   */
+/* #define FT_DEBUG_LOGGING */
+
+
+  /**************************************************************************
+   *
    * Autofitter debugging
    *
-   *   If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to
+   *   If `FT_DEBUG_AUTOFIT` is defined, FreeType provides some means to
    *   control the autofitter behaviour for debugging purposes with global
-   *   boolean variables (consequently, you should *never* enable this
-   *   while compiling in `release' mode):
+   *   boolean variables (consequently, you should **never** enable this
+   *   while compiling in 'release' mode):
    *
-   *   {
-   *     _af_debug_disable_horz_hints
-   *     _af_debug_disable_vert_hints
-   *     _af_debug_disable_blue_hints
-   *   }
+   *   ```
+   *     af_debug_disable_horz_hints_
+   *     af_debug_disable_vert_hints_
+   *     af_debug_disable_blue_hints_
+   *   ```
    *
    *   Additionally, the following functions provide dumps of various
-   *   internal autofit structures to stdout (using `printf'):
+   *   internal autofit structures to stdout (using `printf`):
    *
-   *   {
+   *   ```
    *     af_glyph_hints_dump_points
    *     af_glyph_hints_dump_segments
    *     af_glyph_hints_dump_edges
    *     af_glyph_hints_get_num_segments
    *     af_glyph_hints_get_segment_offset
-   *   }
+   *   ```
    *
    *   As an argument, they use another global variable:
    *
-   *   {
-   *     _af_debug_hints
-   *   }
+   *   ```
+   *     af_debug_hints_
+   *   ```
    *
-   *   Please have a look at the `ftgrid' demo program to see how those
+   *   Please have a look at the `ftgrid` demo program to see how those
    *   variables and macros should be used.
    *
-   *   Do not #undef these macros here since the build system might define
+   *   Do not `#undef` these macros here since the build system might define
    *   them for certain configurations only.
    */
 /* #define FT_DEBUG_AUTOFIT */
@@ -469,16 +499,16 @@
    *
    * Memory Debugging
    *
-   *   FreeType now comes with an integrated memory debugger that is
-   *   capable of detecting simple errors like memory leaks or double
-   *   deletes.  To compile it within your build of the library, you
-   *   should define FT_DEBUG_MEMORY here.
+   *   FreeType now comes with an integrated memory debugger that is capable
+   *   of detecting simple errors like memory leaks or double deletes.  To
+   *   compile it within your build of the library, you should define
+   *   `FT_DEBUG_MEMORY` here.
    *
-   *   Note that the memory debugger is only activated at runtime when
-   *   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also!
+   *   Note that the memory debugger is only activated at runtime when when
+   *   the _environment_ variable `FT2_DEBUG_MEMORY` is defined also!
    *
-   *   Do not #undef this macro here since the build system might define
-   *   it for certain configurations only.
+   *   Do not `#undef` this macro here since the build system might define it
+   *   for certain configurations only.
    */
 /* #define FT_DEBUG_MEMORY */
 
@@ -487,19 +517,46 @@
    *
    * Module errors
    *
-   *   If this macro is set (which is _not_ the default), the higher byte
-   *   of an error code gives the module in which the error has occurred,
-   *   while the lower byte is the real error code.
+   *   If this macro is set (which is _not_ the default), the higher byte of
+   *   an error code gives the module in which the error has occurred, while
+   *   the lower byte is the real error code.
    *
-   *   Setting this macro makes sense for debugging purposes only, since
-   *   it would break source compatibility of certain programs that use
-   *   FreeType 2.
+   *   Setting this macro makes sense for debugging purposes only, since it
+   *   would break source compatibility of certain programs that use
+   *   FreeType~2.
    *
-   *   More details can be found in the files ftmoderr.h and fterrors.h.
+   *   More details can be found in the files `ftmoderr.h` and `fterrors.h`.
    */
 #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
 
 
+  /**************************************************************************
+   *
+   * OpenType SVG Glyph Support
+   *
+   *   Setting this macro enables support for OpenType SVG glyphs.  By
+   *   default, FreeType can only fetch SVG documents.  However, it can also
+   *   render them if external rendering hook functions are plugged in at
+   *   runtime.
+   *
+   *   More details on the hooks can be found in file `otsvg.h`.
+   */
+#define FT_CONFIG_OPTION_SVG
+
+
+  /**************************************************************************
+   *
+   * Error Strings
+   *
+   *   If this macro is set, `FT_Error_String` will return meaningful
+   *   descriptions.  This is not enabled by default to reduce the overall
+   *   size of FreeType.
+   *
+   *   More details can be found in the file `fterrors.h`.
+   */
+/* #define FT_CONFIG_OPTION_ERROR_STRINGS */
+
+
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
@@ -511,47 +568,47 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support
-   * embedded bitmaps in all formats using the SFNT module (namely
-   * TrueType & OpenType).
+   * Define `TT_CONFIG_OPTION_EMBEDDED_BITMAPS` if you want to support
+   * embedded bitmaps in all formats using the 'sfnt' module (namely
+   * TrueType~& OpenType).
    */
 #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_COLOR_LAYERS if you want to support coloured
-   * outlines (from the COLR/CPAL tables) in all formats using the SFNT
-   * module (namely TrueType & OpenType).
+   * Define `TT_CONFIG_OPTION_COLOR_LAYERS` if you want to support colored
+   * outlines (from the 'COLR'/'CPAL' tables) in all formats using the 'sfnt'
+   * module (namely TrueType~& OpenType).
    */
 #define TT_CONFIG_OPTION_COLOR_LAYERS
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to
-   * load and enumerate the glyph Postscript names in a TrueType or
-   * OpenType file.
+   * Define `TT_CONFIG_OPTION_POSTSCRIPT_NAMES` if you want to be able to
+   * load and enumerate Postscript names of glyphs in a TrueType or OpenType
+   * file.
    *
-   * Note that when you do not compile the `PSNames' module by undefining
-   * the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will
-   * contain additional code used to read the PS Names table from a font.
+   * Note that if you do not compile the 'psnames' module by undefining the
+   * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` macro, the 'sfnt' module will
+   * contain additional code to read the PostScript name table from a font.
    *
-   * (By default, the module uses `PSNames' to extract glyph names.)
+   * (By default, the module uses 'psnames' to extract glyph names.)
    */
 #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to
-   * access the internal name table in a SFNT-based format like TrueType
-   * or OpenType.  The name table contains various strings used to
-   * describe the font, like family name, copyright, version, etc.  It
-   * does not contain any glyph name though.
+   * Define `TT_CONFIG_OPTION_SFNT_NAMES` if your applications need to access
+   * the internal name table in a SFNT-based format like TrueType or
+   * OpenType.  The name table contains various strings used to describe the
+   * font, like family name, copyright, version, etc.  It does not contain
+   * any glyph name though.
    *
    * Accessing SFNT names is done through the functions declared in
-   * `ftsnames.h'.
+   * `ftsnames.h`.
    */
 #define TT_CONFIG_OPTION_SFNT_NAMES
 
@@ -584,54 +641,53 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile
-   * a bytecode interpreter in the TrueType driver.
+   * Define `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` if you want to compile a
+   * bytecode interpreter in the TrueType driver.
    *
    * By undefining this, you will only compile the code necessary to load
    * TrueType glyphs without hinting.
    *
-   *   Do not #undef this macro here, since the build system might
-   *   define it for certain configurations only.
+   * Do not `#undef` this macro here, since the build system might define it
+   * for certain configurations only.
    */
 #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile
+   * Define `TT_CONFIG_OPTION_SUBPIXEL_HINTING` if you want to compile
    * subpixel hinting support into the TrueType driver.  This modifies the
-   * TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is
+   * TrueType hinting mechanism when anything but `FT_RENDER_MODE_MONO` is
    * requested.
    *
    * In particular, it modifies the bytecode interpreter to interpret (or
-   * not) instructions in a certain way so that all TrueType fonts look
-   * like they do in a Windows ClearType (DirectWrite) environment.  See
-   * [1] for a technical overview on what this means.  See `ttinterp.h'
-   * for more details on the LEAN option.
+   * 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.
    *
    * 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.
+   *   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.
+   *   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.
    *
@@ -639,18 +695,18 @@
    *   Compile both, making both v38 and v40 available (the latter is the
    *   default).
    *
-   * By undefining these, you get rendering behavior like on Windows
-   * without ClearType, i.e., Windows XP without ClearType enabled and
-   * Win9x (interpreter version v35).  Or not, depending on how much
-   * hinting blood and testing tears the font designer put into a given
-   * font.  If you define one or both subpixel hinting options, you can
-   * switch between between v35 and the ones you define (using
-   * `FT_Property_Set').
+   * By undefining these, you get rendering behavior like on Windows without
+   * ClearType, i.e., Windows XP without ClearType enabled and Win9x
+   * (interpreter version v35).  Or not, depending on how much hinting blood
+   * and testing tears the font designer put into a given font.  If you
+   * define one or both subpixel hinting options, you can switch between
+   * between v35 and the ones you define (using `FT_Property_Set`).
    *
-   * This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be
+   * This option requires `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` to be
    * defined.
    *
-   * [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
+   * [1]
+   * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
    */
 /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1         */
 
@@ -662,16 +718,16 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the
+   * Define `TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED` to compile the
    * TrueType glyph loader to use Apple's definition of how to handle
    * component offsets in composite glyphs.
    *
-   * Apple and MS disagree on the default behavior of component offsets
-   * in composites.  Apple says that they should be scaled by the scaling
-   * factors in the transformation matrix (roughly, it's more complex)
-   * while MS says they should not.  OpenType defines two bits in the
-   * composite flags array which can be used to disambiguate, but old
-   * fonts will not have them.
+   * Apple and MS disagree on the default behavior of component offsets in
+   * composites.  Apple says that they should be scaled by the scaling
+   * factors in the transformation matrix (roughly, it's more complex) while
+   * MS says they should not.  OpenType defines two bits in the composite
+   * flags array which can be used to disambiguate, but old fonts will not
+   * have them.
    *
    *   https://www.microsoft.com/typography/otspec/glyf.htm
    *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html
@@ -681,34 +737,52 @@
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include
-   * support for Apple's distortable font technology (fvar, gvar, cvar,
-   * and avar tables).  This has many similarities to Type 1 Multiple
-   * Masters support.
+   * Define `TT_CONFIG_OPTION_GX_VAR_SUPPORT` if you want to include support
+   * for Apple's distortable font technology ('fvar', 'gvar', 'cvar', and
+   * 'avar' tables).  Tagged 'Font Variations', this is now part of OpenType
+   * also.  This has many similarities to Type~1 Multiple Masters support.
    */
 #define TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
 
   /**************************************************************************
    *
-   * Define TT_CONFIG_OPTION_BDF if you want to include support for
-   * an embedded `BDF ' table within SFNT-based bitmap formats.
+   * Define `TT_CONFIG_OPTION_NO_BORING_EXPANSION` if you want to exclude
+   * support for 'boring' OpenType specification expansions.
+   *
+   *   https://github.com/harfbuzz/boring-expansion-spec
+   *
+   * Right now, the following features are covered:
+   *
+   *   - 'avar' version 2.0
+   *
+   * Most likely, this is a temporary configuration option to be removed in
+   * the near future, since it is assumed that eventually those features are
+   * added to the OpenType standard.
+   */
+/* #define TT_CONFIG_OPTION_NO_BORING_EXPANSION */
+
+
+  /**************************************************************************
+   *
+   * Define `TT_CONFIG_OPTION_BDF` if you want to include support for an
+   * embedded 'BDF~' table within SFNT-based bitmap formats.
    */
 #define TT_CONFIG_OPTION_BDF
 
 
   /**************************************************************************
    *
-   * Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum
+   * Option `TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES` controls the maximum
    * number of bytecode instructions executed for a single run of the
-   * bytecode interpreter, needed to prevent infinite loops.  You don't
-   * want to change this except for very special situations (e.g., making
-   * a library fuzzer spend less time to handle broken fonts).
+   * bytecode interpreter, needed to prevent infinite loops.  You don't want
+   * to change this except for very special situations (e.g., making a
+   * library fuzzer spend less time to handle broken fonts).
    *
    * It is not expected that this value is ever modified by a configuring
-   * script; instead, it gets surrounded with #ifndef ... #endif so that
-   * the value can be set as a preprocessor option on the compiler's
-   * command line.
+   * script; instead, it gets surrounded with `#ifndef ... #endif` so that
+   * the value can be set as a preprocessor option on the compiler's command
+   * line.
    */
 #ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
 #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES  1000000L
@@ -726,16 +800,15 @@
 
   /**************************************************************************
    *
-   * T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and
-   * arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is
-   * required.
+   * `T1_MAX_DICT_DEPTH` is the maximum depth of nest dictionaries and arrays
+   * in the Type~1 stream (see `t1load.c`).  A minimum of~4 is required.
    */
 #define T1_MAX_DICT_DEPTH  5
 
 
   /**************************************************************************
    *
-   * T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine
+   * `T1_MAX_SUBRS_CALLS` details the maximum number of nested sub-routine
    * calls during glyph loading.
    */
 #define T1_MAX_SUBRS_CALLS  16
@@ -743,19 +816,20 @@
 
   /**************************************************************************
    *
-   * T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A
-   * minimum of 16 is required.
+   * `T1_MAX_CHARSTRING_OPERANDS` is the charstring stack's capacity.  A
+   * minimum of~16 is required.
    *
-   * The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256.
+   * The Chinese font 'MingTiEG-Medium' (covering the CNS 11643 character
+   * set) needs 256.
    */
 #define T1_MAX_CHARSTRINGS_OPERANDS  256
 
 
   /**************************************************************************
    *
-   * Define this configuration macro if you want to prevent the
-   * compilation of `t1afm', which is in charge of reading Type 1 AFM
-   * files into an existing face.  Note that if set, the T1 driver will be
+   * Define this configuration macro if you want to prevent the compilation
+   * of the 't1afm' module, which is in charge of reading Type~1 AFM files
+   * into an existing face.  Note that if set, the Type~1 driver will be
    * unable to produce kerning distances.
    */
 #undef T1_CONFIG_OPTION_NO_AFM
@@ -763,19 +837,18 @@
 
   /**************************************************************************
    *
-   * Define this configuration macro if you want to prevent the
-   * compilation of the Multiple Masters font support in the Type 1
-   * driver.
+   * Define this configuration macro if you want to prevent the compilation
+   * of the Multiple Masters font support in the Type~1 driver.
    */
 #undef T1_CONFIG_OPTION_NO_MM_SUPPORT
 
 
   /**************************************************************************
    *
-   * T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1
+   * `T1_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe Type~1
    * engine gets compiled into FreeType.  If defined, it is possible to
-   * switch between the two engines using the `hinting-engine' property of
-   * the type1 driver module.
+   * switch between the two engines using the `hinting-engine` property of
+   * the 'type1' driver module.
    */
 /* #define T1_CONFIG_OPTION_OLD_ENGINE */
 
@@ -791,14 +864,13 @@
 
   /**************************************************************************
    *
-   * Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is
+   * Using `CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4}` it is
    * possible to set up the default values of the four control points that
-   * define the stem darkening behaviour of the (new) CFF engine.  For
-   * more details please read the documentation of the
-   * `darkening-parameters' property (file `ftdriver.h'), which allows the
-   * control at run-time.
+   * define the stem darkening behaviour of the (new) CFF engine.  For more
+   * details please read the documentation of the `darkening-parameters`
+   * property (file `ftdriver.h`), which allows the control at run-time.
    *
-   * Do *not* undefine these macros!
+   * Do **not** undefine these macros!
    */
 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1   500
 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1   400
@@ -815,10 +887,10 @@
 
   /**************************************************************************
    *
-   * CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF
-   * engine gets compiled into FreeType.  If defined, it is possible to
-   * switch between the two engines using the `hinting-engine' property of
-   * the cff driver module.
+   * `CFF_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe CFF engine
+   * gets compiled into FreeType.  If defined, it is possible to switch
+   * between the two engines using the `hinting-engine` property of the 'cff'
+   * driver module.
    */
 /* #define CFF_CONFIG_OPTION_OLD_ENGINE */
 
@@ -834,18 +906,18 @@
 
   /**************************************************************************
    *
-   * There are many PCF fonts just called `Fixed' which look completely
-   * different, and which have nothing to do with each other.  When
-   * selecting `Fixed' in KDE or Gnome one gets results that appear rather
-   * random, the style changes often if one changes the size and one
-   * cannot select some fonts at all.  This option makes the PCF module
-   * prepend the foundry name (plus a space) to the family name.
+   * There are many PCF fonts just called 'Fixed' which look completely
+   * different, and which have nothing to do with each other.  When selecting
+   * 'Fixed' in KDE or Gnome one gets results that appear rather random, the
+   * style changes often if one changes the size and one cannot select some
+   * fonts at all.  This option makes the 'pcf' module prepend the foundry
+   * name (plus a space) to the family name.
    *
-   * We also check whether we have `wide' characters; all put together, we
-   * get family names like `Sony Fixed' or `Misc Fixed Wide'.
+   * We also check whether we have 'wide' characters; all put together, we
+   * get family names like 'Sony Fixed' or 'Misc Fixed Wide'.
    *
    * If this option is activated, it can be controlled with the
-   * `no-long-family-names' property of the pcf driver module.
+   * `no-long-family-names` property of the 'pcf' driver module.
    */
 /* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
 
@@ -861,51 +933,40 @@
 
   /**************************************************************************
    *
-   * Compile autofit module with CJK (Chinese, Japanese, Korean) script
+   * Compile 'autofit' module with CJK (Chinese, Japanese, Korean) script
    * support.
    */
 #define AF_CONFIG_OPTION_CJK
 
+
   /**************************************************************************
    *
-   * Compile autofit module with fallback Indic script support, covering
-   * some scripts that the `latin' submodule of the autofit module doesn't
-   * (yet) handle.
+   * Compile 'autofit' module with fallback Indic script support, covering
+   * some scripts that the 'latin' submodule of the 'autofit' module doesn't
+   * (yet) handle.  Currently, this needs option `AF_CONFIG_OPTION_CJK`.
    */
+#ifdef AF_CONFIG_OPTION_CJK
 #define AF_CONFIG_OPTION_INDIC
+#endif
+
 
   /**************************************************************************
    *
-   * Compile autofit module with warp hinting.  The idea of the warping
-   * code is to slightly scale and shift a glyph within a single dimension
-   * so that as much of its segments are aligned (more or less) on the
-   * grid.  To find out the optimal scaling and shifting value, various
-   * parameter combinations are tried and scored.
-   *
-   * This experimental option is active only if the rendering mode is
-   * FT_RENDER_MODE_LIGHT; you can switch warping on and off with the
-   * `warping' property of the auto-hinter (see file `ftdriver.h' for more
-   * information; by default it is switched off).
-   */
-#define AF_CONFIG_OPTION_USE_WARPER
-
-  /**************************************************************************
-   *
-   * Use TrueType-like size metrics for `light' auto-hinting.
+   * Use TrueType-like size metrics for 'light' auto-hinting.
    *
    * It is strongly recommended to avoid this option, which exists only to
-   * help some legacy applications retain its appearance and behaviour
-   * with respect to auto-hinted TrueType fonts.
+   * help some legacy applications retain its appearance and behaviour with
+   * respect to auto-hinted TrueType fonts.
    *
    * The very reason this option exists at all are GNU/Linux distributions
    * like Fedora that did not un-patch the following change (which was
    * present in FreeType between versions 2.4.6 and 2.7.1, inclusive).
    *
-   * {
+   * ```
    *   2011-07-16  Steven Chu  <steven.f.chu@gmail.com>
    *
    *     [truetype] Fix metrics on size request for scalable fonts.
-   * }
+   * ```
    *
    * This problematic commit is now reverted (more or less).
    */
@@ -915,15 +976,15 @@
 
 
   /*
-   * This macro is obsolete.  Support has been removed in FreeType
-   * version 2.5.
+   * This macro is obsolete.  Support has been removed in FreeType version
+   * 2.5.
    */
 /* #define FT_CONFIG_OPTION_OLD_INTERNALS */
 
 
   /*
-   * This macro is defined if native TrueType hinting is requested by the
-   * definitions above.
+   * The next three 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
@@ -941,8 +1002,23 @@
 
 
   /*
+   * The TT_SUPPORT_COLRV1 macro is defined to indicate to clients that this
+   * version of FreeType has support for 'COLR' v1 API.  This definition is
+   * useful to FreeType clients that want to build in support for 'COLR' v1
+   * depending on a tip-of-tree checkout before it is officially released in
+   * FreeType, and while the feature cannot yet be tested against using
+   * version macros.  Don't change this macro.  This may be removed once the
+   * feature is in a FreeType release version and version macros can be used
+   * to test for availability.
+   */
+#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
+#define  TT_SUPPORT_COLRV1
+#endif
+
+
+  /*
    * Check CFF darkening parameters.  The checks are the same as in function
-   * `cff_property_set' in file `cffdrivr.c'.
+   * `cff_property_set` in file `cffdrivr.c`.
    */
 #if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0   || \
     CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0   || \
@@ -968,8 +1044,8 @@
 #error "Invalid CFF darkening parameters!"
 #endif
 
-FT_END_HEADER
 
+FT_END_HEADER
 
 #endif /* FTOPTION_H_ */
 
diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h
index a744d0d..3c9d2ae 100644
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -5,7 +5,7 @@
  *   ANSI-specific library and header configuration file (specification
  *   only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,11 +19,11 @@
 
   /**************************************************************************
    *
-   * This file is used to group all #includes to the ANSI C library that
+   * This file is used to group all `#includes` to the ANSI~C library that
    * FreeType normally requires.  It also defines macros to rename the
    * standard functions within the FreeType source code.
    *
-   * Load a file which defines FTSTDLIB_H_ before this one to override it.
+   * Load a file which defines `FTSTDLIB_H_` before this one to override it.
    *
    */
 
@@ -37,21 +37,22 @@
 #define ft_ptrdiff_t  ptrdiff_t
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                          integer limits
    *
-   * UINT_MAX and ULONG_MAX are used to automatically compute the size
-   * of `int' and `long' in bytes at compile-time.  So far, this works
-   * for all platforms the library has been tested on.
+   * `UINT_MAX` and `ULONG_MAX` are used to automatically compute the size of
+   * `int` and `long` in bytes at compile-time.  So far, this works for all
+   * platforms the library has been tested on.  We also check `ULLONG_MAX`
+   * to see whether we can use 64-bit `long long` later on.
    *
-   * Note that on the extremely rare platforms that do not provide
-   * integer types that are _exactly_ 16 and 32 bits wide (e.g. some
-   * old Crays where `int' is 36 bits), we do not make any guarantee
-   * about the correct behaviour of FT2 with all fonts.
+   * Note that on the extremely rare platforms that do not provide integer
+   * types that are _exactly_ 16 and 32~bits wide (e.g., some old Crays where
+   * `int` is 36~bits), we do not make any guarantee about the correct
+   * behaviour of FreeType~2 with all fonts.
    *
-   * In these case, `ftconfig.h' will refuse to compile anyway with a
-   * message like `couldn't find 32-bit type' or something similar.
+   * In these cases, `ftconfig.h` will refuse to compile anyway with a
+   * message like 'couldn't find 32-bit type' or something similar.
    *
    */
 
@@ -66,9 +67,18 @@
 #define FT_LONG_MIN    LONG_MIN
 #define FT_LONG_MAX    LONG_MAX
 #define FT_ULONG_MAX   ULONG_MAX
+#ifdef LLONG_MAX
+#define FT_LLONG_MAX   LLONG_MAX
+#endif
+#ifdef LLONG_MIN
+#define FT_LLONG_MIN   LLONG_MIN
+#endif
+#ifdef ULLONG_MAX
+#define FT_ULLONG_MAX  ULLONG_MAX
+#endif
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                character and string processing
    *
@@ -92,7 +102,7 @@
 #define ft_strstr   strstr
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                          file handling
    *
@@ -110,7 +120,7 @@
 #define ft_sprintf  sprintf
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                            sorting
    *
@@ -122,7 +132,7 @@
 #define ft_qsort  qsort
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                       memory allocation
    *
@@ -135,7 +145,7 @@
 #define ft_srealloc  realloc
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                         miscellaneous
    *
@@ -146,7 +156,7 @@
 #define ft_getenv  getenv
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    *                        execution control
    *
@@ -155,16 +165,16 @@
 
 #include <setjmp.h>
 
-#define ft_jmp_buf     jmp_buf  /* note: this cannot be a typedef since */
-                                /*       jmp_buf is defined as a macro  */
-                                /*       on certain platforms           */
+#define ft_jmp_buf     jmp_buf  /* note: this cannot be a typedef since  */
+                                /*       `jmp_buf` is defined as a macro */
+                                /*       on certain platforms            */
 
 #define ft_longjmp     longjmp
 #define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */
 
 
-  /* the following is only used for debugging purposes, i.e., if */
-  /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined    */
+  /* The following is only used for debugging purposes, i.e., if   */
+  /* `FT_DEBUG_LEVEL_ERROR` or `FT_DEBUG_LEVEL_TRACE` are defined. */
 
 #include <stdarg.h>
 
diff --git a/include/freetype/config/integer-types.h b/include/freetype/config/integer-types.h
new file mode 100644
index 0000000..7258b50
--- /dev/null
+++ b/include/freetype/config/integer-types.h
@@ -0,0 +1,250 @@
+/****************************************************************************
+ *
+ * config/integer-types.h
+ *
+ *   FreeType integer types definitions.
+ *
+ * Copyright (C) 1996-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 FREETYPE_CONFIG_INTEGER_TYPES_H_
+#define FREETYPE_CONFIG_INTEGER_TYPES_H_
+
+  /* There are systems (like the Texas Instruments 'C54x) where a `char`  */
+  /* has 16~bits.  ANSI~C says that `sizeof(char)` is always~1.  Since an */
+  /* `int` has 16~bits also for this system, `sizeof(int)` gives~1 which  */
+  /* is probably unexpected.                                              */
+  /*                                                                      */
+  /* `CHAR_BIT` (defined in `limits.h`) gives the number of bits in a     */
+  /* `char` type.                                                         */
+
+#ifndef FT_CHAR_BIT
+#define FT_CHAR_BIT  CHAR_BIT
+#endif
+
+#ifndef FT_SIZEOF_INT
+
+  /* The size of an `int` type. */
+#if                                 FT_UINT_MAX == 0xFFFFUL
+#define FT_SIZEOF_INT  ( 16 / FT_CHAR_BIT )
+#elif                               FT_UINT_MAX == 0xFFFFFFFFUL
+#define FT_SIZEOF_INT  ( 32 / FT_CHAR_BIT )
+#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
+#define FT_SIZEOF_INT  ( 64 / FT_CHAR_BIT )
+#else
+#error "Unsupported size of `int' type!"
+#endif
+
+#endif  /* !defined(FT_SIZEOF_INT) */
+
+#ifndef FT_SIZEOF_LONG
+
+  /* The size of a `long` type.  A five-byte `long` (as used e.g. on the */
+  /* DM642) is recognized but avoided.                                   */
+#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
+#define FT_SIZEOF_LONG  ( 32 / FT_CHAR_BIT )
+#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
+#define FT_SIZEOF_LONG  ( 32 / FT_CHAR_BIT )
+#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
+#define FT_SIZEOF_LONG  ( 64 / FT_CHAR_BIT )
+#else
+#error "Unsupported size of `long' type!"
+#endif
+
+#endif /* !defined(FT_SIZEOF_LONG) */
+
+#ifndef FT_SIZEOF_LONG_LONG
+
+  /* The size of a `long long` type if available */
+#if defined( FT_ULLONG_MAX ) && FT_ULLONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
+#define FT_SIZEOF_LONG_LONG  ( 64 / FT_CHAR_BIT )
+#else
+#define FT_SIZEOF_LONG_LONG  0
+#endif
+
+#endif /* !defined(FT_SIZEOF_LONG_LONG) */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   basic_types
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_Int16
+   *
+   * @description:
+   *   A typedef for a 16bit signed integer type.
+   */
+  typedef signed short  FT_Int16;
+
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_UInt16
+   *
+   * @description:
+   *   A typedef for a 16bit unsigned integer type.
+   */
+  typedef unsigned short  FT_UInt16;
+
+  /* */
+
+
+  /* this #if 0 ... #endif clause is for documentation purposes */
+#if 0
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_Int32
+   *
+   * @description:
+   *   A typedef for a 32bit signed integer type.  The size depends on the
+   *   configuration.
+   */
+  typedef signed XXX  FT_Int32;
+
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_UInt32
+   *
+   *   A typedef for a 32bit unsigned integer type.  The size depends on the
+   *   configuration.
+   */
+  typedef unsigned XXX  FT_UInt32;
+
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_Int64
+   *
+   *   A typedef for a 64bit signed integer type.  The size depends on the
+   *   configuration.  Only defined if there is real 64bit support;
+   *   otherwise, it gets emulated with a structure (if necessary).
+   */
+  typedef signed XXX  FT_Int64;
+
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_UInt64
+   *
+   *   A typedef for a 64bit unsigned integer type.  The size depends on the
+   *   configuration.  Only defined if there is real 64bit support;
+   *   otherwise, it gets emulated with a structure (if necessary).
+   */
+  typedef unsigned XXX  FT_UInt64;
+
+  /* */
+
+#endif
+
+#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
+
+  typedef signed int      FT_Int32;
+  typedef unsigned int    FT_UInt32;
+
+#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
+
+  typedef signed long     FT_Int32;
+  typedef unsigned long   FT_UInt32;
+
+#else
+#error "no 32bit type found -- please check your configuration files"
+#endif
+
+
+  /* look up an integer type that is at least 32~bits */
+#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
+
+  typedef int            FT_Fast;
+  typedef unsigned int   FT_UFast;
+
+#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
+
+  typedef long           FT_Fast;
+  typedef unsigned long  FT_UFast;
+
+#endif
+
+
+  /* determine whether we have a 64-bit integer type */
+#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
+
+#define FT_INT64   long
+#define FT_UINT64  unsigned long
+
+#elif FT_SIZEOF_LONG_LONG >= ( 64 / FT_CHAR_BIT )
+
+#define FT_INT64   long long int
+#define FT_UINT64  unsigned long long int
+
+  /**************************************************************************
+   *
+   * A 64-bit data type may create compilation problems if you compile in
+   * strict ANSI mode.  To avoid them, we disable other 64-bit data types if
+   * `__STDC__` is defined.  You can however ignore this rule by defining the
+   * `FT_CONFIG_OPTION_FORCE_INT64` configuration macro.
+   */
+#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
+
+#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
+
+  /* this compiler provides the `__int64` type */
+#define FT_INT64   __int64
+#define FT_UINT64  unsigned __int64
+
+#elif defined( __BORLANDC__ )  /* Borland C++ */
+
+  /* XXXX: We should probably check the value of `__BORLANDC__` in order */
+  /*       to test the compiler version.                                 */
+
+  /* this compiler provides the `__int64` type */
+#define FT_INT64   __int64
+#define FT_UINT64  unsigned __int64
+
+#elif defined( __WATCOMC__ ) && __WATCOMC__ >= 1100  /* Watcom C++ */
+
+#define FT_INT64   long long int
+#define FT_UINT64  unsigned long long int
+
+#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
+
+#define FT_INT64   long long int
+#define FT_UINT64  unsigned long long int
+
+#elif defined( __GNUC__ )
+
+  /* GCC provides the `long long` type */
+#define FT_INT64   long long int
+#define FT_UINT64  unsigned long long int
+
+#endif /* !__STDC__ */
+
+#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+
+#ifdef FT_INT64
+  typedef FT_INT64   FT_Int64;
+  typedef FT_UINT64  FT_UInt64;
+#endif
+
+
+#endif  /* FREETYPE_CONFIG_INTEGER_TYPES_H_ */
diff --git a/include/freetype/config/mac-support.h b/include/freetype/config/mac-support.h
new file mode 100644
index 0000000..b77b96d
--- /dev/null
+++ b/include/freetype/config/mac-support.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ *
+ * config/mac-support.h
+ *
+ *   Mac/OS X support configuration header.
+ *
+ * Copyright (C) 1996-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 FREETYPE_CONFIG_MAC_SUPPORT_H_
+#define FREETYPE_CONFIG_MAC_SUPPORT_H_
+
+  /**************************************************************************
+   *
+   * Mac support
+   *
+   *   This is the only necessary change, so it is defined here instead
+   *   providing a new configuration file.
+   */
+#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
+  /* No Carbon frameworks for 64bit 10.4.x.                         */
+  /* `AvailabilityMacros.h` is available since Mac OS X 10.2,       */
+  /* so guess the system version by maximum errno before inclusion. */
+#include <errno.h>
+#ifdef ECANCELED /* defined since 10.2 */
+#include "AvailabilityMacros.h"
+#endif
+#if defined( __LP64__ ) && \
+    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
+#undef FT_MACINTOSH
+#endif
+
+#elif defined( __SC__ ) || defined( __MRC__ )
+  /* Classic MacOS compilers */
+#include "ConditionalMacros.h"
+#if TARGET_OS_MAC
+#define FT_MACINTOSH 1
+#endif
+
+#endif  /* Mac support */
+
+#endif  /* FREETYPE_CONFIG_MAC_SUPPORT_H_ */
diff --git a/include/freetype/config/public-macros.h b/include/freetype/config/public-macros.h
new file mode 100644
index 0000000..23d0fa6
--- /dev/null
+++ b/include/freetype/config/public-macros.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+ *
+ * config/public-macros.h
+ *
+ *   Define a set of compiler macros used in public FreeType headers.
+ *
+ * Copyright (C) 2020-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.
+ *
+ */
+
+  /*
+   * The definitions in this file are used by the public FreeType headers
+   * and thus should be considered part of the public API.
+   *
+   * Other compiler-specific macro definitions that are not exposed by the
+   * FreeType API should go into
+   * `include/freetype/internal/compiler-macros.h` instead.
+   */
+#ifndef FREETYPE_CONFIG_PUBLIC_MACROS_H_
+#define FREETYPE_CONFIG_PUBLIC_MACROS_H_
+
+  /*
+   * `FT_BEGIN_HEADER` and `FT_END_HEADER` might have already been defined
+   * by `freetype/config/ftheader.h`, but we don't want to include this
+   * header here, so redefine the macros here only when needed.  Their
+   * definition is very stable, so keeping them in sync with the ones in the
+   * header should not be a maintenance issue.
+   */
+#ifndef FT_BEGIN_HEADER
+#ifdef __cplusplus
+#define FT_BEGIN_HEADER  extern "C" {
+#else
+#define FT_BEGIN_HEADER  /* empty */
+#endif
+#endif  /* FT_BEGIN_HEADER */
+
+#ifndef FT_END_HEADER
+#ifdef __cplusplus
+#define FT_END_HEADER  }
+#else
+#define FT_END_HEADER  /* empty */
+#endif
+#endif  /* FT_END_HEADER */
+
+
+FT_BEGIN_HEADER
+
+  /*
+   * Mark a function declaration as public.  This ensures it will be
+   * properly exported to client code.  Place this before a function
+   * declaration.
+   *
+   * NOTE: This macro should be considered an internal implementation
+   * detail, and not part of the FreeType API.  It is only defined here
+   * because it is needed by `FT_EXPORT`.
+   */
+
+  /* Visual C, mingw */
+#if defined( _WIN32 )
+
+#if defined( FT2_BUILD_LIBRARY ) && defined( DLL_EXPORT )
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE  __declspec( dllexport )
+#elif defined( DLL_IMPORT )
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE  __declspec( dllimport )
+#endif
+
+  /* gcc, clang */
+#elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE \
+          __attribute__(( visibility( "default" ) ))
+
+  /* Sun */
+#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE  __global
+#endif
+
+
+#ifndef FT_PUBLIC_FUNCTION_ATTRIBUTE
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE  /* empty */
+#endif
+
+
+  /*
+   * Define a public FreeType API function.  This ensures it is properly
+   * exported or imported at build time.  The macro parameter is the
+   * function's return type as in:
+   *
+   *   FT_EXPORT( FT_Bool )
+   *   FT_Object_Method( FT_Object  obj,
+   *                     ... );
+   *
+   * NOTE: This requires that all `FT_EXPORT` uses are inside
+   * `FT_BEGIN_HEADER ... FT_END_HEADER` blocks.  This guarantees that the
+   * functions are exported with C linkage, even when the header is included
+   * by a C++ source file.
+   */
+#define FT_EXPORT( x )  FT_PUBLIC_FUNCTION_ATTRIBUTE extern x
+
+
+  /*
+   * `FT_UNUSED` indicates that a given parameter is not used -- this is
+   * only used to get rid of unpleasant compiler warnings.
+   *
+   * Technically, this was not meant to be part of the public API, but some
+   * third-party code depends on it.
+   */
+#ifndef FT_UNUSED
+#define FT_UNUSED( arg )  ( (arg) = (arg) )
+#endif
+
+
+  /*
+   * Support for casts in both C and C++.
+   */
+#ifdef __cplusplus
+#define FT_STATIC_CAST( type, var )       static_cast<type>(var)
+#define FT_REINTERPRET_CAST( type, var )  reinterpret_cast<type>(var)
+
+#define FT_STATIC_BYTE_CAST( type, var )                         \
+          static_cast<type>( static_cast<unsigned char>( var ) )
+#else
+#define FT_STATIC_CAST( type, var )       (type)(var)
+#define FT_REINTERPRET_CAST( type, var )  (type)(var)
+
+#define FT_STATIC_BYTE_CAST( type, var )  (type)(unsigned char)(var)
+#endif
+
+
+FT_END_HEADER
+
+#endif  /* FREETYPE_CONFIG_PUBLIC_MACROS_H_ */
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 620df4c..efff74f 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -4,7 +4,7 @@
  *
  *   FreeType high-level API and common types (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,19 +20,10 @@
 #define FREETYPE_H_
 
 
-#ifndef FT_FREETYPE_H
-#error "`ft2build.h' hasn't been included yet!"
-#error "Please always use macros to include FreeType header files."
-#error "Example:"
-#error "  #include <ft2build.h>"
-#error "  #include FT_FREETYPE_H"
-#endif
-
-
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_TYPES_H
-#include FT_ERRORS_H
+#include <freetype/fttypes.h>
+#include <freetype/fterrors.h>
 
 
 FT_BEGIN_HEADER
@@ -42,6 +33,34 @@
   /**************************************************************************
    *
    * @section:
+   *   preamble
+   *
+   * @title:
+   *   Preamble
+   *
+   * @abstract:
+   *   What FreeType is and isn't
+   *
+   * @description:
+   *   FreeType is a library that provides access to glyphs in font files.  It
+   *   scales the glyph images and their metrics to a requested size, and it
+   *   rasterizes the glyph images to produce pixel or subpixel alpha coverage
+   *   bitmaps.
+   *
+   *   Note that FreeType is _not_ a text layout engine.  You have to use
+   *   higher-level libraries like HarfBuzz, Pango, or ICU for that.
+   *
+   *   Note also that FreeType does _not_ perform alpha blending or
+   *   compositing the resulting bitmaps or pixmaps by itself.  Use your
+   *   favourite graphics library (for example, Cairo or Skia) to further
+   *   process FreeType's output.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
    *   header_inclusion
    *
    * @title:
@@ -51,23 +70,15 @@
    *   How client applications should include FreeType header files.
    *
    * @description:
-   *   To be as flexible as possible (and for historical reasons),
-   *   FreeType uses a very special inclusion scheme to load header
-   *   files, for example
+   *   To be as flexible as possible (and for historical reasons), you must
+   *   load file `ft2build.h` first before other header files, for example
    *
-   *   {
+   *   ```
    *     #include <ft2build.h>
    *
-   *     #include FT_FREETYPE_H
-   *     #include FT_OUTLINE_H
-   *   }
-   *
-   *   A compiler and its preprocessor only needs an include path to find
-   *   the file `ft2build.h'; the exact locations and names of the other
-   *   FreeType header files are hidden by @header_file_macros, loaded by
-   *   `ft2build.h'.  The API documentation always gives the header macro
-   *   name needed for a particular function.
-   *
+   *     #include <freetype/freetype.h>
+   *     #include <freetype/ftoutln.h>
+   *   ```
    */
 
 
@@ -83,10 +94,10 @@
    *   How client applications should allocate FreeType data structures.
    *
    * @description:
-   *   FreeType assumes that structures allocated by the user and passed
-   *   as arguments are zeroed out except for the actual data.  In other
-   *   words, it is recommended to use `calloc' (or variants of it)
-   *   instead of `malloc' for allocation.
+   *   FreeType assumes that structures allocated by the user and passed as
+   *   arguments are zeroed out except for the actual data.  In other words,
+   *   it is recommended to use `calloc` (or variants of it) instead of
+   *   `malloc` for allocation.
    *
    */
 
@@ -142,6 +153,9 @@
    *   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
@@ -150,6 +164,9 @@
    *   FT_HAS_GLYPH_NAMES
    *   FT_HAS_COLOR
    *   FT_HAS_MULTIPLE_MASTERS
+   *   FT_HAS_SVG
+   *   FT_HAS_SBIX
+   *   FT_HAS_SBIX_OVERLAY
    *
    *   FT_IS_SFNT
    *   FT_IS_SCALABLE
@@ -193,11 +210,11 @@
    *   FT_Size_RequestRec
    *   FT_Size_Request
    *   FT_Set_Transform
+   *   FT_Get_Transform
    *   FT_Load_Glyph
    *   FT_Get_Char_Index
    *   FT_Get_First_Char
    *   FT_Get_Next_Char
-   *   FT_Get_Name_Index
    *   FT_Load_Char
    *
    *   FT_OPEN_MEMORY
@@ -213,6 +230,7 @@
    *   FT_LOAD_NO_SCALE
    *   FT_LOAD_NO_HINTING
    *   FT_LOAD_NO_BITMAP
+   *   FT_LOAD_SBITS_ONLY
    *   FT_LOAD_NO_AUTOHINT
    *   FT_LOAD_COLOR
    *
@@ -235,14 +253,15 @@
    *   FT_Get_Kerning
    *   FT_Kerning_Mode
    *   FT_Get_Track_Kerning
-   *   FT_Get_Glyph_Name
-   *   FT_Get_Postscript_Name
    *
    *   FT_CharMapRec
    *   FT_Select_Charmap
    *   FT_Set_Charmap
    *   FT_Get_Charmap_Index
    *
+   *   FT_Get_Name_Index
+   *   FT_Get_Glyph_Name
+   *   FT_Get_Postscript_Name
    *   FT_Get_FSType_Flags
    *   FT_Get_SubGlyph_Info
    *
@@ -269,10 +288,10 @@
    *   FT_Glyph_Metrics
    *
    * @description:
-   *   A structure to model the metrics of a single glyph.  The values
-   *   are expressed in 26.6 fractional pixel format; if the flag
-   *   @FT_LOAD_NO_SCALE has been used while loading the glyph, values
-   *   are expressed in font units instead.
+   *   A structure to model the metrics of a single glyph.  The values are
+   *   expressed in 26.6 fractional pixel format; if the flag
+   *   @FT_LOAD_NO_SCALE has been used while loading the glyph, values are
+   *   expressed in font units instead.
    *
    * @fields:
    *   width ::
@@ -294,25 +313,25 @@
    *     Left side bearing for vertical layout.
    *
    *   vertBearingY ::
-   *     Top side bearing for vertical layout.  Larger positive values
-   *     mean further below the vertical glyph origin.
+   *     Top side bearing for vertical layout.  Larger positive values mean
+   *     further below the vertical glyph origin.
    *
    *   vertAdvance ::
-   *     Advance height for vertical layout.  Positive values mean the
-   *     glyph has a positive advance downward.
+   *     Advance height for vertical layout.  Positive values mean the glyph
+   *     has a positive advance downward.
    *
    * @note:
    *   If not disabled with @FT_LOAD_NO_HINTING, the values represent
    *   dimensions of the hinted glyph (in case hinting is applicable).
    *
    *   Stroking a glyph with an outside border does not increase
-   *   `horiAdvance' or `vertAdvance'; you have to manually adjust these
+   *   `horiAdvance` or `vertAdvance`; you have to manually adjust these
    *   values to account for the added width and height.
    *
-   *   FreeType doesn't use the `VORG' table data for CFF fonts because
-   *   it doesn't have an interface to quickly retrieve the glyph height.
-   *   The y~coordinate of the vertical origin can be simply computed as
-   *   `vertBearingY + height' after loading a glyph.
+   *   FreeType doesn't use the 'VORG' table data for CFF fonts because it
+   *   doesn't have an interface to quickly retrieve the glyph height.  The
+   *   y~coordinate of the vertical origin can be simply computed as
+   *   `vertBearingY + height` after loading a glyph.
    */
   typedef struct  FT_Glyph_Metrics_
   {
@@ -336,42 +355,38 @@
    *   FT_Bitmap_Size
    *
    * @description:
-   *   This structure models the metrics of a bitmap strike (i.e., a set
-   *   of glyphs for a given point size and resolution) in a bitmap font.
-   *   It is used for the `available_sizes' field of @FT_Face.
+   *   This structure models the metrics of a bitmap strike (i.e., a set of
+   *   glyphs for a given point size and resolution) in a bitmap font.  It is
+   *   used for the `available_sizes` field of @FT_Face.
    *
    * @fields:
    *   height ::
-   *     The vertical distance, in pixels, between two
-   *     consecutive baselines.  It is always positive.
+   *     The vertical distance, in pixels, between two consecutive baselines.
+   *     It is always positive.
    *
    *   width ::
-   *     The average width, in pixels, of all glyphs in the
-   *     strike.
+   *     The average width, in pixels, of all glyphs in the strike.
    *
    *   size ::
-   *     The nominal size of the strike in 26.6 fractional
-   *     points.  This field is not very useful.
+   *     The nominal size of the strike in 26.6 fractional points.  This
+   *     field is not very useful.
    *
    *   x_ppem ::
-   *     The horizontal ppem (nominal width) in 26.6 fractional
-   *     pixels.
+   *     The horizontal ppem (nominal width) in 26.6 fractional pixels.
    *
    *   y_ppem ::
-   *     The vertical ppem (nominal height) in 26.6 fractional
-   *     pixels.
+   *     The vertical ppem (nominal height) in 26.6 fractional pixels.
    *
    * @note:
    *   Windows FNT:
-   *     The nominal size given in a FNT font is not reliable.  If the
-   *     driver finds it incorrect, it sets `size' to some calculated
-   *     values, and `x_ppem' and `y_ppem' to the pixel width and height
-   *     given in the font, respectively.
+   *     The nominal size given in a FNT font is not reliable.  If the driver
+   *     finds it incorrect, it sets `size` to some calculated values, and
+   *     `x_ppem` and `y_ppem` to the pixel width and height given in the
+   *     font, respectively.
    *
    *   TrueType embedded bitmaps:
-   *     `size', `width', and `height' values are not contained in the
-   *     bitmap strike itself.  They are computed from the global font
-   *     parameters.
+   *     `size`, `width`, and `height` values are not contained in the bitmap
+   *     strike itself.  They are computed from the global font parameters.
    */
   typedef struct  FT_Bitmap_Size_
   {
@@ -400,24 +415,22 @@
    *   FT_Library
    *
    * @description:
-   *   A handle to a FreeType library instance.  Each `library' is
-   *   completely independent from the others; it is the `root' of a set
-   *   of objects like fonts, faces, sizes, etc.
+   *   A handle to a FreeType library instance.  Each 'library' is completely
+   *   independent from the others; it is the 'root' of a set of objects like
+   *   fonts, faces, sizes, etc.
    *
    *   It also embeds a memory manager (see @FT_Memory), as well as a
    *   scan-line converter object (see @FT_Raster).
    *
-   *   In multi-threaded applications it is easiest to use one
-   *   `FT_Library' object per thread.  In case this is too cumbersome,
-   *   a single `FT_Library' object across threads is possible also
-   *   (since FreeType version 2.5.6), as long as a mutex lock is used
-   *   around @FT_New_Face and @FT_Done_Face.
+   *   [Since 2.5.6] In multi-threaded applications it is easiest to use one
+   *   `FT_Library` object per thread.  In case this is too cumbersome, a
+   *   single `FT_Library` object across threads is possible also, as long as
+   *   a mutex lock is used around @FT_New_Face and @FT_Done_Face.
    *
    * @note:
    *   Library objects are normally created by @FT_Init_FreeType, and
    *   destroyed with @FT_Done_FreeType.  If you need reference-counting
-   *   (cf. @FT_Reference_Library), use @FT_New_Library and
-   *   @FT_Done_Library.
+   *   (cf. @FT_Reference_Library), use @FT_New_Library and @FT_Done_Library.
    */
   typedef struct FT_LibraryRec_  *FT_Library;
 
@@ -435,9 +448,9 @@
    *   FT_Module
    *
    * @description:
-   *   A handle to a given FreeType module object.  A module can be a
-   *   font driver, a renderer, or anything else that provides services
-   *   to the former.
+   *   A handle to a given FreeType module object.  A module can be a font
+   *   driver, a renderer, or anything else that provides services to the
+   *   former.
    */
   typedef struct FT_ModuleRec_*  FT_Module;
 
@@ -448,8 +461,8 @@
    *   FT_Driver
    *
    * @description:
-   *   A handle to a given FreeType font driver object.  A font driver
-   *   is a module capable of creating faces from font files.
+   *   A handle to a given FreeType font driver object.  A font driver is a
+   *   module capable of creating faces from font files.
    */
   typedef struct FT_DriverRec_*  FT_Driver;
 
@@ -461,9 +474,8 @@
    *
    * @description:
    *   A handle to a given FreeType renderer.  A renderer is a module in
-   *   charge of converting a glyph's outline image to a bitmap.  It
-   *   supports a single glyph image format, and one or more target
-   *   surface depths.
+   *   charge of converting a glyph's outline image to a bitmap.  It supports
+   *   a single glyph image format, and one or more target surface depths.
    */
   typedef struct FT_RendererRec_*  FT_Renderer;
 
@@ -481,25 +493,24 @@
    *   FT_Face
    *
    * @description:
-   *   A handle to a typographic face object.  A face object models a
-   *   given typeface, in a given style.
+   *   A handle to a typographic face object.  A face object models a given
+   *   typeface, in a given style.
    *
    * @note:
-   *   A face object also owns a single @FT_GlyphSlot object, as well
-   *   as one or more @FT_Size objects.
+   *   A face object also owns a single @FT_GlyphSlot object, as well as one
+   *   or more @FT_Size objects.
    *
-   *   Use @FT_New_Face or @FT_Open_Face to create a new face object from
-   *   a given filepath or a custom input stream.
+   *   Use @FT_New_Face or @FT_Open_Face to create a new face object from a
+   *   given filepath or a custom input stream.
    *
    *   Use @FT_Done_Face to destroy it (along with its slot and sizes).
    *
-   *   An `FT_Face' object can only be safely used from one thread at a
-   *   time.  Similarly, creation and destruction of `FT_Face' with the
-   *   same @FT_Library object can only be done from one thread at a
-   *   time.  On the other hand, functions like @FT_Load_Glyph and its
-   *   siblings are thread-safe and do not need the lock to be held as
-   *   long as the same `FT_Face' object is not used from multiple
-   *   threads at the same time.
+   *   An `FT_Face` object can only be safely used from one thread at a time.
+   *   Similarly, creation and destruction of `FT_Face` with the same
+   *   @FT_Library object can only be done from one thread at a time.  On the
+   *   other hand, functions like @FT_Load_Glyph and its siblings are
+   *   thread-safe and do not need the lock to be held as long as the same
+   *   `FT_Face` object is not used from multiple threads at the same time.
    *
    * @also:
    *   See @FT_FaceRec for the publicly accessible fields of a given face
@@ -514,23 +525,24 @@
    *   FT_Size
    *
    * @description:
-   *   A handle to an object that models a face scaled to a given
-   *   character size.
+   *   A handle to an object that models a face scaled to a given character
+   *   size.
    *
    * @note:
-   *   An @FT_Face has one _active_ @FT_Size object that is used by
-   *   functions like @FT_Load_Glyph to determine the scaling
-   *   transformation that in turn is used to load and hint glyphs and
-   *   metrics.
+   *   An @FT_Face has one _active_ `FT_Size` object that is used by
+   *   functions like @FT_Load_Glyph to determine the scaling transformation
+   *   that in turn is used to load and hint glyphs and metrics.
    *
-   *   You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes,
-   *   @FT_Request_Size or even @FT_Select_Size to change the content
-   *   (i.e., the scaling values) of the active @FT_Size.
+   *   A newly created `FT_Size` object contains only meaningless zero values.
+   *   You must use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, @FT_Request_Size
+   *   or even @FT_Select_Size to change the content (i.e., the scaling
+   *   values) of the active `FT_Size`.  Otherwise, the scaling and hinting
+   *   will not be performed.
    *
-   *   You can use @FT_New_Size to create additional size objects for a
-   *   given @FT_Face, but they won't be used by other functions until
-   *   you activate it through @FT_Activate_Size.  Only one size can be
-   *   activated at any given time per face.
+   *   You can use @FT_New_Size to create additional size objects for a given
+   *   @FT_Face, but they won't be used by other functions until you activate
+   *   it through @FT_Activate_Size.  Only one size can be activated at any
+   *   given time per face.
    *
    * @also:
    *   See @FT_SizeRec for the publicly accessible fields of a given size
@@ -545,13 +557,12 @@
    *   FT_GlyphSlot
    *
    * @description:
-   *   A handle to a given `glyph slot'.  A slot is a container that can
-   *   hold any of the glyphs contained in its parent face.
+   *   A handle to a given 'glyph slot'.  A slot is a container that can hold
+   *   any of the glyphs contained in its parent face.
    *
-   *   In other words, each time you call @FT_Load_Glyph or
-   *   @FT_Load_Char, the slot's content is erased by the new glyph data,
-   *   i.e., the glyph's metrics, its image (bitmap or outline), and
-   *   other control information.
+   *   In other words, each time you call @FT_Load_Glyph or @FT_Load_Char,
+   *   the slot's content is erased by the new glyph data, i.e., the glyph's
+   *   metrics, its image (bitmap or outline), and other control information.
    *
    * @also:
    *   See @FT_GlyphSlotRec for the publicly accessible glyph fields.
@@ -565,26 +576,26 @@
    *   FT_CharMap
    *
    * @description:
-   *   A handle to a character map (usually abbreviated to `charmap').  A
-   *   charmap is used to translate character codes in a given encoding
-   *   into glyph indexes for its parent's face.  Some font formats may
-   *   provide several charmaps per font.
+   *   A handle to a character map (usually abbreviated to 'charmap').  A
+   *   charmap is used to translate character codes in a given encoding into
+   *   glyph indexes for its parent's face.  Some font formats may provide
+   *   several charmaps per font.
    *
-   *   Each face object owns zero or more charmaps, but only one of them
-   *   can be `active', providing the data used by @FT_Get_Char_Index or
+   *   Each face object owns zero or more charmaps, but only one of them can
+   *   be 'active', providing the data used by @FT_Get_Char_Index or
    *   @FT_Load_Char.
    *
    *   The list of available charmaps in a face is available through the
-   *   `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec.
+   *   `face->num_charmaps` and `face->charmaps` fields of @FT_FaceRec.
    *
-   *   The currently active charmap is available as `face->charmap'.
-   *   You should call @FT_Set_Charmap to change it.
+   *   The currently active charmap is available as `face->charmap`.  You
+   *   should call @FT_Set_Charmap to change it.
    *
    * @note:
    *   When a new face is created (either through @FT_New_Face or
-   *   @FT_Open_Face), the library looks for a Unicode charmap within
-   *   the list and automatically activates it.  If there is no Unicode
-   *   charmap, FreeType doesn't set an `active' charmap.
+   *   @FT_Open_Face), the library looks for a Unicode charmap within the
+   *   list and automatically activates it.  If there is no Unicode charmap,
+   *   FreeType doesn't set an 'active' charmap.
    *
    * @also:
    *   See @FT_CharMapRec for the publicly accessible fields of a given
@@ -600,26 +611,26 @@
    *
    * @description:
    *   This macro converts four-letter tags into an unsigned long.  It is
-   *   used to define `encoding' identifiers (see @FT_Encoding).
+   *   used to define 'encoding' identifiers (see @FT_Encoding).
    *
    * @note:
-   *   Since many 16-bit compilers don't like 32-bit enumerations, you
-   *   should redefine this macro in case of problems to something like
-   *   this:
+   *   Since many 16-bit compilers don't like 32-bit enumerations, you should
+   *   redefine this macro in case of problems to something like this:
    *
-   *   {
+   *   ```
    *     #define FT_ENC_TAG( value, a, b, c, d )  value
-   *   }
+   *   ```
    *
    *   to get a simple enumeration without assigning special numbers.
    */
 
 #ifndef FT_ENC_TAG
-#define FT_ENC_TAG( value, a, b, c, d )         \
-          value = ( ( (FT_UInt32)(a) << 24 ) |  \
-                    ( (FT_UInt32)(b) << 16 ) |  \
-                    ( (FT_UInt32)(c) <<  8 ) |  \
-                      (FT_UInt32)(d)         )
+
+#define FT_ENC_TAG( value, a, b, c, d )                             \
+          value = ( ( FT_STATIC_BYTE_CAST( FT_UInt32, a ) << 24 ) | \
+                    ( FT_STATIC_BYTE_CAST( FT_UInt32, b ) << 16 ) | \
+                    ( FT_STATIC_BYTE_CAST( FT_UInt32, c ) <<  8 ) | \
+                      FT_STATIC_BYTE_CAST( FT_UInt32, d )         )
 
 #endif /* FT_ENC_TAG */
 
@@ -630,12 +641,12 @@
    *   FT_Encoding
    *
    * @description:
-   *   An enumeration to specify character sets supported by charmaps.
-   *   Used in the @FT_Select_Charmap API function.
+   *   An enumeration to specify character sets supported by charmaps.  Used
+   *   in the @FT_Select_Charmap API function.
    *
    * @note:
    *   Despite the name, this enumeration lists specific character
-   *   repertories (i.e., charsets), and not text encoding methods (e.g.,
+   *   repertoires (i.e., charsets), and not text encoding methods (e.g.,
    *   UTF-8, UTF-16, etc.).
    *
    *   Other encodings might be defined in the future.
@@ -646,43 +657,42 @@
    *     and Windows FNT; see below for more information.
    *
    *   FT_ENCODING_UNICODE ::
-   *     The Unicode character set.  This value covers all versions of
-   *     the Unicode repertoire, including ASCII and Latin-1.  Most fonts
-   *     include a Unicode charmap, but not all of them.
+   *     The Unicode character set.  This value covers all versions of the
+   *     Unicode repertoire, including ASCII and Latin-1.  Most fonts include
+   *     a Unicode charmap, but not all of them.
    *
-   *     For example, if you want to access Unicode value U+1F028 (and
-   *     the font contains it), use value 0x1F028 as the input value for
+   *     For example, if you want to access Unicode value U+1F028 (and the
+   *     font contains it), use value 0x1F028 as the input value for
    *     @FT_Get_Char_Index.
    *
    *   FT_ENCODING_MS_SYMBOL ::
-   *     Microsoft Symbol encoding, used to encode mathematical symbols
-   *     and wingdings.  For more information, see
-   *     `https://www.microsoft.com/typography/otspec/recom.htm',
-   *     `http://www.kostis.net/charsets/symbol.htm', and
-   *     `http://www.kostis.net/charsets/wingding.htm'.
+   *     Microsoft Symbol encoding, used to encode mathematical symbols and
+   *     wingdings.  For more information, see
+   *     'https://www.microsoft.com/typography/otspec/recom.htm#non-standard-symbol-fonts',
+   *     'http://www.kostis.net/charsets/symbol.htm', and
+   *     'http://www.kostis.net/charsets/wingding.htm'.
    *
    *     This encoding uses character codes from the PUA (Private Unicode
    *     Area) in the range U+F020-U+F0FF.
    *
    *   FT_ENCODING_SJIS ::
    *     Shift JIS encoding for Japanese.  More info at
-   *     `https://en.wikipedia.org/wiki/Shift_JIS'.  See note on
-   *     multi-byte encodings below.
+   *     'https://en.wikipedia.org/wiki/Shift_JIS'.  See note on multi-byte
+   *     encodings below.
    *
    *   FT_ENCODING_PRC ::
    *     Corresponds to encoding systems mainly for Simplified Chinese as
-   *     used in People's Republic of China (PRC).  The encoding layout
-   *     is based on GB~2312 and its supersets GBK and GB~18030.
+   *     used in People's Republic of China (PRC).  The encoding layout is
+   *     based on GB~2312 and its supersets GBK and GB~18030.
    *
    *   FT_ENCODING_BIG5 ::
-   *     Corresponds to an encoding system for Traditional Chinese as
-   *     used in Taiwan and Hong Kong.
+   *     Corresponds to an encoding system for Traditional Chinese as used in
+   *     Taiwan and Hong Kong.
    *
    *   FT_ENCODING_WANSUNG ::
-   *     Corresponds to the Korean encoding system known as Extended
-   *     Wansung (MS Windows code page 949).
-   *     For more information see
-   *     `https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'.
+   *     Corresponds to the Korean encoding system known as Extended Wansung
+   *     (MS Windows code page 949).  For more information see
+   *     'https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'.
    *
    *   FT_ENCODING_JOHAB ::
    *     The Korean standard character set (KS~C 5601-1992), which
@@ -690,12 +700,12 @@
    *     includes all possible Hangul character combinations.
    *
    *   FT_ENCODING_ADOBE_LATIN_1 ::
-   *     Corresponds to a Latin-1 encoding as defined in a Type~1
-   *     PostScript font.  It is limited to 256 character codes.
+   *     Corresponds to a Latin-1 encoding as defined in a Type~1 PostScript
+   *     font.  It is limited to 256 character codes.
    *
    *   FT_ENCODING_ADOBE_STANDARD ::
-   *     Adobe Standard encoding, as found in Type~1, CFF, and
-   *     OpenType/CFF fonts.  It is limited to 256 character codes.
+   *     Adobe Standard encoding, as found in Type~1, CFF, and OpenType/CFF
+   *     fonts.  It is limited to 256 character codes.
    *
    *   FT_ENCODING_ADOBE_EXPERT ::
    *     Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF
@@ -706,9 +716,9 @@
    *     OpenType/CFF fonts.  It is limited to 256 character codes.
    *
    *   FT_ENCODING_APPLE_ROMAN ::
-   *     Apple roman encoding.  Many TrueType and OpenType fonts contain
-   *     a charmap for this 8-bit encoding, since older versions of Mac
-   *     OS are able to use it.
+   *     Apple roman encoding.  Many TrueType and OpenType fonts contain a
+   *     charmap for this 8-bit encoding, since older versions of Mac OS are
+   *     able to use it.
    *
    *   FT_ENCODING_OLD_LATIN_2 ::
    *     This value is deprecated and was neither used nor reported by
@@ -730,44 +740,46 @@
    *     Same as FT_ENCODING_JOHAB.  Deprecated.
    *
    * @note:
-   *   By default, FreeType enables a Unicode charmap and tags it with
-   *   FT_ENCODING_UNICODE when it is either provided or can be generated
-   *   from PostScript glyph name dictionaries in the font file.
+   *   When loading a font, FreeType makes a Unicode charmap active if
+   *   possible (either if the font provides such a charmap, or if FreeType
+   *   can synthesize one from PostScript glyph name dictionaries; in either
+   *   case, the charmap is tagged with `FT_ENCODING_UNICODE`).  If such a
+   *   charmap is synthesized, it is placed at the first position of the
+   *   charmap array.
+   *
    *   All other encodings are considered legacy and tagged only if
-   *   explicitly defined in the font file.  Otherwise, FT_ENCODING_NONE
-   *   is used.
+   *   explicitly defined in the font file.  Otherwise, `FT_ENCODING_NONE` is
+   *   used.
    *
-   *   FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap
-   *   is neither Unicode nor ISO-8859-1 (otherwise it is set to
-   *   FT_ENCODING_UNICODE).  Use @FT_Get_BDF_Charset_ID to find out
-   *   which encoding is really present.  If, for example, the
-   *   `cs_registry' field is `KOI8' and the `cs_encoding' field is `R',
-   *   the font is encoded in KOI8-R.
+   *   `FT_ENCODING_NONE` is set by the BDF and PCF drivers if the charmap is
+   *   neither Unicode nor ISO-8859-1 (otherwise it is set to
+   *   `FT_ENCODING_UNICODE`).  Use @FT_Get_BDF_Charset_ID to find out which
+   *   encoding is really present.  If, for example, the `cs_registry` field
+   *   is 'KOI8' and the `cs_encoding` field is 'R', the font is encoded in
+   *   KOI8-R.
    *
-   *   FT_ENCODING_NONE is always set (with a single exception) by the
-   *   winfonts driver.  Use @FT_Get_WinFNT_Header and examine the
-   *   `charset' field of the @FT_WinFNT_HeaderRec structure to find out
-   *   which encoding is really present.  For example,
-   *   @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for
-   *   Russian).
+   *   `FT_ENCODING_NONE` is always set (with a single exception) by the
+   *   winfonts driver.  Use @FT_Get_WinFNT_Header and examine the `charset`
+   *   field of the @FT_WinFNT_HeaderRec structure to find out which encoding
+   *   is really present.  For example, @FT_WinFNT_ID_CP1251 (204) means
+   *   Windows code page 1251 (for Russian).
    *
-   *   FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH
-   *   and `encoding_id' is not `TT_MAC_ID_ROMAN' (otherwise it is set to
-   *   FT_ENCODING_APPLE_ROMAN).
+   *   `FT_ENCODING_NONE` is set if `platform_id` is @TT_PLATFORM_MACINTOSH
+   *   and `encoding_id` is not `TT_MAC_ID_ROMAN` (otherwise it is set to
+   *   `FT_ENCODING_APPLE_ROMAN`).
    *
-   *   If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function
-   *   @FT_Get_CMap_Language_ID to query the Mac language ID that may
-   *   be needed to be able to distinguish Apple encoding variants.  See
+   *   If `platform_id` is @TT_PLATFORM_MACINTOSH, use the function
+   *   @FT_Get_CMap_Language_ID to query the Mac language ID that may be
+   *   needed to be able to distinguish Apple encoding variants.  See
    *
    *     https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt
    *
-   *   to get an idea how to do that.  Basically, if the language ID
-   *   is~0, don't use it, otherwise subtract 1 from the language ID.
-   *   Then examine `encoding_id'.  If, for example, `encoding_id' is
-   *   `TT_MAC_ID_ROMAN' and the language ID (minus~1) is
-   *   `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman.
-   *   `TT_MAC_ID_ARABIC' with `TT_MAC_LANGID_FARSI' means the Farsi
-   *   variant the Arabic encoding.
+   *   to get an idea how to do that.  Basically, if the language ID is~0,
+   *   don't use it, otherwise subtract 1 from the language ID.  Then examine
+   *   `encoding_id`.  If, for example, `encoding_id` is `TT_MAC_ID_ROMAN`
+   *   and the language ID (minus~1) is `TT_MAC_LANGID_GREEK`, it is the
+   *   Greek encoding, not Roman.  `TT_MAC_ID_ARABIC` with
+   *   `TT_MAC_LANGID_FARSI` means the Farsi variant of the Arabic encoding.
    */
   typedef enum  FT_Encoding_
   {
@@ -802,7 +814,7 @@
   } FT_Encoding;
 
 
-  /* these constants are deprecated; use the corresponding `FT_Encoding' */
+  /* these constants are deprecated; use the corresponding `FT_Encoding` */
   /* values instead                                                      */
 #define ft_encoding_none            FT_ENCODING_NONE
 #define ft_encoding_unicode         FT_ENCODING_UNICODE
@@ -834,14 +846,13 @@
    *     A handle to the parent face object.
    *
    *   encoding ::
-   *     An @FT_Encoding tag identifying the charmap.  Use
-   *     this with @FT_Select_Charmap.
+   *     An @FT_Encoding tag identifying the charmap.  Use this with
+   *     @FT_Select_Charmap.
    *
    *   platform_id ::
-   *     An ID number describing the platform for the
-   *     following encoding ID.  This comes directly from
-   *     the TrueType specification and gets emulated for
-   *     other formats.
+   *     An ID number describing the platform for the following encoding ID.
+   *     This comes directly from the TrueType specification and gets
+   *     emulated for other formats.
    *
    *   encoding_id ::
    *     A platform-specific encoding number.  This also comes from the
@@ -872,11 +883,11 @@
    *   FT_Face_Internal
    *
    * @description:
-   *   An opaque handle to an `FT_Face_InternalRec' structure that models
-   *   the private data of a given @FT_Face object.
+   *   An opaque handle to an `FT_Face_InternalRec` structure that models the
+   *   private data of a given @FT_Face object.
    *
-   *   This structure might change between releases of FreeType~2 and is
-   *   not generally available to client applications.
+   *   This structure might change between releases of FreeType~2 and is not
+   *   generally available to client applications.
    */
   typedef struct FT_Face_InternalRec_*  FT_Face_Internal;
 
@@ -887,107 +898,89 @@
    *   FT_FaceRec
    *
    * @description:
-   *   FreeType root face class structure.  A face object models a
-   *   typeface in a font file.
+   *   FreeType root face class structure.  A face object models a typeface
+   *   in a font file.
    *
    * @fields:
    *   num_faces ::
-   *     The number of faces in the font file.  Some
-   *     font formats can have multiple faces in
-   *     a single font file.
+   *     The number of faces in the font file.  Some font formats can have
+   *     multiple faces in a single font file.
    *
    *   face_index ::
-   *     This field holds two different values.
-   *     Bits 0-15 are the index of the face in the
-   *     font file (starting with value~0).  They
-   *     are set to~0 if there is only one face in
-   *     the font file.
+   *     This field holds two different values.  Bits 0-15 are the index of
+   *     the face in the font file (starting with value~0).  They are set
+   *     to~0 if there is only one face in the font file.
    *
-   *     [Since 2.6.1] Bits 16-30 are relevant to GX
-   *     and OpenType variation fonts only, holding
-   *     the named instance index for the current
-   *     face index (starting with value~1; value~0
-   *     indicates font access without a named
-   *     instance).  For non-variation fonts, bits
-   *     16-30 are ignored.  If we have the third
-   *     named instance of face~4, say, `face_index'
-   *     is set to 0x00030004.
+   *     [Since 2.6.1] Bits 16-30 are relevant to GX and OpenType variation
+   *     fonts only, holding the named instance index for the current face
+   *     index (starting with value~1; value~0 indicates font access without
+   *     a named instance).  For non-variation fonts, bits 16-30 are ignored.
+   *     If we have the third named instance of face~4, say, `face_index` is
+   *     set to 0x00030004.
    *
-   *     Bit 31 is always zero (this is,
-   *     `face_index' is always a positive value).
+   *     Bit 31 is always zero (this is, `face_index` is always a positive
+   *     value).
    *
-   *     [Since 2.9] Changing the design coordinates
-   *     with @FT_Set_Var_Design_Coordinates or
-   *     @FT_Set_Var_Blend_Coordinates does not
-   *     influence the named instance index value
-   *     (only @FT_Set_Named_Instance does that).
+   *     [Since 2.9] Changing the design coordinates with
+   *     @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does
+   *     not influence the named instance index value (only
+   *     @FT_Set_Named_Instance does that).
    *
    *   face_flags ::
-   *     A set of bit flags that give important
-   *     information about the face; see
-   *     @FT_FACE_FLAG_XXX for the details.
+   *     A set of bit flags that give important information about the face;
+   *     see @FT_FACE_FLAG_XXX for the details.
    *
    *   style_flags ::
-   *     The lower 16~bits contain a set of bit
-   *     flags indicating the style of the face; see
-   *     @FT_STYLE_FLAG_XXX for the details.
+   *     The lower 16~bits contain a set of bit flags indicating the style of
+   *     the face; see @FT_STYLE_FLAG_XXX for the details.
    *
-   *     [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 a
-   *     positive value).  Note that a variation
-   *     font has always at least one named
-   *     instance, namely the default instance.
+   *     [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
+   *     a positive value).  Note that a variation font has always at least
+   *     one named instance, namely the default instance.
    *
    *   num_glyphs ::
-   *     The number of glyphs in the face.  If the
-   *     face is scalable and has sbits (see
-   *     `num_fixed_sizes'), it is set to the number
-   *     of outline glyphs.
+   *     The number of glyphs in the face.  If the face is scalable and has
+   *     sbits (see `num_fixed_sizes`), it is set to the number of outline
+   *     glyphs.
    *
-   *     For CID-keyed fonts (not in an SFNT
-   *     wrapper) this value gives the highest CID
-   *     used in the font.
+   *     For CID-keyed fonts (not in an SFNT wrapper) this value gives the
+   *     highest CID used in the font.
    *
    *   family_name ::
    *     The face's family name.  This is an ASCII string, usually in
-   *     English, that describes the typeface's family (like `Times New
-   *     Roman', `Bodoni', `Garamond', etc).  This is a least common
+   *     English, that describes the typeface's family (like 'Times New
+   *     Roman', 'Bodoni', 'Garamond', etc).  This is a least common
    *     denominator used to list fonts.  Some formats (TrueType & OpenType)
-   *     provide localized and Unicode versions of this string.
-   *     Applications should use the format-specific interface to access
-   *     them.  Can be NULL (e.g., in fonts embedded in a PDF file).
+   *     provide localized and Unicode versions of this string.  Applications
+   *     should use the format-specific interface to access them.  Can be
+   *     `NULL` (e.g., in fonts embedded in a PDF file).
    *
-   *     In case the font doesn't provide a specific
-   *     family name entry, FreeType tries to
-   *     synthesize one, deriving it from other name
+   *     In case the font doesn't provide a specific family name entry,
+   *     FreeType tries to synthesize one, deriving it from other name
    *     entries.
    *
    *   style_name ::
-   *     The face's style name.  This is an ASCII string, usually in
-   *     English, that describes the typeface's style (like `Italic',
-   *     `Bold', `Condensed', etc).  Not all font formats provide a style
-   *     name, so this field is optional, and can be set to NULL.  As for
-   *     `family_name', some formats provide localized and Unicode versions
+   *     The face's style name.  This is an ASCII string, usually in English,
+   *     that describes the typeface's style (like 'Italic', 'Bold',
+   *     'Condensed', etc).  Not all font formats provide a style name, so
+   *     this field is optional, and can be set to `NULL`.  As for
+   *     `family_name`, some formats provide localized and Unicode versions
    *     of this string.  Applications should use the format-specific
    *     interface to access them.
    *
    *   num_fixed_sizes ::
-   *     The number of bitmap strikes in the face.
-   *     Even if the face is scalable, there might
-   *     still be bitmap strikes, which are called
-   *     `sbits' in that case.
+   *     The number of bitmap strikes in the face.  Even if the face is
+   *     scalable, there might still be bitmap strikes, which are called
+   *     'sbits' in that case.
    *
    *   available_sizes ::
-   *     An array of @FT_Bitmap_Size for all bitmap
-   *     strikes in the face.  It is set to NULL if
-   *     there is no bitmap strike.
+   *     An array of @FT_Bitmap_Size for all bitmap strikes in the face.  It
+   *     is set to `NULL` if there is no bitmap strike.
    *
-   *     Note that FreeType tries to sanitize the
-   *     strike data since they are sometimes sloppy
-   *     or incorrect, but this can easily fail.
+   *     Note that FreeType tries to sanitize the strike data since they are
+   *     sometimes sloppy or incorrect, but this can easily fail.
    *
    *   num_charmaps ::
    *     The number of charmaps in the face.
@@ -996,80 +989,65 @@
    *     An array of the charmaps of the face.
    *
    *   generic ::
-   *     A field reserved for client uses.  See the
-   *     @FT_Generic type description.
+   *     A field reserved for client uses.  See the @FT_Generic type
+   *     description.
    *
    *   bbox ::
-   *     The font bounding box.  Coordinates are
-   *     expressed in font units (see
-   *     `units_per_EM').  The box is large enough
-   *     to contain any glyph from the font.  Thus,
-   *     `bbox.yMax' can be seen as the `maximum
-   *     ascender', and `bbox.yMin' as the `minimum
-   *     descender'.  Only relevant for scalable
-   *     formats.
+   *     The font bounding box.  Coordinates are expressed in font units (see
+   *     `units_per_EM`).  The box is large enough to contain any glyph from
+   *     the font.  Thus, `bbox.yMax` can be seen as the 'maximum ascender',
+   *     and `bbox.yMin` as the 'minimum descender'.  Only relevant for
+   *     scalable formats.
    *
-   *     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 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
+   *     and should only be used in relation to the default instance.
    *
    *   units_per_EM ::
-   *     The number of font units per EM square for
-   *     this face.  This is typically 2048 for
-   *     TrueType fonts, and 1000 for Type~1 fonts.
-   *     Only relevant for scalable formats.
+   *     The number of font units per EM square for this face.  This is
+   *     typically 2048 for TrueType fonts, and 1000 for Type~1 fonts.  Only
+   *     relevant for scalable formats.
    *
    *   ascender ::
-   *     The typographic ascender of the face,
-   *     expressed in font units.  For font formats
-   *     not having this information, it is set to
-   *     `bbox.yMax'.  Only relevant for scalable
-   *     formats.
+   *     The typographic ascender of the face, expressed in font units.  For
+   *     font formats not having this information, it is set to `bbox.yMax`.
+   *     Only relevant for scalable formats.
    *
    *   descender ::
-   *     The typographic descender of the face,
-   *     expressed in font units.  For font formats
-   *     not having this information, it is set to
-   *     `bbox.yMin'.  Note that this field is
-   *     negative for values below the baseline.
+   *     The typographic descender of the face, expressed in font units.  For
+   *     font formats not having this information, it is set to `bbox.yMin`.
+   *     Note that this field is negative for values below the baseline.
    *     Only relevant for scalable formats.
    *
    *   height ::
-   *     This value is the vertical distance
-   *     between two consecutive baselines,
-   *     expressed in font units.  It is always
-   *     positive.  Only relevant for scalable
-   *     formats.
-   *
-   *     If you want the global glyph height, use
-   *     `ascender - descender'.
-   *
-   *   max_advance_width ::
-   *     The maximum advance width, in font units,
-   *     for all glyphs in this face.  This can be
-   *     used to make word wrapping computations
-   *     faster.  Only relevant for scalable
-   *     formats.
-   *
-   *   max_advance_height ::
-   *     The maximum advance height, in font units,
-   *     for all glyphs in this face.  This is only
-   *     relevant for vertical layouts, and is set
-   *     to `height' for fonts that do not provide
-   *     vertical metrics.  Only relevant for
-   *     scalable formats.
-   *
-   *   underline_position ::
-   *     The position, in font units, of the
-   *     underline line for this face.  It is the
-   *     center of the underlining stem.  Only
+   *     This value is the vertical distance between two consecutive
+   *     baselines, expressed in font units.  It is always positive.  Only
    *     relevant for scalable formats.
    *
-   *   underline_thickness ::
-   *     The thickness, in font units, of the
-   *     underline for this face.  Only relevant for
+   *     If you want the global glyph height, use `ascender - descender`.
+   *
+   *   max_advance_width ::
+   *     The maximum advance width, in font units, for all glyphs in this
+   *     face.  This can be used to make word wrapping computations faster.
+   *     Only relevant for scalable formats.
+   *
+   *   max_advance_height ::
+   *     The maximum advance height, in font units, for all glyphs in this
+   *     face.  This is only relevant for vertical layouts, and is set to
+   *     `height` for fonts that do not provide vertical metrics.  Only
+   *     relevant for scalable formats.
+   *
+   *   underline_position ::
+   *     The position, in font units, of the underline line for this face.
+   *     It is the center of the underlining stem.  Only relevant for
    *     scalable formats.
    *
+   *   underline_thickness ::
+   *     The thickness, in font units, of the underline for this face.  Only
+   *     relevant for scalable formats.
+   *
    *   glyph ::
    *     The face's associated glyph slot(s).
    *
@@ -1083,11 +1061,10 @@
    *   Fields may be changed after a call to @FT_Attach_File or
    *   @FT_Attach_Stream.
    *
-   *   For an OpenType variation font, the values of the following fields
-   *   can change after a call to @FT_Set_Var_Design_Coordinates (and
-   *   friends) if the font contains an `MVAR' table: `ascender',
-   *   `descender', `height', `underline_position', and
-   *   `underline_thickness'.
+   *   For an OpenType variation font, the values of the following fields can
+   *   change after a call to @FT_Set_Var_Design_Coordinates (and friends) if
+   *   the font contains an 'MVAR' table: `ascender`, `descender`, `height`,
+   *   `underline_position`, and `underline_thickness`.
    *
    *   Especially for TrueType fonts see also the documentation for
    *   @FT_Size_Metrics.
@@ -1113,7 +1090,7 @@
 
     FT_Generic        generic;
 
-    /*# The following member variables (down to `underline_thickness') */
+    /*# The following member variables (down to `underline_thickness`) */
     /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
     /*# for bitmap fonts.                                              */
     FT_BBox           bbox;
@@ -1157,9 +1134,9 @@
    *   FT_FACE_FLAG_XXX
    *
    * @description:
-   *   A list of bit flags used in the `face_flags' field of the
-   *   @FT_FaceRec structure.  They inform client applications of
-   *   properties of the corresponding face.
+   *   A list of bit flags used in the `face_flags` field of the @FT_FaceRec
+   *   structure.  They inform client applications of properties of the
+   *   corresponding face.
    *
    * @values:
    *   FT_FACE_FLAG_SCALABLE ::
@@ -1168,99 +1145,111 @@
    *     @FT_FACE_FLAG_FIXED_SIZES set.
    *
    *   FT_FACE_FLAG_FIXED_SIZES ::
-   *     The face contains bitmap strikes.  See also the
-   *     `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec.
+   *     The face contains bitmap strikes.  See also the `num_fixed_sizes`
+   *     and `available_sizes` fields of @FT_FaceRec.
    *
    *   FT_FACE_FLAG_FIXED_WIDTH ::
    *     The face contains fixed-width characters (like Courier, Lucida,
    *     MonoType, etc.).
    *
    *   FT_FACE_FLAG_SFNT ::
-   *     The face uses the SFNT storage scheme.  For now, this means
-   *     TrueType and OpenType.
+   *     The face uses the SFNT storage scheme.  For now, this means TrueType
+   *     and OpenType.
    *
    *   FT_FACE_FLAG_HORIZONTAL ::
-   *     The face contains horizontal glyph metrics.  This should be set
-   *     for all common formats.
+   *     The face contains horizontal glyph metrics.  This should be set for
+   *     all common formats.
    *
    *   FT_FACE_FLAG_VERTICAL ::
-   *     The face contains vertical glyph metrics.  This is only
-   *     available in some formats, not all of them.
+   *     The face contains vertical glyph metrics.  This is only available in
+   *     some formats, not all of them.
    *
    *   FT_FACE_FLAG_KERNING ::
-   *     The face contains kerning information.  If set, the kerning
-   *     distance can be retrieved using the function @FT_Get_Kerning.
-   *     Otherwise the function always return the vector (0,0).  Note
-   *     that FreeType doesn't handle kerning data from the SFNT `GPOS'
-   *     table (as present in many OpenType fonts).
+   *     The face contains kerning information.  If set, the kerning distance
+   *     can be retrieved using the function @FT_Get_Kerning.  Otherwise the
+   *     function always returns the vector (0,0).  Note that FreeType
+   *     doesn't handle kerning data from the SFNT 'GPOS' table (as present
+   *     in many OpenType fonts).
    *
    *   FT_FACE_FLAG_FAST_GLYPHS ::
    *     THIS FLAG IS DEPRECATED.  DO NOT USE OR TEST IT.
    *
    *   FT_FACE_FLAG_MULTIPLE_MASTERS ::
-   *     The face contains multiple masters and is capable of
-   *     interpolating between them.  Supported formats are Adobe MM,
-   *     TrueType GX, and OpenType variation fonts.
+   *     The face contains multiple masters and is capable of interpolating
+   *     between them.  Supported formats are Adobe MM, TrueType GX, and
+   *     OpenType variation fonts.
    *
    *     See section @multiple_masters for API details.
    *
    *   FT_FACE_FLAG_GLYPH_NAMES ::
    *     The face contains glyph names, which can be retrieved using
-   *     @FT_Get_Glyph_Name.  Note that some TrueType fonts contain
-   *     broken glyph name tables.  Use the function
-   *     @FT_Has_PS_Glyph_Names when needed.
+   *     @FT_Get_Glyph_Name.  Note that some TrueType fonts contain broken
+   *     glyph name tables.  Use the function @FT_Has_PS_Glyph_Names when
+   *     needed.
    *
    *   FT_FACE_FLAG_EXTERNAL_STREAM ::
    *     Used internally by FreeType to indicate that a face's stream was
-   *     provided by the client application and should not be destroyed
-   *     when @FT_Done_Face is called.  Don't read or test this flag.
+   *     provided by the client application and should not be destroyed when
+   *     @FT_Done_Face is called.  Don't read or test this flag.
    *
    *   FT_FACE_FLAG_HINTER ::
-   *     The font driver has a hinting machine of its own.  For example,
-   *     with TrueType fonts, it makes sense to use data from the SFNT
-   *     `gasp' table only if the native TrueType hinting engine (with
-   *     the bytecode interpreter) is available and active.
+   *     The font driver has a hinting machine of its own.  For example, with
+   *     TrueType fonts, it makes sense to use data from the SFNT 'gasp'
+   *     table only if the native TrueType hinting engine (with the bytecode
+   *     interpreter) is available and active.
    *
    *   FT_FACE_FLAG_CID_KEYED ::
-   *     The face is CID-keyed.  In that case, the face is not accessed
-   *     by glyph indices but by CID values.  For subsetted CID-keyed
-   *     fonts this has the consequence that not all index values are a
-   *     valid argument to @FT_Load_Glyph.  Only the CID values for which
-   *     corresponding glyphs in the subsetted font exist make
-   *     `FT_Load_Glyph' return successfully; in all other cases you get
-   *     an `FT_Err_Invalid_Argument' error.
+   *     The face is CID-keyed.  In that case, the face is not accessed by
+   *     glyph indices but by CID values.  For subsetted CID-keyed fonts this
+   *     has the consequence that not all index values are a valid argument
+   *     to @FT_Load_Glyph.  Only the CID values for which corresponding
+   *     glyphs in the subsetted font exist make `FT_Load_Glyph` return
+   *     successfully; in all other cases you get an
+   *     `FT_Err_Invalid_Argument` error.
    *
-   *     Note that CID-keyed fonts that are in an SFNT wrapper (this is,
-   *     all OpenType/CFF fonts) don't have this flag set since the
-   *     glyphs are accessed in the normal way (using contiguous
-   *     indices); the `CID-ness' isn't visible to the application.
+   *     Note that CID-keyed fonts that are in an SFNT wrapper (this is, all
+   *     OpenType/CFF fonts) don't have this flag set since the glyphs are
+   *     accessed in the normal way (using contiguous indices); the
+   *     'CID-ness' isn't visible to the application.
    *
    *   FT_FACE_FLAG_TRICKY ::
-   *     The face is `tricky', this is, it always needs the font format's
-   *     native hinting engine to get a reasonable result.  A typical
-   *     example is the old Chinese font `mingli.ttf' (but not
-   *     `mingliu.ttc') that uses TrueType bytecode instructions to move
-   *     and scale all of its subglyphs.
+   *     The face is 'tricky', this is, it always needs the font format's
+   *     native hinting engine to get a reasonable result.  A typical example
+   *     is the old Chinese font `mingli.ttf` (but not `mingliu.ttc`) that
+   *     uses TrueType bytecode instructions to move and scale all of its
+   *     subglyphs.
    *
    *     It is not possible to auto-hint such fonts using
-   *     @FT_LOAD_FORCE_AUTOHINT; it will also ignore
-   *     @FT_LOAD_NO_HINTING.  You have to set both @FT_LOAD_NO_HINTING
-   *     and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you
-   *     probably never want this except for demonstration purposes.
+   *     @FT_LOAD_FORCE_AUTOHINT; it will also ignore @FT_LOAD_NO_HINTING.
+   *     You have to set both @FT_LOAD_NO_HINTING and @FT_LOAD_NO_AUTOHINT to
+   *     really disable hinting; however, you probably never want this except
+   *     for demonstration purposes.
    *
    *     Currently, there are about a dozen TrueType fonts in the list of
-   *     tricky fonts; they are hard-coded in file `ttobjs.c'.
+   *     tricky fonts; they are hard-coded in file `ttobjs.c`.
    *
    *   FT_FACE_FLAG_COLOR ::
-   *     [Since 2.5.1] The face has color glyph tables.  See
-   *     @FT_LOAD_COLOR for more information.
+   *     [Since 2.5.1] The face has color glyph tables.  See @FT_LOAD_COLOR
+   *     for more information.
    *
    *   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, or @FT_Set_Var_Blend_Coordinates.
+   *     This flag is unset by a call to @FT_Set_Named_Instance.
+   *
+   *   FT_FACE_FLAG_SVG ::
+   *     [Since 2.12] The face has an 'SVG~' OpenType table.
+   *
+   *   FT_FACE_FLAG_SBIX ::
+   *     [Since 2.12] The face has an 'sbix' OpenType table *and* outlines.
+   *     For such fonts, @FT_FACE_FLAG_SCALABLE is not set by default to
+   *     retain backward compatibility.
+   *
+   *   FT_FACE_FLAG_SBIX_OVERLAY ::
+   *     [Since 2.12] The face has an 'sbix' OpenType table where outlines
+   *     should be drawn on top of bitmap strikes.
+   *
    */
 #define FT_FACE_FLAG_SCALABLE          ( 1L <<  0 )
 #define FT_FACE_FLAG_FIXED_SIZES       ( 1L <<  1 )
@@ -1278,26 +1267,29 @@
 #define FT_FACE_FLAG_TRICKY            ( 1L << 13 )
 #define FT_FACE_FLAG_COLOR             ( 1L << 14 )
 #define FT_FACE_FLAG_VARIATION         ( 1L << 15 )
+#define FT_FACE_FLAG_SVG               ( 1L << 16 )
+#define FT_FACE_FLAG_SBIX              ( 1L << 17 )
+#define FT_FACE_FLAG_SBIX_OVERLAY      ( 1L << 18 )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_HORIZONTAL
    *
    * @description:
-   *   A macro that returns true whenever a face object contains
-   *   horizontal metrics (this is true for all font formats though).
+   *   A macro that returns true whenever a face object contains horizontal
+   *   metrics (this is true for all font formats though).
    *
    * @also:
    *   @FT_HAS_VERTICAL can be used to check for vertical metrics.
    *
    */
 #define FT_HAS_HORIZONTAL( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_VERTICAL
@@ -1308,88 +1300,88 @@
    *
    */
 #define FT_HAS_VERTICAL( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_VERTICAL )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_KERNING
    *
    * @description:
-   *   A macro that returns true whenever a face object contains kerning
-   *   data that can be accessed with @FT_Get_Kerning.
+   *   A macro that returns true whenever a face object contains kerning data
+   *   that can be accessed with @FT_Get_Kerning.
    *
    */
 #define FT_HAS_KERNING( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_KERNING )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_KERNING ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_SCALABLE
    *
    * @description:
    *   A macro that returns true whenever a face object contains a scalable
-   *   font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF,
-   *   and PFR font formats).
+   *   font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, and
+   *   PFR font formats).
    *
    */
 #define FT_IS_SCALABLE( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_SCALABLE )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_SFNT
    *
    * @description:
-   *   A macro that returns true whenever a face object contains a font
-   *   whose format is based on the SFNT storage scheme.  This usually
-   *   means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded
-   *   bitmap fonts.
+   *   A macro that returns true whenever a face object contains a font whose
+   *   format is based on the SFNT storage scheme.  This usually means:
+   *   TrueType fonts, OpenType fonts, as well as SFNT-based embedded bitmap
+   *   fonts.
    *
    *   If this macro is true, all functions defined in @FT_SFNT_NAMES_H and
    *   @FT_TRUETYPE_TABLES_H are available.
    *
    */
 #define FT_IS_SFNT( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_SFNT )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_SFNT ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_FIXED_WIDTH
    *
    * @description:
    *   A macro that returns true whenever a face object contains a font face
-   *   that contains fixed-width (or `monospace', `fixed-pitch', etc.)
+   *   that contains fixed-width (or 'monospace', 'fixed-pitch', etc.)
    *   glyphs.
    *
    */
 #define FT_IS_FIXED_WIDTH( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_FIXED_SIZES
    *
    * @description:
    *   A macro that returns true whenever a face object contains some
-   *   embedded bitmaps.  See the `available_sizes' field of the
-   *   @FT_FaceRec structure.
+   *   embedded bitmaps.  See the `available_sizes` field of the @FT_FaceRec
+   *   structure.
    *
    */
 #define FT_HAS_FIXED_SIZES( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_FAST_GLYPHS
@@ -1401,7 +1393,7 @@
 #define FT_HAS_FAST_GLYPHS( face )  0
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_GLYPH_NAMES
@@ -1412,10 +1404,10 @@
    *
    */
 #define FT_HAS_GLYPH_NAMES( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_MULTIPLE_MASTERS
@@ -1427,10 +1419,10 @@
    *
    */
 #define FT_HAS_MULTIPLE_MASTERS( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_NAMED_INSTANCE
@@ -1449,17 +1441,17 @@
    *
    */
 #define FT_IS_NAMED_INSTANCE( face ) \
-          ( (face)->face_index & 0x7FFF0000L )
+          ( !!( (face)->face_index & 0x7FFF0000L ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_VARIATION
    *
    * @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
+   *   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.
    *
    * @since:
@@ -1467,56 +1459,173 @@
    *
    */
 #define FT_IS_VARIATION( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_VARIATION )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_VARIATION ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_CID_KEYED
    *
    * @description:
    *   A macro that returns true whenever a face object contains a CID-keyed
-   *   font.  See the discussion of @FT_FACE_FLAG_CID_KEYED for more
-   *   details.
+   *   font.  See the discussion of @FT_FACE_FLAG_CID_KEYED for more details.
    *
    *   If this macro is true, all functions defined in @FT_CID_H are
    *   available.
    *
    */
 #define FT_IS_CID_KEYED( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_IS_TRICKY
    *
    * @description:
-   *   A macro that returns true whenever a face represents a `tricky' font.
+   *   A macro that returns true whenever a face represents a 'tricky' font.
    *   See the discussion of @FT_FACE_FLAG_TRICKY for more details.
    *
    */
 #define FT_IS_TRICKY( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_TRICKY )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_TRICKY ) )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_HAS_COLOR
    *
    * @description:
-   *   A macro that returns true whenever a face object contains
-   *   tables for color glyphs.
+   *   A macro that returns true whenever a face object contains tables for
+   *   color glyphs.
    *
    * @since:
    *   2.5.1
    *
    */
 #define FT_HAS_COLOR( face ) \
-          ( (face)->face_flags & FT_FACE_FLAG_COLOR )
+          ( !!( (face)->face_flags & FT_FACE_FLAG_COLOR ) )
+
+
+  /**************************************************************************
+   *
+   * @macro:
+   *   FT_HAS_SVG
+   *
+   * @description:
+   *   A macro that returns true whenever a face object contains an 'SVG~'
+   *   OpenType table.
+   *
+   * @since:
+   *   2.12
+   */
+#define FT_HAS_SVG( face ) \
+          ( !!( (face)->face_flags & FT_FACE_FLAG_SVG ) )
+
+
+  /**************************************************************************
+   *
+   * @macro:
+   *   FT_HAS_SBIX
+   *
+   * @description:
+   *   A macro that returns true whenever a face object contains an 'sbix'
+   *   OpenType table *and* outline glyphs.
+   *
+   *   Currently, FreeType only supports bitmap glyphs in PNG format for this
+   *   table (i.e., JPEG and TIFF formats are unsupported, as are
+   *   Apple-specific formats not part of the OpenType specification).
+   *
+   * @note:
+   *   For backward compatibility, a font with an 'sbix' table is treated as
+   *   a bitmap-only face.  Using @FT_Open_Face with
+   *   @FT_PARAM_TAG_IGNORE_SBIX, an application can switch off 'sbix'
+   *   handling so that the face is treated as an ordinary outline font with
+   *   scalable outlines.
+   *
+   *   Here is some pseudo code that roughly illustrates how to implement
+   *   'sbix' handling according to the OpenType specification.
+   *
+   * ```
+   *   if ( FT_HAS_SBIX( face ) )
+   *   {
+   *     // open font as a scalable one without sbix handling
+   *     FT_Face       face2;
+   *     FT_Parameter  param = { FT_PARAM_TAG_IGNORE_SBIX, NULL };
+   *     FT_Open_Args  args  = { FT_OPEN_PARAMS | ...,
+   *                             ...,
+   *                             1, &param };
+   *
+   *
+   *     FT_Open_Face( library, &args, 0, &face2 );
+   *
+   *     <sort `face->available_size` as necessary into
+   *      `preferred_sizes`[*]>
+   *
+   *     for ( i = 0; i < face->num_fixed_sizes; i++ )
+   *     {
+   *       size = preferred_sizes[i].size;
+   *
+   *       error = FT_Set_Pixel_Sizes( face, size, size );
+   *       <error handling omitted>
+   *
+   *       // check whether we have a glyph in a bitmap strike
+   *       error = FT_Load_Glyph( face,
+   *                              glyph_index,
+   *                              FT_LOAD_SBITS_ONLY          |
+   *                              FT_LOAD_BITMAP_METRICS_ONLY );
+   *       if ( error == FT_Err_Invalid_Argument )
+   *         continue;
+   *       else if ( error )
+   *         <other error handling omitted>
+   *       else
+   *         break;
+   *     }
+   *
+   *     if ( i != face->num_fixed_sizes )
+   *       <load embedded bitmap with `FT_Load_Glyph`,
+   *        scale it, display it, etc.>
+   *
+   *     if ( i == face->num_fixed_sizes  ||
+   *          FT_HAS_SBIX_OVERLAY( face ) )
+   *       <use `face2` to load outline glyph with `FT_Load_Glyph`,
+   *        scale it, display it on top of the bitmap, etc.>
+   *   }
+   * ```
+   *
+   * [*] Assuming a target value of 400dpi and available strike sizes 100,
+   * 200, 300, and 400dpi, a possible order might be [400, 200, 300, 100]:
+   * scaling 200dpi to 400dpi usually gives better results than scaling
+   * 300dpi to 400dpi; it is also much faster.  However, scaling 100dpi to
+   * 400dpi can yield a too pixelated result, thus the preference might be
+   * 300dpi over 100dpi.
+   *
+   * @since:
+   *   2.12
+   */
+#define FT_HAS_SBIX( face ) \
+          ( !!( (face)->face_flags & FT_FACE_FLAG_SBIX ) )
+
+
+  /**************************************************************************
+   *
+   * @macro:
+   *   FT_HAS_SBIX_OVERLAY
+   *
+   * @description:
+   *   A macro that returns true whenever a face object contains an 'sbix'
+   *   OpenType table with bit~1 in its `flags` field set, instructing the
+   *   application to overlay the bitmap strike with the corresponding
+   *   outline glyph.  See @FT_HAS_SBIX for pseudo code how to use it.
+   *
+   * @since:
+   *   2.12
+   */
+#define FT_HAS_SBIX_OVERLAY( face ) \
+          ( !!( (face)->face_flags & FT_FACE_FLAG_SBIX_OVERLAY ) )
 
 
   /**************************************************************************
@@ -1525,8 +1634,8 @@
    *   FT_STYLE_FLAG_XXX
    *
    * @description:
-   *   A list of bit flags to indicate the style of a given face.  These
-   *   are used in the `style_flags' field of @FT_FaceRec.
+   *   A list of bit flags to indicate the style of a given face.  These are
+   *   used in the `style_flags` field of @FT_FaceRec.
    *
    * @values:
    *   FT_STYLE_FLAG_ITALIC ::
@@ -1537,9 +1646,9 @@
    *
    * @note:
    *   The style information as provided by FreeType is very basic.  More
-   *   details are beyond the scope and should be done on a higher level
-   *   (for example, by analyzing various fields of the `OS/2' table in
-   *   SFNT based fonts).
+   *   details are beyond the scope and should be done on a higher level (for
+   *   example, by analyzing various fields of the 'OS/2' table in SFNT based
+   *   fonts).
    */
 #define FT_STYLE_FLAG_ITALIC  ( 1 << 0 )
 #define FT_STYLE_FLAG_BOLD    ( 1 << 1 )
@@ -1551,8 +1660,8 @@
    *   FT_Size_Internal
    *
    * @description:
-   *   An opaque handle to an `FT_Size_InternalRec' structure, used to
-   *   model private data of a given @FT_Size object.
+   *   An opaque handle to an `FT_Size_InternalRec` structure, used to model
+   *   private data of a given @FT_Size object.
    */
   typedef struct FT_Size_InternalRec_*  FT_Size_Internal;
 
@@ -1567,89 +1676,80 @@
    *
    * @fields:
    *   x_ppem ::
-   *     The width of the scaled EM square in pixels, hence
-   *     the term `ppem' (pixels per EM).  It is also
-   *     referred to as `nominal width'.
+   *     The width of the scaled EM square in pixels, hence the term 'ppem'
+   *     (pixels per EM).  It is also referred to as 'nominal width'.
    *
    *   y_ppem ::
-   *     The height of the scaled EM square in pixels,
-   *     hence the term `ppem' (pixels per EM).  It is also
-   *     referred to as `nominal height'.
+   *     The height of the scaled EM square in pixels, hence the term 'ppem'
+   *     (pixels per EM).  It is also referred to as 'nominal height'.
    *
    *   x_scale ::
-   *     A 16.16 fractional scaling value to convert
-   *     horizontal metrics from font units to 26.6
-   *     fractional pixels.  Only relevant for scalable
+   *     A 16.16 fractional scaling value to convert horizontal metrics from
+   *     font units to 26.6 fractional pixels.  Only relevant for scalable
    *     font formats.
    *
    *   y_scale ::
-   *     A 16.16 fractional scaling value to convert
-   *     vertical metrics from font units to 26.6
-   *     fractional pixels.  Only relevant for scalable
+   *     A 16.16 fractional scaling value to convert vertical metrics from
+   *     font units to 26.6 fractional pixels.  Only relevant for scalable
    *     font formats.
    *
    *   ascender ::
-   *     The ascender in 26.6 fractional pixels, rounded up
-   *     to an integer value.  See @FT_FaceRec for the
-   *     details.
+   *     The ascender in 26.6 fractional pixels, rounded up to an integer
+   *     value.  See @FT_FaceRec for the details.
    *
    *   descender ::
-   *     The descender in 26.6 fractional pixels, rounded
-   *     down to an integer value.  See @FT_FaceRec for the
-   *     details.
+   *     The descender in 26.6 fractional pixels, rounded down to an integer
+   *     value.  See @FT_FaceRec for the details.
    *
    *   height ::
-   *     The height in 26.6 fractional pixels, rounded to
-   *     an integer value.  See @FT_FaceRec for the
-   *     details.
+   *     The height in 26.6 fractional pixels, rounded to an integer value.
+   *     See @FT_FaceRec for the details.
    *
    *   max_advance ::
-   *     The maximum advance width in 26.6 fractional
-   *     pixels, rounded to an integer value.  See
-   *     @FT_FaceRec for the details.
+   *     The maximum advance width in 26.6 fractional pixels, rounded to an
+   *     integer value.  See @FT_FaceRec for the details.
    *
    * @note:
-   *   The scaling values, if relevant, are determined first during a
-   *   size changing operation.  The remaining fields are then set by the
-   *   driver.  For scalable formats, they are usually set to scaled
-   *   values of the corresponding fields in @FT_FaceRec.  Some values
-   *   like ascender or descender are rounded for historical reasons;
-   *   more precise values (for outline fonts) can be derived by scaling
-   *   the corresponding @FT_FaceRec values manually, with code similar
-   *   to the following.
+   *   The scaling values, if relevant, are determined first during a size
+   *   changing operation.  The remaining fields are then set by the driver.
+   *   For scalable formats, they are usually set to scaled values of the
+   *   corresponding fields in @FT_FaceRec.  Some values like ascender or
+   *   descender are rounded for historical reasons; more precise values (for
+   *   outline fonts) can be derived by scaling the corresponding @FT_FaceRec
+   *   values manually, with code similar to the following.
    *
-   *   {
+   *   ```
    *     scaled_ascender = FT_MulFix( face->ascender,
    *                                  size_metrics->y_scale );
-   *   }
+   *   ```
    *
-   *   Note that due to glyph hinting and the selected rendering mode
-   *   these values are usually not exact; consequently, they must be
-   *   treated as unreliable with an error margin of at least one pixel!
+   *   Note that due to glyph hinting and the selected rendering mode these
+   *   values are usually not exact; consequently, they must be treated as
+   *   unreliable with an error margin of at least one pixel!
    *
    *   Indeed, the only way to get the exact metrics is to render _all_
    *   glyphs.  As this would be a definite performance hit, it is up to
    *   client applications to perform such computations.
    *
-   *   The `FT_Size_Metrics' structure is valid for bitmap fonts also.
+   *   The `FT_Size_Metrics` structure is valid for bitmap fonts also.
    *
    *
-   *   *TrueType* *fonts* *with* *native* *bytecode* *hinting*
+   *   **TrueType fonts with native bytecode hinting**
    *
-   *   All applications that handle TrueType fonts with native hinting
-   *   must be aware that TTFs expect different rounding of vertical font
-   *   dimensions.  The application has to cater for this, especially if
-   *   it wants to rely on a TTF's vertical data (for example, to
-   *   properly align box characters vertically).
+   *   All applications that handle TrueType fonts with native hinting must
+   *   be aware that TTFs expect different rounding of vertical font
+   *   dimensions.  The application has to cater for this, especially if it
+   *   wants to rely on a TTF's vertical data (for example, to properly align
+   *   box characters vertically).
    *
-   *   Only the application knows _in_ _advance_ that it is going to use
-   *   native hinting for TTFs!  FreeType, on the other hand, selects the
-   *   hinting mode not at the time of creating an @FT_Size object but
-   *   much later, namely while calling @FT_Load_Glyph.
+   *   Only the application knows _in advance_ that it is going to use native
+   *   hinting for TTFs!  FreeType, on the other hand, selects the hinting
+   *   mode not at the time of creating an @FT_Size object but much later,
+   *   namely while calling @FT_Load_Glyph.
    *
    *   Here is some pseudo code that illustrates a possible solution.
    *
-   *   {
+   *   ```
    *     font_format = FT_Get_Font_Format( face );
    *
    *     if ( !strcmp( font_format, "TrueType" ) &&
@@ -1668,7 +1768,7 @@
    *
    *     height      = size_metrics->height;
    *     max_advance = size_metrics->max_advance;
-   *   }
+   *   ```
    */
   typedef struct  FT_Size_Metrics_
   {
@@ -1700,10 +1800,9 @@
    *     Handle to the parent face object.
    *
    *   generic ::
-   *     A typeless pointer, unused by the FreeType library or
-   *     any of its drivers.  It can be used by client
-   *     applications to link their own data to each size
-   *     object.
+   *     A typeless pointer, unused by the FreeType library or any of its
+   *     drivers.  It can be used by client applications to link their own
+   *     data to each size object.
    *
    *   metrics ::
    *     Metrics for this size object.  This field is read-only.
@@ -1728,8 +1827,8 @@
    *   subglyphs (for example, in the case of composites).
    *
    * @note:
-   *   The subglyph implementation is not part of the high-level API,
-   *   hence the forward structure declaration.
+   *   The subglyph implementation is not part of the high-level API, hence
+   *   the forward structure declaration.
    *
    *   You can however retrieve subglyph information with
    *   @FT_Get_SubGlyph_Info.
@@ -1743,8 +1842,8 @@
    *   FT_Slot_Internal
    *
    * @description:
-   *   An opaque handle to an `FT_Slot_InternalRec' structure, used to
-   *   model private data of a given @FT_GlyphSlot object.
+   *   An opaque handle to an `FT_Slot_InternalRec` structure, used to model
+   *   private data of a given @FT_GlyphSlot object.
    */
   typedef struct FT_Slot_InternalRec_*  FT_Slot_Internal;
 
@@ -1755,164 +1854,145 @@
    *   FT_GlyphSlotRec
    *
    * @description:
-   *   FreeType root glyph slot class structure.  A glyph slot is a
-   *   container where individual glyphs can be loaded, be they in
-   *   outline or bitmap format.
+   *   FreeType root glyph slot class structure.  A glyph slot is a container
+   *   where individual glyphs can be loaded, be they in outline or bitmap
+   *   format.
    *
    * @fields:
    *   library ::
-   *     A handle to the FreeType library instance
-   *     this slot belongs to.
+   *     A handle to the FreeType library instance this slot belongs to.
    *
    *   face ::
    *     A handle to the parent face object.
    *
    *   next ::
-   *     In some cases (like some font tools), several
-   *     glyph slots per face object can be a good
-   *     thing.  As this is rare, the glyph slots are
-   *     listed through a direct, single-linked list
-   *     using its `next' field.
+   *     In some cases (like some font tools), several glyph slots per face
+   *     object can be a good thing.  As this is rare, the glyph slots are
+   *     listed through a direct, single-linked list using its `next` field.
    *
    *   glyph_index ::
-   *     The glyph index passed as an argument to @FT_Load_Glyph while
-   *     initializeing the glyph slot (since FreeType version 2.10).
+   *     [Since 2.10] The glyph index passed as an argument to @FT_Load_Glyph
+   *     while initializing the glyph slot.
    *
    *   generic ::
-   *     A typeless pointer unused by the FreeType
-   *     library or any of its drivers.  It can be
-   *     used by client applications to link their own
+   *     A typeless pointer unused by the FreeType library or any of its
+   *     drivers.  It can be used by client applications to link their own
    *     data to each glyph slot object.
    *
    *   metrics ::
-   *     The metrics of the last loaded glyph in the
-   *     slot.  The returned values depend on the last
-   *     load flags (see the @FT_Load_Glyph API
-   *     function) and can be expressed either in 26.6
-   *     fractional pixels or font units.
+   *     The metrics of the last loaded glyph in the slot.  The returned
+   *     values depend on the last load flags (see the @FT_Load_Glyph API
+   *     function) and can be expressed either in 26.6 fractional pixels or
+   *     font units.
    *
-   *     Note that even when the glyph image is
-   *     transformed, the metrics are not.
+   *     Note that even when the glyph image is transformed, the metrics are
+   *     not.
    *
    *   linearHoriAdvance ::
-   *     The advance width of the unhinted glyph.
-   *     Its value is expressed in 16.16 fractional
-   *     pixels, unless @FT_LOAD_LINEAR_DESIGN is set
-   *     when loading the glyph.  This field can be
-   *     important to perform correct WYSIWYG layout.
-   *     Only relevant for outline glyphs.
+   *     The advance width of the unhinted glyph.  Its value is expressed in
+   *     16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when
+   *     loading the glyph.  This field can be important to perform correct
+   *     WYSIWYG layout.  Only relevant for scalable glyphs.
    *
    *   linearVertAdvance ::
-   *     The advance height of the unhinted glyph.
-   *     Its value is expressed in 16.16 fractional
-   *     pixels, unless @FT_LOAD_LINEAR_DESIGN is set
-   *     when loading the glyph.  This field can be
-   *     important to perform correct WYSIWYG layout.
-   *     Only relevant for outline glyphs.
+   *     The advance height of the unhinted glyph.  Its value is expressed in
+   *     16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when
+   *     loading the glyph.  This field can be important to perform correct
+   *     WYSIWYG layout.  Only relevant for scalable glyphs.
    *
    *   advance ::
-   *     This shorthand is, depending on
-   *     @FT_LOAD_IGNORE_TRANSFORM, the transformed
-   *     (hinted) advance width for the glyph, in 26.6
-   *     fractional pixel format.  As specified with
-   *     @FT_LOAD_VERTICAL_LAYOUT, it uses either the
-   *     `horiAdvance' or the `vertAdvance' value of
-   *     `metrics' field.
+   *     This shorthand is, depending on @FT_LOAD_IGNORE_TRANSFORM, the
+   *     transformed (hinted) advance width for the glyph, in 26.6 fractional
+   *     pixel format.  As specified with @FT_LOAD_VERTICAL_LAYOUT, it uses
+   *     either the `horiAdvance` or the `vertAdvance` value of `metrics`
+   *     field.
    *
    *   format ::
-   *     This field indicates the format of the image
-   *     contained in the glyph slot.  Typically
-   *     @FT_GLYPH_FORMAT_BITMAP,
-   *     @FT_GLYPH_FORMAT_OUTLINE, or
-   *     @FT_GLYPH_FORMAT_COMPOSITE, but other values
-   *     are possible.
+   *     This field indicates the format of the image contained in the glyph
+   *     slot.  Typically @FT_GLYPH_FORMAT_BITMAP, @FT_GLYPH_FORMAT_OUTLINE,
+   *     or @FT_GLYPH_FORMAT_COMPOSITE, but other values are possible.
    *
    *   bitmap ::
-   *     This field is used as a bitmap descriptor.
-   *     Note that the address and content of the
-   *     bitmap buffer can change between calls of
+   *     This field is used as a bitmap descriptor.  Note that the address
+   *     and content of the bitmap buffer can change between calls of
    *     @FT_Load_Glyph and a few other functions.
    *
    *   bitmap_left ::
-   *     The bitmap's left bearing expressed in
-   *     integer pixels.
+   *     The bitmap's left bearing expressed in integer pixels.
    *
    *   bitmap_top ::
-   *     The bitmap's top bearing expressed in integer
-   *     pixels.  This is the distance from the
-   *     baseline to the top-most glyph scanline,
-   *     upwards y~coordinates being *positive*.
+   *     The bitmap's top bearing expressed in integer pixels.  This is the
+   *     distance from the baseline to the top-most glyph scanline, upwards
+   *     y~coordinates being **positive**.
    *
    *   outline ::
-   *     The outline descriptor for the current glyph
-   *     image if its format is
-   *     @FT_GLYPH_FORMAT_OUTLINE.  Once a glyph is
-   *     loaded, `outline' can be transformed,
-   *     distorted, emboldened, etc.  However, it must
-   *     not be freed.
+   *     The outline descriptor for the current glyph image if its format is
+   *     @FT_GLYPH_FORMAT_OUTLINE.  Once a glyph is loaded, `outline` can be
+   *     transformed, distorted, emboldened, etc.  However, it must not be
+   *     freed.
+   *
+   *     [Since 2.10.1] If @FT_LOAD_NO_SCALE is set, outline coordinates of
+   *     OpenType variation fonts for a selected instance are internally
+   *     handled as 26.6 fractional font units but returned as (rounded)
+   *     integers, as expected.  To get unrounded font units, don't use
+   *     @FT_LOAD_NO_SCALE but load the glyph with @FT_LOAD_NO_HINTING and
+   *     scale it, using the font's `units_per_EM` value as the ppem.
    *
    *   num_subglyphs ::
-   *     The number of subglyphs in a composite glyph.
-   *     This field is only valid for the composite
-   *     glyph format that should normally only be
+   *     The number of subglyphs in a composite glyph.  This field is only
+   *     valid for the composite glyph format that should normally only be
    *     loaded with the @FT_LOAD_NO_RECURSE flag.
    *
    *   subglyphs ::
-   *     An array of subglyph descriptors for
-   *     composite glyphs.  There are `num_subglyphs'
-   *     elements in there.  Currently internal to
-   *     FreeType.
+   *     An array of subglyph descriptors for composite glyphs.  There are
+   *     `num_subglyphs` elements in there.  Currently internal to FreeType.
    *
    *   control_data ::
-   *     Certain font drivers can also return the
-   *     control data for a given glyph image (e.g.
-   *     TrueType bytecode, Type~1 charstrings, etc.).
-   *     This field is a pointer to such data; it is
-   *     currently internal to FreeType.
+   *     Certain font drivers can also return the control data for a given
+   *     glyph image (e.g.  TrueType bytecode, Type~1 charstrings, etc.).
+   *     This field is a pointer to such data; it is currently internal to
+   *     FreeType.
    *
    *   control_len ::
-   *     This is the length in bytes of the control
-   *     data.  Currently internal to FreeType.
+   *     This is the length in bytes of the control data.  Currently internal
+   *     to FreeType.
    *
    *   other ::
    *     Reserved.
    *
    *   lsb_delta ::
-   *     The difference between hinted and unhinted
-   *     left side bearing while auto-hinting is
-   *     active.  Zero otherwise.
+   *     The difference between hinted and unhinted left side bearing while
+   *     auto-hinting is active.  Zero otherwise.
    *
    *   rsb_delta ::
-   *     The difference between hinted and unhinted
-   *     right side bearing while auto-hinting is
-   *     active.  Zero otherwise.
+   *     The difference between hinted and unhinted right side bearing while
+   *     auto-hinting is active.  Zero otherwise.
    *
    * @note:
-   *   If @FT_Load_Glyph is called with default flags (see
-   *   @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in
-   *   its native format (e.g., an outline glyph for TrueType and Type~1
-   *   formats).  [Since 2.9] The prospective bitmap metrics are
-   *   calculated according to @FT_LOAD_TARGET_XXX and other flags even
-   *   for the outline glyph, even if @FT_LOAD_RENDER is not set.
+   *   If @FT_Load_Glyph is called with default flags (see @FT_LOAD_DEFAULT)
+   *   the glyph image is loaded in the glyph slot in its native format
+   *   (e.g., an outline glyph for TrueType and Type~1 formats).  [Since 2.9]
+   *   The prospective bitmap metrics are calculated according to
+   *   @FT_LOAD_TARGET_XXX and other flags even for the outline glyph, even
+   *   if @FT_LOAD_RENDER is not set.
    *
    *   This image can later be converted into a bitmap by calling
-   *   @FT_Render_Glyph.  This function searches the current renderer for
-   *   the native image's format, then invokes it.
+   *   @FT_Render_Glyph.  This function searches the current renderer for the
+   *   native image's format, then invokes it.
    *
-   *   The renderer is in charge of transforming the native image through
-   *   the slot's face transformation fields, then converting it into a
-   *   bitmap that is returned in `slot->bitmap'.
+   *   The renderer is in charge of transforming the native image through the
+   *   slot's face transformation fields, then converting it into a bitmap
+   *   that is returned in `slot->bitmap`.
    *
-   *   Note that `slot->bitmap_left' and `slot->bitmap_top' are also used
-   *   to specify the position of the bitmap relative to the current pen
+   *   Note that `slot->bitmap_left` and `slot->bitmap_top` are also used to
+   *   specify the position of the bitmap relative to the current pen
    *   position (e.g., coordinates (0,0) on the baseline).  Of course,
-   *   `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.
+   *   `slot->format` is also changed to @FT_GLYPH_FORMAT_BITMAP.
    *
-   *   Here is a small pseudo code fragment that shows how to use
-   *   `lsb_delta' and `rsb_delta' to do fractional positioning of
-   *   glyphs:
+   *   Here is a small pseudo code fragment that shows how to use `lsb_delta`
+   *   and `rsb_delta` to do fractional positioning of glyphs:
    *
-   *   {
+   *   ```
    *     FT_GlyphSlot  slot     = face->glyph;
    *     FT_Pos        origin_x = 0;
    *
@@ -1928,15 +2008,14 @@
    *        and add it to `origin_x'>
    *
    *       origin_x += slot->advance.x;
-   *       origin_x += slot->rsb_delta - slot->lsb_delta;
+   *       origin_x += slot->lsb_delta - slot->rsb_delta;
    *     endfor
-   *   }
+   *   ```
    *
    *   Here is another small pseudo code fragment that shows how to use
-   *   `lsb_delta' and `rsb_delta' to improve integer positioning of
-   *   glyphs:
+   *   `lsb_delta` and `rsb_delta` to improve integer positioning of glyphs:
    *
-   *   {
+   *   ```
    *     FT_GlyphSlot  slot           = face->glyph;
    *     FT_Pos        origin_x       = 0;
    *     FT_Pos        prev_rsb_delta = 0;
@@ -1959,13 +2038,13 @@
    *
    *       origin_x += slot->advance.x;
    *     endfor
-   *   }
+   *   ```
    *
-   *   If you use strong auto-hinting, you *must* apply these delta
-   *   values!  Otherwise you will experience far too large inter-glyph
-   *   spacing at small rendering sizes in most cases.  Note that it
-   *   doesn't harm to use the above code for other hinting modes also,
-   *   since the delta values are zero then.
+   *   If you use strong auto-hinting, you **must** apply these delta values!
+   *   Otherwise you will experience far too large inter-glyph spacing at
+   *   small rendering sizes in most cases.  Note that it doesn't harm to use
+   *   the above code for other hinting modes also, since the delta values
+   *   are zero then.
    */
   typedef struct  FT_GlyphSlotRec_
   {
@@ -2019,8 +2098,8 @@
    *   FT_Init_FreeType
    *
    * @description:
-   *   Initialize a new FreeType library object.  The set of modules
-   *   that are registered by this function is determined at build time.
+   *   Initialize a new FreeType library object.  The set of modules that are
+   *   registered by this function is determined at build time.
    *
    * @output:
    *   alibrary ::
@@ -2030,21 +2109,21 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   In case you want to provide your own memory allocating routines,
-   *   use @FT_New_Library instead, followed by a call to
-   *   @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module)
-   *   and @FT_Set_Default_Properties.
+   *   In case you want to provide your own memory allocating routines, use
+   *   @FT_New_Library instead, followed by a call to @FT_Add_Default_Modules
+   *   (or a series of calls to @FT_Add_Module) and
+   *   @FT_Set_Default_Properties.
    *
-   *   See the documentation of @FT_Library and @FT_Face for
-   *   multi-threading issues.
+   *   See the documentation of @FT_Library and @FT_Face for multi-threading
+   *   issues.
    *
    *   If you need reference-counting (cf. @FT_Reference_Library), use
    *   @FT_New_Library and @FT_Done_Library.
    *
-   *   If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is
-   *   set, this function reads the `FREETYPE_PROPERTIES' environment
-   *   variable to control driver properties.  See section @properties
-   *   for more.
+   *   If compilation option `FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES` is
+   *   set, this function reads the `FREETYPE_PROPERTIES` environment
+   *   variable to control driver properties.  See section @properties for
+   *   more.
    */
   FT_EXPORT( FT_Error )
   FT_Init_FreeType( FT_Library  *alibrary );
@@ -2076,7 +2155,7 @@
    *   FT_OPEN_XXX
    *
    * @description:
-   *   A list of bit field constants used within the `flags' field of the
+   *   A list of bit field constants used within the `flags` field of the
    *   @FT_Open_Args structure.
    *
    * @values:
@@ -2084,21 +2163,20 @@
    *     This is a memory-based stream.
    *
    *   FT_OPEN_STREAM ::
-   *     Copy the stream from the `stream' field.
+   *     Copy the stream from the `stream` field.
    *
    *   FT_OPEN_PATHNAME ::
-   *     Create a new input stream from a C~path
-   *     name.
+   *     Create a new input stream from a C~path name.
    *
    *   FT_OPEN_DRIVER ::
-   *     Use the `driver' field.
+   *     Use the `driver` field.
    *
    *   FT_OPEN_PARAMS ::
-   *     Use the `num_params' and `params' fields.
+   *     Use the `num_params` and `params` fields.
    *
    * @note:
-   *   The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME'
-   *   flags are mutually exclusive.
+   *   The `FT_OPEN_MEMORY`, `FT_OPEN_STREAM`, and `FT_OPEN_PATHNAME` flags
+   *   are mutually exclusive.
    */
 #define FT_OPEN_MEMORY    0x1
 #define FT_OPEN_STREAM    0x2
@@ -2107,7 +2185,7 @@
 #define FT_OPEN_PARAMS    0x10
 
 
-  /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */
+  /* these constants are deprecated; use the corresponding `FT_OPEN_XXX` */
   /* values instead                                                      */
 #define ft_open_memory    FT_OPEN_MEMORY
 #define ft_open_stream    FT_OPEN_STREAM
@@ -2133,8 +2211,8 @@
    *     A pointer to the parameter data.
    *
    * @note:
-   *   The ID and function of parameters are driver-specific.  See
-   *   section @parameter_tags for more information.
+   *   The ID and function of parameters are driver-specific.  See section
+   *   @parameter_tags for more information.
    */
   typedef struct  FT_Parameter_
   {
@@ -2156,8 +2234,7 @@
    *
    * @fields:
    *   flags ::
-   *     A set of bit flags indicating how to use the
-   *     structure.
+   *     A set of bit flags indicating how to use the structure.
    *
    *   memory_base ::
    *     The first byte of the file in memory.
@@ -2166,50 +2243,51 @@
    *     The size in bytes of the file in memory.
    *
    *   pathname ::
-   *     A pointer to an 8-bit file pathname.
+   *     A pointer to an 8-bit file pathname, which must be a C~string (i.e.,
+   *     no null bytes except at the very end).  The pointer is not owned by
+   *     FreeType.
    *
    *   stream ::
    *     A handle to a source stream object.
    *
    *   driver ::
-   *     This field is exclusively used by @FT_Open_Face;
-   *     it simply specifies the font driver to use for
-   *     opening the face.  If set to NULL, FreeType tries
-   *     to load the face with each one of the drivers in
-   *     its list.
+   *     This field is exclusively used by @FT_Open_Face; it simply specifies
+   *     the font driver to use for opening the face.  If set to `NULL`,
+   *     FreeType tries to load the face with each one of the drivers in its
+   *     list.
    *
    *   num_params ::
    *     The number of extra parameters.
    *
    *   params ::
-   *     Extra parameters passed to the font driver when
-   *     opening a new face.
+   *     Extra parameters passed to the font driver when opening a new face.
    *
    * @note:
-   *   The stream type is determined by the contents of `flags' that
-   *    are tested in the following order by @FT_Open_Face:
+   *   The stream type is determined by the contents of `flags`:
    *
-   *   If the @FT_OPEN_MEMORY bit is set, assume that this is a
-   *   memory file of `memory_size' bytes, located at `memory_address'.
-   *   The data are not copied, and the client is responsible for
-   *   releasing and destroying them _after_ the corresponding call to
-   *   @FT_Done_Face.
+   *   If the @FT_OPEN_MEMORY bit is set, assume that this is a memory file
+   *   of `memory_size` bytes, located at `memory_address`.  The data are not
+   *   copied, and the client is responsible for releasing and destroying
+   *   them _after_ the corresponding call to @FT_Done_Face.
    *
-   *   Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a
-   *   custom input stream `stream' is used.
+   *   Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a custom
+   *   input stream `stream` is used.
    *
-   *   Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this
-   *   is a normal file and use `pathname' to open it.
+   *   Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this is a
+   *   normal file and use `pathname` to open it.
    *
-   *   If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to
-   *   open the file with the driver whose handler is in `driver'.
+   *   If none of the above bits are set or if multiple are set at the same
+   *   time, the flags are invalid and @FT_Open_Face fails.
+   *
+   *   If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to open
+   *   the file with the driver whose handler is in `driver`.
    *
    *   If the @FT_OPEN_PARAMS bit is set, the parameters given by
-   *   `num_params' and `params' is used.  They are ignored otherwise.
+   *   `num_params` and `params` is used.  They are ignored otherwise.
    *
-   *   Ideally, both the `pathname' and `params' fields should be tagged
-   *   as `const'; this is missing for API backward compatibility.  In
-   *   other words, applications should treat them as read-only.
+   *   Ideally, both the `pathname` and `params` fields should be tagged as
+   *   'const'; this is missing for API backward compatibility.  In other
+   *   words, applications should treat them as read-only.
    */
   typedef struct  FT_Open_Args_
   {
@@ -2242,20 +2320,26 @@
    *     A path to the font file.
    *
    *   face_index ::
-   *     See @FT_Open_Face for a detailed description of this
-   *     parameter.
+   *     See @FT_Open_Face for a detailed description of this parameter.
    *
    * @output:
    *   aface ::
-   *     A handle to a new face object.  If `face_index' is
-   *     greater than or equal to zero, it must be non-NULL.
+   *     A handle to a new face object.  If `face_index` is greater than or
+   *     equal to zero, it must be non-`NULL`.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Use @FT_Done_Face to destroy the created @FT_Face object (along
-   *   with its slot and sizes).
+   *   The `pathname` string should be recognizable as such by a standard
+   *   `fopen` call on your system; in particular, this means that `pathname`
+   *   must not contain null bytes.  If that is not sufficient to address all
+   *   file name possibilities (for example, to handle wide character file
+   *   names on Windows in UTF-16 encoding) you might use @FT_Open_Face to
+   *   pass a memory array or a stream object instead.
+   *
+   *   Use @FT_Done_Face to destroy the created @FT_Face object (along with
+   *   its slot and sizes).
    */
   FT_EXPORT( FT_Error )
   FT_New_Face( FT_Library   library,
@@ -2270,8 +2354,7 @@
    *   FT_New_Memory_Face
    *
    * @description:
-   *   Call @FT_Open_Face to open a font that has been loaded into
-   *   memory.
+   *   Call @FT_Open_Face to open a font that has been loaded into memory.
    *
    * @inout:
    *   library ::
@@ -2285,13 +2368,12 @@
    *     The size of the memory chunk used by the font data.
    *
    *   face_index ::
-   *     See @FT_Open_Face for a detailed description of this
-   *     parameter.
+   *     See @FT_Open_Face for a detailed description of this parameter.
    *
    * @output:
    *   aface ::
-   *     A handle to a new face object.  If `face_index' is
-   *     greater than or equal to zero, it must be non-NULL.
+   *     A handle to a new face object.  If `face_index` is greater than or
+   *     equal to zero, it must be non-`NULL`.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -2313,8 +2395,7 @@
    *   FT_Open_Face
    *
    * @description:
-   *   Create a face object from a given resource described by
-   *   @FT_Open_Args.
+   *   Create a face object from a given resource described by @FT_Open_Args.
    *
    * @inout:
    *   library ::
@@ -2322,73 +2403,70 @@
    *
    * @input:
    *   args ::
-   *     A pointer to an `FT_Open_Args' structure that must
-   *     be filled by the caller.
+   *     A pointer to an `FT_Open_Args` structure that must be filled by the
+   *     caller.
    *
    *   face_index ::
-   *     This field holds two different values.  Bits 0-15
-   *     are the index of the face in the font file (starting
-   *     with value~0).  Set it to~0 if there is only one
-   *     face in the font file.
+   *     This field holds two different values.  Bits 0-15 are the index of
+   *     the face in the font file (starting with value~0).  Set it to~0 if
+   *     there is only one face in the font file.
    *
-   *     [Since 2.6.1] Bits 16-30 are relevant to GX and
-   *     OpenType variation fonts only, specifying the named
-   *     instance index for the current face index (starting
-   *     with value~1; value~0 makes FreeType ignore named
-   *     instances).  For non-variation fonts, bits 16-30 are
-   *     ignored.  Assuming that you want to access the third
-   *     named instance in face~4, `face_index' should be set
-   *     to 0x00030004.  If you want to access face~4 without
-   *     variation handling, simply set `face_index' to
+   *     [Since 2.6.1] Bits 16-30 are relevant to GX and OpenType variation
+   *     fonts only, specifying the named instance index for the current face
+   *     index (starting with value~1; value~0 makes FreeType ignore named
+   *     instances).  For non-variation fonts, bits 16-30 are ignored.
+   *     Assuming that you want to access the third named instance in face~4,
+   *     `face_index` should be set to 0x00030004.  If you want to access
+   *     face~4 without variation handling, simply set `face_index` to
    *     value~4.
    *
-   *     `FT_Open_Face' and its siblings can be used to
-   *     quickly check whether the font format of a given
-   *     font resource is supported by FreeType.  In general,
-   *     if the `face_index' argument is negative, the
-   *     function's return value is~0 if the font format is
-   *     recognized, or non-zero otherwise.  The function
-   *     allocates a more or less empty face handle in
-   *     `*aface' (if `aface' isn't NULL); the only two
-   *     useful fields in this special case are
-   *     `face->num_faces' and `face->style_flags'.  For any
-   *     negative value of `face_index', `face->num_faces'
-   *     gives the number of faces within the font file.  For
-   *     the negative value `-(N+1)' (with `N' a non-negative
-   *     16-bit value), bits 16-30 in `face->style_flags'
-   *     give the number of named instances in face `N' if we
-   *     have a variation font (or zero otherwise).  After
-   *     examination, the returned @FT_Face structure should
-   *     be deallocated with a call to @FT_Done_Face.
+   *     `FT_Open_Face` and its siblings can be used to quickly check whether
+   *     the font format of a given font resource is supported by FreeType.
+   *     In general, if the `face_index` argument is negative, the function's
+   *     return value is~0 if the font format is recognized, or non-zero
+   *     otherwise.  The function allocates a more or less empty face handle
+   *     in `*aface` (if `aface` isn't `NULL`); the only two useful fields in
+   *     this special case are `face->num_faces` and `face->style_flags`.
+   *     For any negative value of `face_index`, `face->num_faces` gives the
+   *     number of faces within the font file.  For the negative value
+   *     '-(N+1)' (with 'N' a non-negative 16-bit value), bits 16-30 in
+   *     `face->style_flags` give the number of named instances in face 'N'
+   *     if we have a variation font (or zero otherwise).  After examination,
+   *     the returned @FT_Face structure should be deallocated with a call to
+   *     @FT_Done_Face.
    *
    * @output:
    *   aface ::
-   *     A handle to a new face object.  If `face_index' is
-   *     greater than or equal to zero, it must be non-NULL.
+   *     A handle to a new face object.  If `face_index` is greater than or
+   *     equal to zero, it must be non-`NULL`.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Unlike FreeType 1.x, this function automatically creates a glyph
-   *   slot for the face object that can be accessed directly through
-   *   `face->glyph'.
+   *   Unlike FreeType 1.x, this function automatically creates a glyph slot
+   *   for the face object that can be accessed directly through
+   *   `face->glyph`.
    *
-   *   Each new face object created with this function also owns a
-   *   default @FT_Size object, accessible as `face->size'.
+   *   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,
-   *   @FT_Open_Face and its siblings can be called multiple times using
-   *   the same `library' argument.
+   *   @FT_Open_Face and its siblings can be called multiple times using the
+   *   same `library` argument.
    *
    *   See the discussion of reference counters in the description of
    *   @FT_Reference_Face.
    *
+   *   If `FT_OPEN_STREAM` is set in `args->flags`, the stream in
+   *   `args->stream` is automatically closed before this function returns
+   *   any error (including `FT_Err_Invalid_Argument`).
+   *
    * @example:
    *   To loop over all faces, use code similar to the following snippet
    *   (omitting the error handling).
    *
-   *   {
+   *   ```
    *     ...
    *     FT_Face  face;
    *     FT_Long  i, num_faces;
@@ -2408,15 +2486,14 @@
    *       FT_Done_Face( face );
    *       ...
    *     }
-   *   }
+   *   ```
    *
-   *   To loop over all valid values for `face_index', use something
-   *   similar to the following snippet, again without error handling.
-   *   The code accesses all faces immediately (thus only a single call
-   *   of `FT_Open_Face' within the do-loop), with and without named
-   *   instances.
+   *   To loop over all valid values for `face_index`, use something similar
+   *   to the following snippet, again without error handling.  The code
+   *   accesses all faces immediately (thus only a single call of
+   *   `FT_Open_Face` within the do-loop), with and without named instances.
    *
-   *   {
+   *   ```
    *     ...
    *     FT_Face  face;
    *
@@ -2451,7 +2528,7 @@
    *       }
    *
    *     } while ( face_idx < num_faces )
-   *   }
+   *   ```
    */
   FT_EXPORT( FT_Error )
   FT_Open_Face( FT_Library           library,
@@ -2490,10 +2567,10 @@
    *   FT_Attach_Stream
    *
    * @description:
-   *   `Attach' data to a face object.  Normally, this is used to read
+   *   'Attach' data to a face object.  Normally, this is used to read
    *   additional information for the face object.  For example, you can
-   *   attach an AFM file that comes with a Type~1 font to get the
-   *   kerning values and other metrics.
+   *   attach an AFM file that comes with a Type~1 font to get the kerning
+   *   values and other metrics.
    *
    * @inout:
    *   face ::
@@ -2501,24 +2578,23 @@
    *
    * @input:
    *   parameters ::
-   *     A pointer to @FT_Open_Args that must be filled by
-   *     the caller.
+   *     A pointer to @FT_Open_Args that must be filled by the caller.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The meaning of the `attach' (i.e., what really happens when the
-   *   new file is read) is not fixed by FreeType itself.  It really
-   *   depends on the font format (and thus the font driver).
+   *   The meaning of the 'attach' (i.e., what really happens when the new
+   *   file is read) is not fixed by FreeType itself.  It really depends on
+   *   the font format (and thus the font driver).
    *
-   *   Client applications are expected to know what they are doing
-   *   when invoking this function.  Most drivers simply do not implement
-   *   file or stream attachments.
+   *   Client applications are expected to know what they are doing when
+   *   invoking this function.  Most drivers simply do not implement file or
+   *   stream attachments.
    */
   FT_EXPORT( FT_Error )
-  FT_Attach_Stream( FT_Face        face,
-                    FT_Open_Args*  parameters );
+  FT_Attach_Stream( FT_Face              face,
+                    const FT_Open_Args*  parameters );
 
 
   /**************************************************************************
@@ -2527,9 +2603,9 @@
    *   FT_Reference_Face
    *
    * @description:
-   *   A counter gets initialized to~1 at the time an @FT_Face structure
-   *   is created.  This function increments the counter.  @FT_Done_Face
-   *   then only destroys a face if the counter is~1, otherwise it simply
+   *   A counter gets initialized to~1 at the time an @FT_Face structure is
+   *   created.  This function increments the counter.  @FT_Done_Face then
+   *   only destroys a face if the counter is~1, otherwise it simply
    *   decrements the counter.
    *
    *   This function helps in managing life-cycles of structures that
@@ -2544,6 +2620,7 @@
    *
    * @since:
    *   2.4.2
+   *
    */
   FT_EXPORT( FT_Error )
   FT_Reference_Face( FT_Face  face );
@@ -2579,10 +2656,10 @@
    *   FT_Select_Size
    *
    * @description:
-   *   Select a bitmap strike.  To be more precise, this function sets
-   *   the scaling factors of the active @FT_Size object in a face so
-   *   that bitmaps from this particular strike are taken by
-   *   @FT_Load_Glyph and friends.
+   *   Select a bitmap strike.  To be more precise, this function sets the
+   *   scaling factors of the active @FT_Size object in a face so that
+   *   bitmaps from this particular strike are taken by @FT_Load_Glyph and
+   *   friends.
    *
    * @inout:
    *   face ::
@@ -2590,23 +2667,22 @@
    *
    * @input:
    *   strike_index ::
-   *     The index of the bitmap strike in the
-   *     `available_sizes' field of @FT_FaceRec structure.
+   *     The index of the bitmap strike in the `available_sizes` field of
+   *     @FT_FaceRec structure.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   For bitmaps embedded in outline fonts it is common that only a
-   *   subset of the available glyphs at a given ppem value is available.
-   *   FreeType silently uses outlines if there is no bitmap for a given
-   *   glyph index.
+   *   For bitmaps embedded in outline fonts it is common that only a subset
+   *   of the available glyphs at a given ppem value is available.  FreeType
+   *   silently uses outlines if there is no bitmap for a given glyph index.
    *
-   *   For GX and OpenType variation fonts, a bitmap strike makes sense
-   *   only if the default instance is active (this is, no glyph
-   *   variation takes place); otherwise, FreeType simply ignores bitmap
-   *   strikes.  The same is true for all named instances that are
-   *   different from the default instance.
+   *   For GX and OpenType variation fonts, a bitmap strike makes sense only
+   *   if the default instance is active (this is, no glyph variation takes
+   *   place); otherwise, FreeType simply ignores bitmap strikes.  The same
+   *   is true for all named instances that are different from the default
+   *   instance.
    *
    *   Don't use this function if you are using the FreeType cache API.
    */
@@ -2621,40 +2697,38 @@
    *   FT_Size_Request_Type
    *
    * @description:
-   *   An enumeration type that lists the supported size request types,
-   *   i.e., what input size (in font units) maps to the requested output
-   *   size (in pixels, as computed from the arguments of
-   *   @FT_Size_Request).
+   *   An enumeration type that lists the supported size request types, i.e.,
+   *   what input size (in font units) maps to the requested output size (in
+   *   pixels, as computed from the arguments of @FT_Size_Request).
    *
    * @values:
    *   FT_SIZE_REQUEST_TYPE_NOMINAL ::
-   *     The nominal size.  The `units_per_EM' field of @FT_FaceRec is
-   *     used to determine both scaling values.
+   *     The nominal size.  The `units_per_EM` field of @FT_FaceRec is used
+   *     to determine both scaling values.
    *
    *     This is the standard scaling found in most applications.  In
-   *     particular, use this size request type for TrueType fonts if
-   *     they provide optical scaling or something similar.  Note,
-   *     however, that `units_per_EM' is a rather abstract value which
-   *     bears no relation to the actual size of the glyphs in a font.
+   *     particular, use this size request type for TrueType fonts if they
+   *     provide optical scaling or something similar.  Note, however, that
+   *     `units_per_EM` is a rather abstract value which bears no relation to
+   *     the actual size of the glyphs in a font.
    *
    *   FT_SIZE_REQUEST_TYPE_REAL_DIM ::
-   *     The real dimension.  The sum of the `ascender' and (minus of)
-   *     the `descender' fields of @FT_FaceRec is used to determine both
-   *     scaling values.
+   *     The real dimension.  The sum of the `ascender` and (minus of) the
+   *     `descender` fields of @FT_FaceRec is used to determine both scaling
+   *     values.
    *
    *   FT_SIZE_REQUEST_TYPE_BBOX ::
-   *     The font bounding box.  The width and height of the `bbox' field
-   *     of @FT_FaceRec are used to determine the horizontal and vertical
+   *     The font bounding box.  The width and height of the `bbox` field of
+   *     @FT_FaceRec are used to determine the horizontal and vertical
    *     scaling value, respectively.
    *
    *   FT_SIZE_REQUEST_TYPE_CELL ::
-   *     The `max_advance_width' field of @FT_FaceRec is used to
-   *     determine the horizontal scaling value; the vertical scaling
-   *     value is determined the same way as
-   *     @FT_SIZE_REQUEST_TYPE_REAL_DIM does.  Finally, both scaling
-   *     values are set to the smaller one.  This type is useful if you
-   *     want to specify the font size for, say, a window of a given
-   *     dimension and 80x24 cells.
+   *     The `max_advance_width` field of @FT_FaceRec is used to determine
+   *     the horizontal scaling value; the vertical scaling value is
+   *     determined the same way as @FT_SIZE_REQUEST_TYPE_REAL_DIM does.
+   *     Finally, both scaling values are set to the smaller one.  This type
+   *     is useful if you want to specify the font size for, say, a window of
+   *     a given dimension and 80x24 cells.
    *
    *   FT_SIZE_REQUEST_TYPE_SCALES ::
    *     Specify the scaling values directly.
@@ -2692,33 +2766,31 @@
    *     See @FT_Size_Request_Type.
    *
    *   width ::
-   *     The desired width, given as a 26.6 fractional
-   *     point value (with 72pt = 1in).
+   *     The desired width, given as a 26.6 fractional point value (with 72pt
+   *     = 1in).
    *
    *   height ::
-   *     The desired height, given as a 26.6 fractional
-   *     point value (with 72pt = 1in).
+   *     The desired height, given as a 26.6 fractional point value (with
+   *     72pt = 1in).
    *
    *   horiResolution ::
-   *     The horizontal resolution (dpi, i.e., pixels per
-   *     inch).  If set to zero, `width' is treated as a
-   *     26.6 fractional *pixel* value, which gets
-   *     internally rounded to an integer.
+   *     The horizontal resolution (dpi, i.e., pixels per inch).  If set to
+   *     zero, `width` is treated as a 26.6 fractional **pixel** value, which
+   *     gets internally rounded to an integer.
    *
    *   vertResolution ::
-   *     The vertical resolution (dpi, i.e., pixels per
-   *     inch).  If set to zero, `height' is treated as a
-   *     26.6 fractional *pixel* value, which gets
-   *     internally rounded to an integer.
+   *     The vertical resolution (dpi, i.e., pixels per inch).  If set to
+   *     zero, `height` is treated as a 26.6 fractional **pixel** value,
+   *     which gets internally rounded to an integer.
    *
    * @note:
-   *   If `width' is zero, the horizontal scaling value is set equal
-   *   to the vertical scaling value, and vice versa.
+   *   If `width` is zero, the horizontal scaling value is set equal to the
+   *   vertical scaling value, and vice versa.
    *
-   *   If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are
-   *   interpreted directly as 16.16 fractional scaling values, without
-   *   any further modification, and both `horiResolution' and
-   *   `vertResolution' are ignored.
+   *   If `type` is `FT_SIZE_REQUEST_TYPE_SCALES`, `width` and `height` are
+   *   interpreted directly as 16.16 fractional scaling values, without any
+   *   further modification, and both `horiResolution` and `vertResolution`
+   *   are ignored.
    */
   typedef struct  FT_Size_RequestRec_
   {
@@ -2762,20 +2834,19 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Although drivers may select the bitmap strike matching the
-   *   request, you should not rely on this if you intend to select a
-   *   particular bitmap strike.  Use @FT_Select_Size instead in that
-   *   case.
+   *   Although drivers may select the bitmap strike matching the request,
+   *   you should not rely on this if you intend to select a particular
+   *   bitmap strike.  Use @FT_Select_Size instead in that case.
    *
-   *   The relation between the requested size and the resulting glyph
-   *   size is dependent entirely on how the size is defined in the
-   *   source face.  The font designer chooses the final size of each
-   *   glyph relative to this size.  For more information refer to
-   *   `https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'.
+   *   The relation between the requested size and the resulting glyph size
+   *   is dependent entirely on how the size is defined in the source face.
+   *   The font designer chooses the final size of each glyph relative to
+   *   this size.  For more information refer to
+   *   'https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'.
    *
-   *   Contrary to @FT_Set_Char_Size, this function doesn't have special
-   *   code to normalize zero-valued widths, heights, or resolutions
-   *   (which lead to errors in most cases).
+   *   Contrary to @FT_Set_Char_Size, this function doesn't have special code
+   *   to normalize zero-valued widths, heights, or resolutions, which are
+   *   treated as @FT_LOAD_NO_SCALE.
    *
    *   Don't use this function if you are using the FreeType cache API.
    */
@@ -2814,17 +2885,17 @@
    *
    * @note:
    *   While this function allows fractional points as input values, the
-   *   resulting ppem value for the given resolution is always rounded to
-   *   the nearest integer.
+   *   resulting ppem value for the given resolution is always rounded to the
+   *   nearest integer.
    *
-   *   If either the character width or height is zero, it is set equal
-   *   to the other value.
+   *   If either the character width or height is zero, it is set equal to
+   *   the other value.
    *
    *   If either the horizontal or vertical resolution is zero, it is set
    *   equal to the other value.
    *
-   *   A character width or height smaller than 1pt is set to 1pt; if
-   *   both resolution values are zero, they are set to 72dpi.
+   *   A character width or height smaller than 1pt is set to 1pt; if both
+   *   resolution values are zero, they are set to 72dpi.
    *
    *   Don't use this function if you are using the FreeType cache API.
    */
@@ -2881,37 +2952,37 @@
    *
    * @inout:
    *   face ::
-   *     A handle to the target face object where the glyph
-   *     is loaded.
+   *     A handle to the target face object where the glyph is loaded.
    *
    * @input:
    *   glyph_index ::
-   *     The index of the glyph in the font file.  For
-   *     CID-keyed fonts (either in PS or in CFF format)
-   *     this argument specifies the CID value.
+   *     The index of the glyph in the font file.  For CID-keyed fonts
+   *     (either in PS or in CFF format) this argument specifies the CID
+   *     value.
    *
    *   load_flags ::
-   *     A flag indicating what to load for this glyph.  The
-   *     @FT_LOAD_XXX constants can be used to control the
-   *     glyph loading process (e.g., whether the outline
-   *     should be scaled, whether to load bitmaps or not,
-   *     whether to hint the outline, etc).
+   *     A flag indicating what to load for this glyph.  The @FT_LOAD_XXX
+   *     flags can be used to control the glyph loading process (e.g.,
+   *     whether the outline should be scaled, whether to load bitmaps or
+   *     not, whether to hint the outline, etc).
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The loaded glyph may be transformed.  See @FT_Set_Transform for
-   *   the details.
+   *   For proper scaling and hinting, the active @FT_Size object owned by
+   *   the face has to be meaningfully initialized by calling
+   *   @FT_Set_Char_Size before this function, for example.  The loaded
+   *   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 corresponding glyph in the font).  See the discussion
-   *   of the @FT_FACE_FLAG_CID_KEYED flag for more 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
+   *   corresponding glyph in the font).  See the discussion of the
+   *   @FT_FACE_FLAG_CID_KEYED flag for more details.
    *
-   *   If you receive `FT_Err_Glyph_Too_Big', try getting the glyph
-   *   outline at EM size, then scale it manually and fill it as a
-   *   graphics operation.
+   *   If you receive `FT_Err_Glyph_Too_Big`, try getting the glyph outline
+   *   at EM size, then scale it manually and fill it as a graphics
+   *   operation.
    */
   FT_EXPORT( FT_Error )
   FT_Load_Glyph( FT_Face   face,
@@ -2930,20 +3001,18 @@
    *
    * @inout:
    *   face ::
-   *     A handle to a target face object where the glyph
-   *     is loaded.
+   *     A handle to a target face object where the glyph is loaded.
    *
    * @input:
    *   char_code ::
-   *     The glyph's character code, according to the
-   *     current charmap used in the face.
+   *     The glyph's character code, according to the current charmap used in
+   *     the face.
    *
    *   load_flags ::
-   *     A flag indicating what to load for this glyph.  The
-   *     @FT_LOAD_XXX constants can be used to control the
-   *     glyph loading process (e.g., whether the outline
-   *     should be scaled, whether to load bitmaps or not,
-   *     whether to hint the outline, etc).
+   *     A flag indicating what to load for this glyph.  The @FT_LOAD_XXX
+   *     constants can be used to control the glyph loading process (e.g.,
+   *     whether the outline should be scaled, whether to load bitmaps or
+   *     not, whether to hint the outline, etc).
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -2951,13 +3020,12 @@
    * @note:
    *   This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph.
    *
-   *   Many fonts contain glyphs that can't be loaded by this function
-   *   since its glyph indices are not listed in any of the font's
-   *   charmaps.
+   *   Many fonts contain glyphs that can't be loaded by this function since
+   *   its glyph indices are not listed in any of the font's charmaps.
    *
-   *   If no active cmap is set up (i.e., `face->charmap' is zero), the
-   *   call to @FT_Get_Char_Index is omitted, and the function behaves
-   *   identically to @FT_Load_Glyph.
+   *   If no active cmap is set up (i.e., `face->charmap` is zero), the call
+   *   to @FT_Get_Char_Index is omitted, and the function behaves identically
+   *   to @FT_Load_Glyph.
    */
   FT_EXPORT( FT_Error )
   FT_Load_Char( FT_Face   face,
@@ -2965,14 +3033,14 @@
                 FT_Int32  load_flags );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_LOAD_XXX
    *
    * @description:
-   *   A list of bit field constants for @FT_Load_Glyph to indicate what
-   *   kind of operations to perform during glyph loading.
+   *   A list of bit field constants for @FT_Load_Glyph to indicate what kind
+   *   of operations to perform during glyph loading.
    *
    * @values:
    *   FT_LOAD_DEFAULT ::
@@ -2980,15 +3048,14 @@
    *     operation.  In this case, the following happens:
    *
    *     1. FreeType looks for a bitmap for the glyph corresponding to the
-   *     face's current size.  If one is found, the function returns.
-   *     The bitmap data can be accessed from the glyph slot (see note
-   *     below).
+   *     face's current size.  If one is found, the function returns.  The
+   *     bitmap data can be accessed from the glyph slot (see note below).
    *
    *     2. If no embedded bitmap is searched for or found, FreeType looks
-   *     for a scalable outline.  If one is found, it is loaded from
-   *     the font file, scaled to device pixels, then `hinted' to the
-   *     pixel grid in order to optimize it.  The outline data can be
-   *     accessed from the glyph slot (see note below).
+   *     for a scalable outline.  If one is found, it is loaded from the font
+   *     file, scaled to device pixels, then 'hinted' to the pixel grid in
+   *     order to optimize it.  The outline data can be accessed from the
+   *     glyph slot (see note below).
    *
    *     Note that by default the glyph loader doesn't render outlines into
    *     bitmaps.  The following flags are used to modify this default
@@ -2996,19 +3063,21 @@
    *
    *   FT_LOAD_NO_SCALE ::
    *     Don't scale the loaded outline glyph but keep it in font units.
+   *     This flag is also assumed if @FT_Size owned by the face was not
+   *     properly initialized.
    *
    *     This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and
    *     unsets @FT_LOAD_RENDER.
    *
-   *     If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using
-   *     FT_LOAD_NO_SCALE usually yields meaningless outlines because the
+   *     If the font is 'tricky' (see @FT_FACE_FLAG_TRICKY for more), using
+   *     `FT_LOAD_NO_SCALE` usually yields meaningless outlines because the
    *     subglyphs must be scaled and positioned with hinting instructions.
-   *     This can be solved by loading the font without FT_LOAD_NO_SCALE and
-   *     setting the character size to `font->units_per_EM'.
+   *     This can be solved by loading the font without `FT_LOAD_NO_SCALE`
+   *     and setting the character size to `font->units_per_EM`.
    *
    *   FT_LOAD_NO_HINTING ::
-   *     Disable hinting.  This generally generates `blurrier' bitmap glyphs
-   *     when the glyph are rendered in any of the anti-aliased modes.  See
+   *     Disable hinting.  This generally generates 'blurrier' bitmap glyphs
+   *     when the glyphs are rendered in any of the anti-aliased modes.  See
    *     also the note below.
    *
    *     This flag is implied by @FT_LOAD_NO_SCALE.
@@ -3026,36 +3095,48 @@
    *
    *     @FT_LOAD_NO_SCALE always sets this flag.
    *
+   *   FT_LOAD_SBITS_ONLY ::
+   *     [Since 2.12] This is the opposite of @FT_LOAD_NO_BITMAP, more or
+   *     less: @FT_Load_Glyph returns `FT_Err_Invalid_Argument` if the face
+   *     contains a bitmap strike for the given size (or the strike selected
+   *     by @FT_Select_Size) but there is no glyph in the strike.
+   *
+   *     Note that this load flag was part of FreeType since version 2.0.6
+   *     but previously tagged as internal.
+   *
    *   FT_LOAD_VERTICAL_LAYOUT ::
    *     Load the glyph for vertical text layout.  In particular, the
-   *     `advance' value in the @FT_GlyphSlotRec structure is set to the
-   *     `vertAdvance' value of the `metrics' field.
+   *     `advance` value in the @FT_GlyphSlotRec structure is set to the
+   *     `vertAdvance` value of the `metrics` field.
    *
-   *     In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use
-   *     this flag currently.  Reason is that in this case vertical metrics
-   *     get synthesized, and those values are not always consistent across
+   *     In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use this
+   *     flag currently.  Reason is that in this case vertical metrics get
+   *     synthesized, and those values are not always consistent across
    *     various font formats.
    *
    *   FT_LOAD_FORCE_AUTOHINT ::
-   *     Prefer the auto-hinter over the font's native hinter.  See also
-   *     the note below.
+   *     Prefer the auto-hinter over the font's native hinter.  See also the
+   *     note below.
    *
    *   FT_LOAD_PEDANTIC ::
    *     Make the font driver perform pedantic verifications during glyph
-   *     loading.  This is mostly used to detect broken glyphs in fonts.
-   *     By default, FreeType tries to handle broken fonts also.
+   *     loading and hinting.  This is mostly used to detect broken glyphs in
+   *     fonts.  By default, FreeType tries to handle broken fonts also.
    *
    *     In particular, errors from the TrueType bytecode engine are not
-   *     passed to the application if this flag is not set; this might
-   *     result in partially hinted or distorted glyphs in case a glyph's
-   *     bytecode is buggy.
+   *     passed to the application if this flag is not set; this might result
+   *     in partially hinted or distorted glyphs in case a glyph's bytecode
+   *     is buggy.
    *
    *   FT_LOAD_NO_RECURSE ::
-   *     Don't load composite glyphs recursively.  Instead, the font
-   *     driver should set the `num_subglyph' and `subglyphs' values of
-   *     the glyph slot accordingly, and set `glyph->format' to
-   *     @FT_GLYPH_FORMAT_COMPOSITE.  The description of subglyphs can
-   *     then be accessed with @FT_Get_SubGlyph_Info.
+   *     Don't load composite glyphs recursively.  Instead, the font driver
+   *     fills the `num_subglyph` and `subglyphs` values of the glyph slot;
+   *     it also sets `glyph->format` to @FT_GLYPH_FORMAT_COMPOSITE.  The
+   *     description of subglyphs can then be accessed with
+   *     @FT_Get_SubGlyph_Info.
+   *
+   *     Don't use this flag for retrieving metrics information since some
+   *     font drivers only return rudimentary data.
    *
    *     This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM.
    *
@@ -3072,36 +3153,45 @@
    *     monochrome-optimized hinting algorithm is used.
    *
    *   FT_LOAD_LINEAR_DESIGN ::
-   *     Keep  `linearHoriAdvance' and `linearVertAdvance' fields of
-   *     @FT_GlyphSlotRec in font units.  See @FT_GlyphSlotRec for
-   *     details.
+   *     Keep `linearHoriAdvance` and `linearVertAdvance` fields of
+   *     @FT_GlyphSlotRec in font units.  See @FT_GlyphSlotRec for details.
    *
    *   FT_LOAD_NO_AUTOHINT ::
    *     Disable the auto-hinter.  See also the note below.
    *
    *   FT_LOAD_COLOR ::
-   *     Load colored glyphs.  There are slight differences depending on the
-   *     font format.
+   *     Load colored glyphs.  FreeType searches in the following order;
+   *     there are slight differences depending on the font format.
    *
-   *     [Since 2.5] Load embedded color bitmap images.  The resulting color
-   *     bitmaps, if available, will have the @FT_PIXEL_MODE_BGRA format,
-   *     with pre-multiplied color channels.  If the flag is not set and
-   *     color bitmaps are found, they are converted to 256-level gray
-   *     bitmaps, using the @FT_PIXEL_MODE_GRAY format.
+   *     [Since 2.5] Load embedded color bitmap images (provided
+   *     @FT_LOAD_NO_BITMAP is not set).  The resulting color bitmaps, if
+   *     available, have the @FT_PIXEL_MODE_BGRA format, with pre-multiplied
+   *     color channels.  If the flag is not set and color bitmaps are found,
+   *     they are converted to 256-level gray bitmaps, using the
+   *     @FT_PIXEL_MODE_GRAY format.
    *
-   *     [Since 2.10] If the glyph index contains an entry in the face's
-   *     `COLR' table with a `CPAL' palette table (as defined in the
-   *     OpenType specification), make @FT_Render_Glyph provide a default
+   *     [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.
+   *
+   *     [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
+   *     the OpenType specification), make @FT_Render_Glyph provide a default
    *     blending of the color glyph layers associated with the glyph index,
    *     using the same bitmap format as embedded color bitmap images.  This
-   *     is mainly for convenience; for full control of color layers use
+   *     is mainly for convenience and works only for glyphs in 'COLR' v0
+   *     tables (or glyphs in 'COLR' v1 tables that exclusively use v0
+   *     features).  For full control of color layers use
    *     @FT_Get_Color_Glyph_Layer and FreeType's color functions like
-   *     @FT_Palette_Select instead of setting FT_LOAD_COLOR for rendering
+   *     @FT_Palette_Select instead of setting @FT_LOAD_COLOR for rendering
    *     so that the client application can handle blending by itself.
    *
    *   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
+   *     [Since 2.6.1] Compute glyph metrics from the glyph data, without the
+   *     use of bundled metrics tables (for example, the 'hdmx' table in
    *     TrueType fonts).  This flag is mainly used by font validating or
    *     font editing applications, which need to ignore, verify, or edit
    *     those tables.
@@ -3110,9 +3200,9 @@
    *
    *   FT_LOAD_BITMAP_METRICS_ONLY ::
    *     [Since 2.7.1] Request loading of the metrics and bitmap image
-   *     information of a (possibly embedded) bitmap glyph without
-   *     allocating or copying the bitmap image data itself.  No effect if
-   *     the target glyph is not a bitmap image.
+   *     information of a (possibly embedded) bitmap glyph without allocating
+   *     or copying the bitmap image data itself.  No effect if the target
+   *     glyph is not a bitmap image.
    *
    *     This flag unsets @FT_LOAD_RENDER.
    *
@@ -3127,8 +3217,8 @@
    *   @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter.  You can
    *   disable hinting by setting @FT_LOAD_NO_HINTING or change the
    *   precedence by setting @FT_LOAD_FORCE_AUTOHINT.  You can also set
-   *   @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be
-   *   used at all.
+   *   @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be used
+   *   at all.
    *
    *   See the description of @FT_FACE_FLAG_TRICKY for a special exception
    *   (affecting only a handful of Asian fonts).
@@ -3139,27 +3229,28 @@
    *   Note that the auto-hinter needs a valid Unicode cmap (either a native
    *   one or synthesized by FreeType) for producing correct results.  If a
    *   font provides an incorrect mapping (for example, assigning the
-   *   character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a
+   *   character code U+005A, LATIN CAPITAL LETTER~Z, to a glyph depicting a
    *   mathematical integral sign), the auto-hinter might produce useless
    *   results.
    *
    */
 #define FT_LOAD_DEFAULT                      0x0
-#define FT_LOAD_NO_SCALE                     ( 1L << 0 )
-#define FT_LOAD_NO_HINTING                   ( 1L << 1 )
-#define FT_LOAD_RENDER                       ( 1L << 2 )
-#define FT_LOAD_NO_BITMAP                    ( 1L << 3 )
-#define FT_LOAD_VERTICAL_LAYOUT              ( 1L << 4 )
-#define FT_LOAD_FORCE_AUTOHINT               ( 1L << 5 )
-#define FT_LOAD_CROP_BITMAP                  ( 1L << 6 )
-#define FT_LOAD_PEDANTIC                     ( 1L << 7 )
-#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH  ( 1L << 9 )
+#define FT_LOAD_NO_SCALE                     ( 1L << 0  )
+#define FT_LOAD_NO_HINTING                   ( 1L << 1  )
+#define FT_LOAD_RENDER                       ( 1L << 2  )
+#define FT_LOAD_NO_BITMAP                    ( 1L << 3  )
+#define FT_LOAD_VERTICAL_LAYOUT              ( 1L << 4  )
+#define FT_LOAD_FORCE_AUTOHINT               ( 1L << 5  )
+#define FT_LOAD_CROP_BITMAP                  ( 1L << 6  )
+#define FT_LOAD_PEDANTIC                     ( 1L << 7  )
+#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH  ( 1L << 9  )
 #define FT_LOAD_NO_RECURSE                   ( 1L << 10 )
 #define FT_LOAD_IGNORE_TRANSFORM             ( 1L << 11 )
 #define FT_LOAD_MONOCHROME                   ( 1L << 12 )
 #define FT_LOAD_LINEAR_DESIGN                ( 1L << 13 )
+#define FT_LOAD_SBITS_ONLY                   ( 1L << 14 )
 #define FT_LOAD_NO_AUTOHINT                  ( 1L << 15 )
-  /* Bits 16-19 are used by `FT_LOAD_TARGET_' */
+  /* Bits 16-19 are used by `FT_LOAD_TARGET_` */
 #define FT_LOAD_COLOR                        ( 1L << 20 )
 #define FT_LOAD_COMPUTE_METRICS              ( 1L << 21 )
 #define FT_LOAD_BITMAP_METRICS_ONLY          ( 1L << 22 )
@@ -3167,8 +3258,8 @@
   /* */
 
   /* used internally only by certain font drivers */
-#define FT_LOAD_ADVANCE_ONLY                 ( 1L << 8 )
-#define FT_LOAD_SBITS_ONLY                   ( 1L << 14 )
+#define FT_LOAD_ADVANCE_ONLY                 ( 1L << 8  )
+#define FT_LOAD_SVG_ONLY                     ( 1L << 23 )
 
 
   /**************************************************************************
@@ -3178,19 +3269,17 @@
    *
    * @description:
    *   A list of values to select a specific hinting algorithm for the
-   *   hinter.  You should OR one of these values to your `load_flags'
-   *   when calling @FT_Load_Glyph.
+   *   hinter.  You should OR one of these values to your `load_flags` when
+   *   calling @FT_Load_Glyph.
    *
-   *   Note that a font's native hinters may ignore the hinting algorithm
-   *   you have specified (e.g., the TrueType bytecode interpreter).  You
-   *   can set @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is
-   *   used.
+   *   Note that a font's native hinters may ignore the hinting algorithm you
+   *   have specified (e.g., the TrueType bytecode interpreter).  You can set
+   *   @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used.
    *
    * @values:
    *   FT_LOAD_TARGET_NORMAL ::
    *     The default hinting algorithm, optimized for standard gray-level
-   *     rendering.  For monochrome output, use @FT_LOAD_TARGET_MONO
-   *     instead.
+   *     rendering.  For monochrome output, use @FT_LOAD_TARGET_MONO instead.
    *
    *   FT_LOAD_TARGET_LIGHT ::
    *     A lighter hinting algorithm for gray-level modes.  Many generated
@@ -3203,13 +3292,13 @@
    *     auto-hinter.
    *
    *     Advance widths are rounded to integer values; however, using the
-   *     `lsb_delta' and `rsb_delta' fields of @FT_GlyphSlotRec, it is
+   *     `lsb_delta` and `rsb_delta` fields of @FT_GlyphSlotRec, it is
    *     possible to get fractional advance widths for subpixel positioning
    *     (which is recommended to use).
    *
-   *     If configuration option AF_CONFIG_OPTION_TT_SIZE_METRICS is active,
-   *     TrueType-like metrics are used to make this mode behave similarly
-   *     as in unpatched FreeType versions between 2.4.6 and 2.7.1
+   *     If configuration option `AF_CONFIG_OPTION_TT_SIZE_METRICS` is
+   *     active, TrueType-like metrics are used to make this mode behave
+   *     similarly as in unpatched FreeType versions between 2.4.6 and 2.7.1
    *     (inclusive).
    *
    *   FT_LOAD_TARGET_MONO ::
@@ -3217,6 +3306,12 @@
    *     output.  The result is probably unpleasant if the glyph is rendered
    *     in non-monochrome modes.
    *
+   *     Note that for outline fonts only the TrueType font driver has proper
+   *     monochrome hinting support, provided the TTFs contain hints for B/W
+   *     rendering (which most fonts no longer provide).  If these conditions
+   *     are not met it is very likely that you get ugly results at smaller
+   *     sizes.
+   *
    *   FT_LOAD_TARGET_LCD ::
    *     A variant of @FT_LOAD_TARGET_LIGHT optimized for horizontally
    *     decimated LCD displays.
@@ -3226,25 +3321,25 @@
    *     decimated LCD displays.
    *
    * @note:
-   *   You should use only _one_ of the FT_LOAD_TARGET_XXX values in your
-   *   `load_flags'.  They can't be ORed.
+   *   You should use only _one_ of the `FT_LOAD_TARGET_XXX` values in your
+   *   `load_flags`.  They can't be ORed.
    *
    *   If @FT_LOAD_RENDER is also set, the glyph is rendered in the
    *   corresponding mode (i.e., the mode that matches the used algorithm
-   *   best).  An exception is FT_LOAD_TARGET_MONO since it implies
+   *   best).  An exception is `FT_LOAD_TARGET_MONO` since it implies
    *   @FT_LOAD_MONOCHROME.
    *
    *   You can use a hinting algorithm that doesn't correspond to the same
-   *   rendering mode.  As an example, it is possible to use the `light'
+   *   rendering mode.  As an example, it is possible to use the 'light'
    *   hinting algorithm and have the results rendered in horizontal LCD
    *   pixel mode, with code like
    *
-   *   {
+   *   ```
    *     FT_Load_Glyph( face, glyph_index,
    *                    load_flags | FT_LOAD_TARGET_LIGHT );
    *
    *     FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD );
-   *   }
+   *   ```
    *
    *   In general, you should stick with one rendering mode.  For example,
    *   switching between @FT_LOAD_TARGET_NORMAL and @FT_LOAD_TARGET_MONO
@@ -3254,7 +3349,7 @@
    *   necessary to empty the cache after a mode switch to avoid false hits.
    *
    */
-#define FT_LOAD_TARGET_( x )   ( (FT_Int32)( (x) & 15 ) << 16 )
+#define FT_LOAD_TARGET_( x )   ( FT_STATIC_CAST( FT_Int32, (x) & 15 ) << 16 )
 
 #define FT_LOAD_TARGET_NORMAL  FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL )
 #define FT_LOAD_TARGET_LIGHT   FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT  )
@@ -3273,7 +3368,8 @@
    *   @FT_LOAD_TARGET_XXX value.
    *
    */
-#define FT_LOAD_TARGET_MODE( x )  ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) )
+#define FT_LOAD_TARGET_MODE( x )                               \
+          FT_STATIC_CAST( FT_Render_Mode, ( (x) >> 16 ) & 15 )
 
 
   /**************************************************************************
@@ -3282,8 +3378,8 @@
    *   FT_Set_Transform
    *
    * @description:
-   *   Set the transformation that is applied to glyph images when they
-   *   are loaded into a glyph slot through @FT_Load_Glyph.
+   *   Set the transformation that is applied to glyph images when they are
+   *   loaded into a glyph slot through @FT_Load_Glyph.
    *
    * @inout:
    *   face ::
@@ -3291,20 +3387,26 @@
    *
    * @input:
    *   matrix ::
-   *     A pointer to the transformation's 2x2 matrix.  Use NULL
-   *     for the identity matrix.
+   *     A pointer to the transformation's 2x2 matrix.  Use `NULL` for the
+   *     identity matrix.
    *   delta ::
-   *     A pointer to the translation vector.  Use NULL for the
-   *     null vector.
+   *     A pointer to the translation vector.  Use `NULL` for the null
+   *     vector.
    *
    * @note:
-   *   The transformation is only applied to scalable image formats after
-   *   the glyph has been loaded.  It means that hinting is unaltered by
-   *   the transformation and is performed on the character size given in
-   *   the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes.
+   *   This function is provided as a convenience, but keep in mind that
+   *   @FT_Matrix coefficients are only 16.16 fixed-point values, which can
+   *   limit the accuracy of the results.  Using floating-point computations
+   *   to perform the transform directly in client code instead will always
+   *   yield better numbers.
    *
-   *   Note that this also transforms the `face.glyph.advance' field, but
-   *   *not* the values in `face.glyph.metrics'.
+   *   The transformation is only applied to scalable image formats after the
+   *   glyph has been loaded.  It means that hinting is unaltered by the
+   *   transformation and is performed on the character size given in the
+   *   last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes.
+   *
+   *   Note that this also transforms the `face.glyph.advance` field, but
+   *   **not** the values in `face.glyph.metrics`.
    */
   FT_EXPORT( void )
   FT_Set_Transform( FT_Face     face,
@@ -3314,6 +3416,39 @@
 
   /**************************************************************************
    *
+   * @function:
+   *   FT_Get_Transform
+   *
+   * @description:
+   *   Return the transformation that is applied to glyph images when they
+   *   are loaded into a glyph slot through @FT_Load_Glyph.  See
+   *   @FT_Set_Transform for more details.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the source face object.
+   *
+   * @output:
+   *   matrix ::
+   *     A pointer to a transformation's 2x2 matrix.  Set this to NULL if you
+   *     are not interested in the value.
+   *
+   *   delta ::
+   *     A pointer to a translation vector.  Set this to NULL if you are not
+   *     interested in the value.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+  FT_EXPORT( void )
+  FT_Get_Transform( FT_Face     face,
+                    FT_Matrix*  matrix,
+                    FT_Vector*  delta );
+
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_Render_Mode
    *
@@ -3321,55 +3456,126 @@
    *   Render modes supported by FreeType~2.  Each mode corresponds to a
    *   specific type of scanline conversion performed on the outline.
    *
-   *   For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode'
-   *   field in the @FT_GlyphSlotRec structure gives the format of the
-   *   returned bitmap.
+   *   For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode` field
+   *   in the @FT_GlyphSlotRec structure gives the format of the returned
+   *   bitmap.
    *
    *   All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity,
    *   indicating pixel coverage.  Use linear alpha blending and gamma
    *   correction to correctly render non-monochrome glyph bitmaps onto a
    *   surface; see @FT_Render_Glyph.
    *
+   *   The @FT_RENDER_MODE_SDF is a special render mode that uses up to 256
+   *   distance values, indicating the signed distance from the grid position
+   *   to the nearest outline.
+   *
    * @values:
    *   FT_RENDER_MODE_NORMAL ::
-   *     Default render mode; it corresponds to 8-bit anti-aliased
-   *     bitmaps.
+   *     Default render mode; it corresponds to 8-bit anti-aliased bitmaps.
    *
    *   FT_RENDER_MODE_LIGHT ::
-   *     This is equivalent to @FT_RENDER_MODE_NORMAL.  It is only
-   *     defined as a separate value because render modes are also used
-   *     indirectly to define hinting algorithm selectors.  See
-   *     @FT_LOAD_TARGET_XXX for details.
+   *     This is equivalent to @FT_RENDER_MODE_NORMAL.  It is only defined as
+   *     a separate value because render modes are also used indirectly to
+   *     define hinting algorithm selectors.  See @FT_LOAD_TARGET_XXX for
+   *     details.
    *
    *   FT_RENDER_MODE_MONO ::
-   *     This mode corresponds to 1-bit bitmaps (with 2~levels of
-   *     opacity).
+   *     This mode corresponds to 1-bit bitmaps (with 2~levels of opacity).
    *
    *   FT_RENDER_MODE_LCD ::
-   *     This mode corresponds to horizontal RGB and BGR subpixel
-   *     displays like LCD screens.  It produces 8-bit bitmaps that are
-   *     3~times the width of the original glyph outline in pixels, and
-   *     which use the @FT_PIXEL_MODE_LCD mode.
+   *     This mode corresponds to horizontal RGB and BGR subpixel displays
+   *     like LCD screens.  It produces 8-bit bitmaps that are 3~times the
+   *     width of the original glyph outline in pixels, and which use the
+   *     @FT_PIXEL_MODE_LCD mode.
    *
    *   FT_RENDER_MODE_LCD_V ::
    *     This mode corresponds to vertical RGB and BGR subpixel displays
-   *     (like PDA screens, rotated LCD displays, etc.).  It produces
-   *     8-bit bitmaps that are 3~times the height of the original
-   *     glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode.
+   *     (like PDA screens, rotated LCD displays, etc.).  It produces 8-bit
+   *     bitmaps that are 3~times the height of the original glyph outline in
+   *     pixels and use the @FT_PIXEL_MODE_LCD_V mode.
+   *
+   *   FT_RENDER_MODE_SDF ::
+   *     This mode corresponds to 8-bit, single-channel signed distance field
+   *     (SDF) bitmaps.  Each pixel in the SDF grid is the value from the
+   *     pixel's position to the nearest glyph's outline.  The distances are
+   *     calculated from the center of the pixel and are positive if they are
+   *     filled by the outline (i.e., inside the outline) and negative
+   *     otherwise.  Check the note below on how to convert the output values
+   *     to usable data.
    *
    * @note:
-   *   Should you define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your
-   *   `ftoption.h', which enables patented ClearType-style rendering,
-   *   the LCD-optimized glyph bitmaps should be filtered to reduce color
-   *   fringes inherent to this technology.  You can either set up LCD
-   *   filtering with @FT_Library_SetLcdFilter or @FT_Face_Properties,
-   *   or do the filtering yourself.  The default FreeType LCD rendering
-   *   technology does not require filtering.
-   *
    *   The selected render mode only affects vector glyphs of a font.
    *   Embedded bitmaps often have a different pixel mode like
-   *   @FT_PIXEL_MODE_MONO.  You can use @FT_Bitmap_Convert to transform
-   *   them into 8-bit pixmaps.
+   *   @FT_PIXEL_MODE_MONO.  You can use @FT_Bitmap_Convert to transform them
+   *   into 8-bit pixmaps.
+   *
+   *   For @FT_RENDER_MODE_SDF the output bitmap buffer contains normalized
+   *   distances that are packed into unsigned 8-bit values.  To get pixel
+   *   values in floating point representation use the following pseudo-C
+   *   code for the conversion.
+   *
+   *   ```
+   *   // Load glyph and render using FT_RENDER_MODE_SDF,
+   *   // then use the output buffer as follows.
+   *
+   *   ...
+   *   FT_Byte  buffer = glyph->bitmap->buffer;
+   *
+   *
+   *   for pixel in buffer
+   *   {
+   *     // `sd` is the signed distance and `spread` is the current spread;
+   *     // the default spread is 2 and can be changed.
+   *
+   *     float  sd = (float)pixel - 128.0f;
+   *
+   *
+   *     // Convert to pixel values.
+   *     sd = ( sd / 128.0f ) * spread;
+   *
+   *     // Store `sd` in a buffer or use as required.
+   *   }
+   *
+   *   ```
+   *
+   *   FreeType has two rasterizers for generating SDF, namely:
+   *
+   *   1. `sdf` for generating SDF directly from glyph's outline, and
+   *
+   *   2. `bsdf` for generating SDF from rasterized bitmaps.
+   *
+   *   Depending on the glyph type (i.e., outline or bitmap), one of the two
+   *   rasterizers is chosen at runtime and used for generating SDFs.  To
+   *   force the use of `bsdf` you should render the glyph with any of the
+   *   FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and
+   *   then re-render with `FT_RENDER_MODE_SDF`.
+   *
+   *   There are some issues with stability and possible failures of the SDF
+   *   renderers (specifically `sdf`).
+   *
+   *   1. The `sdf` rasterizer is sensitive to really small features (e.g.,
+   *      sharp turns that are less than 1~pixel) and imperfections in the
+   *      glyph's outline, causing artifacts in the final output.
+   *
+   *   2. The `sdf` rasterizer has limited support for handling intersecting
+   *      contours and *cannot* handle self-intersecting contours whatsoever.
+   *      Self-intersection happens when a single connected contour
+   *      intersects itself at some point; having these in your font
+   *      definitely poses a problem to the rasterizer and cause artifacts,
+   *      too.
+   *
+   *   3. Generating SDF for really small glyphs may result in undesirable
+   *      output; the pixel grid (which stores distance information) becomes
+   *      too coarse.
+   *
+   *   4. Since the output buffer is normalized, precision at smaller spreads
+   *      is greater than precision at larger spread values because the
+   *      output range of [0..255] gets mapped to a smaller SDF range.  A
+   *      spread of~2 should be sufficient in most cases.
+   *
+   *   Points (1) and (2) can be avoided by using the `bsdf` rasterizer,
+   *   which is more stable than the `sdf` rasterizer in general.
+   *
    */
   typedef enum  FT_Render_Mode_
   {
@@ -3378,6 +3584,7 @@
     FT_RENDER_MODE_MONO,
     FT_RENDER_MODE_LCD,
     FT_RENDER_MODE_LCD_V,
+    FT_RENDER_MODE_SDF,
 
     FT_RENDER_MODE_MAX
 
@@ -3385,7 +3592,7 @@
 
 
   /* these constants are deprecated; use the corresponding */
-  /* `FT_Render_Mode' values instead                       */
+  /* `FT_Render_Mode` values instead                       */
 #define ft_render_mode_normal  FT_RENDER_MODE_NORMAL
 #define ft_render_mode_mono    FT_RENDER_MODE_MONO
 
@@ -3396,112 +3603,102 @@
    *   FT_Render_Glyph
    *
    * @description:
-   *   Convert a given glyph image to a bitmap.  It does so by inspecting
-   *   the glyph image format, finding the relevant renderer, and
-   *   invoking it.
+   *   Convert a given glyph image to a bitmap.  It does so by inspecting the
+   *   glyph image format, finding the relevant renderer, and invoking it.
    *
    * @inout:
    *   slot ::
-   *     A handle to the glyph slot containing the image to
-   *     convert.
+   *     A handle to the glyph slot containing the image to convert.
    *
    * @input:
    *   render_mode ::
-   *     The render mode used to render the glyph image into
-   *     a bitmap.  See @FT_Render_Mode for a list of
-   *     possible values.
+   *     The render mode used to render the glyph image into a bitmap.  See
+   *     @FT_Render_Mode for a list of possible values.
    *
-   *     If @FT_RENDER_MODE_NORMAL is used, the flag
-   *     @FT_LOAD_COLOR can be additionally set to make the
-   *     function provide a default blending of colored
-   *     glyph layers associated with the current glyph slot
-   *     (provided the font contains such layers) instead of
-   *     rendering the glyph slot's outline.  See
+   *     If @FT_RENDER_MODE_NORMAL is used, a previous call of @FT_Load_Glyph
+   *     with flag @FT_LOAD_COLOR makes `FT_Render_Glyph` provide a default
+   *     blending of colored glyph layers associated with the current glyph
+   *     slot (provided the font contains such layers) instead of rendering
+   *     the glyph slot's outline.  This is an experimental feature; see
    *     @FT_LOAD_COLOR for more information.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   To get meaningful results, font scaling values must be set with
-   *   functions like @FT_Set_Char_Size before calling `FT_Render_Glyph'.
+   *   When FreeType outputs a bitmap of a glyph, it really outputs an alpha
+   *   coverage map.  If a pixel is completely covered by a filled-in
+   *   outline, the bitmap contains 0xFF at that pixel, meaning that
+   *   0xFF/0xFF fraction of that pixel is covered, meaning the pixel is 100%
+   *   black (or 0% bright).  If a pixel is only 50% covered (value 0x80),
+   *   the pixel is made 50% black (50% bright or a middle shade of grey).
+   *   0% covered means 0% black (100% bright or white).
    *
-   *   When FreeType outputs a bitmap of a glyph, it really outputs an
-   *   alpha coverage map.  If a pixel is completely covered by a
-   *   filled-in outline, the bitmap contains 0xFF at that pixel, meaning
-   *   that 0xFF/0xFF fraction of that pixel is covered, meaning the
-   *   pixel is 100% black (or 0% bright).  If a pixel is only 50%
-   *   covered (value 0x80), the pixel is made 50% black (50% bright or a
-   *   middle shade of grey).  0% covered means 0% black (100% bright or
-   *   white).
+   *   On high-DPI screens like on smartphones and tablets, the pixels are so
+   *   small that their chance of being completely covered and therefore
+   *   completely black are fairly good.  On the low-DPI screens, however,
+   *   the situation is different.  The pixels are too large for most of the
+   *   details of a glyph and shades of gray are the norm rather than the
+   *   exception.
    *
-   *   On high-DPI screens like on smartphones and tablets, the pixels
-   *   are so small that their chance of being completely covered and
-   *   therefore completely black are fairly good.  On the low-DPI
-   *   screens, however, the situation is different.  The pixels are too
-   *   large for most of the details of a glyph and shades of gray are
-   *   the norm rather than the exception.
-   *
-   *   This is relevant because all our screens have a second problem:
-   *   they are not linear.  1~+~1 is not~2.  Twice the value does not
-   *   result in twice the brightness.  When a pixel is only 50% covered,
-   *   the coverage map says 50% black, and this translates to a pixel
-   *   value of 128 when you use 8~bits per channel (0-255).  However,
-   *   this does not translate to 50% brightness for that pixel on our
-   *   sRGB and gamma~2.2 screens.  Due to their non-linearity, they
-   *   dwell longer in the darks and only a pixel value of about 186
-   *   results in 50% brightness -- 128 ends up too dark on both bright
-   *   and dark backgrounds.  The net result is that dark text looks
-   *   burnt-out, pixely and blotchy on bright background, bright text
-   *   too frail on dark backgrounds, and colored text on colored
+   *   This is relevant because all our screens have a second problem: they
+   *   are not linear.  1~+~1 is not~2.  Twice the value does not result in
+   *   twice the brightness.  When a pixel is only 50% covered, the coverage
+   *   map says 50% black, and this translates to a pixel value of 128 when
+   *   you use 8~bits per channel (0-255).  However, this does not translate
+   *   to 50% brightness for that pixel on our sRGB and gamma~2.2 screens.
+   *   Due to their non-linearity, they dwell longer in the darks and only a
+   *   pixel value of about 186 results in 50% brightness -- 128 ends up too
+   *   dark on both bright and dark backgrounds.  The net result is that dark
+   *   text looks burnt-out, pixely and blotchy on bright background, bright
+   *   text too frail on dark backgrounds, and colored text on colored
    *   background (for example, red on green) seems to have dark halos or
-   *   `dirt' around it.  The situation is especially ugly for diagonal
-   *   stems like in `w' glyph shapes where the quality of FreeType's
-   *   anti-aliasing depends on the correct display of grays.  On
-   *   high-DPI screens where smaller, fully black pixels reign supreme,
-   *   this doesn't matter, but on our low-DPI screens with all the gray
-   *   shades, it does.  0% and 100% brightness are the same things in
-   *   linear and non-linear space, just all the shades in-between
-   *   aren't.
+   *   'dirt' around it.  The situation is especially ugly for diagonal stems
+   *   like in 'w' glyph shapes where the quality of FreeType's anti-aliasing
+   *   depends on the correct display of grays.  On high-DPI screens where
+   *   smaller, fully black pixels reign supreme, this doesn't matter, but on
+   *   our low-DPI screens with all the gray shades, it does.  0% and 100%
+   *   brightness are the same things in linear and non-linear space, just
+   *   all the shades in-between aren't.
    *
    *   The blending function for placing text over a background is
    *
-   *   {
+   *   ```
    *     dst = alpha * src + (1 - alpha) * dst    ,
-   *   }
+   *   ```
    *
    *   which is known as the OVER operator.
    *
-   *   To correctly composite an antialiased pixel of a glyph onto a
+   *   To correctly composite an anti-aliased pixel of a glyph onto a
    *   surface,
    *
    *   1. take the foreground and background colors (e.g., in sRGB space)
    *      and apply gamma to get them in a linear space,
    *
    *   2. use OVER to blend the two linear colors using the glyph pixel
-   *      as the alpha value (remember, the glyph bitmap is an alpha
-   *      coverage bitmap), and
+   *      as the alpha value (remember, the glyph bitmap is an alpha coverage
+   *      bitmap), and
    *
    *   3. apply inverse gamma to the blended pixel and write it back to
    *      the image.
    *
-   *   Internal testing at Adobe found that a target inverse gamma of~1.8
-   *   for step~3 gives good results across a wide range of displays with
-   *   an sRGB gamma curve or a similar one.
+   *   Internal testing at Adobe found that a target inverse gamma of~1.8 for
+   *   step~3 gives good results across a wide range of displays with an sRGB
+   *   gamma curve or a similar one.
    *
    *   This process can cost performance.  There is an approximation that
    *   does not need to know about the background color; see
    *   https://bel.fi/alankila/lcd/ and
    *   https://bel.fi/alankila/lcd/alpcor.html for details.
    *
-   *   *ATTENTION*: Linear blending is even more important when dealing
+   *   **ATTENTION**: Linear blending is even more important when dealing
    *   with subpixel-rendered glyphs to prevent color-fringing!  A
    *   subpixel-rendered glyph must first be filtered with a filter that
-   *   gives equal weight to the three color primaries and does not
-   *   exceed a sum of 0x100, see section @lcd_rendering.  Then the
-   *   only difference to gray linear blending is that subpixel-rendered
-   *   linear blending is done 3~times per pixel: red foreground subpixel
-   *   to red background subpixel and so on for green and blue.
+   *   gives equal weight to the three color primaries and does not exceed a
+   *   sum of 0x100, see section @lcd_rendering.  Then the only difference to
+   *   gray linear blending is that subpixel-rendered linear blending is done
+   *   3~times per pixel: red foreground subpixel to red background subpixel
+   *   and so on for green and blue.
    */
   FT_EXPORT( FT_Error )
   FT_Render_Glyph( FT_GlyphSlot    slot,
@@ -3519,23 +3716,20 @@
    *
    * @values:
    *   FT_KERNING_DEFAULT ::
-   *     Return grid-fitted kerning distances in
-   *     26.6 fractional pixels.
+   *     Return grid-fitted kerning distances in 26.6 fractional pixels.
    *
    *   FT_KERNING_UNFITTED ::
-   *     Return un-grid-fitted kerning distances in
-   *     26.6 fractional pixels.
+   *     Return un-grid-fitted kerning distances in 26.6 fractional pixels.
    *
    *   FT_KERNING_UNSCALED ::
-   *     Return the kerning vector in original font
-   *     units.
+   *     Return the kerning vector in original font units.
    *
    * @note:
-   *   FT_KERNING_DEFAULT returns full pixel values; it also makes
-   *   FreeType heuristically scale down kerning distances at small ppem
-   *   values so that they don't become too big.
+   *   `FT_KERNING_DEFAULT` returns full pixel values; it also makes FreeType
+   *   heuristically scale down kerning distances at small ppem values so
+   *   that they don't become too big.
    *
-   *   Both FT_KERNING_DEFAULT and FT_KERNING_UNFITTED use the current
+   *   Both `FT_KERNING_DEFAULT` and `FT_KERNING_UNFITTED` use the current
    *   horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to
    *   convert font units to pixels.
    */
@@ -3549,7 +3743,7 @@
 
 
   /* these constants are deprecated; use the corresponding */
-  /* `FT_Kerning_Mode' values instead                      */
+  /* `FT_Kerning_Mode` values instead                      */
 #define ft_kerning_default   FT_KERNING_DEFAULT
 #define ft_kerning_unfitted  FT_KERNING_UNFITTED
 #define ft_kerning_unscaled  FT_KERNING_UNSCALED
@@ -3574,29 +3768,27 @@
    *     The index of the right glyph in the kern pair.
    *
    *   kern_mode ::
-   *     See @FT_Kerning_Mode for more information.
-   *     Determines the scale and dimension of the returned
-   *     kerning vector.
+   *     See @FT_Kerning_Mode for more information.  Determines the scale and
+   *     dimension of the returned kerning vector.
    *
    * @output:
    *   akerning ::
-   *     The kerning vector.  This is either in font units,
-   *     fractional pixels (26.6 format), or pixels for
-   *     scalable formats, and in pixels for fixed-sizes
-   *     formats.
+   *     The kerning vector.  This is either in font units, fractional pixels
+   *     (26.6 format), or pixels for scalable formats, and in pixels for
+   *     fixed-sizes formats.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Only horizontal layouts (left-to-right & right-to-left) are
-   *   supported by this method.  Other layouts, or more sophisticated
-   *   kernings, are out of the scope of this API function -- they can be
-   *   implemented through format-specific interfaces.
+   *   Only horizontal layouts (left-to-right & right-to-left) are supported
+   *   by this method.  Other layouts, or more sophisticated kernings, are
+   *   out of the scope of this API function -- they can be implemented
+   *   through format-specific interfaces.
    *
-   *   Kerning for OpenType fonts implemented in a `GPOS' table is not
+   *   Kerning for OpenType fonts implemented in a 'GPOS' table is not
    *   supported; use @FT_HAS_KERNING to find out whether a font has data
-   *   that can be extracted with `FT_Get_Kerning'.
+   *   that can be extracted with `FT_Get_Kerning`.
    */
   FT_EXPORT( FT_Error )
   FT_Get_Kerning( FT_Face     face,
@@ -3622,26 +3814,25 @@
    *     The point size in 16.16 fractional points.
    *
    *   degree ::
-   *     The degree of tightness.  Increasingly negative
-   *     values represent tighter track kerning, while
-   *     increasingly positive values represent looser track
-   *     kerning.  Value zero means no track kerning.
+   *     The degree of tightness.  Increasingly negative values represent
+   *     tighter track kerning, while increasingly positive values represent
+   *     looser track kerning.  Value zero means no track kerning.
    *
    * @output:
    *   akerning ::
-   *     The kerning in 16.16 fractional points, to be
-   *     uniformly applied between all glyphs.
+   *     The kerning in 16.16 fractional points, to be uniformly applied
+   *     between all glyphs.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Currently, only the Type~1 font driver supports track kerning,
-   *   using data from AFM files (if attached with @FT_Attach_File or
+   *   Currently, only the Type~1 font driver supports track kerning, using
+   *   data from AFM files (if attached with @FT_Attach_File or
    *   @FT_Attach_Stream).
    *
-   *   Only very few AFM files come with track kerning data; please refer
-   *   to Adobe's AFM specification for more details.
+   *   Only very few AFM files come with track kerning data; please refer to
+   *   Adobe's AFM specification for more details.
    */
   FT_EXPORT( FT_Error )
   FT_Get_Track_Kerning( FT_Face    face,
@@ -3653,99 +3844,11 @@
   /**************************************************************************
    *
    * @function:
-   *   FT_Get_Glyph_Name
-   *
-   * @description:
-   *   Retrieve the ASCII name of a given glyph in a face.  This only
-   *   works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1.
-   *
-   * @input:
-   *   face ::
-   *     A handle to a source face object.
-   *
-   *   glyph_index ::
-   *     The glyph index.
-   *
-   *   buffer_max ::
-   *     The maximum number of bytes available in the
-   *     buffer.
-   *
-   * @output:
-   *   buffer ::
-   *     A pointer to a target buffer where the name is
-   *     copied to.
-   *
-   * @return:
-   *   FreeType error code.  0~means success.
-   *
-   * @note:
-   *   An error is returned if the face doesn't provide glyph names or if
-   *   the glyph index is invalid.  In all cases of failure, the first
-   *   byte of `buffer' is set to~0 to indicate an empty name.
-   *
-   *   The glyph name is truncated to fit within the buffer if it is too
-   *   long.  The returned string is always zero-terminated.
-   *
-   *   Be aware that FreeType reorders glyph indices internally so that
-   *   glyph index~0 always corresponds to the `missing glyph' (called
-   *   `.notdef').
-   *
-   *   This function always returns an error if the config macro
-   *   `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'.
-   */
-  FT_EXPORT( FT_Error )
-  FT_Get_Glyph_Name( FT_Face     face,
-                     FT_UInt     glyph_index,
-                     FT_Pointer  buffer,
-                     FT_UInt     buffer_max );
-
-
-  /**************************************************************************
-   *
-   * @function:
-   *   FT_Get_Postscript_Name
-   *
-   * @description:
-   *   Retrieve the ASCII PostScript name of a given face, if available.
-   *   This only works with PostScript, TrueType, and OpenType fonts.
-   *
-   * @input:
-   *   face ::
-   *     A handle to the source face object.
-   *
-   * @return:
-   *   A pointer to the face's PostScript name.  NULL if unavailable.
-   *
-   * @note:
-   *   The returned pointer is owned by the face and is destroyed with
-   *   it.
-   *
-   *   For variation fonts, this string changes if you select a different
-   *   instance, and you have to call `FT_Get_PostScript_Name' again to
-   *   retrieve it.  FreeType follows Adobe TechNote #5902, `Generating
-   *   PostScript Names for Fonts Using OpenType Font Variations'.
-   *
-   *     https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html
-   *
-   *   [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.
-   */
-  FT_EXPORT( const char* )
-  FT_Get_Postscript_Name( FT_Face  face );
-
-
-  /**************************************************************************
-   *
-   * @function:
    *   FT_Select_Charmap
    *
    * @description:
    *   Select a given charmap by its encoding tag (as listed in
-   *   `freetype.h').
+   *   `freetype.h`).
    *
    * @inout:
    *   face ::
@@ -3759,14 +3862,14 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This function returns an error if no charmap in the face
-   *   corresponds to the encoding queried here.
+   *   This function returns an error if no charmap in the face corresponds
+   *   to the encoding queried here.
    *
    *   Because many fonts contain more than a single cmap for Unicode
-   *   encoding, this function has some special code to select the one
-   *   that covers Unicode best (`best' in the sense that a UCS-4 cmap is
-   *   preferred to a UCS-2 cmap).  It is thus preferable to
-   *   @FT_Set_Charmap in this case.
+   *   encoding, this function has some special code to select the one that
+   *   covers Unicode best ('best' in the sense that a UCS-4 cmap is
+   *   preferred to a UCS-2 cmap).  It is thus preferable to @FT_Set_Charmap
+   *   in this case.
    */
   FT_EXPORT( FT_Error )
   FT_Select_Charmap( FT_Face      face,
@@ -3793,9 +3896,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This function returns an error if the charmap is not part of
-   *   the face (i.e., if it is not listed in the `face->charmaps'
-   *   table).
+   *   This function returns an error if the charmap is not part of the face
+   *   (i.e., if it is not listed in the `face->charmaps` table).
    *
    *   It also fails if an OpenType type~14 charmap is selected (which
    *   doesn't map character codes to glyph indices at all).
@@ -3805,7 +3907,7 @@
                   FT_CharMap  charmap );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Get_Charmap_Index
@@ -3819,7 +3921,7 @@
    *
    * @return:
    *   The index into the array of character maps within the face to which
-   *   `charmap' belongs.  If an error occurs, -1 is returned.
+   *   `charmap` belongs.  If an error occurs, -1 is returned.
    *
    */
   FT_EXPORT( FT_Int )
@@ -3832,8 +3934,8 @@
    *   FT_Get_Char_Index
    *
    * @description:
-   *   Return the glyph index of a given character code.  This function
-   *   uses the currently selected charmap to do the mapping.
+   *   Return the glyph index of a given character code.  This function uses
+   *   the currently selected charmap to do the mapping.
    *
    * @input:
    *   face ::
@@ -3843,20 +3945,19 @@
    *     The character code.
    *
    * @return:
-   *   The glyph index.  0~means `undefined character code'.
+   *   The glyph index.  0~means 'undefined character code'.
    *
    * @note:
-   *   If you use FreeType to manipulate the contents of font files
-   *   directly, be aware that the glyph index returned by this function
-   *   doesn't always correspond to the internal indices used within the
-   *   file.  This is done to ensure that value~0 always corresponds to
-   *   the `missing glyph'.  If the first glyph is not named `.notdef',
-   *   then for Type~1 and Type~42 fonts, `.notdef' will be moved into
-   *   the glyph ID~0 position, and whatever was there will be moved to
-   *   the position `.notdef' had.  For Type~1 fonts, if there is no
-   *   `.notdef' glyph at all, then one will be created at index~0 and
-   *   whatever was there will be moved to the last index -- Type~42
-   *   fonts are considered invalid under this condition.
+   *   If you use FreeType to manipulate the contents of font files directly,
+   *   be aware that the glyph index returned by this function doesn't always
+   *   correspond to the internal indices used within the file.  This is done
+   *   to ensure that value~0 always corresponds to the 'missing glyph'.  If
+   *   the first glyph is not named '.notdef', then for Type~1 and Type~42
+   *   fonts, '.notdef' will be moved into the glyph ID~0 position, and
+   *   whatever was there will be moved to the position '.notdef' had.  For
+   *   Type~1 fonts, if there is no '.notdef' glyph at all, then one will be
+   *   created at index~0 and whatever was there will be moved to the last
+   *   index -- Type~42 fonts are considered invalid under this condition.
    */
   FT_EXPORT( FT_UInt )
   FT_Get_Char_Index( FT_Face   face,
@@ -3878,18 +3979,17 @@
    *
    * @output:
    *   agindex ::
-   *     Glyph index of first character code.  0~if charmap is
-   *     empty.
+   *     Glyph index of first character code.  0~if charmap is empty.
    *
    * @return:
    *   The charmap's first character code.
    *
    * @note:
-   *   You should use this function together with @FT_Get_Next_Char to
-   *   parse all character codes available in a given charmap.  The code
-   *   should look like this:
+   *   You should use this function together with @FT_Get_Next_Char to parse
+   *   all character codes available in a given charmap.  The code should
+   *   look like this:
    *
-   *   {
+   *   ```
    *     FT_ULong  charcode;
    *     FT_UInt   gindex;
    *
@@ -3901,18 +4001,18 @@
    *
    *       charcode = FT_Get_Next_Char( face, charcode, &gindex );
    *     }
-   *   }
+   *   ```
    *
-   *   Be aware that character codes can have values up to 0xFFFFFFFF;
-   *   this might happen for non-Unicode or malformed cmaps.  However,
-   *   even with regular Unicode encoding, so-called `last resort fonts'
-   *   (using SFNT cmap format 13, see function @FT_Get_CMap_Format)
-   *   normally have entries for all Unicode characters up to 0x1FFFFF,
-   *   which can cause *a lot* of iterations.
+   *   Be aware that character codes can have values up to 0xFFFFFFFF; this
+   *   might happen for non-Unicode or malformed cmaps.  However, even with
+   *   regular Unicode encoding, so-called 'last resort fonts' (using SFNT
+   *   cmap format 13, see function @FT_Get_CMap_Format) normally have
+   *   entries for all Unicode characters up to 0x1FFFFF, which can cause *a
+   *   lot* of iterations.
    *
-   *   Note that `*agindex' is set to~0 if the charmap is empty.  The
-   *   result itself can be~0 in two cases: if the charmap is empty or
-   *   if the value~0 is the first valid character code.
+   *   Note that `*agindex` is set to~0 if the charmap is empty.  The result
+   *   itself can be~0 in two cases: if the charmap is empty or if the
+   *   value~0 is the first valid character code.
    */
   FT_EXPORT( FT_ULong )
   FT_Get_First_Char( FT_Face   face,
@@ -3925,9 +4025,9 @@
    *   FT_Get_Next_Char
    *
    * @description:
-   *   Return the next character code in the current charmap of a given
-   *   face following the value `char_code', as well as the corresponding
-   *   glyph index.
+   *   Return the next character code in the current charmap of a given face
+   *   following the value `char_code`, as well as the corresponding glyph
+   *   index.
    *
    * @input:
    *   face ::
@@ -3938,19 +4038,18 @@
    *
    * @output:
    *   agindex ::
-   *     Glyph index of next character code.  0~if charmap
-   *     is empty.
+   *     Glyph index of next character code.  0~if charmap is empty.
    *
    * @return:
    *   The charmap's next character code.
    *
    * @note:
-   *   You should use this function with @FT_Get_First_Char to walk
-   *   over all character codes available in a given charmap.  See the
-   *   note for that function for a simple code example.
+   *   You should use this function with @FT_Get_First_Char to walk over all
+   *   character codes available in a given charmap.  See the note for that
+   *   function for a simple code example.
    *
-   *   Note that `*agindex' is set to~0 when there are no more codes in
-   *   the charmap.
+   *   Note that `*agindex` is set to~0 when there are no more codes in the
+   *   charmap.
    */
   FT_EXPORT( FT_ULong )
   FT_Get_Next_Char( FT_Face    face,
@@ -3958,7 +4057,7 @@
                     FT_UInt   *agindex );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Face_Properties
@@ -3966,27 +4065,26 @@
    * @description:
    *   Set or override certain (library or module-wide) properties on a
    *   face-by-face basis.  Useful for finer-grained control and avoiding
-   *   locks on shared structures (threads can modify their own faces as
-   *   they see fit).
+   *   locks on shared structures (threads can modify their own faces as they
+   *   see fit).
    *
-   *   Contrary to @FT_Property_Set, this function uses @FT_Parameter so
-   *   that you can pass multiple properties to the target face in one call.
-   *   Note that only a subset of the available properties can be
-   *   controlled.
+   *   Contrary to @FT_Property_Set, this function uses @FT_Parameter so that
+   *   you can pass multiple properties to the target face in one call.  Note
+   *   that only a subset of the available properties can be controlled.
    *
    *   * @FT_PARAM_TAG_STEM_DARKENING (stem darkening, corresponding to the
-   *     property `no-stem-darkening' provided by the `autofit', `cff',
-   *     `type1', and `t1cid' modules; see @no-stem-darkening).
+   *     property `no-stem-darkening` provided by the 'autofit', 'cff',
+   *     'type1', and 't1cid' modules; see @no-stem-darkening).
    *
    *   * @FT_PARAM_TAG_LCD_FILTER_WEIGHTS (LCD filter weights, corresponding
    *     to function @FT_Library_SetLcdFilterWeights).
    *
    *   * @FT_PARAM_TAG_RANDOM_SEED (seed value for the CFF, Type~1, and CID
-   *     `random' operator, corresponding to the `random-seed' property
-   *     provided by the `cff', `type1', and `t1cid' modules; see
+   *     'random' operator, corresponding to the `random-seed` property
+   *     provided by the 'cff', 'type1', and 't1cid' modules; see
    *     @random-seed).
    *
-   *   Pass NULL as `data' in @FT_Parameter for a given tag to reset the
+   *   Pass `NULL` as `data` in @FT_Parameter for a given tag to reset the
    *   option and use the library or module default again.
    *
    * @input:
@@ -3997,17 +4095,17 @@
    *     The number of properties that follow.
    *
    *   properties ::
-   *     A handle to an @FT_Parameter array with `num_properties' elements.
+   *     A handle to an @FT_Parameter array with `num_properties` elements.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @example:
-   *   Here an example that sets three properties.  You must define
-   *   FT_CONFIG_OPTION_SUBPIXEL_RENDERING to make the LCD filter examples
+   *   Here is an example that sets three properties.  You must define
+   *   `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` to make the LCD filter examples
    *   work.
    *
-   *   {
+   *   ```
    *     FT_Parameter         property1;
    *     FT_Bool              darken_stems = 1;
    *
@@ -4033,11 +4131,11 @@
    *     property3.data = &random_seed;
    *
    *     FT_Face_Properties( face, 3, properties );
-   *   }
+   *   ```
    *
    *   The next example resets a single property to its default value.
    *
-   *   {
+   *   ```
    *     FT_Parameter  property;
    *
    *
@@ -4045,7 +4143,7 @@
    *     property.data = NULL;
    *
    *     FT_Face_Properties( face, 1, &property );
-   *   }
+   *   ```
    *
    * @since:
    *   2.8
@@ -4063,7 +4161,8 @@
    *   FT_Get_Name_Index
    *
    * @description:
-   *   Return the glyph index of a given glyph name.
+   *   Return the glyph index of a given glyph name.  This only works
+   *   for those faces where @FT_HAS_GLYPH_NAMES returns true.
    *
    * @input:
    *   face ::
@@ -4073,23 +4172,117 @@
    *     The glyph name.
    *
    * @return:
-   *   The glyph index.  0~means `undefined character code'.
+   *   The glyph index.  0~means 'undefined character code'.
+   *
+   * @note:
+   *   Acceptable glyph names might come from the [Adobe Glyph
+   *   List](https://github.com/adobe-type-tools/agl-aglfn).  See
+   *   @FT_Get_Glyph_Name for the inverse functionality.
+   *
+   *   This function has limited capabilities if the config macro
+   *   `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` is not defined in `ftoption.h`:
+   *   It then works only for fonts that actually embed glyph names (which
+   *   many recent OpenType fonts do not).
    */
   FT_EXPORT( FT_UInt )
-  FT_Get_Name_Index( FT_Face     face,
-                     FT_String*  glyph_name );
+  FT_Get_Name_Index( FT_Face           face,
+                     const FT_String*  glyph_name );
 
 
-  /*************************************************************************
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Glyph_Name
+   *
+   * @description:
+   *   Retrieve the ASCII name of a given glyph in a face.  This only works
+   *   for those faces where @FT_HAS_GLYPH_NAMES returns true.
+   *
+   * @input:
+   *   face ::
+   *     A handle to a source face object.
+   *
+   *   glyph_index ::
+   *     The glyph index.
+   *
+   *   buffer_max ::
+   *     The maximum number of bytes available in the buffer.
+   *
+   * @output:
+   *   buffer ::
+   *     A pointer to a target buffer where the name is copied to.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   An error is returned if the face doesn't provide glyph names or if the
+   *   glyph index is invalid.  In all cases of failure, the first byte of
+   *   `buffer` is set to~0 to indicate an empty name.
+   *
+   *   The glyph name is truncated to fit within the buffer if it is too
+   *   long.  The returned string is always zero-terminated.
+   *
+   *   Be aware that FreeType reorders glyph indices internally so that glyph
+   *   index~0 always corresponds to the 'missing glyph' (called '.notdef').
+   *
+   *   This function has limited capabilities if the config macro
+   *   `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` is not defined in `ftoption.h`:
+   *   It then works only for fonts that actually embed glyph names (which
+   *   many recent OpenType fonts do not).
+   */
+  FT_EXPORT( FT_Error )
+  FT_Get_Glyph_Name( FT_Face     face,
+                     FT_UInt     glyph_index,
+                     FT_Pointer  buffer,
+                     FT_UInt     buffer_max );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Postscript_Name
+   *
+   * @description:
+   *   Retrieve the ASCII PostScript name of a given face, if available.
+   *   This only works with PostScript, TrueType, and OpenType fonts.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the source face object.
+   *
+   * @return:
+   *   A pointer to the face's PostScript name.  `NULL` if unavailable.
+   *
+   * @note:
+   *   The returned pointer is owned by the face and is destroyed with it.
+   *
+   *   For variation fonts, this string changes if you select a different
+   *   instance, and you have to call `FT_Get_PostScript_Name` again to
+   *   retrieve it.  FreeType follows Adobe TechNote #5902, 'Generating
+   *   PostScript Names for Fonts Using OpenType Font Variations'.
+   *
+   *     https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html
+   *
+   *   [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.
+   */
+  FT_EXPORT( const char* )
+  FT_Get_Postscript_Name( FT_Face  face );
+
+
+  /**************************************************************************
    *
    * @enum:
    *   FT_SUBGLYPH_FLAG_XXX
    *
    * @description:
-   *   A list of constants describing subglyphs.  Please refer to the
-   *   `glyf' table description in the OpenType specification for the
-   *   meaning of the various flags (which get synthesized for
-   *   non-OpenType subglyphs).
+   *   A list of constants describing subglyphs.  Please refer to the 'glyf'
+   *   table description in the OpenType specification for the meaning of the
+   *   various flags (which get synthesized for non-OpenType subglyphs).
    *
    *     https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description
    *
@@ -4112,15 +4305,15 @@
 #define FT_SUBGLYPH_FLAG_USE_MY_METRICS      0x200
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Get_SubGlyph_Info
    *
    * @description:
    *   Retrieve a description of a given subglyph.  Only use it if
-   *   `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is
-   *   returned otherwise.
+   *   `glyph->format` is @FT_GLYPH_FORMAT_COMPOSITE; an error is returned
+   *   otherwise.
    *
    * @input:
    *   glyph ::
@@ -4128,7 +4321,7 @@
    *
    *   sub_index ::
    *     The index of the subglyph.  Must be less than
-   *     `glyph->num_subglyphs'.
+   *     `glyph->num_subglyphs`.
    *
    * @output:
    *   p_index ::
@@ -4150,10 +4343,12 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The values of `*p_arg1', `*p_arg2', and `*p_transform' must be
-   *   interpreted depending on the flags returned in `*p_flags'.  See the
+   *   The values of `*p_arg1`, `*p_arg2`, and `*p_transform` must be
+   *   interpreted depending on the flags returned in `*p_flags`.  See the
    *   OpenType specification for details.
    *
+   *     https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description
+   *
    */
   FT_EXPORT( FT_Error )
   FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,
@@ -4167,183 +4362,15 @@
 
   /**************************************************************************
    *
-   * @section:
-   *   layer_management
-   *
-   * @title:
-   *   Glyph Layer Management
-   *
-   * @abstract:
-   *   Retrieving and manipulating OpenType's `COLR' table data.
-   *
-   * @description:
-   *   The functions described here allow access of colored glyph layer data
-   *   in OpenType's `COLR' tables.
-   */
-
-
-  /**********************************************************************
-   *
-   * @struct:
-   *   FT_LayerIterator
-   *
-   * @description:
-   *   This iterator object is needed for @FT_Get_Color_Glyph_Layer.
-   *
-   * @fields:
-   *   num_layers ::
-   *     The number of glyph layers for the requested glyph index.  Will be
-   *     set by @FT_Get_Color_Glyph_Layer.
-   *
-   *   layer ::
-   *     The current layer.  Will be set by @FT_Get_Color_Glyph_Layer.
-   *
-   *   p ::
-   *     An opaque pointer into `COLR' table data.  The caller must set this
-   *     to NULL before the first call of @FT_Get_Color_Glyph_Layer.
-   */
-  typedef struct  FT_LayerIterator_
-  {
-    FT_UInt   num_layers;
-    FT_UInt   layer;
-    FT_Byte*  p;
-
-  } FT_LayerIterator;
-
-
-  /*************************************************************************
-   *
-   * @function:
-   *   FT_Get_Color_Glyph_Layer
-   *
-   * @description:
-   *   This is an interface to the `COLR' table in OpenType fonts to
-   *   iteratively retrieve the colored glyph layers associated with the
-   *   current glyph slot.
-   *
-   *     https://docs.microsoft.com/en-us/typography/opentype/spec/colr
-   *
-   *   The glyph layer data for a given glyph index, if present, provides an
-   *   alternative, multi-colour glyph representation: Instead of rendering
-   *   the outline or bitmap with the given glyph index, glyphs with the
-   *   indices and colors returned by this function are rendered layer by
-   *   layer.
-   *
-   *   The returned elements are ordered in the z~direction from bottom to
-   *   top; the `n'th element should be rendered with the associated palette
-   *   color and blended on top of the already rendered layers (elements 0,
-   *   1, ..., n-1).
-   *
-   * @input:
-   *   face ::
-   *     A handle to the parent face object.
-   *
-   *   base_glyph ::
-   *     The glyph index the colored glyph layers are associated with.
-   *
-   * @inout:
-   *   iterator ::
-   *     An @FT_LayerIterator object.  For the first call you should set
-   *     `iterator->p' to NULL.  For all following calls, simply use the
-   *     same object again.
-   *
-   * @output:
-   *   aglyph_index ::
-   *     The glyph index of the current layer.
-   *
-   *   acolor_index ::
-   *     The color index into the font face's color palette of the current
-   *     layer.  The value 0xFFFF is special; it doesn't reference a palette
-   *     entry but indicates that the text foreground color should be used
-   *     instead (to be set up by the application outside of FreeType).
-   *
-   *     The color palette can be retrieved with @FT_Palette_Select.
-   *
-   * @return:
-   *   Value~1 if everything is OK.  If there are no more layers (or if
-   *   there are no layers at all), value~0 gets returned.  In case of an
-   *   error, value~0 is returned also.
-   *
-   * @note:
-   *   This function is necessary if you want to handle glyph layers by
-   *   yourself.  In particular, functions that operate with @FT_GlyphRec
-   *   objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access
-   *   to this information.
-   *
-   *   @FT_Render_Glyph, however, handles colored glyph layers
-   *   automatically if the @FT_LOAD_COLOR flag is passed to it.
-   *
-   * @example:
-   *   {
-   *     FT_Color*         palette;
-   *     FT_LayerIterator  iterator;
-   *
-   *     FT_Bool  have_layers;
-   *     FT_UInt  layer_glyph_index;
-   *     FT_UInt  layer_color_index;
-   *
-   *
-   *     error = FT_Palette_Select( face, palette_index, &palette );
-   *     if ( error )
-   *       palette = NULL;
-   *
-   *     iterator.p  = NULL;
-   *     have_layers = FT_Get_Color_Glyph_Layer( face,
-   *                                             glyph_index,
-   *                                             &layer_glyph_index,
-   *                                             &layer_color_index,
-   *                                             &iterator );
-   *
-   *     if ( palette && have_layers )
-   *     {
-   *       do
-   *       {
-   *         FT_Color  layer_color;
-   *
-   *
-   *         if ( layer_color_index == 0xFFFF )
-   *           layer_color = text_foreground_color;
-   *         else
-   *           layer_color = palette[layer_color_index];
-   *
-   *         // Load and render glyph `layer_glyph_index', then
-   *         // blend resulting pixmap (using color `layer_color')
-   *         // with previously created pixmaps.
-   *
-   *       } while ( FT_Get_Color_Glyph_Layer( face,
-   *                                           glyph_index,
-   *                                           &layer_glyph_index,
-   *                                           &layer_color_index,
-   *                                           &iterator ) );
-   *     }
-   *   }
-   */
-  FT_EXPORT( FT_Bool )
-  FT_Get_Color_Glyph_Layer( FT_Face            face,
-                            FT_UInt            base_glyph,
-                            FT_UInt           *aglyph_index,
-                            FT_UInt           *acolor_index,
-                            FT_LayerIterator*  iterator );
-
-
-  /**************************************************************************
-   *
-   * @section:
-   *   base_interface
-   *
-   */
-
-  /**************************************************************************
-   *
    * @enum:
    *   FT_FSTYPE_XXX
    *
    * @description:
-   *   A list of bit flags used in the `fsType' field of the OS/2 table
-   *   in a TrueType or OpenType font and the `FSType' entry in a
-   *   PostScript font.  These bit flags are returned by
-   *   @FT_Get_FSType_Flags; they inform client applications of embedding
-   *   and subsetting restrictions associated with a font.
+   *   A list of bit flags used in the `fsType` field of the OS/2 table in a
+   *   TrueType or OpenType font and the `FSType` entry in a PostScript font.
+   *   These bit flags are returned by @FT_Get_FSType_Flags; they inform
+   *   client applications of embedding and subsetting restrictions
+   *   associated with a font.
    *
    *   See
    *   https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf
@@ -4355,36 +4382,36 @@
    *     installed on the remote system by an application.
    *
    *   FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING ::
-   *     Fonts that have only this bit set must not be modified, embedded
-   *     or exchanged in any manner without first obtaining permission of
-   *     the font software copyright owner.
+   *     Fonts that have only this bit set must not be modified, embedded or
+   *     exchanged in any manner without first obtaining permission of the
+   *     font software copyright owner.
    *
    *   FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING ::
    *     The font may be embedded and temporarily loaded on the remote
-   *     system.  Documents containing Preview & Print fonts must be
-   *     opened `read-only'; no edits can be applied to the document.
+   *     system.  Documents containing Preview & Print fonts must be opened
+   *     'read-only'; no edits can be applied to the document.
    *
    *   FT_FSTYPE_EDITABLE_EMBEDDING ::
-   *     The font may be embedded but must only be installed temporarily
-   *     on other systems.  In contrast to Preview & Print fonts,
-   *     documents containing editable fonts may be opened for reading,
-   *     editing is permitted, and changes may be saved.
+   *     The font may be embedded but must only be installed temporarily on
+   *     other systems.  In contrast to Preview & Print fonts, documents
+   *     containing editable fonts may be opened for reading, editing is
+   *     permitted, and changes may be saved.
    *
    *   FT_FSTYPE_NO_SUBSETTING ::
    *     The font may not be subsetted prior to embedding.
    *
    *   FT_FSTYPE_BITMAP_EMBEDDING_ONLY ::
-   *     Only bitmaps contained in the font may be embedded; no outline
-   *     data may be embedded.  If there are no bitmaps available in the
-   *     font, then the font is unembeddable.
+   *     Only bitmaps contained in the font may be embedded; no outline data
+   *     may be embedded.  If there are no bitmaps available in the font,
+   *     then the font is unembeddable.
    *
    * @note:
    *   The flags are ORed together, thus more than a single value can be
    *   returned.
    *
-   *   While the `fsType' flags can indicate that a font may be embedded,
-   *   a license with the font vendor may be separately required to use
-   *   the font in this way.
+   *   While the `fsType` flags can indicate that a font may be embedded, a
+   *   license with the font vendor may be separately required to use the
+   *   font in this way.
    */
 #define FT_FSTYPE_INSTALLABLE_EMBEDDING         0x0000
 #define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING  0x0002
@@ -4400,22 +4427,23 @@
    *   FT_Get_FSType_Flags
    *
    * @description:
-   *   Return the `fsType' flags for a font.
+   *   Return the `fsType` flags for a font.
    *
    * @input:
    *   face ::
    *     A handle to the source face object.
    *
    * @return:
-   *   The `fsType' flags, see @FT_FSTYPE_XXX.
+   *   The `fsType` flags, see @FT_FSTYPE_XXX.
    *
    * @note:
-   *   Use this function rather than directly reading the `fs_type' field
-   *   in the @PS_FontInfoRec structure, which is only guaranteed to
-   *   return the correct results for Type~1 fonts.
+   *   Use this function rather than directly reading the `fs_type` field in
+   *   the @PS_FontInfoRec structure, which is only guaranteed to return the
+   *   correct results for Type~1 fonts.
    *
    * @since:
    *   2.3.8
+   *
    */
   FT_EXPORT( FT_UShort )
   FT_Get_FSType_Flags( FT_Face  face );
@@ -4430,48 +4458,45 @@
    *   Unicode Variation Sequences
    *
    * @abstract:
-   *   The FreeType~2 interface to Unicode Variation Sequences (UVS),
-   *   using the SFNT cmap format~14.
+   *   The FreeType~2 interface to Unicode Variation Sequences (UVS), using
+   *   the SFNT cmap format~14.
    *
    * @description:
-   *   Many characters, especially for CJK scripts, have variant forms.
-   *   They are a sort of grey area somewhere between being totally
-   *   irrelevant and semantically distinct; for this reason, the Unicode
-   *   consortium decided to introduce Variation Sequences (VS),
-   *   consisting of a Unicode base character and a variation selector
-   *   instead of further extending the already huge number of
-   *   characters.
+   *   Many characters, especially for CJK scripts, have variant forms.  They
+   *   are a sort of grey area somewhere between being totally irrelevant and
+   *   semantically distinct; for this reason, the Unicode consortium decided
+   *   to introduce Variation Sequences (VS), consisting of a Unicode base
+   *   character and a variation selector instead of further extending the
+   *   already huge number of characters.
    *
-   *   Unicode maintains two different sets, namely `Standardized
-   *   Variation Sequences' and registered `Ideographic Variation
-   *   Sequences' (IVS), collected in the `Ideographic Variation
-   *   Database' (IVD).
+   *   Unicode maintains two different sets, namely 'Standardized Variation
+   *   Sequences' and registered 'Ideographic Variation Sequences' (IVS),
+   *   collected in the 'Ideographic Variation Database' (IVD).
    *
    *     https://unicode.org/Public/UCD/latest/ucd/StandardizedVariants.txt
-   *     https://unicode.org/reports/tr37/
-   *     https://unicode.org/ivd/
+   *     https://unicode.org/reports/tr37/ https://unicode.org/ivd/
    *
    *   To date (January 2017), the character with the most ideographic
    *   variations is U+9089, having 32 such IVS.
    *
-   *   Three Mongolian Variation Selectors have the values U+180B-U+180D;
-   *   256 generic Variation Selectors are encoded in the ranges
-   *   U+FE00-U+FE0F and U+E0100-U+E01EF.  IVS currently use Variation
-   *   Selectors from the range U+E0100-U+E01EF only.
+   *   Three Mongolian Variation Selectors have the values U+180B-U+180D; 256
+   *   generic Variation Selectors are encoded in the ranges U+FE00-U+FE0F
+   *   and U+E0100-U+E01EF.  IVS currently use Variation Selectors from the
+   *   range U+E0100-U+E01EF only.
    *
    *   A VS consists of the base character value followed by a single
    *   Variation Selector.  For example, to get the first variation of
-   *   U+9089, you have to write the character sequence `U+9089 U+E0100'.
+   *   U+9089, you have to write the character sequence `U+9089 U+E0100`.
    *
-   *   Adobe and MS decided to support both standardized and ideographic
-   *   VS with a new cmap subtable (format~14).  It is an odd subtable
-   *   because it is not a mapping of input code points to glyphs, but
-   *   contains lists of all variations supported by the font.
+   *   Adobe and MS decided to support both standardized and ideographic VS
+   *   with a new cmap subtable (format~14).  It is an odd subtable because
+   *   it is not a mapping of input code points to glyphs, but contains lists
+   *   of all variations supported by the font.
    *
-   *   A variation may be either `default' or `non-default' for a given
-   *   font.  A default variation is the one you will get for that code
-   *   point if you look it up in the standard Unicode cmap.  A
-   *   non-default variation is a different glyph.
+   *   A variation may be either 'default' or 'non-default' for a given font.
+   *   A default variation is the one you will get for that code point if you
+   *   look it up in the standard Unicode cmap.  A non-default variation is a
+   *   different glyph.
    *
    */
 
@@ -4482,8 +4507,8 @@
    *   FT_Face_GetCharVariantIndex
    *
    * @description:
-   *   Return the glyph index of a given character code as modified by
-   *   the variation selector.
+   *   Return the glyph index of a given character code as modified by the
+   *   variation selector.
    *
    * @input:
    *   face ::
@@ -4496,24 +4521,23 @@
    *     The Unicode code point of the variation selector.
    *
    * @return:
-   *   The glyph index.  0~means either `undefined character code', or
-   *   `undefined selector code', or `no variation selector cmap
-   *   subtable', or `current CharMap is not Unicode'.
+   *   The glyph index.  0~means either 'undefined character code', or
+   *   'undefined selector code', or 'no variation selector cmap subtable',
+   *   or 'current CharMap is not Unicode'.
    *
    * @note:
-   *   If you use FreeType to manipulate the contents of font files
-   *   directly, be aware that the glyph index returned by this function
-   *   doesn't always correspond to the internal indices used within
-   *   the file.  This is done to ensure that value~0 always corresponds
-   *   to the `missing glyph'.
+   *   If you use FreeType to manipulate the contents of font files directly,
+   *   be aware that the glyph index returned by this function doesn't always
+   *   correspond to the internal indices used within the file.  This is done
+   *   to ensure that value~0 always corresponds to the 'missing glyph'.
    *
    *   This function is only meaningful if
-   *     a) the font has a variation selector cmap sub table,
-   *   and
+   *     a) the font has a variation selector cmap sub table, and
    *     b) the current charmap has a Unicode encoding.
    *
    * @since:
    *   2.3.6
+   *
    */
   FT_EXPORT( FT_UInt )
   FT_Face_GetCharVariantIndex( FT_Face   face,
@@ -4527,8 +4551,8 @@
    *   FT_Face_GetCharVariantIsDefault
    *
    * @description:
-   *   Check whether this variation of this Unicode character is the one
-   *   to be found in the `cmap'.
+   *   Check whether this variation of this Unicode character is the one to
+   *   be found in the charmap.
    *
    * @input:
    *   face ::
@@ -4541,15 +4565,16 @@
    *     The Unicode codepoint of the variation selector.
    *
    * @return:
-   *   1~if found in the standard (Unicode) cmap, 0~if found in the
-   *   variation selector cmap, or -1 if it is not a variation.
+   *   1~if found in the standard (Unicode) cmap, 0~if found in the variation
+   *   selector cmap, or -1 if it is not a variation.
    *
    * @note:
-   *   This function is only meaningful if the font has a variation
-   *   selector cmap subtable.
+   *   This function is only meaningful if the font has a variation selector
+   *   cmap subtable.
    *
    * @since:
    *   2.3.6
+   *
    */
   FT_EXPORT( FT_Int )
   FT_Face_GetCharVariantIsDefault( FT_Face   face,
@@ -4563,24 +4588,25 @@
    *   FT_Face_GetVariantSelectors
    *
    * @description:
-   *   Return a zero-terminated list of Unicode variation selectors found
-   *   in the font.
+   *   Return a zero-terminated list of Unicode variation selectors found in
+   *   the font.
    *
    * @input:
    *   face ::
    *     A handle to the source face object.
    *
    * @return:
-   *   A pointer to an array of selector code points, or NULL if there is
+   *   A pointer to an array of selector code points, or `NULL` if there is
    *   no valid variation selector cmap subtable.
    *
    * @note:
-   *   The last item in the array is~0; the array is owned by the
-   *   @FT_Face object but can be overwritten or released on the next
-   *   call to a FreeType function.
+   *   The last item in the array is~0; the array is owned by the @FT_Face
+   *   object but can be overwritten or released on the next call to a
+   *   FreeType function.
    *
    * @since:
    *   2.3.6
+   *
    */
   FT_EXPORT( FT_UInt32* )
   FT_Face_GetVariantSelectors( FT_Face  face );
@@ -4592,8 +4618,8 @@
    *   FT_Face_GetVariantsOfChar
    *
    * @description:
-   *   Return a zero-terminated list of Unicode variation selectors found
-   *   for the specified character code.
+   *   Return a zero-terminated list of Unicode variation selectors found for
+   *   the specified character code.
    *
    * @input:
    *   face ::
@@ -4604,16 +4630,17 @@
    *
    * @return:
    *   A pointer to an array of variation selector code points that are
-   *   active for the given character, or NULL if the corresponding list
-   *   is empty.
+   *   active for the given character, or `NULL` if the corresponding list is
+   *   empty.
    *
    * @note:
-   *   The last item in the array is~0; the array is owned by the
-   *   @FT_Face object but can be overwritten or released on the next
-   *   call to a FreeType function.
+   *   The last item in the array is~0; the array is owned by the @FT_Face
+   *   object but can be overwritten or released on the next call to a
+   *   FreeType function.
    *
    * @since:
    *   2.3.6
+   *
    */
   FT_EXPORT( FT_UInt32* )
   FT_Face_GetVariantsOfChar( FT_Face   face,
@@ -4626,8 +4653,8 @@
    *   FT_Face_GetCharsOfVariant
    *
    * @description:
-   *   Return a zero-terminated list of Unicode character codes found for
-   *   the specified variation selector.
+   *   Return a zero-terminated list of Unicode character codes found for the
+   *   specified variation selector.
    *
    * @input:
    *   face ::
@@ -4638,16 +4665,17 @@
    *
    * @return:
    *   A list of all the code points that are specified by this selector
-   *   (both default and non-default codes are returned) or NULL if there
+   *   (both default and non-default codes are returned) or `NULL` if there
    *   is no valid cmap or the variation selector is invalid.
    *
    * @note:
-   *   The last item in the array is~0; the array is owned by the
-   *   @FT_Face object but can be overwritten or released on the next
-   *   call to a FreeType function.
+   *   The last item in the array is~0; the array is owned by the @FT_Face
+   *   object but can be overwritten or released on the next call to a
+   *   FreeType function.
    *
    * @since:
    *   2.3.6
+   *
    */
   FT_EXPORT( FT_UInt32* )
   FT_Face_GetCharsOfVariant( FT_Face   face,
@@ -4666,8 +4694,14 @@
    *   Crunching fixed numbers and vectors.
    *
    * @description:
-   *   This section contains various functions used to perform
-   *   computations on 16.16 fixed-float numbers or 2d vectors.
+   *   This section contains various functions used to perform computations
+   *   on 16.16 fixed-point numbers or 2D vectors.  FreeType does not use
+   *   floating-point data types.
+   *
+   *   **Attention**: Most arithmetic functions take `FT_Long` as arguments.
+   *   For historical reasons, FreeType was designed under the assumption
+   *   that `FT_Long` is a 32-bit integer; results can thus be undefined if
+   *   the arguments don't fit into 32 bits.
    *
    * @order:
    *   FT_MulDiv
@@ -4689,8 +4723,8 @@
    *   FT_MulDiv
    *
    * @description:
-   *   Compute `(a*b)/c' with maximum accuracy, using a 64-bit
-   *   intermediate integer whenever necessary.
+   *   Compute `(a*b)/c` with maximum accuracy, using a 64-bit intermediate
+   *   integer whenever necessary.
    *
    *   This function isn't necessarily as fast as some processor-specific
    *   operations, but is at least completely portable.
@@ -4706,9 +4740,9 @@
    *     The divisor.
    *
    * @return:
-   *   The result of `(a*b)/c'.  This function never traps when trying to
-   *   divide by zero; it simply returns `MaxInt' or `MinInt' depending
-   *   on the signs of `a' and `b'.
+   *   The result of `(a*b)/c`.  This function never traps when trying to
+   *   divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on
+   *   the signs of `a` and `b`.
    */
   FT_EXPORT( FT_Long )
   FT_MulDiv( FT_Long  a,
@@ -4722,7 +4756,7 @@
    *   FT_MulFix
    *
    * @description:
-   *   Compute `(a*b)/0x10000' with maximum accuracy.  Its main use is to
+   *   Compute `(a*b)/0x10000` with maximum accuracy.  Its main use is to
    *   multiply a given value by a 16.16 fixed-point factor.
    *
    * @input:
@@ -4730,22 +4764,21 @@
    *     The first multiplier.
    *
    *   b ::
-   *     The second multiplier.  Use a 16.16 factor here whenever
-   *     possible (see note below).
+   *     The second multiplier.  Use a 16.16 factor here whenever possible
+   *     (see note below).
    *
    * @return:
-   *   The result of `(a*b)/0x10000'.
+   *   The result of `(a*b)/0x10000`.
    *
    * @note:
-   *   This function has been optimized for the case where the absolute
-   *   value of `a' is less than 2048, and `b' is a 16.16 scaling factor.
-   *   As this happens mainly when scaling from notional units to
-   *   fractional pixels in FreeType, it resulted in noticeable speed
-   *   improvements between versions 2.x and 1.x.
+   *   This function has been optimized for the case where the absolute value
+   *   of `a` is less than 2048, and `b` is a 16.16 scaling factor.  As this
+   *   happens mainly when scaling from notional units to fractional pixels
+   *   in FreeType, it resulted in noticeable speed improvements between
+   *   versions 2.x and 1.x.
    *
-   *   As a conclusion, always try to place a 16.16 factor as the
-   *   _second_ argument of this function; this can make a great
-   *   difference.
+   *   As a conclusion, always try to place a 16.16 factor as the _second_
+   *   argument of this function; this can make a great difference.
    */
   FT_EXPORT( FT_Long )
   FT_MulFix( FT_Long  a,
@@ -4758,7 +4791,7 @@
    *   FT_DivFix
    *
    * @description:
-   *   Compute `(a*0x10000)/b' with maximum accuracy.  Its main use is to
+   *   Compute `(a*0x10000)/b` with maximum accuracy.  Its main use is to
    *   divide a given value by a 16.16 fixed-point factor.
    *
    * @input:
@@ -4769,7 +4802,7 @@
    *     The denominator.  Use a 16.16 factor here.
    *
    * @return:
-   *   The result of `(a*0x10000)/b'.
+   *   The result of `(a*0x10000)/b`.
    */
   FT_EXPORT( FT_Long )
   FT_DivFix( FT_Long  a,
@@ -4789,7 +4822,7 @@
    *     The number to be rounded.
    *
    * @return:
-   *   `a' rounded to the nearest 16.16 fixed integer, halfway cases away
+   *   `a` rounded to the nearest 16.16 fixed integer, halfway cases away
    *   from zero.
    *
    * @note:
@@ -4812,7 +4845,7 @@
    *     The number for which the ceiling function is to be computed.
    *
    * @return:
-   *   `a' rounded towards plus infinity.
+   *   `a` rounded towards plus infinity.
    *
    * @note:
    *   The function uses wrap-around arithmetic.
@@ -4834,7 +4867,7 @@
    *     The number for which the floor function is to be computed.
    *
    * @return:
-   *   `a' rounded towards minus infinity.
+   *   `a` rounded towards minus infinity.
    */
   FT_EXPORT( FT_Fixed )
   FT_FloorFix( FT_Fixed  a );
@@ -4857,10 +4890,10 @@
    *     A pointer to the source 2x2 matrix.
    *
    * @note:
-   *   The result is undefined if either `vector' or `matrix' is invalid.
+   *   The result is undefined if either `vector` or `matrix` is invalid.
    */
   FT_EXPORT( void )
-  FT_Vector_Transform( FT_Vector*        vec,
+  FT_Vector_Transform( FT_Vector*        vector,
                        const FT_Matrix*  matrix );
 
 
@@ -4876,9 +4909,9 @@
    *   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.
+   *   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
@@ -4893,14 +4926,14 @@
    */
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FREETYPE_XXX
    *
    * @description:
-   *   These three macros identify the FreeType source code version.
-   *   Use @FT_Library_Version to access them at runtime.
+   *   These three macros identify the FreeType source code version.  Use
+   *   @FT_Library_Version to access them at runtime.
    *
    * @values:
    *   FREETYPE_MAJOR ::
@@ -4911,14 +4944,13 @@
    *     The patch level.
    *
    * @note:
-   *   The version number of FreeType if built as a dynamic link library
-   *   with the `libtool' package is _not_ controlled by these three
-   *   macros.
+   *   The version number of FreeType if built as a dynamic link library with
+   *   the 'libtool' package is _not_ controlled by these three macros.
    *
    */
 #define FREETYPE_MAJOR  2
-#define FREETYPE_MINOR  9
-#define FREETYPE_PATCH  1
+#define FREETYPE_MINOR  13
+#define FREETYPE_PATCH  0
 
 
   /**************************************************************************
@@ -4927,10 +4959,9 @@
    *   FT_Library_Version
    *
    * @description:
-   *   Return the version of the FreeType library being used.  This is
-   *   useful when dynamically linking to the library, since one cannot
-   *   use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and
-   *   @FREETYPE_PATCH.
+   *   Return the version of the FreeType library being used.  This is useful
+   *   when dynamically linking to the library, since one cannot use the
+   *   macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and @FREETYPE_PATCH.
    *
    * @input:
    *   library ::
@@ -4947,12 +4978,12 @@
    *     The patch version number.
    *
    * @note:
-   *   The reason why this function takes a `library' argument is because
-   *   certain programs implement library initialization in a custom way
-   *   that doesn't use @FT_Init_FreeType.
+   *   The reason why this function takes a `library` argument is because
+   *   certain programs implement library initialization in a custom way that
+   *   doesn't use @FT_Init_FreeType.
    *
-   *   In such cases, the library version might not be available before
-   *   the library object has been created.
+   *   In such cases, the library version might not be available before the
+   *   library object has been created.
    */
   FT_EXPORT( void )
   FT_Library_Version( FT_Library   library,
@@ -4981,6 +5012,7 @@
    *
    * @since:
    *   2.3.5
+   *
    */
   FT_EXPORT( FT_Bool )
   FT_Face_CheckTrueTypePatents( FT_Face  face );
@@ -5009,6 +5041,7 @@
    *
    * @since:
    *   2.3.5
+   *
    */
   FT_EXPORT( FT_Bool )
   FT_Face_SetUnpatentedHinting( FT_Face  face,
diff --git a/include/freetype/ftadvanc.h b/include/freetype/ftadvanc.h
index 9c3f545..4560ded 100644
--- a/include/freetype/ftadvanc.h
+++ b/include/freetype/ftadvanc.h
@@ -4,7 +4,7 @@
  *
  *   Quick computation of advance widths (specification only).
  *
- * Copyright 2008-2018 by
+ * Copyright (C) 2008-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTADVANC_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -62,20 +61,18 @@
    *   FT_ADVANCE_FLAG_FAST_ONLY
    *
    * @description:
-   *   A bit-flag to be OR-ed with the `flags' parameter of the
+   *   A bit-flag to be OR-ed with the `flags` parameter of the
    *   @FT_Get_Advance and @FT_Get_Advances functions.
    *
    *   If set, it indicates that you want these functions to fail if the
-   *   corresponding hinting mode or font driver doesn't allow for very
-   *   quick advance computation.
+   *   corresponding hinting mode or font driver doesn't allow for very quick
+   *   advance computation.
    *
-   *   Typically, glyphs that are either unscaled, unhinted, bitmapped,
-   *   or light-hinted can have their advance width computed very
-   *   quickly.
+   *   Typically, glyphs that are either unscaled, unhinted, bitmapped, or
+   *   light-hinted can have their advance width computed very quickly.
    *
-   *   Normal and bytecode hinted modes that require loading, scaling,
-   *   and hinting of the glyph outline, are extremely slow by
-   *   comparison.
+   *   Normal and bytecode hinted modes that require loading, scaling, and
+   *   hinting of the glyph outline, are extremely slow by comparison.
    */
 #define FT_ADVANCE_FLAG_FAST_ONLY  0x20000000L
 
@@ -86,8 +83,7 @@
    *   FT_Get_Advance
    *
    * @description:
-   *   Retrieve the advance value of a given glyph outline in an
-   *   @FT_Face.
+   *   Retrieve the advance value of a given glyph outline in an @FT_Face.
    *
    * @input:
    *   face ::
@@ -97,30 +93,29 @@
    *     The glyph index.
    *
    *   load_flags ::
-   *     A set of bit flags similar to those used when
-   *     calling @FT_Load_Glyph, used to determine what kind
-   *     of advances you need.
+   *     A set of bit flags similar to those used when calling
+   *     @FT_Load_Glyph, used to determine what kind of advances you need.
+   *
    * @output:
    *   padvance ::
-   *     The advance value.  If scaling is performed (based on
-   *     the value of `load_flags'), the advance value is in
-   *     16.16 format.  Otherwise, it is in font units.
+   *     The advance value.  If scaling is performed (based on the value of
+   *     `load_flags`), the advance value is in 16.16 format.  Otherwise, it
+   *     is in font units.
    *
-   *     If @FT_LOAD_VERTICAL_LAYOUT is set, this is the
-   *     vertical advance corresponding to a vertical layout.
-   *     Otherwise, it is the horizontal advance in a
-   *     horizontal layout.
+   *     If @FT_LOAD_VERTICAL_LAYOUT is set, this is the vertical advance
+   *     corresponding to a vertical layout.  Otherwise, it is the horizontal
+   *     advance in a horizontal layout.
    *
    * @return:
    *   FreeType error code.  0 means success.
    *
    * @note:
-   *   This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and
-   *   if the corresponding font backend doesn't have a quick way to
-   *   retrieve the advances.
+   *   This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if
+   *   the corresponding font backend doesn't have a quick way to retrieve
+   *   the advances.
    *
-   *   A scaled advance is returned in 16.16 format but isn't transformed
-   *   by the affine transformation specified by @FT_Set_Transform.
+   *   A scaled advance is returned in 16.16 format but isn't transformed by
+   *   the affine transformation specified by @FT_Set_Transform.
    */
   FT_EXPORT( FT_Error )
   FT_Get_Advance( FT_Face    face,
@@ -135,8 +130,7 @@
    *   FT_Get_Advances
    *
    * @description:
-   *   Retrieve the advance values of several glyph outlines in an
-   *   @FT_Face.
+   *   Retrieve the advance values of several glyph outlines in an @FT_Face.
    *
    * @input:
    *   face ::
@@ -149,34 +143,32 @@
    *     The number of advance values you want to retrieve.
    *
    *   load_flags ::
-   *     A set of bit flags similar to those used when
-   *     calling @FT_Load_Glyph.
+   *     A set of bit flags similar to those used when calling
+   *     @FT_Load_Glyph.
    *
    * @output:
    *   padvance ::
-   *     The advance values.  This array, to be provided by the
-   *     caller, must contain at least `count' elements.
+   *     The advance values.  This array, to be provided by the caller, must
+   *     contain at least `count` elements.
    *
-   *     If scaling is performed (based on the value of
-   *     `load_flags'), the advance values are in 16.16 format.
-   *     Otherwise, they are in font units.
+   *     If scaling is performed (based on the value of `load_flags`), the
+   *     advance values are in 16.16 format.  Otherwise, they are in font
+   *     units.
    *
-   *     If @FT_LOAD_VERTICAL_LAYOUT is set, these are the
-   *     vertical advances corresponding to a vertical layout.
-   *     Otherwise, they are the horizontal advances in a
-   *     horizontal layout.
+   *     If @FT_LOAD_VERTICAL_LAYOUT is set, these are the vertical advances
+   *     corresponding to a vertical layout.  Otherwise, they are the
+   *     horizontal advances in a horizontal layout.
    *
    * @return:
    *   FreeType error code.  0 means success.
    *
    * @note:
-   *   This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and
-   *   if the corresponding font backend doesn't have a quick way to
-   *   retrieve the advances.
+   *   This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if
+   *   the corresponding font backend doesn't have a quick way to retrieve
+   *   the advances.
    *
-   *   Scaled advances are returned in 16.16 format but aren't
-   *   transformed by the affine transformation specified by
-   *   @FT_Set_Transform.
+   *   Scaled advances are returned in 16.16 format but aren't transformed by
+   *   the affine transformation specified by @FT_Set_Transform.
    */
   FT_EXPORT( FT_Error )
   FT_Get_Advances( FT_Face    face,
diff --git a/include/freetype/ftbbox.h b/include/freetype/ftbbox.h
index 9a0dcfc..fc21740 100644
--- a/include/freetype/ftbbox.h
+++ b/include/freetype/ftbbox.h
@@ -4,7 +4,7 @@
  *
  *   FreeType exact bbox computation (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,7 +22,7 @@
    * boxes.
    *
    * It is separated from the rest of the engine for various technical
-   * reasons.  It may well be integrated in `ftoutln' later.
+   * reasons.  It may well be integrated in 'ftoutln' later.
    *
    */
 
@@ -31,8 +31,7 @@
 #define FTBBOX_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -58,11 +57,10 @@
    *   FT_Outline_Get_BBox
    *
    * @description:
-   *   Compute the exact bounding box of an outline.  This is slower
-   *   than computing the control box.  However, it uses an advanced
-   *   algorithm that returns _very_ quickly when the two boxes
-   *   coincide.  Otherwise, the outline Bezier arcs are traversed to
-   *   extract their extrema.
+   *   Compute the exact bounding box of an outline.  This is slower than
+   *   computing the control box.  However, it uses an advanced algorithm
+   *   that returns _very_ quickly when the two boxes coincide.  Otherwise,
+   *   the outline Bezier arcs are traversed to extract their extrema.
    *
    * @input:
    *   outline ::
@@ -78,10 +76,10 @@
    * @note:
    *   If the font is tricky and the glyph has been loaded with
    *   @FT_LOAD_NO_SCALE, the resulting BBox is meaningless.  To get
-   *   reasonable values for the BBox it is necessary to load the glyph
-   *   at a large ppem value (so that the hinting instructions can
-   *   properly shift and scale the subglyphs), then extracting the BBox,
-   *   which can be eventually converted back to font units.
+   *   reasonable values for the BBox it is necessary to load the glyph at a
+   *   large ppem value (so that the hinting instructions can properly shift
+   *   and scale the subglyphs), then extracting the BBox, which can be
+   *   eventually converted back to font units.
    */
   FT_EXPORT( FT_Error )
   FT_Outline_Get_BBox( FT_Outline*  outline,
diff --git a/include/freetype/ftbdf.h b/include/freetype/ftbdf.h
index 69dbb4d..e8ce643 100644
--- a/include/freetype/ftbdf.h
+++ b/include/freetype/ftbdf.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing BDF-specific strings (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTBDF_H_
 #define FTBDF_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -44,13 +43,13 @@
    *   BDF and PCF specific API.
    *
    * @description:
-   *   This section contains the declaration of functions specific to BDF
-   *   and PCF fonts.
+   *   This section contains the declaration of functions specific to BDF and
+   *   PCF fonts.
    *
    */
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *    BDF_PropertyType
@@ -81,19 +80,19 @@
   } BDF_PropertyType;
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @type:
    *    BDF_Property
    *
    * @description:
-   *    A handle to a @BDF_PropertyRec structure to model a given
-   *    BDF/PCF property.
+   *    A handle to a @BDF_PropertyRec structure to model a given BDF/PCF
+   *    property.
    */
   typedef struct BDF_PropertyRec_*  BDF_Property;
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @struct:
    *    BDF_PropertyRec
@@ -107,7 +106,7 @@
    *
    *    u.atom ::
    *      The atom string, if type is @BDF_PROPERTY_TYPE_ATOM.  May be
-   *      NULL, indicating an empty string.
+   *      `NULL`, indicating an empty string.
    *
    *    u.integer ::
    *      A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.
@@ -128,14 +127,14 @@
   } BDF_PropertyRec;
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_BDF_Charset_ID
    *
    * @description:
-   *    Retrieve a BDF font character set identity, according to
-   *    the BDF specification.
+   *    Retrieve a BDF font character set identity, according to the BDF
+   *    specification.
    *
    * @input:
    *    face ::
@@ -160,7 +159,7 @@
                          const char*  *acharset_registry );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_BDF_Property
@@ -187,15 +186,15 @@
    *   otherwise.  It also returns an error if the property is not in the
    *   font.
    *
-   *   A `property' is a either key-value pair within the STARTPROPERTIES
+   *   A 'property' is a either key-value pair within the STARTPROPERTIES
    *   ... ENDPROPERTIES block of a BDF font or a key-value pair from the
-   *   `info->props' array within a `FontRec' structure of a PCF font.
+   *   `info->props` array within a `FontRec` structure of a PCF font.
    *
-   *   Integer properties are always stored as `signed' within PCF fonts;
+   *   Integer properties are always stored as 'signed' within PCF fonts;
    *   consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value
    *   for BDF fonts only.
    *
-   *   In case of error, `aproperty->type' is always set to
+   *   In case of error, `aproperty->type` is always set to
    *   @BDF_PROPERTY_TYPE_NONE.
    */
   FT_EXPORT( FT_Error )
diff --git a/include/freetype/ftbitmap.h b/include/freetype/ftbitmap.h
index c9370af..eb6b4b1 100644
--- a/include/freetype/ftbitmap.h
+++ b/include/freetype/ftbitmap.h
@@ -4,7 +4,7 @@
  *
  *   FreeType utility functions for bitmaps (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define FTBITMAP_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_COLOR_H
+#include <freetype/freetype.h>
+#include <freetype/ftcolor.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -46,10 +45,16 @@
    *   Handling FT_Bitmap objects.
    *
    * @description:
-   *   This section contains functions for handling @FT_Bitmap objects.
-   *   Note that none of the functions changes the bitmap's `flow' (as
-   *   indicated by the sign of the `pitch' field in `FT_Bitmap').
+   *   This section contains functions for handling @FT_Bitmap objects,
+   *   automatically adjusting the target's bitmap buffer size as needed.
    *
+   *   Note that none of the functions changes the bitmap's 'flow' (as
+   *   indicated by the sign of the `pitch` field in @FT_Bitmap).
+   *
+   *   To set the flow, assign an appropriate positive or negative value to
+   *   the `pitch` field of the target @FT_Bitmap object after calling
+   *   @FT_Bitmap_Init but before calling any of the other functions
+   *   described here.
    */
 
 
@@ -66,7 +71,7 @@
    *     A pointer to the bitmap structure.
    *
    * @note:
-   *   A deprecated name for the same function is `FT_Bitmap_New'.
+   *   A deprecated name for the same function is `FT_Bitmap_New`.
    */
   FT_EXPORT( void )
   FT_Bitmap_Init( FT_Bitmap  *abitmap );
@@ -98,6 +103,10 @@
    *
    * @return:
    *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   `source->buffer` and `target->buffer` must neither be equal nor
+   *   overlap.
    */
   FT_EXPORT( FT_Error )
   FT_Bitmap_Copy( FT_Library        library,
@@ -111,21 +120,21 @@
    *   FT_Bitmap_Embolden
    *
    * @description:
-   *   Embolden a bitmap.  The new bitmap will be about `xStrength'
-   *   pixels wider and `yStrength' pixels higher.  The left and bottom
-   *   borders are kept unchanged.
+   *   Embolden a bitmap.  The new bitmap will be about `xStrength` pixels
+   *   wider and `yStrength` pixels higher.  The left and bottom borders are
+   *   kept unchanged.
    *
    * @input:
    *   library ::
    *     A handle to a library object.
    *
    *   xStrength ::
-   *     How strong the glyph is emboldened horizontally.
-   *     Expressed in 26.6 pixel format.
+   *     How strong the glyph is emboldened horizontally.  Expressed in 26.6
+   *     pixel format.
    *
    *   yStrength ::
-   *     How strong the glyph is emboldened vertically.
-   *     Expressed in 26.6 pixel format.
+   *     How strong the glyph is emboldened vertically.  Expressed in 26.6
+   *     pixel format.
    *
    * @inout:
    *   bitmap ::
@@ -135,14 +144,14 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The current implementation restricts `xStrength' to be less than
-   *   or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO.
+   *   The current implementation restricts `xStrength` to be less than or
+   *   equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO.
    *
-   *   If you want to embolden the bitmap owned by a @FT_GlyphSlotRec,
-   *   you should call @FT_GlyphSlot_Own_Bitmap on the slot first.
+   *   If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, you
+   *   should call @FT_GlyphSlot_Own_Bitmap on the slot first.
    *
-   *   Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format
-   *   are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp).
+   *   Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format are
+   *   converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp).
    */
   FT_EXPORT( FT_Error )
   FT_Bitmap_Embolden( FT_Library  library,
@@ -157,9 +166,9 @@
    *   FT_Bitmap_Convert
    *
    * @description:
-   *   Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp
-   *   to a bitmap object with depth 8bpp, making the number of used
-   *   bytes per line (a.k.a. the `pitch') a multiple of `alignment'.
+   *   Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp to
+   *   a bitmap object with depth 8bpp, making the number of used bytes per
+   *   line (a.k.a. the 'pitch') a multiple of `alignment`.
    *
    * @input:
    *   library ::
@@ -169,8 +178,8 @@
    *     The source bitmap.
    *
    *   alignment ::
-   *     The pitch of the bitmap is a multiple of this
-   *     argument.  Common values are 1, 2, or 4.
+   *     The pitch of the bitmap is a multiple of this argument.  Common
+   *     values are 1, 2, or 4.
    *
    * @output:
    *   target ::
@@ -185,8 +194,11 @@
    *
    *   Use @FT_Bitmap_Done to finally remove the bitmap object.
    *
-   *   The `library' argument is taken to have access to FreeType's
-   *   memory handling functions.
+   *   The `library` argument is taken to have access to FreeType's memory
+   *   handling functions.
+   *
+   *   `source->buffer` and `target->buffer` must neither be equal nor
+   *   overlap.
    */
   FT_EXPORT( FT_Error )
   FT_Bitmap_Convert( FT_Library        library,
@@ -212,14 +224,15 @@
    *
    *   source_offset ::
    *     The offset vector to the upper left corner of the source bitmap in
-   *     26.6 pixel format.  This can be a fractional pixel value.
+   *     26.6 pixel format.  It should represent an integer offset; the
+   *     function will set the lowest six bits to zero to enforce that.
    *
    *   color ::
-   *     The color used to draw `source' onto `target'.
+   *     The color used to draw `source` onto `target`.
    *
    * @inout:
    *   target ::
-   *     A handle to an `FT_Bitmap' object.  It should be either initialized
+   *     A handle to an `FT_Bitmap` object.  It should be either initialized
    *     as empty with a call to @FT_Bitmap_Init, or it should be of type
    *     @FT_PIXEL_MODE_BGRA.
    *
@@ -234,12 +247,15 @@
    * @note:
    *   This function doesn't perform clipping.
    *
-   *   The bitmap in `target' gets allocated or reallocated as needed; the
-   *   vector `atarget_offset' is updated accordingly.
+   *   The bitmap in `target` gets allocated or reallocated as needed; the
+   *   vector `atarget_offset` is updated accordingly.
    *
    *   In case of allocation or reallocation, the bitmap's pitch is set to
-   *   `4~*~width'.  Both `source' and `target' must have the same bitmap
-   *   flow (as indicated by the sign of the `pitch' field).
+   *   `4 * width`.  Both `source` and `target` must have the same bitmap
+   *   flow (as indicated by the sign of the `pitch` field).
+   *
+   *   `source->buffer` and `target->buffer` must neither be equal nor
+   *   overlap.
    *
    * @since:
    *   2.10
@@ -259,7 +275,7 @@
    *   FT_GlyphSlot_Own_Bitmap
    *
    * @description:
-   *   Make sure that a glyph slot owns `slot->bitmap'.
+   *   Make sure that a glyph slot owns `slot->bitmap`.
    *
    * @input:
    *   slot ::
@@ -269,8 +285,7 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This function is to be used in combination with
-   *   @FT_Bitmap_Embolden.
+   *   This function is to be used in combination with @FT_Bitmap_Embolden.
    */
   FT_EXPORT( FT_Error )
   FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot );
@@ -295,8 +310,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The `library' argument is taken to have access to FreeType's
-   *   memory handling functions.
+   *   The `library` argument is taken to have access to FreeType's memory
+   *   handling functions.
    */
   FT_EXPORT( FT_Error )
   FT_Bitmap_Done( FT_Library  library,
diff --git a/include/freetype/ftbzip2.h b/include/freetype/ftbzip2.h
index 07a7367..7d29f46 100644
--- a/include/freetype/ftbzip2.h
+++ b/include/freetype/ftbzip2.h
@@ -4,7 +4,7 @@
  *
  *   Bzip2-compressed stream support.
  *
- * Copyright 2010-2018 by
+ * Copyright (C) 2010-2023 by
  * Joel Klinghed.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTBZIP2_H_
 #define FTBZIP2_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -43,20 +42,30 @@
    *   Using bzip2-compressed font files.
    *
    * @description:
+   *   In certain builds of the library, bzip2 compression recognition is
+   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
+   *   This means that if no font driver is capable of handling the raw
+   *   compressed file, the library will try to open a bzip2 compressed
+   *   stream from it and re-open the face with it.
+   *
+   *   The stream implementation is very basic and resets the decompression
+   *   process each time seeking backwards is needed within the stream,
+   *   which significantly undermines the performance.
+   *
    *   This section contains the declaration of Bzip2-specific functions.
    *
    */
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stream_OpenBzip2
    *
    * @description:
    *   Open a new stream to parse bzip2-compressed font files.  This is
-   *   mainly used to support the compressed `*.pcf.bz2' fonts that come
-   *   with XFree86.
+   *   mainly used to support the compressed `*.pcf.bz2` fonts that come with
+   *   XFree86.
    *
    * @input:
    *   stream ::
@@ -71,20 +80,11 @@
    * @note:
    *   The source stream must be opened _before_ calling this function.
    *
-   *   Calling the internal function `FT_Stream_Close' on the new stream will
-   *   *not* call `FT_Stream_Close' on the source stream.  None of the stream
-   *   objects will be released to the heap.
+   *   Calling the internal function `FT_Stream_Close` on the new stream will
+   *   **not** call `FT_Stream_Close` on the source stream.  None of the
+   *   stream objects will be released to the heap.
    *
-   *   The stream implementation is very basic and resets the decompression
-   *   process each time seeking backwards is needed within the stream.
-   *
-   *   In certain builds of the library, bzip2 compression recognition is
-   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
-   *   This means that if no font driver is capable of handling the raw
-   *   compressed file, the library will try to open a bzip2 compressed stream
-   *   from it and re-open the face with it.
-   *
-   *   This function may return `FT_Err_Unimplemented_Feature' if your build
+   *   This function may return `FT_Err_Unimplemented_Feature` if your build
    *   of FreeType was not compiled with bzip2 support.
    */
   FT_EXPORT( FT_Error )
diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h
index 5dedb52..c768695 100644
--- a/include/freetype/ftcache.h
+++ b/include/freetype/ftcache.h
@@ -4,7 +4,7 @@
  *
  *   FreeType Cache subsystem (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,14 +20,13 @@
 #define FTCACHE_H_
 
 
-#include <ft2build.h>
-#include FT_GLYPH_H
+#include <freetype/ftglyph.h>
 
 
 FT_BEGIN_HEADER
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @section:
    *   cache_subsystem
@@ -44,7 +43,7 @@
    *   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.
    *
    *   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
@@ -59,7 +58,7 @@
    *   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
+   *   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.
    *
@@ -69,14 +68,14 @@
    *   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
+   *   **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
-   *   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.
+   *   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.
    *
    *   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
@@ -87,15 +86,15 @@
    *   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, then
-   *   later use @FTC_ImageCache_Lookup to retrieve the corresponding
+   *   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).
+   *   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.
    *
@@ -142,7 +141,7 @@
   /*************************************************************************/
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FTC_FaceID
@@ -151,11 +150,11 @@
    *   An opaque pointer type that is used to identity face objects.  The
    *   contents of such objects is application-dependent.
    *
-   *   These pointers are typically used to point to a user-defined
-   *   structure containing a font file path, and face index.
+   *   These pointers are typically used to point to a user-defined structure
+   *   containing a font file path, and face index.
    *
    * @note:
-   *   Never use NULL as a valid @FTC_FaceID.
+   *   Never use `NULL` as a valid @FTC_FaceID.
    *
    *   Face IDs are passed by the client to the cache manager that calls,
    *   when needed, the @FTC_Face_Requester to translate them into new
@@ -166,13 +165,13 @@
    *   immediately call @FTC_Manager_RemoveFaceID before any other cache
    *   function.
    *
-   *   Failure to do so will result in incorrect behaviour or even
-   *   memory leaks and crashes.
+   *   Failure to do so will result in incorrect behaviour or even memory
+   *   leaks and crashes.
    */
   typedef FT_Pointer  FTC_FaceID;
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   FTC_Face_Requester
@@ -200,7 +199,7 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The third parameter `req_data' is the same as the one passed by the
+   *   The third parameter `req_data` is the same as the one passed by the
    *   client when @FTC_Manager_New is called.
    *
    *   The face requester should not perform funny things on the returned
@@ -233,20 +232,20 @@
    *   FTC_Manager
    *
    * @description:
-   *   This object corresponds to one instance of the cache-subsystem.
-   *   It is used to cache one or more @FT_Face objects, along with
-   *   corresponding @FT_Size objects.
+   *   This object corresponds to one instance of the cache-subsystem.  It is
+   *   used to cache one or more @FT_Face objects, along with corresponding
+   *   @FT_Size objects.
    *
-   *   The manager intentionally limits the total number of opened
-   *   @FT_Face and @FT_Size objects to control memory usage.  See the
-   *   `max_faces' and `max_sizes' parameters of @FTC_Manager_New.
+   *   The manager intentionally limits the total number of opened @FT_Face
+   *   and @FT_Size objects to control memory usage.  See the `max_faces` and
+   *   `max_sizes` parameters of @FTC_Manager_New.
    *
-   *   The manager is also used to cache `nodes' of various types while
+   *   The manager is also used to cache 'nodes' of various types while
    *   limiting their total memory usage.
    *
-   *   All limitations are enforced by keeping lists of managed objects
-   *   in most-recently-used order, and flushing old nodes to make room
-   *   for new ones.
+   *   All limitations are enforced by keeping lists of managed objects in
+   *   most-recently-used order, and flushing old nodes to make room for new
+   *   ones.
    */
   typedef struct FTC_ManagerRec_*  FTC_Manager;
 
@@ -258,13 +257,13 @@
    *
    * @description:
    *   An opaque handle to a cache node object.  Each cache node is
-   *   reference-counted.  A node with a count of~0 might be flushed
-   *   out of a full cache whenever a lookup request is performed.
+   *   reference-counted.  A node with a count of~0 might be flushed out of a
+   *   full cache whenever a lookup request is performed.
    *
-   *   If you look up nodes, you have the ability to `acquire' them,
-   *   i.e., to increment their reference count.  This will prevent the
-   *   node from being flushed out of the cache until you explicitly
-   *   `release' it (see @FTC_Node_Unref).
+   *   If you look up nodes, you have the ability to 'acquire' them, i.e., to
+   *   increment their reference count.  This will prevent the node from
+   *   being flushed out of the cache until you explicitly 'release' it (see
+   *   @FTC_Node_Unref).
    *
    *   See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup.
    */
@@ -284,30 +283,29 @@
    *     The parent FreeType library handle to use.
    *
    *   max_faces ::
-   *     Maximum number of opened @FT_Face objects managed by
-   *     this cache instance.  Use~0 for defaults.
+   *     Maximum number of opened @FT_Face objects managed by this cache
+   *     instance.  Use~0 for defaults.
    *
    *   max_sizes ::
-   *     Maximum number of opened @FT_Size objects managed by
-   *     this cache instance.  Use~0 for defaults.
+   *     Maximum number of opened @FT_Size objects managed by this cache
+   *     instance.  Use~0 for defaults.
    *
    *   max_bytes ::
-   *     Maximum number of bytes to use for cached data nodes.
-   *     Use~0 for defaults.  Note that this value does not
-   *     account for managed @FT_Face and @FT_Size objects.
+   *     Maximum number of bytes to use for cached data nodes.  Use~0 for
+   *     defaults.  Note that this value does not account for managed
+   *     @FT_Face and @FT_Size objects.
    *
    *   requester ::
-   *     An application-provided callback used to translate
-   *     face IDs into real @FT_Face objects.
+   *     An application-provided callback used to translate face IDs into
+   *     real @FT_Face objects.
    *
    *   req_data ::
-   *     A generic pointer that is passed to the requester
-   *     each time it is called (see @FTC_Face_Requester).
+   *     A generic pointer that is passed to the requester each time it is
+   *     called (see @FTC_Face_Requester).
    *
    * @output:
    *   amanager ::
-   *     A handle to a new manager object.  0~in case of
-   *     failure.
+   *     A handle to a new manager object.  0~in case of failure.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -383,20 +381,20 @@
    *   should never try to discard it yourself.
    *
    *   The @FT_Face object doesn't necessarily have a current size object
-   *   (i.e., face->size can be~0).  If you need a specific `font size',
-   *   use @FTC_Manager_LookupSize instead.
+   *   (i.e., face->size can be~0).  If you need a specific 'font size', use
+   *   @FTC_Manager_LookupSize instead.
    *
-   *   Never change the face's transformation matrix (i.e., never call
-   *   the @FT_Set_Transform function) on a returned face!  If you need
-   *   to transform glyphs, do it yourself after glyph loading.
+   *   Never change the face's transformation matrix (i.e., never call the
+   *   @FT_Set_Transform function) on a returned face!  If you need to
+   *   transform glyphs, do it yourself after glyph loading.
    *
-   *   When you perform a lookup, out-of-memory errors are detected
-   *   _within_ the lookup and force incremental flushes of the cache
-   *   until enough memory is released for the lookup to succeed.
+   *   When you perform a lookup, out-of-memory errors are detected _within_
+   *   the lookup and force incremental flushes of the cache until enough
+   *   memory is released for the lookup to succeed.
    *
-   *   If a lookup fails with `FT_Err_Out_Of_Memory' the cache has
-   *   already been completely flushed, and still no memory was available
-   *   for the operation.
+   *   If a lookup fails with `FT_Err_Out_Of_Memory` the cache has already
+   *   been completely flushed, and still no memory was available for the
+   *   operation.
    */
   FT_EXPORT( FT_Error )
   FTC_Manager_LookupFace( FTC_Manager  manager,
@@ -410,9 +408,8 @@
    *   FTC_ScalerRec
    *
    * @description:
-   *   A structure used to describe a given character size in either
-   *   pixels or points to the cache manager.  See
-   *   @FTC_Manager_LookupSize.
+   *   A structure used to describe a given character size in either pixels
+   *   or points to the cache manager.  See @FTC_Manager_LookupSize.
    *
    * @fields:
    *   face_id ::
@@ -425,17 +422,17 @@
    *     The character height.
    *
    *   pixel ::
-   *     A Boolean.  If 1, the `width' and `height' fields are
-   *     interpreted as integer pixel character sizes.
-   *     Otherwise, they are expressed as 1/64th of points.
+   *     A Boolean.  If 1, the `width` and `height` fields are interpreted as
+   *     integer pixel character sizes.  Otherwise, they are expressed as
+   *     1/64 of points.
    *
    *   x_res ::
-   *     Only used when `pixel' is value~0 to indicate the
-   *     horizontal resolution in dpi.
+   *     Only used when `pixel` is value~0 to indicate the horizontal
+   *     resolution in dpi.
    *
    *   y_res ::
-   *     Only used when `pixel' is value~0 to indicate the
-   *     vertical resolution in dpi.
+   *     Only used when `pixel` is value~0 to indicate the vertical
+   *     resolution in dpi.
    *
    * @note:
    *   This type is mainly used to retrieve @FT_Size objects through the
@@ -491,18 +488,17 @@
    *   The returned @FT_Size object is always owned by the manager.  You
    *   should never try to discard it by yourself.
    *
-   *   You can access the parent @FT_Face object simply as `size->face'
-   *   if you need it.  Note that this object is also owned by the
-   *   manager.
+   *   You can access the parent @FT_Face object simply as `size->face` if
+   *   you need it.  Note that this object is also owned by the manager.
    *
    * @note:
-   *   When you perform a lookup, out-of-memory errors are detected
-   *   _within_ the lookup and force incremental flushes of the cache
-   *   until enough memory is released for the lookup to succeed.
+   *   When you perform a lookup, out-of-memory errors are detected _within_
+   *   the lookup and force incremental flushes of the cache until enough
+   *   memory is released for the lookup to succeed.
    *
-   *   If a lookup fails with `FT_Err_Out_Of_Memory' the cache has
-   *   already been completely flushed, and still no memory is available
-   *   for the operation.
+   *   If a lookup fails with `FT_Err_Out_Of_Memory` the cache has already
+   *   been completely flushed, and still no memory is available for the
+   *   operation.
    */
   FT_EXPORT( FT_Error )
   FTC_Manager_LookupSize( FTC_Manager  manager,
@@ -532,15 +528,15 @@
                   FTC_Manager  manager );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FTC_Manager_RemoveFaceID
    *
    * @description:
-   *   A special function used to indicate to the cache manager that
-   *   a given @FTC_FaceID is no longer valid, either because its
-   *   content changed, or because it was deallocated or uninstalled.
+   *   A special function used to indicate to the cache manager that a given
+   *   @FTC_FaceID is no longer valid, either because its content changed, or
+   *   because it was deallocated or uninstalled.
    *
    * @input:
    *   manager ::
@@ -551,11 +547,11 @@
    *
    * @note:
    *   This function flushes all nodes from the cache corresponding to this
-   *   `face_id', with the exception of nodes with a non-null reference
+   *   `face_id`, with the exception of nodes with a non-null reference
    *   count.
    *
-   *   Such nodes are however modified internally so as to never appear
-   *   in later lookups with the same `face_id' value, and to be immediately
+   *   Such nodes are however modified internally so as to never appear in
+   *   later lookups with the same `face_id` value, and to be immediately
    *   destroyed when released by all their users.
    *
    */
@@ -564,20 +560,20 @@
                             FTC_FaceID   face_id );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FTC_CMapCache
    *
    * @description:
-   *   An opaque handle used to model a charmap cache.  This cache is to
-   *   hold character codes -> glyph indices mappings.
+   *   An opaque handle used to model a charmap cache.  This cache is to hold
+   *   character codes -> glyph indices mappings.
    *
    */
   typedef struct FTC_CMapCacheRec_*  FTC_CMapCache;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FTC_CMapCache_New
@@ -591,7 +587,7 @@
    *
    * @output:
    *   acache ::
-   *     A new cache handle.  NULL in case of error.
+   *     A new cache handle.  `NULL` in case of error.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -606,7 +602,7 @@
                      FTC_CMapCache  *acache );
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FTC_CMapCache_Lookup
@@ -630,7 +626,7 @@
    *     The character code (in the corresponding charmap).
    *
    * @return:
-   *    Glyph index.  0~means `no glyph'.
+   *    Glyph index.  0~means 'no glyph'.
    *
    */
   FT_EXPORT( FT_UInt )
@@ -651,7 +647,7 @@
   /*************************************************************************/
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FTC_ImageTypeRec
@@ -683,7 +679,7 @@
   } FTC_ImageTypeRec;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FTC_ImageType
@@ -710,9 +706,9 @@
    *   FTC_ImageCache
    *
    * @description:
-   *   A handle to a glyph image cache object.  They are designed to
-   *   hold many distinct glyph images while not exceeding a certain
-   *   memory threshold.
+   *   A handle to a glyph image cache object.  They are designed to hold
+   *   many distinct glyph images while not exceeding a certain memory
+   *   threshold.
    */
   typedef struct FTC_ImageCacheRec_*  FTC_ImageCache;
 
@@ -761,32 +757,29 @@
    *
    * @output:
    *   aglyph ::
-   *     The corresponding @FT_Glyph object.  0~in case of
-   *     failure.
+   *     The corresponding @FT_Glyph object.  0~in case of failure.
    *
    *   anode ::
-   *     Used to return the address of the corresponding cache
-   *     node after incrementing its reference count (see note
-   *     below).
+   *     Used to return the address of the corresponding cache node after
+   *     incrementing its reference count (see note below).
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
    *   The returned glyph is owned and managed by the glyph image cache.
-   *   Never try to transform or discard it manually!  You can however
-   *   create a copy with @FT_Glyph_Copy and modify the new one.
+   *   Never try to transform or discard it manually!  You can however create
+   *   a copy with @FT_Glyph_Copy and modify the new one.
    *
-   *   If `anode' is _not_ NULL, it receives the address of the cache
-   *   node containing the glyph image, after increasing its reference
-   *   count.  This ensures that the node (as well as the @FT_Glyph) will
-   *   always be kept in the cache until you call @FTC_Node_Unref to
-   *   `release' it.
+   *   If `anode` is _not_ `NULL`, it receives the address of the cache node
+   *   containing the glyph image, after increasing its reference count.
+   *   This ensures that the node (as well as the @FT_Glyph) will always be
+   *   kept in the cache until you call @FTC_Node_Unref to 'release' it.
    *
-   *   If `anode' is NULL, the cache node is left unchanged, which means
-   *   that the @FT_Glyph could be flushed out of the cache on the next
-   *   call to one of the caching sub-system APIs.  Don't assume that it
-   *   is persistent!
+   *   If `anode` is `NULL`, the cache node is left unchanged, which means
+   *   that the @FT_Glyph could be flushed out of the cache on the next call
+   *   to one of the caching sub-system APIs.  Don't assume that it is
+   *   persistent!
    */
   FT_EXPORT( FT_Error )
   FTC_ImageCache_Lookup( FTC_ImageCache  cache,
@@ -802,8 +795,8 @@
    *   FTC_ImageCache_LookupScaler
    *
    * @description:
-   *   A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec
-   *   to specify the face ID and its size.
+   *   A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec to
+   *   specify the face ID and its size.
    *
    * @input:
    *   cache ::
@@ -820,32 +813,29 @@
    *
    * @output:
    *   aglyph ::
-   *     The corresponding @FT_Glyph object.  0~in case of
-   *     failure.
+   *     The corresponding @FT_Glyph object.  0~in case of failure.
    *
    *   anode ::
-   *     Used to return the address of the corresponding
-   *     cache node after incrementing its reference count
-   *     (see note below).
+   *     Used to return the address of the corresponding cache node after
+   *     incrementing its reference count (see note below).
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
    *   The returned glyph is owned and managed by the glyph image cache.
-   *   Never try to transform or discard it manually!  You can however
-   *   create a copy with @FT_Glyph_Copy and modify the new one.
+   *   Never try to transform or discard it manually!  You can however create
+   *   a copy with @FT_Glyph_Copy and modify the new one.
    *
-   *   If `anode' is _not_ NULL, it receives the address of the cache
-   *   node containing the glyph image, after increasing its reference
-   *   count.  This ensures that the node (as well as the @FT_Glyph) will
-   *   always be kept in the cache until you call @FTC_Node_Unref to
-   *   `release' it.
+   *   If `anode` is _not_ `NULL`, it receives the address of the cache node
+   *   containing the glyph image, after increasing its reference count.
+   *   This ensures that the node (as well as the @FT_Glyph) will always be
+   *   kept in the cache until you call @FTC_Node_Unref to 'release' it.
    *
-   *   If `anode' is NULL, the cache node is left unchanged, which means
-   *   that the @FT_Glyph could be flushed out of the cache on the next
-   *   call to one of the caching sub-system APIs.  Don't assume that it
-   *   is persistent!
+   *   If `anode` is `NULL`, the cache node is left unchanged, which means
+   *   that the @FT_Glyph could be flushed out of the cache on the next call
+   *   to one of the caching sub-system APIs.  Don't assume that it is
+   *   persistent!
    *
    *   Calls to @FT_Set_Char_Size and friends have no effect on cached
    *   glyphs; you should always use the FreeType cache API instead.
@@ -865,8 +855,8 @@
    *   FTC_SBit
    *
    * @description:
-   *   A handle to a small bitmap descriptor.  See the @FTC_SBitRec
-   *   structure for details.
+   *   A handle to a small bitmap descriptor.  See the @FTC_SBitRec structure
+   *   for details.
    */
   typedef struct FTC_SBitRec_*  FTC_SBit;
 
@@ -887,15 +877,13 @@
    *     The bitmap height in pixels.
    *
    *   left ::
-   *     The horizontal distance from the pen position to the
-   *     left bitmap border (a.k.a. `left side bearing', or
-   *     `lsb').
+   *     The horizontal distance from the pen position to the left bitmap
+   *     border (a.k.a. 'left side bearing', or 'lsb').
    *
    *   top ::
-   *     The vertical distance from the pen position (on the
-   *     baseline) to the upper bitmap border (a.k.a. `top
-   *     side bearing').  The distance is positive for upwards
-   *     y~coordinates.
+   *     The vertical distance from the pen position (on the baseline) to the
+   *     upper bitmap border (a.k.a. 'top side bearing').  The distance is
+   *     positive for upwards y~coordinates.
    *
    *   format ::
    *     The format of the glyph bitmap (monochrome or gray).
@@ -904,8 +892,7 @@
    *     Maximum gray level value (in the range 1 to~255).
    *
    *   pitch ::
-   *     The number of bytes per bitmap line.  May be positive
-   *     or negative.
+   *     The number of bytes per bitmap line.  May be positive or negative.
    *
    *   xadvance ::
    *     The horizontal advance width in pixels.
@@ -941,9 +928,9 @@
    *
    * @description:
    *   A handle to a small bitmap cache.  These are special cache objects
-   *   used to store small glyph bitmaps (and anti-aliased pixmaps) in a
-   *   much more efficient way than the traditional glyph image cache
-   *   implemented by @FTC_ImageCache.
+   *   used to store small glyph bitmaps (and anti-aliased pixmaps) in a much
+   *   more efficient way than the traditional glyph image cache implemented
+   *   by @FTC_ImageCache.
    */
   typedef struct FTC_SBitCacheRec_*  FTC_SBitCache;
 
@@ -962,7 +949,7 @@
    *
    * @output:
    *   acache ::
-   *     A handle to the new sbit cache.  NULL in case of error.
+   *     A handle to the new sbit cache.  `NULL` in case of error.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -978,8 +965,8 @@
    *   FTC_SBitCache_Lookup
    *
    * @description:
-   *   Look up a given small glyph bitmap in a given sbit cache and
-   *   `lock' it to prevent its flushing from the cache until needed.
+   *   Look up a given small glyph bitmap in a given sbit cache and 'lock' it
+   *   to prevent its flushing from the cache until needed.
    *
    * @input:
    *   cache ::
@@ -996,31 +983,30 @@
    *     A handle to a small bitmap descriptor.
    *
    *   anode ::
-   *     Used to return the address of the corresponding cache
-   *     node after incrementing its reference count (see note
-   *     below).
+   *     Used to return the address of the corresponding cache node after
+   *     incrementing its reference count (see note below).
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The small bitmap descriptor and its bit buffer are owned by the
-   *   cache and should never be freed by the application.  They might
-   *   as well disappear from memory on the next cache lookup, so don't
-   *   treat them as persistent data.
+   *   The small bitmap descriptor and its bit buffer are owned by the cache
+   *   and should never be freed by the application.  They might as well
+   *   disappear from memory on the next cache lookup, so don't treat them as
+   *   persistent data.
    *
-   *   The descriptor's `buffer' field is set to~0 to indicate a missing
+   *   The descriptor's `buffer` field is set to~0 to indicate a missing
    *   glyph bitmap.
    *
-   *   If `anode' is _not_ NULL, it receives the address of the cache
-   *   node containing the bitmap, after increasing its reference count.
-   *   This ensures that the node (as well as the image) will always be
-   *   kept in the cache until you call @FTC_Node_Unref to `release' it.
+   *   If `anode` is _not_ `NULL`, it receives the address of the cache node
+   *   containing the bitmap, after increasing its reference count.  This
+   *   ensures that the node (as well as the image) will always be kept in
+   *   the cache until you call @FTC_Node_Unref to 'release' it.
    *
-   *   If `anode' is NULL, the cache node is left unchanged, which means
-   *   that the bitmap could be flushed out of the cache on the next
-   *   call to one of the caching sub-system APIs.  Don't assume that it
-   *   is persistent!
+   *   If `anode` is `NULL`, the cache node is left unchanged, which means
+   *   that the bitmap could be flushed out of the cache on the next call to
+   *   one of the caching sub-system APIs.  Don't assume that it is
+   *   persistent!
    */
   FT_EXPORT( FT_Error )
   FTC_SBitCache_Lookup( FTC_SBitCache    cache,
@@ -1036,8 +1022,8 @@
    *   FTC_SBitCache_LookupScaler
    *
    * @description:
-   *   A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec
-   *   to specify the face ID and its size.
+   *   A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec to
+   *   specify the face ID and its size.
    *
    * @input:
    *   cache ::
@@ -1057,31 +1043,30 @@
    *     A handle to a small bitmap descriptor.
    *
    *   anode ::
-   *     Used to return the address of the corresponding
-   *     cache node after incrementing its reference count
-   *     (see note below).
+   *     Used to return the address of the corresponding cache node after
+   *     incrementing its reference count (see note below).
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The small bitmap descriptor and its bit buffer are owned by the
-   *   cache and should never be freed by the application.  They might
-   *   as well disappear from memory on the next cache lookup, so don't
-   *   treat them as persistent data.
+   *   The small bitmap descriptor and its bit buffer are owned by the cache
+   *   and should never be freed by the application.  They might as well
+   *   disappear from memory on the next cache lookup, so don't treat them as
+   *   persistent data.
    *
-   *   The descriptor's `buffer' field is set to~0 to indicate a missing
+   *   The descriptor's `buffer` field is set to~0 to indicate a missing
    *   glyph bitmap.
    *
-   *   If `anode' is _not_ NULL, it receives the address of the cache
-   *   node containing the bitmap, after increasing its reference count.
-   *   This ensures that the node (as well as the image) will always be
-   *   kept in the cache until you call @FTC_Node_Unref to `release' it.
+   *   If `anode` is _not_ `NULL`, it receives the address of the cache node
+   *   containing the bitmap, after increasing its reference count.  This
+   *   ensures that the node (as well as the image) will always be kept in
+   *   the cache until you call @FTC_Node_Unref to 'release' it.
    *
-   *   If `anode' is NULL, the cache node is left unchanged, which means
-   *   that the bitmap could be flushed out of the cache on the next
-   *   call to one of the caching sub-system APIs.  Don't assume that it
-   *   is persistent!
+   *   If `anode` is `NULL`, the cache node is left unchanged, which means
+   *   that the bitmap could be flushed out of the cache on the next call to
+   *   one of the caching sub-system APIs.  Don't assume that it is
+   *   persistent!
    */
   FT_EXPORT( FT_Error )
   FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,
diff --git a/include/freetype/ftchapters.h b/include/freetype/ftchapters.h
index f4297d3..6a9733a 100644
--- a/include/freetype/ftchapters.h
+++ b/include/freetype/ftchapters.h
@@ -6,7 +6,7 @@
  */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   general_remarks
@@ -15,13 +15,14 @@
    *   General Remarks
    *
    * @sections:
+   *   preamble
    *   header_inclusion
    *   user_allocation
    *
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   core_api
@@ -44,7 +45,7 @@
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   format_specific
@@ -61,13 +62,14 @@
    *   cid_fonts
    *   pfr_fonts
    *   winfnt_fonts
+   *   svg_fonts
    *   font_formats
    *   gasp_table
    *
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   module_specific
@@ -81,6 +83,7 @@
    *   t1_cid_driver
    *   tt_driver
    *   pcf_driver
+   *   ot_svg_driver
    *   properties
    *   parameter_tags
    *   lcd_rendering
@@ -88,7 +91,7 @@
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   cache_subsystem
@@ -102,7 +105,7 @@
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   support_api
@@ -123,11 +126,12 @@
    *   gzip
    *   lzw
    *   bzip2
+   *   debugging_apis
    *
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @chapter:
    *   error_codes
diff --git a/include/freetype/ftcid.h b/include/freetype/ftcid.h
index b427cbd..ef22939 100644
--- a/include/freetype/ftcid.h
+++ b/include/freetype/ftcid.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing CID font information (specification).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * Dereg Clegg and Michael Toftdal.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTCID_H_
 #define FTCID_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -50,7 +49,7 @@
    */
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_CID_Registry_Ordering_Supplement
@@ -90,15 +89,15 @@
                                            FT_Int       *supplement );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_CID_Is_Internally_CID_Keyed
    *
    * @description:
-   *    Retrieve the type of the input face, CID keyed or not.  In
-   *    contrast to the @FT_IS_CID_KEYED macro this function returns
-   *    successfully also for CID-keyed fonts in an SFNT wrapper.
+   *    Retrieve the type of the input face, CID keyed or not.  In contrast
+   *    to the @FT_IS_CID_KEYED macro this function returns successfully also
+   *    for CID-keyed fonts in an SFNT wrapper.
    *
    * @input:
    *    face ::
@@ -112,8 +111,8 @@
    *    FreeType error code.  0~means success.
    *
    * @note:
-   *    This function only works with CID faces and OpenType fonts,
-   *    returning an error otherwise.
+   *    This function only works with CID faces and OpenType fonts, returning
+   *    an error otherwise.
    *
    * @since:
    *    2.3.9
@@ -123,7 +122,7 @@
                                       FT_Bool  *is_cid );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_CID_From_Glyph_Index
@@ -146,8 +145,8 @@
    *    FreeType error code.  0~means success.
    *
    * @note:
-   *    This function only works with CID faces and OpenType fonts,
-   *    returning an error otherwise.
+   *    This function only works with CID faces and OpenType fonts, returning
+   *    an error otherwise.
    *
    * @since:
    *    2.3.9
diff --git a/include/freetype/ftcolor.h b/include/freetype/ftcolor.h
index e4fa4af..eae200f 100644
--- a/include/freetype/ftcolor.h
+++ b/include/freetype/ftcolor.h
@@ -4,7 +4,7 @@
  *
  *   FreeType's glyph color management (specification).
  *
- * Copyright 2018 by
+ * Copyright (C) 2018-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTCOLOR_H_
 #define FTCOLOR_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -41,11 +40,11 @@
    *   Glyph Color Management
    *
    * @abstract:
-   *   Retrieving and manipulating OpenType's `CPAL' table data.
+   *   Retrieving and manipulating OpenType's 'CPAL' table data.
    *
    * @description:
    *   The functions described here allow access and manipulation of color
-   *   palette entries in OpenType's `CPAL' tables.
+   *   palette entries in OpenType's 'CPAL' tables.
    */
 
 
@@ -55,7 +54,7 @@
    *   FT_Color
    *
    * @description:
-   *   This structure models a BGRA color value of a `CPAL' palette entry.
+   *   This structure models a BGRA color value of a 'CPAL' palette entry.
    *
    *   The used color space is sRGB; the colors are not pre-multiplied, and
    *   alpha values must be explicitly set.
@@ -92,9 +91,9 @@
    *   FT_PALETTE_XXX
    *
    * @description:
-   *   A list of bit field constants used in the `palette_flags' array of
-   *   the @FT_Palette_Data structure to indicate for which background a
-   *   palette with a given index is usable.
+   *   A list of bit field constants used in the `palette_flags` array of the
+   *   @FT_Palette_Data structure to indicate for which background a palette
+   *   with a given index is usable.
    *
    * @values:
    *   FT_PALETTE_FOR_LIGHT_BACKGROUND ::
@@ -102,8 +101,8 @@
    *     light background such as white.
    *
    *   FT_PALETTE_FOR_DARK_BACKGROUND ::
-   *     The palette is appropriate to use when displaying the font on a
-   *     dark background such as black.
+   *     The palette is appropriate to use when displaying the font on a dark
+   *     background such as black.
    *
    * @since:
    *   2.10
@@ -118,52 +117,54 @@
    *   FT_Palette_Data
    *
    * @description:
-   *   This structure holds the data of the `CPAL' table.
+   *   This structure holds the data of the 'CPAL' table.
    *
    * @fields:
    *   num_palettes ::
    *     The number of palettes.
    *
    *   palette_name_ids ::
-   *     A read-only array of palette name IDs with `num_palettes' elements,
-   *     corresponding to entries like `dark' or `light' in the font's
-   *     `name' table.
+   *     An optional read-only array of palette name IDs with `num_palettes`
+   *     elements, corresponding to entries like 'dark' or 'light' in the
+   *     font's 'name' table.
    *
-   *     An empty name ID in the `CPAL' table gets represented as value
+   *     An empty name ID in the 'CPAL' table gets represented as value
    *     0xFFFF.
    *
-   *     NULL if the font's `CPAL' table doesn't contain appropriate data.
+   *     `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
    *
    *   palette_flags ::
-   *     A read-only array of palette flags with `num_palettes' elements.
-   *     Possible values are an ORed combination of
+   *     An optional read-only array of palette flags with `num_palettes`
+   *     elements.  Possible values are an ORed combination of
    *     @FT_PALETTE_FOR_LIGHT_BACKGROUND and
    *     @FT_PALETTE_FOR_DARK_BACKGROUND.
    *
-   *     NULL if the font's `CPAL' table doesn't contain appropriate data.
+   *     `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
    *
    *   num_palette_entries ::
    *     The number of entries in a single palette.  All palettes have the
    *     same size.
    *
    *   palette_entry_name_ids ::
-   *     A read-only array of palette entry name IDs with
-   *     `num_palette_entries'.  In each palette, entries with the same
-   *     index have the same function.  For example, index~0 might
-   *     correspond to string `outline' in the font's `name' table to
-   *     indicate that this palette entry is used for outlines, index~1
-   *     might correspond to `fill' to indicate the filling color palette
-   *     entry, etc.
+   *     An optional read-only array of palette entry name IDs with
+   *     `num_palette_entries`.  In each palette, entries with the same index
+   *     have the same function.  For example, index~0 might correspond to
+   *     string 'outline' in the font's 'name' table to indicate that this
+   *     palette entry is used for outlines, index~1 might correspond to
+   *     'fill' to indicate the filling color palette entry, etc.
    *
-   *     An empty entry name ID in the `CPAL' table gets represented as
-   *     value 0xFFFF.
+   *     An empty entry name ID in the 'CPAL' table gets represented as value
+   *     0xFFFF.
    *
-   *     NULL if the font's `CPAL' table doesn't contain appropriate data.
+   *     `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
    *
    * @note:
    *   Use function @FT_Get_Sfnt_Name to map name IDs and entry name IDs to
    *   name strings.
    *
+   *   Use function @FT_Palette_Select to get the colors associated with a
+   *   palette entry.
+   *
    * @since:
    *   2.10
    */
@@ -201,7 +202,7 @@
    *   All arrays in the returned @FT_Palette_Data structure are read-only.
    *
    *   This function always returns an error if the config macro
-   *   `TT_CONFIG_OPTION_COLOR_LAYERS' is not defined in `ftoption.h'.
+   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
    *
    * @since:
    *   2.10
@@ -227,7 +228,7 @@
    *
    * A corollary of (2) is that calling the function, then modifying some
    * values, then calling the function again with the same arguments resets
-   * all color entries to the original `CPAL' values; all user modifications
+   * all color entries to the original 'CPAL' values; all user modifications
    * are lost.
    *
    * @input:
@@ -239,24 +240,22 @@
    *
    * @output:
    *   apalette ::
-   *     An array of color entries for a palette with index `palette_index'.
-   *     If `apalette' is set to NULL, no array gets returned (and no color
-   *     entries can be modified).
+   *     An array of color entries for a palette with index `palette_index`,
+   *     having `num_palette_entries` elements (as found in the
+   *     `FT_Palette_Data` structure).  If `apalette` is set to `NULL`, no
+   *     array gets returned (and no color entries can be modified).
    *
-   *     In case the font doesn't support color palettes, NULL is returned.
+   *     In case the font doesn't support color palettes, `NULL` is returned.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The number of color entries is given by the `num_palette_entries'
-   *   field in the @FT_Palette_Data structure.
-   *
-   *   The array pointed to by `apalette_entries' is owned and managed by
+   *   The array pointed to by `apalette_entries` is owned and managed by
    *   FreeType.
    *
    *   This function always returns an error if the config macro
-   *   `TT_CONFIG_OPTION_COLOR_LAYERS' is not defined in `ftoption.h'.
+   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
    *
    * @since:
    *   2.10
@@ -273,7 +272,7 @@
    *   FT_Palette_Set_Foreground_Color
    *
    * @description:
-   *   `COLR' uses palette index 0xFFFF to indicate a `text foreground
+   *   'COLR' uses palette index 0xFFFF to indicate a 'text foreground
    *   color'.  This function sets this value.
    *
    * @input:
@@ -281,7 +280,7 @@
    *     The source face handle.
    *
    *   foreground_color ::
-   *     An `FT_Color' structure to define the text foreground color.
+   *     An `FT_Color` structure to define the text foreground color.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -289,13 +288,12 @@
    * @note:
    *   If this function isn't called, the text foreground color is set to
    *   white opaque (BGRA value 0xFFFFFFFF) if
-   *   @FT_PALETTE_FOR_DARK_BACKGROUND is present for the current
-   *   palette, and black opaque (BGRA value 0x000000FF) otherwise,
-   *   including the case that no palette types are available in the `CPAL'
-   *   table.
+   *   @FT_PALETTE_FOR_DARK_BACKGROUND is present for the current palette,
+   *   and black opaque (BGRA value 0x000000FF) otherwise, including the case
+   *   that no palette types are available in the 'CPAL' table.
    *
    *   This function always returns an error if the config macro
-   *   `TT_CONFIG_OPTION_COLOR_LAYERS' is not defined in `ftoption.h'.
+   *   `TT_CONFIG_OPTION_COLOR_LAYERS` is not defined in `ftoption.h`.
    *
    * @since:
    *   2.10
@@ -304,6 +302,1360 @@
   FT_Palette_Set_Foreground_Color( FT_Face   face,
                                    FT_Color  foreground_color );
 
+
+  /**************************************************************************
+   *
+   * @section:
+   *   layer_management
+   *
+   * @title:
+   *   Glyph Layer Management
+   *
+   * @abstract:
+   *   Retrieving and manipulating OpenType's 'COLR' table data.
+   *
+   * @description:
+   *   The functions described here allow access of colored glyph layer data
+   *   in OpenType's 'COLR' tables.
+   */
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_LayerIterator
+   *
+   * @description:
+   *   This iterator object is needed for @FT_Get_Color_Glyph_Layer.
+   *
+   * @fields:
+   *   num_layers ::
+   *     The number of glyph layers for the requested glyph index.  Will be
+   *     set by @FT_Get_Color_Glyph_Layer.
+   *
+   *   layer ::
+   *     The current layer.  Will be set by @FT_Get_Color_Glyph_Layer.
+   *
+   *   p ::
+   *     An opaque pointer into 'COLR' table data.  The caller must set this
+   *     to `NULL` before the first call of @FT_Get_Color_Glyph_Layer.
+   */
+  typedef struct  FT_LayerIterator_
+  {
+    FT_UInt   num_layers;
+    FT_UInt   layer;
+    FT_Byte*  p;
+
+  } FT_LayerIterator;
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Color_Glyph_Layer
+   *
+   * @description:
+   *   This is an interface to the 'COLR' table in OpenType fonts to
+   *   iteratively retrieve the colored glyph layers associated with the
+   *   current glyph slot.
+   *
+   *     https://docs.microsoft.com/en-us/typography/opentype/spec/colr
+   *
+   *   The glyph layer data for a given glyph index, if present, provides an
+   *   alternative, multi-color glyph representation: Instead of rendering
+   *   the outline or bitmap with the given glyph index, glyphs with the
+   *   indices and colors returned by this function are rendered layer by
+   *   layer.
+   *
+   *   The returned elements are ordered in the z~direction from bottom to
+   *   top; the 'n'th element should be rendered with the associated palette
+   *   color and blended on top of the already rendered layers (elements 0,
+   *   1, ..., n-1).
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   *   base_glyph ::
+   *     The glyph index the colored glyph layers are associated with.
+   *
+   * @inout:
+   *   iterator ::
+   *     An @FT_LayerIterator object.  For the first call you should set
+   *     `iterator->p` to `NULL`.  For all following calls, simply use the
+   *     same object again.
+   *
+   * @output:
+   *   aglyph_index ::
+   *     The glyph index of the current layer.
+   *
+   *   acolor_index ::
+   *     The color index into the font face's color palette of the current
+   *     layer.  The value 0xFFFF is special; it doesn't reference a palette
+   *     entry but indicates that the text foreground color should be used
+   *     instead (to be set up by the application outside of FreeType).
+   *
+   *     The color palette can be retrieved with @FT_Palette_Select.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  If there are no more layers (or if there
+   *   are no layers at all), value~0 gets returned.  In case of an error,
+   *   value~0 is returned also.
+   *
+   * @note:
+   *   This function is necessary if you want to handle glyph layers by
+   *   yourself.  In particular, functions that operate with @FT_GlyphRec
+   *   objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access
+   *   to this information.
+   *
+   *   Note that @FT_Render_Glyph is able to handle colored glyph layers
+   *   automatically if the @FT_LOAD_COLOR flag is passed to a previous call
+   *   to @FT_Load_Glyph.  [This is an experimental feature.]
+   *
+   * @example:
+   *   ```
+   *     FT_Color*         palette;
+   *     FT_LayerIterator  iterator;
+   *
+   *     FT_Bool  have_layers;
+   *     FT_UInt  layer_glyph_index;
+   *     FT_UInt  layer_color_index;
+   *
+   *
+   *     error = FT_Palette_Select( face, palette_index, &palette );
+   *     if ( error )
+   *       palette = NULL;
+   *
+   *     iterator.p  = NULL;
+   *     have_layers = FT_Get_Color_Glyph_Layer( face,
+   *                                             glyph_index,
+   *                                             &layer_glyph_index,
+   *                                             &layer_color_index,
+   *                                             &iterator );
+   *
+   *     if ( palette && have_layers )
+   *     {
+   *       do
+   *       {
+   *         FT_Color  layer_color;
+   *
+   *
+   *         if ( layer_color_index == 0xFFFF )
+   *           layer_color = text_foreground_color;
+   *         else
+   *           layer_color = palette[layer_color_index];
+   *
+   *         // Load and render glyph `layer_glyph_index', then
+   *         // blend resulting pixmap (using color `layer_color')
+   *         // with previously created pixmaps.
+   *
+   *       } while ( FT_Get_Color_Glyph_Layer( face,
+   *                                           glyph_index,
+   *                                           &layer_glyph_index,
+   *                                           &layer_color_index,
+   *                                           &iterator ) );
+   *     }
+   *   ```
+   *
+   * @since:
+   *   2.10
+   */
+  FT_EXPORT( FT_Bool )
+  FT_Get_Color_Glyph_Layer( FT_Face            face,
+                            FT_UInt            base_glyph,
+                            FT_UInt           *aglyph_index,
+                            FT_UInt           *acolor_index,
+                            FT_LayerIterator*  iterator );
+
+
+  /**************************************************************************
+   *
+   * @enum:
+   *   FT_PaintFormat
+   *
+   * @description:
+   *   Enumeration describing the different paint format types of the v1
+   *   extensions to the 'COLR' table, see
+   *   'https://github.com/googlefonts/colr-gradients-spec'.
+   *
+   *   The enumeration values loosely correspond with the format numbers of
+   *   the specification: FreeType always returns a fully specified 'Paint'
+   *   structure for the 'Transform', 'Translate', 'Scale', 'Rotate', and
+   *   'Skew' table types even though the specification has different formats
+   *   depending on whether or not a center is specified, whether the scale
+   *   is uniform in x and y~direction or not, etc.  Also, only non-variable
+   *   format identifiers are listed in this enumeration; as soon as support
+   *   for variable 'COLR' v1 fonts is implemented, interpolation is
+   *   performed dependent on axis coordinates, which are configured on the
+   *   @FT_Face through @FT_Set_Var_Design_Coordinates.  This implies that
+   *   always static, readily interpolated values are returned in the 'Paint'
+   *   structures.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef enum  FT_PaintFormat_
+  {
+    FT_COLR_PAINTFORMAT_COLR_LAYERS     = 1,
+    FT_COLR_PAINTFORMAT_SOLID           = 2,
+    FT_COLR_PAINTFORMAT_LINEAR_GRADIENT = 4,
+    FT_COLR_PAINTFORMAT_RADIAL_GRADIENT = 6,
+    FT_COLR_PAINTFORMAT_SWEEP_GRADIENT  = 8,
+    FT_COLR_PAINTFORMAT_GLYPH           = 10,
+    FT_COLR_PAINTFORMAT_COLR_GLYPH      = 11,
+    FT_COLR_PAINTFORMAT_TRANSFORM       = 12,
+    FT_COLR_PAINTFORMAT_TRANSLATE       = 14,
+    FT_COLR_PAINTFORMAT_SCALE           = 16,
+    FT_COLR_PAINTFORMAT_ROTATE          = 24,
+    FT_COLR_PAINTFORMAT_SKEW            = 28,
+    FT_COLR_PAINTFORMAT_COMPOSITE       = 32,
+    FT_COLR_PAINT_FORMAT_MAX            = 33,
+    FT_COLR_PAINTFORMAT_UNSUPPORTED     = 255
+
+  } FT_PaintFormat;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_ColorStopIterator
+   *
+   * @description:
+   *   This iterator object is needed for @FT_Get_Colorline_Stops.  It keeps
+   *   state while iterating over the stops of an @FT_ColorLine, representing
+   *   the `ColorLine` struct of the v1 extensions to 'COLR', see
+   *   'https://github.com/googlefonts/colr-gradients-spec'.  Do not manually
+   *   modify fields of this iterator.
+   *
+   * @fields:
+   *   num_color_stops ::
+   *     The number of color stops for the requested glyph index.  Set by
+   *     @FT_Get_Paint.
+   *
+   *   current_color_stop ::
+   *     The current color stop.  Set by @FT_Get_Colorline_Stops.
+   *
+   *   p ::
+   *     An opaque pointer into 'COLR' table data.  Set by @FT_Get_Paint.
+   *     Updated by @FT_Get_Colorline_Stops.
+   *
+   *   read_variable ::
+   *     A boolean keeping track of whether variable color lines are to be
+   *     read.  Set by @FT_Get_Paint.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_ColorStopIterator_
+  {
+    FT_UInt  num_color_stops;
+    FT_UInt  current_color_stop;
+
+    FT_Byte*  p;
+
+    FT_Bool  read_variable;
+
+  } FT_ColorStopIterator;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_ColorIndex
+   *
+   * @description:
+   *   A structure representing a `ColorIndex` value of the 'COLR' v1
+   *   extensions, see 'https://github.com/googlefonts/colr-gradients-spec'.
+   *
+   * @fields:
+   *   palette_index ::
+   *     The palette index into a 'CPAL' palette.
+   *
+   *   alpha ::
+   *     Alpha transparency value multiplied with the value from 'CPAL'.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_ColorIndex_
+  {
+    FT_UInt16   palette_index;
+    FT_F2Dot14  alpha;
+
+  } FT_ColorIndex;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_ColorStop
+   *
+   * @description:
+   *   A structure representing a `ColorStop` value of the 'COLR' v1
+   *   extensions, see 'https://github.com/googlefonts/colr-gradients-spec'.
+   *
+   * @fields:
+   *   stop_offset ::
+   *     The stop offset along the gradient, expressed as a 16.16 fixed-point
+   *     coordinate.
+   *
+   *   color ::
+   *     The color information for this stop, see @FT_ColorIndex.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_ColorStop_
+  {
+    FT_Fixed       stop_offset;
+    FT_ColorIndex  color;
+
+  } FT_ColorStop;
+
+
+  /**************************************************************************
+   *
+   * @enum:
+   *   FT_PaintExtend
+   *
+   * @description:
+   *   An enumeration representing the 'Extend' mode of the 'COLR' v1
+   *   extensions, see 'https://github.com/googlefonts/colr-gradients-spec'.
+   *   It describes how the gradient fill continues at the other boundaries.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef enum  FT_PaintExtend_
+  {
+    FT_COLR_PAINT_EXTEND_PAD     = 0,
+    FT_COLR_PAINT_EXTEND_REPEAT  = 1,
+    FT_COLR_PAINT_EXTEND_REFLECT = 2
+
+  } FT_PaintExtend;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_ColorLine
+   *
+   * @description:
+   *   A structure representing a `ColorLine` value of the 'COLR' v1
+   *   extensions, see 'https://github.com/googlefonts/colr-gradients-spec'.
+   *   It describes a list of color stops along the defined gradient.
+   *
+   * @fields:
+   *   extend ::
+   *     The extend mode at the outer boundaries, see @FT_PaintExtend.
+   *
+   *   color_stop_iterator ::
+   *     The @FT_ColorStopIterator used to enumerate and retrieve the
+   *     actual @FT_ColorStop's.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_ColorLine_
+  {
+    FT_PaintExtend        extend;
+    FT_ColorStopIterator  color_stop_iterator;
+
+  } FT_ColorLine;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_Affine23
+   *
+   * @description:
+   *   A structure used to store a 2x3 matrix.  Coefficients are in
+   *   16.16 fixed-point format.  The computation performed is
+   *
+   *   ```
+   *     x' = x*xx + y*xy + dx
+   *     y' = x*yx + y*yy + dy
+   *   ```
+   *
+   * @fields:
+   *   xx ::
+   *     Matrix coefficient.
+   *
+   *   xy ::
+   *     Matrix coefficient.
+   *
+   *   dx ::
+   *     x translation.
+   *
+   *   yx ::
+   *     Matrix coefficient.
+   *
+   *   yy ::
+   *     Matrix coefficient.
+   *
+   *   dy ::
+   *     y translation.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_Affine_23_
+  {
+    FT_Fixed  xx, xy, dx;
+    FT_Fixed  yx, yy, dy;
+
+  } FT_Affine23;
+
+
+  /**************************************************************************
+   *
+   * @enum:
+   *   FT_Composite_Mode
+   *
+   * @description:
+   *   An enumeration listing the 'COLR' v1 composite modes used in
+   *   @FT_PaintComposite.  For more details on each paint mode, see
+   *   'https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators'.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef enum  FT_Composite_Mode_
+  {
+    FT_COLR_COMPOSITE_CLEAR          = 0,
+    FT_COLR_COMPOSITE_SRC            = 1,
+    FT_COLR_COMPOSITE_DEST           = 2,
+    FT_COLR_COMPOSITE_SRC_OVER       = 3,
+    FT_COLR_COMPOSITE_DEST_OVER      = 4,
+    FT_COLR_COMPOSITE_SRC_IN         = 5,
+    FT_COLR_COMPOSITE_DEST_IN        = 6,
+    FT_COLR_COMPOSITE_SRC_OUT        = 7,
+    FT_COLR_COMPOSITE_DEST_OUT       = 8,
+    FT_COLR_COMPOSITE_SRC_ATOP       = 9,
+    FT_COLR_COMPOSITE_DEST_ATOP      = 10,
+    FT_COLR_COMPOSITE_XOR            = 11,
+    FT_COLR_COMPOSITE_PLUS           = 12,
+    FT_COLR_COMPOSITE_SCREEN         = 13,
+    FT_COLR_COMPOSITE_OVERLAY        = 14,
+    FT_COLR_COMPOSITE_DARKEN         = 15,
+    FT_COLR_COMPOSITE_LIGHTEN        = 16,
+    FT_COLR_COMPOSITE_COLOR_DODGE    = 17,
+    FT_COLR_COMPOSITE_COLOR_BURN     = 18,
+    FT_COLR_COMPOSITE_HARD_LIGHT     = 19,
+    FT_COLR_COMPOSITE_SOFT_LIGHT     = 20,
+    FT_COLR_COMPOSITE_DIFFERENCE     = 21,
+    FT_COLR_COMPOSITE_EXCLUSION      = 22,
+    FT_COLR_COMPOSITE_MULTIPLY       = 23,
+    FT_COLR_COMPOSITE_HSL_HUE        = 24,
+    FT_COLR_COMPOSITE_HSL_SATURATION = 25,
+    FT_COLR_COMPOSITE_HSL_COLOR      = 26,
+    FT_COLR_COMPOSITE_HSL_LUMINOSITY = 27,
+    FT_COLR_COMPOSITE_MAX            = 28
+
+  } FT_Composite_Mode;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_OpaquePaint
+   *
+   * @description:
+   *   A structure representing an offset to a `Paint` value stored in any
+   *   of the paint tables of a 'COLR' v1 font.  Compare Offset<24> there.
+   *   When 'COLR' v1 paint tables represented by FreeType objects such as
+   *   @FT_PaintColrLayers, @FT_PaintComposite, or @FT_PaintTransform
+   *   reference downstream nested paint tables, we do not immediately
+   *   retrieve them but encapsulate their location in this type.  Use
+   *   @FT_Get_Paint to retrieve the actual @FT_COLR_Paint object that
+   *   describes the details of the respective paint table.
+   *
+   * @fields:
+   *   p ::
+   *     An internal offset to a Paint table, needs to be set to NULL before
+   *     passing this struct as an argument to @FT_Get_Paint.
+   *
+   *   insert_root_transform ::
+   *     An internal boolean to track whether an initial root transform is
+   *     to be provided.  Do not set this value.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_Opaque_Paint_
+  {
+    FT_Byte*  p;
+    FT_Bool   insert_root_transform;
+  } FT_OpaquePaint;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintColrLayers
+   *
+   * @description:
+   *   A structure representing a `PaintColrLayers` table of a 'COLR' v1
+   *   font.  This table describes a set of layers that are to be composited
+   *   with composite mode `FT_COLR_COMPOSITE_SRC_OVER`.  The return value
+   *   of this function is an @FT_LayerIterator initialized so that it can
+   *   be used with @FT_Get_Paint_Layers to retrieve the @FT_OpaquePaint
+   *   objects as references to each layer.
+   *
+   * @fields:
+   *   layer_iterator ::
+   *     The layer iterator that describes the layers of this paint.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintColrLayers_
+  {
+    FT_LayerIterator  layer_iterator;
+
+  } FT_PaintColrLayers;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintSolid
+   *
+   * @description:
+   *   A structure representing a `PaintSolid` value of the 'COLR' v1
+   *   extensions, see 'https://github.com/googlefonts/colr-gradients-spec'.
+   *   Using a `PaintSolid` value means that the glyph layer filled with
+   *   this paint is solid-colored and does not contain a gradient.
+   *
+   * @fields:
+   *   color ::
+   *     The color information for this solid paint, see @FT_ColorIndex.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintSolid_
+  {
+    FT_ColorIndex  color;
+
+  } FT_PaintSolid;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintLinearGradient
+   *
+   * @description:
+   *   A structure representing a `PaintLinearGradient` value of the 'COLR'
+   *   v1 extensions, see
+   *   'https://github.com/googlefonts/colr-gradients-spec'.  The glyph
+   *   layer filled with this paint is drawn filled with a linear gradient.
+   *
+   * @fields:
+   *   colorline ::
+   *     The @FT_ColorLine information for this paint, i.e., the list of
+   *     color stops along the gradient.
+   *
+   *   p0 ::
+   *     The starting point of the gradient definition in font units
+   *     represented as a 16.16 fixed-point `FT_Vector`.
+   *
+   *   p1 ::
+   *     The end point of the gradient definition in font units
+   *     represented as a 16.16 fixed-point `FT_Vector`.
+   *
+   *   p2 ::
+   *     Optional point~p2 to rotate the gradient in font units
+   *     represented as a 16.16 fixed-point `FT_Vector`.
+   *     Otherwise equal to~p0.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintLinearGradient_
+  {
+    FT_ColorLine  colorline;
+
+    /* TODO: Potentially expose those as x0, y0 etc. */
+    FT_Vector  p0;
+    FT_Vector  p1;
+    FT_Vector  p2;
+
+  } FT_PaintLinearGradient;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintRadialGradient
+   *
+   * @description:
+   *   A structure representing a `PaintRadialGradient` value of the 'COLR'
+   *   v1 extensions, see
+   *   'https://github.com/googlefonts/colr-gradients-spec'.  The glyph
+   *   layer filled with this paint is drawn filled with a radial gradient.
+   *
+   * @fields:
+   *   colorline ::
+   *     The @FT_ColorLine information for this paint, i.e., the list of
+   *     color stops along the gradient.
+   *
+   *   c0 ::
+   *     The center of the starting point of the radial gradient in font
+   *     units represented as a 16.16 fixed-point `FT_Vector`.
+   *
+   *   r0 ::
+   *     The radius of the starting circle of the radial gradient in font
+   *     units represented as a 16.16 fixed-point value.
+   *
+   *   c1 ::
+   *     The center of the end point of the radial gradient in font units
+   *     represented as a 16.16 fixed-point `FT_Vector`.
+   *
+   *   r1 ::
+   *     The radius of the end circle of the radial gradient in font
+   *     units represented as a 16.16 fixed-point value.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintRadialGradient_
+  {
+    FT_ColorLine  colorline;
+
+    FT_Vector  c0;
+    FT_Pos     r0;
+    FT_Vector  c1;
+    FT_Pos     r1;
+
+  } FT_PaintRadialGradient;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintSweepGradient
+   *
+   * @description:
+   *   A structure representing a `PaintSweepGradient` value of the 'COLR'
+   *   v1 extensions, see
+   *   'https://github.com/googlefonts/colr-gradients-spec'.  The glyph
+   *   layer filled with this paint is drawn filled with a sweep gradient
+   *   from `start_angle` to `end_angle`.
+   *
+   * @fields:
+   *   colorline ::
+   *     The @FT_ColorLine information for this paint, i.e., the list of
+   *     color stops along the gradient.
+   *
+   *   center ::
+   *     The center of the sweep gradient in font units represented as a
+   *     vector of 16.16 fixed-point values.
+   *
+   *   start_angle ::
+   *     The start angle of the sweep gradient in 16.16 fixed-point
+   *     format specifying degrees divided by 180.0 (as in the
+   *     spec).  Multiply by 180.0f to receive degrees value.  Values are
+   *     given counter-clockwise, starting from the (positive) y~axis.
+   *
+   *   end_angle ::
+   *     The end angle of the sweep gradient in 16.16 fixed-point
+   *     format specifying degrees divided by 180.0 (as in the
+   *     spec).  Multiply by 180.0f to receive degrees value.  Values are
+   *     given counter-clockwise, starting from the (positive) y~axis.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintSweepGradient_
+  {
+    FT_ColorLine  colorline;
+
+    FT_Vector  center;
+    FT_Fixed   start_angle;
+    FT_Fixed   end_angle;
+
+  } FT_PaintSweepGradient;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintGlyph
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintGlyph` paint table.
+   *
+   * @fields:
+   *   paint ::
+   *     An opaque paint object pointing to a `Paint` table that serves as
+   *     the fill for the glyph ID.
+   *
+   *   glyphID ::
+   *     The glyph ID from the 'glyf' table, which serves as the contour
+   *     information that is filled with paint.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintGlyph_
+  {
+    FT_OpaquePaint  paint;
+    FT_UInt         glyphID;
+
+  } FT_PaintGlyph;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintColrGlyph
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintColorGlyph` paint table.
+   *
+   * @fields:
+   *   glyphID ::
+   *     The glyph ID from the `BaseGlyphV1List` table that is drawn for
+   *     this paint.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintColrGlyph_
+  {
+    FT_UInt  glyphID;
+
+  } FT_PaintColrGlyph;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintTransform
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintTransform` paint table.
+   *
+   * @fields:
+   *   paint ::
+   *     An opaque paint that is subject to being transformed.
+   *
+   *   affine ::
+   *     A 2x3 transformation matrix in @FT_Affine23 format containing
+   *     16.16 fixed-point values.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintTransform_
+  {
+    FT_OpaquePaint  paint;
+    FT_Affine23     affine;
+
+  } FT_PaintTransform;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintTranslate
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintTranslate` paint table.
+   *   Used for translating downstream paints by a given x and y~delta.
+   *
+   * @fields:
+   *   paint ::
+   *     An @FT_OpaquePaint object referencing the paint that is to be
+   *     rotated.
+   *
+   *   dx ::
+   *     Translation in x~direction in font units represented as a
+   *     16.16 fixed-point value.
+   *
+   *   dy ::
+   *     Translation in y~direction in font units represented as a
+   *     16.16 fixed-point value.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintTranslate_
+  {
+    FT_OpaquePaint  paint;
+
+    FT_Fixed  dx;
+    FT_Fixed  dy;
+
+  } FT_PaintTranslate;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintScale
+   *
+   * @description:
+   *   A structure representing all of the 'COLR' v1 'PaintScale*' paint
+   *   tables.  Used for scaling downstream paints by a given x and y~scale,
+   *   with a given center.  This structure is used for all 'PaintScale*'
+   *   types that are part of specification; fields of this structure are
+   *   filled accordingly.  If there is a center, the center values are set,
+   *   otherwise they are set to the zero coordinate.  If the source font
+   *   file has 'PaintScaleUniform*' set, the scale values are set
+   *   accordingly to the same value.
+   *
+   * @fields:
+   *   paint ::
+   *     An @FT_OpaquePaint object referencing the paint that is to be
+   *     scaled.
+   *
+   *   scale_x ::
+   *     Scale factor in x~direction represented as a
+   *     16.16 fixed-point value.
+   *
+   *   scale_y ::
+   *     Scale factor in y~direction represented as a
+   *     16.16 fixed-point value.
+   *
+   *   center_x ::
+   *     x~coordinate of center point to scale from represented as a
+   *     16.16 fixed-point value.
+   *
+   *   center_y ::
+   *     y~coordinate of center point to scale from represented as a
+   *     16.16 fixed-point value.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintScale_
+  {
+    FT_OpaquePaint  paint;
+
+    FT_Fixed  scale_x;
+    FT_Fixed  scale_y;
+
+    FT_Fixed  center_x;
+    FT_Fixed  center_y;
+
+  } FT_PaintScale;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintRotate
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintRotate` paint table.  Used
+   *   for rotating downstream paints with a given center and angle.
+   *
+   * @fields:
+   *   paint ::
+   *     An @FT_OpaquePaint object referencing the paint that is to be
+   *     rotated.
+   *
+   *   angle ::
+   *     The rotation angle that is to be applied in degrees divided by
+   *     180.0 (as in the spec) represented as a 16.16 fixed-point
+   *     value.  Multiply by 180.0f to receive degrees value.
+   *
+   *   center_x ::
+   *     The x~coordinate of the pivot point of the rotation in font
+   *     units represented as a 16.16 fixed-point value.
+   *
+   *   center_y ::
+   *     The y~coordinate of the pivot point of the rotation in font
+   *     units represented as a 16.16 fixed-point value.
+   *
+   * @since:
+   *   2.13
+   */
+
+  typedef struct  FT_PaintRotate_
+  {
+    FT_OpaquePaint  paint;
+
+    FT_Fixed  angle;
+
+    FT_Fixed  center_x;
+    FT_Fixed  center_y;
+
+  } FT_PaintRotate;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintSkew
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintSkew` paint table.  Used
+   *   for skewing or shearing downstream paints by a given center and
+   *   angle.
+   *
+   * @fields:
+   *   paint ::
+   *     An @FT_OpaquePaint object referencing the paint that is to be
+   *     skewed.
+   *
+   *   x_skew_angle ::
+   *     The skewing angle in x~direction in degrees divided by 180.0
+   *     (as in the spec) represented as a 16.16 fixed-point
+   *     value. Multiply by 180.0f to receive degrees.
+   *
+   *   y_skew_angle ::
+   *     The skewing angle in y~direction in degrees divided by 180.0
+   *     (as in the spec) represented as a 16.16 fixed-point
+   *     value.  Multiply by 180.0f to receive degrees.
+   *
+   *   center_x ::
+   *     The x~coordinate of the pivot point of the skew in font units
+   *     represented as a 16.16 fixed-point value.
+   *
+   *   center_y ::
+   *     The y~coordinate of the pivot point of the skew in font units
+   *     represented as a 16.16 fixed-point value.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintSkew_
+  {
+    FT_OpaquePaint  paint;
+
+    FT_Fixed  x_skew_angle;
+    FT_Fixed  y_skew_angle;
+
+    FT_Fixed  center_x;
+    FT_Fixed  center_y;
+
+  } FT_PaintSkew;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_PaintComposite
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 `PaintComposite` paint table.
+   *   Used for compositing two paints in a 'COLR' v1 directed acyclic graph.
+   *
+   * @fields:
+   *   source_paint ::
+   *     An @FT_OpaquePaint object referencing the source that is to be
+   *     composited.
+   *
+   *   composite_mode ::
+   *     An @FT_Composite_Mode enum value determining the composition
+   *     operation.
+   *
+   *   backdrop_paint ::
+   *     An @FT_OpaquePaint object referencing the backdrop paint that
+   *     `source_paint` is composited onto.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_PaintComposite_
+  {
+    FT_OpaquePaint     source_paint;
+    FT_Composite_Mode  composite_mode;
+    FT_OpaquePaint     backdrop_paint;
+
+  } FT_PaintComposite;
+
+
+  /**************************************************************************
+   *
+   * @union:
+   *   FT_COLR_Paint
+   *
+   * @description:
+   *   A union object representing format and details of a paint table of a
+   *   'COLR' v1 font, see
+   *   'https://github.com/googlefonts/colr-gradients-spec'.  Use
+   *   @FT_Get_Paint to retrieve a @FT_COLR_Paint for an @FT_OpaquePaint
+   *   object.
+   *
+   * @fields:
+   *   format ::
+   *     The gradient format for this Paint structure.
+   *
+   *   u ::
+   *     Union of all paint table types:
+   *
+   *       * @FT_PaintColrLayers
+   *       * @FT_PaintGlyph
+   *       * @FT_PaintSolid
+   *       * @FT_PaintLinearGradient
+   *       * @FT_PaintRadialGradient
+   *       * @FT_PaintSweepGradient
+   *       * @FT_PaintTransform
+   *       * @FT_PaintTranslate
+   *       * @FT_PaintRotate
+   *       * @FT_PaintSkew
+   *       * @FT_PaintComposite
+   *       * @FT_PaintColrGlyph
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_COLR_Paint_
+  {
+    FT_PaintFormat format;
+
+    union
+    {
+      FT_PaintColrLayers      colr_layers;
+      FT_PaintGlyph           glyph;
+      FT_PaintSolid           solid;
+      FT_PaintLinearGradient  linear_gradient;
+      FT_PaintRadialGradient  radial_gradient;
+      FT_PaintSweepGradient   sweep_gradient;
+      FT_PaintTransform       transform;
+      FT_PaintTranslate       translate;
+      FT_PaintScale           scale;
+      FT_PaintRotate          rotate;
+      FT_PaintSkew            skew;
+      FT_PaintComposite       composite;
+      FT_PaintColrGlyph       colr_glyph;
+
+    } u;
+
+  } FT_COLR_Paint;
+
+
+  /**************************************************************************
+   *
+   * @enum:
+   *   FT_Color_Root_Transform
+   *
+   * @description:
+   *   An enumeration to specify whether @FT_Get_Color_Glyph_Paint is to
+   *   return a root transform to configure the client's graphics context
+   *   matrix.
+   *
+   * @values:
+   *   FT_COLOR_INCLUDE_ROOT_TRANSFORM ::
+   *     Do include the root transform as the initial @FT_COLR_Paint object.
+   *
+   *   FT_COLOR_NO_ROOT_TRANSFORM ::
+   *     Do not output an initial root transform.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef enum  FT_Color_Root_Transform_
+  {
+    FT_COLOR_INCLUDE_ROOT_TRANSFORM,
+    FT_COLOR_NO_ROOT_TRANSFORM,
+
+    FT_COLOR_ROOT_TRANSFORM_MAX
+
+  } FT_Color_Root_Transform;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_ClipBox
+   *
+   * @description:
+   *   A structure representing a 'COLR' v1 'ClipBox' table.  'COLR' v1
+   *   glyphs may optionally define a clip box for aiding allocation or
+   *   defining a maximum drawable region.  Use @FT_Get_Color_Glyph_ClipBox
+   *   to retrieve it.
+   *
+   * @fields:
+   *   bottom_left ::
+   *     The bottom left corner of the clip box as an @FT_Vector with
+   *     fixed-point coordinates in 26.6 format.
+   *
+   *   top_left ::
+   *     The top left corner of the clip box as an @FT_Vector with
+   *     fixed-point coordinates in 26.6 format.
+   *
+   *   top_right ::
+   *     The top right corner of the clip box as an @FT_Vector with
+   *     fixed-point coordinates in 26.6 format.
+   *
+   *   bottom_right ::
+   *     The bottom right corner of the clip box as an @FT_Vector with
+   *     fixed-point coordinates in 26.6 format.
+   *
+   * @since:
+   *   2.13
+   */
+  typedef struct  FT_ClipBox_
+  {
+    FT_Vector  bottom_left;
+    FT_Vector  top_left;
+    FT_Vector  top_right;
+    FT_Vector  bottom_right;
+
+  } FT_ClipBox;
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Color_Glyph_Paint
+   *
+   * @description:
+   *   This is the starting point and interface to color gradient
+   *   information in a 'COLR' v1 table in OpenType fonts to recursively
+   *   retrieve the paint tables for the directed acyclic graph of a colored
+   *   glyph, given a glyph ID.
+   *
+   *     https://github.com/googlefonts/colr-gradients-spec
+   *
+   *   In a 'COLR' v1 font, each color glyph defines a directed acyclic
+   *   graph of nested paint tables, such as `PaintGlyph`, `PaintSolid`,
+   *   `PaintLinearGradient`, `PaintRadialGradient`, and so on.  Using this
+   *   function and specifying a glyph ID, one retrieves the root paint
+   *   table for this glyph ID.
+   *
+   *   This function allows control whether an initial root transform is
+   *   returned to configure scaling, transform, and translation correctly
+   *   on the client's graphics context.  The initial root transform is
+   *   computed and returned according to the values configured for @FT_Size
+   *   and @FT_Set_Transform on the @FT_Face object, see below for details
+   *   of the `root_transform` parameter.  This has implications for a
+   *   client 'COLR' v1 implementation: When this function returns an
+   *   initially computed root transform, at the time of executing the
+   *   @FT_PaintGlyph operation, the contours should be retrieved using
+   *   @FT_Load_Glyph at unscaled, untransformed size.  This is because the
+   *   root transform applied to the graphics context will take care of
+   *   correct scaling.
+   *
+   *   Alternatively, to allow hinting of contours, at the time of executing
+   *   @FT_Load_Glyph, the current graphics context transformation matrix
+   *   can be decomposed into a scaling matrix and a remainder, and
+   *   @FT_Load_Glyph can be used to retrieve the contours at scaled size.
+   *   Care must then be taken to blit or clip to the graphics context with
+   *   taking this remainder transformation into account.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   *   base_glyph ::
+   *     The glyph index for which to retrieve the root paint table.
+   *
+   *   root_transform ::
+   *     Specifies whether an initially computed root is returned by the
+   *     @FT_PaintTransform operation to account for the activated size
+   *     (see @FT_Activate_Size) and the configured transform and translate
+   *     (see @FT_Set_Transform).
+   *
+   *     This root transform is returned before nodes of the glyph graph of
+   *     the font are returned.  Subsequent @FT_COLR_Paint structures
+   *     contain unscaled and untransformed values.  The inserted root
+   *     transform enables the client application to apply an initial
+   *     transform to its graphics context.  When executing subsequent
+   *     FT_COLR_Paint operations, values from @FT_COLR_Paint operations
+   *     will ultimately be correctly scaled because of the root transform
+   *     applied to the graphics context.  Use
+   *     @FT_COLOR_INCLUDE_ROOT_TRANSFORM to include the root transform, use
+   *     @FT_COLOR_NO_ROOT_TRANSFORM to not include it.  The latter may be
+   *     useful when traversing the 'COLR' v1 glyph graph and reaching a
+   *     @FT_PaintColrGlyph.  When recursing into @FT_PaintColrGlyph and
+   *     painting that inline, no additional root transform is needed as it
+   *     has already been applied to the graphics context at the beginning
+   *     of drawing this glyph.
+   *
+   * @output:
+   *   paint ::
+   *     The @FT_OpaquePaint object that references the actual paint table.
+   *
+   *     The respective actual @FT_COLR_Paint object is retrieved via
+   *     @FT_Get_Paint.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  If no color glyph is found, or the root
+   *   paint could not be retrieved, value~0 gets returned.  In case of an
+   *   error, value~0 is returned also.
+   *
+   * @since:
+   *   2.13
+   */
+  FT_EXPORT( FT_Bool )
+  FT_Get_Color_Glyph_Paint( FT_Face                  face,
+                            FT_UInt                  base_glyph,
+                            FT_Color_Root_Transform  root_transform,
+                            FT_OpaquePaint*          paint );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Color_Glyph_ClipBox
+   *
+   * @description:
+   *   Search for a 'COLR' v1 clip box for the specified `base_glyph` and
+   *   fill the `clip_box` parameter with the 'COLR' v1 'ClipBox' information
+   *   if one is found.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   *   base_glyph ::
+   *     The glyph index for which to retrieve the clip box.
+   *
+   * @output:
+   *   clip_box ::
+   *     The clip box for the requested `base_glyph` if one is found.  The
+   *     clip box is computed taking scale and transformations configured on
+   *     the @FT_Face into account.  @FT_ClipBox contains @FT_Vector values
+   *     in 26.6 format.
+   *
+   * @return:
+   *   Value~1 if a clip box is found.  If no clip box is found or an error
+   *   occured, value~0 is returned.
+   *
+   * @note:
+   *   To retrieve the clip box in font units, reset scale to units-per-em
+   *   and remove transforms configured using @FT_Set_Transform.
+   *
+   * @since:
+   *   2.13
+   */
+  FT_EXPORT( FT_Bool )
+  FT_Get_Color_Glyph_ClipBox( FT_Face      face,
+                              FT_UInt      base_glyph,
+                              FT_ClipBox*  clip_box );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Paint_Layers
+   *
+   * @description:
+   *   Access the layers of a `PaintColrLayers` table.
+   *
+   *   If the root paint of a color glyph, or a nested paint of a 'COLR'
+   *   glyph is a `PaintColrLayers` table, this function retrieves the
+   *   layers of the `PaintColrLayers` table.
+   *
+   *   The @FT_PaintColrLayers object contains an @FT_LayerIterator, which
+   *   is used here to iterate over the layers.  Each layer is returned as
+   *   an @FT_OpaquePaint object, which then can be used with @FT_Get_Paint
+   *   to retrieve the actual paint object.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   * @inout:
+   *   iterator ::
+   *     The @FT_LayerIterator from an @FT_PaintColrLayers object, for which
+   *     the layers are to be retrieved.  The internal state of the iterator
+   *     is incremented after one call to this function for retrieving one
+   *     layer.
+   *
+   * @output:
+   *   paint ::
+   *     The @FT_OpaquePaint object that references the actual paint table.
+   *     The respective actual @FT_COLR_Paint object is retrieved via
+   *     @FT_Get_Paint.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  Value~0 gets returned when the paint
+   *   object can not be retrieved or any other error occurs.
+   *
+   * @since:
+   *   2.13
+   */
+  FT_EXPORT( FT_Bool )
+  FT_Get_Paint_Layers( FT_Face            face,
+                       FT_LayerIterator*  iterator,
+                       FT_OpaquePaint*    paint );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Colorline_Stops
+   *
+   * @description:
+   *   This is an interface to color gradient information in a 'COLR' v1
+   *   table in OpenType fonts to iteratively retrieve the gradient and
+   *   solid fill information for colored glyph layers for a specified glyph
+   *   ID.
+   *
+   *     https://github.com/googlefonts/colr-gradients-spec
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   * @inout:
+   *   iterator ::
+   *     The retrieved @FT_ColorStopIterator, configured on an @FT_ColorLine,
+   *     which in turn got retrieved via paint information in
+   *     @FT_PaintLinearGradient or @FT_PaintRadialGradient.
+   *
+   * @output:
+   *   color_stop ::
+   *     Color index and alpha value for the retrieved color stop.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  If there are no more color stops,
+   *   value~0 gets returned.  In case of an error, value~0 is returned
+   *   also.
+   *
+   * @since:
+   *   2.13
+   */
+  FT_EXPORT( FT_Bool )
+  FT_Get_Colorline_Stops( FT_Face                face,
+                          FT_ColorStop*          color_stop,
+                          FT_ColorStopIterator*  iterator );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *  FT_Get_Paint
+   *
+   * @description:
+   *   Access the details of a paint using an @FT_OpaquePaint opaque paint
+   *   object, which internally stores the offset to the respective `Paint`
+   *   object in the 'COLR' table.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   *   opaque_paint ::
+   *     The opaque paint object for which the underlying @FT_COLR_Paint
+   *     data is to be retrieved.
+   *
+   * @output:
+   *   paint ::
+   *     The specific @FT_COLR_Paint object containing information coming
+   *     from one of the font's `Paint*` tables.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  Value~0 if no details can be found for
+   *   this paint or any other error occured.
+   *
+   * @since:
+   *   2.13
+   */
+  FT_EXPORT( FT_Bool )
+  FT_Get_Paint( FT_Face         face,
+                FT_OpaquePaint  opaque_paint,
+                FT_COLR_Paint*  paint );
+
   /* */
 
 
diff --git a/include/freetype/ftdriver.h b/include/freetype/ftdriver.h
index b0a53d6..f90946f 100644
--- a/include/freetype/ftdriver.h
+++ b/include/freetype/ftdriver.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for controlling driver modules (specification only).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,9 +19,8 @@
 #ifndef FTDRIVER_H_
 #define FTDRIVER_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_PARAMETER_TAGS_H
+#include <freetype/freetype.h>
+#include <freetype/ftparams.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -50,14 +49,14 @@
    *   @FT_Property_Get.  The following lists the available properties
    *   together with the necessary macros and structures.
    *
-   *   Note that the auto-hinter's module name is `autofitter' for
-   *   historical reasons.
+   *   Note that the auto-hinter's module name is 'autofitter' for historical
+   *   reasons.
    *
    *   Available properties are @increase-x-height, @no-stem-darkening
-   *   (experimental), @darkening-parameters (experimental), @warping
-   *   (experimental), @glyph-to-script-map (experimental), @fallback-script
-   *   (experimental), and @default-script (experimental), as documented in
-   *   the @properties section.
+   *   (experimental), @darkening-parameters (experimental),
+   *   @glyph-to-script-map (experimental), @fallback-script (experimental),
+   *   and @default-script (experimental), as documented in the @properties
+   *   section.
    *
    */
 
@@ -74,54 +73,53 @@
    *   Controlling the CFF driver module.
    *
    * @description:
-   *   While FreeType's CFF driver doesn't expose API functions by itself,
-   *   it is possible to control its behaviour with @FT_Property_Set and
+   *   While FreeType's CFF driver doesn't expose API functions by itself, it
+   *   is possible to control its behaviour with @FT_Property_Set and
    *   @FT_Property_Get.
    *
-   *   The CFF driver's module name is `cff'.
+   *   The CFF driver's module name is 'cff'.
    *
    *   Available properties are @hinting-engine, @no-stem-darkening,
    *   @darkening-parameters, and @random-seed, as documented in the
    *   @properties section.
    *
    *
-   *   *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine*
+   *   **Hinting and anti-aliasing principles of the new engine**
    *
    *   The rasterizer is positioning horizontal features (e.g., ascender
    *   height & x-height, or crossbars) on the pixel grid and minimizing the
-   *   amount of antialiasing applied to them, while placing vertical
+   *   amount of anti-aliasing applied to them, while placing vertical
    *   features (vertical stems) on the pixel grid without hinting, thus
    *   representing the stem position and weight accurately.  Sometimes the
    *   vertical stems may be only partially black.  In this context,
-   *   `antialiasing' means that stems are not positioned exactly on pixel
+   *   'anti-aliasing' means that stems are not positioned exactly on pixel
    *   borders, causing a fuzzy appearance.
    *
    *   There are two principles behind this approach.
    *
-   *   1) No hinting in the horizontal direction: Unlike `superhinted'
+   *   1) No hinting in the horizontal direction: Unlike 'superhinted'
    *   TrueType, which changes glyph widths to accommodate regular
-   *   inter-glyph spacing, Adobe's approach is `faithful to the design' in
-   *   representing both the glyph width and the inter-glyph spacing
-   *   designed for the font.  This makes the screen display as close as it
-   *   can be to the result one would get with infinite resolution, while
-   *   preserving what is considered the key characteristics of each glyph.
-   *   Note that the distances between unhinted and grid-fitted positions at
-   *   small sizes are comparable to kerning values and thus would be
-   *   noticeable (and distracting) while reading if hinting were applied.
+   *   inter-glyph spacing, Adobe's approach is 'faithful to the design' in
+   *   representing both the glyph width and the inter-glyph spacing designed
+   *   for the font.  This makes the screen display as close as it can be to
+   *   the result one would get with infinite resolution, while preserving
+   *   what is considered the key characteristics of each glyph.  Note that
+   *   the distances between unhinted and grid-fitted positions at small
+   *   sizes are comparable to kerning values and thus would be noticeable
+   *   (and distracting) while reading if hinting were applied.
    *
-   *   One of the reasons to not hint horizontally is antialiasing for LCD
-   *   screens: The pixel geometry of modern displays supplies three
-   *   vertical subpixels as the eye moves horizontally across each visible
-   *   pixel.  On devices where we can be certain this characteristic is
-   *   present a rasterizer can take advantage of the subpixels to add
-   *   increments of weight.  In Western writing systems this turns out to
-   *   be the more critical direction anyway; the weights and spacing of
-   *   vertical stems (see above) are central to Armenian, Cyrillic, Greek,
-   *   and Latin type designs.  Even when the rasterizer uses greyscale
-   *   antialiasing instead of color (a necessary compromise when one
-   *   doesn't know the screen characteristics), the unhinted vertical
-   *   features preserve the design's weight and spacing much better than
-   *   aliased type would.
+   *   One of the reasons to not hint horizontally is anti-aliasing for LCD
+   *   screens: The pixel geometry of modern displays supplies three vertical
+   *   subpixels as the eye moves horizontally across each visible pixel.  On
+   *   devices where we can be certain this characteristic is present a
+   *   rasterizer can take advantage of the subpixels to add increments of
+   *   weight.  In Western writing systems this turns out to be the more
+   *   critical direction anyway; the weights and spacing of vertical stems
+   *   (see above) are central to Armenian, Cyrillic, Greek, and Latin type
+   *   designs.  Even when the rasterizer uses greyscale anti-aliasing instead
+   *   of color (a necessary compromise when one doesn't know the screen
+   *   characteristics), the unhinted vertical features preserve the design's
+   *   weight and spacing much better than aliased type would.
    *
    *   2) Alignment in the vertical direction: Weights and spacing along the
    *   y~axis are less critical; what is much more important is the visual
@@ -132,16 +130,16 @@
    *
    *   On the technical side, horizontal alignment zones for ascender,
    *   x-height, and other important height values (traditionally called
-   *   `blue zones') as defined in the font are positioned independently,
-   *   each being rounded to the nearest pixel edge, taking care of
-   *   overshoot suppression at small sizes, stem darkening, and scaling.
+   *   'blue zones') as defined in the font are positioned independently,
+   *   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
    *   horizontal features) that fall within a blue zone are said to be
-   *   `captured' and are aligned to that zone.  Uncaptured stems are moved
+   *   '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.
-   *   Unless there are conflicting hstems, the smallest movement is taken
-   *   to minimize distortion.
+   *   Unless there are conflicting hstems, the smallest movement is taken to
+   *   minimize distortion.
    *
    */
 
@@ -158,13 +156,13 @@
    *   Controlling the PCF driver module.
    *
    * @description:
-   *   While FreeType's PCF driver doesn't expose API functions by itself,
-   *   it is possible to control its behaviour with @FT_Property_Set and
+   *   While FreeType's PCF driver doesn't expose API functions by itself, it
+   *   is possible to control its behaviour with @FT_Property_Set and
    *   @FT_Property_Get.  Right now, there is a single property
    *   @no-long-family-names available if FreeType is compiled with
    *   PCF_CONFIG_OPTION_LONG_FAMILY_NAMES.
    *
-   *   The PCF driver's module name is `pcf'.
+   *   The PCF driver's module name is 'pcf'.
    *
    */
 
@@ -187,15 +185,15 @@
    *   Behind the scenes, both drivers use the Adobe CFF engine for hinting;
    *   however, the used properties must be specified separately.
    *
-   *   The Type~1 driver's module name is `type1'; the CID driver's module
-   *   name is `t1cid'.
+   *   The Type~1 driver's module name is 'type1'; the CID driver's module
+   *   name is 't1cid'.
    *
    *   Available properties are @hinting-engine, @no-stem-darkening,
    *   @darkening-parameters, and @random-seed, as documented in the
    *   @properties section.
    *
-   *   Please see the @cff_driver section for more details on the new
-   *   hinting engine.
+   *   Please see the @cff_driver section for more details on the new hinting
+   *   engine.
    *
    */
 
@@ -214,47 +212,45 @@
    * @description:
    *   While FreeType's TrueType driver doesn't expose API functions by
    *   itself, it is possible to control its behaviour with @FT_Property_Set
-   *   and @FT_Property_Get.  The following lists the available properties
-   *   together with the necessary macros and structures.
+   *   and @FT_Property_Get.
    *
-   *   The TrueType driver's module name is `truetype'.
+   *   The TrueType driver's module name is 'truetype'; a single property
+   *   @interpreter-version is available, as documented in the @properties
+   *   section.
    *
-   *   A single property @interpreter-version is available, as documented in
-   *   the @properties section.
+   *   To help understand the differences between interpreter versions, we
+   *   introduce a list of definitions, kindly provided by Greg Hitchcock.
    *
-   *   We start with a list of definitions, kindly provided by Greg
-   *   Hitchcock.
-   *
-   *   _Bi-Level_ _Rendering_
+   *   _Bi-Level Rendering_
    *
    *   Monochromatic rendering, exclusively used in the early days of
    *   TrueType by both Apple and Microsoft.  Microsoft's GDI interface
    *   supported hinting of the right-side bearing point, such that the
    *   advance width could be non-linear.  Most often this was done to
    *   achieve some level of glyph symmetry.  To enable reasonable
-   *   performance (e.g., not having to run hinting on all glyphs just to
-   *   get the widths) there was a bit in the head table indicating if the
-   *   side bearing was hinted, and additional tables, `hdmx' and `LTSH', to
-   *   cache hinting widths across multiple sizes and device aspect ratios.
+   *   performance (e.g., not having to run hinting on all glyphs just to get
+   *   the widths) there was a bit in the head table indicating if the side
+   *   bearing was hinted, and additional tables, 'hdmx' and 'LTSH', to cache
+   *   hinting widths across multiple sizes and device aspect ratios.
    *
-   *   _Font_ _Smoothing_
+   *   _Font Smoothing_
    *
    *   Microsoft's GDI implementation of anti-aliasing.  Not traditional
    *   anti-aliasing as the outlines were hinted before the sampling.  The
    *   widths matched the bi-level rendering.
    *
-   *   _ClearType_ _Rendering_
+   *   _ClearType Rendering_
    *
    *   Technique that uses physical subpixels to improve rendering on LCD
    *   (and other) displays.  Because of the higher resolution, many methods
-   *   of improving symmetry in glyphs through hinting the right-side
-   *   bearing were no longer necessary.  This lead to what GDI calls
-   *   `natural widths' ClearType, see
-   *   http://www.beatstamm.com/typography/RTRCh4.htm#Sec21.  Since hinting
+   *   of improving symmetry in glyphs through hinting the right-side bearing
+   *   were no longer necessary.  This lead to what GDI calls 'natural
+   *   widths' ClearType, see
+   *   http://rastertragedy.com/RTRCh4.htm#Sec21.  Since hinting
    *   has extra resolution, most non-linearity went away, but it is still
    *   possible for hints to change the advance widths in this mode.
    *
-   *   _ClearType_ _Compatible_ _Widths_
+   *   _ClearType Compatible Widths_
    *
    *   One of the earliest challenges with ClearType was allowing the
    *   implementation in GDI to be selected without requiring all UI and
@@ -263,41 +259,66 @@
    *   to determine the width in bi-level rendering, and then re-run in
    *   ClearType, with the difference in widths being absorbed in the font
    *   hints for ClearType (mostly in the white space of hints); see
-   *   http://www.beatstamm.com/typography/RTRCh4.htm#Sec20.  Somewhat by
+   *   http://rastertragedy.com/RTRCh4.htm#Sec20.  Somewhat by
    *   definition, compatible width ClearType allows for non-linear widths,
    *   but only when the bi-level version has non-linear widths.
    *
-   *   _ClearType_ _Subpixel_ _Positioning_
+   *   _ClearType Subpixel Positioning_
    *
    *   One of the nice benefits of ClearType is the ability to more crisply
    *   display fractional widths; unfortunately, the GDI model of integer
    *   bitmaps did not support this.  However, the WPF and Direct Write
-   *   frameworks do support fractional widths.  DWrite calls this `natural
-   *   mode', not to be confused with GDI's `natural widths'.  Subpixel
+   *   frameworks do support fractional widths.  DWrite calls this 'natural
+   *   mode', not to be confused with GDI's 'natural widths'.  Subpixel
    *   positioning, in the current implementation of Direct Write,
    *   unfortunately does not support hinted advance widths, see
-   *   http://www.beatstamm.com/typography/RTRCh4.htm#Sec22.  Note that the
+   *   http://rastertragedy.com/RTRCh4.htm#Sec22.  Note that the
    *   TrueType interpreter fully allows the advance width to be adjusted in
    *   this mode, just the DWrite client will ignore those changes.
    *
-   *   _ClearType_ _Backward_ _Compatibility_
+   *   _ClearType Backward Compatibility_
    *
    *   This is a set of exceptions made in the TrueType interpreter to
    *   minimize hinting techniques that were problematic with the extra
    *   resolution of ClearType; see
-   *   http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and
+   *   http://rastertragedy.com/RTRCh4.htm#Sec1 and
    *   https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx.
-   *   This technique is not to be confused with ClearType compatible
-   *   widths.  ClearType backward compatibility has no direct impact on
-   *   changing advance widths, but there might be an indirect impact on
-   *   disabling some deltas.  This could be worked around in backward
-   *   compatibility mode.
+   *   This technique is not to be confused with ClearType compatible widths.
+   *   ClearType backward compatibility has no direct impact on changing
+   *   advance widths, but there might be an indirect impact on disabling
+   *   some deltas.  This could be worked around in backward compatibility
+   *   mode.
    *
-   *   _Native_ _ClearType_ _Mode_
+   *   _Native ClearType Mode_
    *
-   *   (Not to be confused with `natural widths'.)  This mode removes all
-   *   the exceptions in the TrueType interpreter when running with
-   *   ClearType.  Any issues on widths would still apply, though.
+   *   (Not to be confused with 'natural widths'.)  This mode removes all the
+   *   exceptions in the TrueType interpreter when running with ClearType.
+   *   Any issues on widths would still apply, though.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   ot_svg_driver
+   *
+   * @title:
+   *   The SVG driver
+   *
+   * @abstract:
+   *   Controlling the external rendering of OT-SVG glyphs.
+   *
+   * @description:
+   *   By default, FreeType can only load the 'SVG~' table of OpenType fonts
+   *   if configuration macro `FT_CONFIG_OPTION_SVG` is defined.  To make it
+   *   render SVG glyphs, an external SVG rendering library is needed.  All
+   *   details on the interface between FreeType and the external library
+   *   via function hooks can be found in section @svg_fonts.
+   *
+   *   The OT-SVG driver's module name is 'ot-svg'; it supports a single
+   *   property called @svg-hooks, documented below in the @properties
+   *   section.
    *
    */
 
@@ -328,8 +349,8 @@
    *   FT_HINTING_XXX
    *
    * @description:
-   *   A list of constants used for the @hinting-engine property to
-   *   select the hinting engine for CFF, Type~1, and CID fonts.
+   *   A list of constants used for the @hinting-engine property to select
+   *   the hinting engine for CFF, Type~1, and CID fonts.
    *
    * @values:
    *   FT_HINTING_FREETYPE ::
@@ -356,46 +377,42 @@
    *   hinting-engine
    *
    * @description:
-   *   Thanks to Adobe, which contributed a new hinting (and parsing)
-   *   engine, an application can select between `freetype' and `adobe' if
-   *   compiled with CFF_CONFIG_OPTION_OLD_ENGINE.  If this configuration
-   *   macro isn't defined, `hinting-engine' does nothing.
+   *   Thanks to Adobe, which contributed a new hinting (and parsing) engine,
+   *   an application can select between 'freetype' and 'adobe' if compiled
+   *   with `CFF_CONFIG_OPTION_OLD_ENGINE`.  If this configuration macro
+   *   isn't defined, 'hinting-engine' does nothing.
    *
    *   The same holds for the Type~1 and CID modules if compiled with
-   *   T1_CONFIG_OPTION_OLD_ENGINE.
+   *   `T1_CONFIG_OPTION_OLD_ENGINE`.
    *
-   *   For the `cff' module, the default engine is `freetype' if
-   *   CFF_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' otherwise.
-   *
-   *   For both the `type1' and `t1cid' modules, the default engine is
-   *   `freetype' if T1_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe'
-   *   otherwise.
+   *   For the 'cff' module, the default engine is 'adobe'.  For both the
+   *   'type1' and 't1cid' modules, the default engine is 'adobe', too.
    *
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
-   *   variable (using values `adobe' or `freetype').
+   *   This property can be set via the `FREETYPE_PROPERTIES` environment
+   *   variable (using values 'adobe' or 'freetype').
    *
    * @example:
    *   The following example code demonstrates how to select Adobe's hinting
-   *   engine for the `cff' module (omitting the error handling).
+   *   engine for the 'cff' module (omitting the error handling).
    *
-   *   {
+   *   ```
    *     FT_Library  library;
-   *     FT_UInt     hinting_engine = FT_CFF_HINTING_ADOBE;
+   *     FT_UInt     hinting_engine = FT_HINTING_ADOBE;
    *
    *
    *     FT_Init_FreeType( &library );
    *
    *     FT_Property_Set( library, "cff",
    *                               "hinting-engine", &hinting_engine );
-   *   }
+   *   ```
    *
    * @since:
-   *   2.4.12 (for `cff' module)
+   *   2.4.12 (for 'cff' module)
    *
-   *   2.9 (for `type1' and `t1cid' modules)
+   *   2.9 (for 'type1' and 't1cid' modules)
    *
    */
 
@@ -406,10 +423,10 @@
    *   no-stem-darkening
    *
    * @description:
-   *   All glyphs that pass through the auto-hinter will be emboldened
-   *   unless this property is set to TRUE.  The same is true for the CFF,
-   *   Type~1, and CID font modules if the `Adobe' engine is selected (which
-   *   is the default).
+   *   All glyphs that pass through the auto-hinter will be emboldened unless
+   *   this property is set to TRUE.  The same is true for the CFF, Type~1,
+   *   and CID font modules if the 'Adobe' engine is selected (which is the
+   *   default).
    *
    *   Stem darkening emboldens glyphs at smaller sizes to make them more
    *   readable on common low-DPI screens when using linear alpha blending
@@ -420,39 +437,34 @@
    *   Gamma correction essentially lightens fonts since shades of grey are
    *   shifted to higher pixel values (=~higher brightness) to match the
    *   original intention to the reality of our screens.  The side-effect is
-   *   that glyphs `thin out'.  Mac OS~X and Adobe's proprietary font
+   *   that glyphs 'thin out'.  Mac OS~X and Adobe's proprietary font
    *   rendering library implement a counter-measure: stem darkening at
    *   smaller sizes where shades of gray dominate.  By emboldening a glyph
    *   slightly in relation to its pixel size, individual pixels get higher
-   *   coverage of filled-in outlines and are therefore `blacker'.  This
-   *   counteracts the `thinning out' of glyphs, making text remain readable
+   *   coverage of filled-in outlines and are therefore 'blacker'.  This
+   *   counteracts the 'thinning out' of glyphs, making text remain readable
    *   at smaller sizes.
    *
-   *   By default, the Adobe engines for CFF, Type~1, and CID fonts darken
-   *   stems at smaller sizes, regardless of hinting, to enhance contrast.
-   *   Setting this property, stem darkening gets switched off.
-   *
-   *   For the auto-hinter, stem-darkening is experimental currently and
-   *   thus switched off by default (this 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
+   *   For the auto-hinter, stem-darkening is experimental currently and thus
+   *   switched off by default (this 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
    *   precomputed blue zones.  The smaller the size (especially 9ppem and
    *   down), the higher the loss of emboldening versus the CFF driver.
    *
-   *   Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is
-   *   set.
+   *   Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set.
    *
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
-   *   variable (using values 1 and 0 for `on' and `off', respectively).
-   *   It can also be set per face using @FT_Face_Properties with
+   *   This property can be set via the `FREETYPE_PROPERTIES` environment
+   *   variable (using values 1 and 0 for 'on' and 'off', respectively).  It
+   *   can also be set per face using @FT_Face_Properties with
    *   @FT_PARAM_TAG_STEM_DARKENING.
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Library  library;
    *     FT_Bool     no_stem_darkening = TRUE;
    *
@@ -461,14 +473,14 @@
    *
    *     FT_Property_Set( library, "cff",
    *                               "no-stem-darkening", &no_stem_darkening );
-   *   }
+   *   ```
    *
    * @since:
-   *   2.4.12 (for `cff' module)
+   *   2.4.12 (for 'cff' module)
    *
-   *   2.6.2 (for `autofitter' module)
+   *   2.6.2 (for 'autofitter' module)
    *
-   *   2.9 (for `type1' and `t1cid' modules)
+   *   2.9 (for 'type1' and 't1cid' modules)
    *
    */
 
@@ -480,29 +492,29 @@
    *
    * @description:
    *   By default, the Adobe hinting engine, as used by the CFF, Type~1, and
-   *   CID font drivers, darkens stems as follows (if the
-   *   `no-stem-darkening' property isn't set):
+   *   CID font drivers, darkens stems as follows (if the `no-stem-darkening`
+   *   property isn't set):
    *
-   *   {
+   *   ```
    *     stem width <= 0.5px:   darkening amount = 0.4px
    *     stem width  = 1px:     darkening amount = 0.275px
    *     stem width  = 1.667px: darkening amount = 0.275px
    *     stem width >= 2.333px: darkening amount = 0px
-   *   }
+   *   ```
    *
    *   and piecewise linear in-between.  At configuration time, these four
    *   control points can be set with the macro
-   *   `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'; the CFF, Type~1, and CID
+   *   `CFF_CONFIG_OPTION_DARKENING_PARAMETERS`; the CFF, Type~1, and CID
    *   drivers share these values.  At runtime, the control points can be
-   *   changed using the `darkening-parameters' property (see the example
+   *   changed using the `darkening-parameters` property (see the example
    *   below that demonstrates this for the Type~1 driver).
    *
    *   The x~values give the stem width, and the y~values the darkening
    *   amount.  The unit is 1000th of pixels.  All coordinate values must be
-   *   positive; the x~values must be monotonically increasing; the
-   *   y~values must be monotonically decreasing and smaller than or
-   *   equal to 500 (corresponding to half a pixel); the slope of each
-   *   linear piece must be shallower than -1 (e.g., -.4).
+   *   positive; the x~values must be monotonically increasing; the y~values
+   *   must be monotonically decreasing and smaller than or equal to 500
+   *   (corresponding to half a pixel); the slope of each linear piece must
+   *   be shallower than -1 (e.g., -.4).
    *
    *   The auto-hinter provides this property, too, as an experimental
    *   feature.  See @no-stem-darkening for more.
@@ -510,17 +522,17 @@
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   This property can be set via the `FREETYPE_PROPERTIES` environment
    *   variable, using eight comma-separated integers without spaces.  Here
-   *   the above example, using `\' to break the line for readability.
+   *   the above example, using `\` to break the line for readability.
    *
-   *   {
+   *   ```
    *     FREETYPE_PROPERTIES=\
    *     type1:darkening-parameters=500,300,1000,200,1500,100,2000,0
-   *   }
+   *   ```
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Library  library;
    *     FT_Int      darken_params[8] = {  500, 300,   // x1, y1
    *                                      1000, 200,   // x2, y2
@@ -532,14 +544,14 @@
    *
    *     FT_Property_Set( library, "type1",
    *                               "darkening-parameters", darken_params );
-   *   }
+   *   ```
    *
    * @since:
-   *   2.5.1 (for `cff' module)
+   *   2.5.1 (for 'cff' module)
    *
-   *   2.6.2 (for `autofitter' module)
+   *   2.6.2 (for 'autofitter' module)
    *
-   *   2.9 (for `type1' and `t1cid' modules)
+   *   2.9 (for 'type1' and 't1cid' modules)
    *
    */
 
@@ -550,29 +562,29 @@
    *   random-seed
    *
    * @description:
-   *   By default, the seed value for the CFF `random' operator and the
-   *   similar `0 28 callothersubr pop' command for the Type~1 and CID
+   *   By default, the seed value for the CFF 'random' operator and the
+   *   similar '0 28 callothersubr pop' command for the Type~1 and CID
    *   drivers is set to a random value.  However, mainly for debugging
-   *   purposes, it is often necessary to use a known value as a seed so
-   *   that the pseudo-random number sequences generated by `random' are
+   *   purposes, it is often necessary to use a known value as a seed so that
+   *   the pseudo-random number sequences generated by 'random' are
    *   repeatable.
    *
-   *   The `random-seed' property does that.  Its argument is a signed 32bit
+   *   The `random-seed` property does that.  Its argument is a signed 32bit
    *   integer; if the value is zero or negative, the seed given by the
-   *   `intitialRandomSeed' private DICT operator in a CFF file gets used
-   *   (or a default value if there is no such operator).  If the value is
-   *   positive, use it instead of `initialRandomSeed', which is
-   *   consequently ignored.
+   *   `intitialRandomSeed` private DICT operator in a CFF file gets used (or
+   *   a default value if there is no such operator).  If the value is
+   *   positive, use it instead of `initialRandomSeed`, which is consequently
+   *   ignored.
    *
    * @note:
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   This property can be set via the `FREETYPE_PROPERTIES` environment
    *   variable.  It can also be set per face using @FT_Face_Properties with
    *   @FT_PARAM_TAG_RANDOM_SEED.
    *
    * @since:
-   *   2.8 (for `cff' module)
+   *   2.8 (for 'cff' module)
    *
-   *   2.9 (for `type1' and `t1cid' modules)
+   *   2.9 (for 'type1' and 't1cid' modules)
    *
    */
 
@@ -583,28 +595,28 @@
    *   no-long-family-names
    *
    * @description:
-   *   If PCF_CONFIG_OPTION_LONG_FAMILY_NAMES is active while compiling
+   *   If `PCF_CONFIG_OPTION_LONG_FAMILY_NAMES` is active while compiling
    *   FreeType, the PCF driver constructs long family names.
    *
-   *   There are many PCF fonts just called `Fixed' which look completely
+   *   There are many PCF fonts just called 'Fixed' which look completely
    *   different, and which have nothing to do with each other.  When
-   *   selecting `Fixed' in KDE or Gnome one gets results that appear rather
-   *   random, the style changes often if one changes the size and one
-   *   cannot select some fonts at all.  The improve this situation, the PCF
-   *   module prepends the foundry name (plus a space) to the family name.
-   *   It also checks whether there are `wide' characters; all put together,
-   *   family names like `Sony Fixed' or `Misc Fixed Wide' are constructed.
+   *   selecting 'Fixed' in KDE or Gnome one gets results that appear rather
+   *   random, the style changes often if one changes the size and one cannot
+   *   select some fonts at all.  The improve this situation, the PCF module
+   *   prepends the foundry name (plus a space) to the family name.  It also
+   *   checks whether there are 'wide' characters; all put together, family
+   *   names like 'Sony Fixed' or 'Misc Fixed Wide' are constructed.
    *
-   *   If `no-long-family-names' is set, this feature gets switched off.
+   *   If `no-long-family-names` is set, this feature gets switched off.
    *
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
-   *   variable (using values 1 and 0 for `on' and `off', respectively).
+   *   This property can be set via the `FREETYPE_PROPERTIES` environment
+   *   variable (using values 1 and 0 for 'on' and 'off', respectively).
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Library  library;
    *     FT_Bool     no_long_family_names = TRUE;
    *
@@ -614,7 +626,7 @@
    *     FT_Property_Set( library, "pcf",
    *                               "no-long-family-names",
    *                               &no_long_family_names );
-   *   }
+   *   ```
    *
    * @since:
    *   2.8
@@ -630,8 +642,8 @@
    *   A list of constants used for the @interpreter-version property to
    *   select the hinting engine for Truetype fonts.
    *
-   *   The numeric value in the constant names represents the version
-   *   number as returned by the `GETINFO' bytecode instruction.
+   *   The numeric value in the constant names represents the version number
+   *   as returned by the 'GETINFO' bytecode instruction.
    *
    * @values:
    *   TT_INTERPRETER_VERSION_35 ::
@@ -642,38 +654,37 @@
    *     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.
+   *     Windows~7).  It is used in FreeType to select the 'Infinality'
+   *     subpixel hinting code.  The code may be removed in a future version.
    *
    *   TT_INTERPRETER_VERSION_40 ::
    *     Version~40 corresponds to MS rasterizer v.2.1; it is roughly
    *     equivalent to the hinting provided by DirectWrite ClearType (as can
    *     be found, for example, in Microsoft's Edge Browser on Windows~10).
-   *     It is used in FreeType to select the `minimal' subpixel hinting
+   *     It is used in FreeType to select the 'minimal' subpixel hinting
    *     code, a stripped-down and higher performance version of the
-   *     `Infinality' code.
+   *     'Infinality' code.
    *
    * @note:
-   *   This property controls the behaviour of the bytecode interpreter
-   *   and thus how outlines get hinted.  It does *not* control how glyph
-   *   get rasterized!  In particular, it does not control subpixel color
+   *   This property controls the behaviour of the bytecode interpreter and
+   *   thus how outlines get hinted.  It does **not** control how glyph get
+   *   rasterized!  In particular, it does not control subpixel color
    *   filtering.
    *
    *   If FreeType has not been compiled with the configuration option
-   *   TT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes
-   *   an `FT_Err_Unimplemented_Feature' error.
+   *   `TT_CONFIG_OPTION_SUBPIXEL_HINTING`, selecting version~38 or~40 causes
+   *   an `FT_Err_Unimplemented_Feature` error.
    *
-   *   Depending on the graphics framework, Microsoft uses different
-   *   bytecode and rendering engines.  As a consequence, the version
-   *   numbers returned by a call to the `GETINFO' bytecode instruction are
-   *   more convoluted than desired.
+   *   Depending on the graphics framework, Microsoft uses different bytecode
+   *   and rendering engines.  As a consequence, the version numbers returned
+   *   by a call to the 'GETINFO' bytecode instruction are more convoluted
+   *   than desired.
    *
-   *   Here are two tables that try to shed some light on the possible
-   *   values for the MS rasterizer engine, together with the additional
-   *   features introduced by it.
+   *   Here are two tables that try to shed some light on the possible values
+   *   for the MS rasterizer engine, together with the additional features
+   *   introduced by it.
    *
-   *   {
+   *   ```
    *     GETINFO framework               version feature
    *     -------------------------------------------------------------------
    *         3   GDI (Win 3.1),            v1.0  16-bit, first version
@@ -696,15 +707,15 @@
    *        40   GDI+ (after Win 7),       v2.1  Y-direction ClearType flag
    *             DWrite (Win 8)                    in GETINFO opcode,
    *                                             Gray ClearType
-   *   }
+   *   ```
    *
-   *   The `version' field gives a rough orientation only, since some
+   *   The 'version' field gives a rough orientation only, since some
    *   applications provided certain features much earlier (as an example,
    *   Microsoft Reader used subpixel and Y-direction ClearType already in
    *   Windows 2000).  Similarly, updates to a given framework might include
    *   improved hinting support.
    *
-   *   {
+   *   ```
    *      version   sampling          rendering        comment
    *               x        y       x           y
    *     --------------------------------------------------------------
@@ -714,38 +725,38 @@
    *       v1.9   high    high    color-filter  gray   Color ClearType
    *       v2.1   high    normal  gray          B/W    Gray ClearType
    *       v2.1   high    high    gray          gray   Gray ClearType
-   *   }
+   *   ```
    *
    *   Color and Gray ClearType are the two available variants of
-   *   `Y-direction ClearType', meaning grayscale rasterization along the
+   *   'Y-direction ClearType', meaning grayscale rasterization along the
    *   Y-direction; the name used in the TrueType specification for this
-   *   feature is `symmetric smoothing'.  `Classic ClearType' is the
-   *   original algorithm used before introducing a modified version in
-   *   Win~XP.  Another name for v1.6's grayscale rendering is `font
-   *   smoothing', and `Color ClearType' is sometimes also called `DWrite
-   *   ClearType'.  To differentiate between today's Color ClearType and the
-   *   earlier ClearType variant with B/W rendering along the vertical axis,
-   *   the latter is sometimes called `GDI ClearType'.
+   *   feature is 'symmetric smoothing'.  'Classic ClearType' is the original
+   *   algorithm used before introducing a modified version in Win~XP.
+   *   Another name for v1.6's grayscale rendering is 'font smoothing', and
+   *   'Color ClearType' is sometimes also called 'DWrite ClearType'.  To
+   *   differentiate between today's Color ClearType and the earlier
+   *   ClearType variant with B/W rendering along the vertical axis, the
+   *   latter is sometimes called 'GDI ClearType'.
    *
-   *   `Normal' and `high' sampling describe the (virtual) resolution to
-   *   access the rasterized outline after the hinting process.  `Normal'
+   *   'Normal' and 'high' sampling describe the (virtual) resolution to
+   *   access the rasterized outline after the hinting process.  'Normal'
    *   means 1 sample per grid line (i.e., B/W).  In the current Microsoft
-   *   implementation, `high' means an extra virtual resolution of 16x16 (or
-   *   16x1) grid lines per pixel for bytecode instructions like `MIRP'.
+   *   implementation, 'high' means an extra virtual resolution of 16x16 (or
+   *   16x1) grid lines per pixel for bytecode instructions like 'MIRP'.
    *   After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid
    *   lines for color filtering if Color ClearType is activated.
    *
-   *   Note that `Gray ClearType' is essentially the same as v1.6's
-   *   grayscale rendering.  However, the GETINFO instruction handles it
-   *   differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1
-   *   returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing),
-   *   and~19 (Gray ClearType).  Also, this mode respects bits 2 and~3 for
-   *   the version~1 gasp table exclusively (like Color ClearType), while
-   *   v1.6 only respects the values of version~0 (bits 0 and~1).
+   *   Note that 'Gray ClearType' is essentially the same as v1.6's grayscale
+   *   rendering.  However, the GETINFO instruction handles it differently:
+   *   v1.6 returns bit~12 (hinting for grayscale), while v2.1 returns
+   *   bits~13 (hinting for ClearType), 18 (symmetrical smoothing), and~19
+   *   (Gray ClearType).  Also, this mode respects bits 2 and~3 for the
+   *   version~1 gasp table exclusively (like Color ClearType), while v1.6
+   *   only respects the values of version~0 (bits 0 and~1).
    *
-   *   Keep in mind that the features of the above interpreter versions
-   *   might not map exactly to FreeType features or behavior because it is
-   *   a fundamentally different library with different internals.
+   *   Keep in mind that the features of the above interpreter versions might
+   *   not map exactly to FreeType features or behavior because it is a
+   *   fundamentally different library with different internals.
    *
    */
 #define TT_INTERPRETER_VERSION_35  35
@@ -759,25 +770,25 @@
    *   interpreter-version
    *
    * @description:
-   *   Currently, three versions are available, two representing the
-   *   bytecode interpreter with subpixel hinting support (old `Infinality'
-   *   code and new stripped-down and higher performance `minimal' code) and
-   *   one without, respectively.  The default is subpixel support if
-   *   TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support
-   *   otherwise (since it isn't available then).
+   *   Currently, three versions are available, two representing the bytecode
+   *   interpreter with subpixel hinting support (old 'Infinality' code and
+   *   new stripped-down and higher performance 'minimal' code) and one
+   *   without, respectively.  The default is subpixel support if
+   *   `TT_CONFIG_OPTION_SUBPIXEL_HINTING` is defined, and no subpixel
+   *   support otherwise (since it isn't available then).
    *
    *   If subpixel hinting is on, many TrueType bytecode instructions behave
-   *   differently compared to B/W or grayscale rendering (except if `native
+   *   differently compared to B/W or grayscale rendering (except if 'native
    *   ClearType' is selected by the font).  Microsoft's main idea is to
    *   render at a much increased horizontal resolution, then sampling down
    *   the created output to subpixel precision.  However, many older fonts
-   *   are not suited to this and must be specially taken care of by
-   *   applying (hardcoded) tweaks in Microsoft's interpreter.
+   *   are not suited to this and must be specially taken care of by applying
+   *   (hardcoded) tweaks in Microsoft's interpreter.
    *
    *   Details on subpixel hinting and some of the necessary tweaks can be
    *   found in Greg Hitchcock's whitepaper at
-   *   `https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
-   *   Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2,
+   *   'https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
+   *   Note that FreeType currently doesn't really 'subpixel hint' (6x1, 6x2,
    *   or 6x5 supersampling) like discussed in the paper.  Depending on the
    *   chosen interpreter, it simply ignores instructions on vertical stems
    *   to arrive at very similar results.
@@ -785,14 +796,14 @@
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
-   *   variable (using values `35', `38', or `40').
+   *   This property can be set via the `FREETYPE_PROPERTIES` environment
+   *   variable (using values '35', '38', or '40').
    *
    * @example:
    *   The following example code demonstrates how to deactivate subpixel
    *   hinting (omitting the error handling).
    *
-   *   {
+   *   ```
    *     FT_Library  library;
    *     FT_Face     face;
    *     FT_UInt     interpreter_version = TT_INTERPRETER_VERSION_35;
@@ -803,12 +814,45 @@
    *     FT_Property_Set( library, "truetype",
    *                               "interpreter-version",
    *                               &interpreter_version );
-   *   }
+   *   ```
    *
    * @since:
    *   2.5
    */
 
+  /**************************************************************************
+   *
+   * @property:
+   *   svg-hooks
+   *
+   * @description:
+   *   Set up the interface between FreeType and an extern SVG rendering
+   *   library like 'librsvg'.  All details on the function hooks can be
+   *   found in section @svg_fonts.
+   *
+   * @example:
+   *   The following example code expects that the four hook functions
+   *   `svg_*` are defined elsewhere.  Error handling is omitted, too.
+   *
+   *   ```
+   *     FT_Library  library;
+   *     SVG_RendererHooks  hooks = {
+   *                          (SVG_Lib_Init_Func)svg_init,
+   *                          (SVG_Lib_Free_Func)svg_free,
+   *                          (SVG_Lib_Render_Func)svg_render,
+   *                          (SVG_Lib_Preset_Slot_Func)svg_preset_slot };
+   *
+   *
+   *     FT_Init_FreeType( &library );
+   *
+   *     FT_Property_Set( library, "ot-svg",
+   *                               "svg-hooks", &hooks );
+   *   ```
+   *
+   * @since:
+   *   2.12
+   */
+
 
   /**************************************************************************
    *
@@ -816,7 +860,7 @@
    *   glyph-to-script-map
    *
    * @description:
-   *   *Experimental* *only*
+   *   **Experimental only**
    *
    *   The auto-hinter provides various script modules to hint glyphs.
    *   Examples of supported scripts are Latin or CJK.  Before a glyph is
@@ -824,26 +868,26 @@
    *   the script is then determined based on Unicode character ranges, see
    *   below.
    *
-   *   OpenType fonts, however, often provide much more glyphs than
-   *   character codes (small caps, superscripts, ligatures, swashes, etc.),
-   *   to be controlled by so-called `features'.  Handling OpenType features
-   *   can be quite complicated and thus needs a separate library on top of
+   *   OpenType fonts, however, often provide much more glyphs than character
+   *   codes (small caps, superscripts, ligatures, swashes, etc.), to be
+   *   controlled by so-called 'features'.  Handling OpenType features can be
+   *   quite complicated and thus needs a separate library on top of
    *   FreeType.
    *
    *   The mapping between glyph indices and scripts (in the auto-hinter
-   *   sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an
-   *   array with `num_glyphs' elements, as found in the font's @FT_Face
-   *   structure.  The `glyph-to-script-map' property returns a pointer to
-   *   this array, which can be modified as needed.  Note that the
-   *   modification should happen before the first glyph gets processed by
-   *   the auto-hinter so that the global analysis of the font shapes
-   *   actually uses the modified mapping.
+   *   sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an array
+   *   with `num_glyphs` elements, as found in the font's @FT_Face structure.
+   *   The `glyph-to-script-map` property returns a pointer to this array,
+   *   which can be modified as needed.  Note that the modification should
+   *   happen before the first glyph gets processed by the auto-hinter so
+   *   that the global analysis of the font shapes actually uses the modified
+   *   mapping.
    *
    * @example:
-   *   The following example code demonstrates how to access it (omitting
-   *   the error handling).
+   *   The following example code demonstrates how to access it (omitting the
+   *   error handling).
    *
-   *   {
+   *   ```
    *     FT_Library                library;
    *     FT_Face                   face;
    *     FT_Prop_GlyphToScriptMap  prop;
@@ -860,7 +904,7 @@
    *     // adjust `prop.map' as needed right here
    *
    *     FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT );
-   *   }
+   *   ```
    *
    * @since:
    *   2.4.11
@@ -874,7 +918,7 @@
    *   FT_AUTOHINTER_SCRIPT_XXX
    *
    * @description:
-   *   *Experimental* *only*
+   *   **Experimental only**
    *
    *   A list of constants used for the @glyph-to-script-map property to
    *   specify the script submodule the auto-hinter should use for hinting a
@@ -885,14 +929,14 @@
    *     Don't auto-hint this glyph.
    *
    *   FT_AUTOHINTER_SCRIPT_LATIN ::
-   *     Apply the latin auto-hinter.  For the auto-hinter, `latin' is a
-   *     very broad term, including Cyrillic and Greek also since characters
-   *     from those scripts share the same design constraints.
+   *     Apply the latin auto-hinter.  For the auto-hinter, 'latin' is a very
+   *     broad term, including Cyrillic and Greek also since characters from
+   *     those scripts share the same design constraints.
    *
    *     By default, characters from the following Unicode ranges are
    *     assigned to this submodule.
    *
-   *     {
+   *     ```
    *       U+0020 - U+007F  // Basic Latin (no control characters)
    *       U+00A0 - U+00FF  // Latin-1 Supplement (no control characters)
    *       U+0100 - U+017F  // Latin Extended-A
@@ -921,7 +965,7 @@
    *       U+FB00 - U+FB06  // Alphab. Present. Forms (Latin Ligatures)
    *      U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols
    *      U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement
-   *     }
+   *     ```
    *
    *   FT_AUTOHINTER_SCRIPT_CJK ::
    *     Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old
@@ -930,7 +974,7 @@
    *     By default, characters from the following Unicode ranges are
    *     assigned to this submodule.
    *
-   *     {
+   *     ```
    *       U+1100 - U+11FF  // Hangul Jamo
    *       U+2E80 - U+2EFF  // CJK Radicals Supplement
    *       U+2F00 - U+2FDF  // Kangxi Radicals
@@ -963,7 +1007,7 @@
    *      U+2A700 - U+2B73F // CJK Unified Ideographs Extension C
    *      U+2B740 - U+2B81F // CJK Unified Ideographs Extension D
    *      U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement
-   *     }
+   *     ```
    *
    *   FT_AUTOHINTER_SCRIPT_INDIC ::
    *     Apply the indic auto-hinter, covering all major scripts from the
@@ -973,7 +1017,7 @@
    *     By default, characters from the following Unicode ranges are
    *     assigned to this submodule.
    *
-   *     {
+   *     ```
    *       U+0900 - U+0DFF  // Indic Range
    *       U+0F00 - U+0FFF  // Tibetan
    *       U+1900 - U+194F  // Limbu
@@ -981,7 +1025,7 @@
    *       U+A800 - U+A82F  // Syloti Nagri
    *       U+ABC0 - U+ABFF  // Meetei Mayek
    *      U+11800 - U+118DF // Sharada
-   *     }
+   *     ```
    *
    *     Note that currently Indic support is rudimentary only, missing blue
    *     zone support.
@@ -1002,7 +1046,7 @@
    *   FT_Prop_GlyphToScriptMap
    *
    * @description:
-   *   *Experimental* *only*
+   *   **Experimental only**
    *
    *   The data exchange structure for the @glyph-to-script-map property.
    *
@@ -1024,27 +1068,26 @@
    *   fallback-script
    *
    * @description:
-   *   *Experimental* *only*
+   *   **Experimental only**
    *
-   *   If no auto-hinter script module can be assigned to a glyph, a
-   *   fallback script gets assigned to it (see also the
-   *   @glyph-to-script-map property).  By default, this is
-   *   @FT_AUTOHINTER_SCRIPT_CJK.  Using the `fallback-script' property,
-   *   this fallback value can be changed.
+   *   If no auto-hinter script module can be assigned to a glyph, a fallback
+   *   script gets assigned to it (see also the @glyph-to-script-map
+   *   property).  By default, this is @FT_AUTOHINTER_SCRIPT_CJK.  Using the
+   *   `fallback-script` property, this fallback value can be changed.
    *
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
    *   It's important to use the right timing for changing this value: The
-   *   creation of the glyph-to-script map that eventually uses the
-   *   fallback script value gets triggered either by setting or reading a
+   *   creation of the glyph-to-script map that eventually uses the fallback
+   *   script value gets triggered either by setting or reading a
    *   face-specific property like @glyph-to-script-map, or by auto-hinting
    *   any glyph from that face.  In particular, if you have already created
    *   an @FT_Face structure but not loaded any glyph (using the
    *   auto-hinter), a change of the fallback script will affect this face.
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Library  library;
    *     FT_UInt     fallback_script = FT_AUTOHINTER_SCRIPT_NONE;
    *
@@ -1053,7 +1096,7 @@
    *
    *     FT_Property_Set( library, "autofitter",
    *                               "fallback-script", &fallback_script );
-   *   }
+   *   ```
    *
    * @since:
    *   2.4.11
@@ -1067,33 +1110,33 @@
    *   default-script
    *
    * @description:
-   *   *Experimental* *only*
+   *   **Experimental only**
    *
-   *   If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make
-   *   the HarfBuzz library access OpenType features for getting better
-   *   glyph coverages, this property sets the (auto-fitter) script to be
-   *   used for the default (OpenType) script data of a font's GSUB table.
-   *   Features for the default script are intended for all scripts not
-   *   explicitly handled in GSUB; an example is a `dlig' feature,
-   *   containing the combination of the characters `T', `E', and `L' to
-   *   form a `TEL' ligature.
+   *   If FreeType gets compiled with `FT_CONFIG_OPTION_USE_HARFBUZZ` to make
+   *   the HarfBuzz library access OpenType features for getting better glyph
+   *   coverages, this property sets the (auto-fitter) script to be used for
+   *   the default (OpenType) script data of a font's GSUB table.  Features
+   *   for the default script are intended for all scripts not explicitly
+   *   handled in GSUB; an example is a 'dlig' feature, containing the
+   *   combination of the characters 'T', 'E', and 'L' to form a 'TEL'
+   *   ligature.
    *
    *   By default, this is @FT_AUTOHINTER_SCRIPT_LATIN.  Using the
-   *   `default-script' property, this default value can be changed.
+   *   `default-script` property, this default value can be changed.
    *
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
    *   It's important to use the right timing for changing this value: The
-   *   creation of the glyph-to-script map that eventually uses the
-   *   default script value gets triggered either by setting or reading a
+   *   creation of the glyph-to-script map that eventually uses the default
+   *   script value gets triggered either by setting or reading a
    *   face-specific property like @glyph-to-script-map, or by auto-hinting
    *   any glyph from that face.  In particular, if you have already created
    *   an @FT_Face structure but not loaded any glyph (using the
    *   auto-hinter), a change of the default script will affect this face.
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Library  library;
    *     FT_UInt     default_script = FT_AUTOHINTER_SCRIPT_NONE;
    *
@@ -1102,7 +1145,7 @@
    *
    *     FT_Property_Set( library, "autofitter",
    *                               "default-script", &default_script );
-   *   }
+   *   ```
    *
    * @since:
    *   2.5.3
@@ -1116,9 +1159,9 @@
    *   increase-x-height
    *
    * @description:
-   *   For ppem values in the range 6~<= ppem <= `increase-x-height', round
-   *   up the font's x~height much more often than normally.  If the value
-   *   is set to~0, which is the default, this feature is switched off.  Use
+   *   For ppem values in the range 6~<= ppem <= `increase-x-height`, round
+   *   up the font's x~height much more often than normally.  If the value is
+   *   set to~0, which is the default, this feature is switched off.  Use
    *   this property to improve the legibility of small font sizes if
    *   necessary.
    *
@@ -1129,7 +1172,7 @@
    *   loading any glyph (using the auto-hinter).
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Library               library;
    *     FT_Face                  face;
    *     FT_Prop_IncreaseXHeight  prop;
@@ -1144,7 +1187,7 @@
    *
    *     FT_Property_Set( library, "autofitter",
    *                               "increase-x-height", &prop );
-   *   }
+   *   ```
    *
    * @since:
    *   2.4.11
@@ -1175,48 +1218,18 @@
    *   warping
    *
    * @description:
-   *   *Experimental* *only*
+   *   **Obsolete**
    *
-   *   If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to
-   *   activate the warp hinting code in the auto-hinter, this property
-   *   switches warping on and off.
+   *   This property was always experimental and probably never worked
+   *   correctly.  It was entirely removed from the FreeType~2 sources.  This
+   *   entry is only here for historical reference.
    *
-   *   Warping only works in `normal' auto-hinting mode replacing it.
-   *   The idea of the code is to slightly scale and shift a glyph along
-   *   the non-hinted dimension (which is usually the horizontal axis) so
-   *   that as much of its segments are aligned (more or less) to the grid.
-   *   To find out a glyph's optimal scaling and shifting value, various
-   *   parameter combinations are tried and scored.
-   *
-   *   By default, warping is off.
-   *
-   * @note:
-   *   This property can be used with @FT_Property_Get also.
-   *
-   *   This property can be set via the `FREETYPE_PROPERTIES' environment
-   *   variable (using values 1 and 0 for `on' and `off', respectively).
-   *
-   *   The warping code can also change advance widths.  Have a look at the
-   *   `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure
-   *   for details on improving inter-glyph distances while rendering.
-   *
-   *   Since warping is a global property of the auto-hinter it is best to
-   *   change its value before rendering any face.  Otherwise, you should
-   *   reload all faces that get auto-hinted in `normal' hinting mode.
-   *
-   * @example:
-   *   This example shows how to switch on warping (omitting the error
-   *   handling).
-   *
-   *   {
-   *     FT_Library  library;
-   *     FT_Bool     warping = 1;
-   *
-   *
-   *     FT_Init_FreeType( &library );
-   *
-   *     FT_Property_Set( library, "autofitter", "warping", &warping );
-   *   }
+   *   Warping only worked in 'normal' auto-hinting mode replacing it.  The
+   *   idea of the code was to slightly scale and shift a glyph along the
+   *   non-hinted dimension (which is usually the horizontal axis) so that as
+   *   much of its segments were aligned (more or less) to the grid.  To find
+   *   out a glyph's optimal scaling and shifting value, various parameter
+   *   combinations were tried and scored.
    *
    * @since:
    *   2.6
diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h
index 3d91ed0..d59b3cc 100644
--- a/include/freetype/fterrdef.h
+++ b/include/freetype/fterrdef.h
@@ -4,7 +4,7 @@
  *
  *   FreeType error codes (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -28,21 +28,20 @@
    *  All possible error codes returned by FreeType functions.
    *
    * @description:
-   *  The list below is taken verbatim from the file `fterrdef.h'
-   *  (loaded automatically by including `FT_FREETYPE_H').  The first
-   *  argument of the `FT_ERROR_DEF_' macro is the error label; by
-   *  default, the prefix `FT_Err_' gets added so that you get error
-   *  names like `FT_Err_Cannot_Open_Resource'.  The second argument is
-   *  the error code, and the last argument an error string, which is not
-   *  used by FreeType.
+   *  The list below is taken verbatim from the file `fterrdef.h` (loaded
+   *  automatically by including `FT_FREETYPE_H`).  The first argument of the
+   *  `FT_ERROR_DEF_` macro is the error label; by default, the prefix
+   *  `FT_Err_` gets added so that you get error names like
+   *  `FT_Err_Cannot_Open_Resource`.  The second argument is the error code,
+   *  and the last argument an error string, which is not used by FreeType.
    *
-   *  Within your application you should *only* use error names and
-   *  *never* its numeric values!  The latter might (and actually do)
+   *  Within your application you should **only** use error names and
+   *  **never** its numeric values!  The latter might (and actually do)
    *  change in forthcoming FreeType versions.
    *
-   *  Macro `FT_NOERRORDEF_' defines `FT_Err_Ok', which is always zero.
-   *  See the `Error Enumerations' subsection how to automatically
-   *  generate a list of error strings.
+   *  Macro `FT_NOERRORDEF_` defines `FT_Err_Ok`, which is always zero.  See
+   *  the 'Error Enumerations' subsection how to automatically generate a
+   *  list of error strings.
    *
    */
 
@@ -102,6 +101,8 @@
                 "too many hints" )
   FT_ERRORDEF_( Invalid_Pixel_Size,                          0x17,
                 "invalid pixel size" )
+  FT_ERRORDEF_( Invalid_SVG_Document,                        0x18,
+                "invalid SVG document" )
 
   /* handle errors */
 
@@ -235,6 +236,8 @@
                 "found FDEF or IDEF opcode in glyf bytecode" )
   FT_ERRORDEF_( Missing_Bitmap,                              0x9D,
                 "missing bitmap in strike" )
+  FT_ERRORDEF_( Missing_SVG_Hooks,                           0x9E,
+                "SVG hooks have not been set" )
 
   /* CFF, CID, and Type 1 errors */
 
diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h
index d602bd5..15ef3f7 100644
--- a/include/freetype/fterrors.h
+++ b/include/freetype/fterrors.h
@@ -4,7 +4,7 @@
  *
  *   FreeType error code handling (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,92 +19,102 @@
   /**************************************************************************
    *
    * @section:
-   *  error_enumerations
+   *   error_enumerations
    *
    * @title:
-   *  Error Enumerations
+   *   Error Enumerations
    *
    * @abstract:
-   *  How to handle errors and error strings.
+   *   How to handle errors and error strings.
    *
    * @description:
-   *  The header file `fterrors.h' (which is automatically included by
-   *  `freetype.h' defines the handling of FreeType's enumeration
-   *  constants.  It can also be used to generate error message strings
-   *  with a small macro trick explained below.
+   *   The header file `fterrors.h` (which is automatically included by
+   *   `freetype.h`) defines the handling of FreeType's enumeration
+   *   constants.  It can also be used to generate error message strings
+   *   with a small macro trick explained below.
    *
-   *  *Error* *Formats*
+   *   **Error Formats**
    *
-   *  The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be
-   *  defined in `ftoption.h' in order to make the higher byte indicate
-   *  the module where the error has happened (this is not compatible
-   *  with standard builds of FreeType~2, however).  See the file
-   *  `ftmoderr.h' for more details.
+   *   The configuration macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` can be
+   *   defined in `ftoption.h` in order to make the higher byte indicate the
+   *   module where the error has happened (this is not compatible with
+   *   standard builds of FreeType~2, however).  See the file `ftmoderr.h`
+   *   for more details.
    *
-   *  *Error* *Message* *Strings*
+   *   **Error Message Strings**
    *
-   *  Error definitions are set up with special macros that allow client
-   *  applications to build a table of error message strings.  The
-   *  strings are not included in a normal build of FreeType~2 to save
-   *  space (most client applications do not use them).
+   *   Error definitions are set up with special macros that allow client
+   *   applications to build a table of error message strings.  The strings
+   *   are not included in a normal build of FreeType~2 to save space (most
+   *   client applications do not use them).
    *
-   *  To do so, you have to define the following macros before including
-   *  this file.
+   *   To do so, you have to define the following macros before including
+   *   this file.
    *
-   *  {
-   *    FT_ERROR_START_LIST
-   *  }
+   *   ```
+   *     FT_ERROR_START_LIST
+   *   ```
    *
-   *  This macro is called before anything else to define the start of
-   *  the error list.  It is followed by several FT_ERROR_DEF calls.
+   *   This macro is called before anything else to define the start of the
+   *   error list.  It is followed by several `FT_ERROR_DEF` calls.
    *
-   *  {
-   *    FT_ERROR_DEF( e, v, s )
-   *  }
+   *   ```
+   *     FT_ERROR_DEF( e, v, s )
+   *   ```
    *
-   *  This macro is called to define one single error.  `e' is the error
-   *  code identifier (e.g., `Invalid_Argument'), `v' is the error's
-   *  numerical value, and `s' is the corresponding error string.
+   *   This macro is called to define one single error.  'e' is the error
+   *   code identifier (e.g., `Invalid_Argument`), 'v' is the error's
+   *   numerical value, and 's' is the corresponding error string.
    *
-   *  {
-   *    FT_ERROR_END_LIST
-   *  }
+   *   ```
+   *     FT_ERROR_END_LIST
+   *   ```
    *
-   *  This macro ends the list.
+   *   This macro ends the list.
    *
-   *  Additionally, you have to undefine `FTERRORS_H_' before #including
-   *  this file.
+   *   Additionally, you have to undefine `FTERRORS_H_` before #including
+   *   this file.
    *
-   *  Here is a simple example.
+   *   Here is a simple example.
    *
-   *  {
-   *    #undef FTERRORS_H_
-   *    #define FT_ERRORDEF( e, v, s )  { e, s },
-   *    #define FT_ERROR_START_LIST     {
-   *    #define FT_ERROR_END_LIST       { 0, NULL } };
+   *   ```
+   *     #undef FTERRORS_H_
+   *     #define FT_ERRORDEF( e, v, s )  { e, s },
+   *     #define FT_ERROR_START_LIST     {
+   *     #define FT_ERROR_END_LIST       { 0, NULL } };
    *
-   *    const struct
-   *    {
-   *      int          err_code;
-   *      const char*  err_msg;
-   *    } ft_errors[] =
+   *     const struct
+   *     {
+   *       int          err_code;
+   *       const char*  err_msg;
+   *     } ft_errors[] =
    *
-   *    #include FT_ERRORS_H
-   *  }
+   *     #include <freetype/fterrors.h>
+   *   ```
    *
-   *  Note that `FT_Err_Ok' is _not_ defined with `FT_ERRORDEF' but with
-   *  `FT_NOERRORDEF'; it is always zero.
+   *   An alternative to using an array is a switch statement.
    *
+   *   ```
+   *     #undef FTERRORS_H_
+   *     #define FT_ERROR_START_LIST     switch ( error_code ) {
+   *     #define FT_ERRORDEF( e, v, s )    case v: return s;
+   *     #define FT_ERROR_END_LIST       }
+   *   ```
+   *
+   *   If you use `FT_CONFIG_OPTION_USE_MODULE_ERRORS`, `error_code` should
+   *   be replaced with `FT_ERROR_BASE(error_code)` in the last example.
    */
 
   /* */
 
-  /* In previous FreeType versions we used `__FTERRORS_H__'.  However, */
+  /* In previous FreeType versions we used `__FTERRORS_H__`.  However, */
   /* using two successive underscores in a non-system symbol name      */
   /* violates the C (and C++) standard, so it was changed to the       */
   /* current form.  In spite of this, we have to make                  */
   /*                                                                   */
+  /* ```                                                               */
   /*   #undefine __FTERRORS_H__                                        */
+  /* ```                                                               */
   /*                                                                   */
   /* work for backward compatibility.                                  */
   /*                                                                   */
@@ -114,7 +124,7 @@
 
 
   /* include module base error codes */
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 
   /*******************************************************************/
@@ -130,7 +140,7 @@
 
 
   /* FT_ERR_PREFIX is used as a prefix for error identifiers. */
-  /* By default, we use `FT_Err_'.                            */
+  /* By default, we use `FT_Err_`.                            */
   /*                                                          */
 #ifndef FT_ERR_PREFIX
 #define FT_ERR_PREFIX  FT_Err_
@@ -158,6 +168,8 @@
   /*                                                           */
 #ifndef FT_ERRORDEF
 
+#define FT_INCLUDE_ERR_PROTOS
+
 #define FT_ERRORDEF( e, v, s )  e = v,
 #define FT_ERROR_START_LIST     enum {
 #define FT_ERROR_END_LIST       FT_ERR_CAT( FT_ERR_PREFIX, Max ) };
@@ -185,7 +197,7 @@
 
 
   /* now include the error codes */
-#include FT_ERROR_DEFINITIONS_H
+#include <freetype/fterrdef.h>
 
 
 #ifdef FT_ERROR_END_LIST
@@ -220,6 +232,64 @@
 #undef FT_ERR_PREFIX
 #endif
 
+  /* FT_INCLUDE_ERR_PROTOS: Control whether function prototypes should be */
+  /*                        included with                                 */
+  /*                                                                      */
+  /*                          #include <freetype/fterrors.h>              */
+  /*                                                                      */
+  /*                        This is only true where `FT_ERRORDEF` is      */
+  /*                        undefined.                                    */
+  /*                                                                      */
+  /* FT_ERR_PROTOS_DEFINED: Actual multiple-inclusion protection of       */
+  /*                        `fterrors.h`.                                 */
+#ifdef FT_INCLUDE_ERR_PROTOS
+#undef FT_INCLUDE_ERR_PROTOS
+
+#ifndef FT_ERR_PROTOS_DEFINED
+#define FT_ERR_PROTOS_DEFINED
+
+
+FT_BEGIN_HEADER
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Error_String
+   *
+   * @description:
+   *   Retrieve the description of a valid FreeType error code.
+   *
+   * @input:
+   *   error_code ::
+   *     A valid FreeType error code.
+   *
+   * @return:
+   *   A C~string or `NULL`, if any error occurred.
+   *
+   * @note:
+   *   FreeType has to be compiled with `FT_CONFIG_OPTION_ERROR_STRINGS` or
+   *   `FT_DEBUG_LEVEL_ERROR` to get meaningful descriptions.
+   *   'error_string' will be `NULL` otherwise.
+   *
+   *   Module identification will be ignored:
+   *
+   *   ```c
+   *     strcmp( FT_Error_String(  FT_Err_Unknown_File_Format ),
+   *             FT_Error_String( BDF_Err_Unknown_File_Format ) ) == 0;
+   *   ```
+   */
+  FT_EXPORT( const char* )
+  FT_Error_String( FT_Error  error_code );
+
+  /* */
+
+FT_END_HEADER
+
+
+#endif /* FT_ERR_PROTOS_DEFINED */
+
+#endif /* FT_INCLUDE_ERR_PROTOS */
+
 #endif /* !(FTERRORS_H_ && __FTERRORS_H__) */
 
 
diff --git a/include/freetype/ftfntfmt.h b/include/freetype/ftfntfmt.h
index 3f3d410..c0018fc 100644
--- a/include/freetype/ftfntfmt.h
+++ b/include/freetype/ftfntfmt.h
@@ -4,7 +4,7 @@
  *
  *   Support functions for font formats.
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTFNTFMT_H_
 #define FTFNTFMT_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -44,10 +43,10 @@
    *  Getting the font format.
    *
    * @description:
-   *  The single function in this section can be used to get the font
-   *  format.  Note that this information is not needed normally;
-   *  however, there are special cases (like in PDF devices) where it is
-   *  important to differentiate, in spite of FreeType's uniform API.
+   *  The single function in this section can be used to get the font format.
+   *  Note that this information is not needed normally; however, there are
+   *  special cases (like in PDF devices) where it is important to
+   *  differentiate, in spite of FreeType's uniform API.
    *
    */
 
@@ -58,9 +57,9 @@
    *  FT_Get_Font_Format
    *
    * @description:
-   *  Return a string describing the format of a given face.  Possible
-   *  values are `TrueType', `Type~1', `BDF', `PCF', `Type~42',
-   *  `CID~Type~1', `CFF', `PFR', and `Windows~FNT'.
+   *  Return a string describing the format of a given face.  Possible values
+   *  are 'TrueType', 'Type~1', 'BDF', 'PCF', 'Type~42', 'CID~Type~1', 'CFF',
+   *  'PFR', and 'Windows~FNT'.
    *
    *  The return value is suitable to be used as an X11 FONT_PROPERTY.
    *
@@ -69,11 +68,10 @@
    *    Input face handle.
    *
    * @return:
-   *  Font format string.  NULL in case of error.
+   *  Font format string.  `NULL` in case of error.
    *
    * @note:
-   *  A deprecated name for the same function is
-   *  `FT_Get_X11_Font_Format'.
+   *  A deprecated name for the same function is `FT_Get_X11_Font_Format`.
    */
   FT_EXPORT( const char* )
   FT_Get_Font_Format( FT_Face  face );
diff --git a/include/freetype/ftgasp.h b/include/freetype/ftgasp.h
index 605ff28..d5f19ad 100644
--- a/include/freetype/ftgasp.h
+++ b/include/freetype/ftgasp.h
@@ -2,9 +2,9 @@
  *
  * ftgasp.h
  *
- *   Access of TrueType's `gasp' table (specification).
+ *   Access of TrueType's 'gasp' table (specification).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTGASP_H_
 #define FTGASP_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -32,7 +31,7 @@
 FT_BEGIN_HEADER
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @section:
    *   gasp_table
@@ -41,16 +40,16 @@
    *   Gasp Table
    *
    * @abstract:
-   *   Retrieving TrueType `gasp' table entries.
+   *   Retrieving TrueType 'gasp' table entries.
    *
    * @description:
    *   The function @FT_Get_Gasp can be used to query a TrueType or OpenType
-   *   font for specific entries in its `gasp' table, if any.  This is
-   *   mainly useful when implementing native TrueType hinting with the
-   *   bytecode interpreter to duplicate the Windows text rendering results.
+   *   font for specific entries in its 'gasp' table, if any.  This is mainly
+   *   useful when implementing native TrueType hinting with the bytecode
+   *   interpreter to duplicate the Windows text rendering results.
    */
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_GASP_XXX
@@ -66,7 +65,7 @@
    *
    *   FT_GASP_DO_GRIDFIT ::
    *     Grid-fitting and hinting should be performed at the specified ppem.
-   *     This *really* means TrueType bytecode interpretation.  If this bit
+   *     This **really** means TrueType bytecode interpretation.  If this bit
    *     is not set, no hinting gets applied.
    *
    *   FT_GASP_DO_GRAY ::
@@ -80,13 +79,13 @@
    *     Grid-fitting must be used with ClearType's symmetric smoothing.
    *
    * @note:
-   *   The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be
+   *   The bit-flags `FT_GASP_DO_GRIDFIT` and `FT_GASP_DO_GRAY` are to be
    *   used for standard font rasterization only.  Independently of that,
-   *   `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to
-   *   be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and
-   *   `FT_GASP_DO_GRAY' are consequently ignored).
+   *   `FT_GASP_SYMMETRIC_SMOOTHING` and `FT_GASP_SYMMETRIC_GRIDFIT` are to
+   *   be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT` and
+   *   `FT_GASP_DO_GRAY` are consequently ignored).
    *
-   *   `ClearType' is Microsoft's implementation of LCD rendering, partly
+   *   'ClearType' is Microsoft's implementation of LCD rendering, partly
    *   protected by patents.
    *
    * @since:
@@ -99,15 +98,15 @@
 #define FT_GASP_SYMMETRIC_SMOOTHING  0x08
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Get_Gasp
    *
    * @description:
    *   For a TrueType or OpenType font file, return the rasterizer behaviour
-   *   flags from the font's `gasp' table corresponding to a given
-   *   character pixel size.
+   *   flags from the font's 'gasp' table corresponding to a given character
+   *   pixel size.
    *
    * @input:
    *   face ::
@@ -118,12 +117,12 @@
    *
    * @return:
    *   Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no
-   *   `gasp' table in the face.
+   *   'gasp' table in the face.
    *
    * @note:
    *   If you want to use the MM functionality of OpenType variation fonts
    *   (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this
-   *   function *after* setting an instance since the return values can
+   *   function **after** setting an instance since the return values can
    *   change.
    *
    * @since:
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index be17a77..4658895 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -4,7 +4,7 @@
  *
  *   FreeType convenience functions to handle glyphs (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,13 +18,13 @@
 
   /**************************************************************************
    *
-   * This file contains the definition of several convenience functions
-   * that can be used by client applications to easily retrieve glyph
-   * bitmaps and outlines from a given face.
+   * This file contains the definition of several convenience functions that
+   * can be used by client applications to easily retrieve glyph bitmaps and
+   * outlines from a given face.
    *
-   * These functions should be optional if you are writing a font server
-   * or text layout engine on top of FreeType.  However, they are pretty
-   * handy for many other simple uses of the library.
+   * These functions should be optional if you are writing a font server or
+   * text layout engine on top of FreeType.  However, they are pretty handy
+   * for many other simple uses of the library.
    *
    */
 
@@ -33,8 +33,7 @@
 #define FTGLYPH_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -58,9 +57,10 @@
    *   Generic interface to manage individual glyph data.
    *
    * @description:
-   *   This section contains definitions used to manage glyph data
-   *   through generic FT_Glyph objects.  Each of them can contain a
-   *   bitmap, a vector outline, or even images in other formats.
+   *   This section contains definitions used to manage glyph data through
+   *   generic @FT_Glyph objects.  Each of them can contain a bitmap,
+   *   a vector outline, or even images in other formats.  These objects are
+   *   detached from @FT_Face, contrary to @FT_GlyphSlot.
    *
    */
 
@@ -76,8 +76,8 @@
    *
    * @description:
    *   Handle to an object used to model generic glyph images.  It is a
-   *   pointer to the @FT_GlyphRec structure and can contain a glyph
-   *   bitmap or pointer.
+   *   pointer to the @FT_GlyphRec structure and can contain a glyph bitmap
+   *   or pointer.
    *
    * @note:
    *   Glyph objects are not owned by the library.  You must thus release
@@ -93,8 +93,8 @@
    *   FT_GlyphRec
    *
    * @description:
-   *   The root glyph structure contains a given glyph image plus its
-   *   advance width in 16.16 fixed-point format.
+   *   The root glyph structure contains a given glyph image plus its advance
+   *   width in 16.16 fixed-point format.
    *
    * @fields:
    *   library ::
@@ -125,8 +125,8 @@
    *   FT_BitmapGlyph
    *
    * @description:
-   *   A handle to an object used to model a bitmap glyph image.  This is
-   *   a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec.
+   *   A handle to an object used to model a bitmap glyph image.  This is a
+   *   'sub-class' of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec.
    */
   typedef struct FT_BitmapGlyphRec_*  FT_BitmapGlyph;
 
@@ -138,32 +138,31 @@
    *
    * @description:
    *   A structure used for bitmap glyph images.  This really is a
-   *   `sub-class' of @FT_GlyphRec.
+   *   'sub-class' of @FT_GlyphRec.
    *
    * @fields:
    *   root ::
-   *     The root @FT_Glyph fields.
+   *     The root fields of @FT_Glyph.
    *
    *   left ::
-   *     The left-side bearing, i.e., the horizontal distance
-   *     from the current pen position to the left border of the
-   *     glyph bitmap.
+   *     The left-side bearing, i.e., the horizontal distance from the
+   *     current pen position to the left border of the glyph bitmap.
    *
    *   top ::
-   *     The top-side bearing, i.e., the vertical distance from
-   *     the current pen position to the top border of the glyph
-   *     bitmap.  This distance is positive for upwards~y!
+   *     The top-side bearing, i.e., the vertical distance from the current
+   *     pen position to the top border of the glyph bitmap.  This distance
+   *     is positive for upwards~y!
    *
    *   bitmap ::
    *     A descriptor for the bitmap.
    *
    * @note:
    *   You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have
-   *   `glyph->format == FT_GLYPH_FORMAT_BITMAP'.  This lets you access
-   *   the bitmap's contents easily.
+   *   `glyph->format == FT_GLYPH_FORMAT_BITMAP`.  This lets you access the
+   *   bitmap's contents easily.
    *
-   *   The corresponding pixel buffer is always owned by @FT_BitmapGlyph
-   *   and is thus created and destroyed with it.
+   *   The corresponding pixel buffer is always owned by @FT_BitmapGlyph and
+   *   is thus created and destroyed with it.
    */
   typedef struct  FT_BitmapGlyphRec_
   {
@@ -181,8 +180,8 @@
    *   FT_OutlineGlyph
    *
    * @description:
-   *   A handle to an object used to model an outline glyph image.  This
-   *   is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec.
+   *   A handle to an object used to model an outline glyph image.  This is a
+   *   'sub-class' of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec.
    */
   typedef struct FT_OutlineGlyphRec_*  FT_OutlineGlyph;
 
@@ -193,8 +192,8 @@
    *   FT_OutlineGlyphRec
    *
    * @description:
-   *   A structure used for outline (vectorial) glyph images.  This
-   *   really is a `sub-class' of @FT_GlyphRec.
+   *   A structure used for outline (vectorial) glyph images.  This really is
+   *   a 'sub-class' of @FT_GlyphRec.
    *
    * @fields:
    *   root ::
@@ -205,15 +204,15 @@
    *
    * @note:
    *   You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have
-   *   `glyph->format == FT_GLYPH_FORMAT_OUTLINE'.  This lets you access
-   *   the outline's content easily.
+   *   `glyph->format == FT_GLYPH_FORMAT_OUTLINE`.  This lets you access the
+   *   outline's content easily.
    *
    *   As the outline is extracted from a glyph slot, its coordinates are
-   *   expressed normally in 26.6 pixels, unless the flag
-   *   @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char().
+   *   expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE
+   *   was used in @FT_Load_Glyph or @FT_Load_Char.
    *
-   *   The outline's tables are always owned by the object and are
-   *   destroyed with it.
+   *   The outline's tables are always owned by the object and are destroyed
+   *   with it.
    */
   typedef struct  FT_OutlineGlyphRec_
   {
@@ -225,6 +224,92 @@
 
   /**************************************************************************
    *
+   * @type:
+   *   FT_SvgGlyph
+   *
+   * @description:
+   *   A handle to an object used to model an SVG glyph.  This is a
+   *   'sub-class' of @FT_Glyph, and a pointer to @FT_SvgGlyphRec.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef struct FT_SvgGlyphRec_*  FT_SvgGlyph;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_SvgGlyphRec
+   *
+   * @description:
+   *   A structure used for OT-SVG glyphs.  This is a 'sub-class' of
+   *   @FT_GlyphRec.
+   *
+   * @fields:
+   *   root ::
+   *     The root @FT_GlyphRec fields.
+   *
+   *   svg_document ::
+   *     A pointer to the SVG document.
+   *
+   *   svg_document_length ::
+   *     The length of `svg_document`.
+   *
+   *   glyph_index ::
+   *     The index of the glyph to be rendered.
+   *
+   *   metrics ::
+   *     A metrics object storing the size information.
+   *
+   *   units_per_EM ::
+   *     The size of the EM square.
+   *
+   *   start_glyph_id ::
+   *     The first glyph ID in the glyph range covered by this document.
+   *
+   *   end_glyph_id ::
+   *     The last glyph ID in the glyph range covered by this document.
+   *
+   *   transform ::
+   *     A 2x2 transformation matrix to apply to the glyph while rendering
+   *     it.
+   *
+   *   delta ::
+   *     Translation to apply to the glyph while rendering.
+   *
+   * @note:
+   *   The Glyph Management API requires @FT_Glyph or its 'sub-class' to have
+   *   all the information needed to completely define the glyph's rendering.
+   *   Outline-based glyphs can directly apply transformations to the outline
+   *   but this is not possible for an SVG document that hasn't been parsed.
+   *   Therefore, the transformation is stored along with the document.  In
+   *   the absence of a 'ViewBox' or 'Width'/'Height' attribute, the size of
+   *   the ViewPort should be assumed to be 'units_per_EM'.
+   */
+  typedef struct  FT_SvgGlyphRec_
+  {
+    FT_GlyphRec  root;
+
+    FT_Byte*  svg_document;
+    FT_ULong  svg_document_length;
+
+    FT_UInt  glyph_index;
+
+    FT_Size_Metrics  metrics;
+    FT_UShort        units_per_EM;
+
+    FT_UShort  start_glyph_id;
+    FT_UShort  end_glyph_id;
+
+    FT_Matrix  transform;
+    FT_Vector  delta;
+
+  } FT_SvgGlyphRec;
+
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_New_Glyph
    *
@@ -261,8 +346,8 @@
    *   FT_Get_Glyph
    *
    * @description:
-   *   A function used to extract a glyph image from a slot.  Note that
-   *   the created @FT_Glyph object must be released with @FT_Done_Glyph.
+   *   A function used to extract a glyph image from a slot.  Note that the
+   *   created @FT_Glyph object must be released with @FT_Done_Glyph.
    *
    * @input:
    *   slot ::
@@ -270,16 +355,15 @@
    *
    * @output:
    *   aglyph ::
-   *     A handle to the glyph object.
+   *     A handle to the glyph object.  `NULL` in case of error.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Because `*aglyph->advance.x' and `*aglyph->advance.y' are 16.16
-   *   fixed-point numbers, `slot->advance.x' and `slot->advance.y'
-   *   (which are in 26.6 fixed-point format) must be in the range
-   *   ]-32768;32768[.
+   *   Because `*aglyph->advance.x` and `*aglyph->advance.y` are 16.16
+   *   fixed-point numbers, `slot->advance.x` and `slot->advance.y` (which
+   *   are in 26.6 fixed-point format) must be in the range ]-32768;32768[.
    */
   FT_EXPORT( FT_Error )
   FT_Get_Glyph( FT_GlyphSlot  slot,
@@ -301,8 +385,7 @@
    *
    * @output:
    *   target ::
-   *     A handle to the target glyph object.  0~in case of
-   *     error.
+   *     A handle to the target glyph object.  `NULL` in case of error.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -329,20 +412,20 @@
    *     A pointer to a 2x2 matrix to apply.
    *
    *   delta ::
-   *     A pointer to a 2d vector to apply.  Coordinates are
-   *     expressed in 1/64th of a pixel.
+   *     A pointer to a 2d vector to apply.  Coordinates are expressed in
+   *     1/64 of a pixel.
    *
    * @return:
    *   FreeType error code (if not 0, the glyph format is not scalable).
    *
    * @note:
-   *   The 2x2 transformation matrix is also applied to the glyph's
-   *   advance vector.
+   *   The 2x2 transformation matrix is also applied to the glyph's advance
+   *   vector.
    */
   FT_EXPORT( FT_Error )
-  FT_Glyph_Transform( FT_Glyph    glyph,
-                      FT_Matrix*  matrix,
-                      FT_Vector*  delta );
+  FT_Glyph_Transform( FT_Glyph          glyph,
+                      const FT_Matrix*  matrix,
+                      const FT_Vector*  delta );
 
 
   /**************************************************************************
@@ -381,7 +464,7 @@
 
 
   /* these constants are deprecated; use the corresponding */
-  /* `FT_Glyph_BBox_Mode' values instead                   */
+  /* `FT_Glyph_BBox_Mode` values instead                   */
 #define ft_glyph_bbox_unscaled   FT_GLYPH_BBOX_UNSCALED
 #define ft_glyph_bbox_subpixels  FT_GLYPH_BBOX_SUBPIXELS
 #define ft_glyph_bbox_gridfit    FT_GLYPH_BBOX_GRIDFIT
@@ -395,71 +478,71 @@
    *   FT_Glyph_Get_CBox
    *
    * @description:
-   *   Return a glyph's `control box'.  The control box encloses all the
+   *   Return a glyph's 'control box'.  The control box encloses all the
    *   outline's points, including Bezier control points.  Though it
    *   coincides with the exact bounding box for most glyphs, it can be
-   *   slightly larger in some situations (like when rotating an outline
-   *   that contains Bezier outside arcs).
+   *   slightly larger in some situations (like when rotating an outline that
+   *   contains Bezier outside arcs).
    *
-   *   Computing the control box is very fast, while getting the bounding
-   *   box can take much more time as it needs to walk over all segments
-   *   and arcs in the outline.  To get the latter, you can use the
-   *   `ftbbox' component, which is dedicated to this single task.
+   *   Computing the control box is very fast, while getting the bounding box
+   *   can take much more time as it needs to walk over all segments and arcs
+   *   in the outline.  To get the latter, you can use the 'ftbbox'
+   *   component, which is dedicated to this single task.
    *
    * @input:
    *   glyph ::
    *     A handle to the source glyph object.
    *
    *   mode ::
-   *     The mode that indicates how to interpret the returned
-   *     bounding box values.
+   *     The mode that indicates how to interpret the returned bounding box
+   *     values.
    *
    * @output:
    *   acbox ::
-   *     The glyph coordinate bounding box.  Coordinates are
-   *     expressed in 1/64th of pixels if it is grid-fitted.
+   *     The glyph coordinate bounding box.  Coordinates are expressed in
+   *     1/64 of pixels if it is grid-fitted.
    *
    * @note:
    *   Coordinates are relative to the glyph origin, using the y~upwards
    *   convention.
    *
-   *   If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode'
-   *   must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font
-   *   units in 26.6 pixel format.  The value @FT_GLYPH_BBOX_SUBPIXELS
-   *   is another name for this constant.
+   *   If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode` must
+   *   be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font units in 26.6
+   *   pixel format.  The value @FT_GLYPH_BBOX_SUBPIXELS is another name for
+   *   this constant.
    *
    *   If the font is tricky and the glyph has been loaded with
    *   @FT_LOAD_NO_SCALE, the resulting CBox is meaningless.  To get
-   *   reasonable values for the CBox it is necessary to load the glyph
-   *   at a large ppem value (so that the hinting instructions can
-   *   properly shift and scale the subglyphs), then extracting the CBox,
-   *   which can be eventually converted back to font units.
+   *   reasonable values for the CBox it is necessary to load the glyph at a
+   *   large ppem value (so that the hinting instructions can properly shift
+   *   and scale the subglyphs), then extracting the CBox, which can be
+   *   eventually converted back to font units.
    *
-   *   Note that the maximum coordinates are exclusive, which means that
-   *   one can compute the width and height of the glyph image (be it in
-   *   integer or 26.6 pixels) as:
+   *   Note that the maximum coordinates are exclusive, which means that one
+   *   can compute the width and height of the glyph image (be it in integer
+   *   or 26.6 pixels) as:
    *
-   *   {
+   *   ```
    *     width  = bbox.xMax - bbox.xMin;
    *     height = bbox.yMax - bbox.yMin;
-   *   }
+   *   ```
    *
-   *   Note also that for 26.6 coordinates, if `bbox_mode' is set to
+   *   Note also that for 26.6 coordinates, if `bbox_mode` is set to
    *   @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted,
    *   which corresponds to:
    *
-   *   {
+   *   ```
    *     bbox.xMin = FLOOR(bbox.xMin);
    *     bbox.yMin = FLOOR(bbox.yMin);
    *     bbox.xMax = CEILING(bbox.xMax);
    *     bbox.yMax = CEILING(bbox.yMax);
-   *   }
+   *   ```
    *
-   *   To get the bbox in pixel coordinates, set `bbox_mode' to
+   *   To get the bbox in pixel coordinates, set `bbox_mode` to
    *   @FT_GLYPH_BBOX_TRUNCATE.
    *
-   *   To get the bbox in grid-fitted pixel coordinates, set `bbox_mode'
-   *   to @FT_GLYPH_BBOX_PIXELS.
+   *   To get the bbox in grid-fitted pixel coordinates, set `bbox_mode` to
+   *   @FT_GLYPH_BBOX_PIXELS.
    */
   FT_EXPORT( void )
   FT_Glyph_Get_CBox( FT_Glyph  glyph,
@@ -481,19 +564,16 @@
    *
    * @input:
    *   render_mode ::
-   *     An enumeration that describes how the data is
-   *     rendered.
+   *     An enumeration that describes how the data is rendered.
    *
    *   origin ::
-   *     A pointer to a vector used to translate the glyph
-   *     image before rendering.  Can be~0 (if no
-   *     translation).  The origin is expressed in
-   *     26.6 pixels.
+   *     A pointer to a vector used to translate the glyph image before
+   *     rendering.  Can be~0 (if no translation).  The origin is expressed
+   *     in 26.6 pixels.
    *
    *   destroy ::
-   *     A boolean that indicates that the original glyph
-   *     image should be destroyed by this function.  It is
-   *     never destroyed in case of error.
+   *     A boolean that indicates that the original glyph image should be
+   *     destroyed by this function.  It is never destroyed in case of error.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -501,14 +581,14 @@
    * @note:
    *   This function does nothing if the glyph format isn't scalable.
    *
-   *   The glyph image is translated with the `origin' vector before
+   *   The glyph image is translated with the `origin` vector before
    *   rendering.
    *
-   *   The first parameter is a pointer to an @FT_Glyph handle, that will
-   *   be _replaced_ by this function (with newly allocated data).
-   *   Typically, you would use (omitting error handling):
+   *   The first parameter is a pointer to an @FT_Glyph handle that will be
+   *   _replaced_ by this function (with newly allocated data).  Typically,
+   *   you would do something like the following (omitting error handling).
    *
-   *   {
+   *   ```
    *     FT_Glyph        glyph;
    *     FT_BitmapGlyph  glyph_bitmap;
    *
@@ -523,7 +603,7 @@
    *     if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
    *     {
    *       error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL,
-   *                                     0, 1 );
+   *                                   0, 1 );
    *       if ( error ) // `glyph' unchanged
    *         ...
    *     }
@@ -536,11 +616,11 @@
    *
    *     // discard glyph image (bitmap or not)
    *     FT_Done_Glyph( glyph );
-   *   }
+   *   ```
    *
-   *   Here another example, again without error handling:
+   *   Here is another example, again without error handling.
    *
-   *   {
+   *   ```
    *     FT_Glyph  glyphs[MAX_GLYPHS]
    *
    *
@@ -572,13 +652,13 @@
    *
    *     for ( idx = 0; i < MAX_GLYPHS; i++ )
    *       FT_Done_Glyph( glyphs[idx] );
-   *   }
+   *   ```
    */
   FT_EXPORT( FT_Error )
-  FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,
-                      FT_Render_Mode  render_mode,
-                      FT_Vector*      origin,
-                      FT_Bool         destroy );
+  FT_Glyph_To_Bitmap( FT_Glyph*         the_glyph,
+                      FT_Render_Mode    render_mode,
+                      const FT_Vector*  origin,
+                      FT_Bool           destroy );
 
 
   /**************************************************************************
@@ -591,7 +671,7 @@
    *
    * @input:
    *   glyph ::
-   *     A handle to the target glyph object.
+   *     A handle to the target glyph object.  Can be `NULL`.
    */
   FT_EXPORT( void )
   FT_Done_Glyph( FT_Glyph  glyph );
@@ -615,18 +695,18 @@
    *   FT_Matrix_Multiply
    *
    * @description:
-   *   Perform the matrix operation `b = a*b'.
+   *   Perform the matrix operation `b = a*b`.
    *
    * @input:
    *   a ::
-   *     A pointer to matrix `a'.
+   *     A pointer to matrix `a`.
    *
    * @inout:
    *   b ::
-   *     A pointer to matrix `b'.
+   *     A pointer to matrix `b`.
    *
    * @note:
-   *   The result is undefined if either `a' or `b' is zero.
+   *   The result is undefined if either `a` or `b` is zero.
    *
    *   Since the function uses wrap-around arithmetic, results become
    *   meaningless if the arguments are very large.
@@ -646,8 +726,7 @@
    *
    * @inout:
    *   matrix ::
-   *     A pointer to the target matrix.  Remains untouched in
-   *     case of error.
+   *     A pointer to the target matrix.  Remains untouched in case of error.
    *
    * @return:
    *   FreeType error code.  0~means success.
diff --git a/include/freetype/ftgxval.h b/include/freetype/ftgxval.h
index 532b484..e8de9a6 100644
--- a/include/freetype/ftgxval.h
+++ b/include/freetype/ftgxval.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for validating TrueTypeGX/AAT tables (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Masatake YAMATO, Redhat K.K,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -28,8 +28,7 @@
 #ifndef FTGXVAL_H_
 #define FTGXVAL_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -53,9 +52,9 @@
    *   An API to validate TrueTypeGX/AAT tables.
    *
    * @description:
-   *   This section contains the declaration of functions to validate
-   *   some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd,
-   *   trak, prop, lcar).
+   *   This section contains the declaration of functions to validate some
+   *   TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, trak,
+   *   prop, lcar).
    *
    * @order:
    *   FT_TrueTypeGX_Validate
@@ -73,8 +72,8 @@
   /**************************************************************************
    *
    *
-   * Warning: Use FT_VALIDATE_XXX to validate a table.
-   *         Following definitions are for gxvalid developers.
+   * Warning: Use `FT_VALIDATE_XXX` to validate a table.
+   *          Following definitions are for gxvalid developers.
    *
    *
    */
@@ -92,14 +91,14 @@
 #define FT_VALIDATE_GX_LAST_INDEX  FT_VALIDATE_lcar_INDEX
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_VALIDATE_GX_LENGTH
    *
    * @description:
    *   The number of tables checked in this module.  Use it as a parameter
-   *   for the `table-length' argument of function @FT_TrueTypeGX_Validate.
+   *   for the `table-length` argument of function @FT_TrueTypeGX_Validate.
    */
 #define FT_VALIDATE_GX_LENGTH  ( FT_VALIDATE_GX_LAST_INDEX + 1 )
 
@@ -112,7 +111,7 @@
           ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX )
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *    FT_VALIDATE_GXXXX
@@ -123,34 +122,34 @@
    *
    * @values:
    *    FT_VALIDATE_feat ::
-   *      Validate `feat' table.
+   *      Validate 'feat' table.
    *
    *    FT_VALIDATE_mort ::
-   *      Validate `mort' table.
+   *      Validate 'mort' table.
    *
    *    FT_VALIDATE_morx ::
-   *      Validate `morx' table.
+   *      Validate 'morx' table.
    *
    *    FT_VALIDATE_bsln ::
-   *      Validate `bsln' table.
+   *      Validate 'bsln' table.
    *
    *    FT_VALIDATE_just ::
-   *      Validate `just' table.
+   *      Validate 'just' table.
    *
    *    FT_VALIDATE_kern ::
-   *      Validate `kern' table.
+   *      Validate 'kern' table.
    *
    *    FT_VALIDATE_opbd ::
-   *      Validate `opbd' table.
+   *      Validate 'opbd' table.
    *
    *    FT_VALIDATE_trak ::
-   *      Validate `trak' table.
+   *      Validate 'trak' table.
    *
    *    FT_VALIDATE_prop ::
-   *      Validate `prop' table.
+   *      Validate 'prop' table.
    *
    *    FT_VALIDATE_lcar ::
-   *      Validate `lcar' table.
+   *      Validate 'lcar' table.
    *
    *    FT_VALIDATE_GX ::
    *      Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern,
@@ -181,7 +180,7 @@
                           FT_VALIDATE_lcar )
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_TrueTypeGX_Validate
@@ -189,8 +188,8 @@
    * @description:
    *    Validate various TrueTypeGX tables to assure that all offsets and
    *    indices are valid.  The idea is that a higher-level library that
-   *    actually does the text layout can access those tables without
-   *    error checking (which can be quite time consuming).
+   *    actually does the text layout can access those tables without error
+   *    checking (which can be quite time consuming).
    *
    * @input:
    *    face ::
@@ -201,13 +200,13 @@
    *      @FT_VALIDATE_GXXXX for possible values.
    *
    *    table_length ::
-   *      The size of the `tables' array.  Normally, @FT_VALIDATE_GX_LENGTH
+   *      The size of the `tables` array.  Normally, @FT_VALIDATE_GX_LENGTH
    *      should be passed.
    *
    * @output:
    *    tables ::
-   *      The array where all validated sfnt tables are stored.
-   *      The array itself must be allocated by a client.
+   *      The array where all validated sfnt tables are stored.  The array
+   *      itself must be allocated by a client.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -217,7 +216,7 @@
    *   otherwise.
    *
    *   After use, the application should deallocate the buffers pointed to by
-   *   each `tables' element, by calling @FT_TrueTypeGX_Free.  A NULL value
+   *   each `tables` element, by calling @FT_TrueTypeGX_Free.  A `NULL` value
    *   indicates that the table either doesn't exist in the font, the
    *   application hasn't asked for validation, or the validator doesn't have
    *   the ability to validate the sfnt table.
@@ -229,7 +228,7 @@
                           FT_UInt   table_length );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_TrueTypeGX_Free
@@ -242,8 +241,7 @@
    *      A handle to the input face.
    *
    *    table ::
-   *      The pointer to the buffer allocated by
-   *      @FT_TrueTypeGX_Validate.
+   *      The pointer to the buffer allocated by @FT_TrueTypeGX_Validate.
    *
    * @note:
    *   This function must be used to free the buffer allocated by
@@ -254,26 +252,25 @@
                       FT_Bytes  table );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *    FT_VALIDATE_CKERNXXX
    *
    * @description:
-   *    A list of bit-field constants used with @FT_ClassicKern_Validate
-   *    to indicate the classic kern dialect or dialects.  If the selected
-   *    type doesn't fit, @FT_ClassicKern_Validate regards the table as
-   *    invalid.
+   *    A list of bit-field constants used with @FT_ClassicKern_Validate to
+   *    indicate the classic kern dialect or dialects.  If the selected type
+   *    doesn't fit, @FT_ClassicKern_Validate regards the table as invalid.
    *
    * @values:
    *    FT_VALIDATE_MS ::
-   *      Handle the `kern' table as a classic Microsoft kern table.
+   *      Handle the 'kern' table as a classic Microsoft kern table.
    *
    *    FT_VALIDATE_APPLE ::
-   *      Handle the `kern' table as a classic Apple kern table.
+   *      Handle the 'kern' table as a classic Apple kern table.
    *
    *    FT_VALIDATE_CKERN ::
-   *      Handle the `kern' as either classic Apple or Microsoft kern table.
+   *      Handle the 'kern' as either classic Apple or Microsoft kern table.
    */
 #define FT_VALIDATE_MS     ( FT_VALIDATE_GX_START << 0 )
 #define FT_VALIDATE_APPLE  ( FT_VALIDATE_GX_START << 1 )
@@ -281,18 +278,18 @@
 #define FT_VALIDATE_CKERN  ( FT_VALIDATE_MS | FT_VALIDATE_APPLE )
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_ClassicKern_Validate
    *
    * @description:
-   *    Validate classic (16-bit format) kern table to assure that the offsets
-   *    and indices are valid.  The idea is that a higher-level library that
-   *    actually does the text layout can access those tables without error
-   *    checking (which can be quite time consuming).
+   *    Validate classic (16-bit format) kern table to assure that the
+   *    offsets and indices are valid.  The idea is that a higher-level
+   *    library that actually does the text layout can access those tables
+   *    without error checking (which can be quite time consuming).
    *
-   *    The `kern' table validator in @FT_TrueTypeGX_Validate deals with both
+   *    The 'kern' table validator in @FT_TrueTypeGX_Validate deals with both
    *    the new 32-bit format and the classic 16-bit format, while
    *    FT_ClassicKern_Validate only supports the classic 16-bit format.
    *
@@ -313,7 +310,7 @@
    *
    * @note:
    *   After use, the application should deallocate the buffers pointed to by
-   *   `ckern_table', by calling @FT_ClassicKern_Free.  A NULL value
+   *   `ckern_table`, by calling @FT_ClassicKern_Free.  A `NULL` value
    *   indicates that the table doesn't exist in the font.
    */
   FT_EXPORT( FT_Error )
@@ -322,7 +319,7 @@
                            FT_Bytes  *ckern_table );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_ClassicKern_Free
diff --git a/include/freetype/ftgzip.h b/include/freetype/ftgzip.h
index 378a365..443ec29 100644
--- a/include/freetype/ftgzip.h
+++ b/include/freetype/ftgzip.h
@@ -4,7 +4,7 @@
  *
  *   Gzip-compressed stream support.
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTGZIP_H_
 #define FTGZIP_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -43,20 +42,30 @@
    *   Using gzip-compressed font files.
    *
    * @description:
+   *   In certain builds of the library, gzip compression recognition is
+   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
+   *   This means that if no font driver is capable of handling the raw
+   *   compressed file, the library will try to open a gzipped stream from it
+   *   and re-open the face with it.
+   *
+   *   The stream implementation is very basic and resets the decompression
+   *   process each time seeking backwards is needed within the stream,
+   *   which significantly undermines the performance.
+   *
    *   This section contains the declaration of Gzip-specific functions.
    *
    */
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stream_OpenGzip
    *
    * @description:
-   *   Open a new stream to parse gzip-compressed font files.  This is
-   *   mainly used to support the compressed `*.pcf.gz' fonts that come
-   *   with XFree86.
+   *   Open a new stream to parse gzip-compressed font files.  This is mainly
+   *   used to support the compressed `*.pcf.gz` fonts that come with
+   *   XFree86.
    *
    * @input:
    *   stream ::
@@ -71,20 +80,11 @@
    * @note:
    *   The source stream must be opened _before_ calling this function.
    *
-   *   Calling the internal function `FT_Stream_Close' on the new stream will
-   *   *not* call `FT_Stream_Close' on the source stream.  None of the stream
-   *   objects will be released to the heap.
+   *   Calling the internal function `FT_Stream_Close` on the new stream will
+   *   **not** call `FT_Stream_Close` on the source stream.  None of the
+   *   stream objects will be released to the heap.
    *
-   *   The stream implementation is very basic and resets the decompression
-   *   process each time seeking backwards is needed within the stream.
-   *
-   *   In certain builds of the library, gzip compression recognition is
-   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
-   *   This means that if no font driver is capable of handling the raw
-   *   compressed file, the library will try to open a gzipped stream from
-   *   it and re-open the face with it.
-   *
-   *   This function may return `FT_Err_Unimplemented_Feature' if your build
+   *   This function may return `FT_Err_Unimplemented_Feature` if your build
    *   of FreeType was not compiled with zlib support.
    */
   FT_EXPORT( FT_Error )
@@ -92,14 +92,14 @@
                       FT_Stream  source );
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Gzip_Uncompress
    *
    * @description:
    *   Decompress a zipped input buffer into an output buffer.  This function
-   *   is modeled after zlib's `uncompress' function.
+   *   is modeled after zlib's `uncompress` function.
    *
    * @input:
    *   memory ::
@@ -120,14 +120,14 @@
    *     Before calling the function, this is the total size of the output
    *     buffer, which must be large enough to hold the entire uncompressed
    *     data (so the size of the uncompressed data must be known in
-   *     advance).  After calling the function, `output_len' is the size of
-   *     the used data in `output'.
+   *     advance).  After calling the function, `output_len` is the size of
+   *     the used data in `output`.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This function may return `FT_Err_Unimplemented_Feature' if your build
+   *   This function may return `FT_Err_Unimplemented_Feature` if your build
    *   of FreeType was not compiled with zlib support.
    *
    * @since:
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index a3fa0b6..2e8e673 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -5,7 +5,7 @@
  *   FreeType glyph image formats and default raster interface
  *   (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,7 +18,7 @@
 
   /**************************************************************************
    *
-   * Note: A `raster' is simply a scan-line converter, used to render
+   * Note: A 'raster' is simply a scan-line converter, used to render
    *       FT_Outlines into FT_Bitmaps.
    *
    */
@@ -28,12 +28,6 @@
 #define FTIMAGE_H_
 
 
-  /* STANDALONE_ is from ftgrays.c */
-#ifndef STANDALONE_
-#include <ft2build.h>
-#endif
-
-
 FT_BEGIN_HEADER
 
 
@@ -51,9 +45,9 @@
    *   FT_Pos
    *
    * @description:
-   *   The type FT_Pos is used to store vectorial coordinates.  Depending
-   *   on the context, these can represent distances in integer font
-   *   units, or 16.16, or 26.6 fixed-point pixel coordinates.
+   *   The type FT_Pos is used to store vectorial coordinates.  Depending on
+   *   the context, these can represent distances in integer font units, or
+   *   16.16, or 26.6 fixed-point pixel coordinates.
    */
   typedef signed long  FT_Pos;
 
@@ -64,8 +58,8 @@
    *   FT_Vector
    *
    * @description:
-   *   A simple structure used to store a 2D vector; coordinates are of
-   *   the FT_Pos type.
+   *   A simple structure used to store a 2D vector; coordinates are of the
+   *   FT_Pos type.
    *
    * @fields:
    *   x ::
@@ -88,8 +82,7 @@
    *
    * @description:
    *   A structure used to hold an outline's bounding box, i.e., the
-   *   coordinates of its extrema in the horizontal and vertical
-   *   directions.
+   *   coordinates of its extrema in the horizontal and vertical directions.
    *
    * @fields:
    *   xMin ::
@@ -105,18 +98,17 @@
    *     The vertical maximum (top-most).
    *
    * @note:
-   *   The bounding box is specified with the coordinates of the lower
-   *   left and the upper right corner.  In PostScript, those values are
-   *   often called (llx,lly) and (urx,ury), respectively.
+   *   The bounding box is specified with the coordinates of the lower left
+   *   and the upper right corner.  In PostScript, those values are often
+   *   called (llx,lly) and (urx,ury), respectively.
    *
-   *   If `yMin' is negative, this value gives the glyph's descender.
-   *   Otherwise, the glyph doesn't descend below the baseline.
-   *   Similarly, if `ymax' is positive, this value gives the glyph's
-   *   ascender.
+   *   If `yMin` is negative, this value gives the glyph's descender.
+   *   Otherwise, the glyph doesn't descend below the baseline.  Similarly,
+   *   if `ymax` is positive, this value gives the glyph's ascender.
    *
-   *   `xMin' gives the horizontal distance from the glyph's origin to
-   *   the left edge of the glyph's bounding box.  If `xMin' is negative,
-   *   the glyph extends to the left of the origin.
+   *   `xMin` gives the horizontal distance from the glyph's origin to the
+   *   left edge of the glyph's bounding box.  If `xMin` is negative, the
+   *   glyph extends to the left of the origin.
    */
   typedef struct  FT_BBox_
   {
@@ -132,56 +124,53 @@
    *   FT_Pixel_Mode
    *
    * @description:
-   *   An enumeration type used to describe the format of pixels in a
-   *   given bitmap.  Note that additional formats may be added in the
-   *   future.
+   *   An enumeration type used to describe the format of pixels in a given
+   *   bitmap.  Note that additional formats may be added in the future.
    *
    * @values:
    *   FT_PIXEL_MODE_NONE ::
    *     Value~0 is reserved.
    *
    *   FT_PIXEL_MODE_MONO ::
-   *     A monochrome bitmap, using 1~bit per pixel.  Note that pixels
-   *     are stored in most-significant order (MSB), which means that
-   *     the left-most pixel in a byte has value 128.
+   *     A monochrome bitmap, using 1~bit per pixel.  Note that pixels are
+   *     stored in most-significant order (MSB), which means that the
+   *     left-most pixel in a byte has value 128.
    *
    *   FT_PIXEL_MODE_GRAY ::
    *     An 8-bit bitmap, generally used to represent anti-aliased glyph
-   *     images.  Each pixel is stored in one byte.  Note that the number
-   *     of `gray' levels is stored in the `num_grays' field of the
-   *     @FT_Bitmap structure (it generally is 256).
+   *     images.  Each pixel is stored in one byte.  Note that the number of
+   *     'gray' levels is stored in the `num_grays` field of the @FT_Bitmap
+   *     structure (it generally is 256).
    *
    *   FT_PIXEL_MODE_GRAY2 ::
-   *     A 2-bit per pixel bitmap, used to represent embedded
-   *     anti-aliased bitmaps in font files according to the OpenType
-   *     specification.  We haven't found a single font using this
-   *     format, however.
+   *     A 2-bit per pixel bitmap, used to represent embedded anti-aliased
+   *     bitmaps in font files according to the OpenType specification.  We
+   *     haven't found a single font using this format, however.
    *
    *   FT_PIXEL_MODE_GRAY4 ::
-   *     A 4-bit per pixel bitmap, representing embedded anti-aliased
-   *     bitmaps in font files according to the OpenType specification.
-   *     We haven't found a single font using this format, however.
+   *     A 4-bit per pixel bitmap, representing embedded anti-aliased bitmaps
+   *     in font files according to the OpenType specification.  We haven't
+   *     found a single font using this format, however.
    *
    *   FT_PIXEL_MODE_LCD ::
-   *     An 8-bit bitmap, representing RGB or BGR decimated glyph images
-   *     used for display on LCD displays; the bitmap is three times
-   *     wider than the original glyph image.  See also
-   *     @FT_RENDER_MODE_LCD.
+   *     An 8-bit bitmap, representing RGB or BGR decimated glyph images used
+   *     for display on LCD displays; the bitmap is three times wider than
+   *     the original glyph image.  See also @FT_RENDER_MODE_LCD.
    *
    *   FT_PIXEL_MODE_LCD_V ::
-   *     An 8-bit bitmap, representing RGB or BGR decimated glyph images
-   *     used for display on rotated LCD displays; the bitmap is three
-   *     times taller than the original glyph image.  See also
+   *     An 8-bit bitmap, representing RGB or BGR decimated glyph images used
+   *     for display on rotated LCD displays; the bitmap is three times
+   *     taller than the original glyph image.  See also
    *     @FT_RENDER_MODE_LCD_V.
    *
    *   FT_PIXEL_MODE_BGRA ::
    *     [Since 2.5] An image with four 8-bit channels per pixel,
-   *     representing a color image (such as emoticons) with alpha
-   *     channel.  For each pixel, the format is BGRA, which means, the
-   *     blue channel comes first in memory.  The color channels are
-   *     pre-multiplied and in the sRGB colorspace.  For example, full
-   *     red at half-translucent opacity will be represented as
-   *     `00,00,80,80', not `00,00,FF,80'.  See also @FT_LOAD_COLOR.
+   *     representing a color image (such as emoticons) with alpha channel.
+   *     For each pixel, the format is BGRA, which means, the blue channel
+   *     comes first in memory.  The color channels are pre-multiplied and in
+   *     the sRGB colorspace.  For example, full red at half-translucent
+   *     opacity will be represented as '00,00,80,80', not '00,00,FF,80'.
+   *     See also @FT_LOAD_COLOR.
    */
   typedef enum  FT_Pixel_Mode_
   {
@@ -199,7 +188,7 @@
   } FT_Pixel_Mode;
 
 
-  /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */
+  /* these constants are deprecated; use the corresponding `FT_Pixel_Mode` */
   /* values instead.                                                       */
 #define ft_pixel_mode_none   FT_PIXEL_MODE_NONE
 #define ft_pixel_mode_mono   FT_PIXEL_MODE_MONO
@@ -207,6 +196,11 @@
 #define ft_pixel_mode_pal2   FT_PIXEL_MODE_GRAY2
 #define ft_pixel_mode_pal4   FT_PIXEL_MODE_GRAY4
 
+  /* */
+
+  /* For debugging, the @FT_Pixel_Mode enumeration must stay in sync */
+  /* with the `pixel_modes` array in file `ftobjs.c`.                */
+
 
   /**************************************************************************
    *
@@ -214,9 +208,9 @@
    *   FT_Bitmap
    *
    * @description:
-   *   A structure used to describe a bitmap or pixmap to the raster.
-   *   Note that we now manage pixmaps of various depths through the
-   *   `pixel_mode' field.
+   *   A structure used to describe a bitmap or pixmap to the raster.  Note
+   *   that we now manage pixmaps of various depths through the `pixel_mode`
+   *   field.
    *
    * @fields:
    *   rows ::
@@ -226,51 +220,42 @@
    *     The number of pixels in bitmap row.
    *
    *   pitch ::
-   *     The pitch's absolute value is the number of bytes
-   *     taken by one bitmap row, including padding.
-   *     However, the pitch is positive when the bitmap has
-   *     a `down' flow, and negative when it has an `up'
-   *     flow.  In all cases, the pitch is an offset to add
-   *     to a bitmap pointer in order to go down one row.
+   *     The pitch's absolute value is the number of bytes taken by one
+   *     bitmap row, including padding.  However, the pitch is positive when
+   *     the bitmap has a 'down' flow, and negative when it has an 'up' flow.
+   *     In all cases, the pitch is an offset to add to a bitmap pointer in
+   *     order to go down one row.
    *
-   *     Note that `padding' means the alignment of a
-   *     bitmap to a byte border, and FreeType functions
-   *     normally align to the smallest possible integer
-   *     value.
+   *     Note that 'padding' means the alignment of a bitmap to a byte
+   *     border, and FreeType functions normally align to the smallest
+   *     possible integer value.
    *
-   *     For the B/W rasterizer, `pitch' is always an even
-   *     number.
+   *     For the B/W rasterizer, `pitch` is always an even number.
    *
-   *     To change the pitch of a bitmap (say, to make it a
-   *     multiple of 4), use @FT_Bitmap_Convert.
-   *     Alternatively, you might use callback functions to
-   *     directly render to the application's surface; see
-   *     the file `example2.cpp' in the tutorial for a
-   *     demonstration.
+   *     To change the pitch of a bitmap (say, to make it a multiple of 4),
+   *     use @FT_Bitmap_Convert.  Alternatively, you might use callback
+   *     functions to directly render to the application's surface; see the
+   *     file `example2.cpp` in the tutorial for a demonstration.
    *
    *   buffer ::
-   *     A typeless pointer to the bitmap buffer.  This
-   *     value should be aligned on 32-bit boundaries in
-   *     most cases.
+   *     A typeless pointer to the bitmap buffer.  This value should be
+   *     aligned on 32-bit boundaries in most cases.
    *
    *   num_grays ::
-   *     This field is only used with
-   *     @FT_PIXEL_MODE_GRAY; it gives the number of gray
-   *     levels used in the bitmap.
+   *     This field is only used with @FT_PIXEL_MODE_GRAY; it gives the
+   *     number of gray levels used in the bitmap.
    *
    *   pixel_mode ::
-   *     The pixel mode, i.e., how pixel bits are stored.
-   *     See @FT_Pixel_Mode for possible values.
+   *     The pixel mode, i.e., how pixel bits are stored.  See @FT_Pixel_Mode
+   *     for possible values.
    *
    *   palette_mode ::
-   *     This field is intended for paletted pixel modes;
-   *     it indicates how the palette is stored.  Not
-   *     used currently.
+   *     This field is intended for paletted pixel modes; it indicates how
+   *     the palette is stored.  Not used currently.
    *
    *   palette ::
-   *     A typeless pointer to the bitmap palette; this
-   *     field is intended for paletted pixel modes.  Not
-   *     used currently.
+   *     A typeless pointer to the bitmap palette; this field is intended for
+   *     paletted pixel modes.  Not used currently.
    */
   typedef struct  FT_Bitmap_
   {
@@ -311,45 +296,42 @@
    *     The number of points in the outline.
    *
    *   points ::
-   *     A pointer to an array of `n_points' @FT_Vector
-   *     elements, giving the outline's point coordinates.
+   *     A pointer to an array of `n_points` @FT_Vector elements, giving the
+   *     outline's point coordinates.
    *
    *   tags ::
-   *     A pointer to an array of `n_points' chars, giving
-   *     each outline point's type.
+   *     A pointer to an array of `n_points` chars, giving each outline
+   *     point's type.
    *
-   *     If bit~0 is unset, the point is `off' the curve,
-   *     i.e., a Bezier control point, while it is `on' if
-   *     set.
+   *     If bit~0 is unset, the point is 'off' the curve, i.e., a Bezier
+   *     control point, while it is 'on' if set.
    *
-   *     Bit~1 is meaningful for `off' points only.  If set,
-   *     it indicates a third-order Bezier arc control point;
-   *     and a second-order control point if unset.
+   *     Bit~1 is meaningful for 'off' points only.  If set, it indicates a
+   *     third-order Bezier arc control point; and a second-order control
+   *     point if unset.
    *
-   *     If bit~2 is set, bits 5-7 contain the drop-out mode
-   *     (as defined in the OpenType specification; the value
-   *     is the same as the argument to the SCANMODE
-   *     instruction).
+   *     If bit~2 is set, bits 5-7 contain the drop-out mode (as defined in
+   *     the OpenType specification; the value is the same as the argument to
+   *     the 'SCANMODE' instruction).
    *
    *     Bits 3 and~4 are reserved for internal purposes.
    *
    *   contours ::
-   *     An array of `n_contours' shorts, giving the end
-   *     point of each contour within the outline.  For
-   *     example, the first contour is defined by the points
-   *     `0' to `contours[0]', the second one is defined by
-   *     the points `contours[0]+1' to `contours[1]', etc.
+   *     An array of `n_contours` shorts, giving the end point of each
+   *     contour within the outline.  For example, the first contour is
+   *     defined by the points '0' to `contours[0]`, the second one is
+   *     defined by the points `contours[0]+1` to `contours[1]`, etc.
    *
    *   flags ::
-   *     A set of bit flags used to characterize the outline
-   *     and give hints to the scan-converter and hinter on
-   *     how to convert/grid-fit it.  See @FT_OUTLINE_XXX.
+   *     A set of bit flags used to characterize the outline and give hints
+   *     to the scan-converter and hinter on how to convert/grid-fit it.  See
+   *     @FT_OUTLINE_XXX.
    *
    * @note:
-   *   The B/W rasterizer only checks bit~2 in the `tags' array for the
-   *   first point of each contour.  The drop-out mode as given with
+   *   The B/W rasterizer only checks bit~2 in the `tags` array for the first
+   *   point of each contour.  The drop-out mode as given with
    *   @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and
-   *   @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden.
+   *   @FT_OUTLINE_INCLUDE_STUBS in `flags` is then overridden.
    */
   typedef struct  FT_Outline_
   {
@@ -378,22 +360,22 @@
    *   FT_OUTLINE_XXX
    *
    * @description:
-   *   A list of bit-field constants use for the flags in an outline's
-   *   `flags' field.
+   *   A list of bit-field constants used for the flags in an outline's
+   *   `flags` field.
    *
    * @values:
    *   FT_OUTLINE_NONE ::
    *     Value~0 is reserved.
    *
    *   FT_OUTLINE_OWNER ::
-   *     If set, this flag indicates that the outline's field arrays
-   *     (i.e., `points', `flags', and `contours') are `owned' by the
-   *     outline object, and should thus be freed when it is destroyed.
+   *     If set, this flag indicates that the outline's field arrays (i.e.,
+   *     `points`, `flags`, and `contours`) are 'owned' by the outline
+   *     object, and should thus be freed when it is destroyed.
    *
    *   FT_OUTLINE_EVEN_ODD_FILL ::
-   *     By default, outlines are filled using the non-zero winding rule.
-   *     If set to 1, the outline will be filled using the even-odd fill
-   *     rule (only works with the smooth rasterizer).
+   *     By default, outlines are filled using the non-zero winding rule.  If
+   *     set to 1, the outline will be filled using the even-odd fill rule
+   *     (only works with the smooth rasterizer).
    *
    *   FT_OUTLINE_REVERSE_FILL ::
    *     By default, outside contours of an outline are oriented in
@@ -403,46 +385,51 @@
    *     converter.
    *
    *   FT_OUTLINE_IGNORE_DROPOUTS ::
-   *     By default, the scan converter will try to detect drop-outs in
-   *     an outline and correct the glyph bitmap to ensure consistent
-   *     shape continuity.  If set, this flag hints the scan-line
-   *     converter to ignore such cases.  See below for more information.
+   *     By default, the scan converter will try to detect drop-outs in an
+   *     outline and correct the glyph bitmap to ensure consistent shape
+   *     continuity.  If set, this flag hints the scan-line converter to
+   *     ignore such cases.  See below for more information.
    *
    *   FT_OUTLINE_SMART_DROPOUTS ::
-   *     Select smart dropout control.  If unset, use simple dropout
-   *     control.  Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See
-   *     below for more information.
+   *     Select smart dropout control.  If unset, use simple dropout control.
+   *     Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See below for more
+   *     information.
    *
    *   FT_OUTLINE_INCLUDE_STUBS ::
-   *     If set, turn pixels on for `stubs', otherwise exclude them.
-   *     Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See below for
-   *     more information.
+   *     If set, turn pixels on for 'stubs', otherwise exclude them.  Ignored
+   *     if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See below for more
+   *     information.
+   *
+   *   FT_OUTLINE_OVERLAP ::
+   *     [Since 2.10.3] This flag indicates that this outline contains
+   *     overlapping contours and the anti-aliased renderer should perform
+   *     oversampling to mitigate possible artifacts.  This flag should _not_
+   *     be set for well designed glyphs without overlaps because it quadruples
+   *     the rendering time.
    *
    *   FT_OUTLINE_HIGH_PRECISION ::
    *     This flag indicates that the scan-line converter should try to
-   *     convert this outline to bitmaps with the highest possible
-   *     quality.  It is typically set for small character sizes.  Note
-   *     that this is only a hint that might be completely ignored by a
-   *     given scan-converter.
+   *     convert this outline to bitmaps with the highest possible quality.
+   *     It is typically set for small character sizes.  Note that this is
+   *     only a hint that might be completely ignored by a given
+   *     scan-converter.
    *
    *   FT_OUTLINE_SINGLE_PASS ::
    *     This flag is set to force a given scan-converter to only use a
    *     single pass over the outline to render a bitmap glyph image.
-   *     Normally, it is set for very large character sizes.  It is only
-   *     a hint that might be completely ignored by a given
-   *     scan-converter.
+   *     Normally, it is set for very large character sizes.  It is only a
+   *     hint that might be completely ignored by a given scan-converter.
    *
    * @note:
-   *   The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS,
-   *   and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth
-   *   rasterizer.
+   *   The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and
+   *   @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth rasterizer.
    *
-   *   There exists a second mechanism to pass the drop-out mode to the
-   *   B/W rasterizer; see the `tags' field in @FT_Outline.
+   *   There exists a second mechanism to pass the drop-out mode to the B/W
+   *   rasterizer; see the `tags` field in @FT_Outline.
    *
-   *   Please refer to the description of the `SCANTYPE' instruction in
-   *   the OpenType specification (in file `ttinst1.doc') how simple
-   *   drop-outs, smart drop-outs, and stubs are defined.
+   *   Please refer to the description of the 'SCANTYPE' instruction in the
+   *   OpenType specification (in file `ttinst1.doc`) how simple drop-outs,
+   *   smart drop-outs, and stubs are defined.
    */
 #define FT_OUTLINE_NONE             0x0
 #define FT_OUTLINE_OWNER            0x1
@@ -451,13 +438,14 @@
 #define FT_OUTLINE_IGNORE_DROPOUTS  0x8
 #define FT_OUTLINE_SMART_DROPOUTS   0x10
 #define FT_OUTLINE_INCLUDE_STUBS    0x20
+#define FT_OUTLINE_OVERLAP          0x40
 
 #define FT_OUTLINE_HIGH_PRECISION   0x100
 #define FT_OUTLINE_SINGLE_PASS      0x200
 
 
   /* these constants are deprecated; use the corresponding */
-  /* `FT_OUTLINE_XXX' values instead                       */
+  /* `FT_OUTLINE_XXX` values instead                       */
 #define ft_outline_none             FT_OUTLINE_NONE
 #define ft_outline_owner            FT_OUTLINE_OWNER
 #define ft_outline_even_odd_fill    FT_OUTLINE_EVEN_ODD_FILL
@@ -468,20 +456,25 @@
 
   /* */
 
-#define FT_CURVE_TAG( flag )  ( flag & 3 )
+#define FT_CURVE_TAG( flag )  ( flag & 0x03 )
 
-#define FT_CURVE_TAG_ON            1
-#define FT_CURVE_TAG_CONIC         0
-#define FT_CURVE_TAG_CUBIC         2
+  /* see the `tags` field in `FT_Outline` for a description of the values */
+#define FT_CURVE_TAG_ON            0x01
+#define FT_CURVE_TAG_CONIC         0x00
+#define FT_CURVE_TAG_CUBIC         0x02
 
-#define FT_CURVE_TAG_HAS_SCANMODE  4
+#define FT_CURVE_TAG_HAS_SCANMODE  0x04
 
-#define FT_CURVE_TAG_TOUCH_X       8  /* reserved for the TrueType hinter */
-#define FT_CURVE_TAG_TOUCH_Y      16  /* reserved for the TrueType hinter */
+#define FT_CURVE_TAG_TOUCH_X       0x08  /* reserved for TrueType hinter */
+#define FT_CURVE_TAG_TOUCH_Y       0x10  /* reserved for TrueType hinter */
 
 #define FT_CURVE_TAG_TOUCH_BOTH    ( FT_CURVE_TAG_TOUCH_X | \
                                      FT_CURVE_TAG_TOUCH_Y )
+  /* values 0x20, 0x40, and 0x80 are reserved */
 
+
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_CURVE_TAG_XXX` values instead                     */
 #define FT_Curve_Tag_On       FT_CURVE_TAG_ON
 #define FT_Curve_Tag_Conic    FT_CURVE_TAG_CONIC
 #define FT_Curve_Tag_Cubic    FT_CURVE_TAG_CUBIC
@@ -495,14 +488,14 @@
    *   FT_Outline_MoveToFunc
    *
    * @description:
-   *   A function pointer type used to describe the signature of a `move
-   *   to' function during outline walking/decomposition.
+   *   A function pointer type used to describe the signature of a 'move to'
+   *   function during outline walking/decomposition.
    *
-   *   A `move to' is emitted to start a new contour in an outline.
+   *   A 'move to' is emitted to start a new contour in an outline.
    *
    * @input:
    *   to ::
-   *     A pointer to the target point of the `move to'.
+   *     A pointer to the target point of the 'move to'.
    *
    *   user ::
    *     A typeless pointer, which is passed from the caller of the
@@ -524,14 +517,14 @@
    *   FT_Outline_LineToFunc
    *
    * @description:
-   *   A function pointer type used to describe the signature of a `line
-   *   to' function during outline walking/decomposition.
+   *   A function pointer type used to describe the signature of a 'line to'
+   *   function during outline walking/decomposition.
    *
-   *   A `line to' is emitted to indicate a segment in the outline.
+   *   A 'line to' is emitted to indicate a segment in the outline.
    *
    * @input:
    *   to ::
-   *     A pointer to the target point of the `line to'.
+   *     A pointer to the target point of the 'line to'.
    *
    *   user ::
    *     A typeless pointer, which is passed from the caller of the
@@ -553,23 +546,23 @@
    *   FT_Outline_ConicToFunc
    *
    * @description:
-   *   A function pointer type used to describe the signature of a `conic
-   *   to' function during outline walking or decomposition.
+   *   A function pointer type used to describe the signature of a 'conic to'
+   *   function during outline walking or decomposition.
    *
-   *   A `conic to' is emitted to indicate a second-order Bezier arc in
-   *   the outline.
+   *   A 'conic to' is emitted to indicate a second-order Bezier arc in the
+   *   outline.
    *
    * @input:
    *   control ::
-   *     An intermediate control point between the last position
-   *     and the new target in `to'.
+   *     An intermediate control point between the last position and the new
+   *     target in `to`.
    *
    *   to ::
    *     A pointer to the target end point of the conic arc.
    *
    *   user ::
-   *     A typeless pointer, which is passed from the caller of
-   *     the decomposition function.
+   *     A typeless pointer, which is passed from the caller of the
+   *     decomposition function.
    *
    * @return:
    *   Error code.  0~means success.
@@ -588,10 +581,10 @@
    *   FT_Outline_CubicToFunc
    *
    * @description:
-   *   A function pointer type used to describe the signature of a `cubic
-   *   to' function during outline walking or decomposition.
+   *   A function pointer type used to describe the signature of a 'cubic to'
+   *   function during outline walking or decomposition.
    *
-   *   A `cubic to' is emitted to indicate a third-order Bezier arc.
+   *   A 'cubic to' is emitted to indicate a third-order Bezier arc.
    *
    * @input:
    *   control1 ::
@@ -604,8 +597,8 @@
    *     A pointer to the target end point.
    *
    *   user ::
-   *     A typeless pointer, which is passed from the caller of
-   *     the decomposition function.
+   *     A typeless pointer, which is passed from the caller of the
+   *     decomposition function.
    *
    * @return:
    *   Error code.  0~means success.
@@ -630,7 +623,7 @@
    *
    * @fields:
    *   move_to ::
-   *     The `move to' emitter.
+   *     The 'move to' emitter.
    *
    *   line_to ::
    *     The segment emitter.
@@ -642,25 +635,25 @@
    *     The third-order Bezier arc emitter.
    *
    *   shift ::
-   *     The shift that is applied to coordinates before they
-   *     are sent to the emitter.
+   *     The shift that is applied to coordinates before they are sent to the
+   *     emitter.
    *
    *   delta ::
-   *     The delta that is applied to coordinates before they
-   *     are sent to the emitter, but after the shift.
+   *     The delta that is applied to coordinates before they are sent to the
+   *     emitter, but after the shift.
    *
    * @note:
-   *   The point coordinates sent to the emitters are the transformed
-   *   version of the original coordinates (this is important for high
-   *   accuracy during scan-conversion).  The transformation is simple:
+   *   The point coordinates sent to the emitters are the transformed version
+   *   of the original coordinates (this is important for high accuracy
+   *   during scan-conversion).  The transformation is simple:
    *
-   *   {
+   *   ```
    *     x' = (x << shift) - delta
    *     y' = (y << shift) - delta
-   *   }
+   *   ```
    *
-   *   Set the values of `shift' and `delta' to~0 to get the original
-   *   point coordinates.
+   *   Set the values of `shift` and `delta` to~0 to get the original point
+   *   coordinates.
    */
   typedef struct  FT_Outline_Funcs_
   {
@@ -692,22 +685,23 @@
    *   This macro converts four-letter tags to an unsigned long type.
    *
    * @note:
-   *   Since many 16-bit compilers don't like 32-bit enumerations, you
-   *   should redefine this macro in case of problems to something like
-   *   this:
+   *   Since many 16-bit compilers don't like 32-bit enumerations, you should
+   *   redefine this macro in case of problems to something like this:
    *
-   *   {
+   *   ```
    *     #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )  value
-   *   }
+   *   ```
    *
    *   to get a simple enumeration without assigning special numbers.
    */
 #ifndef FT_IMAGE_TAG
-#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )  \
-          value = ( ( (unsigned long)_x1 << 24 ) | \
-                    ( (unsigned long)_x2 << 16 ) | \
-                    ( (unsigned long)_x3 << 8  ) | \
-                      (unsigned long)_x4         )
+
+#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )                         \
+          value = ( ( FT_STATIC_BYTE_CAST( unsigned long, _x1 ) << 24 ) | \
+                    ( FT_STATIC_BYTE_CAST( unsigned long, _x2 ) << 16 ) | \
+                    ( FT_STATIC_BYTE_CAST( unsigned long, _x3 ) << 8  ) | \
+                      FT_STATIC_BYTE_CAST( unsigned long, _x4 )         )
+
 #endif /* FT_IMAGE_TAG */
 
 
@@ -727,27 +721,30 @@
    *     The value~0 is reserved.
    *
    *   FT_GLYPH_FORMAT_COMPOSITE ::
-   *     The glyph image is a composite of several other images.  This
-   *     format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to
-   *     report compound glyphs (like accented characters).
+   *     The glyph image is a composite of several other images.  This format
+   *     is _only_ used with @FT_LOAD_NO_RECURSE, and is used to report
+   *     compound glyphs (like accented characters).
    *
    *   FT_GLYPH_FORMAT_BITMAP ::
-   *     The glyph image is a bitmap, and can be described as an
-   *     @FT_Bitmap.  You generally need to access the `bitmap' field of
-   *     the @FT_GlyphSlotRec structure to read it.
+   *     The glyph image is a bitmap, and can be described as an @FT_Bitmap.
+   *     You generally need to access the `bitmap` field of the
+   *     @FT_GlyphSlotRec structure to read it.
    *
    *   FT_GLYPH_FORMAT_OUTLINE ::
-   *     The glyph image is a vectorial outline made of line segments
-   *     and Bezier arcs; it can be described as an @FT_Outline; you
-   *     generally want to access the `outline' field of the
-   *     @FT_GlyphSlotRec structure to read it.
+   *     The glyph image is a vectorial outline made of line segments and
+   *     Bezier arcs; it can be described as an @FT_Outline; you generally
+   *     want to access the `outline` field of the @FT_GlyphSlotRec structure
+   *     to read it.
    *
    *   FT_GLYPH_FORMAT_PLOTTER ::
    *     The glyph image is a vectorial path with no inside and outside
    *     contours.  Some Type~1 fonts, like those in the Hershey family,
-   *     contain glyphs in this format.  These are described as
-   *     @FT_Outline, but FreeType isn't currently capable of rendering
-   *     them correctly.
+   *     contain glyphs in this format.  These are described as @FT_Outline,
+   *     but FreeType isn't currently capable of rendering them correctly.
+   *
+   *   FT_GLYPH_FORMAT_SVG ::
+   *     [Since 2.12] The glyph is represented by an SVG document in the
+   *     'SVG~' table.
    */
   typedef enum  FT_Glyph_Format_
   {
@@ -756,13 +753,14 @@
     FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ),
     FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP,    'b', 'i', 't', 's' ),
     FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE,   'o', 'u', 't', 'l' ),
-    FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER,   'p', 'l', 'o', 't' )
+    FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER,   'p', 'l', 'o', 't' ),
+    FT_IMAGE_TAG( FT_GLYPH_FORMAT_SVG,       'S', 'V', 'G', ' ' )
 
   } FT_Glyph_Format;
 
 
   /* these constants are deprecated; use the corresponding */
-  /* `FT_Glyph_Format' values instead.                     */
+  /* `FT_Glyph_Format` values instead.                     */
 #define ft_glyph_format_none       FT_GLYPH_FORMAT_NONE
 #define ft_glyph_format_composite  FT_GLYPH_FORMAT_COMPOSITE
 #define ft_glyph_format_bitmap     FT_GLYPH_FORMAT_BITMAP
@@ -781,17 +779,6 @@
   /*************************************************************************/
 
 
-  /**************************************************************************
-   *
-   * A raster is a scan converter, in charge of rendering an outline into
-   * a bitmap.  This section contains the public API for rasters.
-   *
-   * Note that in FreeType 2, all rasters are now encapsulated within
-   * specific modules called `renderers'.  See `ftrender.h' for more
-   * details on renderers.
-   *
-   */
-
 
   /**************************************************************************
    *
@@ -805,16 +792,35 @@
    *   How vectorial outlines are converted into bitmaps and pixmaps.
    *
    * @description:
-   *   This section contains technical definitions.
+   *   A raster or a rasterizer is a scan converter in charge of producing a
+   *   pixel coverage bitmap that can be used as an alpha channel when
+   *   compositing a glyph with a background.  FreeType comes with two
+   *   rasterizers: bilevel `raster1` and anti-aliased `smooth` are two
+   *   separate modules.  They are usually called from the high-level
+   *   @FT_Load_Glyph or @FT_Render_Glyph functions and produce the entire
+   *   coverage bitmap at once, while staying largely invisible to users.
+   *
+   *   Instead of working with complete coverage bitmaps, it is also possible
+   *   to intercept consecutive pixel runs on the same scanline with the same
+   *   coverage, called _spans_, and process them individually.  Only the
+   *   `smooth` rasterizer permits this when calling @FT_Outline_Render with
+   *   @FT_Raster_Params as described below.
+   *
+   *   Working with either complete bitmaps or spans it is important to think
+   *   of them as colorless coverage objects suitable as alpha channels to
+   *   blend arbitrary colors with a background.  For best results, it is
+   *   recommended to use gamma correction, too.
+   *
+   *   This section also describes the public API needed to set up alternative
+   *   @FT_Renderer modules.
    *
    * @order:
-   *   FT_Raster
    *   FT_Span
    *   FT_SpanFunc
-   *
    *   FT_Raster_Params
    *   FT_RASTER_FLAG_XXX
    *
+   *   FT_Raster
    *   FT_Raster_NewFunc
    *   FT_Raster_DoneFunc
    *   FT_Raster_ResetFunc
@@ -827,23 +833,11 @@
 
   /**************************************************************************
    *
-   * @type:
-   *   FT_Raster
-   *
-   * @description:
-   *   An opaque handle (pointer) to a raster object.  Each object can be
-   *   used independently to convert an outline into a bitmap or pixmap.
-   */
-  typedef struct FT_RasterRec_*  FT_Raster;
-
-
-  /**************************************************************************
-   *
    * @struct:
    *   FT_Span
    *
    * @description:
-   *   A structure used to model a single span of gray pixels when
+   *   A structure to model a single span of consecutive pixels when
    *   rendering an anti-aliased bitmap.
    *
    * @fields:
@@ -854,16 +848,15 @@
    *     The span's length in pixels.
    *
    *   coverage ::
-   *     The span color/coverage, ranging from 0 (background)
-   *     to 255 (foreground).
+   *     The span color/coverage, ranging from 0 (background) to 255
+   *     (foreground).
    *
    * @note:
    *   This structure is used by the span drawing callback type named
-   *   @FT_SpanFunc that takes the y~coordinate of the span as a
-   *   parameter.
+   *   @FT_SpanFunc that takes the y~coordinate of the span as a parameter.
    *
-   *   The coverage value is always between 0 and 255.  If you want less
-   *   gray values, the callback function has to reduce them.
+   *   The anti-aliased rasterizer produces coverage values from 0 to 255,
+   *   this is, from completely transparent to completely opaque.
    */
   typedef struct  FT_Span_
   {
@@ -880,29 +873,30 @@
    *   FT_SpanFunc
    *
    * @description:
-   *   A function used as a call-back by the anti-aliased renderer in
-   *   order to let client applications draw themselves the gray pixel
-   *   spans on each scan line.
+   *   A function used as a call-back by the anti-aliased renderer in order
+   *   to let client applications draw themselves the pixel spans on each
+   *   scan line.
    *
    * @input:
    *   y ::
-   *     The scanline's y~coordinate.
+   *     The scanline's upward y~coordinate.
    *
    *   count ::
    *     The number of spans to draw on this scanline.
    *
    *   spans ::
-   *     A table of `count' spans to draw on the scanline.
+   *     A table of `count` spans to draw on the scanline.
    *
    *   user ::
    *     User-supplied data that is passed to the callback.
    *
    * @note:
-   *   This callback allows client applications to directly render the
-   *   gray spans of the anti-aliased bitmap to any kind of surfaces.
+   *   This callback allows client applications to directly render the spans
+   *   of the anti-aliased bitmap to any kind of surfaces.
    *
-   *   This can be used to write anti-aliased outlines directly to a
-   *   given background bitmap, and even perform translucency.
+   *   This can be used to write anti-aliased outlines directly to a given
+   *   background bitmap using alpha compositing.  It can also be used for
+   *   oversampling and averaging.
    */
   typedef void
   (*FT_SpanFunc)( int             y,
@@ -947,7 +941,7 @@
    *   FT_RASTER_FLAG_XXX
    *
    * @description:
-   *   A list of bit flag constants as used in the `flags' field of a
+   *   A list of bit flag constants as used in the `flags` field of a
    *   @FT_Raster_Params structure.
    *
    * @values:
@@ -955,43 +949,37 @@
    *     This value is 0.
    *
    *   FT_RASTER_FLAG_AA ::
-   *     This flag is set to indicate that an
-   *     anti-aliased glyph image should be
-   *     generated.  Otherwise, it will be
-   *     monochrome (1-bit).
+   *     This flag is set to indicate that an anti-aliased glyph image should
+   *     be generated.  Otherwise, it will be monochrome (1-bit).
    *
    *   FT_RASTER_FLAG_DIRECT ::
-   *     This flag is set to indicate direct
-   *     rendering.  In this mode, client
-   *     applications must provide their own span
-   *     callback.  This lets them directly
-   *     draw or compose over an existing bitmap.
-   *     If this bit is not set, the target
-   *     pixmap's buffer _must_ be zeroed before
-   *     rendering.
+   *     This flag is set to indicate direct rendering.  In this mode, client
+   *     applications must provide their own span callback.  This lets them
+   *     directly draw or compose over an existing bitmap.  If this bit is
+   *     _not_ set, the target pixmap's buffer _must_ be zeroed before
+   *     rendering and the output will be clipped to its size.
    *
-   *     Direct rendering is only possible with
-   *     anti-aliased glyphs.
+   *     Direct rendering is only possible with anti-aliased glyphs.
    *
    *   FT_RASTER_FLAG_CLIP ::
-   *     This flag is only used in direct
-   *     rendering mode.  If set, the output will
-   *     be clipped to a box specified in the
-   *     `clip_box' field of the
-   *     @FT_Raster_Params structure.
+   *     This flag is only used in direct rendering mode.  If set, the output
+   *     will be clipped to a box specified in the `clip_box` field of the
+   *     @FT_Raster_Params structure.  Otherwise, the `clip_box` is
+   *     effectively set to the bounding box and all spans are generated.
    *
-   *     Note that by default, the glyph bitmap
-   *     is clipped to the target pixmap, except
-   *     in direct rendering mode where all spans
-   *     are generated if no clipping box is set.
+   *   FT_RASTER_FLAG_SDF ::
+   *     This flag is set to indicate that a signed distance field glyph
+   *     image should be generated.  This is only used while rendering with
+   *     the @FT_RENDER_MODE_SDF render mode.
    */
 #define FT_RASTER_FLAG_DEFAULT  0x0
 #define FT_RASTER_FLAG_AA       0x1
 #define FT_RASTER_FLAG_DIRECT   0x2
 #define FT_RASTER_FLAG_CLIP     0x4
+#define FT_RASTER_FLAG_SDF      0x8
 
   /* these constants are deprecated; use the corresponding */
-  /* `FT_RASTER_FLAG_XXX' values instead                   */
+  /* `FT_RASTER_FLAG_XXX` values instead                   */
 #define ft_raster_flag_default  FT_RASTER_FLAG_DEFAULT
 #define ft_raster_flag_aa       FT_RASTER_FLAG_AA
 #define ft_raster_flag_direct   FT_RASTER_FLAG_DIRECT
@@ -1004,16 +992,15 @@
    *   FT_Raster_Params
    *
    * @description:
-   *   A structure to hold the arguments used by a raster's render
-   *   function.
+   *   A structure to hold the parameters used by a raster's render function,
+   *   passed as an argument to @FT_Outline_Render.
    *
    * @fields:
    *   target ::
    *     The target bitmap.
    *
    *   source ::
-   *     A pointer to the source glyph image (e.g., an
-   *     @FT_Outline).
+   *     A pointer to the source glyph image (e.g., an @FT_Outline).
    *
    *   flags ::
    *     The rendering flags.
@@ -1031,25 +1018,29 @@
    *     Unused.
    *
    *   user ::
-   *     User-supplied data that is passed to each drawing
-   *     callback.
+   *     User-supplied data that is passed to each drawing callback.
    *
    *   clip_box ::
-   *     An optional clipping box.  It is only used in
-   *     direct rendering mode.  Note that coordinates here
-   *     should be expressed in _integer_ pixels (and not in
-   *     26.6 fixed-point units).
+   *     An optional span clipping box expressed in _integer_ pixels
+   *     (not in 26.6 fixed-point units).
    *
    * @note:
-   *   An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA
-   *   bit flag is set in the `flags' field, otherwise a monochrome
-   *   bitmap is generated.
+   *   The @FT_RASTER_FLAG_AA bit flag must be set in the `flags` to
+   *   generate an anti-aliased glyph bitmap, otherwise a monochrome bitmap
+   *   is generated.  The `target` should have appropriate pixel mode and its
+   *   dimensions define the clipping region.
    *
-   *   If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the
-   *   raster will call the `gray_spans' callback to draw gray pixel
-   *   spans.  This allows direct composition over a pre-existing bitmap
-   *   through user-provided callbacks to perform the span drawing and
-   *   composition.    Not supported by the monochrome rasterizer.
+   *   If both @FT_RASTER_FLAG_AA and @FT_RASTER_FLAG_DIRECT bit flags
+   *   are set in `flags`, the raster calls an @FT_SpanFunc callback
+   *   `gray_spans` with `user` data as an argument ignoring `target`.  This
+   *   allows direct composition over a pre-existing user surface to perform
+   *   the span drawing and composition.  To optionally clip the spans, set
+   *   the @FT_RASTER_FLAG_CLIP flag and `clip_box`.  The monochrome raster
+   *   does not support the direct mode.
+   *
+   *   The gray-level rasterizer always uses 256 gray levels.  If you want
+   *   fewer gray levels, you have to use @FT_RASTER_FLAG_DIRECT and reduce
+   *   the levels in the callback function.
    */
   typedef struct  FT_Raster_Params_
   {
@@ -1068,6 +1059,23 @@
 
   /**************************************************************************
    *
+   * @type:
+   *   FT_Raster
+   *
+   * @description:
+   *   An opaque handle (pointer) to a raster object.  Each object can be
+   *   used independently to convert an outline into a bitmap or pixmap.
+   *
+   * @note:
+   *   In FreeType 2, all rasters are now encapsulated within specific
+   *   @FT_Renderer modules and only used in their context.
+   *
+   */
+  typedef struct FT_RasterRec_*  FT_Raster;
+
+
+  /**************************************************************************
+   *
    * @functype:
    *   FT_Raster_NewFunc
    *
@@ -1086,11 +1094,11 @@
    *   Error code.  0~means success.
    *
    * @note:
-   *   The `memory' parameter is a typeless pointer in order to avoid
-   *   un-wanted dependencies on the rest of the FreeType code.  In
-   *   practice, it is an @FT_Memory object, i.e., a handle to the
-   *   standard FreeType memory allocator.  However, this field can be
-   *   completely ignored by a given raster implementation.
+   *   The `memory` parameter is a typeless pointer in order to avoid
+   *   un-wanted dependencies on the rest of the FreeType code.  In practice,
+   *   it is an @FT_Memory object, i.e., a handle to the standard FreeType
+   *   memory allocator.  However, this field can be completely ignored by a
+   *   given raster implementation.
    */
   typedef int
   (*FT_Raster_NewFunc)( void*       memory,
@@ -1123,9 +1131,9 @@
    *   FT_Raster_ResetFunc
    *
    * @description:
-   *   FreeType used to provide an area of memory called the `render
-   *   pool' available to all registered rasterizers.  This was not
-   *   thread safe, however, and now FreeType never allocates this pool.
+   *   FreeType used to provide an area of memory called the 'render pool'
+   *   available to all registered rasterizers.  This was not thread safe,
+   *   however, and now FreeType never allocates this pool.
    *
    *   This function is called after a new raster object is created.
    *
@@ -1134,17 +1142,16 @@
    *     A handle to the new raster object.
    *
    *   pool_base ::
-   *     Previously, the address in memory of the render pool.
-   *     Set this to NULL.
+   *     Previously, the address in memory of the render pool.  Set this to
+   *     `NULL`.
    *
    *   pool_size ::
-   *     Previously, the size in bytes of the render pool.
-   *     Set this to 0.
+   *     Previously, the size in bytes of the render pool.  Set this to 0.
    *
    * @note:
-   *   Rasterizers should rely on dynamic or stack allocation if they
-   *   want to (a handle to the memory allocator is passed to the
-   *   rasterizer constructor).
+   *   Rasterizers should rely on dynamic or stack allocation if they want to
+   *   (a handle to the memory allocator is passed to the rasterizer
+   *   constructor).
    */
   typedef void
   (*FT_Raster_ResetFunc)( FT_Raster       raster,
@@ -1160,10 +1167,9 @@
    *   FT_Raster_SetModeFunc
    *
    * @description:
-   *   This function is a generic facility to change modes or attributes
-   *   in a given raster.  This can be used for debugging purposes, or
-   *   simply to allow implementation-specific `features' in a given
-   *   raster module.
+   *   This function is a generic facility to change modes or attributes in a
+   *   given raster.  This can be used for debugging purposes, or simply to
+   *   allow implementation-specific 'features' in a given raster module.
    *
    * @input:
    *   raster ::
@@ -1197,8 +1203,8 @@
    *     A handle to the raster object.
    *
    *   params ::
-   *     A pointer to an @FT_Raster_Params structure used to
-   *     store the rendering parameters.
+   *     A pointer to an @FT_Raster_Params structure used to store the
+   *     rendering parameters.
    *
    * @return:
    *   Error code.  0~means success.
@@ -1210,14 +1216,8 @@
    *   glyph formats.
    *
    *   Note also that the render function can fail and return a
-   *   `FT_Err_Unimplemented_Feature' error code if the raster used does
-   *   not support direct composition.
-   *
-   *   XXX: For now, the standard raster doesn't support direct
-   *        composition but this should change for the final release (see
-   *        the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c'
-   *        for examples of distinct implementations that support direct
-   *        composition).
+   *   `FT_Err_Unimplemented_Feature` error code if the raster used does not
+   *   support direct composition.
    */
   typedef int
   (*FT_Raster_RenderFunc)( FT_Raster                raster,
diff --git a/include/freetype/ftincrem.h b/include/freetype/ftincrem.h
index b3a17c3..2d4f5de 100644
--- a/include/freetype/ftincrem.h
+++ b/include/freetype/ftincrem.h
@@ -4,7 +4,7 @@
  *
  *   FreeType incremental loading (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,9 +19,8 @@
 #ifndef FTINCREM_H_
 #define FTINCREM_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_PARAMETER_TAGS_H
+#include <freetype/freetype.h>
+#include <freetype/ftparams.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -32,7 +31,7 @@
 
 FT_BEGIN_HEADER
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @section:
    *    incremental
@@ -45,7 +44,7 @@
    *
    * @description:
    *   This section contains various functions used to perform so-called
-   *   `incremental' glyph loading.  This is a mode where all glyphs loaded
+   *   'incremental' glyph loading.  This is a mode where all glyphs loaded
    *   from a given @FT_Face are provided by the client application.
    *
    *   Apart from that, all other tables are loaded normally from the font
@@ -60,23 +59,24 @@
    */
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Incremental
    *
    * @description:
    *   An opaque type describing a user-provided object used to implement
-   *   `incremental' glyph loading within FreeType.  This is used to support
-   *   embedded fonts in certain environments (e.g., PostScript interpreters),
-   *   where the glyph data isn't in the font file, or must be overridden by
-   *   different values.
+   *   'incremental' glyph loading within FreeType.  This is used to support
+   *   embedded fonts in certain environments (e.g., PostScript
+   *   interpreters), where the glyph data isn't in the font file, or must be
+   *   overridden by different values.
    *
    * @note:
-   *   It is up to client applications to create and implement @FT_Incremental
-   *   objects, as long as they provide implementations for the methods
-   *   @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc
-   *   and @FT_Incremental_GetGlyphMetricsFunc.
+   *   It is up to client applications to create and implement
+   *   @FT_Incremental objects, as long as they provide implementations for
+   *   the methods @FT_Incremental_GetGlyphDataFunc,
+   *   @FT_Incremental_FreeGlyphDataFunc and
+   *   @FT_Incremental_GetGlyphMetricsFunc.
    *
    *   See the description of @FT_Incremental_InterfaceRec to understand how
    *   to use incremental objects with FreeType.
@@ -85,14 +85,14 @@
   typedef struct FT_IncrementalRec_*  FT_Incremental;
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FT_Incremental_MetricsRec
    *
    * @description:
-   *   A small structure used to contain the basic glyph metrics returned
-   *   by the @FT_Incremental_GetGlyphMetricsFunc method.
+   *   A small structure used to contain the basic glyph metrics returned by
+   *   the @FT_Incremental_GetGlyphMetricsFunc method.
    *
    * @fields:
    *   bearing_x ::
@@ -109,7 +109,7 @@
    *
    * @note:
    *   These correspond to horizontal or vertical metrics depending on the
-   *   value of the `vertical' argument to the function
+   *   value of the `vertical` argument to the function
    *   @FT_Incremental_GetGlyphMetricsFunc.
    *
    */
@@ -123,7 +123,7 @@
   } FT_Incremental_MetricsRec;
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FT_Incremental_Metrics
@@ -135,7 +135,7 @@
    typedef struct FT_Incremental_MetricsRec_*  FT_Incremental_Metrics;
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Incremental_GetGlyphDataFunc
@@ -147,8 +147,8 @@
    *
    *   Note that the format of the glyph's data bytes depends on the font
    *   file format.  For TrueType, it must correspond to the raw bytes within
-   *   the `glyf' table.  For PostScript formats, it must correspond to the
-   *   *unencrypted* charstring bytes, without any `lenIV' header.  It is
+   *   the 'glyf' table.  For PostScript formats, it must correspond to the
+   *   **unencrypted** charstring bytes, without any `lenIV` header.  It is
    *   undefined for any other format.
    *
    * @input:
@@ -169,8 +169,8 @@
    *
    * @note:
    *   If this function returns successfully the method
-   *   @FT_Incremental_FreeGlyphDataFunc will be called later to release
-   *   the data bytes.
+   *   @FT_Incremental_FreeGlyphDataFunc will be called later to release the
+   *   data bytes.
    *
    *   Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for
    *   compound glyphs.
@@ -182,7 +182,7 @@
                                       FT_Data*        adata );
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Incremental_FreeGlyphDataFunc
@@ -206,16 +206,21 @@
                                        FT_Data*        data );
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Incremental_GetGlyphMetricsFunc
    *
    * @description:
    *   A function used to retrieve the basic metrics of a given glyph index
-   *   before accessing its data.  This is necessary because, in certain
-   *   formats like TrueType, the metrics are stored in a different place from
-   *   the glyph images proper.
+   *   before accessing its data.  This allows for handling font types such
+   *   as PCL~XL Format~1, Class~2 downloaded TrueType fonts, where the glyph
+   *   metrics (`hmtx` and `vmtx` tables) are permitted to be omitted from
+   *   the font, and the relevant metrics included in the header of the glyph
+   *   outline data.  Importantly, this is not intended to allow custom glyph
+   *   metrics (for example, Postscript Metrics dictionaries), because that
+   *   conflicts with the requirements of outline hinting.  Such custom
+   *   metrics must be handled separately, by the calling application.
    *
    * @input:
    *   incremental ::
@@ -229,13 +234,13 @@
    *     If true, return vertical metrics.
    *
    *   ametrics ::
-   *     This parameter is used for both input and output.
-   *     The original glyph metrics, if any, in font units.  If metrics are
-   *     not available all the values must be set to zero.
+   *     This parameter is used for both input and output.  The original
+   *     glyph metrics, if any, in font units.  If metrics are not available
+   *     all the values must be set to zero.
    *
    * @output:
    *   ametrics ::
-   *     The replacement glyph metrics in font units.
+   *     The glyph metrics in font units.
    *
    */
   typedef FT_Error
@@ -252,8 +257,8 @@
    *   FT_Incremental_FuncsRec
    *
    * @description:
-   *   A table of functions for accessing fonts that load data
-   *   incrementally.  Used in @FT_Incremental_InterfaceRec.
+   *   A table of functions for accessing fonts that load data incrementally.
+   *   Used in @FT_Incremental_InterfaceRec.
    *
    * @fields:
    *   get_glyph_data ::
@@ -263,8 +268,8 @@
    *     The function to release glyph data.  Must not be null.
    *
    *   get_glyph_metrics ::
-   *     The function to get glyph metrics.  May be null if the font does
-   *     not provide overriding glyph metrics.
+   *     The function to get glyph metrics.  May be null if the font does not
+   *     require it.
    *
    */
   typedef struct  FT_Incremental_FuncsRec_
@@ -276,7 +281,7 @@
   } FT_Incremental_FuncsRec;
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FT_Incremental_InterfaceRec
@@ -286,7 +291,7 @@
    *   wants to support incremental glyph loading.  You should use it with
    *   @FT_PARAM_TAG_INCREMENTAL as in the following example:
    *
-   *   {
+   *   ```
    *     FT_Incremental_InterfaceRec  inc_int;
    *     FT_Parameter                 parameter;
    *     FT_Open_Args                 open_args;
@@ -309,7 +314,7 @@
    *     // open the font
    *     error = FT_Open_Face( library, &open_args, index, &face );
    *     ...
-   *   }
+   *   ```
    *
    */
   typedef struct  FT_Incremental_InterfaceRec_
@@ -320,7 +325,7 @@
   } FT_Incremental_InterfaceRec;
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Incremental_Interface
diff --git a/include/freetype/ftlcdfil.h b/include/freetype/ftlcdfil.h
index 8d27135..d3723e1 100644
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -5,7 +5,7 @@
  *   FreeType API for color filtering of subpixel bitmap glyphs
  *   (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #ifndef FTLCDFIL_H_
 #define FTLCDFIL_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_PARAMETER_TAGS_H
+#include <freetype/freetype.h>
+#include <freetype/ftparams.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -33,7 +32,7 @@
 
 FT_BEGIN_HEADER
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @section:
    *   lcd_rendering
@@ -46,8 +45,8 @@
    *
    * @description:
    *   FreeType provides two alternative subpixel rendering technologies.
-   *   Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your
-   *   `ftoption.h', this enables patented ClearType-style rendering.
+   *   Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your
+   *   `ftoption.h` file, this enables ClearType-style rendering.
    *   Otherwise, Harmony LCD rendering is enabled.  These technologies are
    *   controlled differently and API described below, although always
    *   available, performs its function when appropriate method is enabled
@@ -56,21 +55,21 @@
    *   ClearType-style LCD rendering exploits the color-striped structure of
    *   LCD pixels, increasing the available resolution in the direction of
    *   the stripe (usually horizontal RGB) by a factor of~3.  Using the
-   *   subpixels coverages unfiltered can create severe color fringes
+   *   subpixel coverages unfiltered can create severe color fringes
    *   especially when rendering thin features.  Indeed, to produce
-   *   black-on-white text, the nearby color subpixels must be dimmed equally.
+   *   black-on-white text, the nearby color subpixels must be dimmed
+   *   evenly.  Therefore, an equalizing 5-tap FIR filter should be applied
+   *   to subpixel coverages regardless of pixel boundaries and should have
+   *   these properties:
    *
-   *   A good 5-tap FIR filter should be applied to subpixel coverages
-   *   regardless of pixel boundaries and should have these properties:
-   *
-   *   1) It should be symmetrical, like {~a, b, c, b, a~}, to avoid
+   *   1. It should be symmetrical, like {~a, b, c, b, a~}, to avoid
    *      any shifts in appearance.
    *
-   *   2) It should be color-balanced, meaning a~+ b~=~c, to reduce color
+   *   2. It should be color-balanced, meaning a~+ b~=~c, to reduce color
    *      fringes by distributing the computed coverage for one subpixel to
    *      all subpixels equally.
    *
-   *   3) It should be normalized, meaning 2a~+ 2b~+ c~=~1.0 to maintain
+   *   3. It should be normalized, meaning 2a~+ 2b~+ c~=~1.0 to maintain
    *      overall brightness.
    *
    *   Boxy 3-tap filter {0, 1/3, 1/3, 1/3, 0} is sharper but is less
@@ -82,32 +81,32 @@
    *   subpixel-rendered bitmaps generated through @FT_Render_Glyph.
    *
    *   Harmony LCD rendering is suitable to panels with any regular subpixel
-   *   structure, not just monitors with 3 color striped subpixels, as long as
-   *   the color subpixels have fixed positions relative to the pixel center.
-   *   In this case, each color channel is then rendered separately after
-   *   shifting the outline opposite to the subpixel shift so that the
+   *   structure, not just monitors with 3 color striped subpixels, as long
+   *   as the color subpixels have fixed positions relative to the pixel
+   *   center.  In this case, each color channel can be rendered separately
+   *   after shifting the outline opposite to the subpixel shift so that the
    *   coverage maps are aligned.  This method is immune to color fringes
    *   because the shifts do not change integral coverage.
    *
    *   The subpixel geometry must be specified by xy-coordinates for each
-   *   subpixel. By convention they may come in the RGB order:
-   *   {{-1/3, 0}, {0, 0}, {1/3, 0}} for standard RGB striped panel or
-   *   {{-1/6, 1/4}, {-1/6, -1/4}, {1/3, 0}} for a certain PenTile panel.
+   *   subpixel. By convention they may come in the RGB order: {{-1/3, 0},
+   *   {0, 0}, {1/3, 0}} for standard RGB striped panel or {{-1/6, 1/4},
+   *   {-1/6, -1/4}, {1/3, 0}} for a certain PenTile panel.
    *
    *   Use the @FT_Library_SetLcdGeometry API to specify subpixel positions.
-   *   If one follows the RGB order convention, the same order applies
-   *   to the resulting @FT_PIXEL_MODE_LCD and @FT_PIXEL_MODE_LCD_V bitmaps.
-   *   Note, however, that the coordinate frame for the latter must be rotated
+   *   If one follows the RGB order convention, the same order applies to the
+   *   resulting @FT_PIXEL_MODE_LCD and @FT_PIXEL_MODE_LCD_V bitmaps.  Note,
+   *   however, that the coordinate frame for the latter must be rotated
    *   clockwise.  Harmony with default LCD geometry is equivalent to
    *   ClearType with light filter.
    *
-   *   As a result of ClearType filtering or Harmony rendering, the dimensions
-   *   of LCD bitmaps can be either wider or taller than the dimensions of
-   *   the corresponding outline with regard to the pixel grid.  For example,
-   *   for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to the left, and
-   *   2~subpixels to the right.  The bitmap offset values are adjusted
-   *   accordingly, so clients shouldn't need to modify their layout and
-   *   glyph positioning code when enabling the filter.
+   *   As a result of ClearType filtering or Harmony shifts, the resulting
+   *   dimensions of LCD bitmaps can be slightly wider or taller than the
+   *   dimensions the original outline with regard to the pixel grid.
+   *   For example, for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to
+   *   the left, and 2~subpixels to the right.  The bitmap offset values are
+   *   adjusted accordingly, so clients shouldn't need to modify their layout
+   *   and glyph positioning code when enabling the filter.
    *
    *   The ClearType and Harmony rendering is applicable to glyph bitmaps
    *   rendered through @FT_Render_Glyph, @FT_Load_Glyph, @FT_Load_Char, and
@@ -116,14 +115,14 @@
    *   @FT_Outline_Get_Bitmap.
    *
    *   The described algorithms can completely remove color artefacts when
-   *   combined with gamma-corrected alpha blending in linear space.
-   *   Each of the 3~alpha values (subpixels) must by independently used to
-   *   blend one color channel.  That is, red alpha blends the red channel of
-   *   the text color with the red channel of the background pixel.
+   *   combined with gamma-corrected alpha blending in linear space.  Each of
+   *   the 3~alpha values (subpixels) must by independently used to blend one
+   *   color channel.  That is, red alpha blends the red channel of the text
+   *   color with the red channel of the background pixel.
    */
 
 
-  /****************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_LcdFilter
@@ -138,11 +137,11 @@
    *
    *   FT_LCD_FILTER_DEFAULT ::
    *     This is a beveled, normalized, and color-balanced five-tap filter
-   *     with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256th units.
+   *     with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256 units.
    *
    *   FT_LCD_FILTER_LIGHT ::
-   *     this is a boxy, normalized, and color-balanced three-tap filter
-   *     with weights of [0x00 0x55 0x56 0x55 0x00] in 1/256th units.
+   *     this is a boxy, normalized, and color-balanced three-tap filter with
+   *     weights of [0x00 0x55 0x56 0x55 0x00] in 1/256 units.
    *
    *   FT_LCD_FILTER_LEGACY ::
    *   FT_LCD_FILTER_LEGACY1 ::
@@ -151,12 +150,11 @@
    *     fringes if glyphs are not extremely well hinted to the pixel grid.
    *     This filter is only provided for comparison purposes, and might be
    *     disabled or stay unsupported in the future. The second value is
-   *     provided for compatibility with FontConfig, which historically
-   *     used different enumeration, sometimes incorrectly forwarded to
-   *     FreeType.
+   *     provided for compatibility with FontConfig, which historically used
+   *     different enumeration, sometimes incorrectly forwarded to FreeType.
    *
    * @since:
-   *   2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2)
+   *   2.3.0 (`FT_LCD_FILTER_LEGACY1` since 2.6.2)
    */
   typedef enum  FT_LcdFilter_
   {
@@ -177,7 +175,7 @@
    *   FT_Library_SetLcdFilter
    *
    * @description:
-   *   This function is used to apply color filtering to LCD decimated
+   *   This function is used to change filter applied to LCD decimated
    *   bitmaps, like the ones used when calling @FT_Render_Glyph with
    *   @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V.
    *
@@ -189,22 +187,21 @@
    *     The filter type.
    *
    *     You can use @FT_LCD_FILTER_NONE here to disable this feature, or
-   *     @FT_LCD_FILTER_DEFAULT to use a default filter that should work
-   *     well on most LCD screens.
+   *     @FT_LCD_FILTER_DEFAULT to use a default filter that should work well
+   *     on most LCD screens.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This feature is always disabled by default.  Clients must make an
-   *   explicit call to this function with a `filter' value other than
-   *   @FT_LCD_FILTER_NONE in order to enable it.
+   *   Since 2.10.3 the LCD filtering is enabled with @FT_LCD_FILTER_DEFAULT.
+   *   It is no longer necessary to call this function explicitly except
+   *   to choose a different filter or disable filtering altogether with
+   *   @FT_LCD_FILTER_NONE.
    *
-   *   Due to *PATENTS* covering subpixel rendering, this function doesn't
-   *   do anything except returning `FT_Err_Unimplemented_Feature' if the
-   *   configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not
-   *   defined in your build of the library, which should correspond to all
-   *   default builds of FreeType.
+   *   This function does nothing but returns `FT_Err_Unimplemented_Feature`
+   *   if the configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is
+   *   not defined in your build of the library.
    *
    * @since:
    *   2.3.0
@@ -229,17 +226,15 @@
    *
    *   weights ::
    *     A pointer to an array; the function copies the first five bytes and
-   *     uses them to specify the filter weights in 1/256th units.
+   *     uses them to specify the filter weights in 1/256 units.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   Due to *PATENTS* covering subpixel rendering, this function doesn't
-   *   do anything except returning `FT_Err_Unimplemented_Feature' if the
-   *   configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not
-   *   defined in your build of the library, which should correspond to all
-   *   default builds of FreeType.
+   *   This function does nothing but returns `FT_Err_Unimplemented_Feature`
+   *   if the configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is
+   *   not defined in your build of the library.
    *
    *   LCD filter weights can also be set per face using @FT_Face_Properties
    *   with @FT_PARAM_TAG_LCD_FILTER_WEIGHTS.
@@ -296,8 +291,8 @@
    *   - {{-21, 0}, {0, 0}, {21, 0}} is the default, corresponding to 3 color
    *   stripes shifted by a third of a pixel. This could be an RGB panel.
    *
-   *   - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but
-   *   can specify a BGR panel instead, while keeping the bitmap in the same
+   *   - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but can
+   *   specify a BGR panel instead, while keeping the bitmap in the same
    *   RGB888 format.
    *
    *   - {{0, 21}, {0, 0}, {0, -21}} is the vertical RGB, but the bitmap
@@ -305,9 +300,9 @@
    *
    *   - {{-11, 16}, {-11, -16}, {22, 0}} is a certain PenTile arrangement.
    *
-   *   This function does nothing and returns `FT_Err_Unimplemented_Feature'
+   *   This function does nothing and returns `FT_Err_Unimplemented_Feature`
    *   in the context of ClearType-style subpixel rendering when
-   *   FT_CONFIG_OPTION_SUBPIXEL_RENDERING is defined in your build of the
+   *   `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is defined in your build of the
    *   library.
    *
    * @since:
diff --git a/include/freetype/ftlist.h b/include/freetype/ftlist.h
index cdea897..b553131 100644
--- a/include/freetype/ftlist.h
+++ b/include/freetype/ftlist.h
@@ -4,7 +4,7 @@
  *
  *   Generic list support for FreeType (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,8 +18,8 @@
 
   /**************************************************************************
    *
-   * This file implements functions relative to list processing.  Its
-   * data structures are defined in `freetype.h'.
+   * This file implements functions relative to list processing.  Its data
+   * structures are defined in `freetype.h`.
    *
    */
 
@@ -28,8 +28,7 @@
 #define FTLIST_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -53,8 +52,8 @@
    *   Simple management of lists.
    *
    * @description:
-   *   This section contains various definitions related to list
-   *   processing using doubly-linked nodes.
+   *   This section contains various definitions related to list processing
+   *   using doubly-linked nodes.
    *
    * @order:
    *   FT_List
@@ -90,7 +89,7 @@
    *     The address of the listed object.
    *
    * @return:
-   *   List node.  NULL if it wasn't found.
+   *   List node.  `NULL` if it wasn't found.
    */
   FT_EXPORT( FT_ListNode )
   FT_List_Find( FT_List  list,
@@ -141,8 +140,8 @@
    *   FT_List_Remove
    *
    * @description:
-   *   Remove a node from a list.  This function doesn't check whether
-   *   the node is in the list!
+   *   Remove a node from a list.  This function doesn't check whether the
+   *   node is in the list!
    *
    * @input:
    *   node ::
@@ -163,8 +162,7 @@
    *   FT_List_Up
    *
    * @description:
-   *   Move a node to the head/top of a list.  Used to maintain LRU
-   *   lists.
+   *   Move a node to the head/top of a list.  Used to maintain LRU lists.
    *
    * @inout:
    *   list ::
@@ -183,16 +181,16 @@
    *   FT_List_Iterator
    *
    * @description:
-   *   An FT_List iterator function that is called during a list parse
-   *   by @FT_List_Iterate.
+   *   An FT_List iterator function that is called during a list parse by
+   *   @FT_List_Iterate.
    *
    * @input:
    *   node ::
    *     The current iteration list node.
    *
    *   user ::
-   *     A typeless pointer passed to @FT_List_Iterate.
-   *     Can be used to point to the iteration's state.
+   *     A typeless pointer passed to @FT_List_Iterate.  Can be used to point
+   *     to the iteration's state.
    */
   typedef FT_Error
   (*FT_List_Iterator)( FT_ListNode  node,
@@ -215,8 +213,8 @@
    *   iterator ::
    *     An iterator function, called on each node of the list.
    *   user ::
-   *     A user-supplied field that is passed as the second
-   *     argument to the iterator.
+   *     A user-supplied field that is passed as the second argument to the
+   *     iterator.
    *
    * @return:
    *   The result (a FreeType error code) of the last iterator call.
@@ -234,8 +232,8 @@
    *
    * @description:
    *   An @FT_List iterator function that is called during a list
-   *   finalization by @FT_List_Finalize to destroy all elements in a
-   *   given list.
+   *   finalization by @FT_List_Finalize to destroy all elements in a given
+   *   list.
    *
    * @input:
    *   system ::
@@ -245,8 +243,8 @@
    *     The current object to destroy.
    *
    *   user ::
-   *     A typeless pointer passed to @FT_List_Iterate.  It can
-   *     be used to point to the iteration's state.
+   *     A typeless pointer passed to @FT_List_Iterate.  It can be used to
+   *     point to the iteration's state.
    */
   typedef void
   (*FT_List_Destructor)( FT_Memory  memory,
@@ -267,15 +265,15 @@
    *     A handle to the list.
    *
    *   destroy ::
-   *     A list destructor that will be applied to each element
-   *     of the list.  Set this to NULL if not needed.
+   *     A list destructor that will be applied to each element of the list.
+   *     Set this to `NULL` if not needed.
    *
    *   memory ::
    *     The current memory object that handles deallocation.
    *
    *   user ::
-   *     A user-supplied field that is passed as the last
-   *     argument to the destructor.
+   *     A user-supplied field that is passed as the last argument to the
+   *     destructor.
    *
    * @note:
    *   This function expects that all nodes added by @FT_List_Add or
diff --git a/include/freetype/ftlogging.h b/include/freetype/ftlogging.h
new file mode 100644
index 0000000..2246dc8
--- /dev/null
+++ b/include/freetype/ftlogging.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+ *
+ * ftlogging.h
+ *
+ *   Additional debugging APIs.
+ *
+ * Copyright (C) 2020-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 FTLOGGING_H_
+#define FTLOGGING_H_
+
+
+#include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   debugging_apis
+   *
+   * @title:
+   *   External Debugging APIs
+   *
+   * @abstract:
+   *   Public APIs to control the `FT_DEBUG_LOGGING` macro.
+   *
+   * @description:
+   *   This section contains the declarations of public functions that
+   *   enables fine control of what the `FT_DEBUG_LOGGING` macro outputs.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Trace_Set_Level
+   *
+   * @description:
+   *   Change the levels of tracing components of FreeType at run time.
+   *
+   * @input:
+   *   tracing_level ::
+   *     New tracing value.
+   *
+   * @example:
+   *   The following call makes FreeType trace everything but the 'memory'
+   *   component.
+   *
+   *   ```
+   *   FT_Trace_Set_Level( "any:7 memory:0 );
+   *   ```
+   *
+   * @note:
+   *   This function does nothing if compilation option `FT_DEBUG_LOGGING`
+   *   isn't set.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+  FT_EXPORT( void )
+  FT_Trace_Set_Level( const char*  tracing_level );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Trace_Set_Default_Level
+   *
+   * @description:
+   *   Reset tracing value of FreeType's components to the default value
+   *   (i.e., to the value of the `FT2_DEBUG` environment value or to NULL
+   *   if `FT2_DEBUG` is not set).
+   *
+   * @note:
+   *   This function does nothing if compilation option `FT_DEBUG_LOGGING`
+   *   isn't set.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+  FT_EXPORT( void )
+  FT_Trace_Set_Default_Level( void );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   FT_Custom_Log_Handler
+   *
+   * @description:
+   *   A function typedef that is used to handle the logging of tracing and
+   *   debug messages on a file system.
+   *
+   * @input:
+   *   ft_component ::
+   *     The name of `FT_COMPONENT` from which the current debug or error
+   *     message is produced.
+   *
+   *   fmt ::
+   *     Actual debug or tracing message.
+   *
+   *   args::
+   *     Arguments of debug or tracing messages.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+  typedef void
+  (*FT_Custom_Log_Handler)( const char*  ft_component,
+                            const char*  fmt,
+                            va_list      args );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Set_Log_Handler
+   *
+   * @description:
+   *   A function to set a custom log handler.
+   *
+   * @input:
+   *   handler ::
+   *     New logging function.
+   *
+   * @note:
+   *   This function does nothing if compilation option `FT_DEBUG_LOGGING`
+   *   isn't set.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+  FT_EXPORT( void )
+  FT_Set_Log_Handler( FT_Custom_Log_Handler  handler );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Set_Default_Log_Handler
+   *
+   * @description:
+   *   A function to undo the effect of @FT_Set_Log_Handler, resetting the
+   *   log handler to FreeType's built-in version.
+   *
+   * @note:
+   *   This function does nothing if compilation option `FT_DEBUG_LOGGING`
+   *   isn't set.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+  FT_EXPORT( void )
+  FT_Set_Default_Log_Handler( void );
+
+  /* */
+
+
+FT_END_HEADER
+
+#endif /* FTLOGGING_H_ */
+
+
+/* END */
diff --git a/include/freetype/ftlzw.h b/include/freetype/ftlzw.h
index 01433ca..adfd172 100644
--- a/include/freetype/ftlzw.h
+++ b/include/freetype/ftlzw.h
@@ -4,7 +4,7 @@
  *
  *   LZW-compressed stream support.
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTLZW_H_
 #define FTLZW_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -43,19 +42,28 @@
    *   Using LZW-compressed font files.
    *
    * @description:
+   *   In certain builds of the library, LZW compression recognition is
+   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
+   *   This means that if no font driver is capable of handling the raw
+   *   compressed file, the library will try to open a LZW stream from it and
+   *   re-open the face with it.
+   *
+   *   The stream implementation is very basic and resets the decompression
+   *   process each time seeking backwards is needed within the stream,
+   *   which significantly undermines the performance.
+   *
    *   This section contains the declaration of LZW-specific functions.
    *
    */
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stream_OpenLZW
    *
    * @description:
-   *   Open a new stream to parse LZW-compressed font files.  This is
-   *   mainly used to support the compressed `*.pcf.Z' fonts that come
-   *   with XFree86.
+   *   Open a new stream to parse LZW-compressed font files.  This is mainly
+   *   used to support the compressed `*.pcf.Z` fonts that come with XFree86.
    *
    * @input:
    *   stream ::
@@ -70,20 +78,11 @@
    * @note:
    *   The source stream must be opened _before_ calling this function.
    *
-   *   Calling the internal function `FT_Stream_Close' on the new stream will
-   *   *not* call `FT_Stream_Close' on the source stream.  None of the stream
-   *   objects will be released to the heap.
+   *   Calling the internal function `FT_Stream_Close` on the new stream will
+   *   **not** call `FT_Stream_Close` on the source stream.  None of the
+   *   stream objects will be released to the heap.
    *
-   *   The stream implementation is very basic and resets the decompression
-   *   process each time seeking backwards is needed within the stream
-   *
-   *   In certain builds of the library, LZW compression recognition is
-   *   automatically handled when calling @FT_New_Face or @FT_Open_Face.
-   *   This means that if no font driver is capable of handling the raw
-   *   compressed file, the library will try to open a LZW stream from it
-   *   and re-open the face with it.
-   *
-   *   This function may return `FT_Err_Unimplemented_Feature' if your build
+   *   This function may return `FT_Err_Unimplemented_Feature` if your build
    *   of FreeType was not compiled with LZW support.
    */
   FT_EXPORT( FT_Error )
diff --git a/include/freetype/ftmac.h b/include/freetype/ftmac.h
index 4249ff5..a91e38f 100644
--- a/include/freetype/ftmac.h
+++ b/include/freetype/ftmac.h
@@ -4,7 +4,7 @@
  *
  *   Additional Mac-specific API.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,9 +18,9 @@
 
 /****************************************************************************
  *
- * NOTE: Include this file after FT_FREETYPE_H and after any
+ * NOTE: Include this file after `FT_FREETYPE_H` and after any
  *       Mac-specific headers (because this header uses Mac types such as
- *       Handle, FSSpec, FSRef, etc.)
+ *       'Handle', 'FSSpec', 'FSRef', etc.)
  *
  */
 
@@ -29,7 +29,6 @@
 #define FTMAC_H_
 
 
-#include <ft2build.h>
 
 
 FT_BEGIN_HEADER
@@ -59,8 +58,8 @@
    *   Only available on the Macintosh.
    *
    * @description:
-   *   The following definitions are only available if FreeType is
-   *   compiled on a Macintosh.
+   *   The following definitions are only available if FreeType is compiled
+   *   on a Macintosh.
    *
    */
 
@@ -82,8 +81,7 @@
    *     A FOND resource.
    *
    *   face_index ::
-   *     Only supported for the -1 `sanity check' special
-   *     case.
+   *     Only supported for the -1 'sanity check' special case.
    *
    * @output:
    *   aface ::
@@ -93,13 +91,13 @@
    *   FreeType error code.  0~means success.
    *
    * @example:
-   *   This function can be used to create @FT_Face objects from fonts
-   *   that are installed in the system as follows.
+   *   This function can be used to create @FT_Face objects from fonts that
+   *   are installed in the system as follows.
    *
-   *   {
+   *   ```
    *     fond  = GetResource( 'FOND', fontName );
    *     error = FT_New_Face_From_FOND( library, fond, 0, &face );
-   *   }
+   *   ```
    */
   FT_EXPORT( FT_Error )
   FT_New_Face_From_FOND( FT_Library  library,
@@ -119,17 +117,14 @@
    *
    * @input:
    *   fontName ::
-   *     Mac OS name of the font (e.g., Times New Roman
-   *     Bold).
+   *     Mac OS name of the font (e.g., Times New Roman Bold).
    *
    * @output:
    *   pathSpec ::
-   *     FSSpec to the file.  For passing to
-   *     @FT_New_Face_From_FSSpec.
+   *     FSSpec to the file.  For passing to @FT_New_Face_From_FSSpec.
    *
    *   face_index ::
-   *     Index of the face.  For passing to
-   *     @FT_New_Face_From_FSSpec.
+   *     Index of the face.  For passing to @FT_New_Face_From_FSSpec.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -155,12 +150,10 @@
    *
    * @output:
    *   pathSpec ::
-   *     FSSpec to the file. For passing to
-   *     @FT_New_Face_From_FSSpec.
+   *     FSSpec to the file. For passing to @FT_New_Face_From_FSSpec.
    *
    *   face_index ::
-   *     Index of the face. For passing to
-   *     @FT_New_Face_From_FSSpec.
+   *     Index of the face. For passing to @FT_New_Face_From_FSSpec.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -178,8 +171,8 @@
    *   FT_GetFilePath_From_Mac_ATS_Name
    *
    * @description:
-   *   Return a pathname of the disk file and face index for given font
-   *   name that is handled by ATS framework.
+   *   Return a pathname of the disk file and face index for given font name
+   *   that is handled by ATS framework.
    *
    * @input:
    *   fontName ::
@@ -187,12 +180,11 @@
    *
    * @output:
    *   path ::
-   *     Buffer to store pathname of the file.  For passing
-   *     to @FT_New_Face.  The client must allocate this
-   *     buffer before calling this function.
+   *     Buffer to store pathname of the file.  For passing to @FT_New_Face.
+   *     The client must allocate this buffer before calling this function.
    *
    *   maxPathSize ::
-   *     Lengths of the buffer `path' that client allocated.
+   *     Lengths of the buffer `path` that client allocated.
    *
    *   face_index ::
    *     Index of the face.  For passing to @FT_New_Face.
@@ -226,8 +218,8 @@
    *     FSSpec to the font file.
    *
    *   face_index ::
-   *     The index of the face within the resource.  The
-   *     first face has index~0.
+   *     The index of the face within the resource.  The first face has
+   *     index~0.
    * @output:
    *   aface ::
    *     A handle to a new face object.
@@ -236,8 +228,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   @FT_New_Face_From_FSSpec is identical to @FT_New_Face except
-   *   it accepts an FSSpec instead of a path.
+   *   @FT_New_Face_From_FSSpec is identical to @FT_New_Face except it
+   *   accepts an FSSpec instead of a path.
    */
   FT_EXPORT( FT_Error )
   FT_New_Face_From_FSSpec( FT_Library     library,
@@ -265,8 +257,8 @@
    *     FSRef to the font file.
    *
    *   face_index ::
-   *     The index of the face within the resource.  The
-   *     first face has index~0.
+   *     The index of the face within the resource.  The first face has
+   *     index~0.
    * @output:
    *   aface ::
    *     A handle to a new face object.
@@ -275,8 +267,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   @FT_New_Face_From_FSRef is identical to @FT_New_Face except
-   *   it accepts an FSRef instead of a path.
+   *   @FT_New_Face_From_FSRef is identical to @FT_New_Face except it accepts
+   *   an FSRef instead of a path.
    */
   FT_EXPORT( FT_Error )
   FT_New_Face_From_FSRef( FT_Library    library,
diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h
index a903241..e381ef3 100644
--- a/include/freetype/ftmm.h
+++ b/include/freetype/ftmm.h
@@ -4,7 +4,7 @@
  *
  *   FreeType Multiple Master font interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTMM_H_
 
 
-#include <ft2build.h>
-#include FT_TYPE1_TABLES_H
+#include <freetype/t1tables.h>
 
 
 FT_BEGIN_HEADER
@@ -39,14 +38,17 @@
    *   How to manage Multiple Masters fonts.
    *
    * @description:
-   *   The following types and functions are used to manage Multiple
-   *   Master fonts, i.e., the selection of specific design instances by
-   *   setting design axis coordinates.
+   *   The following types and functions are used to manage Multiple Master
+   *   fonts, i.e., the selection of specific design instances by setting
+   *   design axis coordinates.
    *
-   *   Besides Adobe MM fonts, the interface supports Apple's TrueType GX
-   *   and OpenType variation fonts.  Some of the routines only work with
-   *   Adobe MM fonts, others will work with all three types.  They are
-   *   similar enough that a consistent interface makes sense.
+   *   Besides Adobe MM fonts, the interface supports Apple's TrueType GX and
+   *   OpenType variation fonts.  Some of the routines only work with Adobe
+   *   MM fonts, others will work with all three types.  They are similar
+   *   enough that a consistent interface makes sense.
+   *
+   *   For Adobe MM fonts, macro @FT_IS_SFNT returns false.  For GX and
+   *   OpenType variation fonts, it returns true.
    *
    */
 
@@ -57,8 +59,8 @@
    *   FT_MM_Axis
    *
    * @description:
-   *   A structure to model a given axis in design space for Multiple
-   *   Masters fonts.
+   *   A structure to model a given axis in design space for Multiple Masters
+   *   fonts.
    *
    *   This structure can't be used for TrueType GX or OpenType variation
    *   fonts.
@@ -88,8 +90,7 @@
    *   FT_Multi_Master
    *
    * @description:
-   *   A structure to model the axes and space of a Multiple Masters
-   *   font.
+   *   A structure to model the axes and space of a Multiple Masters font.
    *
    *   This structure can't be used for TrueType GX or OpenType variation
    *   fonts.
@@ -99,10 +100,9 @@
    *     Number of axes.  Cannot exceed~4.
    *
    *   num_designs ::
-   *     Number of designs; should be normally 2^num_axis
-   *     even though the Type~1 specification strangely
-   *     allows for intermediate designs to be present.
-   *     This number cannot exceed~16.
+   *     Number of designs; should be normally 2^num_axis even though the
+   *     Type~1 specification strangely allows for intermediate designs to be
+   *     present.  This number cannot exceed~16.
    *
    *   axis ::
    *     A table of axis descriptors.
@@ -127,36 +127,33 @@
    *
    * @fields:
    *   name ::
-   *     The axis's name.
-   *     Not always meaningful for TrueType GX or OpenType
+   *     The axis's name.  Not always meaningful for TrueType GX or OpenType
    *     variation fonts.
    *
    *   minimum ::
    *     The axis's minimum design coordinate.
    *
    *   def ::
-   *     The axis's default design coordinate.
-   *     FreeType computes meaningful default values for Adobe
-   *     MM fonts.
+   *     The axis's default design coordinate.  FreeType computes meaningful
+   *     default values for Adobe MM fonts.
    *
    *   maximum ::
    *     The axis's maximum design coordinate.
    *
    *   tag ::
-   *     The axis's tag (the equivalent to `name' for TrueType
-   *     GX and OpenType variation fonts).  FreeType provides
-   *     default values for Adobe MM fonts if possible.
+   *     The axis's tag (the equivalent to 'name' for TrueType GX and
+   *     OpenType variation fonts).  FreeType provides default values for
+   *     Adobe MM fonts if possible.
    *
    *   strid ::
-   *     The axis name entry in the font's `name' table.  This
-   *     is another (and often better) version of the `name'
-   *     field for TrueType GX or OpenType variation fonts.  Not
-   *     meaningful for Adobe MM fonts.
+   *     The axis name entry in the font's 'name' table.  This is another
+   *     (and often better) version of the 'name' field for TrueType GX or
+   *     OpenType variation fonts.  Not meaningful for Adobe MM fonts.
    *
    * @note:
-   *   The fields `minimum', `def', and `maximum' are 16.16 fractional
-   *   values for TrueType GX and OpenType variation fonts.  For Adobe MM
-   *   fonts, the values are integers.
+   *   The fields `minimum`, `def`, and `maximum` are 16.16 fractional values
+   *   for TrueType GX and OpenType variation fonts.  For Adobe MM fonts, the
+   *   values are integers.
    */
   typedef struct  FT_Var_Axis_
   {
@@ -185,16 +182,15 @@
    *
    * @fields:
    *   coords ::
-   *     The design coordinates for this instance.
-   *     This is an array with one entry for each axis.
+   *     The design coordinates for this instance.  This is an array with one
+   *     entry for each axis.
    *
    *   strid ::
-   *     The entry in `name' table identifying this instance.
+   *     The entry in 'name' table identifying this instance.
    *
    *   psid ::
-   *     The entry in `name' table identifying a PostScript name
-   *     for this instance.  Value 0xFFFF indicates a missing
-   *     entry.
+   *     The entry in 'name' table identifying a PostScript name for this
+   *     instance.  Value 0xFFFF indicates a missing entry.
    */
   typedef struct  FT_Var_Named_Style_
   {
@@ -211,48 +207,40 @@
    *   FT_MM_Var
    *
    * @description:
-   *   A structure to model the axes and space of an Adobe MM, TrueType
-   *   GX, or OpenType variation font.
+   *   A structure to model the axes and space of an Adobe MM, TrueType GX,
+   *   or OpenType variation font.
    *
    *   Some fields are specific to one format and not to the others.
    *
    * @fields:
    *   num_axis ::
-   *     The number of axes.  The maximum value is~4 for
-   *     Adobe MM fonts; no limit in TrueType GX or
-   *     OpenType variation fonts.
+   *     The number of axes.  The maximum value is~4 for Adobe MM fonts; no
+   *     limit in TrueType GX or OpenType variation fonts.
    *
    *   num_designs ::
-   *     The number of designs; should be normally
-   *     2^num_axis for Adobe MM fonts.  Not meaningful
-   *     for TrueType GX or OpenType variation fonts
-   *     (where every glyph could have a different
-   *     number of designs).
+   *     The number of designs; should be normally 2^num_axis for Adobe MM
+   *     fonts.  Not meaningful for TrueType GX or OpenType variation fonts
+   *     (where every glyph could have a different number of designs).
    *
    *   num_namedstyles ::
-   *     The number of named styles; a `named style' is
-   *     a tuple of design coordinates that has a string
-   *     ID (in the `name' table) associated with it.
-   *     The font can tell the user that, for example,
-   *     [Weight=1.5,Width=1.1] is `Bold'.  Another name
-   *     for `named style' is `named instance'.
+   *     The number of named styles; a 'named style' is a tuple of design
+   *     coordinates that has a string ID (in the 'name' table) associated
+   *     with it.  The font can tell the user that, for example,
+   *     [Weight=1.5,Width=1.1] is 'Bold'.  Another name for 'named style' is
+   *     'named instance'.
    *
-   *     For Adobe Multiple Masters fonts, this value is
-   *     always zero because the format does not support
-   *     named styles.
+   *     For Adobe Multiple Masters fonts, this value is always zero because
+   *     the format does not support named styles.
    *
    *   axis ::
-   *     An axis descriptor table.
-   *     TrueType GX and OpenType variation fonts
-   *     contain slightly more data than Adobe MM fonts.
-   *     Memory management of this pointer is done
-   *     internally by FreeType.
+   *     An axis descriptor table.  TrueType GX and OpenType variation fonts
+   *     contain slightly more data than Adobe MM fonts.  Memory management
+   *     of this pointer is done internally by FreeType.
    *
    *   namedstyle ::
-   *     A named style (instance) table.
-   *     Only meaningful for TrueType GX and OpenType
-   *     variation fonts.  Memory management of this
-   *     pointer is done internally by FreeType.
+   *     A named style (instance) table.  Only meaningful for TrueType GX and
+   *     OpenType variation fonts.  Memory management of this pointer is done
+   *     internally by FreeType.
    */
   typedef struct  FT_MM_Var_
   {
@@ -308,9 +296,8 @@
    *
    * @output:
    *   amaster ::
-   *     The variation descriptor.
-   *     Allocates a data structure, which the user must
-   *     deallocate with a call to @FT_Done_MM_Var after use.
+   *     The variation descriptor.  Allocates a data structure, which the
+   *     user must deallocate with a call to @FT_Done_MM_Var after use.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -330,8 +317,8 @@
    *
    * @input:
    *   library ::
-   *     A handle of the face's parent library object that was
-   *     used in the call to @FT_Get_MM_Var to create `amaster'.
+   *     A handle of the face's parent library object that was used in the
+   *     call to @FT_Get_MM_Var to create `amaster`.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -347,8 +334,8 @@
    *   FT_Set_MM_Design_Coordinates
    *
    * @description:
-   *   For Adobe MM fonts, choose an interpolated font design through
-   *   design coordinates.
+   *   For Adobe MM fonts, choose an interpolated font design through design
+   *   coordinates.
    *
    *   This function can't be used with TrueType GX or OpenType variation
    *   fonts.
@@ -359,10 +346,9 @@
    *
    * @input:
    *   num_coords ::
-   *     The number of available design coordinates.  If it
-   *     is larger than the number of axes, ignore the excess
-   *     values.  If it is smaller than the number of axes,
-   *     use default values for the remaining axes.
+   *     The number of available design coordinates.  If it is larger than
+   *     the number of axes, ignore the excess values.  If it is smaller than
+   *     the number of axes, use default values for the remaining axes.
    *
    *   coords ::
    *     An array of design coordinates.
@@ -372,12 +358,12 @@
    *
    * @note:
    *   [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.
+   *   function with `num_coords` set to zero and `coords` set to `NULL`.
    *
-   *   [Since 2.9] If `num_coords' 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 `num_coords'
-   *   is zero, this bit flag gets unset.
+   *   [Since 2.9] If `num_coords` 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 `num_coords` is zero,
+   *   this bit flag gets unset.
    */
   FT_EXPORT( FT_Error )
   FT_Set_MM_Design_Coordinates( FT_Face   face,
@@ -401,10 +387,9 @@
    *
    * @input:
    *   num_coords ::
-   *     The number of available design coordinates.  If it
-   *     is larger than the number of axes, ignore the excess
-   *     values.  If it is smaller than the number of axes,
-   *     use default values for the remaining axes.
+   *     The number of available design coordinates.  If it is larger than
+   *     the number of axes, ignore the excess values.  If it is smaller than
+   *     the number of axes, use default values for the remaining axes.
    *
    *   coords ::
    *     An array of design coordinates.
@@ -413,15 +398,19 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
+   *   The design coordinates are 16.16 fractional values for TrueType GX and
+   *   OpenType variation fonts.  For Adobe MM fonts, the values are
+   *   integers.
+   *
    *   [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.
-   *   [Since 2.9] `Default values' means the currently selected named
+   *   function with `num_coords` set to zero and `coords` set to `NULL`.
+   *   [Since 2.9] 'Default values' means the currently selected named
    *   instance (or the base font if no named instance is selected).
    *
-   *   [Since 2.9] If `num_coords' 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 `num_coords'
-   *   is zero, this bit flag gets unset.
+   *   [Since 2.9] If `num_coords` 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 `num_coords` is zero,
+   *   this bit flag gets unset.
    */
   FT_EXPORT( FT_Error )
   FT_Set_Var_Design_Coordinates( FT_Face    face,
@@ -445,9 +434,8 @@
    *     A handle to the source face.
    *
    *   num_coords ::
-   *     The number of design coordinates to retrieve.  If it
-   *     is larger than the number of axes, set the excess
-   *     values to~0.
+   *     The number of design coordinates to retrieve.  If it is larger than
+   *     the number of axes, set the excess values to~0.
    *
    * @output:
    *   coords ::
@@ -456,6 +444,11 @@
    * @return:
    *   FreeType error code.  0~means success.
    *
+   * @note:
+   *   The design coordinates are 16.16 fractional values for TrueType GX and
+   *   OpenType variation fonts.  For Adobe MM fonts, the values are
+   *   integers.
+   *
    * @since:
    *   2.7.1
    */
@@ -482,30 +475,28 @@
    *
    * @input:
    *   num_coords ::
-   *     The number of available design coordinates.  If it
-   *     is larger than the number of axes, ignore the excess
-   *     values.  If it is smaller than the number of axes,
-   *     use default values for the remaining axes.
+   *     The number of available design coordinates.  If it is larger than
+   *     the number of axes, ignore the excess values.  If it is smaller than
+   *     the number of axes, use default values for the remaining axes.
    *
    *   coords ::
-   *     The design coordinates array (each element must be
-   *     between 0 and 1.0 for Adobe MM fonts, and between
-   *     -1.0 and 1.0 for TrueType GX and OpenType variation
-   *     fonts).
+   *     The design coordinates array.  Each element is a 16.16 fractional
+   *     value and must be between 0 and 1.0 for Adobe MM fonts, and between
+   *     -1.0 and 1.0 for TrueType GX and OpenType variation fonts.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
    *   [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.
-   *   [Since 2.9] `Default values' means the currently selected named
+   *   function with `num_coords` set to zero and `coords` set to `NULL`.
+   *   [Since 2.9] 'Default values' means the currently selected named
    *   instance (or the base font if no named instance is selected).
    *
-   *   [Since 2.9] If `num_coords' 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 `num_coords'
-   *   is zero, this bit flag gets unset.
+   *   [Since 2.9] If `num_coords` 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 `num_coords` is zero,
+   *   this bit flag gets unset.
    */
   FT_EXPORT( FT_Error )
   FT_Set_MM_Blend_Coordinates( FT_Face    face,
@@ -529,14 +520,14 @@
    *     A handle to the source face.
    *
    *   num_coords ::
-   *     The number of normalized blend coordinates to
-   *     retrieve.  If it is larger than the number of axes,
-   *     set the excess values to~0.5 for Adobe MM fonts, and
-   *     to~0 for TrueType GX and OpenType variation fonts.
+   *     The number of normalized blend coordinates to retrieve.  If it is
+   *     larger than the number of axes, set the excess values to~0.5 for
+   *     Adobe MM fonts, and to~0 for TrueType GX and OpenType variation
+   *     fonts.
    *
    * @output:
    *   coords ::
-   *     The normalized blend coordinates array.
+   *     The normalized blend coordinates array (as 16.16 fractional values).
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -583,6 +574,98 @@
 
   /**************************************************************************
    *
+   * @function:
+   *   FT_Set_MM_WeightVector
+   *
+   * @description:
+   *   For Adobe MM fonts, choose an interpolated font design by directly
+   *   setting the weight vector.
+   *
+   *   This function can't be used with TrueType GX or OpenType variation
+   *   fonts.
+   *
+   * @inout:
+   *   face ::
+   *     A handle to the source face.
+   *
+   * @input:
+   *   len ::
+   *     The length of the weight vector array.  If it is larger than the
+   *     number of designs, the extra values are ignored.  If it is less than
+   *     the number of designs, the remaining values are set to zero.
+   *
+   *   weightvector ::
+   *     An array representing the weight vector.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   Adobe Multiple Master fonts limit the number of designs, and thus the
+   *   length of the weight vector to~16.
+   *
+   *   If `len` is zero and `weightvector` is `NULL`, 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
+   *   not seem to be enforced, so is not enforced here, either.
+   *
+   * @since:
+   *   2.10
+   */
+  FT_EXPORT( FT_Error )
+  FT_Set_MM_WeightVector( FT_Face    face,
+                          FT_UInt    len,
+                          FT_Fixed*  weightvector );
+
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_MM_WeightVector
+   *
+   * @description:
+   *   For Adobe MM fonts, retrieve the current weight vector of the font.
+   *
+   *   This function can't be used with TrueType GX or OpenType variation
+   *   fonts.
+   *
+   * @inout:
+   *   face ::
+   *     A handle to the source face.
+   *
+   *   len ::
+   *     A pointer to the size of the array to be filled.  If the size of the
+   *     array is less than the number of designs, `FT_Err_Invalid_Argument`
+   *     is returned, and `len` is set to the required size (the number of
+   *     designs).  If the size of the array is greater than the number of
+   *     designs, the remaining entries are set to~0.  On successful
+   *     completion, `len` is set to the number of designs (i.e., the number
+   *     of values written to the array).
+   *
+   * @output:
+   *   weightvector ::
+   *     An array to be filled.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   Adobe Multiple Master fonts limit the number of designs, and thus the
+   *   length of the WeightVector to~16.
+   *
+   * @since:
+   *   2.10
+   */
+  FT_EXPORT( FT_Error )
+  FT_Get_MM_WeightVector( FT_Face    face,
+                          FT_UInt*   len,
+                          FT_Fixed*  weightvector );
+
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_VAR_AXIS_FLAG_XXX
    *
@@ -606,9 +689,9 @@
    *   FT_Get_Var_Axis_Flags
    *
    * @description:
-   *   Get the `flags' field of an OpenType Variation Axis Record.
+   *   Get the 'flags' field of an OpenType Variation Axis Record.
    *
-   *   Not meaningful for Adobe MM fonts (`*flags' is always zero).
+   *   Not meaningful for Adobe MM fonts (`*flags` is always zero).
    *
    * @input:
    *   master ::
@@ -619,8 +702,7 @@
    *
    * @output:
    *   flags ::
-   *     The `flags' field.  See @FT_VAR_AXIS_FLAG_XXX for
-   *     possible values.
+   *     The 'flags' field.  See @FT_VAR_AXIS_FLAG_XXX for possible values.
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -647,23 +729,22 @@
    *     A handle to the source face.
    *
    *   instance_index ::
-   *     The index of the requested instance, starting
-   *     with value 1.  If set to value 0, FreeType
-   *     switches to font access without a named
+   *     The index of the requested instance, starting with value 1.  If set
+   *     to value 0, FreeType switches to font access without a named
    *     instance.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The function uses the value of `instance_index' to set bits 16-30
-   *   of the face's `face_index' field.  It also resets any variation
-   *   applied to the font, and the @FT_FACE_FLAG_VARIATION bit of the
-   *   face's `face_flags' field gets reset to zero (i.e.,
-   *   @FT_IS_VARIATION will return false).
+   *   The function uses the value of `instance_index` to set bits 16-30 of
+   *   the face's `face_index` field.  It also resets any variation applied
+   *   to the font, and the @FT_FACE_FLAG_VARIATION bit of the face's
+   *   `face_flags` field gets reset to zero (i.e., @FT_IS_VARIATION will
+   *   return false).
    *
-   *   For Adobe MM fonts (which don't have named instances) this
-   *   function simply resets the current face to the default instance.
+   *   For Adobe MM fonts (which don't have named instances) this function
+   *   simply resets the current face to the default instance.
    *
    * @since:
    *   2.9
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index c50c9ce..c8f0c2c 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -4,7 +4,7 @@
  *
  *   FreeType modules public interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTMODAPI_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -46,13 +45,15 @@
    *
    * @description:
    *   The definitions below are used to manage modules within FreeType.
-   *   Modules can be added, upgraded, and removed at runtime.
-   *   Additionally, some module properties can be controlled also.
+   *   Internal and external modules can be added, upgraded, and removed at
+   *   runtime.  For example, an alternative renderer or proprietary font
+   *   driver can be registered and prioritized.  Additionally, some module
+   *   properties can also be controlled.
    *
-   *   Here is a list of possible values of the `module_name' field in
-   *   the @FT_Module_Class structure.
+   *   Here is a list of existing values of the `module_name` field in the
+   *   @FT_Module_Class structure.
    *
-   *   {
+   *   ```
    *     autofitter
    *     bdf
    *     cff
@@ -65,13 +66,13 @@
    *     psnames
    *     raster1
    *     sfnt
-   *     smooth, smooth-lcd, smooth-lcdv
+   *     smooth
    *     truetype
    *     type1
    *     type42
    *     t1cid
    *     winfonts
-   *   }
+   *   ```
    *
    *   Note that the FreeType Cache sub-system is not a FreeType module.
    *
@@ -87,6 +88,7 @@
    *   FT_Remove_Module
    *   FT_Add_Default_Modules
    *
+   *   FT_FACE_DRIVER_NAME
    *   FT_Property_Set
    *   FT_Property_Get
    *   FT_Set_Default_Properties
@@ -195,9 +197,9 @@
    *   FT_Module_Class
    *
    * @description:
-   *   The module class descriptor.  While being a public structure
-   *   necessary for FreeType's module bookkeeping, most of the fields are
-   *   essentially internal, not to be used directly by an application.
+   *   The module class descriptor.  While being a public structure necessary
+   *   for FreeType's module bookkeeping, most of the fields are essentially
+   *   internal, not to be used directly by an application.
    *
    * @fields:
    *   module_flags ::
@@ -219,7 +221,7 @@
    *   module_interface ::
    *     A typeless pointer to a structure (which varies between different
    *     modules) that holds the module's interface functions.  This is
-   *     essentially what `get_interface' returns.
+   *     essentially what `get_interface` returns.
    *
    *   module_init ::
    *     The initializing function.
@@ -267,8 +269,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   An error will be returned if a module already exists by that name,
-   *   or if the module requires a version of FreeType that is too great.
+   *   An error will be returned if a module already exists by that name, or
+   *   if the module requires a version of FreeType that is too great.
    */
   FT_EXPORT( FT_Error )
   FT_Add_Module( FT_Library              library,
@@ -329,7 +331,28 @@
                     FT_Module   module );
 
 
-  /**********************************************************************
+  /**************************************************************************
+   *
+   * @macro:
+   *   FT_FACE_DRIVER_NAME
+   *
+   * @description:
+   *   A macro that retrieves the name of a font driver from a face object.
+   *
+   * @note:
+   *   The font driver name is a valid `module_name` for @FT_Property_Set
+   *   and @FT_Property_Get.  This is not the same as @FT_Get_Font_Format.
+   *
+   * @since:
+   *   2.11
+   *
+   */
+#define FT_FACE_DRIVER_NAME( face )                                     \
+          ( ( *FT_REINTERPRET_CAST( FT_Module_Class**,                  \
+                                    ( face )->driver ) )->module_name )
+
+
+  /**************************************************************************
    *
    * @function:
    *    FT_Property_Set
@@ -352,37 +375,35 @@
    *
    *    value ::
    *      A generic pointer to a variable or structure that gives the new
-   *      value of the property.  The exact definition of `value' is
+   *      value of the property.  The exact definition of `value` is
    *      dependent on the property; see section @properties.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *    If `module_name' isn't a valid module name, or `property_name'
-   *    doesn't specify a valid property, or if `value' doesn't represent a
+   *    If `module_name` isn't a valid module name, or `property_name`
+   *    doesn't specify a valid property, or if `value` doesn't represent a
    *    valid value for the given property, an error is returned.
    *
-   *    The following example sets property `bar' (a simple integer) in
-   *    module `foo' to value~1.
+   *    The following example sets property 'bar' (a simple integer) in
+   *    module 'foo' to value~1.
    *
-   *    {
+   *    ```
    *      FT_UInt  bar;
    *
    *
    *      bar = 1;
    *      FT_Property_Set( library, "foo", "bar", &bar );
-   *    }
+   *    ```
    *
    *    Note that the FreeType Cache sub-system doesn't recognize module
    *    property changes.  To avoid glyph lookup confusion within the cache
-   *    you should call @FTC_Manager_Reset to completely flush the cache if
-   *    a module property gets changed after @FTC_Manager_New has been
-   *    called.
+   *    you should call @FTC_Manager_Reset to completely flush the cache if a
+   *    module property gets changed after @FTC_Manager_New has been called.
    *
-   *    It is not possible to set properties of the FreeType Cache
-   *    sub-system itself with FT_Property_Set; use @FTC_Property_Set
-   *    instead.
+   *    It is not possible to set properties of the FreeType Cache sub-system
+   *    itself with FT_Property_Set; use @FTC_Property_Set instead.
    *
    * @since:
    *   2.4.11
@@ -395,7 +416,7 @@
                    const void*       value );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Property_Get
@@ -416,21 +437,21 @@
    *
    * @inout:
    *    value ::
-   *      A generic pointer to a variable or structure that gives the
-   *      value of the property.  The exact definition of `value' is
-   *      dependent on the property; see section @properties.
+   *      A generic pointer to a variable or structure that gives the value
+   *      of the property.  The exact definition of `value` is dependent on
+   *      the property; see section @properties.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *    If `module_name' isn't a valid module name, or `property_name'
-   *    doesn't specify a valid property, or if `value' doesn't represent a
+   *    If `module_name` isn't a valid module name, or `property_name`
+   *    doesn't specify a valid property, or if `value` doesn't represent a
    *    valid value for the given property, an error is returned.
    *
-   *    The following example gets property `baz' (a range) in module `foo'.
+   *    The following example gets property 'baz' (a range) in module 'foo'.
    *
-   *    {
+   *    ```
    *      typedef  range_
    *      {
    *        FT_Int32  min;
@@ -442,7 +463,7 @@
    *
    *
    *      FT_Property_Get( library, "foo", "baz", &baz );
-   *    }
+   *    ```
    *
    *    It is not possible to retrieve properties of the FreeType Cache
    *    sub-system with FT_Property_Get; use @FTC_Property_Get instead.
@@ -464,17 +485,17 @@
    *   FT_Set_Default_Properties
    *
    * @description:
-   *   If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is
-   *   set, this function reads the `FREETYPE_PROPERTIES' environment
-   *   variable to control driver properties.  See section @properties
-   *   for more.
+   *   If compilation option `FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES` is
+   *   set, this function reads the `FREETYPE_PROPERTIES` environment
+   *   variable to control driver properties.  See section @properties for
+   *   more.
    *
    *   If the compilation option is not set, this function does nothing.
    *
-   *   `FREETYPE_PROPERTIES' has the following syntax form (broken here
-   *   into multiple lines for better readability).
+   *   `FREETYPE_PROPERTIES` has the following syntax form (broken here into
+   *   multiple lines for better readability).
    *
-   *   {
+   *   ```
    *     <optional whitespace>
    *     <module-name1> ':'
    *     <property-name1> '=' <property-value1>
@@ -482,15 +503,14 @@
    *     <module-name2> ':'
    *     <property-name2> '=' <property-value2>
    *     ...
-   *   }
+   *   ```
    *
    *   Example:
    *
-   *   {
+   *   ```
    *     FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
-   *                         cff:no-stem-darkening=1 \
-   *                         autofitter:warping=1
-   *   }
+   *                         cff:no-stem-darkening=0
+   *   ```
    *
    * @inout:
    *   library ::
@@ -509,10 +529,10 @@
    *   FT_Reference_Library
    *
    * @description:
-   *   A counter gets initialized to~1 at the time an @FT_Library
-   *   structure is created.  This function increments the counter.
-   *   @FT_Done_Library then only destroys a library if the counter is~1,
-   *   otherwise it simply decrements the counter.
+   *   A counter gets initialized to~1 at the time an @FT_Library structure
+   *   is created.  This function increments the counter.  @FT_Done_Library
+   *   then only destroys a library if the counter is~1, otherwise it simply
+   *   decrements the counter.
    *
    *   This function helps in managing life-cycles of structures that
    *   reference @FT_Library objects.
@@ -537,19 +557,19 @@
    *   FT_New_Library
    *
    * @description:
-   *   This function is used to create a new FreeType library instance
-   *   from a given memory object.  It is thus possible to use libraries
-   *   with distinct memory allocators within the same program.  Note,
-   *   however, that the used @FT_Memory structure is expected to remain
-   *   valid for the life of the @FT_Library object.
+   *   This function is used to create a new FreeType library instance from a
+   *   given memory object.  It is thus possible to use libraries with
+   *   distinct memory allocators within the same program.  Note, however,
+   *   that the used @FT_Memory structure is expected to remain valid for the
+   *   life of the @FT_Library object.
    *
    *   Normally, you would call this function (followed by a call to
-   *   @FT_Add_Default_Modules or a series of calls to @FT_Add_Module,
-   *   and a call to @FT_Set_Default_Properties) instead of
-   *   @FT_Init_FreeType to initialize the FreeType library.
+   *   @FT_Add_Default_Modules or a series of calls to @FT_Add_Module, and a
+   *   call to @FT_Set_Default_Properties) instead of @FT_Init_FreeType to
+   *   initialize the FreeType library.
    *
-   *   Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a
-   *   library instance.
+   *   Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a library
+   *   instance.
    *
    * @input:
    *   memory ::
@@ -577,8 +597,8 @@
    *   FT_Done_Library
    *
    * @description:
-   *   Discard a given library object.  This closes all drivers and
-   *   discards all resource objects.
+   *   Discard a given library object.  This closes all drivers and discards
+   *   all resource objects.
    *
    * @input:
    *   library ::
@@ -594,14 +614,58 @@
   FT_EXPORT( FT_Error )
   FT_Done_Library( FT_Library  library );
 
-  /* */
 
-  typedef void
+  /**************************************************************************
+   *
+   * @functype:
+   *   FT_DebugHook_Func
+   *
+   * @description:
+   *   A drop-in replacement (or rather a wrapper) for the bytecode or
+   *   charstring interpreter's main loop function.
+   *
+   *   Its job is essentially
+   *
+   *   - to activate debug mode to enforce single-stepping,
+   *
+   *   - to call the main loop function to interpret the next opcode, and
+   *
+   *   - to show the changed context to the user.
+   *
+   *   An example for such a main loop function is `TT_RunIns` (declared in
+   *   FreeType's internal header file `src/truetype/ttinterp.h`).
+   *
+   *   Have a look at the source code of the `ttdebug` FreeType demo program
+   *   for an example of a drop-in replacement.
+   *
+   * @inout:
+   *   arg ::
+   *     A typeless pointer, to be cast to the main loop function's data
+   *     structure (which depends on the font module).  For TrueType fonts
+   *     it is bytecode interpreter's execution context, `TT_ExecContext`,
+   *     which is declared in FreeType's internal header file `tttypes.h`.
+   */
+  typedef FT_Error
   (*FT_DebugHook_Func)( void*  arg );
 
 
   /**************************************************************************
    *
+   * @enum:
+   *   FT_DEBUG_HOOK_XXX
+   *
+   * @description:
+   *   A list of named debug hook indices.
+   *
+   * @values:
+   *   FT_DEBUG_HOOK_TRUETYPE::
+   *     This hook index identifies the TrueType bytecode debugger.
+   */
+#define FT_DEBUG_HOOK_TRUETYPE  0
+
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Set_Debug_Hook
    *
@@ -609,26 +673,27 @@
    *   Set a debug hook function for debugging the interpreter of a font
    *   format.
    *
+   *   While this is a public API function, an application needs access to
+   *   FreeType's internal header files to do something useful.
+   *
+   *   Have a look at the source code of the `ttdebug` FreeType demo program
+   *   for an example of its usage.
+   *
    * @inout:
    *   library ::
    *     A handle to the library object.
    *
    * @input:
    *   hook_index ::
-   *     The index of the debug hook.  You should use the
-   *     values defined in `ftobjs.h', e.g.,
-   *     `FT_DEBUG_HOOK_TRUETYPE'.
+   *     The index of the debug hook.  You should use defined enumeration
+   *     macros like @FT_DEBUG_HOOK_TRUETYPE.
    *
    *   debug_hook ::
    *     The function used to debug the interpreter.
    *
    * @note:
-   *   Currently, four debug hook slots are available, but only two (for
-   *   the TrueType and the Type~1 interpreter) are defined.
-   *
-   *   Since the internal headers of FreeType are no longer installed,
-   *   the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly.
-   *   This is a bug and will be fixed in a forthcoming release.
+   *   Currently, four debug hook slots are available, but only one (for the
+   *   TrueType interpreter) is defined.
    */
   FT_EXPORT( void )
   FT_Set_Debug_Hook( FT_Library         library,
@@ -642,9 +707,9 @@
    *   FT_Add_Default_Modules
    *
    * @description:
-   *   Add the set of default drivers to a given library object.
-   *   This is only useful when you create a library object with
-   *   @FT_New_Library (usually to plug a custom memory manager).
+   *   Add the set of default drivers to a given library object.  This is
+   *   only useful when you create a library object with @FT_New_Library
+   *   (usually to plug a custom memory manager).
    *
    * @inout:
    *   library ::
@@ -679,9 +744,9 @@
    *    FT_TrueTypeEngineType
    *
    * @description:
-   *    A list of values describing which kind of TrueType bytecode
-   *    engine is implemented in a given FT_Library instance.  It is used
-   *    by the @FT_Get_TrueType_Engine_Type function.
+   *    A list of values describing which kind of TrueType bytecode engine is
+   *    implemented in a given FT_Library instance.  It is used by the
+   *    @FT_Get_TrueType_Engine_Type function.
    *
    * @values:
    *    FT_TRUETYPE_ENGINE_TYPE_NONE ::
@@ -691,9 +756,9 @@
    *      Deprecated and removed.
    *
    *    FT_TRUETYPE_ENGINE_TYPE_PATENTED ::
-   *      The library implements a bytecode interpreter that covers
-   *      the full instruction set of the TrueType virtual machine (this
-   *      was governed by patents until May 2010, hence the name).
+   *      The library implements a bytecode interpreter that covers the full
+   *      instruction set of the TrueType virtual machine (this was governed
+   *      by patents until May 2010, hence the name).
    *
    * @since:
    *    2.2
@@ -714,8 +779,8 @@
    *    FT_Get_TrueType_Engine_Type
    *
    * @description:
-   *    Return an @FT_TrueTypeEngineType value to indicate which level of
-   *    the TrueType virtual machine a given library instance supports.
+   *    Return an @FT_TrueTypeEngineType value to indicate which level of the
+   *    TrueType virtual machine a given library instance supports.
    *
    * @input:
    *    library ::
diff --git a/include/freetype/ftmoderr.h b/include/freetype/ftmoderr.h
index 661b0da..c8c892d 100644
--- a/include/freetype/ftmoderr.h
+++ b/include/freetype/ftmoderr.h
@@ -4,7 +4,7 @@
  *
  *   FreeType module error offsets (specification).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,60 +20,69 @@
    *
    * This file is used to define the FreeType module error codes.
    *
-   * If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is
+   * If the macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` in `ftoption.h` is
    * set, the lower byte of an error value identifies the error code as
    * usual.  In addition, the higher byte identifies the module.  For
-   * example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the
-   * error `TT_Err_Invalid_File_Format' has value 0x1303, the error
-   * `T1_Err_Invalid_File_Format' has value 0x1403, etc.
+   * example, the error `FT_Err_Invalid_File_Format` has value 0x0003, the
+   * error `TT_Err_Invalid_File_Format` has value 0x1303, the error
+   * `T1_Err_Invalid_File_Format` has value 0x1403, etc.
    *
-   * Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero,
+   * Note that `FT_Err_Ok`, `TT_Err_Ok`, etc. are always equal to zero,
    * including the high byte.
    *
-   * If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of
-   * an error value is set to zero.
+   * If `FT_CONFIG_OPTION_USE_MODULE_ERRORS` isn't set, the higher byte of an
+   * error value is set to zero.
    *
-   * To hide the various `XXX_Err_' prefixes in the source code, FreeType
-   * provides some macros in `fttypes.h'.
+   * To hide the various `XXX_Err_` prefixes in the source code, FreeType
+   * provides some macros in `fttypes.h`.
    *
    *   FT_ERR( err )
-   *     Add current error module prefix (as defined with the
-   *     `FT_ERR_PREFIX' macro) to `err'.  For example, in the BDF module
-   *     the line
    *
+   *     Add current error module prefix (as defined with the `FT_ERR_PREFIX`
+   *     macro) to `err`.  For example, in the BDF module the line
+   *
+   *     ```
    *       error = FT_ERR( Invalid_Outline );
+   *     ```
    *
    *     expands to
    *
+   *     ```
    *       error = BDF_Err_Invalid_Outline;
+   *     ```
    *
-   *     For simplicity, you can always use `FT_Err_Ok' directly instead
-   *     of `FT_ERR( Ok )'.
+   *     For simplicity, you can always use `FT_Err_Ok` directly instead of
+   *     `FT_ERR( Ok )`.
    *
    *   FT_ERR_EQ( errcode, err )
    *   FT_ERR_NEQ( errcode, err )
-   *     Compare error code `errcode' with the error `err' for equality
-   *     and inequality, respectively.  Example:
    *
+   *     Compare error code `errcode` with the error `err` for equality and
+   *     inequality, respectively.  Example:
+   *
+   *     ```
    *       if ( FT_ERR_EQ( error, Invalid_Outline ) )
    *         ...
+   *     ```
    *
-   *     Using this macro you don't have to think about error prefixes.
-   *     Of course, if module errors are not active, the above example is
-   *     the same as
+   *     Using this macro you don't have to think about error prefixes.  Of
+   *     course, if module errors are not active, the above example is the
+   *     same as
    *
+   *     ```
    *       if ( error == FT_Err_Invalid_Outline )
    *         ...
+   *     ```
    *
    *   FT_ERROR_BASE( errcode )
    *   FT_ERROR_MODULE( errcode )
+   *
    *     Get base error and module error code, respectively.
    *
+   * It can also be used to create a module error message table easily with
+   * something like
    *
-   * It can also be used to create a module error message table easily
-   * with something like
-   *
-   * {
+   * ```
    *   #undef FTMODERR_H_
    *   #define FT_MODERRDEF( e, v, s )  { FT_Mod_Err_ ## e, s },
    *   #define FT_MODERR_START_LIST     {
@@ -85,8 +94,8 @@
    *     const char*  mod_err_msg
    *   } ft_mod_errors[] =
    *
-   *   #include FT_MODULE_ERRORS_H
-   * }
+   *   #include <freetype/ftmoderr.h>
+   * ```
    *
    */
 
@@ -162,6 +171,7 @@
   FT_MODERRDEF( Type42,   0x1400, "Type 42 module" )
   FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" )
   FT_MODERRDEF( GXvalid,  0x1600, "GX validation module" )
+  FT_MODERRDEF( Sdf,      0x1700, "Signed distance field raster module" )
 
 
 #ifdef FT_MODERR_END_LIST
diff --git a/include/freetype/ftotval.h b/include/freetype/ftotval.h
index 698b429..011bdfc 100644
--- a/include/freetype/ftotval.h
+++ b/include/freetype/ftotval.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for validating OpenType tables (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -30,8 +30,7 @@
 #ifndef FTOTVAL_H_
 #define FTOTVAL_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -55,8 +54,8 @@
    *   An API to validate OpenType tables.
    *
    * @description:
-   *   This section contains the declaration of functions to validate
-   *   some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).
+   *   This section contains the declaration of functions to validate some
+   *   OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).
    *
    * @order:
    *   FT_OpenType_Validate
@@ -67,7 +66,7 @@
    */
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *    FT_VALIDATE_OTXXX
@@ -114,7 +113,7 @@
                           FT_VALIDATE_MATH )
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_OpenType_Validate
@@ -122,8 +121,8 @@
    * @description:
    *    Validate various OpenType tables to assure that all offsets and
    *    indices are valid.  The idea is that a higher-level library that
-   *    actually does the text layout can access those tables without
-   *    error checking (which can be quite time consuming).
+   *    actually does the text layout can access those tables without error
+   *    checking (which can be quite time consuming).
    *
    * @input:
    *    face ::
@@ -157,7 +156,7 @@
    *   otherwise.
    *
    *   After use, the application should deallocate the five tables with
-   *   @FT_OpenType_Free.  A NULL value indicates that the table either
+   *   @FT_OpenType_Free.  A `NULL` value indicates that the table either
    *   doesn't exist in the font, or the application hasn't asked for
    *   validation.
    */
@@ -171,7 +170,7 @@
                         FT_Bytes  *JSTF_table );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_OpenType_Free
diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h
index 9dae104..54434b2 100644
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -5,7 +5,7 @@
  *   Support for the FT_Outline type used to store glyph shapes of
  *   most scalable font formats (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,8 +21,7 @@
 #define FTOUTLN_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -47,7 +46,7 @@
    *
    * @description:
    *   This section contains routines used to create and destroy scalable
-   *   glyph images known as `outlines'.  These can also be measured,
+   *   glyph images known as 'outlines'.  These can also be measured,
    *   transformed, and converted into bitmaps and pixmaps.
    *
    * @order:
@@ -89,7 +88,7 @@
    *
    * @description:
    *   Walk over an outline's structure to decompose it into individual
-   *   segments and Bezier arcs.  This function also emits `move to'
+   *   segments and Bezier arcs.  This function also emits 'move to'
    *   operations to indicate the start of new contours in the outline.
    *
    * @input:
@@ -97,30 +96,30 @@
    *     A pointer to the source target.
    *
    *   func_interface ::
-   *     A table of `emitters', i.e., function pointers
-   *     called during decomposition to indicate path
-   *     operations.
+   *     A table of 'emitters', i.e., function pointers called during
+   *     decomposition to indicate path operations.
    *
    * @inout:
    *   user ::
-   *     A typeless pointer that is passed to each
-   *     emitter during the decomposition.  It can be
-   *     used to store the state during the
+   *     A typeless pointer that is passed to each emitter during the
+   *     decomposition.  It can be used to store the state during the
    *     decomposition.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   A contour that contains a single point only is represented by a
-   *   `move to' operation followed by `line to' to the same point.  In
-   *   most cases, it is best to filter this out before using the
-   *   outline for stroking purposes (otherwise it would result in a
-   *   visible dot when round caps are used).
+   *   Degenerate contours, segments, and Bezier arcs may be reported.  In
+   *   most cases, it is best to filter these out before using the outline
+   *   for stroking or other path modification purposes (which may cause
+   *   degenerate segments to become non-degenrate and visible, like when
+   *   stroke caps are used or the path is otherwise outset).  Some glyph
+   *   outlines may contain deliberate degenerate single points for mark
+   *   attachement.
    *
    *   Similarly, the function returns success for an empty outline also
-   *   (doing nothing, this is, not calling any emitter); if necessary,
-   *   you should filter this out, too.
+   *   (doing nothing, this is, not calling any emitter); if necessary, you
+   *   should filter this out, too.
    */
   FT_EXPORT( FT_Error )
   FT_Outline_Decompose( FT_Outline*              outline,
@@ -138,18 +137,17 @@
    *
    * @input:
    *   library ::
-   *     A handle to the library object from where the
-   *     outline is allocated.  Note however that the new
-   *     outline will *not* necessarily be *freed*, when
-   *     destroying the library, by @FT_Done_FreeType.
+   *     A handle to the library object from where the outline is allocated.
+   *     Note however that the new outline will **not** necessarily be
+   *     **freed**, when destroying the library, by @FT_Done_FreeType.
    *
    *   numPoints ::
-   *     The maximum number of points within the outline.
-   *     Must be smaller than or equal to 0xFFFF (65535).
+   *     The maximum number of points within the outline.  Must be smaller
+   *     than or equal to 0xFFFF (65535).
    *
    *   numContours ::
-   *     The maximum number of contours within the outline.
-   *     This value must be in the range 0 to `numPoints'.
+   *     The maximum number of contours within the outline.  This value must
+   *     be in the range 0 to `numPoints`.
    *
    * @output:
    *   anoutline ::
@@ -159,8 +157,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The reason why this function takes a `library' parameter is simply
-   *   to use the library's memory allocator.
+   *   The reason why this function takes a `library` parameter is simply to
+   *   use the library's memory allocator.
    */
   FT_EXPORT( FT_Error )
   FT_Outline_New( FT_Library   library,
@@ -169,13 +167,6 @@
                   FT_Outline  *anoutline );
 
 
-  FT_EXPORT( FT_Error )
-  FT_Outline_New_Internal( FT_Memory    memory,
-                           FT_UInt      numPoints,
-                           FT_Int       numContours,
-                           FT_Outline  *anoutline );
-
-
   /**************************************************************************
    *
    * @function:
@@ -186,8 +177,7 @@
    *
    * @input:
    *   library ::
-   *     A handle of the library object used to allocate the
-   *     outline.
+   *     A handle of the library object used to allocate the outline.
    *
    *   outline ::
    *     A pointer to the outline object to be discarded.
@@ -196,19 +186,14 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   If the outline's `owner' field is not set, only the outline
-   *   descriptor will be released.
+   *   If the outline's 'owner' field is not set, only the outline descriptor
+   *   will be released.
    */
   FT_EXPORT( FT_Error )
   FT_Outline_Done( FT_Library   library,
                    FT_Outline*  outline );
 
 
-  FT_EXPORT( FT_Error )
-  FT_Outline_Done_Internal( FT_Memory    memory,
-                            FT_Outline*  outline );
-
-
   /**************************************************************************
    *
    * @function:
@@ -238,16 +223,16 @@
    *   FT_Outline_Get_CBox
    *
    * @description:
-   *   Return an outline's `control box'.  The control box encloses all
-   *   the outline's points, including Bezier control points.  Though it
+   *   Return an outline's 'control box'.  The control box encloses all the
+   *   outline's points, including Bezier control points.  Though it
    *   coincides with the exact bounding box for most glyphs, it can be
-   *   slightly larger in some situations (like when rotating an outline
-   *   that contains Bezier outside arcs).
+   *   slightly larger in some situations (like when rotating an outline that
+   *   contains Bezier outside arcs).
    *
-   *   Computing the control box is very fast, while getting the bounding
-   *   box can take much more time as it needs to walk over all segments
-   *   and arcs in the outline.  To get the latter, you can use the
-   *   `ftbbox' component, which is dedicated to this single task.
+   *   Computing the control box is very fast, while getting the bounding box
+   *   can take much more time as it needs to walk over all segments and arcs
+   *   in the outline.  To get the latter, you can use the 'ftbbox'
+   *   component, which is dedicated to this single task.
    *
    * @input:
    *   outline ::
@@ -296,9 +281,9 @@
    *   FT_Outline_Copy
    *
    * @description:
-   *   Copy an outline into another one.  Both objects must have the
-   *   same sizes (number of points & number of contours) when this
-   *   function is called.
+   *   Copy an outline into another one.  Both objects must have the same
+   *   sizes (number of points & number of contours) when this function is
+   *   called.
    *
    * @input:
    *   source ::
@@ -322,8 +307,8 @@
    *   FT_Outline_Transform
    *
    * @description:
-   *   Apply a simple 2x2 matrix to all of an outline's points.  Useful
-   *   for applying rotations, slanting, flipping, etc.
+   *   Apply a simple 2x2 matrix to all of an outline's points.  Useful for
+   *   applying rotations, slanting, flipping, etc.
    *
    * @inout:
    *   outline ::
@@ -349,10 +334,10 @@
    *
    * @description:
    *   Embolden an outline.  The new outline will be at most 4~times
-   *   `strength' pixels wider and higher.  You may think of the left and
+   *   `strength` pixels wider and higher.  You may think of the left and
    *   bottom borders as unchanged.
    *
-   *   Negative `strength' values to reduce the outline thickness are
+   *   Negative `strength` values to reduce the outline thickness are
    *   possible also.
    *
    * @inout:
@@ -361,31 +346,30 @@
    *
    * @input:
    *   strength ::
-   *     How strong the glyph is emboldened.  Expressed in
-   *     26.6 pixel format.
+   *     How strong the glyph is emboldened.  Expressed in 26.6 pixel format.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The used algorithm to increase or decrease the thickness of the
-   *   glyph doesn't change the number of points; this means that certain
-   *   situations like acute angles or intersections are sometimes
-   *   handled incorrectly.
+   *   The used algorithm to increase or decrease the thickness of the glyph
+   *   doesn't change the number of points; this means that certain
+   *   situations like acute angles or intersections are sometimes handled
+   *   incorrectly.
    *
-   *   If you need `better' metrics values you should call
+   *   If you need 'better' metrics values you should call
    *   @FT_Outline_Get_CBox or @FT_Outline_Get_BBox.
    *
    *   To get meaningful results, font scaling values must be set with
    *   functions like @FT_Set_Char_Size before calling FT_Render_Glyph.
    *
    * @example:
-   *   {
+   *   ```
    *     FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );
    *
    *     if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
    *       FT_Outline_Embolden( &face->glyph->outline, strength );
-   *   }
+   *   ```
    *
    */
   FT_EXPORT( FT_Error )
@@ -399,10 +383,9 @@
    *   FT_Outline_EmboldenXY
    *
    * @description:
-   *   Embolden an outline.  The new outline will be `xstrength' pixels
-   *   wider and `ystrength' pixels higher.  Otherwise, it is similar to
-   *   @FT_Outline_Embolden, which uses the same strength in both
-   *   directions.
+   *   Embolden an outline.  The new outline will be `xstrength` pixels wider
+   *   and `ystrength` pixels higher.  Otherwise, it is similar to
+   *   @FT_Outline_Embolden, which uses the same strength in both directions.
    *
    * @since:
    *   2.4.10
@@ -419,19 +402,19 @@
    *   FT_Outline_Reverse
    *
    * @description:
-   *   Reverse the drawing direction of an outline.  This is used to
-   *   ensure consistent fill conventions for mirrored glyphs.
+   *   Reverse the drawing direction of an outline.  This is used to ensure
+   *   consistent fill conventions for mirrored glyphs.
    *
    * @inout:
    *   outline ::
    *     A pointer to the target outline descriptor.
    *
    * @note:
-   *   This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in
-   *   the outline's `flags' field.
+   *   This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in the
+   *   outline's `flags` field.
    *
-   *   It shouldn't be used by a normal client application, unless it
-   *   knows what it is doing.
+   *   It shouldn't be used by a normal client application, unless it knows
+   *   what it is doing.
    */
   FT_EXPORT( void )
   FT_Outline_Reverse( FT_Outline*  outline );
@@ -461,15 +444,15 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This function does NOT CREATE the bitmap, it only renders an
+   *   This function does **not create** the bitmap, it only renders an
    *   outline image within the one you pass to it!  Consequently, the
-   *   various fields in `abitmap' should be set accordingly.
+   *   various fields in `abitmap` should be set accordingly.
    *
    *   It will use the raster corresponding to the default glyph format.
    *
-   *   The value of the `num_grays' field in `abitmap' is ignored.  If
-   *   you select the gray-level rasterizer, and you want less than 256
-   *   gray levels, you have to use @FT_Outline_Render directly.
+   *   The value of the `num_grays` field in `abitmap` is ignored.  If you
+   *   select the gray-level rasterizer, and you want less than 256 gray
+   *   levels, you have to use @FT_Outline_Render directly.
    */
   FT_EXPORT( FT_Error )
   FT_Outline_Get_Bitmap( FT_Library        library,
@@ -484,9 +467,6 @@
    *
    * @description:
    *   Render an outline within a bitmap using the current scan-convert.
-   *   This function uses an @FT_Raster_Params structure as an argument,
-   *   allowing advanced features like direct composition, translucency,
-   *   etc.
    *
    * @input:
    *   library ::
@@ -497,24 +477,20 @@
    *
    * @inout:
    *   params ::
-   *     A pointer to an @FT_Raster_Params structure used to
-   *     describe the rendering operation.
+   *     A pointer to an @FT_Raster_Params structure used to describe the
+   *     rendering operation.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   You should know what you are doing and how @FT_Raster_Params works
-   *   to use this function.
-   *
-   *   The field `params.source' will be set to `outline' before the scan
+   *   This advanced function uses @FT_Raster_Params as an argument.
+   *   The field `params.source` will be set to `outline` before the scan
    *   converter is called, which means that the value you give to it is
-   *   actually ignored.
-   *
-   *   The gray-level rasterizer always uses 256 gray levels.  If you
-   *   want less gray levels, you have to provide your own span callback.
-   *   See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the
-   *   @FT_Raster_Params structure for more details.
+   *   actually ignored.  Either `params.target` must point to preallocated
+   *   bitmap, or @FT_RASTER_FLAG_DIRECT must be set in `params.flags`
+   *   allowing FreeType rasterizer to be used for direct composition,
+   *   translucency, etc.  See @FT_Raster_Params for more details.
    */
   FT_EXPORT( FT_Error )
   FT_Outline_Render( FT_Library         library,
@@ -535,22 +511,22 @@
    *
    * @values:
    *   FT_ORIENTATION_TRUETYPE ::
-   *     According to the TrueType specification, clockwise contours must
-   *     be filled, and counter-clockwise ones must be unfilled.
+   *     According to the TrueType specification, clockwise contours must be
+   *     filled, and counter-clockwise ones must be unfilled.
    *
    *   FT_ORIENTATION_POSTSCRIPT ::
-   *     According to the PostScript specification, counter-clockwise contours
-   *     must be filled, and clockwise ones must be unfilled.
+   *     According to the PostScript specification, counter-clockwise
+   *     contours must be filled, and clockwise ones must be unfilled.
    *
    *   FT_ORIENTATION_FILL_RIGHT ::
    *     This is identical to @FT_ORIENTATION_TRUETYPE, but is used to
-   *     remember that in TrueType, everything that is to the right of
-   *     the drawing direction of a contour must be filled.
+   *     remember that in TrueType, everything that is to the right of the
+   *     drawing direction of a contour must be filled.
    *
    *   FT_ORIENTATION_FILL_LEFT ::
    *     This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to
-   *     remember that in PostScript, everything that is to the left of
-   *     the drawing direction of a contour must be filled.
+   *     remember that in PostScript, everything that is to the left of the
+   *     drawing direction of a contour must be filled.
    *
    *   FT_ORIENTATION_NONE ::
    *     The orientation cannot be determined.  That is, different parts of
@@ -574,11 +550,11 @@
    *   FT_Outline_Get_Orientation
    *
    * @description:
-   *   This function analyzes a glyph outline and tries to compute its
-   *   fill orientation (see @FT_Orientation).  This is done by integrating
-   *   the total area covered by the outline. The positive integral
-   *   corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT
-   *   is returned. The negative integral corresponds to the counter-clockwise
+   *   This function analyzes a glyph outline and tries to compute its fill
+   *   orientation (see @FT_Orientation).  This is done by integrating the
+   *   total area covered by the outline. The positive integral corresponds
+   *   to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT is
+   *   returned. The negative integral corresponds to the counter-clockwise
    *   orientation and @FT_ORIENTATION_TRUETYPE is returned.
    *
    *   Note that this will return @FT_ORIENTATION_TRUETYPE for empty
diff --git a/include/freetype/ftparams.h b/include/freetype/ftparams.h
index 004eaf5..6a9f243 100644
--- a/include/freetype/ftparams.h
+++ b/include/freetype/ftparams.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for possible FT_Parameter tags (specification only).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTPARAMS_H_
 #define FTPARAMS_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -51,16 +50,16 @@
    */
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY
    *
    * @description:
    *   A tag for @FT_Parameter to make @FT_Open_Face ignore typographic
-   *   family names in the `name' table (introduced in OpenType version
-   *   1.4).  Use this for backward compatibility with legacy systems that
-   *   have a four-faces-per-family restriction.
+   *   family names in the 'name' table (introduced in OpenType version 1.4).
+   *   Use this for backward compatibility with legacy systems that have a
+   *   four-faces-per-family restriction.
    *
    * @since:
    *   2.8
@@ -75,14 +74,14 @@
           FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY
    *
    * @description:
    *   A tag for @FT_Parameter to make @FT_Open_Face ignore typographic
-   *   subfamily names in the `name' table (introduced in OpenType version
+   *   subfamily names in the 'name' table (introduced in OpenType version
    *   1.4).  Use this for backward compatibility with legacy systems that
    *   have a four-faces-per-family restriction.
    *
@@ -99,7 +98,7 @@
           FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_PARAM_TAG_INCREMENTAL
@@ -116,13 +115,28 @@
   /**************************************************************************
    *
    * @enum:
+   *   FT_PARAM_TAG_IGNORE_SBIX
+   *
+   * @description:
+   *   A tag for @FT_Parameter to make @FT_Open_Face ignore an 'sbix' table
+   *   while loading a font.  Use this if @FT_FACE_FLAG_SBIX is set and you
+   *   want to access the outline glyphs in the font.
+   *
+   */
+#define FT_PARAM_TAG_IGNORE_SBIX \
+          FT_MAKE_TAG( 'i', 's', 'b', 'x' )
+
+
+  /**************************************************************************
+   *
+   * @enum:
    *   FT_PARAM_TAG_LCD_FILTER_WEIGHTS
    *
    * @description:
    *   An @FT_Parameter tag to be used with @FT_Face_Properties.  The
    *   corresponding argument specifies the five LCD filter weights for a
-   *   given face (if using @FT_LOAD_TARGET_LCD, for example), overriding
-   *   the global default values or the values set up with
+   *   given face (if using @FT_LOAD_TARGET_LCD, for example), overriding the
+   *   global default values or the values set up with
    *   @FT_Library_SetLcdFilterWeights.
    *
    * @since:
@@ -141,8 +155,7 @@
    * @description:
    *   An @FT_Parameter tag to be used with @FT_Face_Properties.  The
    *   corresponding 32bit signed integer argument overrides the font
-   *   driver's random seed value with a face-specific one; see
-   *   @random-seed.
+   *   driver's random seed value with a face-specific one; see @random-seed.
    *
    * @since:
    *   2.8
@@ -163,10 +176,10 @@
    *   darkening, overriding the global default values or the values set up
    *   with @FT_Property_Set (see @no-stem-darkening).
    *
-   *   This is a passive setting that only takes effect if the font driver
-   *   or autohinter honors it, which the CFF, Type~1, and CID drivers
-   *   always do, but the autohinter only in `light' hinting mode (as of
-   *   version 2.9).
+   *   This is a passive setting that only takes effect if the font driver or
+   *   autohinter honors it, which the CFF, Type~1, and CID drivers always
+   *   do, but the autohinter only in 'light' hinting mode (as of version
+   *   2.9).
    *
    * @since:
    *   2.8
@@ -176,7 +189,7 @@
           FT_MAKE_TAG( 'd', 'a', 'r', 'k' )
 
 
-  /***************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_PARAM_TAG_UNPATENTED_HINTING
@@ -184,9 +197,9 @@
    * @description:
    *   Deprecated, no effect.
    *
-   *   Previously: A constant used as the tag of an @FT_Parameter structure to
-   *   indicate that unpatented methods only should be used by the TrueType
-   *   bytecode interpreter for a typeface opened by @FT_Open_Face.
+   *   Previously: A constant used as the tag of an @FT_Parameter structure
+   *   to indicate that unpatented methods only should be used by the
+   *   TrueType bytecode interpreter for a typeface opened by @FT_Open_Face.
    *
    */
 #define FT_PARAM_TAG_UNPATENTED_HINTING \
diff --git a/include/freetype/ftpfr.h b/include/freetype/ftpfr.h
index deaae61..7111d40 100644
--- a/include/freetype/ftpfr.h
+++ b/include/freetype/ftpfr.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing PFR-specific data (specification only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTPFR_H_
 #define FTPFR_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -49,7 +48,7 @@
    */
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_PFR_Metrics
@@ -63,22 +62,22 @@
    *
    * @output:
    *    aoutline_resolution ::
-   *      Outline resolution.  This is equivalent to `face->units_per_EM'
-   *      for non-PFR fonts.  Optional (parameter can be NULL).
+   *      Outline resolution.  This is equivalent to `face->units_per_EM` for
+   *      non-PFR fonts.  Optional (parameter can be `NULL`).
    *
    *    ametrics_resolution ::
-   *      Metrics resolution.  This is equivalent to `outline_resolution'
-   *      for non-PFR fonts.  Optional (parameter can be NULL).
+   *      Metrics resolution.  This is equivalent to `outline_resolution` for
+   *      non-PFR fonts.  Optional (parameter can be `NULL`).
    *
    *    ametrics_x_scale ::
-   *      A 16.16 fixed-point number used to scale distance expressed
-   *      in metrics units to device subpixels.  This is equivalent to
-   *      `face->size->x_scale', but for metrics only.  Optional (parameter
-   *      can be NULL).
+   *      A 16.16 fixed-point number used to scale distance expressed in
+   *      metrics units to device subpixels.  This is equivalent to
+   *      `face->size->x_scale`, but for metrics only.  Optional (parameter
+   *      can be `NULL`).
    *
    *    ametrics_y_scale ::
-   *      Same as `ametrics_x_scale' but for the vertical direction.
-   *      optional (parameter can be NULL).
+   *      Same as `ametrics_x_scale` but for the vertical direction.
+   *      optional (parameter can be `NULL`).
    *
    * @return:
    *    FreeType error code.  0~means success.
@@ -95,7 +94,7 @@
                       FT_Fixed  *ametrics_y_scale );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_PFR_Kerning
@@ -123,11 +122,11 @@
    *    FreeType error code.  0~means success.
    *
    * @note:
-   *    This function always return distances in original PFR metrics
-   *    units.  This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED
-   *    mode, which always returns distances converted to outline units.
+   *    This function always return distances in original PFR metrics units.
+   *    This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED mode,
+   *    which always returns distances converted to outline units.
    *
-   *    You can use the value of the `x_scale' and `y_scale' parameters
+   *    You can use the value of the `x_scale` and `y_scale` parameters
    *    returned by @FT_Get_PFR_Metrics to scale these to device subpixels.
    */
   FT_EXPORT( FT_Error )
@@ -137,7 +136,7 @@
                       FT_Vector  *avector );
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_PFR_Advance
@@ -161,8 +160,8 @@
    *    FreeType error code.  0~means success.
    *
    * @note:
-   *    You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics
-   *    to convert the advance to device subpixels (i.e., 1/64th of pixels).
+   *    You can use the `x_scale` or `y_scale` results of @FT_Get_PFR_Metrics
+   *    to convert the advance to device subpixels (i.e., 1/64 of pixels).
    */
   FT_EXPORT( FT_Error )
   FT_Get_PFR_Advance( FT_Face   face,
diff --git a/include/freetype/ftrender.h b/include/freetype/ftrender.h
index 2b7e5c8..a8576da 100644
--- a/include/freetype/ftrender.h
+++ b/include/freetype/ftrender.h
@@ -4,7 +4,7 @@
  *
  *   FreeType renderer modules public interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define FTRENDER_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
-#include FT_GLYPH_H
+#include <freetype/ftmodapi.h>
+#include <freetype/ftglyph.h>
 
 
 FT_BEGIN_HEADER
@@ -132,12 +131,11 @@
    *     The glyph image format this renderer handles.
    *
    *   render_glyph ::
-   *     A method used to render the image that is in a
-   *     given glyph slot into a bitmap.
+   *     A method used to render the image that is in a given glyph slot into
+   *     a bitmap.
    *
    *   transform_glyph ::
-   *     A method used to transform the image that is in
-   *     a given glyph slot.
+   *     A method used to transform the image that is in a given glyph slot.
    *
    *   get_glyph_cbox ::
    *     A method used to access the glyph's cbox.
@@ -146,8 +144,8 @@
    *     A method used to pass additional parameters.
    *
    *   raster_class ::
-   *     For @FT_GLYPH_FORMAT_OUTLINE renderers only.
-   *     This is a pointer to its raster's class.
+   *     For @FT_GLYPH_FORMAT_OUTLINE renderers only.  This is a pointer to
+   *     its raster's class.
    */
   typedef struct  FT_Renderer_Class_
   {
@@ -184,8 +182,8 @@
    *   A renderer handle.  0~if none found.
    *
    * @note:
-   *   An error will be returned if a module already exists by that name,
-   *   or if the module requires a version of FreeType that is too great.
+   *   An error will be returned if a module already exists by that name, or
+   *   if the module requires a version of FreeType that is too great.
    *
    *   To add a new renderer, simply use @FT_Add_Module.  To retrieve a
    *   renderer by its name, use @FT_Get_Module.
@@ -221,13 +219,13 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   In case of success, the renderer will be used to convert glyph
-   *   images in the renderer's known format into bitmaps.
+   *   In case of success, the renderer will be used to convert glyph images
+   *   in the renderer's known format into bitmaps.
    *
    *   This doesn't change the current renderer for other formats.
    *
-   *   Currently, no FreeType renderer module uses `parameters'; you
-   *   should thus always pass NULL as the value.
+   *   Currently, no FreeType renderer module uses `parameters`; you should
+   *   thus always pass `NULL` as the value.
    */
   FT_EXPORT( FT_Error )
   FT_Set_Renderer( FT_Library     library,
diff --git a/include/freetype/ftsizes.h b/include/freetype/ftsizes.h
index 481a053..7bfb1ae 100644
--- a/include/freetype/ftsizes.h
+++ b/include/freetype/ftsizes.h
@@ -4,7 +4,7 @@
  *
  *   FreeType size objects management (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
   /**************************************************************************
    *
    * Typical application would normally not need to use these functions.
-   * However, they have been placed in a public API for the rare cases
-   * where they are needed.
+   * However, they have been placed in a public API for the rare cases where
+   * they are needed.
    *
    */
 
@@ -29,8 +29,7 @@
 #define FTSIZES_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -54,22 +53,20 @@
    *   Managing multiple sizes per face.
    *
    * @description:
-   *   When creating a new face object (e.g., with @FT_New_Face), an
-   *   @FT_Size object is automatically created and used to store all
-   *   pixel-size dependent information, available in the `face->size'
-   *   field.
+   *   When creating a new face object (e.g., with @FT_New_Face), an @FT_Size
+   *   object is automatically created and used to store all pixel-size
+   *   dependent information, available in the `face->size` field.
    *
-   *   It is however possible to create more sizes for a given face,
-   *   mostly in order to manage several character pixel sizes of the
-   *   same font family and style.  See @FT_New_Size and @FT_Done_Size.
+   *   It is however possible to create more sizes for a given face, mostly
+   *   in order to manage several character pixel sizes of the same font
+   *   family and style.  See @FT_New_Size and @FT_Done_Size.
    *
-   *   Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only
-   *   modify the contents of the current `active' size; you thus need
-   *   to use @FT_Activate_Size to change it.
+   *   Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only modify the
+   *   contents of the current 'active' size; you thus need to use
+   *   @FT_Activate_Size to change it.
    *
-   *   99% of applications won't need the functions provided here,
-   *   especially if they use the caching sub-system, so be cautious
-   *   when using these.
+   *   99% of applications won't need the functions provided here, especially
+   *   if they use the caching sub-system, so be cautious when using these.
    *
    */
 
@@ -94,8 +91,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   You need to call @FT_Activate_Size in order to select the new size
-   *   for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size,
+   *   You need to call @FT_Activate_Size in order to select the new size for
+   *   upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size,
    *   @FT_Load_Glyph, @FT_Load_Char, etc.
    */
   FT_EXPORT( FT_Error )
@@ -109,9 +106,8 @@
    *   FT_Done_Size
    *
    * @description:
-   *   Discard a given size object.  Note that @FT_Done_Face
-   *   automatically discards all size objects allocated with
-   *   @FT_New_Size.
+   *   Discard a given size object.  Note that @FT_Done_Face automatically
+   *   discards all size objects allocated with @FT_New_Size.
    *
    * @input:
    *   size ::
@@ -130,12 +126,12 @@
    *   FT_Activate_Size
    *
    * @description:
-   *   Even though it is possible to create several size objects for a
-   *   given face (see @FT_New_Size for details), functions like
-   *   @FT_Load_Glyph or @FT_Load_Char only use the one that has been
-   *   activated last to determine the `current character pixel size'.
+   *   Even though it is possible to create several size objects for a given
+   *   face (see @FT_New_Size for details), functions like @FT_Load_Glyph or
+   *   @FT_Load_Char only use the one that has been activated last to
+   *   determine the 'current character pixel size'.
    *
-   *   This function can be used to `activate' a previously created size
+   *   This function can be used to 'activate' a previously created size
    *   object.
    *
    * @input:
@@ -146,8 +142,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   If `face' is the size's parent face object, this function changes
-   *   the value of `face->size' to the input size handle.
+   *   If `face` is the size's parent face object, this function changes the
+   *   value of `face->size` to the input size handle.
    */
   FT_EXPORT( FT_Error )
   FT_Activate_Size( FT_Size  size );
diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h
index 0a0ac31..9d5d22b 100644
--- a/include/freetype/ftsnames.h
+++ b/include/freetype/ftsnames.h
@@ -2,12 +2,12 @@
  *
  * ftsnames.h
  *
- *   Simple interface to access SFNT `name' tables (which are used
+ *   Simple interface to access SFNT 'name' tables (which are used
  *   to hold font names, copyright info, notices, etc.) (specification).
  *
  *   This is _not_ used to retrieve glyph names!
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -23,9 +23,8 @@
 #define FTSNAMES_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_PARAMETER_TAGS_H
+#include <freetype/freetype.h>
+#include <freetype/ftparams.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -49,10 +48,10 @@
    *   Access the names embedded in TrueType and OpenType files.
    *
    * @description:
-   *   The TrueType and OpenType specifications allow the inclusion of
-   *   a special names table (`name') in font files.  This table contains
-   *   textual (and internationalized) information regarding the font,
-   *   like family name, copyright, version, etc.
+   *   The TrueType and OpenType specifications allow the inclusion of a
+   *   special names table ('name') in font files.  This table contains
+   *   textual (and internationalized) information regarding the font, like
+   *   family name, copyright, version, etc.
    *
    *   The definitions below are used to access them if available.
    *
@@ -67,43 +66,39 @@
    *   FT_SfntName
    *
    * @description:
-   *   A structure used to model an SFNT `name' table entry.
+   *   A structure used to model an SFNT 'name' table entry.
    *
    * @fields:
    *   platform_id ::
-   *     The platform ID for `string'.
-   *     See @TT_PLATFORM_XXX for possible values.
+   *     The platform ID for `string`.  See @TT_PLATFORM_XXX for possible
+   *     values.
    *
    *   encoding_id ::
-   *     The encoding ID for `string'.
-   *     See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX,
-   *     @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX
-   *     for possible values.
+   *     The encoding ID for `string`.  See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX,
+   *     @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX for possible
+   *     values.
    *
    *   language_id ::
-   *     The language ID for `string'.
-   *     See @TT_MAC_LANGID_XXX and @TT_MS_LANGID_XXX for
-   *     possible values.
+   *     The language ID for `string`.  See @TT_MAC_LANGID_XXX and
+   *     @TT_MS_LANGID_XXX for possible values.
    *
-   *     Registered OpenType values for `language_id' are
-   *     always smaller than 0x8000; values equal or larger
-   *     than 0x8000 usually indicate a language tag string
-   *     (introduced in OpenType version 1.6).  Use function
-   *     @FT_Get_Sfnt_LangTag with `language_id' as its
-   *     argument to retrieve the associated language tag.
+   *     Registered OpenType values for `language_id` are always smaller than
+   *     0x8000; values equal or larger than 0x8000 usually indicate a
+   *     language tag string (introduced in OpenType version 1.6).  Use
+   *     function @FT_Get_Sfnt_LangTag with `language_id` as its argument to
+   *     retrieve the associated language tag.
    *
    *   name_id ::
-   *     An identifier for `string'.
-   *     See @TT_NAME_ID_XXX for possible values.
+   *     An identifier for `string`.  See @TT_NAME_ID_XXX for possible
+   *     values.
    *
    *   string ::
-   *     The `name' string.  Note that its format differs
-   *     depending on the (platform,encoding) pair, being
-   *     either a string of bytes (without a terminating
-   *     NULL byte) or containing UTF-16BE entities.
+   *     The 'name' string.  Note that its format differs depending on the
+   *     (platform,encoding) pair, being either a string of bytes (without a
+   *     terminating `NULL` byte) or containing UTF-16BE entities.
    *
    *   string_len ::
-   *     The length of `string' in bytes.
+   *     The length of `string` in bytes.
    *
    * @note:
    *   Please refer to the TrueType or OpenType specification for more
@@ -128,18 +123,18 @@
    *   FT_Get_Sfnt_Name_Count
    *
    * @description:
-   *   Retrieve the number of name strings in the SFNT `name' table.
+   *   Retrieve the number of name strings in the SFNT 'name' table.
    *
    * @input:
    *   face ::
    *     A handle to the source face.
    *
    * @return:
-   *   The number of strings in the `name' table.
+   *   The number of strings in the 'name' table.
    *
    * @note:
    *   This function always returns an error if the config macro
-   *   `TT_CONFIG_OPTION_SFNT_NAMES' is not defined in `ftoption.h'.
+   *   `TT_CONFIG_OPTION_SFNT_NAMES` is not defined in `ftoption.h`.
    */
   FT_EXPORT( FT_UInt )
   FT_Get_Sfnt_Name_Count( FT_Face  face );
@@ -151,14 +146,14 @@
    *   FT_Get_Sfnt_Name
    *
    * @description:
-   *   Retrieve a string of the SFNT `name' table for a given index.
+   *   Retrieve a string of the SFNT 'name' table for a given index.
    *
    * @input:
    *   face ::
    *     A handle to the source face.
    *
    *   idx ::
-   *     The index of the `name' string.
+   *     The index of the 'name' string.
    *
    * @output:
    *   aname ::
@@ -168,19 +163,19 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The `string' array returned in the `aname' structure is not
-   *   null-terminated.  Note that you don't have to deallocate `string'
-   *   by yourself; FreeType takes care of it if you call @FT_Done_Face.
+   *   The `string` array returned in the `aname` structure is not
+   *   null-terminated.  Note that you don't have to deallocate `string` by
+   *   yourself; FreeType takes care of it if you call @FT_Done_Face.
    *
    *   Use @FT_Get_Sfnt_Name_Count to get the total number of available
-   *   `name' table entries, then do a loop until you get the right
-   *   platform, encoding, and name ID.
+   *   'name' table entries, then do a loop until you get the right platform,
+   *   encoding, and name ID.
    *
-   *   `name' table format~1 entries can use language tags also, see
+   *   'name' table format~1 entries can use language tags also, see
    *   @FT_Get_Sfnt_LangTag.
    *
    *   This function always returns an error if the config macro
-   *   `TT_CONFIG_OPTION_SFNT_NAMES' is not defined in `ftoption.h'.
+   *   `TT_CONFIG_OPTION_SFNT_NAMES` is not defined in `ftoption.h`.
    */
   FT_EXPORT( FT_Error )
   FT_Get_Sfnt_Name( FT_Face       face,
@@ -194,16 +189,15 @@
    *   FT_SfntLangTag
    *
    * @description:
-   *   A structure to model a language tag entry from an SFNT `name'
-   *   table.
+   *   A structure to model a language tag entry from an SFNT 'name' table.
    *
    * @fields:
    *   string ::
-   *     The language tag string, encoded in UTF-16BE
-   *     (without trailing NULL bytes).
+   *     The language tag string, encoded in UTF-16BE (without trailing
+   *     `NULL` bytes).
    *
    *   string_len ::
-   *     The length of `string' in *bytes*.
+   *     The length of `string` in **bytes**.
    *
    * @note:
    *   Please refer to the TrueType or OpenType specification for more
@@ -227,36 +221,36 @@
    *
    * @description:
    *   Retrieve the language tag associated with a language ID of an SFNT
-   *   `name' table entry.
+   *   'name' table entry.
    *
    * @input:
    *   face ::
    *     A handle to the source face.
    *
    *   langID ::
-   *     The language ID, as returned by @FT_Get_Sfnt_Name.
-   *     This is always a value larger than 0x8000.
+   *     The language ID, as returned by @FT_Get_Sfnt_Name.  This is always a
+   *     value larger than 0x8000.
    *
    * @output:
    *   alangTag ::
-   *     The language tag associated with the `name' table
-   *     entry's language ID.
+   *     The language tag associated with the 'name' table entry's language
+   *     ID.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   The `string' array returned in the `alangTag' structure is not
-   *   null-terminated.  Note that you don't have to deallocate `string'
-   *   by yourself; FreeType takes care of it if you call @FT_Done_Face.
+   *   The `string` array returned in the `alangTag` structure is not
+   *   null-terminated.  Note that you don't have to deallocate `string` by
+   *   yourself; FreeType takes care of it if you call @FT_Done_Face.
    *
-   *   Only `name' table format~1 supports language tags.  For format~0
+   *   Only 'name' table format~1 supports language tags.  For format~0
    *   tables, this function always returns FT_Err_Invalid_Table.  For
    *   invalid format~1 language ID values, FT_Err_Invalid_Argument is
    *   returned.
    *
    *   This function always returns an error if the config macro
-   *   `TT_CONFIG_OPTION_SFNT_NAMES' is not defined in `ftoption.h'.
+   *   `TT_CONFIG_OPTION_SFNT_NAMES` is not defined in `ftoption.h`.
    *
    * @since:
    *   2.8
diff --git a/include/freetype/ftstroke.h b/include/freetype/ftstroke.h
index 91d2776..b3d9080 100644
--- a/include/freetype/ftstroke.h
+++ b/include/freetype/ftstroke.h
@@ -4,7 +4,7 @@
  *
  *   FreeType path stroker (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,15 +19,14 @@
 #ifndef FTSTROKE_H_
 #define FTSTROKE_H_
 
-#include <ft2build.h>
-#include FT_OUTLINE_H
-#include FT_GLYPH_H
+#include <freetype/ftoutln.h>
+#include <freetype/ftglyph.h>
 
 
 FT_BEGIN_HEADER
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @section:
    *    glyph_stroker
@@ -39,12 +38,12 @@
    *    Generating bordered and stroked glyphs.
    *
    * @description:
-   *    This component generates stroked outlines of a given vectorial
-   *    glyph.  It also allows you to retrieve the `outside' and/or the
-   *    `inside' borders of the stroke.
+   *    This component generates stroked outlines of a given vectorial glyph.
+   *    It also allows you to retrieve the 'outside' and/or the 'inside'
+   *    borders of the stroke.
    *
-   *    This can be useful to generate `bordered' glyph, i.e., glyphs
-   *    displayed with a coloured (and anti-aliased) border around their
+   *    This can be useful to generate 'bordered' glyph, i.e., glyphs
+   *    displayed with a colored (and anti-aliased) border around their
    *    shape.
    *
    * @order:
@@ -81,7 +80,7 @@
    */
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Stroker
@@ -92,51 +91,45 @@
   typedef struct FT_StrokerRec_*  FT_Stroker;
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_Stroker_LineJoin
    *
    * @description:
-   *   These values determine how two joining lines are rendered
-   *   in a stroker.
+   *   These values determine how two joining lines are rendered in a
+   *   stroker.
    *
    * @values:
    *   FT_STROKER_LINEJOIN_ROUND ::
-   *     Used to render rounded line joins.  Circular arcs are used
-   *     to join two lines smoothly.
+   *     Used to render rounded line joins.  Circular arcs are used to join
+   *     two lines smoothly.
    *
    *   FT_STROKER_LINEJOIN_BEVEL ::
-   *     Used to render beveled line joins.  The outer corner of
-   *     the joined lines is filled by enclosing the triangular
-   *     region of the corner with a straight line between the
-   *     outer corners of each stroke.
+   *     Used to render beveled line joins.  The outer corner of the joined
+   *     lines is filled by enclosing the triangular region of the corner
+   *     with a straight line between the outer corners of each stroke.
    *
    *   FT_STROKER_LINEJOIN_MITER_FIXED ::
-   *     Used to render mitered line joins, with fixed bevels if the
-   *     miter limit is exceeded.  The outer edges of the strokes
-   *     for the two segments are extended until they meet at an
-   *     angle.  If the segments meet at too sharp an angle (such
-   *     that the miter would extend from the intersection of the
-   *     segments a distance greater than the product of the miter
-   *     limit value and the border radius), then a bevel join (see
-   *     above) is used instead.  This prevents long spikes being
-   *     created.  FT_STROKER_LINEJOIN_MITER_FIXED generates a miter
-   *     line join as used in PostScript and PDF.
+   *     Used to render mitered line joins, with fixed bevels if the miter
+   *     limit is exceeded.  The outer edges of the strokes for the two
+   *     segments are extended until they meet at an angle.  A bevel join
+   *     (see above) is used if the segments meet at too sharp an angle and
+   *     the outer edges meet beyond a distance corresponding to the meter
+   *     limit.  This prevents long spikes being created.
+   *     `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line join as
+   *     used in PostScript and PDF.
    *
    *   FT_STROKER_LINEJOIN_MITER_VARIABLE ::
    *   FT_STROKER_LINEJOIN_MITER ::
-   *     Used to render mitered line joins, with variable bevels if
-   *     the miter limit is exceeded.  The intersection of the
-   *     strokes is clipped at a line perpendicular to the bisector
-   *     of the angle between the strokes, at the distance from the
-   *     intersection of the segments equal to the product of the
-   *     miter limit value and the border radius.  This prevents
-   *     long spikes being created.
-   *     FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line
-   *     join as used in XPS.  FT_STROKER_LINEJOIN_MITER is an alias
-   *     for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for
-   *     backward compatibility.
+   *     Used to render mitered line joins, with variable bevels if the miter
+   *     limit is exceeded.  The intersection of the strokes is clipped
+   *     perpendicularly to the bisector, at a distance corresponding to
+   *     the miter limit. This prevents long spikes being created.
+   *     `FT_STROKER_LINEJOIN_MITER_VARIABLE` generates a mitered line join
+   *     as used in XPS.  `FT_STROKER_LINEJOIN_MITER` is an alias for
+   *     `FT_STROKER_LINEJOIN_MITER_VARIABLE`, retained for backward
+   *     compatibility.
    */
   typedef enum  FT_Stroker_LineJoin_
   {
@@ -149,27 +142,25 @@
   } FT_Stroker_LineJoin;
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_Stroker_LineCap
    *
    * @description:
-   *   These values determine how the end of opened sub-paths are
-   *   rendered in a stroke.
+   *   These values determine how the end of opened sub-paths are rendered in
+   *   a stroke.
    *
    * @values:
    *   FT_STROKER_LINECAP_BUTT ::
-   *     The end of lines is rendered as a full stop on the last
-   *     point itself.
+   *     The end of lines is rendered as a full stop on the last point
+   *     itself.
    *
    *   FT_STROKER_LINECAP_ROUND ::
-   *     The end of lines is rendered as a half-circle around the
-   *     last point.
+   *     The end of lines is rendered as a half-circle around the last point.
    *
    *   FT_STROKER_LINECAP_SQUARE ::
-   *     The end of lines is rendered as a square around the
-   *     last point.
+   *     The end of lines is rendered as a square around the last point.
    */
   typedef enum  FT_Stroker_LineCap_
   {
@@ -180,14 +171,14 @@
   } FT_Stroker_LineCap;
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_StrokerBorder
    *
    * @description:
-   *   These values are used to select a given stroke border
-   *   in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder.
+   *   These values are used to select a given stroke border in
+   *   @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder.
    *
    * @values:
    *   FT_STROKER_BORDER_LEFT ::
@@ -197,9 +188,9 @@
    *     Select the right border, relative to the drawing direction.
    *
    * @note:
-   *   Applications are generally interested in the `inside' and `outside'
+   *   Applications are generally interested in the 'inside' and 'outside'
    *   borders.  However, there is no direct mapping between these and the
-   *   `left' and `right' ones, since this really depends on the glyph's
+   *   'left' and 'right' ones, since this really depends on the glyph's
    *   drawing orientation, which varies between font formats.
    *
    *   You can however use @FT_Outline_GetInsideBorder and
@@ -213,14 +204,14 @@
   } FT_StrokerBorder;
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Outline_GetInsideBorder
    *
    * @description:
-   *   Retrieve the @FT_StrokerBorder value corresponding to the
-   *   `inside' borders of a given outline.
+   *   Retrieve the @FT_StrokerBorder value corresponding to the 'inside'
+   *   borders of a given outline.
    *
    * @input:
    *   outline ::
@@ -234,14 +225,14 @@
   FT_Outline_GetInsideBorder( FT_Outline*  outline );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Outline_GetOutsideBorder
    *
    * @description:
-   *   Retrieve the @FT_StrokerBorder value corresponding to the
-   *   `outside' borders of a given outline.
+   *   Retrieve the @FT_StrokerBorder value corresponding to the 'outside'
+   *   borders of a given outline.
    *
    * @input:
    *   outline ::
@@ -255,7 +246,7 @@
   FT_Outline_GetOutsideBorder( FT_Outline*  outline );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_New
@@ -269,7 +260,7 @@
    *
    * @output:
    *   astroker ::
-   *     A new stroker object handle.  NULL in case of error.
+   *     A new stroker object handle.  `NULL` in case of error.
    *
    * @return:
    *    FreeType error code.  0~means success.
@@ -279,7 +270,7 @@
                   FT_Stroker  *astroker );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_Set
@@ -301,14 +292,18 @@
    *     The line join style.
    *
    *   miter_limit ::
-   *     The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and
-   *     FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles,
+   *     The maximum reciprocal sine of half-angle at the miter join,
    *     expressed as 16.16 fixed-point value.
    *
    * @note:
-   *   The radius is expressed in the same units as the outline
+   *   The `radius` is expressed in the same units as the outline
    *   coordinates.
    *
+   *   The `miter_limit` multiplied by the `radius` gives the maximum size
+   *   of a miter spike, at which it is clipped for
+   *   @FT_STROKER_LINEJOIN_MITER_VARIABLE or replaced with a bevel join for
+   *   @FT_STROKER_LINEJOIN_MITER_FIXED.
+   *
    *   This function calls @FT_Stroker_Rewind automatically.
    */
   FT_EXPORT( void )
@@ -319,16 +314,15 @@
                   FT_Fixed             miter_limit );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_Rewind
    *
    * @description:
-   *   Reset a stroker object without changing its attributes.
-   *   You should call this function before beginning a new
-   *   series of calls to @FT_Stroker_BeginSubPath or
-   *   @FT_Stroker_EndSubPath.
+   *   Reset a stroker object without changing its attributes.  You should
+   *   call this function before beginning a new series of calls to
+   *   @FT_Stroker_BeginSubPath or @FT_Stroker_EndSubPath.
    *
    * @input:
    *   stroker ::
@@ -338,15 +332,15 @@
   FT_Stroker_Rewind( FT_Stroker  stroker );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_ParseOutline
    *
    * @description:
-   *   A convenience function used to parse a whole outline with
-   *   the stroker.  The resulting outline(s) can be retrieved
-   *   later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export.
+   *   A convenience function used to parse a whole outline with the stroker.
+   *   The resulting outline(s) can be retrieved later by functions like
+   *   @FT_Stroker_GetCounts and @FT_Stroker_Export.
    *
    * @input:
    *   stroker ::
@@ -356,18 +350,18 @@
    *     The source outline.
    *
    *   opened ::
-   *     A boolean.  If~1, the outline is treated as an open path instead
-   *     of a closed one.
+   *     A boolean.  If~1, the outline is treated as an open path instead of
+   *     a closed one.
    *
    * @return:
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   If `opened' is~0 (the default), the outline is treated as a closed
-   *   path, and the stroker generates two distinct `border' outlines.
+   *   If `opened` is~0 (the default), the outline is treated as a closed
+   *   path, and the stroker generates two distinct 'border' outlines.
    *
-   *   If `opened' is~1, the outline is processed as an open path, and the
-   *   stroker generates a single `stroke' outline.
+   *   If `opened` is~1, the outline is processed as an open path, and the
+   *   stroker generates a single 'stroke' outline.
    *
    *   This function calls @FT_Stroker_Rewind automatically.
    */
@@ -377,7 +371,7 @@
                            FT_Bool      opened );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_BeginSubPath
@@ -399,8 +393,8 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   This function is useful when you need to stroke a path that is
-   *   not stored as an @FT_Outline object.
+   *   This function is useful when you need to stroke a path that is not
+   *   stored as an @FT_Outline object.
    */
   FT_EXPORT( FT_Error )
   FT_Stroker_BeginSubPath( FT_Stroker  stroker,
@@ -408,7 +402,7 @@
                            FT_Bool     open );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_EndSubPath
@@ -424,22 +418,22 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   You should call this function after @FT_Stroker_BeginSubPath.
-   *   If the subpath was not `opened', this function `draws' a
-   *   single line segment to the start position when needed.
+   *   You should call this function after @FT_Stroker_BeginSubPath.  If the
+   *   subpath was not 'opened', this function 'draws' a single line segment
+   *   to the start position when needed.
    */
   FT_EXPORT( FT_Error )
   FT_Stroker_EndSubPath( FT_Stroker  stroker );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_LineTo
    *
    * @description:
-   *   `Draw' a single line segment in the stroker's current sub-path,
-   *   from the last position.
+   *   'Draw' a single line segment in the stroker's current sub-path, from
+   *   the last position.
    *
    * @input:
    *   stroker ::
@@ -460,13 +454,13 @@
                      FT_Vector*  to );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_ConicTo
    *
    * @description:
-   *   `Draw' a single quadratic Bezier in the stroker's current sub-path,
+   *   'Draw' a single quadratic Bezier in the stroker's current sub-path,
    *   from the last position.
    *
    * @input:
@@ -492,14 +486,14 @@
                       FT_Vector*  to );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_CubicTo
    *
    * @description:
-   *   `Draw' a single cubic Bezier in the stroker's current sub-path,
-   *   from the last position.
+   *   'Draw' a single cubic Bezier in the stroker's current sub-path, from
+   *   the last position.
    *
    * @input:
    *   stroker ::
@@ -528,16 +522,16 @@
                       FT_Vector*  to );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_GetBorderCounts
    *
    * @description:
-   *   Call this function once you have finished parsing your paths
-   *   with the stroker.  It returns the number of points and
-   *   contours necessary to export one of the `border' or `stroke'
-   *   outlines generated by the stroker.
+   *   Call this function once you have finished parsing your paths with the
+   *   stroker.  It returns the number of points and contours necessary to
+   *   export one of the 'border' or 'stroke' outlines generated by the
+   *   stroker.
    *
    * @input:
    *   stroker ::
@@ -557,15 +551,15 @@
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   When an outline, or a sub-path, is `closed', the stroker generates
-   *   two independent `border' outlines, named `left' and `right'.
+   *   When an outline, or a sub-path, is 'closed', the stroker generates two
+   *   independent 'border' outlines, named 'left' and 'right'.
    *
-   *   When the outline, or a sub-path, is `opened', the stroker merges
-   *   the `border' outlines with caps.  The `left' border receives all
-   *   points, while the `right' border becomes empty.
+   *   When the outline, or a sub-path, is 'opened', the stroker merges the
+   *   'border' outlines with caps.  The 'left' border receives all points,
+   *   while the 'right' border becomes empty.
    *
-   *   Use the function @FT_Stroker_GetCounts instead if you want to
-   *   retrieve the counts associated to both borders.
+   *   Use the function @FT_Stroker_GetCounts instead if you want to retrieve
+   *   the counts associated to both borders.
    */
   FT_EXPORT( FT_Error )
   FT_Stroker_GetBorderCounts( FT_Stroker        stroker,
@@ -574,19 +568,17 @@
                               FT_UInt          *anum_contours );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_ExportBorder
    *
    * @description:
-   *   Call this function after @FT_Stroker_GetBorderCounts to
-   *   export the corresponding border to your own @FT_Outline
-   *   structure.
+   *   Call this function after @FT_Stroker_GetBorderCounts to export the
+   *   corresponding border to your own @FT_Outline structure.
    *
-   *   Note that this function appends the border points and
-   *   contours to your outline, but does not try to resize its
-   *   arrays.
+   *   Note that this function appends the border points and contours to your
+   *   outline, but does not try to resize its arrays.
    *
    * @input:
    *   stroker ::
@@ -599,19 +591,19 @@
    *     The target outline handle.
    *
    * @note:
-   *   Always call this function after @FT_Stroker_GetBorderCounts to
-   *   get sure that there is enough room in your @FT_Outline object to
-   *   receive all new data.
+   *   Always call this function after @FT_Stroker_GetBorderCounts to get
+   *   sure that there is enough room in your @FT_Outline object to receive
+   *   all new data.
    *
-   *   When an outline, or a sub-path, is `closed', the stroker generates
-   *   two independent `border' outlines, named `left' and `right'.
+   *   When an outline, or a sub-path, is 'closed', the stroker generates two
+   *   independent 'border' outlines, named 'left' and 'right'.
    *
-   *   When the outline, or a sub-path, is `opened', the stroker merges
-   *   the `border' outlines with caps.  The `left' border receives all
-   *   points, while the `right' border becomes empty.
+   *   When the outline, or a sub-path, is 'opened', the stroker merges the
+   *   'border' outlines with caps.  The 'left' border receives all points,
+   *   while the 'right' border becomes empty.
    *
-   *   Use the function @FT_Stroker_Export instead if you want to
-   *   retrieve all borders at once.
+   *   Use the function @FT_Stroker_Export instead if you want to retrieve
+   *   all borders at once.
    */
   FT_EXPORT( void )
   FT_Stroker_ExportBorder( FT_Stroker        stroker,
@@ -619,16 +611,15 @@
                            FT_Outline*       outline );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_GetCounts
    *
    * @description:
-   *   Call this function once you have finished parsing your paths
-   *   with the stroker.  It returns the number of points and
-   *   contours necessary to export all points/borders from the stroked
-   *   outline/path.
+   *   Call this function once you have finished parsing your paths with the
+   *   stroker.  It returns the number of points and contours necessary to
+   *   export all points/borders from the stroked outline/path.
    *
    * @input:
    *   stroker ::
@@ -650,18 +641,17 @@
                         FT_UInt    *anum_contours );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_Export
    *
    * @description:
-   *   Call this function after @FT_Stroker_GetBorderCounts to
-   *   export all borders to your own @FT_Outline structure.
+   *   Call this function after @FT_Stroker_GetBorderCounts to export all
+   *   borders to your own @FT_Outline structure.
    *
-   *   Note that this function appends the border points and
-   *   contours to your outline, but does not try to resize its
-   *   arrays.
+   *   Note that this function appends the border points and contours to your
+   *   outline, but does not try to resize its arrays.
    *
    * @input:
    *   stroker ::
@@ -675,7 +665,7 @@
                      FT_Outline*  outline );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Stroker_Done
@@ -685,13 +675,13 @@
    *
    * @input:
    *   stroker ::
-   *     A stroker handle.  Can be NULL.
+   *     A stroker handle.  Can be `NULL`.
    */
   FT_EXPORT( void )
   FT_Stroker_Done( FT_Stroker  stroker );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Glyph_Stroke
@@ -708,8 +698,7 @@
    *     A stroker handle.
    *
    *   destroy ::
-   *     A Boolean.  If~1, the source glyph object is destroyed
-   *     on success.
+   *     A Boolean.  If~1, the source glyph object is destroyed on success.
    *
    * @return:
    *    FreeType error code.  0~means success.
@@ -719,8 +708,8 @@
    *
    *   Adding stroke may yield a significantly wider and taller glyph
    *   depending on how large of a radius was used to stroke the glyph.  You
-   *   may need to manually adjust horizontal and vertical advance amounts
-   *   to account for this added size.
+   *   may need to manually adjust horizontal and vertical advance amounts to
+   *   account for this added size.
    */
   FT_EXPORT( FT_Error )
   FT_Glyph_Stroke( FT_Glyph    *pglyph,
@@ -728,14 +717,14 @@
                    FT_Bool      destroy );
 
 
-  /**************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Glyph_StrokeBorder
    *
    * @description:
-   *   Stroke a given outline glyph object with a given stroker, but
-   *   only return either its inside or outside border.
+   *   Stroke a given outline glyph object with a given stroker, but only
+   *   return either its inside or outside border.
    *
    * @inout:
    *   pglyph ::
@@ -746,12 +735,11 @@
    *     A stroker handle.
    *
    *   inside ::
-   *     A Boolean.  If~1, return the inside border, otherwise
-   *     the outside border.
+   *     A Boolean.  If~1, return the inside border, otherwise the outside
+   *     border.
    *
    *   destroy ::
-   *     A Boolean.  If~1, the source glyph object is destroyed
-   *     on success.
+   *     A Boolean.  If~1, the source glyph object is destroyed on success.
    *
    * @return:
    *    FreeType error code.  0~means success.
@@ -761,8 +749,8 @@
    *
    *   Adding stroke may yield a significantly wider and taller glyph
    *   depending on how large of a radius was used to stroke the glyph.  You
-   *   may need to manually adjust horizontal and vertical advance amounts
-   *   to account for this added size.
+   *   may need to manually adjust horizontal and vertical advance amounts to
+   *   account for this added size.
    */
   FT_EXPORT( FT_Error )
   FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,
diff --git a/include/freetype/ftsynth.h b/include/freetype/ftsynth.h
index f2e7856..5d19697 100644
--- a/include/freetype/ftsynth.h
+++ b/include/freetype/ftsynth.h
@@ -5,7 +5,7 @@
  *   FreeType synthesizing code for emboldening and slanting
  *   (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -35,7 +35,7 @@
 
 
   /* Main reason for not lifting the functions in this module to a  */
-  /* `standard' API is that the used parameters for emboldening and */
+  /* 'standard' API is that the used parameters for emboldening and */
   /* slanting are not configurable.  Consider the functions as a    */
   /* code resource that should be copied into the application and   */
   /* adapted to the particular needs.                               */
@@ -45,8 +45,7 @@
 #define FTSYNTH_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -57,7 +56,7 @@
 
 FT_BEGIN_HEADER
 
-  /* Embolden a glyph by a `reasonable' value (which is highly a matter of */
+  /* Embolden a glyph by a 'reasonable' value (which is highly a matter of */
   /* taste).  This function is actually a convenience function, providing  */
   /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden.           */
   /*                                                                       */
@@ -69,10 +68,19 @@
   FT_EXPORT( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );
 
-  /* Slant an outline glyph to the right by about 12 degrees. */
+  /* Slant an outline glyph to the right by about 12 degrees.              */
   FT_EXPORT( void )
   FT_GlyphSlot_Oblique( FT_GlyphSlot  slot );
 
+  /* Slant an outline glyph by a given sine of an angle.  You can apply    */
+  /* slant along either x- or y-axis by choosing a corresponding non-zero  */
+  /* argument.  If both slants are non-zero, some affine transformation    */
+  /* will result.                                                          */
+  FT_EXPORT( void )
+  FT_GlyphSlot_Slant( FT_GlyphSlot  slot,
+                      FT_Fixed      xslant,
+                      FT_Fixed      yslant );
+
   /* */
 
 
diff --git a/include/freetype/ftsystem.h b/include/freetype/ftsystem.h
index 0b415b6..a995b07 100644
--- a/include/freetype/ftsystem.h
+++ b/include/freetype/ftsystem.h
@@ -4,7 +4,7 @@
  *
  *   FreeType low-level system interface definition (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define FTSYSTEM_H_
 
 
-#include <ft2build.h>
 
 
 FT_BEGIN_HEADER
@@ -38,10 +37,9 @@
    *  How FreeType manages memory and i/o.
    *
    * @description:
-   *  This section contains various definitions related to memory
-   *  management and i/o access.  You need to understand this
-   *  information if you want to use a custom memory manager or you own
-   *  i/o streams.
+   *  This section contains various definitions related to memory management
+   *  and i/o access.  You need to understand this information if you want to
+   *  use a custom memory manager or you own i/o streams.
    *
    */
 
@@ -53,7 +51,7 @@
    */
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Memory
@@ -66,13 +64,13 @@
   typedef struct FT_MemoryRec_*  FT_Memory;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   FT_Alloc_Func
    *
    * @description:
-   *   A function used to allocate `size' bytes from `memory'.
+   *   A function used to allocate `size` bytes from `memory`.
    *
    * @input:
    *   memory ::
@@ -90,7 +88,7 @@
                     long       size );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   FT_Free_Func
@@ -111,7 +109,7 @@
                    void*      block );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   FT_Realloc_Func
@@ -146,7 +144,7 @@
                       void*      block );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FT_MemoryRec
@@ -184,7 +182,7 @@
    */
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Stream
@@ -193,21 +191,21 @@
    *   A handle to an input stream.
    *
    * @also:
-   *   See @FT_StreamRec for the publicly accessible fields of a given
-   *   stream object.
+   *   See @FT_StreamRec for the publicly accessible fields of a given stream
+   *   object.
    *
    */
   typedef struct FT_StreamRec_*  FT_Stream;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FT_StreamDesc
    *
    * @description:
    *   A union type used to store either a long or a pointer.  This is used
-   *   to store a file descriptor or a `FILE*' in an input stream.
+   *   to store a file descriptor or a `FILE*` in an input stream.
    *
    */
   typedef union  FT_StreamDesc_
@@ -218,7 +216,7 @@
   } FT_StreamDesc;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   FT_Stream_IoFunc
@@ -231,7 +229,8 @@
    *     A handle to the source stream.
    *
    *   offset ::
-   *     The offset of read in stream (always from start).
+   *     The offset from the start of the stream to seek to if this is a seek
+   *     operation (see note).
    *
    *   buffer ::
    *     The address of the read buffer.
@@ -243,9 +242,13 @@
    *   The number of bytes effectively read by the stream.
    *
    * @note:
-   *   This function might be called to perform a seek or skip operation
-   *   with a `count' of~0.  A non-zero return value then indicates an
-   *   error.
+   *   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.
    *
    */
   typedef unsigned long
@@ -255,7 +258,7 @@
                        unsigned long   count );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   FT_Stream_CloseFunc
@@ -272,7 +275,7 @@
   (*FT_Stream_CloseFunc)( FT_Stream  stream );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   FT_StreamRec
@@ -283,7 +286,7 @@
    * @input:
    *   base ::
    *     For memory-based streams, this is the address of the first stream
-   *     byte in memory.  This field should always be set to NULL for
+   *     byte in memory.  This field should always be set to `NULL` for
    *     disk-based streams.
    *
    *   size ::
@@ -299,7 +302,7 @@
    *
    *   descriptor ::
    *     This field is a union that can hold an integer or a pointer.  It is
-   *     used by stream implementations to store file descriptors or `FILE*'
+   *     used by stream implementations to store file descriptors or `FILE*`
    *     pointers.
    *
    *   pathname ::
@@ -314,14 +317,13 @@
    *     The stream's close function.
    *
    *   memory ::
-   *     The memory manager to use to preload frames.  This is set
-   *     internally by FreeType and shouldn't be touched by stream
-   *     implementations.
+   *     The memory manager to use to preload frames.  This is set internally
+   *     by FreeType and shouldn't be touched by stream implementations.
    *
    *   cursor ::
    *     This field is set and used internally by FreeType when parsing
-   *     frames.  In particular, the `FT_GET_XXX' macros use this instead
-   *     of the `pos' field.
+   *     frames.  In particular, the `FT_GET_XXX` macros use this instead of
+   *     the `pos` field.
    *
    *   limit ::
    *     This field is set and used internally by FreeType when parsing
diff --git a/include/freetype/fttrigon.h b/include/freetype/fttrigon.h
index 7a27bb2..294981a 100644
--- a/include/freetype/fttrigon.h
+++ b/include/freetype/fttrigon.h
@@ -4,7 +4,7 @@
  *
  *   FreeType trigonometric functions (specification).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef FTTRIGON_H_
 #define FTTRIGON_H_
 
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -39,7 +39,7 @@
    */
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   FT_Angle
@@ -52,7 +52,7 @@
   typedef FT_Fixed  FT_Angle;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_ANGLE_PI
@@ -64,7 +64,7 @@
 #define FT_ANGLE_PI  ( 180L << 16 )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_ANGLE_2PI
@@ -76,7 +76,7 @@
 #define FT_ANGLE_2PI  ( FT_ANGLE_PI * 2 )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_ANGLE_PI2
@@ -88,7 +88,7 @@
 #define FT_ANGLE_PI2  ( FT_ANGLE_PI / 2 )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @macro:
    *   FT_ANGLE_PI4
@@ -100,7 +100,7 @@
 #define FT_ANGLE_PI4  ( FT_ANGLE_PI / 4 )
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Sin
@@ -124,7 +124,7 @@
   FT_Sin( FT_Angle  angle );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Cos
@@ -148,7 +148,7 @@
   FT_Cos( FT_Angle  angle );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Tan
@@ -168,14 +168,14 @@
   FT_Tan( FT_Angle  angle );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Atan2
    *
    * @description:
-   *   Return the arc-tangent corresponding to a given vector (x,y) in
-   *   the 2d plane.
+   *   Return the arc-tangent corresponding to a given vector (x,y) in the 2d
+   *   plane.
    *
    * @input:
    *   x ::
@@ -193,7 +193,7 @@
             FT_Fixed  y );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Angle_Diff
@@ -210,7 +210,7 @@
    *     Second angle.
    *
    * @return:
-   *   Constrained value of `value2-value1'.
+   *   Constrained value of `angle2-angle1`.
    *
    */
   FT_EXPORT( FT_Angle )
@@ -218,15 +218,15 @@
                  FT_Angle  angle2 );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Vector_Unit
    *
    * @description:
    *   Return the unit vector corresponding to a given angle.  After the
-   *   call, the value of `vec.x' will be `cos(angle)', and the value of
-   *   `vec.y' will be `sin(angle)'.
+   *   call, the value of `vec.x` will be `cos(angle)`, and the value of
+   *   `vec.y` will be `sin(angle)`.
    *
    *   This function is useful to retrieve both the sinus and cosinus of a
    *   given angle quickly.
@@ -245,7 +245,7 @@
                   FT_Angle    angle );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Vector_Rotate
@@ -267,7 +267,7 @@
                     FT_Angle    angle );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Vector_Length
@@ -288,7 +288,7 @@
   FT_Vector_Length( FT_Vector*  vec );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Vector_Polarize
@@ -314,7 +314,7 @@
                       FT_Angle   *angle );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @function:
    *   FT_Vector_From_Polar
diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h
index 9da08a0..5b109f0 100644
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -4,7 +4,7 @@
  *
  *   FreeType simple types definitions (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,8 +22,8 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_SYSTEM_H
-#include FT_IMAGE_H
+#include <freetype/ftsystem.h>
+#include <freetype/ftimage.h>
 
 #include <stddef.h>
 
@@ -45,7 +45,10 @@
    * @description:
    *   This section contains the basic data types defined by FreeType~2,
    *   ranging from simple scalar types to bitmap descriptors.  More
-   *   font-specific structures are defined in a different section.
+   *   font-specific structures are defined in a different section.  Note
+   *   that FreeType does not use floating-point data types.  Fractional
+   *   values are represented by fixed-point integers, with lower bits
+   *   storing the fractional part.
    *
    * @order:
    *   FT_Byte
@@ -126,8 +129,8 @@
    *   FT_UFWord
    *
    * @description:
-   *   An unsigned 16-bit integer used to store a distance in original
-   *   font units.
+   *   An unsigned 16-bit integer used to store a distance in original font
+   *   units.
    */
   typedef unsigned short  FT_UFWord;  /* unsigned distance */
 
@@ -270,8 +273,7 @@
    *   FT_F26Dot6
    *
    * @description:
-   *   A signed 26.6 fixed-point type used for vectorial pixel
-   *   coordinates.
+   *   A signed 26.6 fixed-point type used for vectorial pixel coordinates.
    */
   typedef signed long  FT_F26Dot6;
 
@@ -294,8 +296,8 @@
    *   FT_Error
    *
    * @description:
-   *   The FreeType error code type.  A value of~0 is always interpreted
-   *   as a successful operation.
+   *   The FreeType error code type.  A value of~0 is always interpreted as a
+   *   successful operation.
    */
   typedef int  FT_Error;
 
@@ -317,9 +319,9 @@
    *   FT_Offset
    *
    * @description:
-   *   This is equivalent to the ANSI~C `size_t' type, i.e., the largest
-   *   _unsigned_ integer type used to express a file size or position,
-   *   or a memory block size.
+   *   This is equivalent to the ANSI~C `size_t` type, i.e., the largest
+   *   _unsigned_ integer type used to express a file size or position, or a
+   *   memory block size.
    */
   typedef size_t  FT_Offset;
 
@@ -330,9 +332,9 @@
    *   FT_PtrDist
    *
    * @description:
-   *   This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the
-   *   largest _signed_ integer type used to express the distance
-   *   between two pointers.
+   *   This is equivalent to the ANSI~C `ptrdiff_t` type, i.e., the largest
+   *   _signed_ integer type used to express the distance between two
+   *   pointers.
    */
   typedef ft_ptrdiff_t  FT_PtrDist;
 
@@ -367,13 +369,13 @@
    *   FT_Matrix
    *
    * @description:
-   *   A simple structure used to store a 2x2 matrix.  Coefficients are
-   *   in 16.16 fixed-point format.  The computation performed is:
+   *   A simple structure used to store a 2x2 matrix.  Coefficients are in
+   *   16.16 fixed-point format.  The computation performed is:
    *
-   *   {
+   *   ```
    *     x' = x*xx + y*xy
    *     y' = x*yx + y*yy
-   *   }
+   *   ```
    *
    * @fields:
    *   xx ::
@@ -414,7 +416,7 @@
   typedef struct  FT_Data_
   {
     const FT_Byte*  pointer;
-    FT_Int          length;
+    FT_UInt         length;
 
   } FT_Data;
 
@@ -425,13 +427,13 @@
    *   FT_Generic_Finalizer
    *
    * @description:
-   *   Describe a function used to destroy the `client' data of any
-   *   FreeType object.  See the description of the @FT_Generic type for
-   *   details of usage.
+   *   Describe a function used to destroy the 'client' data of any FreeType
+   *   object.  See the description of the @FT_Generic type for details of
+   *   usage.
    *
    * @input:
-   *   The address of the FreeType object that is under finalization.
-   *   Its client data is accessed through its `generic' field.
+   *   The address of the FreeType object that is under finalization.  Its
+   *   client data is accessed through its `generic` field.
    */
   typedef void  (*FT_Generic_Finalizer)( void*  object );
 
@@ -446,25 +448,24 @@
    *   variety of FreeType core objects.  For example, a text layout API
    *   might want to associate a glyph cache to a given size object.
    *
-   *   Some FreeType object contains a `generic' field, of type
-   *   FT_Generic, which usage is left to client applications and font
-   *   servers.
+   *   Some FreeType object contains a `generic` field, of type `FT_Generic`,
+   *   which usage is left to client applications and font servers.
    *
-   *   It can be used to store a pointer to client-specific data, as well
-   *   as the address of a `finalizer' function, which will be called by
+   *   It can be used to store a pointer to client-specific data, as well as
+   *   the address of a 'finalizer' function, which will be called by
    *   FreeType when the object is destroyed (for example, the previous
-   *   client example would put the address of the glyph cache destructor
-   *   in the `finalizer' field).
+   *   client example would put the address of the glyph cache destructor in
+   *   the `finalizer` field).
    *
    * @fields:
    *   data ::
-   *     A typeless pointer to any client-specified data. This
-   *     field is completely ignored by the FreeType library.
+   *     A typeless pointer to any client-specified data. This field is
+   *     completely ignored by the FreeType library.
    *
    *   finalizer ::
-   *     A pointer to a `generic finalizer' function, which
-   *     will be called when the object is destroyed.  If this
-   *     field is set to NULL, no code will be called.
+   *     A pointer to a 'generic finalizer' function, which will be called
+   *     when the object is destroyed.  If this field is set to `NULL`, no
+   *     code will be called.
    */
   typedef struct  FT_Generic_
   {
@@ -480,19 +481,18 @@
    *   FT_MAKE_TAG
    *
    * @description:
-   *   This macro converts four-letter tags that are used to label
-   *   TrueType tables into an unsigned long, to be used within FreeType.
+   *   This macro converts four-letter tags that are used to label TrueType
+   *   tables into an `FT_Tag` type, to be used within FreeType.
    *
    * @note:
-   *   The produced values *must* be 32-bit integers.  Don't redefine
-   *   this macro.
+   *   The produced values **must** be 32-bit integers.  Don't redefine this
+   *   macro.
    */
-#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
-          (FT_Tag)                        \
-          ( ( (FT_ULong)_x1 << 24 ) |     \
-            ( (FT_ULong)_x2 << 16 ) |     \
-            ( (FT_ULong)_x3 <<  8 ) |     \
-              (FT_ULong)_x4         )
+#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 )                  \
+          ( ( FT_STATIC_BYTE_CAST( FT_Tag, _x1 ) << 24 ) | \
+            ( FT_STATIC_BYTE_CAST( FT_Tag, _x2 ) << 16 ) | \
+            ( FT_STATIC_BYTE_CAST( FT_Tag, _x3 ) <<  8 ) | \
+              FT_STATIC_BYTE_CAST( FT_Tag, _x4 )         )
 
 
   /*************************************************************************/
@@ -518,9 +518,9 @@
    *   FT_ListNode
    *
    * @description:
-   *    Many elements and objects in FreeType are listed through an
-   *    @FT_List record (see @FT_ListRec).  As its name suggests, an
-   *    FT_ListNode is a handle to a single list element.
+   *    Many elements and objects in FreeType are listed through an @FT_List
+   *    record (see @FT_ListRec).  As its name suggests, an FT_ListNode is a
+   *    handle to a single list element.
    */
   typedef struct FT_ListNodeRec_*  FT_ListNode;
 
@@ -546,10 +546,10 @@
    *
    * @fields:
    *   prev ::
-   *     The previous element in the list.  NULL if first.
+   *     The previous element in the list.  `NULL` if first.
    *
    *   next ::
-   *     The next element in the list.  NULL if last.
+   *     The next element in the list.  `NULL` if last.
    *
    *   data ::
    *     A typeless pointer to the listed object.
@@ -569,8 +569,8 @@
    *   FT_ListRec
    *
    * @description:
-   *   A structure used to hold a simple doubly-linked list.  These are
-   *   used in many parts of FreeType.
+   *   A structure used to hold a simple doubly-linked list.  These are used
+   *   in many parts of FreeType.
    *
    * @fields:
    *   head ::
@@ -590,13 +590,13 @@
 
 
 #define FT_IS_EMPTY( list )  ( (list).head == 0 )
-#define FT_BOOL( x )  ( (FT_Bool)( x ) )
+#define FT_BOOL( x )         FT_STATIC_CAST( FT_Bool, (x) != 0 )
 
   /* concatenate C tokens */
 #define FT_ERR_XCAT( x, y )  x ## y
 #define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
 
-  /* see `ftmoderr.h' for descriptions of the following macros */
+  /* see `ftmoderr.h` for descriptions of the following macros */
 
 #define FT_ERR( e )  FT_ERR_CAT( FT_ERR_PREFIX, e )
 
diff --git a/include/freetype/ftwinfnt.h b/include/freetype/ftwinfnt.h
index 5d0eb0f..7b701ea 100644
--- a/include/freetype/ftwinfnt.h
+++ b/include/freetype/ftwinfnt.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing Windows fnt-specific data.
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef FTWINFNT_H_
 #define FTWINFNT_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -50,26 +49,25 @@
    */
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   FT_WinFNT_ID_XXX
    *
    * @description:
-   *   A list of valid values for the `charset' byte in
-   *   @FT_WinFNT_HeaderRec.  Exact mapping tables for the various cpXXXX
-   *   encodings (except for cp1361) can be found at
-   *   ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS
-   *   subdirectory.  cp1361 is roughly a superset of
-   *   MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT.
+   *   A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec.
+   *   Exact mapping tables for the various 'cpXXXX' encodings (except for
+   *   'cp1361') can be found at 'ftp://ftp.unicode.org/Public/' in the
+   *   `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory.  'cp1361' is roughly a
+   *   superset of `MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT`.
    *
    * @values:
    *   FT_WinFNT_ID_DEFAULT ::
-   *     This is used for font enumeration and font creation as a
-   *     `don't care' value.  Valid font files don't contain this value.
-   *     When querying for information about the character set of the font
-   *     that is currently selected into a specified device context, this
-   *     return value (of the related Windows API) simply denotes failure.
+   *     This is used for font enumeration and font creation as a 'don't
+   *     care' value.  Valid font files don't contain this value.  When
+   *     querying for information about the character set of the font that is
+   *     currently selected into a specified device context, this return
+   *     value (of the related Windows API) simply denotes failure.
    *
    *   FT_WinFNT_ID_SYMBOL ::
    *     There is no known mapping table available.
@@ -80,26 +78,27 @@
    *   FT_WinFNT_ID_OEM ::
    *     From Michael Poettgen <michael@poettgen.de>:
    *
-   *     The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM
-   *     is used for the charset of vector fonts, like `modern.fon',
-   *     `roman.fon', and `script.fon' on Windows.
+   *     The 'Windows Font Mapping' article says that `FT_WinFNT_ID_OEM` is
+   *     used for the charset of vector fonts, like `modern.fon`,
+   *     `roman.fon`, and `script.fon` on Windows.
    *
-   *     The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value
+   *     The 'CreateFont' documentation says: The `FT_WinFNT_ID_OEM` value
    *     specifies a character set that is operating-system dependent.
    *
-   *     The `IFIMETRICS' documentation from the `Windows Driver
-   *     Development Kit' says: This font supports an OEM-specific
-   *     character set.  The OEM character set is system dependent.
+   *     The 'IFIMETRICS' documentation from the 'Windows Driver Development
+   *     Kit' says: This font supports an OEM-specific character set.  The
+   *     OEM character set is system dependent.
    *
-   *     In general OEM, as opposed to ANSI (i.e., cp1252), denotes the
-   *     second default codepage that most international versions of
-   *     Windows have.  It is one of the OEM codepages from
+   *     In general OEM, as opposed to ANSI (i.e., 'cp1252'), denotes the
+   *     second default codepage that most international versions of Windows
+   *     have.  It is one of the OEM codepages from
    *
-   *     https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers ,
+   *     https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers
+   *     ,
    *
-   *     and is used for the `DOS boxes', to support legacy applications.
-   *     A German Windows version for example usually uses ANSI codepage
-   *     1252 and OEM codepage 850.
+   *     and is used for the 'DOS boxes', to support legacy applications.  A
+   *     German Windows version for example usually uses ANSI codepage 1252
+   *     and OEM codepage 850.
    *
    *   FT_WinFNT_ID_CP874 ::
    *     A superset of Thai TIS 620 and ISO 8859-11.
@@ -112,8 +111,8 @@
    *     ordering and minor deviations).
    *
    *   FT_WinFNT_ID_CP949 ::
-   *     A superset of Korean Hangul KS~C 5601-1987 (with different
-   *     ordering and minor deviations).
+   *     A superset of Korean Hangul KS~C 5601-1987 (with different ordering
+   *     and minor deviations).
    *
    *   FT_WinFNT_ID_CP950 ::
    *     A superset of traditional Chinese Big~5 ETen (with different
@@ -234,7 +233,7 @@
   typedef struct FT_WinFNT_HeaderRec_*  FT_WinFNT_Header;
 
 
-  /**********************************************************************
+  /**************************************************************************
    *
    * @function:
    *    FT_Get_WinFNT_Header
diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h
index c20a18e..bf9c8b7 100644
--- a/include/freetype/internal/autohint.h
+++ b/include/freetype/internal/autohint.h
@@ -2,9 +2,9 @@
  *
  * autohint.h
  *
- *   High-level `autohint' module-specific interface (specification).
+ *   High-level 'autohint' module-specific interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -30,31 +30,31 @@
 
   /**************************************************************************
    *
-   * A small technical note regarding automatic hinting in order to
-   * clarify this module interface.
+   * A small technical note regarding automatic hinting in order to clarify
+   * this module interface.
    *
    * An automatic hinter might compute two kinds of data for a given face:
    *
    * - global hints: Usually some metrics that describe global properties
    *                 of the face.  It is computed by scanning more or less
    *                 aggressively the glyphs in the face, and thus can be
-   *                 very slow to compute (even if the size of global
-   *                 hints is really small).
+   *                 very slow to compute (even if the size of global hints
+   *                 is really small).
    *
-   * - glyph hints:  These describe some important features of the glyph
+   * - glyph hints: These describe some important features of the glyph
    *                 outline, as well as how to align them.  They are
    *                 generally much faster to compute than global hints.
    *
-   * The current FreeType auto-hinter does a pretty good job while
-   * performing fast computations for both global and glyph hints.
-   * However, we might be interested in introducing more complex and
-   * powerful algorithms in the future, like the one described in the John
-   * D. Hobby paper, which unfortunately requires a lot more horsepower.
+   * The current FreeType auto-hinter does a pretty good job while performing
+   * fast computations for both global and glyph hints.  However, we might be
+   * interested in introducing more complex and powerful algorithms in the
+   * future, like the one described in the John D. Hobby paper, which
+   * unfortunately requires a lot more horsepower.
    *
    * Because a sufficiently sophisticated font management system would
-   * typically implement an LRU cache of opened face objects to reduce
-   * memory usage, it is a good idea to be able to avoid recomputing
-   * global hints every time the same face is re-opened.
+   * typically implement an LRU cache of opened face objects to reduce memory
+   * usage, it is a good idea to be able to avoid recomputing global hints
+   * every time the same face is re-opened.
    *
    * We thus provide the ability to cache global hints outside of the face
    * object, in order to speed up font re-opening time.  Of course, this
@@ -62,16 +62,15 @@
    * it.
    *
    * I initially thought that it would be a good idea to cache the glyph
-   * hints too.  However, my general idea now is that if you really need
-   * to cache these too, you are simply in need of a new font format,
-   * where all this information could be stored within the font file and
-   * decoded on the fly.
+   * hints too.  However, my general idea now is that if you really need to
+   * cache these too, you are simply in need of a new font format, where all
+   * this information could be stored within the font file and decoded on the
+   * fly.
    *
    */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 
 FT_BEGIN_HEADER
@@ -87,8 +86,8 @@
    *
    * @description:
    *   Retrieve the global hints computed for a given face object.  The
-   *   resulting data is dissociated from the face and will survive a
-   *   call to FT_Done_Face().  It must be discarded through the API
+   *   resulting data is dissociated from the face and will survive a call to
+   *   FT_Done_Face().  It must be discarded through the API
    *   FT_AutoHinter_GlobalDoneFunc().
    *
    * @input:
@@ -119,8 +118,8 @@
    *
    * @description:
    *   Discard the global hints retrieved through
-   *   FT_AutoHinter_GlobalGetFunc().  This is the only way these hints
-   *   are freed from memory.
+   *   FT_AutoHinter_GlobalGetFunc().  This is the only way these hints are
+   *   freed from memory.
    *
    * @input:
    *   hinter ::
@@ -140,9 +139,9 @@
    *   FT_AutoHinter_GlobalResetFunc
    *
    * @description:
-   *   This function is used to recompute the global metrics in a given
-   *   font.  This is useful when global font data changes (e.g. Multiple
-   *   Masters fonts where blend coordinates change).
+   *   This function is used to recompute the global metrics in a given font.
+   *   This is useful when global font data changes (e.g. Multiple Masters
+   *   fonts where blend coordinates change).
    *
    * @input:
    *   hinter ::
@@ -162,8 +161,8 @@
    *   FT_AutoHinter_GlyphLoadFunc
    *
    * @description:
-   *   This function is used to load, scale, and automatically hint a
-   *   glyph from a given face.
+   *   This function is used to load, scale, and automatically hint a glyph
+   *   from a given face.
    *
    * @input:
    *   face ::
@@ -176,8 +175,8 @@
    *     The load flags.
    *
    * @note:
-   *   This function is capable of loading composite glyphs by hinting
-   *   each sub-glyph independently (which improves quality).
+   *   This function is capable of loading composite glyphs by hinting each
+   *   sub-glyph independently (which improves quality).
    *
    *   It will call the font driver with @FT_Load_Glyph, with
    *   @FT_LOAD_NO_SCALE set.
@@ -208,6 +207,9 @@
   } FT_AutoHinter_InterfaceRec, *FT_AutoHinter_Interface;
 
 
+#define FT_DECLARE_AUTOHINTER_INTERFACE( class_ )            \
+  FT_CALLBACK_TABLE const FT_AutoHinter_InterfaceRec  class_;
+
 #define FT_DEFINE_AUTOHINTER_INTERFACE(       \
           class_,                             \
           reset_face_,                        \
diff --git a/include/freetype/internal/cffotypes.h b/include/freetype/internal/cffotypes.h
index c01dba4..50d5353 100644
--- a/include/freetype/internal/cffotypes.h
+++ b/include/freetype/internal/cffotypes.h
@@ -4,7 +4,7 @@
  *
  *   Basic OpenType/CFF object type definitions (specification).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,12 +19,11 @@
 #ifndef CFFOTYPES_H_
 #define CFFOTYPES_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_CFF_TYPES_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/cfftypes.h>
+#include <freetype/internal/tttypes.h>
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/pshints.h>
 
 
 FT_BEGIN_HEADER
@@ -76,7 +75,7 @@
    *   CFF_Internal
    *
    * @description:
-   *   The interface to the `internal' field of `FT_Size'.
+   *   The interface to the 'internal' field of `FT_Size`.
    */
   typedef struct  CFF_InternalRec_
   {
diff --git a/include/freetype/internal/cfftypes.h b/include/freetype/internal/cfftypes.h
index 534ee16..c252176 100644
--- a/include/freetype/internal/cfftypes.h
+++ b/include/freetype/internal/cfftypes.h
@@ -5,7 +5,7 @@
  *   Basic OpenType/CFF type definitions and interface (specification
  *   only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,13 +21,12 @@
 #define CFFTYPES_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TYPE1_TABLES_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/freetype.h>
+#include <freetype/t1tables.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/pshints.h>
+#include <freetype/internal/t1types.h>
 
 
 FT_BEGIN_HEADER
@@ -46,8 +45,7 @@
    *     The source input stream.
    *
    *   start ::
-   *     The position of the first index byte in the
-   *     input stream.
+   *     The position of the first index byte in the input stream.
    *
    *   count ::
    *     The number of elements in the index.
@@ -56,15 +54,13 @@
    *     The size in bytes of object offsets in index.
    *
    *   data_offset ::
-   *     The position of first data byte in the index's
-   *     bytes.
+   *     The position of first data byte in the index's bytes.
    *
    *   data_size ::
    *     The size of the data table in this index.
    *
    *   offsets ::
-   *     A table of element offsets in the index.  Must be
-   *     loaded explicitly.
+   *     A table of element offsets in the index.  Must be loaded explicitly.
    *
    *   bytes ::
    *     If the index is loaded in memory, its bytes.
@@ -319,7 +315,7 @@
     /* The normal stack then points to these values instead of the DICT   */
     /* because all other operators in Private DICT clear the stack.       */
     /* `blend_stack' could be cleared at each operator other than blend.  */
-    /* Blended values are stored as 5-byte fixed point values.            */
+    /* Blended values are stored as 5-byte fixed-point values.            */
 
     FT_Byte*  blend_stack;    /* base of stack allocation     */
     FT_Byte*  blend_top;      /* first empty slot             */
diff --git a/include/freetype/internal/compiler-macros.h b/include/freetype/internal/compiler-macros.h
new file mode 100644
index 0000000..7883317
--- /dev/null
+++ b/include/freetype/internal/compiler-macros.h
@@ -0,0 +1,340 @@
+/****************************************************************************
+ *
+ * internal/compiler-macros.h
+ *
+ *   Compiler-specific macro definitions used internally by FreeType.
+ *
+ * Copyright (C) 2020-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 INTERNAL_COMPILER_MACROS_H_
+#define INTERNAL_COMPILER_MACROS_H_
+
+#include <freetype/config/public-macros.h>
+
+FT_BEGIN_HEADER
+
+  /* Fix compiler warning with sgi compiler. */
+#if defined( __sgi ) && !defined( __GNUC__ )
+#  if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
+#    pragma set woff 3505
+#  endif
+#endif
+
+  /* Fix compiler warning with sgi compiler. */
+#if defined( __sgi ) && !defined( __GNUC__ )
+#  if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
+#    pragma set woff 3505
+#  endif
+#endif
+
+  /* Newer compilers warn for fall-through case statements. */
+#ifndef FALL_THROUGH
+#  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 )
+#    define FALL_THROUGH  __attribute__(( __fallthrough__ ))
+#  else
+#    define FALL_THROUGH  ( (void)0 )
+#  endif
+#endif
+
+  /*
+   * When defining a macro that expands to a non-trivial C statement, use
+   * FT_BEGIN_STMNT and FT_END_STMNT to enclose the macro's body.  This
+   * ensures there are no surprises when the macro is invoked in conditional
+   * branches.
+   *
+   * Example:
+   *
+   *   #define  LOG( ... )        \
+   *     FT_BEGIN_STMNT           \
+   *       if ( logging_enabled ) \
+   *         log( __VA_ARGS__ );  \
+   *     FT_END_STMNT
+   */
+#define FT_BEGIN_STMNT  do {
+#define FT_END_STMNT    } while ( 0 )
+
+  /*
+   * FT_DUMMY_STMNT expands to an empty C statement.  Useful for
+   * conditionally defined statement macros.
+   *
+   * Example:
+   *
+   *   #ifdef BUILD_CONFIG_LOGGING
+   *   #define  LOG( ... )         \
+   *      FT_BEGIN_STMNT           \
+   *        if ( logging_enabled ) \
+   *          log( __VA_ARGS__ );  \
+   *      FT_END_STMNT
+   *   #else
+   *   #  define LOG( ... )  FT_DUMMY_STMNT
+   *   #endif
+   */
+#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
+
+#ifdef __UINTPTR_TYPE__
+  /*
+   * GCC and Clang both provide a `__UINTPTR_TYPE__` that can be used to
+   * avoid a dependency on `stdint.h`.
+   */
+#  define FT_UINT_TO_POINTER( x )  (void *)(__UINTPTR_TYPE__)(x)
+#elif defined( _WIN64 )
+  /* only 64bit Windows uses the LLP64 data model, i.e., */
+  /* 32-bit integers, 64-bit pointers.                   */
+#  define FT_UINT_TO_POINTER( x )  (void *)(unsigned __int64)(x)
+#else
+#  define FT_UINT_TO_POINTER( x )  (void *)(unsigned long)(x)
+#endif
+
+  /*
+   * Use `FT_TYPEOF( type )` to cast a value to `type`.  This is useful to
+   * suppress signedness compilation warnings in macros.
+   *
+   * Example:
+   *
+   *   #define PAD_( x, n )  ( (x) & ~FT_TYPEOF( x )( (n) - 1 ) )
+   *
+   * (The `typeof` condition is taken from gnulib's `intprops.h` header
+   * file.)
+   */
+#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
+      ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
+        defined( __IBM__TYPEOF__ ) )                                 || \
+      ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
+#define FT_TYPEOF( type )  ( __typeof__ ( type ) )
+#else
+#define FT_TYPEOF( type )  /* empty */
+#endif
+
+  /*
+   * Mark a function declaration as internal to the library.  This ensures
+   * that it will not be exposed by default to client code, and helps
+   * generate smaller and faster code on ELF-based platforms.  Place this
+   * before a function declaration.
+   */
+
+  /* Visual C, mingw */
+#if defined( _WIN32 )
+#define FT_INTERNAL_FUNCTION_ATTRIBUTE  /* empty */
+
+  /* gcc, clang */
+#elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
+#define FT_INTERNAL_FUNCTION_ATTRIBUTE  \
+          __attribute__(( visibility( "hidden" ) ))
+
+  /* Sun */
+#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
+#define FT_INTERNAL_FUNCTION_ATTRIBUTE  __hidden
+
+#else
+#define FT_INTERNAL_FUNCTION_ATTRIBUTE  /* empty */
+#endif
+
+  /*
+   * FreeType supports compilation of its C sources with a C++ compiler (in
+   * C++ mode); this introduces a number of subtle issues.
+   *
+   * The main one is that a C++ function declaration and its definition must
+   * have the same 'linkage'.  Because all FreeType headers declare their
+   * functions with C linkage (i.e., within an `extern "C" { ... }` block
+   * due to the magic of FT_BEGIN_HEADER and FT_END_HEADER), their
+   * definition in FreeType sources should also be prefixed with `extern
+   * "C"` when compiled in C++ mode.
+   *
+   * The `FT_FUNCTION_DECLARATION` and `FT_FUNCTION_DEFINITION` macros are
+   * provided to deal with this case, as well as `FT_CALLBACK_DEF` and its
+   * siblings below.
+   */
+
+  /*
+   * `FT_FUNCTION_DECLARATION( type )` can be used to write a C function
+   * declaration to ensure it will have C linkage when the library is built
+   * with a C++ compiler.  The parameter is the function's return type, so a
+   * declaration would look like
+   *
+   *    FT_FUNCTION_DECLARATION( int )
+   *    foo( int x );
+   *
+   * NOTE: This requires that all uses are inside of `FT_BEGIN_HEADER ...
+   * FT_END_HEADER` blocks, which guarantees that the declarations have C
+   * linkage when the headers are included by C++ sources.
+   *
+   * NOTE: Do not use directly.  Use `FT_LOCAL`, `FT_BASE`, and `FT_EXPORT`
+   * instead.
+   */
+#define FT_FUNCTION_DECLARATION( x )  extern x
+
+  /*
+   * Same as `FT_FUNCTION_DECLARATION`, but for function definitions instead.
+   *
+   * NOTE: Do not use directly.  Use `FT_LOCAL_DEF`, `FT_BASE_DEF`, and
+   * `FT_EXPORT_DEF` instead.
+   */
+#ifdef __cplusplus
+#define FT_FUNCTION_DEFINITION( x )  extern "C" x
+#else
+#define FT_FUNCTION_DEFINITION( x )  x
+#endif
+
+  /*
+   * Use `FT_LOCAL` and `FT_LOCAL_DEF` to declare and define, respectively,
+   * an internal FreeType function that is only used by the sources of a
+   * single `src/module/` directory.  This ensures that the functions are
+   * turned into static ones at build time, resulting in smaller and faster
+   * code.
+   */
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+
+#define FT_LOCAL( x )      static x
+#define FT_LOCAL_DEF( x )  static x
+
+#else
+
+#define FT_LOCAL( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
+                           FT_FUNCTION_DECLARATION( x )
+#define FT_LOCAL_DEF( x )  FT_FUNCTION_DEFINITION( x )
+
+#endif  /* FT_MAKE_OPTION_SINGLE_OBJECT */
+
+  /*
+   * Use `FT_LOCAL_ARRAY` and `FT_LOCAL_ARRAY_DEF` to declare and define,
+   * respectively, a constant array that must be accessed from several
+   * sources in the same `src/module/` sub-directory, and which are internal
+   * to the library.
+   */
+#define FT_LOCAL_ARRAY( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
+                                 extern const x
+#define FT_LOCAL_ARRAY_DEF( x )  FT_FUNCTION_DEFINITION( const x )
+
+  /*
+   * `Use FT_BASE` and `FT_BASE_DEF` to declare and define, respectively, an
+   * internal library function that is used by more than a single module.
+   */
+#define FT_BASE( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
+                          FT_FUNCTION_DECLARATION( x )
+#define FT_BASE_DEF( x )  FT_FUNCTION_DEFINITION( x )
+
+
+  /*
+   * NOTE: Conditionally define `FT_EXPORT_VAR` due to its definition in
+   * `src/smooth/ftgrays.h` to make the header more portable.
+   */
+#ifndef FT_EXPORT_VAR
+#define FT_EXPORT_VAR( x )  FT_FUNCTION_DECLARATION( x )
+#endif
+
+  /*
+   * When compiling FreeType as a DLL or DSO with hidden visibility,
+   * some systems/compilers need a special attribute in front OR after
+   * the return type of function declarations.
+   *
+   * Two macros are used within the FreeType source code to define
+   * exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`.
+   *
+   * - `FT_EXPORT( return_type )`
+   *
+   *   is used in a function declaration, as in
+   *
+   *   ```
+   *     FT_EXPORT( FT_Error )
+   *     FT_Init_FreeType( FT_Library*  alibrary );
+   *   ```
+   *
+   * - `FT_EXPORT_DEF( return_type )`
+   *
+   *   is used in a function definition, as in
+   *
+   *   ```
+   *     FT_EXPORT_DEF( FT_Error )
+   *     FT_Init_FreeType( FT_Library*  alibrary )
+   *     {
+   *       ... some code ...
+   *       return FT_Err_Ok;
+   *     }
+   *   ```
+   *
+   * You can provide your own implementation of `FT_EXPORT` and
+   * `FT_EXPORT_DEF` here if you want.
+   *
+   * To export a variable, use `FT_EXPORT_VAR`.
+   */
+
+  /* See `freetype/config/public-macros.h` for the `FT_EXPORT` definition */
+#define FT_EXPORT_DEF( x )  FT_FUNCTION_DEFINITION( x )
+
+  /*
+   * The following macros are needed to compile the library with a
+   * C++ compiler and with 16bit compilers.
+   */
+
+  /*
+   * This is special.  Within C++, you must specify `extern "C"` for
+   * functions which are used via function pointers, and you also
+   * must do that for structures which contain function pointers to
+   * assure C linkage -- it's not possible to have (local) anonymous
+   * functions which are accessed by (global) function pointers.
+   *
+   *
+   * FT_CALLBACK_DEF is used to _define_ a callback function,
+   * located in the same source code file as the structure that uses
+   * it.  FT_COMPARE_DEF, in addition, ensures the `cdecl` calling
+   * convention on x86, required by the C library function `qsort`.
+   *
+   * FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare
+   * and define a callback function, respectively, in a similar way
+   * as FT_BASE and FT_BASE_DEF work.
+   *
+   * FT_CALLBACK_TABLE is used to _declare_ a constant variable that
+   * contains pointers to callback functions.
+   *
+   * FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable
+   * that contains pointers to callback functions.
+   *
+   *
+   * Some 16bit compilers have to redefine these macros to insert
+   * the infamous `_cdecl` or `__fastcall` declarations.
+   */
+#ifdef __cplusplus
+#define FT_CALLBACK_DEF( x )  extern "C"  x
+#else
+#define FT_CALLBACK_DEF( x )  static  x
+#endif
+
+#if defined( __GNUC__ ) && defined( __i386__ )
+#define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x ) __attribute__(( cdecl ))
+#elif defined( _MSC_VER ) && defined( _M_IX86 )
+#define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x ) __cdecl
+#elif defined( __WATCOMC__ ) && __WATCOMC__ >= 1240
+#define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x ) __watcall
+#else
+#define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x )
+#endif
+
+#define FT_BASE_CALLBACK( x )      FT_FUNCTION_DECLARATION( x )
+#define FT_BASE_CALLBACK_DEF( x )  FT_FUNCTION_DEFINITION( x )
+
+#ifndef FT_CALLBACK_TABLE
+#ifdef __cplusplus
+#define FT_CALLBACK_TABLE      extern "C"
+#define FT_CALLBACK_TABLE_DEF  extern "C"
+#else
+#define FT_CALLBACK_TABLE      extern
+#define FT_CALLBACK_TABLE_DEF  /* nothing */
+#endif
+#endif /* FT_CALLBACK_TABLE */
+
+FT_END_HEADER
+
+#endif  /* INTERNAL_COMPILER_MACROS_H_ */
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index 733b674..d1baa39 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -4,7 +4,7 @@
  *
  *   Arithmetic computations (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,9 @@
 #define FTCALC_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -252,7 +252,7 @@
    *   FT_MulDiv_No_Round
    *
    * @description:
-   *   A very simple function used to perform the computation `(a*b)/c'
+   *   A very simple function used to perform the computation '(a*b)/c'
    *   (without rounding) with maximum accuracy (it uses a 64-bit
    *   intermediate integer whenever necessary).
    *
@@ -268,9 +268,9 @@
    *     The divisor.
    *
    * @return:
-   *   The result of `(a*b)/c'.  This function never traps when trying to
-   *   divide by zero; it simply returns `MaxInt' or `MinInt' depending
-   *   on the signs of `a' and `b'.
+   *   The result of '(a*b)/c'.  This function never traps when trying to
+   *   divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on
+   *   the signs of 'a' and 'b'.
    */
   FT_BASE( FT_Long )
   FT_MulDiv_No_Round( FT_Long  a,
@@ -278,13 +278,46 @@
                       FT_Long  c );
 
 
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_MulAddFix
+   *
+   * @description:
+   *   Compute `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`, where `s[n]` is
+   *   usually a 16.16 scalar.
+   *
+   * @input:
+   *   s ::
+   *     The array of scalars.
+   *   f ::
+   *     The array of factors.
+   *   count ::
+   *     The number of entries in the array.
+   *
+   * @return:
+   *   The result of `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`.
+   *
+   * @note:
+   *   This function is currently used for the scaled delta computation of
+   *   variation stores.  It internally uses 64-bit data types when
+   *   available, otherwise it emulates 64-bit math by using 32-bit
+   *   operations, which produce a correct result but most likely at a slower
+   *   performance in comparison to the implementation base on `int64_t`.
+   *
+   */
+  FT_BASE( FT_Int32 )
+  FT_MulAddFix( FT_Fixed*  s,
+                FT_Int32*  f,
+                FT_UInt    count );
+
+
   /*
-   * A variant of FT_Matrix_Multiply which scales its result afterwards.
-   * The idea is that both `a' and `b' are scaled by factors of 10 so that
-   * the values are as precise as possible to get a correct result during
-   * the 64bit multiplication.  Let `sa' and `sb' be the scaling factors of
-   * `a' and `b', respectively, then the scaling factor of the result is
-   * `sa*sb'.
+   * A variant of FT_Matrix_Multiply which scales its result afterwards.  The
+   * idea is that both `a' and `b' are scaled by factors of 10 so that the
+   * values are as precise as possible to get a correct result during the
+   * 64bit multiplication.  Let `sa' and `sb' be the scaling factors of `a'
+   * and `b', respectively, then the scaling factor of the result is `sa*sb'.
    */
   FT_BASE( void )
   FT_Matrix_Multiply_Scaled( const FT_Matrix*  a,
@@ -318,22 +351,22 @@
 
 
   /*
-   * This function normalizes a vector and returns its original length.
-   * The normalized vector is a 16.16 fixed-point unit vector with length
-   * close to 0x10000.  The accuracy of the returned length is limited to
-   * 16 bits also.  The function utilizes quick inverse square root
-   * approximation without divisions and square roots relying on Newton's
-   * iterations instead.
+   * This function normalizes a vector and returns its original length.  The
+   * normalized vector is a 16.16 fixed-point unit vector with length close
+   * to 0x10000.  The accuracy of the returned length is limited to 16 bits
+   * also.  The function utilizes quick inverse square root approximation
+   * without divisions and square roots relying on Newton's iterations
+   * instead.
    */
   FT_BASE( FT_UInt32 )
   FT_Vector_NormLen( FT_Vector*  vector );
 
 
   /*
-   * Return -1, 0, or +1, depending on the orientation of a given corner.
-   * We use the Cartesian coordinate system, with positive vertical values
-   * going upwards.  The function returns +1 if the corner turns to the
-   * left, -1 to the right, and 0 for undecidable cases.
+   * Return -1, 0, or +1, depending on the orientation of a given corner.  We
+   * use the Cartesian coordinate system, with positive vertical values going
+   * upwards.  The function returns +1 if the corner turns to the left, -1 to
+   * the right, and 0 for undecidable cases.
    */
   FT_BASE( FT_Int )
   ft_corner_orientation( FT_Pos  in_x,
@@ -360,8 +393,8 @@
 
 #ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
 
-#if defined( __GNUC__ )                                          && \
-    ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) )
+#if defined( __clang__ ) || ( defined( __GNUC__ )                &&  \
+    ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) )
 
 #if FT_SIZEOF_INT == 4
 
@@ -371,14 +404,28 @@
 
 #define FT_MSB( x )  ( 31 - __builtin_clzl( x ) )
 
-#endif /* __GNUC__ */
+#endif
 
+#elif defined( _MSC_VER ) && _MSC_VER >= 1400
 
-#elif defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
+#if defined( _WIN32_WCE )
 
-#if FT_SIZEOF_INT == 4
+#include <cmnintrin.h>
+#pragma intrinsic( _CountLeadingZeros )
+
+#define FT_MSB( x )  ( 31 - _CountLeadingZeros( x ) )
+
+#elif defined( _M_ARM64 ) || defined( _M_ARM )
 
 #include <intrin.h>
+#pragma intrinsic( _CountLeadingZeros )
+
+#define FT_MSB( x )  ( 31 - _CountLeadingZeros( x ) )
+
+#elif defined( _M_IX86 ) || defined( _M_AMD64 ) || defined( _M_IA64 )
+
+#include <intrin.h>
+#pragma intrinsic( _BitScanReverse )
 
   static __inline FT_Int32
   FT_MSB_i386( FT_UInt32  x )
@@ -386,21 +433,45 @@
     unsigned long  where;
 
 
-    /* not available in older VC versions */
     _BitScanReverse( &where, x );
 
     return (FT_Int32)where;
   }
 
-#define FT_MSB( x )  ( FT_MSB_i386( x ) )
+#define FT_MSB( x )  FT_MSB_i386( x )
 
 #endif
 
-#endif /* _MSC_VER */
+#elif defined( __WATCOMC__ ) && defined( __386__ )
 
+  extern __inline FT_Int32
+  FT_MSB_i386( FT_UInt32  x );
+
+#pragma aux FT_MSB_i386 =             \
+  "bsr eax, eax"                      \
+  __parm [__eax] __nomemory           \
+  __value [__eax]                     \
+  __modify __exact [__eax] __nomemory;
+
+#define FT_MSB( x )  FT_MSB_i386( x )
+
+#elif defined( __DECC ) || defined( __DECCXX )
+
+#include <builtins.h>
+
+#define FT_MSB( x )  (FT_Int)( 63 - _leadz( x ) )
+
+#elif defined( _CRAYC )
+
+#include <intrinsics.h>
+
+#define FT_MSB( x )  (FT_Int)( 31 - _leadz32( x ) )
+
+#endif /* FT_MSB macro definitions */
 
 #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
 
+
 #ifndef FT_MSB
 
   FT_BASE( FT_Int )
@@ -433,7 +504,7 @@
    *     The value to compute the root for.
    *
    * @return:
-   *   The result of `sqrt(x)'.
+   *   The result of 'sqrt(x)'.
    *
    * @note:
    *   This function is not very fast.
@@ -450,8 +521,7 @@
 #define F2DOT14_TO_FIXED( x )  ( (FT_Long)(x) * 4 )      /* << 2  */
 #define FIXED_TO_INT( x )      ( FT_RoundFix( x ) >> 16 )
 
-#define ROUND_F26DOT6( x )     ( x >= 0 ? (    ( (x) + 32 ) & -64 )     \
-                                        : ( -( ( 32 - (x) ) & -64 ) ) )
+#define ROUND_F26DOT6( x )     ( ( (x) + 32 - ( x < 0 ) ) & -64 )
 
   /*
    * The following macros have two purposes.
@@ -489,6 +559,19 @@
 #define NEG_INT32( a )                                  \
           (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
 
+#ifdef FT_INT64
+
+#define ADD_INT64( a, b )                               \
+          (FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) )
+#define SUB_INT64( a, b )                               \
+          (FT_Int64)( (FT_UInt64)(a) - (FT_UInt64)(b) )
+#define MUL_INT64( a, b )                               \
+          (FT_Int64)( (FT_UInt64)(a) * (FT_UInt64)(b) )
+#define NEG_INT64( a )                                  \
+          (FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) )
+
+#endif /* FT_INT64 */
+
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h
index d6e8a3a..4e013ba 100644
--- a/include/freetype/internal/ftdebug.h
+++ b/include/freetype/internal/ftdebug.h
@@ -4,7 +4,7 @@
  *
  *   Debugging and logging component (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -15,7 +15,7 @@
  *
  *
  * IMPORTANT: A description of FreeType's debugging support can be
- *             found in `docs/DEBUG.TXT'.  Read it if you need to use or
+ *             found in 'docs/DEBUG.TXT'.  Read it if you need to use or
  *             understand this code.
  *
  */
@@ -27,11 +27,28 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
+
+#include "compiler-macros.h"
+
+#ifdef FT_DEBUG_LOGGING
+#define DLG_STATIC
+#include <dlg/output.h>
+#include <dlg/dlg.h>
+
+#include <freetype/ftlogging.h>
+#endif /* FT_DEBUG_LOGGING */
 
 
 FT_BEGIN_HEADER
 
+  /* force the definition of FT_DEBUG_LEVEL_TRACE if FT_DEBUG_LOGGING is */
+  /* already defined.                                                    */
+  /*                                                                     */
+#ifdef FT_DEBUG_LOGGING
+#undef  FT_DEBUG_LEVEL_TRACE
+#define FT_DEBUG_LEVEL_TRACE
+#endif
 
   /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */
   /* is already defined; this simplifies the following #ifdefs            */
@@ -44,8 +61,8 @@
 
   /**************************************************************************
    *
-   * Define the trace enums as well as the trace levels array when they
-   * are needed.
+   * Define the trace enums as well as the trace levels array when they are
+   * needed.
    *
    */
 
@@ -56,7 +73,7 @@
   /* defining the enumeration */
   typedef enum  FT_Trace_
   {
-#include FT_INTERNAL_TRACE_H
+#include <freetype/internal/fttrace.h>
     trace_count
 
   } FT_Trace;
@@ -80,16 +97,66 @@
    * Each component must define the macro FT_COMPONENT to a valid FT_Trace
    * value before using any TRACE macro.
    *
+   * To get consistent logging output, there should be no newline character
+   * (i.e., '\n') or a single trailing one in the message string of
+   * `FT_TRACEx` and `FT_ERROR`.
    */
 
+
+  /*************************************************************************
+   *
+   * If FT_DEBUG_LOGGING is enabled, tracing messages are sent to dlg's API.
+   * If FT_DEBUG_LOGGING is disabled, tracing messages are sent to
+   * `FT_Message` (defined in ftdebug.c).
+   */
+#ifdef FT_DEBUG_LOGGING
+
+  /* we need two macros to convert the names of `FT_COMPONENT` to a string */
+#define FT_LOGGING_TAG( x )   FT_LOGGING_TAG_( x )
+#define FT_LOGGING_TAG_( x )  #x
+
+  /* we need two macros to convert the component and the trace level */
+  /* to a string that combines them                                  */
+#define FT_LOGGING_TAGX( x, y )   FT_LOGGING_TAGX_( x, y )
+#define FT_LOGGING_TAGX_( x, y )  #x ":" #y
+
+
+#define FT_LOG( level, varformat )                                         \
+          do                                                               \
+          {                                                                \
+            const char*  dlg_tag = FT_LOGGING_TAGX( FT_COMPONENT, level ); \
+                                                                           \
+                                                                           \
+            ft_add_tag( dlg_tag );                                         \
+            if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
+            {                                                              \
+              if ( custom_output_handler != NULL )                         \
+                FT_Logging_Callback varformat;                             \
+              else                                                         \
+                dlg_trace varformat;                                       \
+            }                                                              \
+            ft_remove_tag( dlg_tag );                                      \
+          } while( 0 )
+
+#else /* !FT_DEBUG_LOGGING */
+
+#define FT_LOG( level, varformat )                                         \
+          do                                                               \
+          {                                                                \
+            if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
+              FT_Message varformat;                                        \
+          } while ( 0 )
+
+#endif /* !FT_DEBUG_LOGGING */
+
+
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-#define FT_TRACE( level, varformat )                      \
-          do                                              \
-          {                                               \
-            if ( ft_trace_levels[FT_COMPONENT] >= level ) \
-              FT_Message varformat;                       \
-          } while ( 0 )
+  /* we need two macros here to make cpp expand `FT_COMPONENT' */
+#define FT_TRACE_COMP( x )   FT_TRACE_COMP_( x )
+#define FT_TRACE_COMP_( x )  trace_ ## x
+
+#define FT_TRACE( level, varformat )  FT_LOG( level, varformat )
 
 #else /* !FT_DEBUG_LEVEL_TRACE */
 
@@ -111,8 +178,8 @@
    *   FT_DEBUG_LEVEL_TRACE definition.
    *
    * @note:
-   *   This function may be useful if you want to access elements of
-   *   the internal trace levels array by an index.
+   *   This function may be useful if you want to access elements of the
+   *   internal trace levels array by an index.
    */
   FT_BASE( FT_Int )
   FT_Trace_Get_Count( void );
@@ -131,8 +198,8 @@
    *
    * @return:
    *   The name of the trace component.  This is a statically allocated
-   *   C~string, so do not free it after use.  NULL if FreeType is not built
-   *   with FT_DEBUG_LEVEL_TRACE definition.
+   *   C~string, so do not free it after use.  `NULL` if FreeType is not
+   *   built with FT_DEBUG_LEVEL_TRACE definition.
    *
    * @note:
    *   Use @FT_Trace_Get_Count to get the number of available trace
@@ -198,7 +265,32 @@
 
 #ifdef FT_DEBUG_LEVEL_ERROR
 
-#define FT_ERROR( varformat )  FT_Message  varformat
+  /**************************************************************************
+   *
+   * If FT_DEBUG_LOGGING is enabled, error messages are sent to dlg's API.
+   * If FT_DEBUG_LOGGING is disabled, error messages are sent to `FT_Message`
+   * (defined in ftdebug.c).
+   *
+   */
+#ifdef FT_DEBUG_LOGGING
+
+#define FT_ERROR( varformat )                                      \
+          do                                                       \
+          {                                                        \
+            const char*  dlg_tag = FT_LOGGING_TAG( FT_COMPONENT ); \
+                                                                   \
+                                                                   \
+            ft_add_tag( dlg_tag );                                 \
+            dlg_trace varformat;                                   \
+            ft_remove_tag( dlg_tag );                              \
+          } while ( 0 )
+
+#else /* !FT_DEBUG_LOGGING */
+
+#define FT_ERROR( varformat )  FT_Message varformat
+
+#endif /* !FT_DEBUG_LOGGING */
+
 
 #else  /* !FT_DEBUG_LEVEL_ERROR */
 
@@ -209,8 +301,8 @@
 
   /**************************************************************************
    *
-   * Define the FT_ASSERT and FT_THROW macros.  The call to `FT_Throw'
-   * makes it possible to easily set a breakpoint at this function.
+   * Define the FT_ASSERT and FT_THROW macros.  The call to `FT_Throw` makes
+   * it possible to easily set a breakpoint at this function.
    *
    */
 
@@ -241,7 +333,7 @@
 
   /**************************************************************************
    *
-   * Define `FT_Message' and `FT_Panic' when needed.
+   * Define `FT_Message` and `FT_Panic` when needed.
    *
    */
 
@@ -271,6 +363,77 @@
   FT_BASE( void )
   ft_debug_init( void );
 
+
+#ifdef FT_DEBUG_LOGGING
+
+  /**************************************************************************
+   *
+   * 'dlg' uses output handlers to control how and where log messages are
+   * printed.  Therefore we need to define a default output handler for
+   * FreeType.
+   */
+  FT_BASE( void )
+  ft_log_handler( const struct dlg_origin*  origin,
+                  const char*               string,
+                  void*                     data );
+
+
+  /**************************************************************************
+   *
+   * 1. `ft_default_log_handler` stores the function pointer that is used
+   *    internally by FreeType to print logs to a file.
+   *
+   * 2. `custom_output_handler` stores the function pointer to the callback
+   *    function provided by the user.
+   *
+   * It is defined in `ftdebug.c`.
+   */
+  extern dlg_handler            ft_default_log_handler;
+  extern FT_Custom_Log_Handler  custom_output_handler;
+
+
+  /**************************************************************************
+   *
+   * If FT_DEBUG_LOGGING macro is enabled, FreeType needs to initialize and
+   * un-initialize `FILE*`.
+   *
+   * These functions are defined in `ftdebug.c`.
+   */
+  FT_BASE( void )
+  ft_logging_init( void );
+
+  FT_BASE( void )
+  ft_logging_deinit( void );
+
+
+  /**************************************************************************
+   *
+   * For printing the name of `FT_COMPONENT` along with the actual log we
+   * need to add a tag with the name of `FT_COMPONENT`.
+   *
+   * These functions are defined in `ftdebug.c`.
+   */
+  FT_BASE( void )
+  ft_add_tag( const char*  tag );
+
+  FT_BASE( void )
+  ft_remove_tag( const char*  tag );
+
+
+  /**************************************************************************
+   *
+   * A function to print log data using a custom callback logging function
+   * (which is set using `FT_Set_Log_Handler`).
+   *
+   * This function is defined in `ftdebug.c`.
+   */
+  FT_BASE( void )
+  FT_Logging_Callback( const char*  fmt,
+                       ... );
+
+#endif /* FT_DEBUG_LOGGING */
+
+
 FT_END_HEADER
 
 #endif /* FTDEBUG_H_ */
diff --git a/include/freetype/internal/ftdrv.h b/include/freetype/internal/ftdrv.h
index 745b78a..f78912c 100644
--- a/include/freetype/internal/ftdrv.h
+++ b/include/freetype/internal/ftdrv.h
@@ -4,7 +4,7 @@
  *
  *   FreeType internal font driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,9 @@
 #define FTDRV_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -129,46 +129,37 @@
    *
    *
    *   load_glyph ::
-   *     A function handle to load a glyph to a slot.
-   *     This field is mandatory!
+   *     A function handle to load a glyph to a slot.  This field is
+   *     mandatory!
    *
    *   get_kerning ::
-   *     A function handle to return the unscaled
-   *     kerning for a given pair of glyphs.  Can be
-   *     set to 0 if the format doesn't support
-   *     kerning.
+   *     A function handle to return the unscaled kerning for a given pair of
+   *     glyphs.  Can be set to 0 if the format doesn't support kerning.
    *
    *   attach_file ::
-   *     This function handle is used to read
-   *     additional data for a face from another
-   *     file/stream.  For example, this can be used to
-   *     add data from AFM or PFM files on a Type 1
-   *     face, or a CIDMap on a CID-keyed face.
+   *     This function handle is used to read additional data for a face from
+   *     another file/stream.  For example, this can be used to add data from
+   *     AFM or PFM files on a Type 1 face, or a CIDMap on a CID-keyed face.
    *
    *   get_advances ::
-   *     A function handle used to return advance
-   *     widths of `count' glyphs (in font units),
-   *     starting at `first'.  The `vertical' flag must
-   *     be set to get vertical advance heights.  The
-   *     `advances' buffer is caller-allocated.
-   *     The idea of this function is to be able to
-   *     perform device-independent text layout without
-   *     loading a single glyph image.
+   *     A function handle used to return advance widths of 'count' glyphs
+   *     (in font units), starting at 'first'.  The 'vertical' flag must be
+   *     set to get vertical advance heights.  The 'advances' buffer is
+   *     caller-allocated.  The idea of this function is to be able to
+   *     perform device-independent text layout without loading a single
+   *     glyph image.
    *
    *   request_size ::
-   *     A handle to a function used to request the new
-   *     character size.  Can be set to 0 if the
-   *     scaling done in the base layer suffices.
+   *     A handle to a function used to request the new character size.  Can
+   *     be set to 0 if the scaling done in the base layer suffices.
    *
    *   select_size ::
-   *     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.
+   *     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.
+   *   Most function pointers, with the exception of `load_glyph`, can be set
+   *   to 0 to indicate a default behaviour.
    */
   typedef struct  FT_Driver_ClassRec_
   {
@@ -206,8 +197,8 @@
    *   FT_DECLARE_DRIVER
    *
    * @description:
-   *   Used to create a forward declaration of an FT_Driver_ClassRec
-   *   struct instance.
+   *   Used to create a forward declaration of an FT_Driver_ClassRec struct
+   *   instance.
    *
    * @macro:
    *   FT_DEFINE_DRIVER
@@ -215,12 +206,12 @@
    * @description:
    *   Used to initialize an instance of FT_Driver_ClassRec struct.
    *
-   *   `ftinit.c' (ft_create_default_module_classes) already contains a
-   *   mechanism to call these functions for the default modules
-   *   described in `ftmodule.h'.
+   *   `ftinit.c` (ft_create_default_module_classes) already contains a
+   *   mechanism to call these functions for the default modules described in
+   *   `ftmodule.h`.
    *
-   *   The struct will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   The struct will be allocated in the global scope (or the scope where
+   *   the macro is used).
    */
 #define FT_DECLARE_DRIVER( class_ )  \
   FT_CALLBACK_TABLE                  \
diff --git a/include/freetype/internal/ftgloadr.h b/include/freetype/internal/ftgloadr.h
index c731b2d..36e5509 100644
--- a/include/freetype/internal/ftgloadr.h
+++ b/include/freetype/internal/ftgloadr.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph loader (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,9 @@
 #define FTGLOADR_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -138,13 +138,6 @@
   FT_BASE( void )
   FT_GlyphLoader_Add( FT_GlyphLoader  loader );
 
-  /* copy points from one glyph loader to another */
-  FT_BASE( FT_Error )
-  FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,
-                             FT_GlyphLoader  source );
-
- /* */
-
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/fthash.h b/include/freetype/internal/fthash.h
index 2491880..622ec76 100644
--- a/include/freetype/internal/fthash.h
+++ b/include/freetype/internal/fthash.h
@@ -43,8 +43,7 @@
 #define FTHASH_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h
index f15c77d..5eb1d21 100644
--- a/include/freetype/internal/ftmemory.h
+++ b/include/freetype/internal/ftmemory.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType memory management macros (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,8 +22,9 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_TYPES_H
+#include <freetype/fttypes.h>
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -34,7 +35,7 @@
    *   FT_SET_ERROR
    *
    * @description:
-   *   This macro is used to set an implicit `error' variable to a given
+   *   This macro is used to set an implicit 'error' variable to a given
    *   expression's value (usually a function call), and convert it to a
    *   boolean which is set whenever the value is != 0.
    */
@@ -57,10 +58,18 @@
   /*************************************************************************/
 
 
+  /* The calculation `NULL + n' is undefined in C.  Even if the resulting */
+  /* pointer doesn't get dereferenced, this causes warnings with          */
+  /* sanitizers.                                                          */
+  /*                                                                      */
+  /* We thus provide a macro that should be used if `base' can be NULL.   */
+#define FT_OFFSET( base, count )  ( (base) ? (base) + (count) : NULL )
+
+
   /*
    * C++ refuses to handle statements like p = (void*)anything, with `p' a
-   * typed pointer.  Since we don't have a `typeof' operator in standard
-   * C++, we have to use a template to emulate it.
+   * typed pointer.  Since we don't have a `typeof' operator in standard C++,
+   * we have to use a template to emulate it.
    */
 
 #ifdef __cplusplus
@@ -87,15 +96,15 @@
 
 #ifdef FT_DEBUG_MEMORY
 
-  FT_BASE( const char* )  _ft_debug_file;
-  FT_BASE( long )         _ft_debug_lineno;
+  FT_BASE( const char* )  ft_debug_file_;
+  FT_BASE( long )         ft_debug_lineno_;
 
-#define FT_DEBUG_INNER( exp )  ( _ft_debug_file   = __FILE__, \
-                                 _ft_debug_lineno = __LINE__, \
+#define FT_DEBUG_INNER( exp )  ( ft_debug_file_   = __FILE__, \
+                                 ft_debug_lineno_ = __LINE__, \
                                  (exp) )
 
-#define FT_ASSIGNP_INNER( p, exp )  ( _ft_debug_file   = __FILE__, \
-                                      _ft_debug_lineno = __LINE__, \
+#define FT_ASSIGNP_INNER( p, exp )  ( ft_debug_file_   = __FILE__, \
+                                      ft_debug_lineno_ = __LINE__, \
                                       FT_ASSIGNP( p, exp ) )
 
 #else /* !FT_DEBUG_MEMORY */
@@ -107,8 +116,8 @@
 
 
   /*
-   * The allocation functions return a pointer, and the error code
-   * is written to through the `p_error' parameter.
+   * The allocation functions return a pointer, and the error code is written
+   * to through the `p_error' parameter.
    */
 
   /* The `q' variants of the functions below (`q' for `quick') don't fill */
@@ -153,10 +162,10 @@
                                                (FT_Long)(size), \
                                                &error ) )
 
-#define FT_MEM_FREE( ptr )                \
-          FT_BEGIN_STMNT                  \
-            ft_mem_free( memory, (ptr) ); \
-            (ptr) = NULL;                 \
+#define FT_MEM_FREE( ptr )                                  \
+          FT_BEGIN_STMNT                                    \
+            FT_DEBUG_INNER( ft_mem_free( memory, (ptr) ) ); \
+            (ptr) = NULL;                                   \
           FT_END_STMNT
 
 #define FT_MEM_NEW( ptr )                        \
@@ -253,9 +262,8 @@
 
 
   /*
-   * Return the maximum number of addressable elements in an array.
-   * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid
-   * any problems.
+   * Return the maximum number of addressable elements in an array.  We limit
+   * ourselves to INT_MAX, rather than UINT_MAX, to avoid any problems.
    */
 #define FT_ARRAY_MAX( ptr )           ( FT_INT_MAX / sizeof ( *(ptr) ) )
 
@@ -336,14 +344,13 @@
 #define FT_RENEW_ARRAY( ptr, curcnt, newcnt )                           \
           FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
 
-#define FT_QNEW( ptr )                           \
-          FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) )
+#define FT_QNEW( ptr )  FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) )
 
-#define FT_QNEW_ARRAY( ptr, count )                          \
-          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
+#define FT_QNEW_ARRAY( ptr, count )                           \
+          FT_MEM_SET_ERROR( FT_MEM_QNEW_ARRAY( ptr, count ) )
 
-#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt )                          \
-          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
+#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt )                           \
+          FT_MEM_SET_ERROR( FT_MEM_QRENEW_ARRAY( ptr, curcnt, newcnt ) )
 
 
   FT_BASE( FT_Pointer )
@@ -382,8 +389,6 @@
 #define FT_STRCPYN( dst, src, size )                                         \
           ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) )
 
- /* */
-
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/ftmmtypes.h b/include/freetype/internal/ftmmtypes.h
new file mode 100644
index 0000000..b7c66c3
--- /dev/null
+++ b/include/freetype/internal/ftmmtypes.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+ *
+ * ftmmtypes.h
+ *
+ *   OpenType Variations type definitions for internal use
+ *   with the multi-masters service (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and
+ * Dominik Röttsches.
+ *
+ * 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 FTMMTYPES_H_
+#define FTMMTYPES_H_
+
+FT_BEGIN_HEADER
+
+
+  typedef FT_Int32  FT_ItemVarDelta;
+
+  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  */
+
+  } GX_ItemVarDataRec, *GX_ItemVarData;
+
+
+  /* contribution of one axis to a region */
+  typedef struct  GX_AxisCoordsRec_
+  {
+    FT_Fixed  startCoord;
+    FT_Fixed  peakCoord;      /* zero means no effect (factor = 1) */
+    FT_Fixed  endCoord;
+
+  } GX_AxisCoordsRec, *GX_AxisCoords;
+
+
+  typedef struct  GX_VarRegionRec_
+  {
+    GX_AxisCoords  axisList;               /* array of axisCount records */
+
+  } GX_VarRegionRec, *GX_VarRegion;
+
+
+  /* item variation store */
+  typedef struct  GX_ItemVarStoreRec_
+  {
+    FT_UInt         dataCount;
+    GX_ItemVarData  varData;            /* array of dataCount records;     */
+                                        /* use `outerIndex' for this array */
+    FT_UShort     axisCount;
+    FT_UInt       regionCount;          /* total number of regions defined */
+    GX_VarRegion  varRegionList;
+
+  } GX_ItemVarStoreRec, *GX_ItemVarStore;
+
+
+  typedef struct  GX_DeltaSetIdxMapRec_
+  {
+    FT_ULong  mapCount;
+    FT_UInt*  outerIndex;               /* indices to item var data */
+    FT_UInt*  innerIndex;               /* indices to delta set     */
+
+  } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
+
+
+FT_END_HEADER
+
+#endif /* FTMMTYPES_H_ */
+
+
+/* END */
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index 88ced18..28bc9b6 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType private base classes (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,21 +26,21 @@
 #ifndef FTOBJS_H_
 #define FTOBJS_H_
 
-#include <ft2build.h>
-#include FT_RENDER_H
-#include FT_SIZES_H
-#include FT_LCD_FILTER_H
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_GLYPH_LOADER_H
-#include FT_INTERNAL_DRIVER_H
-#include FT_INTERNAL_AUTOHINT_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_INTERNAL_CALC_H
+#include <freetype/ftrender.h>
+#include <freetype/ftsizes.h>
+#include <freetype/ftlcdfil.h>
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftgloadr.h>
+#include <freetype/internal/ftdrv.h>
+#include <freetype/internal/autohint.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/ftcalc.h>
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-#include FT_INCREMENTAL_H
+#include <freetype/ftincrem.h>
 #endif
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -73,9 +73,9 @@
 #define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )
 
   /*
-   * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
-   * algorithm.  We use alpha = 1, beta = 3/8, giving us results with a
-   * largest error less than 7% compared to the exact value.
+   * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' algorithm.
+   * We use alpha = 1, beta = 3/8, giving us results with a largest error
+   * less than 7% compared to the exact value.
    */
 #define FT_HYPOT( x, y )                 \
           ( x = FT_ABS( x ),             \
@@ -110,9 +110,8 @@
 
 
   /*
-   * character classification functions -- since these are used to parse
-   * font files, we must not use those in <ctypes.h> which are
-   * locale-dependent
+   * character classification functions -- since these are used to parse font
+   * files, we must not use those in <ctypes.h> which are locale-dependent
    */
 #define  ft_isdigit( x )   ( ( (unsigned)(x) - '0' ) < 10U )
 
@@ -186,7 +185,7 @@
                                FT_UInt32  char_code,
                                FT_UInt32  variant_selector );
 
-  typedef FT_Bool
+  typedef FT_Int
   (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap    cmap,
                                    FT_UInt32  char_code,
                                    FT_UInt32  variant_selector );
@@ -227,8 +226,8 @@
   } FT_CMap_ClassRec;
 
 
-#define FT_DECLARE_CMAP_CLASS( class_ )              \
-  FT_CALLBACK_TABLE const  FT_CMap_ClassRec class_;
+#define FT_DECLARE_CMAP_CLASS( class_ )            \
+  FT_CALLBACK_TABLE const FT_CMap_ClassRec  class_;
 
 #define FT_DEFINE_CMAP_CLASS(       \
           class_,                   \
@@ -279,14 +278,12 @@
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 
   typedef void  (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap*      bitmap,
-                                            FT_Render_Mode  render_mode,
                                             FT_Byte*        weights );
 
 
   /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
   FT_BASE( void )
   ft_lcd_filter_fir( FT_Bitmap*           bitmap,
-                     FT_Render_Mode       mode,
                      FT_LcdFiveTapFilter  weights );
 
 #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
@@ -297,67 +294,65 @@
    *   FT_Face_InternalRec
    *
    * @description:
-   *   This structure contains the internal fields of each FT_Face
-   *   object.  These fields may change between different releases of
-   *   FreeType.
+   *   This structure contains the internal fields of each FT_Face object.
+   *   These fields may change between different releases of FreeType.
    *
    * @fields:
    *   max_points ::
-   *     The maximum number of points used to store the vectorial outline
+   *     The maximum number of points used to store the vectorial outline of
+   *     any glyph in this face.  If this value cannot be known in advance,
+   *     or if the face isn't scalable, this should be set to 0.  Only
+   *     relevant for scalable formats.
+   *
+   *   max_contours ::
+   *     The maximum number of contours used to store the vectorial outline
    *     of any glyph in this face.  If this value cannot be known in
    *     advance, or if the face isn't scalable, this should be set to 0.
    *     Only relevant for scalable formats.
    *
-   *   max_contours ::
-   *     The maximum number of contours used to store the vectorial
-   *     outline of any glyph in this face.  If this value cannot be
-   *     known in advance, or if the face isn't scalable, this should be
-   *     set to 0.  Only relevant for scalable formats.
-   *
    *   transform_matrix ::
-   *     A 2x2 matrix of 16.16 coefficients used to transform glyph
-   *     outlines after they are loaded from the font.  Only used by the
-   *     convenience functions.
+   *     A 2x2 matrix of 16.16 coefficients used to transform glyph outlines
+   *     after they are loaded from the font.  Only used by the convenience
+   *     functions.
    *
    *   transform_delta ::
-   *     A translation vector used to transform glyph outlines after they
-   *     are loaded from the font.  Only used by the convenience
-   *     functions.
+   *     A translation vector used to transform glyph outlines after they are
+   *     loaded from the font.  Only used by the convenience functions.
    *
    *   transform_flags ::
    *     Some flags used to classify the transform.  Only used by the
    *     convenience functions.
    *
    *   services ::
-   *     A cache for frequently used services.  It should be only
-   *     accessed with the macro `FT_FACE_LOOKUP_SERVICE'.
+   *     A cache for frequently used services.  It should be only accessed
+   *     with the macro `FT_FACE_LOOKUP_SERVICE`.
    *
    *   incremental_interface ::
-   *     If non-null, the interface through which glyph data and metrics
-   *     are loaded incrementally for faces that do not provide all of
-   *     this data when first opened.  This field exists only if
+   *     If non-null, the interface through which glyph data and metrics are
+   *     loaded incrementally for faces that do not provide all of this data
+   *     when first opened.  This field exists only if
    *     @FT_CONFIG_OPTION_INCREMENTAL is defined.
    *
    *   no_stem_darkening ::
-   *     Overrides the module-level default, see @stem-darkening[cff],
-   *     for example.  FALSE and TRUE toggle stem darkening on and off,
+   *     Overrides the module-level default, see @stem-darkening[cff], for
+   *     example.  FALSE and TRUE toggle stem darkening on and off,
    *     respectively, value~-1 means to use the module/driver default.
    *
    *   random_seed ::
-   *     If positive, override the seed value for the CFF `random'
-   *     operator.  Value~0 means to use the font's value.  Value~-1
-   *     means to use the CFF driver's default.
+   *     If positive, override the seed value for the CFF 'random' operator.
+   *     Value~0 means to use the font's value.  Value~-1 means to use the
+   *     CFF driver's default.
    *
    *   lcd_weights ::
    *   lcd_filter_func ::
-   *     These fields specify the LCD filtering weights and callback
-   *     function for ClearType-style subpixel rendering.
+   *     These fields specify the LCD filtering weights and callback function
+   *     for ClearType-style subpixel rendering.
    *
    *   refcount ::
    *     A counter initialized to~1 at the time an @FT_Face structure is
    *     created.  @FT_Reference_Face increments this counter, and
-   *     @FT_Done_Face only destroys a face if the counter is~1,
-   *     otherwise it simply decrements it.
+   *     @FT_Done_Face only destroys a face if the counter is~1, otherwise it
+   *     simply decrements it.
    */
   typedef struct  FT_Face_InternalRec_
   {
@@ -396,29 +391,24 @@
    *
    * @fields:
    *   loader ::
-   *     The glyph loader object used to load outlines
-   *     into the glyph slot.
+   *     The glyph loader object used to load outlines into the glyph slot.
    *
    *   flags ::
-   *     Possible values are zero or
-   *     FT_GLYPH_OWN_BITMAP.  The latter indicates
-   *     that the FT_GlyphSlot structure owns the
-   *     bitmap buffer.
+   *     Possible values are zero or FT_GLYPH_OWN_BITMAP.  The latter
+   *     indicates that the FT_GlyphSlot structure owns the bitmap buffer.
    *
    *   glyph_transformed ::
-   *     Boolean.  Set to TRUE when the loaded glyph
-   *     must be transformed through a specific
-   *     font transformation.  This is _not_ the same
-   *     as the face transform set through
-   *     FT_Set_Transform().
+   *     Boolean.  Set to TRUE when the loaded glyph must be transformed
+   *     through a specific font transformation.  This is _not_ the same as
+   *     the face transform set through FT_Set_Transform().
    *
    *   glyph_matrix ::
-   *     The 2x2 matrix corresponding to the glyph
-   *     transformation, if necessary.
+   *     The 2x2 matrix corresponding to the glyph transformation, if
+   *     necessary.
    *
    *   glyph_delta ::
-   *     The 2d translation vector corresponding to
-   *     the glyph transformation, if necessary.
+   *     The 2d translation vector corresponding to the glyph transformation,
+   *     if necessary.
    *
    *   glyph_hints ::
    *     Format-specific glyph hints management.
@@ -428,7 +418,8 @@
    *     initializing the glyph slot.
    */
 
-#define FT_GLYPH_OWN_BITMAP  0x1U
+#define FT_GLYPH_OWN_BITMAP    0x1U
+#define FT_GLYPH_OWN_GZIP_SVG  0x2U
 
   typedef struct  FT_Slot_InternalRec_
   {
@@ -450,8 +441,7 @@
    *   FT_Size_InternalRec
    *
    * @description:
-   *   This structure contains the internal fields of each FT_Size
-   *   object.
+   *   This structure contains the internal fields of each FT_Size object.
    *
    * @fields:
    *   module_data ::
@@ -568,8 +558,8 @@
    *   A module-specific interface if available, 0 otherwise.
    *
    * @note:
-   *   You should better be familiar with FreeType internals to know
-   *   which module to look for, and what its interface is :-)
+   *   You should better be familiar with FreeType internals to know which
+   *   module to look for, and what its interface is :-)
    */
   FT_BASE( const void* )
   FT_Get_Module_Interface( FT_Library   library,
@@ -627,10 +617,9 @@
    *   FT_New_GlyphSlot
    *
    * @description:
-   *   It is sometimes useful to have more than one glyph slot for a
-   *   given face object.  This function is used to create additional
-   *   slots.  All of them are automatically discarded when the face is
-   *   destroyed.
+   *   It is sometimes useful to have more than one glyph slot for a given
+   *   face object.  This function is used to create additional slots.  All
+   *   of them are automatically discarded when the face is destroyed.
    *
    * @input:
    *   face ::
@@ -655,8 +644,8 @@
    *
    * @description:
    *   Destroys a given glyph slot.  Remember however that all slots are
-   *   automatically destroyed with its parent.  Using this function is
-   *   not always mandatory.
+   *   automatically destroyed with its parent.  Using this function is not
+   *   always mandatory.
    *
    * @input:
    *   slot ::
@@ -665,7 +654,7 @@
   FT_BASE( void )
   FT_Done_GlyphSlot( FT_GlyphSlot  slot );
 
- /* */
+  /* */
 
 #define FT_REQUEST_WIDTH( req )                                            \
           ( (req)->horiResolution                                          \
@@ -685,7 +674,7 @@
 
 
   /* Set the metrics according to a size request. */
-  FT_BASE( void )
+  FT_BASE( FT_Error )
   FT_Request_Metrics( FT_Face          face,
                       FT_Size_Request  req );
 
@@ -711,8 +700,9 @@
   ft_glyphslot_free_bitmap( FT_GlyphSlot  slot );
 
 
-  /* Preset bitmap metrics of an outline glyphslot prior to rendering. */
-  FT_BASE( void )
+  /* Preset bitmap metrics of an outline glyphslot prior to rendering */
+  /* and check whether the truncated bbox is too large for rendering. */
+  FT_BASE( FT_Bool )
   ft_glyphslot_preset_bitmap( FT_GlyphSlot      slot,
                               FT_Render_Mode    mode,
                               const FT_Vector*  origin );
@@ -789,25 +779,23 @@
    *   FT_DriverRec
    *
    * @description:
-   *   The root font driver class.  A font driver is responsible for
-   *   managing and loading font files of a given format.
+   *   The root font driver class.  A font driver is responsible for managing
+   *   and loading font files of a given format.
    *
    * @fields:
    *   root ::
    *     Contains the fields of the root module class.
    *
    *   clazz ::
-   *     A pointer to the font driver's class.  Note that
-   *     this is NOT root.clazz.  `class' wasn't used
-   *     as it is a reserved word in C++.
+   *     A pointer to the font driver's class.  Note that this is NOT
+   *     root.clazz.  'class' wasn't used as it is a reserved word in C++.
    *
    *   faces_list ::
-   *     The list of faces currently opened by this
-   *     driver.
+   *     The list of faces currently opened by this driver.
    *
    *   glyph_loader ::
-   *     Unused.  Used to be glyph loader for all faces
-   *     managed by this driver.
+   *     Unused.  Used to be glyph loader for all faces managed by this
+   *     driver.
    */
   typedef struct  FT_DriverRec_
   {
@@ -832,25 +820,19 @@
   /*************************************************************************/
 
 
-  /* This hook is used by the TrueType debugger.  It must be set to an */
-  /* alternate truetype bytecode interpreter function.                 */
-#define FT_DEBUG_HOOK_TRUETYPE  0
-
-
   /**************************************************************************
    *
    * @struct:
    *   FT_LibraryRec
    *
    * @description:
-   *   The FreeType library class.  This is the root of all FreeType
-   *   data.  Use FT_New_Library() to create a library object, and
-   *   FT_Done_Library() to discard it and all child objects.
+   *   The FreeType library class.  This is the root of all FreeType data.
+   *   Use FT_New_Library() to create a library object, and FT_Done_Library()
+   *   to discard it and all child objects.
    *
    * @fields:
    *   memory ::
-   *     The library's memory object.  Manages memory
-   *     allocation.
+   *     The library's memory object.  Manages memory allocation.
    *
    *   version_major ::
    *     The major version number of the library.
@@ -862,60 +844,52 @@
    *     The current patch level of the library.
    *
    *   num_modules ::
-   *     The number of modules currently registered
-   *     within this library.  This is set to 0 for new
-   *     libraries.  New modules are added through the
-   *     FT_Add_Module() API function.
+   *     The number of modules currently registered within this library.
+   *     This is set to 0 for new libraries.  New modules are added through
+   *     the FT_Add_Module() API function.
    *
    *   modules ::
-   *     A table used to store handles to the currently
-   *     registered modules. Note that each font driver
-   *     contains a list of its opened faces.
+   *     A table used to store handles to the currently registered
+   *     modules. Note that each font driver contains a list of its opened
+   *     faces.
    *
    *   renderers ::
-   *     The list of renderers currently registered
-   *     within the library.
+   *     The list of renderers currently registered within the library.
    *
    *   cur_renderer ::
-   *     The current outline renderer.  This is a
-   *     shortcut used to avoid parsing the list on
-   *     each call to FT_Outline_Render().  It is a
-   *     handle to the current renderer for the
-   *     FT_GLYPH_FORMAT_OUTLINE format.
+   *     The current outline renderer.  This is a shortcut used to avoid
+   *     parsing the list on each call to FT_Outline_Render().  It is a
+   *     handle to the current renderer for the FT_GLYPH_FORMAT_OUTLINE
+   *     format.
    *
    *   auto_hinter ::
    *     The auto-hinter module interface.
    *
    *   debug_hooks ::
-   *     An array of four function pointers that allow
-   *     debuggers to hook into a font format's
-   *     interpreter.  Currently, only the TrueType
-   *     bytecode debugger uses this.
+   *     An array of four function pointers that allow debuggers to hook into
+   *     a font format's interpreter.  Currently, only the TrueType bytecode
+   *     debugger uses this.
    *
    *   lcd_weights ::
-   *     The LCD filter weights for ClearType-style
-   *     subpixel rendering.
+   *     The LCD filter weights for ClearType-style subpixel rendering.
    *
    *   lcd_filter_func ::
-   *     The LCD filtering callback function for
-   *     for ClearType-style subpixel rendering.
+   *     The LCD filtering callback function for for ClearType-style subpixel
+   *     rendering.
    *
    *   lcd_geometry ::
-   *     This array specifies LCD subpixel geometry
-   *     and controls Harmony LCD rendering technique,
-   *     alternative to ClearType.
+   *     This array specifies LCD subpixel geometry and controls Harmony LCD
+   *     rendering technique, alternative to ClearType.
    *
    *   pic_container ::
-   *     Contains global structs and tables, instead
-   *     of defining them globally.
+   *     Contains global structs and tables, instead of defining them
+   *     globally.
    *
    *   refcount ::
-   *     A counter initialized to~1 at the time an
-   *     @FT_Library structure is created.
-   *     @FT_Reference_Library increments this counter,
-   *     and @FT_Done_Library only destroys a library
-   *     if the counter is~1, otherwise it simply
-   *     decrements it.
+   *     A counter initialized to~1 at the time an @FT_Library structure is
+   *     created.  @FT_Reference_Library increments this counter, and
+   *     @FT_Done_Library only destroys a library if the counter is~1,
+   *     otherwise it simply decrements it.
    */
   typedef struct  FT_LibraryRec_
   {
@@ -966,8 +940,8 @@
                                FT_UInt     buffer_max );
 
   typedef FT_UInt
-  (*FT_Face_GetGlyphNameIndexFunc)( FT_Face     face,
-                                    FT_String*  glyph_name );
+  (*FT_Face_GetGlyphNameIndexFunc)( FT_Face           face,
+                                    const FT_String*  glyph_name );
 
 
 #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@@ -1022,9 +996,9 @@
    *   FT_DEFINE_OUTLINE_FUNCS
    *
    * @description:
-   *   Used to initialize an instance of FT_Outline_Funcs struct.
-   *   The struct will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   Used to initialize an instance of FT_Outline_Funcs struct.  The struct
+   *   will be allocated in the global scope (or the scope where the macro is
+   *   used).
    */
 #define FT_DEFINE_OUTLINE_FUNCS(           \
           class_,                          \
@@ -1051,9 +1025,9 @@
    *   FT_DEFINE_RASTER_FUNCS
    *
    * @description:
-   *   Used to initialize an instance of FT_Raster_Funcs struct.
-   *   The struct will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   Used to initialize an instance of FT_Raster_Funcs struct.  The struct
+   *   will be allocated in the global scope (or the scope where the macro is
+   *   used).
    */
 #define FT_DEFINE_RASTER_FUNCS(    \
           class_,                  \
@@ -1081,9 +1055,12 @@
    *   FT_DEFINE_GLYPH
    *
    * @description:
-   *   The struct will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   The struct will be allocated in the global scope (or the scope where
+   *   the macro is used).
    */
+#define FT_DECLARE_GLYPH( class_ )                \
+  FT_CALLBACK_TABLE const FT_Glyph_Class  class_;
+
 #define FT_DEFINE_GLYPH(          \
           class_,                 \
           size_,                  \
@@ -1114,8 +1091,8 @@
    *   FT_DECLARE_RENDERER
    *
    * @description:
-   *   Used to create a forward declaration of a
-   *   FT_Renderer_Class struct instance.
+   *   Used to create a forward declaration of a FT_Renderer_Class struct
+   *   instance.
    *
    * @macro:
    *   FT_DEFINE_RENDERER
@@ -1123,8 +1100,8 @@
    * @description:
    *   Used to initialize an instance of FT_Renderer_Class struct.
    *
-   *   The struct will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   The struct will be allocated in the global scope (or the scope where
+   *   the macro is used).
    */
 #define FT_DECLARE_RENDERER( class_ )               \
   FT_EXPORT_VAR( const FT_Renderer_Class ) class_;
@@ -1175,8 +1152,8 @@
    *   FT_DECLARE_MODULE
    *
    * @description:
-   *   Used to create a forward declaration of a
-   *   FT_Module_Class struct instance.
+   *   Used to create a forward declaration of a FT_Module_Class struct
+   *   instance.
    *
    * @macro:
    *   FT_DEFINE_MODULE
@@ -1184,16 +1161,16 @@
    * @description:
    *   Used to initialize an instance of an FT_Module_Class struct.
    *
-   *   The struct will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   The struct will be allocated in the global scope (or the scope where
+   *   the macro is used).
    *
    * @macro:
    *   FT_DEFINE_ROOT_MODULE
    *
    * @description:
    *   Used to initialize an instance of an FT_Module_Class struct inside
-   *   another struct that contains it or in a function that initializes
-   *   that containing struct.
+   *   another struct that contains it or in a function that initializes that
+   *   containing struct.
    */
 #define FT_DECLARE_MODULE( class_ )  \
   FT_CALLBACK_TABLE                  \
diff --git a/include/freetype/internal/ftpsprop.h b/include/freetype/internal/ftpsprop.h
index dd0588f..1d5b287 100644
--- a/include/freetype/internal/ftpsprop.h
+++ b/include/freetype/internal/ftpsprop.h
@@ -4,7 +4,7 @@
  *
  *   Get and set properties of PostScript drivers (specification).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTPSPROP_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/ftrfork.h b/include/freetype/internal/ftrfork.h
index a056171..e964599 100644
--- a/include/freetype/internal/ftrfork.h
+++ b/include/freetype/internal/ftrfork.h
@@ -4,7 +4,7 @@
  *
  *   Embedded resource forks accessor (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Masatake YAMATO and Redhat K.K.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,8 +25,7 @@
 #define FTRFORK_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 
 
 FT_BEGIN_HEADER
@@ -72,8 +71,8 @@
   } FT_RFork_Rule;
 
   /* For fast translation between rule index and rule type,
-   * the macros FT_RFORK_xxx should be kept consistent with
-   * the raccess_guess_funcs table
+   * the macros FT_RFORK_xxx should be kept consistent with the
+   * raccess_guess_funcs table
    */
   typedef struct ft_raccess_guess_rec_ {
     ft_raccess_guess_func  func;
@@ -98,11 +97,11 @@
    *   FT_Raccess_Guess
    *
    * @description:
-   *   Guess a file name and offset where the actual resource fork is
-   *   stored.  The macro FT_RACCESS_N_RULES holds the number of
-   *   guessing rules;  the guessed result for the Nth rule is
-   *   represented as a triplet: a new file name (new_names[N]), a file
-   *   offset (offsets[N]), and an error code (errors[N]).
+   *   Guess a file name and offset where the actual resource fork is stored.
+   *   The macro FT_RACCESS_N_RULES holds the number of guessing rules; the
+   *   guessed result for the Nth rule is represented as a triplet: a new
+   *   file name (new_names[N]), a file offset (offsets[N]), and an error
+   *   code (errors[N]).
    *
    * @input:
    *   library ::
@@ -112,24 +111,24 @@
    *     A file stream containing the resource fork.
    *
    *   base_name ::
-   *     The (base) file name of the resource fork used for some
-   *     guessing rules.
+   *     The (base) file name of the resource fork used for some guessing
+   *     rules.
    *
    * @output:
    *   new_names ::
    *     An array of guessed file names in which the resource forks may
-   *     exist.  If `new_names[N]' is NULL, the guessed file name is
-   *     equal to `base_name'.
+   *     exist.  If 'new_names[N]' is `NULL`, the guessed file name is equal
+   *     to `base_name`.
    *
    *   offsets ::
-   *     An array of guessed file offsets.  `offsets[N]' holds the file
+   *     An array of guessed file offsets.  'offsets[N]' holds the file
    *     offset of the possible start of the resource fork in file
-   *     `new_names[N]'.
+   *     'new_names[N]'.
    *
    *   errors ::
-   *     An array of FreeType error codes.  `errors[N]' is the error
-   *     code of Nth guessing rule function.  If `errors[N]' is not
-   *     FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless.
+   *     An array of FreeType error codes.  'errors[N]' is the error code of
+   *     Nth guessing rule function.  If 'errors[N]' is not FT_Err_Ok,
+   *     'new_names[N]' and 'offsets[N]' are meaningless.
    */
   FT_BASE( void )
   FT_Raccess_Guess( FT_Library  library,
@@ -146,10 +145,10 @@
    *   FT_Raccess_Get_HeaderInfo
    *
    * @description:
-   *   Get the information from the header of resource fork.  The
-   *   information includes the file offset where the resource map
-   *   starts, and the file offset where the resource data starts.
-   *   `FT_Raccess_Get_DataOffsets' requires these two data.
+   *   Get the information from the header of resource fork.  The information
+   *   includes the file offset where the resource map starts, and the file
+   *   offset where the resource data starts.  `FT_Raccess_Get_DataOffsets`
+   *   requires these two data.
    *
    * @input:
    *   library ::
@@ -185,9 +184,9 @@
    *   FT_Raccess_Get_DataOffsets
    *
    * @description:
-   *   Get the data offsets for a tag in a resource fork.  Offsets are
-   *   stored in an array because, in some cases, resources in a resource
-   *   fork have the same tag.
+   *   Get the data offsets for a tag in a resource fork.  Offsets are stored
+   *   in an array because, in some cases, resources in a resource fork have
+   *   the same tag.
    *
    * @input:
    *   library ::
@@ -206,17 +205,16 @@
    *     The resource tag.
    *
    *   sort_by_res_id ::
-   *     A Boolean to sort the fragmented resource by their ids.
-   *     The fragmented resources for `POST' resource should be sorted
-   *     to restore Type1 font properly.  For `sfnt' resources, sorting
-   *     may induce a different order of the faces in comparison to that
-   *     by QuickDraw API.
+   *     A Boolean to sort the fragmented resource by their ids.  The
+   *     fragmented resources for 'POST' resource should be sorted to restore
+   *     Type1 font properly.  For 'sfnt' resources, sorting may induce a
+   *     different order of the faces in comparison to that by QuickDraw API.
    *
    * @output:
    *   offsets ::
-   *     The stream offsets for the resource data specified by `tag'.
-   *     This array is allocated by the function, so you have to call
-   *     @ft_mem_free after use.
+   *     The stream offsets for the resource data specified by 'tag'.  This
+   *     array is allocated by the function, so you have to call @ft_mem_free
+   *     after use.
    *
    *   count ::
    *     The length of offsets array.
@@ -225,8 +223,8 @@
    *   FreeType error code.  FT_Err_Ok means success.
    *
    * @note:
-   *   Normally you should use `FT_Raccess_Get_HeaderInfo' to get the
-   *   value for `map_offset' and `rdata_pos'.
+   *   Normally you should use `FT_Raccess_Get_HeaderInfo` to get the value
+   *   for `map_offset` and `rdata_pos`.
    */
   FT_BASE( FT_Error )
   FT_Raccess_Get_DataOffsets( FT_Library  library,
diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h
index 3f493b5..1e85d6d 100644
--- a/include/freetype/internal/ftserv.h
+++ b/include/freetype/internal/ftserv.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType services (specification only).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,13 +17,13 @@
 
   /**************************************************************************
    *
-   * Each module can export one or more `services'.  Each service is
+   * Each module can export one or more 'services'.  Each service is
    * identified by a constant string and modeled by a pointer; the latter
    * generally corresponds to a structure containing function pointers.
    *
-   * Note that a service's data cannot be a mere function pointer because
-   * in C it is possible that function pointers might be implemented
-   * differently than data pointers (e.g. 48 bits instead of 32).
+   * Note that a service's data cannot be a mere function pointer because in
+   * C it is possible that function pointers might be implemented differently
+   * than data pointers (e.g. 48 bits instead of 32).
    *
    */
 
@@ -31,6 +31,7 @@
 #ifndef FTSERV_H_
 #define FTSERV_H_
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -47,15 +48,15 @@
    *     The source face handle.
    *
    *   id ::
-   *     A string describing the service as defined in the service's
-   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
-   *     `multi-masters').  It is automatically prefixed with
-   *     `FT_SERVICE_ID_'.
+   *     A string describing the service as defined in the service's header
+   *     files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
+   *     'multi-masters').  It is automatically prefixed with
+   *     `FT_SERVICE_ID_`.
    *
    * @output:
    *   ptr ::
-   *     A variable that receives the service pointer.  Will be NULL
-   *     if not found.
+   *     A variable that receives the service pointer.  Will be `NULL` if not
+   *     found.
    */
 #ifdef __cplusplus
 
@@ -99,15 +100,15 @@
    *     The source face handle.
    *
    *   id ::
-   *     A string describing the service as defined in the service's
-   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
-   *     `multi-masters').  It is automatically prefixed with
-   *     `FT_SERVICE_ID_'.
+   *     A string describing the service as defined in the service's header
+   *     files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
+   *     'multi-masters').  It is automatically prefixed with
+   *     `FT_SERVICE_ID_`.
    *
    * @output:
    *   ptr ::
-   *     A variable that receives the service pointer.  Will be NULL
-   *     if not found.
+   *     A variable that receives the service pointer.  Will be `NULL` if not
+   *     found.
    */
 #ifdef __cplusplus
 
@@ -146,8 +147,8 @@
   /*************************************************************************/
 
   /*
-   * The following structure is used to _describe_ a given service
-   * to the library.  This is useful to build simple static service lists.
+   * The following structure is used to _describe_ a given service to the
+   * library.  This is useful to build simple static service lists.
    */
   typedef struct  FT_ServiceDescRec_
   {
@@ -176,8 +177,8 @@
    * @description:
    *   Used to initialize an array of FT_ServiceDescRec structures.
    *
-   *   The array will be allocated in the global scope (or the scope
-   *   where the macro is used).
+   *   The array will be allocated in the global scope (or the scope where
+   *   the macro is used).
    */
 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
                                    serv_id_1, serv_data_1 )                 \
@@ -351,13 +352,13 @@
 
 
   /*
-   * Parse a list of FT_ServiceDescRec descriptors and look for
-   * a specific service by ID.  Note that the last element in the
-   * array must be { NULL, NULL }, and that the function should
-   * return NULL if the service isn't available.
+   * Parse a list of FT_ServiceDescRec descriptors and look for a specific
+   * service by ID.  Note that the last element in the array must be { NULL,
+   * NULL }, and that the function should return NULL if the service isn't
+   * available.
    *
-   * This function can be used by modules to implement their
-   * `get_service' method.
+   * This function can be used by modules to implement their `get_service'
+   * method.
    */
   FT_BASE( FT_Pointer )
   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
@@ -374,14 +375,14 @@
 
   /*
    * This structure is used to store a cache for several frequently used
-   * services.  It is the type of `face->internal->services'.  You
-   * should only use FT_FACE_LOOKUP_SERVICE to access it.
+   * services.  It is the type of `face->internal->services'.  You should
+   * only use FT_FACE_LOOKUP_SERVICE to access it.
    *
    * All fields should have the type FT_Pointer to relax compilation
    * dependencies.  We assume the developer isn't completely stupid.
    *
-   * Each field must be named `service_XXXX' where `XXX' corresponds to
-   * the correct FT_SERVICE_ID_XXXX macro.  See the definition of
+   * Each field must be named `service_XXXX' where `XXX' corresponds to the
+   * correct FT_SERVICE_ID_XXXX macro.  See the definition of
    * FT_FACE_LOOKUP_SERVICE below how this is implemented.
    *
    */
@@ -426,7 +427,7 @@
    *
    * @output:
    *   ptr ::
-   *     A variable receiving the service data.  NULL if not available.
+   *     A variable receiving the service data.  `NULL` if not available.
    */
 #ifdef __cplusplus
 
@@ -486,33 +487,6 @@
 
   /* */
 
-  /*
-   * The header files containing the services.
-   */
-
-#define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
-#define FT_SERVICE_CFF_TABLE_LOAD_H     <freetype/internal/services/svcfftl.h>
-#define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
-#define FT_SERVICE_FONT_FORMAT_H        <freetype/internal/services/svfntfmt.h>
-#define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
-#define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
-#define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
-#define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h>
-#define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
-#define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
-#define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
-#define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
-#define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
-#define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
-#define FT_SERVICE_PROPERTIES_H         <freetype/internal/services/svprop.h>
-#define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
-#define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
-#define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
-#define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
-#define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
-
- /* */
-
 FT_END_HEADER
 
 #endif /* FTSERV_H_ */
diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h
index aaf8e0b..88e1928 100644
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -4,7 +4,7 @@
  *
  *   Stream handling (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,8 +21,8 @@
 
 
 #include <ft2build.h>
-#include FT_SYSTEM_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftsystem.h>
+#include <freetype/internal/ftobjs.h>
 
 
 FT_BEGIN_HEADER
@@ -96,13 +96,13 @@
   /* The structure type must be set in the FT_STRUCTURE macro before       */
   /* calling the FT_FRAME_START() macro.                                   */
   /*                                                                       */
-#define FT_FIELD_SIZE( f ) \
+#define FT_FIELD_SIZE( f )                          \
           (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f )
 
-#define FT_FIELD_SIZE_DELTA( f ) \
+#define FT_FIELD_SIZE_DELTA( f )                       \
           (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] )
 
-#define FT_FIELD_OFFSET( f ) \
+#define FT_FIELD_OFFSET( f )                         \
           (FT_UShort)( offsetof( FT_STRUCTURE, f ) )
 
 #define FT_FRAME_FIELD( frame_op, field ) \
@@ -149,8 +149,8 @@
 
   /**************************************************************************
    *
-   * Integer extraction macros -- the `buffer' parameter must ALWAYS be of
-   * type `char*' or equivalent (1-byte elements).
+   * Integer extraction macros -- the 'buffer' parameter must ALWAYS be of
+   * type 'char*' or equivalent (1-byte elements).
    */
 
 #define FT_BYTE_( p, i )  ( ((const FT_Byte*)(p))[(i)] )
@@ -166,8 +166,19 @@
 
 
   /*
-   * `FT_PEEK_XXX' are generic macros to get data from a buffer position.
-   * No safety checks are performed.
+   *    function      acts on      increases  does range   for    emits
+   *                                pointer    checking   frames  error
+   *  -------------------------------------------------------------------
+   *   FT_PEEK_XXX  buffer pointer      no         no        no     no
+   *   FT_NEXT_XXX  buffer pointer     yes         no        no     no
+   *   FT_GET_XXX   stream->cursor     yes        yes       yes     no
+   *   FT_READ_XXX  stream->pos        yes        yes        no    yes
+   */
+
+
+  /*
+   * `FT_PEEK_XXX' are generic macros to get data from a buffer position.  No
+   * safety checks are performed.
    */
 #define FT_PEEK_SHORT( p )  FT_INT16( FT_BYTE_U16( p, 0, 8 ) | \
                                       FT_BYTE_U16( p, 1, 0 ) )
@@ -185,9 +196,9 @@
                                        FT_BYTE_U32( p, 2,  8 ) | \
                                        FT_BYTE_U32( p, 3,  0 ) )
 
-#define FT_PEEK_OFF3( p )  FT_INT32( FT_BYTE_U32( p, 0, 16 ) | \
-                                     FT_BYTE_U32( p, 1,  8 ) | \
-                                     FT_BYTE_U32( p, 2,  0 ) )
+#define FT_PEEK_OFF3( p )  ( FT_INT32( FT_BYTE_U32( p, 0, 24 ) | \
+                                       FT_BYTE_U32( p, 1, 16 ) | \
+                                       FT_BYTE_U32( p, 2,  8 ) ) >> 8 )
 
 #define FT_PEEK_UOFF3( p )  FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \
                                        FT_BYTE_U32( p, 1,  8 ) | \
@@ -209,9 +220,9 @@
                                           FT_BYTE_U32( p, 1,  8 ) | \
                                           FT_BYTE_U32( p, 0,  0 ) )
 
-#define FT_PEEK_OFF3_LE( p )  FT_INT32( FT_BYTE_U32( p, 2, 16 ) | \
-                                        FT_BYTE_U32( p, 1,  8 ) | \
-                                        FT_BYTE_U32( p, 0,  0 ) )
+#define FT_PEEK_OFF3_LE( p )  ( FT_INT32( FT_BYTE_U32( p, 2, 24 ) | \
+                                          FT_BYTE_U32( p, 1, 16 ) | \
+                                          FT_BYTE_U32( p, 0,  8 ) ) >> 8 )
 
 #define FT_PEEK_UOFF3_LE( p )  FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \
                                           FT_BYTE_U32( p, 1,  8 ) | \
@@ -227,51 +238,51 @@
 #define FT_NEXT_BYTE( buffer )         \
           ( (unsigned char)*buffer++ )
 
-#define FT_NEXT_SHORT( buffer )                                   \
-          ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) )
+#define FT_NEXT_SHORT( buffer )                        \
+          ( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) )
 
-#define FT_NEXT_USHORT( buffer )                                            \
-          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) )
+#define FT_NEXT_USHORT( buffer )                        \
+          ( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) )
 
-#define FT_NEXT_OFF3( buffer )                                  \
-          ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) )
+#define FT_NEXT_OFF3( buffer )                        \
+          ( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) )
 
-#define FT_NEXT_UOFF3( buffer )                                           \
-          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) )
+#define FT_NEXT_UOFF3( buffer )                        \
+          ( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) )
 
-#define FT_NEXT_LONG( buffer )                                  \
-          ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) )
+#define FT_NEXT_LONG( buffer )                        \
+          ( buffer += 4, FT_PEEK_LONG( buffer - 4 ) )
 
-#define FT_NEXT_ULONG( buffer )                                           \
-          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) )
+#define FT_NEXT_ULONG( buffer )                        \
+          ( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) )
 
 
-#define FT_NEXT_SHORT_LE( buffer )                                   \
-          ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) )
+#define FT_NEXT_SHORT_LE( buffer )                        \
+          ( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) )
 
-#define FT_NEXT_USHORT_LE( buffer )                                            \
-          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) )
+#define FT_NEXT_USHORT_LE( buffer )                        \
+          ( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) )
 
-#define FT_NEXT_OFF3_LE( buffer )                                  \
-          ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) )
+#define FT_NEXT_OFF3_LE( buffer )                        \
+          ( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) )
 
-#define FT_NEXT_UOFF3_LE( buffer )                                           \
-          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) )
+#define FT_NEXT_UOFF3_LE( buffer )                        \
+          ( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) )
 
-#define FT_NEXT_LONG_LE( buffer )                                  \
-          ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) )
+#define FT_NEXT_LONG_LE( buffer )                        \
+          ( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) )
 
-#define FT_NEXT_ULONG_LE( buffer )                                           \
-          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) )
+#define FT_NEXT_ULONG_LE( buffer )                        \
+          ( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) )
 
 
   /**************************************************************************
    *
-   * The `FT_GET_XXX' macros use an implicit `stream' variable.
+   * The `FT_GET_XXX` macros use an implicit 'stream' variable.
    *
-   * Note that a call to `FT_STREAM_SEEK' or `FT_STREAM_POS' has *no* effect
-   * on `FT_GET_XXX'!  They operate on `stream->pos', while `FT_GET_XXX' use
-   * `stream->cursor'.
+   * Note that a call to `FT_STREAM_SEEK` or `FT_STREAM_POS` has **no**
+   * effect on `FT_GET_XXX`!  They operate on `stream->pos`, while
+   * `FT_GET_XXX` use `stream->cursor`.
    */
 #if 0
 #define FT_GET_MACRO( type )    FT_NEXT_ ## type ( stream->cursor )
@@ -294,20 +305,19 @@
 #else
 #define FT_GET_MACRO( func, type )        ( (type)func( stream ) )
 
-#define FT_GET_CHAR()       FT_GET_MACRO( FT_Stream_GetChar, FT_Char )
-#define FT_GET_BYTE()       FT_GET_MACRO( FT_Stream_GetChar, FT_Byte )
-#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetUShort, FT_Short )
-#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort )
-#define FT_GET_OFF3()       FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long )
-#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong )
-#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetULong, FT_Long )
-#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
-#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
+#define FT_GET_CHAR()       FT_GET_MACRO( FT_Stream_GetByte, FT_Char )
+#define FT_GET_BYTE()       FT_GET_MACRO( FT_Stream_GetByte, FT_Byte )
+#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetUShort, FT_Int16 )
+#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetUShort, FT_UInt16 )
+#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetUOffset, FT_UInt32 )
+#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetULong, FT_Int32 )
+#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
+#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
 
-#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short )
-#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort )
-#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long )
-#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
+#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Int16 )
+#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UInt16 )
+#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetULongLE, FT_Int32 )
+#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_UInt32 )
 #endif
 
 
@@ -319,22 +329,21 @@
    * The `FT_READ_XXX' macros use implicit `stream' and `error' variables.
    *
    * `FT_READ_XXX' can be controlled with `FT_STREAM_SEEK' and
-   * `FT_STREAM_POS'.  They use the full machinery to check whether a read
-   * is valid.
+   * `FT_STREAM_POS'.  They use the full machinery to check whether a read is
+   * valid.
    */
-#define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var )
-#define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var )
-#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var )
-#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var )
-#define FT_READ_OFF3( var )       FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, var )
-#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var )
-#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var )
-#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var )
+#define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadByte, FT_Byte, var )
+#define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadByte, FT_Char, var )
+#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, FT_Int16, var )
+#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadUShort, FT_UInt16, var )
+#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadUOffset, FT_UInt32, var )
+#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadULong, FT_Int32, var )
+#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadULong, FT_UInt32, var )
 
-#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var )
-#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var )
-#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var )
-#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var )
+#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Int16, var )
+#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UInt16, var )
+#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Int32, var )
+#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadULongLE, FT_UInt32, var )
 
 
 #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@@ -406,12 +415,14 @@
 
   /* Enter a frame of `count' consecutive bytes in a stream.  Returns an */
   /* error if the frame could not be read/accessed.  The caller can use  */
-  /* the `FT_Stream_Get_XXX' functions to retrieve frame data without    */
+  /* the `FT_Stream_GetXXX' functions to retrieve frame data without     */
   /* error checks.                                                       */
   /*                                                                     */
   /* You must _always_ call `FT_Stream_ExitFrame' once you have entered  */
   /* a stream frame!                                                     */
   /*                                                                     */
+  /* Nested frames are not permitted.                                    */
+  /*                                                                     */
   FT_BASE( FT_Error )
   FT_Stream_EnterFrame( FT_Stream  stream,
                         FT_ULong   count );
@@ -420,14 +431,17 @@
   FT_BASE( void )
   FT_Stream_ExitFrame( FT_Stream  stream );
 
+
   /* Extract a stream frame.  If the stream is disk-based, a heap block */
   /* is allocated and the frame bytes are read into it.  If the stream  */
-  /* is memory-based, this function simply set a pointer to the data.   */
+  /* is memory-based, this function simply sets a pointer to the data.  */
   /*                                                                    */
   /* Useful to optimize access to memory-based streams transparently.   */
   /*                                                                    */
-  /* All extracted frames must be `freed' with a call to the function   */
-  /* FT_Stream_ReleaseFrame().                                          */
+  /* `FT_Stream_GetXXX' functions can't be used.                        */
+  /*                                                                    */
+  /* An extracted frame must be `freed' with a call to the function     */
+  /* `FT_Stream_ReleaseFrame'.                                          */
   /*                                                                    */
   FT_BASE( FT_Error )
   FT_Stream_ExtractFrame( FT_Stream  stream,
@@ -439,38 +453,39 @@
   FT_Stream_ReleaseFrame( FT_Stream  stream,
                           FT_Byte**  pbytes );
 
+
   /* read a byte from an entered frame */
-  FT_BASE( FT_Char )
-  FT_Stream_GetChar( FT_Stream  stream );
+  FT_BASE( FT_Byte )
+  FT_Stream_GetByte( FT_Stream  stream );
 
   /* read a 16-bit big-endian unsigned integer from an entered frame */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_GetUShort( FT_Stream  stream );
 
   /* read a 24-bit big-endian unsigned integer from an entered frame */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_GetUOffset( FT_Stream  stream );
 
   /* read a 32-bit big-endian unsigned integer from an entered frame */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_GetULong( FT_Stream  stream );
 
   /* read a 16-bit little-endian unsigned integer from an entered frame */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_GetUShortLE( FT_Stream  stream );
 
   /* read a 32-bit little-endian unsigned integer from an entered frame */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_GetULongLE( FT_Stream  stream );
 
 
   /* read a byte from a stream */
-  FT_BASE( FT_Char )
-  FT_Stream_ReadChar( FT_Stream  stream,
+  FT_BASE( FT_Byte )
+  FT_Stream_ReadByte( FT_Stream  stream,
                       FT_Error*  error );
 
   /* read a 16-bit big-endian unsigned integer from a stream */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_ReadUShort( FT_Stream  stream,
                         FT_Error*  error );
 
@@ -480,17 +495,17 @@
                          FT_Error*  error );
 
   /* read a 32-bit big-endian integer from a stream */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_ReadULong( FT_Stream  stream,
                        FT_Error*  error );
 
   /* read a 16-bit little-endian unsigned integer from a stream */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_ReadUShortLE( FT_Stream  stream,
                           FT_Error*  error );
 
   /* read a 32-bit little-endian unsigned integer from a stream */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_ReadULongLE( FT_Stream  stream,
                          FT_Error*  error );
 
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index 78b731c..319fe56 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -4,7 +4,7 @@
  *
  *   Tracing handling (specification only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,6 +18,11 @@
 
   /* definitions of trace levels for FreeType 2 */
 
+  /* the maximum string length (if the argument to `FT_TRACE_DEF` */
+  /* gets used as a string) plus one charachter for ':' plus      */
+  /* another one for the trace level                              */
+#define FT_MAX_TRACE_LEVEL_LENGTH  (9 + 1 + 1)
+
   /* the first level must always be `trace_any' */
 FT_TRACE_DEF( any )
 
@@ -38,20 +43,28 @@
 FT_TRACE_DEF( mm )        /* MM interface            (ftmm.c)     */
 FT_TRACE_DEF( psprops )   /* PS driver properties    (ftpsprop.c) */
 FT_TRACE_DEF( raccess )   /* resource fork accessor  (ftrfork.c)  */
-FT_TRACE_DEF( raster )    /* monochrome rasterizer   (ftraster.c) */
-FT_TRACE_DEF( smooth )    /* anti-aliasing raster    (ftgrays.c)  */
 FT_TRACE_DEF( synth )     /* bold/slant synthesizer  (ftsynth.c)  */
 
-  /* Cache sub-system */
-FT_TRACE_DEF( cache )     /* cache sub-system        (ftcache.c, etc.) */
+  /* rasterizers */
+FT_TRACE_DEF( raster )    /* monochrome rasterizer   (ftraster.c) */
+FT_TRACE_DEF( smooth )    /* anti-aliasing raster    (ftgrays.c)  */
+
+  /* ot-svg module */
+FT_TRACE_DEF( otsvg )     /* OT-SVG renderer         (ftsvg.c)    */
+
+  /* cache sub-system */
+FT_TRACE_DEF( cache )     /* cache sub-system   (ftcache.c, etc.) */
 
   /* SFNT driver components */
 FT_TRACE_DEF( sfdriver )  /* SFNT font driver        (sfdriver.c) */
 FT_TRACE_DEF( sfobjs )    /* SFNT object handler     (sfobjs.c)   */
+FT_TRACE_DEF( sfwoff )    /* WOFF format handler     (sfwoff.c)   */
+FT_TRACE_DEF( sfwoff2 )   /* WOFF2 format handler    (sfwoff2.c)  */
 FT_TRACE_DEF( ttbdf )     /* TrueType embedded BDF   (ttbdf.c)    */
 FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)   */
 FT_TRACE_DEF( ttcolr )    /* glyph layer table       (ttcolr.c)   */
 FT_TRACE_DEF( ttcpal )    /* color palette table     (ttcpal.c)   */
+FT_TRACE_DEF( ttsvg )     /* OpenType SVG table      (ttsvg.c)    */
 FT_TRACE_DEF( ttkern )    /* kerning handler         (ttkern.c)   */
 FT_TRACE_DEF( ttload )    /* basic TrueType tables   (ttload.c)   */
 FT_TRACE_DEF( ttmtx )     /* metrics-related tables  (ttmtx.c)    */
@@ -75,6 +88,7 @@
 FT_TRACE_DEF( t1parse )
 
   /* PostScript helper module `psaux' */
+FT_TRACE_DEF( afmparse )
 FT_TRACE_DEF( cffdecode )
 FT_TRACE_DEF( psconv )
 FT_TRACE_DEF( psobjs )
@@ -149,8 +163,10 @@
 FT_TRACE_DEF( afhints )
 FT_TRACE_DEF( afmodule )
 FT_TRACE_DEF( aflatin )
-FT_TRACE_DEF( aflatin2 )
 FT_TRACE_DEF( afshaper )
-FT_TRACE_DEF( afwarp )
+
+  /* SDF components */
+FT_TRACE_DEF( sdf )       /* signed distance raster for outlines (ftsdf.c) */
+FT_TRACE_DEF( bsdf )      /* signed distance raster for bitmaps (ftbsdf.c) */
 
 /* END */
diff --git a/include/freetype/internal/ftvalid.h b/include/freetype/internal/ftvalid.h
index 265d79b..e98ee4e 100644
--- a/include/freetype/internal/ftvalid.h
+++ b/include/freetype/internal/ftvalid.h
@@ -4,7 +4,7 @@
  *
  *   FreeType validation support (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,9 @@
 #define FTVALID_H_
 
 #include <ft2build.h>
-#include FT_CONFIG_STANDARD_LIBRARY_H   /* for ft_setjmp and ft_longjmp */
+#include FT_CONFIG_STANDARD_LIBRARY_H   /* for ft_jmpbuf */
 
+#include "compiler-macros.h"
 
 FT_BEGIN_HEADER
 
@@ -54,17 +55,17 @@
    * FT_VALIDATE_TIGHT ::
    *   A table that passes this validation level can be used reliably and
    *   doesn't contain invalid data.  For example, a charmap table that
-   *   returns invalid glyph indices will not pass, even though it can
-   *   be used with FreeType in default mode (the library will simply
-   *   return an error later when trying to load the glyph).
+   *   returns invalid glyph indices will not pass, even though it can be
+   *   used with FreeType in default mode (the library will simply return an
+   *   error later when trying to load the glyph).
    *
    *   It also checks that fields which must be a multiple of 2, 4, or 8,
    *   don't have incorrect values, etc.
    *
    * FT_VALIDATE_PARANOID ::
    *   Only for font debugging.  Checks that a table follows the
-   *   specification by 100%.  Very few fonts will be able to pass this
-   *   level anyway but it can be useful for certain tools like font
+   *   specification by 100%.  Very few fonts will be able to pass this level
+   *   anyway but it can be useful for certain tools like font
    *   editors/converters.
    */
   typedef enum  FT_ValidationLevel_
diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
deleted file mode 100644
index 8261043..0000000
--- a/include/freetype/internal/internal.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
- *
- * internal.h
- *
- *   Internal header files (specification only).
- *
- * Copyright 1996-2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- * This file is part of the FreeType project, and may only be used,
- * modified, and distributed under the terms of the FreeType project
- * license, LICENSE.TXT.  By continuing to use, modify, or distribute
- * this file you indicate that you have read the license and
- * understand and accept it fully.
- *
- */
-
-
-  /**************************************************************************
-   *
-   * This file is automatically included by `ft2build.h'.
-   * Do not include it manually!
-   *
-   */
-
-
-#define FT_INTERNAL_OBJECTS_H             <freetype/internal/ftobjs.h>
-#define FT_INTERNAL_STREAM_H              <freetype/internal/ftstream.h>
-#define FT_INTERNAL_MEMORY_H              <freetype/internal/ftmemory.h>
-#define FT_INTERNAL_DEBUG_H               <freetype/internal/ftdebug.h>
-#define FT_INTERNAL_CALC_H                <freetype/internal/ftcalc.h>
-#define FT_INTERNAL_HASH_H                <freetype/internal/fthash.h>
-#define FT_INTERNAL_DRIVER_H              <freetype/internal/ftdrv.h>
-#define FT_INTERNAL_TRACE_H               <freetype/internal/fttrace.h>
-#define FT_INTERNAL_GLYPH_LOADER_H        <freetype/internal/ftgloadr.h>
-#define FT_INTERNAL_SFNT_H                <freetype/internal/sfnt.h>
-#define FT_INTERNAL_SERVICE_H             <freetype/internal/ftserv.h>
-#define FT_INTERNAL_RFORK_H               <freetype/internal/ftrfork.h>
-#define FT_INTERNAL_VALIDATE_H            <freetype/internal/ftvalid.h>
-
-#define FT_INTERNAL_TRUETYPE_TYPES_H      <freetype/internal/tttypes.h>
-#define FT_INTERNAL_TYPE1_TYPES_H         <freetype/internal/t1types.h>
-
-#define FT_INTERNAL_POSTSCRIPT_AUX_H      <freetype/internal/psaux.h>
-#define FT_INTERNAL_POSTSCRIPT_HINTS_H    <freetype/internal/pshints.h>
-#define FT_INTERNAL_POSTSCRIPT_PROPS_H    <freetype/internal/ftpsprop.h>
-
-#define FT_INTERNAL_AUTOHINT_H            <freetype/internal/autohint.h>
-
-#define FT_INTERNAL_CFF_TYPES_H           <freetype/internal/cfftypes.h>
-#define FT_INTERNAL_CFF_OBJECTS_TYPES_H   <freetype/internal/cffotypes.h>
-
-
-#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
-
-  /* We disable the warning `conditional expression is constant' here */
-  /* in order to compile cleanly with the maximum level of warnings.  */
-  /* In particular, the warning complains about stuff like `while(0)' */
-  /* which is very useful in macro definitions.  There is no benefit  */
-  /* in having it enabled.                                            */
-#pragma warning( disable : 4127 )
-
-#endif /* _MSC_VER */
-
-
-/* END */
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index 2c5a6d2..dfb1987 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -5,7 +5,7 @@
  *   Auxiliary functions and data structures related to PostScript fonts
  *   (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,21 +21,20 @@
 #define PSAUX_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_TYPE1_TYPES_H
-#include FT_INTERNAL_HASH_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_CFF_TYPES_H
-#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/fthash.h>
+#include <freetype/internal/tttypes.h>
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/cfftypes.h>
+#include <freetype/internal/cffotypes.h>
 
 
 
 FT_BEGIN_HEADER
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * PostScript modules driver class.
    */
@@ -96,10 +95,10 @@
     (*done)( PS_Table  table );
 
     FT_Error
-    (*add)( PS_Table  table,
-            FT_Int    idx,
-            void*     object,
-            FT_UInt   length );
+    (*add)( PS_Table     table,
+            FT_Int       idx,
+            const void*  object,
+            FT_UInt      length );
 
     void
     (*release)( PS_Table  table );
@@ -113,32 +112,26 @@
    *   PS_TableRec
    *
    * @description:
-   *   A PS_Table is a simple object used to store an array of objects in
-   *   a single memory block.
+   *   A PS_Table is a simple object used to store an array of objects in a
+   *   single memory block.
    *
    * @fields:
    *   block ::
-   *     The address in memory of the growheap's block.  This
-   *     can change between two object adds, due to
-   *     reallocation.
+   *     The address in memory of the growheap's block.  This can change
+   *     between two object adds, due to reallocation.
    *
    *   cursor ::
    *     The current top of the grow heap within its block.
    *
    *   capacity ::
-   *     The current size of the heap block.  Increments by
-   *     1kByte chunks.
+   *     The current size of the heap block.  Increments by 1kByte chunks.
    *
    *   init ::
-   *     Set to 0xDEADBEEF if `elements' and `lengths' have
-   *     been allocated.
+   *     Set to 0xDEADBEEF if 'elements' and 'lengths' have been allocated.
    *
    *   max_elems ::
    *     The maximum number of elements in table.
    *
-   *   num_elems ::
-   *     The current number of elements in table.
-   *
    *   elements ::
    *     A table of element addresses within the block.
    *
@@ -146,8 +139,7 @@
    *     A table of element sizes within the block.
    *
    *   memory ::
-   *     The object used for memory operations
-   *     (alloc/realloc).
+   *     The object used for memory operations (alloc/realloc).
    *
    *   funcs ::
    *     A table of method pointers for this object.
@@ -160,7 +152,6 @@
     FT_ULong           init;
 
     FT_Int             max_elems;
-    FT_Int             num_elems;
     FT_Byte**          elements;       /* addresses of table elements */
     FT_UInt*           lengths;        /* lengths of table elements   */
 
@@ -556,9 +547,8 @@
    *     Set but not used.
    *
    *   metrics_only ::
-   *     A boolean indicating that we only want to compute
-   *     the metrics of a given glyph, not load all of its
-   *     points.
+   *     A boolean indicating that we only want to compute the metrics of a
+   *     given glyph, not load all of its points.
    *
    *   is_t1 ::
    *     Set if current font type is Type 1.
@@ -815,8 +805,7 @@
    *     Unused.
    *
    *   parse_state ::
-   *     An enumeration which controls the charstring
-   *     parsing state.
+   *     An enumeration which controls the charstring parsing state.
    *
    *   load_points ::
    *     If this flag is not set, no points are loaded.
@@ -825,9 +814,8 @@
    *     Set but not used.
    *
    *   metrics_only ::
-   *     A boolean indicating that we only want to compute
-   *     the metrics of a given glyph, not load all of its
-   *     points.
+   *     A boolean indicating that we only want to compute the metrics of a
+   *     given glyph, not load all of its points.
    *
    *   funcs ::
    *     An array of function pointers for the builder.
@@ -1100,9 +1088,8 @@
    *     Set but not used.
    *
    *   metrics_only ::
-   *     A boolean indicating that we only want to compute
-   *     the metrics of a given glyph, not load all of its
-   *     points.
+   *     A boolean indicating that we only want to compute the metrics of a
+   *     given glyph, not load all of its points.
    *
    *   hints_funcs ::
    *     Auxiliary pointer for hinting.
@@ -1294,8 +1281,7 @@
    *
    * @fields:
    *   memory ::
-   *     The object used for memory operations (alloc and
-   *     realloc).
+   *     The object used for memory operations (alloc and realloc).
    *
    *   stream ::
    *     This is an opaque object.
@@ -1304,8 +1290,7 @@
    *     The result will be stored here.
    *
    *   get_index ::
-   *     A user provided function to get a glyph index by its
-   *     name.
+   *     A user provided function to get a glyph index by its name.
    */
   typedef struct  AFM_ParserRec_
   {
diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h
index 90a28ac..ededc4c 100644
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -4,9 +4,9 @@
  *
  *   Interface to Postscript-specific (Type 1 and Type 2) hints
  *   recorders (specification only).  These are used to support native
- *   T1/T2 hints in the `type1', `cid', and `cff' font drivers.
+ *   T1/T2 hints in the 'type1', 'cid', and 'cff' font drivers.
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,9 +22,8 @@
 #define PSHINTS_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TYPE1_TABLES_H
+#include <freetype/freetype.h>
+#include <freetype/t1tables.h>
 
 
 FT_BEGIN_HEADER
@@ -73,7 +72,7 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   T1_Hints
@@ -86,16 +85,16 @@
    *   @T1_Hints_FuncsRec structure.  Recording glyph hints is normally
    *   achieved through the following scheme:
    *
-   *   - Open a new hint recording session by calling the `open' method.
+   *   - Open a new hint recording session by calling the 'open' method.
    *     This rewinds the recorder and prepare it for new input.
    *
    *   - For each hint found in the glyph charstring, call the corresponding
-   *     method (`stem', `stem3', or `reset').  Note that these functions do
+   *     method ('stem', 'stem3', or 'reset').  Note that these functions do
    *     not return an error code.
    *
-   *   - Close the recording session by calling the `close' method.  It
-   *     returns an error code if the hints were invalid or something
-   *     strange happened (e.g., memory shortage).
+   *   - Close the recording session by calling the 'close' method.  It
+   *     returns an error code if the hints were invalid or something strange
+   *     happened (e.g., memory shortage).
    *
    *   The hints accumulated in the object can later be used by the
    *   PostScript hinter.
@@ -104,7 +103,7 @@
   typedef struct T1_HintsRec_*  T1_Hints;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   T1_Hints_Funcs
@@ -117,7 +116,7 @@
   typedef const struct T1_Hints_FuncsRec_*  T1_Hints_Funcs;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T1_Hints_OpenFunc
@@ -139,14 +138,14 @@
   (*T1_Hints_OpenFunc)( T1_Hints  hints );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T1_Hints_SetStemFunc
    *
    * @description:
    *   A method of the @T1_Hints class used to record a new horizontal or
-   *   vertical stem.  This corresponds to the Type 1 `hstem' and `vstem'
+   *   vertical stem.  This corresponds to the Type 1 'hstem' and 'vstem'
    *   operators.
    *
    * @input:
@@ -164,15 +163,15 @@
    *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
    *   horizontal coordinates (x) for vertical stems (dim=1).
    *
-   *   `coords[0]' is the absolute stem position (lowest coordinate);
-   *   `coords[1]' is the length.
+   *   'coords[0]' is the absolute stem position (lowest coordinate);
+   *   'coords[1]' is the length.
    *
    *   The length can be negative, in which case it must be either -20 or
-   *   -21.  It is interpreted as a `ghost' stem, according to the Type 1
+   *   -21.  It is interpreted as a 'ghost' stem, according to the Type 1
    *   specification.
    *
-   *   If the length is -21 (corresponding to a bottom ghost stem), then
-   *   the real stem position is `coords[0]+coords[1]'.
+   *   If the length is -21 (corresponding to a bottom ghost stem), then the
+   *   real stem position is 'coords[0]+coords[1]'.
    *
    */
   typedef void
@@ -181,7 +180,7 @@
                            FT_Fixed*  coords );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T1_Hints_SetStem3Func
@@ -215,7 +214,7 @@
                             FT_Fixed*  coords );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T1_Hints_ResetFunc
@@ -238,7 +237,7 @@
                          FT_UInt   end_point );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T1_Hints_CloseFunc
@@ -267,7 +266,7 @@
                          FT_UInt   end_point );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T1_Hints_ApplyFunc
@@ -295,9 +294,9 @@
    *
    * @note:
    *   On input, all points within the outline are in font coordinates. On
-   *   output, they are in 1/64th of pixels.
+   *   output, they are in 1/64 of pixels.
    *
-   *   The scaling transformation is taken from the `globals' object which
+   *   The scaling transformation is taken from the 'globals' object which
    *   must correspond to the same font as the glyph.
    *
    */
@@ -308,7 +307,7 @@
                          FT_Render_Mode  hint_mode );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   T1_Hints_FuncsRec
@@ -360,7 +359,7 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   T2_Hints
@@ -373,16 +372,16 @@
    *   @T2_Hints_FuncsRec structure.  Recording glyph hints is normally
    *   achieved through the following scheme:
    *
-   *   - Open a new hint recording session by calling the `open' method.
+   *   - Open a new hint recording session by calling the 'open' method.
    *     This rewinds the recorder and prepare it for new input.
    *
    *   - For each hint found in the glyph charstring, call the corresponding
-   *     method (`stems', `hintmask', `counters').  Note that these
-   *     functions do not return an error code.
+   *     method ('stems', 'hintmask', 'counters').  Note that these functions
+   *     do not return an error code.
    *
-   *   - Close the recording session by calling the `close' method.  It
-   *     returns an error code if the hints were invalid or something
-   *     strange happened (e.g., memory shortage).
+   *   - Close the recording session by calling the 'close' method.  It
+   *     returns an error code if the hints were invalid or something strange
+   *     happened (e.g., memory shortage).
    *
    *   The hints accumulated in the object can later be used by the
    *   Postscript hinter.
@@ -391,7 +390,7 @@
   typedef struct T2_HintsRec_*  T2_Hints;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @type:
    *   T2_Hints_Funcs
@@ -404,7 +403,7 @@
   typedef const struct T2_Hints_FuncsRec_*  T2_Hints_Funcs;
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T2_Hints_OpenFunc
@@ -426,7 +425,7 @@
   (*T2_Hints_OpenFunc)( T2_Hints  hints );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T2_Hints_StemsFunc
@@ -434,7 +433,7 @@
    * @description:
    *   A method of the @T2_Hints class used to set the table of stems in
    *   either the vertical or horizontal dimension.  Equivalent to the
-   *   `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators.
+   *   'hstem', 'vstem', 'hstemhm', and 'vstemhm' Type 2 operators.
    *
    * @input:
    *   hints ::
@@ -447,18 +446,18 @@
    *     The number of stems.
    *
    *   coords ::
-   *     An array of `count' (position,length) pairs in 16.16 format.
+   *     An array of 'count' (position,length) pairs in 16.16 format.
    *
    * @note:
    *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
    *   horizontal coordinates (x) for vertical stems (dim=1).
    *
-   *   There are `2*count' elements in the `coords' array.  Each even
-   *   element is an absolute position in font units, each odd element is a
-   *   length in font units.
+   *   There are '2*count' elements in the 'coords' array.  Each even element
+   *   is an absolute position in font units, each odd element is a length in
+   *   font units.
    *
-   *   A length can be negative, in which case it must be either -20 or
-   *   -21.  It is interpreted as a `ghost' stem, according to the Type 1
+   *   A length can be negative, in which case it must be either -20 or -21.
+   *   It is interpreted as a 'ghost' stem, according to the Type 1
    *   specification.
    *
    */
@@ -469,22 +468,22 @@
                          FT_Fixed*  coordinates );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T2_Hints_MaskFunc
    *
    * @description:
    *   A method of the @T2_Hints class used to set a given hintmask (this
-   *   corresponds to the `hintmask' Type 2 operator).
+   *   corresponds to the 'hintmask' Type 2 operator).
    *
    * @input:
    *   hints ::
    *     A handle to the Type 2 hints recorder.
    *
    *   end_point ::
-   *     The glyph index of the last point to which the previously defined
-   *     or activated hints apply.
+   *     The glyph index of the last point to which the previously defined or
+   *     activated hints apply.
    *
    *   bit_count ::
    *     The number of bits in the hint mask.
@@ -494,13 +493,13 @@
    *
    * @note:
    *   If the hintmask starts the charstring (before any glyph point
-   *   definition), the value of `end_point' should be 0.
+   *   definition), the value of `end_point` should be 0.
    *
-   *   `bit_count' is the number of meaningful bits in the `bytes' array; it
+   *   `bit_count` is the number of meaningful bits in the 'bytes' array; it
    *   must be equal to the total number of hints defined so far (i.e.,
    *   horizontal+verticals).
    *
-   *   The `bytes' array can come directly from the Type 2 charstring and
+   *   The 'bytes' array can come directly from the Type 2 charstring and
    *   respects the same format.
    *
    */
@@ -511,14 +510,14 @@
                         const FT_Byte*  bytes );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T2_Hints_CounterFunc
    *
    * @description:
-   *   A method of the @T2_Hints class used to set a given counter mask
-   *   (this corresponds to the `hintmask' Type 2 operator).
+   *   A method of the @T2_Hints class used to set a given counter mask (this
+   *   corresponds to the 'hintmask' Type 2 operator).
    *
    * @input:
    *   hints ::
@@ -536,13 +535,13 @@
    *
    * @note:
    *   If the hintmask starts the charstring (before any glyph point
-   *   definition), the value of `end_point' should be 0.
+   *   definition), the value of `end_point` should be 0.
    *
-   *   `bit_count' is the number of meaningful bits in the `bytes' array; it
+   *   `bit_count` is the number of meaningful bits in the 'bytes' array; it
    *   must be equal to the total number of hints defined so far (i.e.,
    *   horizontal+verticals).
    *
-   *    The `bytes' array can come directly from the Type 2 charstring and
+   *    The 'bytes' array can come directly from the Type 2 charstring and
    *    respects the same format.
    *
    */
@@ -552,7 +551,7 @@
                            const FT_Byte*  bytes );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T2_Hints_CloseFunc
@@ -581,15 +580,14 @@
                          FT_UInt   end_point );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @functype:
    *   T2_Hints_ApplyFunc
    *
    * @description:
    *   A method of the @T2_Hints class used to apply hints to the
-   *   corresponding glyph outline.  Must be called after the `close'
-   *   method.
+   *   corresponding glyph outline.  Must be called after the 'close' method.
    *
    * @input:
    *   hints ::
@@ -609,9 +607,9 @@
    *
    * @note:
    *   On input, all points within the outline are in font coordinates. On
-   *   output, they are in 1/64th of pixels.
+   *   output, they are in 1/64 of pixels.
    *
-   *   The scaling transformation is taken from the `globals' object which
+   *   The scaling transformation is taken from the 'globals' object which
    *   must correspond to the same font than the glyph.
    *
    */
@@ -622,7 +620,7 @@
                          FT_Render_Mode  hint_mode );
 
 
-  /*************************************************************************
+  /**************************************************************************
    *
    * @struct:
    *   T2_Hints_FuncsRec
diff --git a/include/freetype/internal/services/svbdf.h b/include/freetype/internal/services/svbdf.h
index b29f537..bf0c1dc 100644
--- a/include/freetype/internal/services/svbdf.h
+++ b/include/freetype/internal/services/svbdf.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType BDF services (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVBDF_H_
 #define SVBDF_H_
 
-#include FT_BDF_H
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/ftbdf.h>
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svcfftl.h b/include/freetype/internal/services/svcfftl.h
index 9e4486e..4a20498 100644
--- a/include/freetype/internal/services/svcfftl.h
+++ b/include/freetype/internal/services/svcfftl.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType CFF tables loader service (specification).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVCFFTL_H_
 #define SVCFFTL_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_INTERNAL_CFF_TYPES_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/cfftypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svcid.h b/include/freetype/internal/services/svcid.h
index 9ef0a0c..06d0cb8 100644
--- a/include/freetype/internal/services/svcid.h
+++ b/include/freetype/internal/services/svcid.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType CID font services (specification).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * Derek Clegg and Michael Toftdal.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef SVCID_H_
 #define SVCID_H_
 
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svfntfmt.h b/include/freetype/internal/services/svfntfmt.h
index 6182362..bc45e80 100644
--- a/include/freetype/internal/services/svfntfmt.h
+++ b/include/freetype/internal/services/svfntfmt.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType font format service (specification only).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef SVFNTFMT_H_
 #define SVFNTFMT_H_
 
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
@@ -27,8 +27,8 @@
 
   /*
    * A trivial service used to return the name of a face's font driver,
-   * according to the XFree86 nomenclature.  Note that the service data
-   * is a simple constant string pointer.
+   * according to the XFree86 nomenclature.  Note that the service data is a
+   * simple constant string pointer.
    */
 
 #define FT_SERVICE_ID_FONT_FORMAT  "font-format"
diff --git a/include/freetype/internal/services/svgldict.h b/include/freetype/internal/services/svgldict.h
index 0840b58..6437abf 100644
--- a/include/freetype/internal/services/svgldict.h
+++ b/include/freetype/internal/services/svgldict.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph dictionary services (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,15 +19,15 @@
 #ifndef SVGLDICT_H_
 #define SVGLDICT_H_
 
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
 
 
   /*
-   * A service used to retrieve glyph names, as well as to find the
-   * index of a given glyph name in a font.
+   * A service used to retrieve glyph names, as well as to find the index of
+   * a given glyph name in a font.
    *
    */
 
@@ -41,8 +41,8 @@
                                FT_UInt     buffer_max );
 
   typedef FT_UInt
-  (*FT_GlyphDict_NameIndexFunc)( FT_Face     face,
-                                 FT_String*  glyph_name );
+  (*FT_GlyphDict_NameIndexFunc)( FT_Face           face,
+                                 const FT_String*  glyph_name );
 
 
   FT_DEFINE_SERVICE( GlyphDict )
diff --git a/include/freetype/internal/services/svgxval.h b/include/freetype/internal/services/svgxval.h
index 7fa27ff..31016af 100644
--- a/include/freetype/internal/services/svgxval.h
+++ b/include/freetype/internal/services/svgxval.h
@@ -4,7 +4,7 @@
  *
  *   FreeType API for validating TrueTypeGX/AAT tables (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -28,8 +28,8 @@
 #ifndef SVGXVAL_H_
 #define SVGXVAL_H_
 
-#include FT_GX_VALIDATE_H
-#include FT_INTERNAL_VALIDATE_H
+#include <freetype/ftgxval.h>
+#include <freetype/internal/ftvalid.h>
 
 FT_BEGIN_HEADER
 
diff --git a/include/freetype/internal/services/svkern.h b/include/freetype/internal/services/svkern.h
index ef95b32..bcabbc3 100644
--- a/include/freetype/internal/services/svkern.h
+++ b/include/freetype/internal/services/svkern.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType Kerning service (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVKERN_H_
 #define SVKERN_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_TRUETYPE_TABLES_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/tttables.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svmetric.h b/include/freetype/internal/services/svmetric.h
index 91de020..e588ea4 100644
--- a/include/freetype/internal/services/svmetric.h
+++ b/include/freetype/internal/services/svmetric.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType services for metrics variations (specification).
  *
- * Copyright 2016-2018 by
+ * Copyright (C) 2016-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef SVMETRIC_H_
 #define SVMETRIC_H_
 
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h
index 6aeaa45..d942042 100644
--- a/include/freetype/internal/services/svmm.h
+++ b/include/freetype/internal/services/svmm.h
@@ -4,8 +4,8 @@
  *
  *   The FreeType Multiple Masters and GX var services (specification).
  *
- * Copyright 2003-2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
+ * Copyright (C) 2003-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
  *
  * This file is part of the FreeType project, and may only be used,
  * modified, and distributed under the terms of the FreeType project
@@ -19,7 +19,9 @@
 #ifndef SVMM_H_
 #define SVMM_H_
 
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/ftmmtypes.h>
 
 
 FT_BEGIN_HEADER
@@ -86,47 +88,104 @@
   typedef void
   (*FT_Done_Blend_Func)( FT_Face );
 
+  typedef FT_Error
+  (*FT_Set_MM_WeightVector_Func)( FT_Face    face,
+                                  FT_UInt    len,
+                                  FT_Fixed*  weight_vector );
+
+  typedef FT_Error
+  (*FT_Get_MM_WeightVector_Func)( FT_Face    face,
+                                  FT_UInt*   len,
+                                  FT_Fixed*  weight_vector );
+
+  typedef FT_Error
+  (*FT_Var_Load_Delta_Set_Idx_Map_Func)( FT_Face            face,
+                                         FT_ULong           offset,
+                                         GX_DeltaSetIdxMap  map,
+                                         GX_ItemVarStore    itemStore,
+                                         FT_ULong           table_len );
+
+  typedef FT_Error
+  (*FT_Var_Load_Item_Var_Store_Func)( FT_Face          face,
+                                      FT_ULong         offset,
+                                      GX_ItemVarStore  itemStore );
+
+  typedef FT_ItemVarDelta
+  (*FT_Var_Get_Item_Delta_Func)( FT_Face          face,
+                                 GX_ItemVarStore  itemStore,
+                                 FT_UInt          outerIndex,
+                                 FT_UInt          innerIndex );
+
+  typedef void
+  (*FT_Var_Done_Item_Var_Store_Func)( FT_Face          face,
+                                      GX_ItemVarStore  itemStore );
+
+  typedef void
+  (*FT_Var_Done_Delta_Set_Idx_Map_Func)( FT_Face            face,
+                                         GX_DeltaSetIdxMap  deltaSetIdxMap );
+
 
   FT_DEFINE_SERVICE( MultiMasters )
   {
-    FT_Get_MM_Func          get_mm;
-    FT_Set_MM_Design_Func   set_mm_design;
-    FT_Set_MM_Blend_Func    set_mm_blend;
-    FT_Get_MM_Blend_Func    get_mm_blend;
-    FT_Get_MM_Var_Func      get_mm_var;
-    FT_Set_Var_Design_Func  set_var_design;
-    FT_Get_Var_Design_Func  get_var_design;
-    FT_Set_Instance_Func    set_instance;
+    FT_Get_MM_Func                        get_mm;
+    FT_Set_MM_Design_Func                 set_mm_design;
+    FT_Set_MM_Blend_Func                  set_mm_blend;
+    FT_Get_MM_Blend_Func                  get_mm_blend;
+    FT_Get_MM_Var_Func                    get_mm_var;
+    FT_Set_Var_Design_Func                set_var_design;
+    FT_Get_Var_Design_Func                get_var_design;
+    FT_Set_Instance_Func                  set_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_Get_Var_Blend_Func   get_var_blend;
-    FT_Done_Blend_Func      done_blend;
+    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;
+    FT_Var_Done_Item_Var_Store_Func       done_item_var_store;
+    FT_Var_Done_Delta_Set_Idx_Map_Func    done_delta_set_idx_map;
+    FT_Get_Var_Blend_Func                 get_var_blend;
+    FT_Done_Blend_Func                    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_instance_,   \
-                                           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_,                                          \
-    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_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_                                                     \
   };
 
   /* */
diff --git a/include/freetype/internal/services/svotval.h b/include/freetype/internal/services/svotval.h
index 9a3ff47..a4683cd 100644
--- a/include/freetype/internal/services/svotval.h
+++ b/include/freetype/internal/services/svotval.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType OpenType validation service (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVOTVAL_H_
 #define SVOTVAL_H_
 
-#include FT_OPENTYPE_VALIDATE_H
-#include FT_INTERNAL_VALIDATE_H
+#include <freetype/ftotval.h>
+#include <freetype/internal/ftvalid.h>
 
 FT_BEGIN_HEADER
 
diff --git a/include/freetype/internal/services/svpfr.h b/include/freetype/internal/services/svpfr.h
index 21deb31..fd189c7 100644
--- a/include/freetype/internal/services/svpfr.h
+++ b/include/freetype/internal/services/svpfr.h
@@ -4,7 +4,7 @@
  *
  *   Internal PFR service functions (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVPFR_H_
 #define SVPFR_H_
 
-#include FT_PFR_H
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/ftpfr.h>
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
@@ -56,7 +56,6 @@
 
   };
 
- /* */
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/services/svpostnm.h b/include/freetype/internal/services/svpostnm.h
index 1e39dce..2b8f6df 100644
--- a/include/freetype/internal/services/svpostnm.h
+++ b/include/freetype/internal/services/svpostnm.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType PostScript name services (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,16 +19,16 @@
 #ifndef SVPOSTNM_H_
 #define SVPOSTNM_H_
 
-#include FT_INTERNAL_SERVICE_H
+#include <freetype/internal/ftserv.h>
 
 
 FT_BEGIN_HEADER
 
   /*
-   * A trivial service used to retrieve the PostScript name of a given
-   * font when available.  The `get_name' field should never be NULL.
+   * A trivial service used to retrieve the PostScript name of a given font
+   * when available.  The `get_name' field should never be `NULL`.
    *
-   * The corresponding function can return NULL to indicate that the
+   * The corresponding function can return `NULL` to indicate that the
    * PostScript name is not available.
    *
    * The name is owned by the face and will be destroyed with it.
diff --git a/include/freetype/internal/services/svprop.h b/include/freetype/internal/services/svprop.h
index 7e84cc8..932ce32 100644
--- a/include/freetype/internal/services/svprop.h
+++ b/include/freetype/internal/services/svprop.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType property service (specification).
  *
- * Copyright 2012-2018 by
+ * Copyright (C) 2012-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/include/freetype/internal/services/svpscmap.h b/include/freetype/internal/services/svpscmap.h
index 136879d..fd99d85 100644
--- a/include/freetype/internal/services/svpscmap.h
+++ b/include/freetype/internal/services/svpscmap.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType PostScript charmap service (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef SVPSCMAP_H_
 #define SVPSCMAP_H_
 
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 
 
 FT_BEGIN_HEADER
@@ -35,21 +35,20 @@
   (*PS_Unicode_ValueFunc)( const char*  glyph_name );
 
   /*
-   * Macintosh name id to glyph name.  NULL if invalid index.
+   * Macintosh name id to glyph name.  `NULL` if invalid index.
    */
   typedef const char*
   (*PS_Macintosh_NameFunc)( FT_UInt  name_index );
 
   /*
-   * Adobe standard string ID to glyph name.  NULL if invalid index.
+   * Adobe standard string ID to glyph name.  `NULL` if invalid index.
    */
   typedef const char*
   (*PS_Adobe_Std_StringsFunc)( FT_UInt  string_index );
 
 
   /*
-   * Simple unicode -> glyph index charmap built from font glyph names
-   * table.
+   * Simple unicode -> glyph index charmap built from font glyph names table.
    */
   typedef struct  PS_UniMap_
   {
@@ -72,7 +71,7 @@
 
   /*
    * A function which returns a glyph name for a given index.  Returns
-   * NULL if invalid index.
+   * `NULL` if invalid index.
    */
   typedef const char*
   (*PS_GetGlyphNameFunc)( FT_Pointer  data,
diff --git a/include/freetype/internal/services/svpsinfo.h b/include/freetype/internal/services/svpsinfo.h
index 214fd1e..09c4cdc 100644
--- a/include/freetype/internal/services/svpsinfo.h
+++ b/include/freetype/internal/services/svpsinfo.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType PostScript info service (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVPSINFO_H_
 #define SVPSINFO_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/t1types.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svsfnt.h b/include/freetype/internal/services/svsfnt.h
index 035e119..f98df2e 100644
--- a/include/freetype/internal/services/svsfnt.h
+++ b/include/freetype/internal/services/svsfnt.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType SFNT table loading service (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVSFNT_H_
 #define SVSFNT_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_TRUETYPE_TABLES_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/tttables.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svttcmap.h b/include/freetype/internal/services/svttcmap.h
index cc4328f..5f9eb02 100644
--- a/include/freetype/internal/services/svttcmap.h
+++ b/include/freetype/internal/services/svttcmap.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType TrueType/sfnt cmap extra information service.
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * Masatake YAMATO, Redhat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -22,8 +22,8 @@
 #ifndef SVTTCMAP_H_
 #define SVTTCMAP_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_TRUETYPE_TABLES_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/tttables.h>
 
 
 FT_BEGIN_HEADER
@@ -45,15 +45,14 @@
    * @fields:
    *   language ::
    *     The language ID used in Mac fonts.  Definitions of values are in
-   *     `ttnameid.h'.
+   *     `ttnameid.h`.
    *
    *   format ::
-   *     The cmap format.  OpenType 1.6 defines the formats 0 (byte
-   *     encoding table), 2~(high-byte mapping through table), 4~(segment
-   *     mapping to delta values), 6~(trimmed table mapping), 8~(mixed
-   *     16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented
-   *     coverage), 13~(last resort font), and 14 (Unicode Variation
-   *     Sequences).
+   *     The cmap format.  OpenType 1.6 defines the formats 0 (byte encoding
+   *     table), 2~(high-byte mapping through table), 4~(segment mapping to
+   *     delta values), 6~(trimmed table mapping), 8~(mixed 16-bit and 32-bit
+   *     coverage), 10~(trimmed array), 12~(segmented coverage), 13~(last
+   *     resort font), and 14 (Unicode Variation Sequences).
    */
   typedef struct  TT_CMapInfo_
   {
diff --git a/include/freetype/internal/services/svtteng.h b/include/freetype/internal/services/svtteng.h
index 2564a41..ad577cb 100644
--- a/include/freetype/internal/services/svtteng.h
+++ b/include/freetype/internal/services/svtteng.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType TrueType engine query service (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVTTENG_H_
 #define SVTTENG_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_MODULE_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svttglyf.h b/include/freetype/internal/services/svttglyf.h
index 38444e9..ca6fff7 100644
--- a/include/freetype/internal/services/svttglyf.h
+++ b/include/freetype/internal/services/svttglyf.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType TrueType glyph service.
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * David Turner.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,8 +18,8 @@
 #ifndef SVTTGLYF_H_
 #define SVTTGLYF_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_TRUETYPE_TABLES_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/tttables.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/services/svwinfnt.h b/include/freetype/internal/services/svwinfnt.h
index 3aaa8a8..002923f 100644
--- a/include/freetype/internal/services/svwinfnt.h
+++ b/include/freetype/internal/services/svwinfnt.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType Windows FNT/FONT service (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,8 @@
 #ifndef SVWINFNT_H_
 #define SVWINFNT_H_
 
-#include FT_INTERNAL_SERVICE_H
-#include FT_WINFONTS_H
+#include <freetype/internal/ftserv.h>
+#include <freetype/ftwinfnt.h>
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 178d892..a2d4e15 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -2,9 +2,9 @@
  *
  * sfnt.h
  *
- *   High-level `sfnt' driver interface (specification).
+ *   High-level 'sfnt' driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,9 @@
 #define SFNT_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/ftdrv.h>
+#include <freetype/internal/tttypes.h>
+#include <freetype/internal/wofftypes.h>
 
 
 FT_BEGIN_HEADER
@@ -34,8 +34,8 @@
    *   TT_Init_Face_Func
    *
    * @description:
-   *   First part of the SFNT face object initialization.  This finds
-   *   the face in a SFNT file or collection, and load its format tag in
+   *   First part of the SFNT face object initialization.  This finds the
+   *   face in a SFNT file or collection, and load its format tag in
    *   face->format_tag.
    *
    * @input:
@@ -46,10 +46,9 @@
    *     A handle to the target face object.
    *
    *   face_index ::
-   *     The index of the TrueType font, if we are opening a
-   *     collection, in bits 0-15.  The numbered instance
-   *     index~+~1 of a GX (sub)font, if applicable, in bits
-   *     16-30.
+   *     The index of the TrueType font, if we are opening a collection, in
+   *     bits 0-15.  The numbered instance index~+~1 of a GX (sub)font, if
+   *     applicable, in bits 16-30.
    *
    *   num_params ::
    *     The number of additional parameters.
@@ -63,12 +62,11 @@
    * @note:
    *   The stream cursor must be at the font file's origin.
    *
-   *   This function recognizes fonts embedded in a `TrueType
-   *   collection'.
+   *   This function recognizes fonts embedded in a 'TrueType collection'.
    *
-   *   Once the format tag has been validated by the font driver, it
-   *   should then call the TT_Load_Face_Func() callback to read the rest
-   *   of the SFNT tables in the object.
+   *   Once the format tag has been validated by the font driver, it should
+   *   then call the TT_Load_Face_Func() callback to read the rest of the
+   *   SFNT tables in the object.
    */
   typedef FT_Error
   (*TT_Init_Face_Func)( FT_Stream      stream,
@@ -84,9 +82,9 @@
    *   TT_Load_Face_Func
    *
    * @description:
-   *   Second part of the SFNT face object initialization.  This loads
-   *   the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the
-   *   face object.
+   *   Second part of the SFNT face object initialization.  This loads the
+   *   common SFNT tables (head, OS/2, maxp, metrics, etc.) in the face
+   *   object.
    *
    * @input:
    *   stream ::
@@ -96,10 +94,9 @@
    *     A handle to the target face object.
    *
    *   face_index ::
-   *     The index of the TrueType font, if we are opening a
-   *     collection, in bits 0-15.  The numbered instance
-   *     index~+~1 of a GX (sub)font, if applicable, in bits
-   *     16-30.
+   *     The index of the TrueType font, if we are opening a collection, in
+   *     bits 0-15.  The numbered instance index~+~1 of a GX (sub)font, if
+   *     applicable, in bits 16-30.
    *
    *   num_params ::
    *     The number of additional parameters.
@@ -153,30 +150,24 @@
    *     The face object to look for.
    *
    *   tag ::
-   *     The tag of table to load.  Use the value 0 if you want
-   *     to access the whole font file, else set this parameter
-   *     to a valid TrueType table tag that you can forge with
-   *     the MAKE_TT_TAG macro.
+   *     The tag of table to load.  Use the value 0 if you want to access the
+   *     whole font file, else set this parameter to a valid TrueType table
+   *     tag that you can forge with the MAKE_TT_TAG macro.
    *
    *   offset ::
-   *     The starting offset in the table (or the file if
-   *     tag == 0).
+   *     The starting offset in the table (or the file if tag == 0).
    *
    *   length ::
    *     The address of the decision variable:
    *
-   *     If length == NULL:
-   *     Loads the whole table.  Returns an error if
-   *     `offset' == 0!
+   *     If `length == NULL`: Loads the whole table.  Returns an error if
+   *     'offset' == 0!
    *
-   *     If *length == 0:
-   *     Exits immediately; returning the length of the given
-   *     table or of the font file, depending on the value of
-   *     `tag'.
+   *     If `*length == 0`: Exits immediately; returning the length of the
+   *     given table or of the font file, depending on the value of 'tag'.
    *
-   *     If *length != 0:
-   *     Loads the next `length' bytes of table or font,
-   *     starting at offset `offset' (in table or font too).
+   *     If `*length != 0`: Loads the next 'length' bytes of table or font,
+   *     starting at offset 'offset' (in table or font too).
    *
    * @output:
    *   buffer ::
@@ -199,8 +190,8 @@
    *   TT_Find_SBit_Image_Func
    *
    * @description:
-   *   Check whether an embedded bitmap (an `sbit') exists for a given
-   *   glyph, at a given strike.
+   *   Check whether an embedded bitmap (an 'sbit') exists for a given glyph,
+   *   at a given strike.
    *
    * @input:
    *   face ::
@@ -220,12 +211,11 @@
    *     The SBit strike containing the glyph index.
    *
    *   aglyph_offset ::
-   *     The offset of the glyph data in `EBDT' table.
+   *     The offset of the glyph data in 'EBDT' table.
    *
    * @return:
    *   FreeType error code.  0 means success.  Returns
-   *   SFNT_Err_Invalid_Argument if no sbit exists for the requested
-   *   glyph.
+   *   SFNT_Err_Invalid_Argument if no sbit exists for the requested glyph.
    */
   typedef FT_Error
   (*TT_Find_SBit_Image_Func)( TT_Face          face,
@@ -259,11 +249,11 @@
    *   FreeType error code.  0 means success.
    *
    * @note:
-   *   The stream cursor must be positioned at the glyph's offset within
-   *   the `EBDT' table before the call.
+   *   The stream cursor must be positioned at the glyph's offset within the
+   *   'EBDT' table before the call.
    *
    *   If the image format uses variable metrics, the stream cursor is
-   *   positioned just after the metrics header in the `EBDT' table on
+   *   positioned just after the metrics header in the 'EBDT' table on
    *   function exit.
    */
   typedef FT_Error
@@ -305,11 +295,11 @@
    *     A big sbit metrics structure for the glyph image.
    *
    * @return:
-   *   FreeType error code.  0 means success.  Returns an error if no
-   *   glyph sbit exists for the index.
+   *   FreeType error code.  0 means success.  Returns an error if no glyph
+   *   sbit exists for the index.
    *
    * @note:
-   *   The `map.buffer' field is always freed before the glyph is loaded.
+   *   The `map.buffer` field is always freed before the glyph is loaded.
    */
   typedef FT_Error
   (*TT_Load_SBit_Image_Func)( TT_Face              face,
@@ -324,6 +314,33 @@
   /**************************************************************************
    *
    * @functype:
+   *   TT_Load_Svg_Doc_Func
+   *
+   * @description:
+   *   Scan the SVG document list to find the document containing the glyph
+   *   that has the ID 'glyph*XXX*', where *XXX* is the value of
+   *   `glyph_index` as a decimal integer.
+   *
+   * @inout:
+   *   glyph ::
+   *     The glyph slot from which pointers to the SVG document list is to be
+   *     grabbed.  The results are stored back in the slot.
+   *
+   * @input:
+   *   glyph_index ::
+   *     The index of the glyph that is to be looked up.
+   *
+   * @return:
+   *   FreeType error code.  0 means success.
+   */
+  typedef FT_Error
+  (*TT_Load_Svg_Doc_Func)( FT_GlyphSlot  glyph,
+                           FT_UInt       glyph_index );
+
+
+  /**************************************************************************
+   *
+   * @functype:
    *   TT_Set_SBit_Strike_Func
    *
    * @description:
@@ -341,8 +358,8 @@
    *     The index of the sbit strike.
    *
    * @return:
-   *   FreeType error code.  0 means success.  Returns an error if no
-   *   sbit strike exists for the selected ppem values.
+   *   FreeType error code.  0 means success.  Returns an error if no sbit
+   *   strike exists for the selected ppem values.
    */
   typedef FT_Error
   (*TT_Set_SBit_Strike_Func)( TT_Face          face,
@@ -370,8 +387,8 @@
    *     the metrics of the strike.
    *
    * @return:
-   *   FreeType error code.  0 means success.  Returns an error if no
-   *   such sbit strike exists.
+   *   FreeType error code.  0 means success.  Returns an error if no such
+   *   sbit strike exists.
    */
   typedef FT_Error
   (*TT_Load_Strike_Metrics_Func)( TT_Face           face,
@@ -392,8 +409,8 @@
    *     The glyph index.
    *
    *   PSname ::
-   *     The address of a string pointer.  Will be NULL in case
-   *     of error, otherwise it is a pointer to the glyph name.
+   *     The address of a string pointer.  Will be `NULL` in case of error,
+   *     otherwise it is a pointer to the glyph name.
    *
    *     You must not modify the returned string!
    *
@@ -454,12 +471,10 @@
    *
    * @output:
    *   abearing ::
-   *     The horizontal (or vertical) bearing.  Set to zero in
-   *     case of error.
+   *     The horizontal (or vertical) bearing.  Set to zero in case of error.
    *
    *   aadvance ::
-   *     The horizontal (or vertical) advance.  Set to zero in
-   *     case of error.
+   *     The horizontal (or vertical) advance.  Set to zero in case of error.
    */
   typedef void
   (*TT_Get_Metrics_Func)( TT_Face     face,
@@ -475,7 +490,7 @@
    *   TT_Set_Palette_Func
    *
    * @description:
-   *   Load the colors into `face->palette' for a given palette index.
+   *   Load the colors into `face->palette` for a given palette index.
    *
    * @input:
    *   face ::
@@ -510,7 +525,7 @@
    * @inout:
    *   iterator ::
    *     An @FT_LayerIterator object.  For the first call you should set
-   *     `iterator->p' to NULL.  For all following calls, simply use the
+   *     `iterator->p` to `NULL`.  For all following calls, simply use the
    *     same object again.
    *
    * @output:
@@ -524,9 +539,9 @@
    *     instead (to be set up by the application outside of FreeType).
    *
    * @return:
-   *   Value~1 if everything is OK.  If there are no more layers (or if
-   *   there are no layers at all), value~0 gets returned.  In case of an
-   *   error, value~0 is returned also.
+   *   Value~1 if everything is OK.  If there are no more layers (or if there
+   *   are no layers at all), value~0 gets returned.  In case of an error,
+   *   value~0 is returned also.
    */
   typedef FT_Bool
   (*TT_Get_Colr_Layer_Func)( TT_Face            face,
@@ -539,13 +554,177 @@
   /**************************************************************************
    *
    * @functype:
+   *   TT_Get_Color_Glyph_Paint_Func
+   *
+   * @description:
+   *   Find the root @FT_OpaquePaint object for a given glyph ID.
+   *
+   * @input:
+   *   face ::
+   *     The target face object.
+   *
+   *   base_glyph ::
+   *     The glyph index the colored glyph layers are associated with.
+   *
+   * @output:
+   *   paint ::
+   *     The root @FT_OpaquePaint object.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  If no color glyph is found, or the root
+   *   paint could not be retrieved, value~0 gets returned.  In case of an
+   *   error, value~0 is returned also.
+   */
+  typedef FT_Bool
+  ( *TT_Get_Color_Glyph_Paint_Func )( TT_Face                   face,
+                                      FT_UInt                   base_glyph,
+                                      FT_Color_Root_Transform   root_transform,
+                                      FT_OpaquePaint           *paint );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   TT_Get_Color_Glyph_ClipBox_Func
+   *
+   * @description:
+   *   Search for a 'COLR' v1 clip box for the specified `base_glyph` and
+   *   fill the `clip_box` parameter with the 'COLR' v1 'ClipBox' information
+   *   if one is found.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the parent face object.
+   *
+   *   base_glyph ::
+   *     The glyph index for which to retrieve the clip box.
+   *
+   * @output:
+   *   clip_box ::
+   *     The clip box for the requested `base_glyph` if one is found.  The
+   *     clip box is computed taking scale and transformations configured on
+   *     the @FT_Face into account.  @FT_ClipBox contains @FT_Vector values
+   *     in 26.6 format.
+   *
+   * @note:
+   *     To retrieve the clip box in font units, reset scale to units-per-em
+   *     and remove transforms configured using @FT_Set_Transform.
+   *
+   * @return:
+   *   Value~1 if a ClipBox is found.  If no clip box is found or an
+   *   error occured, value~0 is returned.
+   */
+  typedef FT_Bool
+  ( *TT_Get_Color_Glyph_ClipBox_Func )( TT_Face      face,
+                                        FT_UInt      base_glyph,
+                                        FT_ClipBox*  clip_box );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   TT_Get_Paint_Layers_Func
+   *
+   * @description:
+   *   Access the layers of a `PaintColrLayers` table.
+   *
+   * @input:
+   *   face ::
+   *     The target face object.
+   *
+   * @inout:
+   *   iterator ::
+   *     The @FT_LayerIterator from an @FT_PaintColrLayers object, for which
+   *     the layers are to be retrieved.  The internal state of the iterator
+   *     is incremented after one call to this function for retrieving one
+   *     layer.
+   *
+   * @output:
+   *   paint ::
+   *     The root @FT_OpaquePaint object referencing the actual paint table.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  Value~0 gets returned when the paint
+   *   object can not be retrieved or any other error occurs.
+   */
+  typedef FT_Bool
+  ( *TT_Get_Paint_Layers_Func )( TT_Face            face,
+                                 FT_LayerIterator*  iterator,
+                                 FT_OpaquePaint    *paint );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   TT_Get_Colorline_Stops_Func
+   *
+   * @description:
+   *   Get the gradient and solid fill information for a given glyph.
+   *
+   * @input:
+   *   face ::
+   *     The target face object.
+   *
+   * @inout:
+   *   iterator ::
+   *     An @FT_ColorStopIterator object.  For the first call you should set
+   *     `iterator->p` to `NULL`.  For all following calls, simply use the
+   *     same object again.
+   *
+   * @output:
+   *   color_stop ::
+   *     Color index and alpha value for the retrieved color stop.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  If there are no more color stops,
+   *   value~0 gets returned.  In case of an error, value~0 is returned
+   *   also.
+   */
+  typedef FT_Bool
+  ( *TT_Get_Colorline_Stops_Func )( TT_Face                face,
+                                    FT_ColorStop          *color_stop,
+                                    FT_ColorStopIterator*  iterator );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   TT_Get_Paint_Func
+   *
+   * @description:
+   *   Get the paint details for a given @FT_OpaquePaint object.
+   *
+   * @input:
+   *   face ::
+   *     The target face object.
+   *
+   *   opaque_paint ::
+   *     The @FT_OpaquePaint object.
+   *
+   * @output:
+   *   paint ::
+   *     An @FT_COLR_Paint object holding the details on `opaque_paint`.
+   *
+   * @return:
+   *   Value~1 if everything is OK.  Value~0 if no details can be found for
+   *   this paint or any other error occured.
+   */
+  typedef FT_Bool
+  ( *TT_Get_Paint_Func )( TT_Face         face,
+                          FT_OpaquePaint  opaque_paint,
+                          FT_COLR_Paint  *paint );
+
+
+  /**************************************************************************
+   *
+   * @functype:
    *   TT_Blend_Colr_Func
    *
    * @description:
-   *   Blend the bitmap in `new_glyph' into `base_glyph' using the color
-   *   specified by `color_index'.  If `color_index' is 0xFFFF, use
-   *   `face->foreground_color' if `face->have_foreground_color' is set.
-   *   Otherwise check `face->palette_data.palette_flags': If present and
+   *   Blend the bitmap in `new_glyph` into `base_glyph` using the color
+   *   specified by `color_index`.  If `color_index` is 0xFFFF, use
+   *   `face->foreground_color` if `face->have_foreground_color` is set.
+   *   Otherwise check `face->palette_data.palette_flags`: If present and
    *   @FT_PALETTE_FOR_DARK_BACKGROUND is set, use BGRA value 0xFFFFFFFF
    *   (white opaque).  Otherwise use BGRA value 0x000000FF (black opaque).
    *
@@ -557,11 +736,11 @@
    *     Color index from the COLR table.
    *
    *   base_glyph ::
-   *     Slot for bitmap to be merged into.  The underlying
-   *     bitmap may get reallocated.
+   *     Slot for bitmap to be merged into.  The underlying bitmap may get
+   *     reallocated.
    *
    *   new_glyph ::
-   *     Slot to be incooperated into `base_glyph'.
+   *     Slot to be incooperated into `base_glyph`.
    *
    * @return:
    *   FreeType error code.  0 means success.  Returns an error if
@@ -580,8 +759,7 @@
    *   TT_Get_Name_Func
    *
    * @description:
-   *   From the `name' table, return a given ENGLISH name record in
-   *   ASCII.
+   *   From the 'name' table, return a given ENGLISH name record in ASCII.
    *
    * @input:
    *   face ::
@@ -592,8 +770,8 @@
    *
    * @inout:
    *   name ::
-   *     The address of an allocated string pointer.  NULL if
-   *     no name is present.
+   *     The address of an allocated string pointer.  `NULL` if no name is
+   *     present.
    *
    * @return:
    *   FreeType error code.  0 means success.
@@ -610,8 +788,8 @@
    *   TT_Get_Name_ID_Func
    *
    * @description:
-   *   Search whether an ENGLISH version for a given name ID is in the
-   *   `name' table.
+   *   Search whether an ENGLISH version for a given name ID is in the 'name'
+   *   table.
    *
    * @input:
    *   face ::
@@ -622,12 +800,12 @@
    *
    * @output:
    *   win ::
-   *     If non-negative, an index into the `name' table with
-   *     the corresponding (3,1) or (3,0) Windows entry.
+   *     If non-negative, an index into the 'name' table with the
+   *     corresponding (3,1) or (3,0) Windows entry.
    *
    *   apple ::
-   *     If non-negative, an index into the `name' table with
-   *     the corresponding (1,0) Apple entry.
+   *     If non-negative, an index into the 'name' table with the
+   *     corresponding (1,0) Apple entry.
    *
    * @return:
    *   1 if there is either a win or apple entry (or both), 0 otheriwse.
@@ -658,8 +836,8 @@
    *   FreeType error code.  0 means success.
    *
    * @note:
-   *   The function uses `face->goto_table' to seek the stream to the
-   *   start of the table, except while loading the font directory.
+   *   The function uses `face->goto_table` to seek the stream to the start
+   *   of the table, except while loading the font directory.
    */
   typedef FT_Error
   (*TT_Load_Table_Func)( TT_Face    face,
@@ -690,9 +868,14 @@
    *    Return the horizontal kerning value between two glyphs.
    *
    * @input:
-   *    face        :: A handle to the source face object.
-   *    left_glyph  :: The left glyph index.
-   *    right_glyph :: The right glyph index.
+   *    face ::
+   *      A handle to the source face object.
+   *
+   *    left_glyph ::
+   *      The left glyph index.
+   *
+   *    right_glyph ::
+   *      The right glyph index.
    *
    * @return:
    *    The kerning value in font units.
@@ -709,81 +892,91 @@
    *   SFNT_Interface
    *
    * @description:
-   *   This structure holds pointers to the functions used to load and
-   *   free the basic tables that are required in a `sfnt' font file.
+   *   This structure holds pointers to the functions used to load and free
+   *   the basic tables that are required in a 'sfnt' font file.
    *
    * @fields:
    *   Check the various xxx_Func() descriptions for details.
    */
   typedef struct  SFNT_Interface_
   {
-    TT_Loader_GotoTableFunc      goto_table;
+    TT_Loader_GotoTableFunc  goto_table;
 
-    TT_Init_Face_Func            init_face;
-    TT_Load_Face_Func            load_face;
-    TT_Done_Face_Func            done_face;
-    FT_Module_Requester          get_interface;
+    TT_Init_Face_Func    init_face;
+    TT_Load_Face_Func    load_face;
+    TT_Done_Face_Func    done_face;
+    FT_Module_Requester  get_interface;
 
-    TT_Load_Any_Func             load_any;
+    TT_Load_Any_Func  load_any;
 
     /* these functions are called by `load_face' but they can also  */
     /* be called from external modules, if there is a need to do so */
-    TT_Load_Table_Func           load_head;
-    TT_Load_Metrics_Func         load_hhea;
-    TT_Load_Table_Func           load_cmap;
-    TT_Load_Table_Func           load_maxp;
-    TT_Load_Table_Func           load_os2;
-    TT_Load_Table_Func           load_post;
+    TT_Load_Table_Func    load_head;
+    TT_Load_Metrics_Func  load_hhea;
+    TT_Load_Table_Func    load_cmap;
+    TT_Load_Table_Func    load_maxp;
+    TT_Load_Table_Func    load_os2;
+    TT_Load_Table_Func    load_post;
 
-    TT_Load_Table_Func           load_name;
-    TT_Free_Table_Func           free_name;
+    TT_Load_Table_Func  load_name;
+    TT_Free_Table_Func  free_name;
 
     /* this field was called `load_kerning' up to version 2.1.10 */
-    TT_Load_Table_Func           load_kern;
+    TT_Load_Table_Func  load_kern;
 
-    TT_Load_Table_Func           load_gasp;
-    TT_Load_Table_Func           load_pclt;
+    TT_Load_Table_Func  load_gasp;
+    TT_Load_Table_Func  load_pclt;
 
     /* see `ttload.h'; this field was called `load_bitmap_header' up to */
     /* version 2.1.10                                                   */
-    TT_Load_Table_Func           load_bhed;
+    TT_Load_Table_Func  load_bhed;
 
-    TT_Load_SBit_Image_Func      load_sbit_image;
+    TT_Load_SBit_Image_Func  load_sbit_image;
 
     /* see `ttpost.h' */
-    TT_Get_PS_Name_Func          get_psname;
-    TT_Free_Table_Func           free_psnames;
+    TT_Get_PS_Name_Func  get_psname;
+    TT_Free_Table_Func   free_psnames;
 
     /* starting here, the structure differs from version 2.1.7 */
 
     /* this field was introduced in version 2.1.8, named `get_psname' */
-    TT_Face_GetKerningFunc       get_kerning;
+    TT_Face_GetKerningFunc  get_kerning;
 
     /* new elements introduced after version 2.1.10 */
 
     /* load the font directory, i.e., the offset table and */
     /* the table directory                                 */
-    TT_Load_Table_Func           load_font_dir;
-    TT_Load_Metrics_Func         load_hmtx;
+    TT_Load_Table_Func    load_font_dir;
+    TT_Load_Metrics_Func  load_hmtx;
 
-    TT_Load_Table_Func           load_eblc;
-    TT_Free_Table_Func           free_eblc;
+    TT_Load_Table_Func  load_eblc;
+    TT_Free_Table_Func  free_eblc;
 
     TT_Set_SBit_Strike_Func      set_sbit_strike;
     TT_Load_Strike_Metrics_Func  load_strike_metrics;
 
-    TT_Load_Table_Func           load_cpal;
-    TT_Load_Table_Func           load_colr;
-    TT_Free_Table_Func           free_cpal;
-    TT_Free_Table_Func           free_colr;
-    TT_Set_Palette_Func          set_palette;
-    TT_Get_Colr_Layer_Func       get_colr_layer;
-    TT_Blend_Colr_Func           colr_blend;
+    TT_Load_Table_Func               load_cpal;
+    TT_Load_Table_Func               load_colr;
+    TT_Free_Table_Func               free_cpal;
+    TT_Free_Table_Func               free_colr;
+    TT_Set_Palette_Func              set_palette;
+    TT_Get_Colr_Layer_Func           get_colr_layer;
+    TT_Get_Color_Glyph_Paint_Func    get_colr_glyph_paint;
+    TT_Get_Color_Glyph_ClipBox_Func  get_color_glyph_clipbox;
+    TT_Get_Paint_Layers_Func         get_paint_layers;
+    TT_Get_Colorline_Stops_Func      get_colorline_stops;
+    TT_Get_Paint_Func                get_paint;
+    TT_Blend_Colr_Func               colr_blend;
 
-    TT_Get_Metrics_Func          get_metrics;
+    TT_Get_Metrics_Func  get_metrics;
 
-    TT_Get_Name_Func             get_name;
-    TT_Get_Name_ID_Func          get_name_id;
+    TT_Get_Name_Func     get_name;
+    TT_Get_Name_ID_Func  get_name_id;
+
+    /* OpenType SVG Support */
+    TT_Load_Table_Func    load_svg;
+    TT_Free_Table_Func    free_svg;
+    TT_Load_Svg_Doc_Func  load_svg_doc;
 
   } SFNT_Interface;
 
@@ -828,10 +1021,18 @@
           free_colr_,                    \
           set_palette_,                  \
           get_colr_layer_,               \
+          get_colr_glyph_paint_,         \
+          get_color_glyph_clipbox,       \
+          get_paint_layers_,             \
+          get_colorline_stops_,          \
+          get_paint_,                    \
           colr_blend_,                   \
           get_metrics_,                  \
           get_name_,                     \
-          get_name_id_ )                 \
+          get_name_id_,                  \
+          load_svg_,                     \
+          free_svg_,                     \
+          load_svg_doc_ )                \
   static const SFNT_Interface  class_ =  \
   {                                      \
     goto_table_,                         \
@@ -868,10 +1069,18 @@
     free_colr_,                          \
     set_palette_,                        \
     get_colr_layer_,                     \
+    get_colr_glyph_paint_,               \
+    get_color_glyph_clipbox,             \
+    get_paint_layers_,                   \
+    get_colorline_stops_,                \
+    get_paint_,                          \
     colr_blend_,                         \
     get_metrics_,                        \
     get_name_,                           \
-    get_name_id_                         \
+    get_name_id_,                        \
+    load_svg_,                           \
+    free_svg_,                           \
+    load_svg_doc_                        \
   };
 
 
diff --git a/include/freetype/internal/svginterface.h b/include/freetype/internal/svginterface.h
new file mode 100644
index 0000000..f464b2c
--- /dev/null
+++ b/include/freetype/internal/svginterface.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ *
+ * svginterface.h
+ *
+ *   Interface of ot-svg module (specification only).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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 SVGINTERFACE_H_
+#define SVGINTERFACE_H_
+
+#include <ft2build.h>
+#include <freetype/otsvg.h>
+
+
+FT_BEGIN_HEADER
+
+  typedef FT_Error
+  (*Preset_Bitmap_Func)( FT_Module     module,
+                         FT_GlyphSlot  slot,
+                         FT_Bool       cache );
+
+  typedef struct  SVG_Interface_
+  {
+    Preset_Bitmap_Func  preset_slot;
+
+  } SVG_Interface;
+
+  typedef SVG_Interface*  SVG_Service;
+
+FT_END_HEADER
+
+#endif /* SVGINTERFACE_H_ */
+
+
+/* END */
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index 67c3857..5a105c5 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -5,7 +5,7 @@
  *   Basic Type1/Type2 type definitions and interface (specification
  *   only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,12 +21,11 @@
 #define T1TYPES_H_
 
 
-#include <ft2build.h>
-#include FT_TYPE1_TABLES_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_INTERNAL_HASH_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+#include <freetype/t1tables.h>
+#include <freetype/internal/pshints.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/fthash.h>
+#include <freetype/internal/services/svpscmap.h>
 
 
 FT_BEGIN_HEADER
@@ -55,16 +54,14 @@
    *
    * @fields:
    *   num_chars ::
-   *     The number of character codes in the encoding.
-   *     Usually 256.
+   *     The number of character codes in the encoding.  Usually 256.
    *
    *   code_first ::
    *     The lowest valid character code in the encoding.
    *
    *   code_last ::
-   *     The highest valid character code in the encoding
-   *     + 1. When equal to code_first there are no valid
-   *     character codes.
+   *     The highest valid character code in the encoding + 1. When equal to
+   *     code_first there are no valid character codes.
    *
    *   char_index ::
    *     An array of corresponding glyph indices.
@@ -78,8 +75,8 @@
     FT_Int       code_first;
     FT_Int       code_last;
 
-    FT_UShort*   char_index;
-    FT_String**  char_name;
+    FT_UShort*         char_index;
+    const FT_String**  char_name;
 
   } T1_EncodingRec, *T1_Encoding;
 
@@ -175,8 +172,8 @@
   {
     FT_Bool        IsCIDFont;
     FT_BBox        FontBBox;
-    FT_Fixed       Ascender;
-    FT_Fixed       Descender;
+    FT_Fixed       Ascender;     /* optional, mind the zero */
+    FT_Fixed       Descender;    /* optional, mind the zero */
     AFM_TrackKern  TrackKerns;   /* free if non-NULL */
     FT_UInt        NumTrackKern;
     AFM_KernPair   KernPairs;    /* free if non-NULL */
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 4df6b29..3b52192 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -5,7 +5,7 @@
  *   Basic SFNT/TrueType type definitions and interface (specification
  *   only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,13 +21,12 @@
 #define TTTYPES_H_
 
 
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_COLOR_H
+#include <freetype/tttables.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftcolor.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_MULTIPLE_MASTERS_H
+#include <freetype/ftmm.h>
 #endif
 
 
@@ -53,21 +52,20 @@
    *   TTC_HeaderRec
    *
    * @description:
-   *   TrueType collection header.  This table contains the offsets of
-   *   the font headers of each distinct TrueType face in the file.
+   *   TrueType collection header.  This table contains the offsets of the
+   *   font headers of each distinct TrueType face in the file.
    *
    * @fields:
    *   tag ::
-   *     Must be `ttc ' to indicate a TrueType collection.
+   *     Must be 'ttc~' to indicate a TrueType collection.
    *
    *   version ::
    *     The version number.
    *
    *   count ::
-   *     The number of faces in the collection.  The
-   *     specification says this should be an unsigned long, but
-   *     we use a signed long since we need the value -1 for
-   *     specific purposes.
+   *     The number of faces in the collection.  The specification says this
+   *     should be an unsigned long, but we use a signed long since we need
+   *     the value -1 for specific purposes.
    *
    *   offsets ::
    *     The offsets of the font headers, one per face.
@@ -98,13 +96,13 @@
    *     The number of tables in file.
    *
    *   search_range ::
-   *     Must be `16 * (max power of 2 <= num_tables)'.
+   *     Must be '16 * (max power of 2 <= num_tables)'.
    *
    *   entry_selector ::
-   *     Must be log2 of `search_range / 16'.
+   *     Must be log2 of 'search_range / 16'.
    *
    *   range_shift ::
-   *     Must be `num_tables * 16 - search_range'.
+   *     Must be 'num_tables * 16 - search_range'.
    */
   typedef struct  SFNT_HeaderRec_
   {
@@ -135,8 +133,8 @@
    *     The table checksum.  This value can be ignored.
    *
    *   Offset ::
-   *     The offset of the table from the start of the TrueType
-   *     font in its resource.
+   *     The offset of the table from the start of the TrueType font in its
+   *     resource.
    *
    *   Length ::
    *     The table length (in bytes).
@@ -154,85 +152,10 @@
   /**************************************************************************
    *
    * @struct:
-   *   WOFF_HeaderRec
-   *
-   * @description:
-   *   WOFF file format header.
-   *
-   * @fields:
-   *   See
-   *
-   *     https://www.w3.org/TR/WOFF/#WOFFHeader
-   */
-  typedef struct  WOFF_HeaderRec_
-  {
-    FT_ULong   signature;
-    FT_ULong   flavor;
-    FT_ULong   length;
-    FT_UShort  num_tables;
-    FT_UShort  reserved;
-    FT_ULong   totalSfntSize;
-    FT_UShort  majorVersion;
-    FT_UShort  minorVersion;
-    FT_ULong   metaOffset;
-    FT_ULong   metaLength;
-    FT_ULong   metaOrigLength;
-    FT_ULong   privOffset;
-    FT_ULong   privLength;
-
-  } WOFF_HeaderRec, *WOFF_Header;
-
-
-  /**************************************************************************
-   *
-   * @struct:
-   *   WOFF_TableRec
-   *
-   * @description:
-   *   This structure describes a given table of a WOFF font.
-   *
-   * @fields:
-   *   Tag ::
-   *     A four-bytes tag describing the table.
-   *
-   *   Offset ::
-   *     The offset of the table from the start of the WOFF
-   *     font in its resource.
-   *
-   *   CompLength ::
-   *     Compressed table length (in bytes).
-   *
-   *   OrigLength ::
-   *     Uncompressed table length (in bytes).
-   *
-   *   CheckSum ::
-   *     The table checksum.  This value can be ignored.
-   *
-   *   OrigOffset ::
-   *     The uncompressed table file offset.  This value gets
-   *     computed while constructing the (uncompressed) SFNT
-   *     header.  It is not contained in the WOFF file.
-   */
-  typedef struct  WOFF_TableRec_
-  {
-    FT_ULong  Tag;           /* table ID                  */
-    FT_ULong  Offset;        /* table file offset         */
-    FT_ULong  CompLength;    /* compressed table length   */
-    FT_ULong  OrigLength;    /* uncompressed table length */
-    FT_ULong  CheckSum;      /* uncompressed checksum     */
-
-    FT_ULong  OrigOffset;    /* uncompressed table file offset */
-                             /* (not in the WOFF file)         */
-  } WOFF_TableRec, *WOFF_Table;
-
-
-  /**************************************************************************
-   *
-   * @struct:
    *   TT_LongMetricsRec
    *
    * @description:
-   *   A structure modeling the long metrics of the `hmtx' and `vmtx'
+   *   A structure modeling the long metrics of the 'hmtx' and 'vmtx'
    *   TrueType tables.  The values are expressed in font units.
    *
    * @fields:
@@ -256,7 +179,7 @@
    *   TT_ShortMetrics
    *
    * @description:
-   *   A simple type to model the short metrics of the `hmtx' and `vmtx'
+   *   A simple type to model the short metrics of the 'hmtx' and 'vmtx'
    *   tables.
    */
   typedef FT_Short  TT_ShortMetrics;
@@ -268,10 +191,9 @@
    *   TT_NameRec
    *
    * @description:
-   *   A structure modeling TrueType name records.  Name records are used
-   *   to store important strings like family name, style name,
-   *   copyright, etc. in _localized_ versions (i.e., language, encoding,
-   *   etc).
+   *   A structure modeling TrueType name records.  Name records are used to
+   *   store important strings like family name, style name, copyright,
+   *   etc. in _localized_ versions (i.e., language, encoding, etc).
    *
    * @fields:
    *   platformID ::
@@ -290,11 +212,11 @@
    *     The length of the string in bytes.
    *
    *   stringOffset ::
-   *     The offset to the string in the `name' table.
+   *     The offset to the string in the 'name' table.
    *
    *   string ::
-   *     A pointer to the string's bytes.  Note that these
-   *     are usually UTF-16 encoded characters.
+   *     A pointer to the string's bytes.  Note that these are usually UTF-16
+   *     encoded characters.
    */
   typedef struct  TT_NameRec_
   {
@@ -319,7 +241,7 @@
    *   TT_LangTagRec
    *
    * @description:
-   *   A structure modeling language tag records in SFNT `name' tables,
+   *   A structure modeling language tag records in SFNT 'name' tables,
    *   introduced in OpenType version 1.6.
    *
    * @fields:
@@ -327,11 +249,11 @@
    *     The length of the string in bytes.
    *
    *   stringOffset ::
-   *     The offset to the string in the `name' table.
+   *     The offset to the string in the 'name' table.
    *
    *   string ::
-   *     A pointer to the string's bytes.  Note that these
-   *     are UTF-16BE encoded characters.
+   *     A pointer to the string's bytes.  Note that these are UTF-16BE
+   *     encoded characters.
    */
   typedef struct TT_LangTagRec_
   {
@@ -362,8 +284,7 @@
    *     The number of names in table.
    *
    *   storageOffset ::
-   *     The offset of the name table in the `name'
-   *     TrueType table.
+   *     The offset of the name table in the 'name' TrueType table.
    *
    *   names ::
    *     An array of name records.
@@ -409,16 +330,16 @@
    *   TT_GaspRangeRec
    *
    * @description:
-   *   A tiny structure used to model a gasp range according to the
-   *   TrueType specification.
+   *   A tiny structure used to model a gasp range according to the TrueType
+   *   specification.
    *
    * @fields:
    *   maxPPEM ::
-   *     The maximum ppem value to which `gaspFlag' applies.
+   *     The maximum ppem value to which `gaspFlag` applies.
    *
    *   gaspFlag ::
-   *     A flag describing the grid-fitting and anti-aliasing
-   *     modes to be used.
+   *     A flag describing the grid-fitting and anti-aliasing modes to be
+   *     used.
    */
   typedef struct  TT_GaspRangeRec_
   {
@@ -438,7 +359,7 @@
    *   TT_GaspRec
    *
    * @description:
-   *   A structure modeling the TrueType `gasp' table used to specify
+   *   A structure modeling the TrueType 'gasp' table used to specify
    *   grid-fitting and anti-aliasing behaviour.
    *
    * @fields:
@@ -479,9 +400,9 @@
    *   TT_SBit_MetricsRec
    *
    * @description:
-   *   A structure used to hold the big metrics of a given glyph bitmap
-   *   in a TrueType or OpenType font.  These are usually found in the
-   *   `EBDT' (Microsoft) or `bloc' (Apple) table.
+   *   A structure used to hold the big metrics of a given glyph bitmap in a
+   *   TrueType or OpenType font.  These are usually found in the 'EBDT'
+   *   (Microsoft) or 'bloc' (Apple) table.
    *
    * @fields:
    *   height ::
@@ -530,9 +451,9 @@
    *   TT_SBit_SmallMetricsRec
    *
    * @description:
-   *   A structure used to hold the small metrics of a given glyph bitmap
-   *   in a TrueType or OpenType font.  These are usually found in the
-   *   `EBDT' (Microsoft) or the `bdat' (Apple) table.
+   *   A structure used to hold the small metrics of a given glyph bitmap in
+   *   a TrueType or OpenType font.  These are usually found in the 'EBDT'
+   *   (Microsoft) or the 'bdat' (Apple) table.
    *
    * @fields:
    *   height ::
@@ -568,8 +489,8 @@
    *   TT_SBit_LineMetricsRec
    *
    * @description:
-   *   A structure used to describe the text line metrics of a given
-   *   bitmap strike, for either a horizontal or vertical layout.
+   *   A structure used to describe the text line metrics of a given bitmap
+   *   strike, for either a horizontal or vertical layout.
    *
    * @fields:
    *   ascender ::
@@ -582,34 +503,27 @@
    *     The maximum glyph width in pixels.
    *
    *   caret_slope_enumerator ::
-   *     Rise of the caret slope, typically set
-   *     to 1 for non-italic fonts.
+   *     Rise of the caret slope, typically set to 1 for non-italic fonts.
    *
    *   caret_slope_denominator ::
-   *     Rise of the caret slope, typically set
-   *     to 0 for non-italic fonts.
+   *     Rise of the caret slope, typically set to 0 for non-italic fonts.
    *
    *   caret_offset ::
-   *     Offset in pixels to move the caret for
-   *     proper positioning.
+   *     Offset in pixels to move the caret for proper positioning.
    *
    *   min_origin_SB ::
-   *     Minimum of horiBearingX (resp.
-   *     vertBearingY).
+   *     Minimum of horiBearingX (resp.  vertBearingY).
    *   min_advance_SB ::
    *     Minimum of
    *
-   *     horizontal advance -
-   *     ( horiBearingX + width )
+   *     horizontal advance - ( horiBearingX + width )
    *
    *     resp.
    *
-   *     vertical advance -
-   *     ( vertBearingY + height )
+   *     vertical advance - ( vertBearingY + height )
    *
    *   max_before_BL ::
-   *     Maximum of horiBearingY (resp.
-   *     vertBearingY).
+   *     Maximum of horiBearingY (resp.  vertBearingY).
    *
    *   min_after_BL ::
    *     Minimum of
@@ -621,8 +535,7 @@
    *     vertBearingX - width
    *
    *   pads ::
-   *     Unused (to make the size of the record
-   *     a multiple of 32 bits.
+   *     Unused (to make the size of the record a multiple of 32 bits.
    */
   typedef struct  TT_SBit_LineMetricsRec_
   {
@@ -647,8 +560,8 @@
    *   TT_SBit_RangeRec
    *
    * @description:
-   *   A TrueType/OpenType subIndexTable as defined in the `EBLC'
-   *   (Microsoft) or `bloc' (Apple) tables.
+   *   A TrueType/OpenType subIndexTable as defined in the 'EBLC' (Microsoft)
+   *   or 'bloc' (Apple) tables.
    *
    * @fields:
    *   first_glyph ::
@@ -658,26 +571,25 @@
    *     The last glyph index in the range.
    *
    *   index_format ::
-   *     The format of index table.  Valid values are 1
-   *     to 5.
+   *     The format of index table.  Valid values are 1 to 5.
    *
    *   image_format ::
-   *     The format of `EBDT' image data.
+   *     The format of 'EBDT' image data.
    *
    *   image_offset ::
-   *     The offset to image data in `EBDT'.
+   *     The offset to image data in 'EBDT'.
    *
    *   image_size ::
-   *     For index formats 2 and 5.  This is the size in
-   *     bytes of each glyph bitmap.
+   *     For index formats 2 and 5.  This is the size in bytes of each glyph
+   *     bitmap.
    *
    *   big_metrics ::
-   *     For index formats 2 and 5.  This is the big
-   *     metrics for each glyph bitmap.
+   *     For index formats 2 and 5.  This is the big metrics for each glyph
+   *     bitmap.
    *
    *   num_glyphs ::
-   *     For index formats 4 and 5.  This is the number of
-   *     glyphs in the code array.
+   *     For index formats 4 and 5.  This is the number of glyphs in the code
+   *     array.
    *
    *   glyph_offsets ::
    *     For index formats 1 and 3.
@@ -686,8 +598,8 @@
    *     For index formats 4 and 5.
    *
    *   table_offset ::
-   *     The offset of the index table in the `EBLC'
-   *     table.  Only used during strike loading.
+   *     The offset of the index table in the 'EBLC' table.  Only used during
+   *     strike loading.
    */
   typedef struct  TT_SBit_RangeRec_
   {
@@ -716,8 +628,8 @@
    *   TT_SBit_StrikeRec
    *
    * @description:
-   *   A structure used describe a given bitmap strike in the `EBLC'
-   *   (Microsoft) or `bloc' (Apple) tables.
+   *   A structure used describe a given bitmap strike in the 'EBLC'
+   *   (Microsoft) or 'bloc' (Apple) tables.
    *
    * @fields:
    *  num_index_ranges ::
@@ -727,10 +639,9 @@
    *    An array of glyph index ranges.
    *
    *  color_ref ::
-   *    Unused.  `color_ref' is put in for future
-   *    enhancements, but these fields are already
-   *    in use by other platforms (e.g. Newton).
-   *    For details, please see
+   *    Unused.  `color_ref` is put in for future enhancements, but these
+   *    fields are already in use by other platforms (e.g. Newton).  For
+   *    details, please see
    *
    *    https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html
    *
@@ -753,12 +664,10 @@
    *    The number of vertical pixels per EM.
    *
    *  bit_depth ::
-   *    The bit depth.  Valid values are 1, 2, 4,
-   *    and 8.
+   *    The bit depth.  Valid values are 1, 2, 4, and 8.
    *
    *  flags ::
-   *    Is this a vertical or horizontal strike?  For
-   *    details, please see
+   *    Is this a vertical or horizontal strike?  For details, please see
    *
    *    https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html
    */
@@ -818,8 +727,8 @@
    *   TT_SBit_ScaleRec
    *
    * @description:
-   *   A structure used describe a given bitmap scaling table, as defined
-   *   in the `EBSC' table.
+   *   A structure used describe a given bitmap scaling table, as defined in
+   *   the 'EBSC' table.
    *
    * @fields:
    *   hori ::
@@ -873,8 +782,8 @@
    *   TT_Post_20Rec
    *
    * @description:
-   *   Postscript names sub-table, format 2.0.  Stores the PS name of
-   *   each glyph in the font face.
+   *   Postscript names sub-table, format 2.0.  Stores the PS name of each
+   *   glyph in the font face.
    *
    * @fields:
    *   num_glyphs ::
@@ -905,16 +814,15 @@
    *   TT_Post_25Rec
    *
    * @description:
-   *   Postscript names sub-table, format 2.5.  Stores the PS name of
-   *   each glyph in the font face.
+   *   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.
+   *     An array of signed offsets in a normal Mac Postscript name encoding.
    */
   typedef struct  TT_Post_25_
   {
@@ -987,25 +895,25 @@
 
   /*
    * These types are used to support a `BDF ' table that isn't part of the
-   * official TrueType specification.  It is mainly used in SFNT-based
-   * bitmap fonts that were generated from a set of BDF fonts.
+   * official TrueType specification.  It is mainly used in SFNT-based bitmap
+   * fonts that were generated from a set of BDF fonts.
    *
    * The format of the table is as follows.
    *
-   *   USHORT   version      `BDF ' table version number, should be 0x0001.
-   *   USHORT   strikeCount  Number of strikes (bitmap sizes) in this table.
-   *   ULONG    stringTable  Offset (from start of BDF table) to string
+   *   USHORT version `BDF ' table version number, should be 0x0001.  USHORT
+   *   strikeCount Number of strikes (bitmap sizes) in this table.  ULONG
+   *   stringTable Offset (from start of BDF table) to string
    *                         table.
    *
    * This is followed by an array of `strikeCount' descriptors, having the
    * following format.
    *
-   *   USHORT   ppem         Vertical pixels per EM for this strike.
-   *   USHORT   numItems     Number of items for this strike (properties and
+   *   USHORT ppem Vertical pixels per EM for this strike.  USHORT numItems
+   *   Number of items for this strike (properties and
    *                         atoms).  Maximum is 255.
    *
-   * This array in turn is followed by `strikeCount' value sets.  Each
-   * `value set' is an array of `numItems' items with the following format.
+   * This array in turn is followed by `strikeCount' value sets.  Each `value
+   * set' is an array of `numItems' items with the following format.
    *
    *   ULONG    item_name    Offset in string table to item name.
    *   USHORT   item_type    The item type.  Possible values are
@@ -1058,8 +966,8 @@
    * This structure/class is defined here because it is common to the
    * following formats: TTF, OpenType-TT, and OpenType-CFF.
    *
-   * Note, however, that the classes TT_Size and TT_GlyphSlot are not
-   * shared between font drivers, and are thus defined in `ttobjs.h'.
+   * Note, however, that the classes TT_Size and TT_GlyphSlot are not shared
+   * between font drivers, and are thus defined in `ttobjs.h`.
    *
    */
 
@@ -1070,12 +978,11 @@
    *   TT_Face
    *
    * @description:
-   *   A handle to a TrueType face/font object.  A TT_Face encapsulates
-   *   the resolution and scaling independent parts of a TrueType font
-   *   resource.
+   *   A handle to a TrueType face/font object.  A TT_Face encapsulates the
+   *   resolution and scaling independent parts of a TrueType font resource.
    *
    * @note:
-   *   The TT_Face structure is also used as a `parent class' for the
+   *   The TT_Face structure is also used as a 'parent class' for the
    *   OpenType-CFF class (T2_Face).
    */
   typedef struct TT_FaceRec_*  TT_Face;
@@ -1109,8 +1016,7 @@
    *
    * @output:
    *   length ::
-   *     The length of the table in bytes.  Set to 0 if not
-   *     needed.
+   *     The length of the table in bytes.  Set to 0 if not needed.
    *
    * @return:
    *   FreeType error code.  0 means success.
@@ -1141,8 +1047,7 @@
    *     glyph index :: The index of the glyph to access.
    *
    *   offset ::
-   *     The offset of the glyph according to the
-   *     `locations' table.
+   *     The offset of the glyph according to the 'locations' table.
    *
    *   byte_count ::
    *     The size of the frame in bytes.
@@ -1152,8 +1057,8 @@
    *
    * @note:
    *   This function is normally equivalent to FT_STREAM_SEEK(offset)
-   *   followed by FT_FRAME_ENTER(byte_count) with the loader's stream,
-   *   but alternative formats (e.g. compressed ones) might use something
+   *   followed by FT_FRAME_ENTER(byte_count) with the loader's stream, but
+   *   alternative formats (e.g. compressed ones) might use something
    *   different.
    */
   typedef FT_Error
@@ -1169,8 +1074,8 @@
    *   TT_Loader_ReadGlyphFunc
    *
    * @description:
-   *   Reads one glyph element (its header, a simple glyph, or a
-   *   composite) from the loader's current stream frame.
+   *   Reads one glyph element (its header, a simple glyph, or a composite)
+   *   from the loader's current stream frame.
    *
    * @input:
    *   loader ::
@@ -1254,111 +1159,90 @@
    *
    * @fields:
    *   root ::
-   *     The base FT_Face structure, managed by the
-   *     base layer.
+   *     The base FT_Face structure, managed by the base layer.
    *
    *   ttc_header ::
-   *     The TrueType collection header, used when
-   *     the file is a `ttc' rather than a `ttf'.
-   *     For ordinary font files, the field
-   *     `ttc_header.count' is set to 0.
+   *     The TrueType collection header, used when the file is a 'ttc' rather
+   *     than a 'ttf'.  For ordinary font files, the field `ttc_header.count`
+   *     is set to 0.
    *
    *   format_tag ::
    *     The font format tag.
    *
    *   num_tables ::
-   *     The number of TrueType tables in this font
-   *     file.
+   *     The number of TrueType tables in this font file.
    *
    *   dir_tables ::
-   *     The directory of TrueType tables for this
-   *     font file.
+   *     The directory of TrueType tables for this font file.
    *
    *   header ::
-   *     The font's font header (`head' table).
-   *     Read on font opening.
+   *     The font's font header ('head' table).  Read on font opening.
    *
    *   horizontal ::
-   *     The font's horizontal header (`hhea'
-   *     table).  This field also contains the
-   *     associated horizontal metrics table
-   *     (`hmtx').
+   *     The font's horizontal header ('hhea' table).  This field also
+   *     contains the associated horizontal metrics table ('hmtx').
    *
    *   max_profile ::
-   *     The font's maximum profile table.  Read on
-   *     font opening.  Note that some maximum
-   *     values cannot be taken directly from this
-   *     table.  We thus define additional fields
-   *     below to hold the computed maxima.
+   *     The font's maximum profile table.  Read on font opening.  Note that
+   *     some maximum values cannot be taken directly from this table.  We
+   *     thus define additional fields below to hold the computed maxima.
    *
    *   vertical_info ::
-   *     A boolean which is set when the font file
-   *     contains vertical metrics.  If not, the
-   *     value of the `vertical' field is
-   *     undefined.
+   *     A boolean which is set when the font file contains vertical metrics.
+   *     If not, the value of the 'vertical' field is undefined.
    *
    *   vertical ::
-   *     The font's vertical header (`vhea' table).
-   *     This field also contains the associated
-   *     vertical metrics table (`vmtx'), if found.
-   *     IMPORTANT: The contents of this field is
-   *     undefined if the `vertical_info' field is
-   *     unset.
+   *     The font's vertical header ('vhea' table).  This field also contains
+   *     the associated vertical metrics table ('vmtx'), if found.
+   *     IMPORTANT: The contents of this field is undefined if the
+   *     `vertical_info` field is unset.
    *
    *   num_names ::
-   *     The number of name records within this
-   *     TrueType font.
+   *     The number of name records within this TrueType font.
    *
    *   name_table ::
-   *     The table of name records (`name').
+   *     The table of name records ('name').
    *
    *   os2 ::
-   *     The font's OS/2 table (`OS/2').
+   *     The font's OS/2 table ('OS/2').
    *
    *   postscript ::
-   *     The font's PostScript table (`post'
-   *     table).  The PostScript glyph names are
-   *     not loaded by the driver on face opening.
-   *     See the `ttpost' module for more details.
+   *     The font's PostScript table ('post' table).  The PostScript glyph
+   *     names are not loaded by the driver on face opening.  See the
+   *     'ttpost' module for more details.
    *
    *   cmap_table ::
-   *     Address of the face's `cmap' SFNT table
-   *     in memory (it's an extracted frame).
+   *     Address of the face's 'cmap' SFNT table in memory (it's an extracted
+   *     frame).
    *
    *   cmap_size ::
-   *     The size in bytes of the `cmap_table'
-   *     described above.
+   *     The size in bytes of the `cmap_table` described above.
    *
    *   goto_table ::
-   *     A function called by each TrueType table
-   *     loader to position a stream's cursor to
-   *     the start of a given table according to
-   *     its tag.  It defaults to TT_Goto_Face but
-   *     can be different for strange formats (e.g.
-   *     Type 42).
+   *     A function called by each TrueType table loader to position a
+   *     stream's cursor to the start of a given table according to its tag.
+   *     It defaults to TT_Goto_Face but can be different for strange formats
+   *     (e.g.  Type 42).
    *
    *   access_glyph_frame ::
-   *     A function used to access the frame of a
-   *     given glyph within the face's font file.
+   *     A function used to access the frame of a given glyph within the
+   *     face's font file.
    *
    *   forget_glyph_frame ::
-   *     A function used to forget the frame of a
-   *     given glyph when all data has been loaded.
+   *     A function used to forget the frame of a given glyph when all data
+   *     has been loaded.
    *
    *   read_glyph_header ::
-   *     A function used to read a glyph header.
-   *     It must be called between an `access' and
-   *     `forget'.
+   *     A function used to read a glyph header.  It must be called between
+   *     an 'access' and 'forget'.
    *
    *   read_simple_glyph ::
-   *     A function used to read a simple glyph.
-   *     It must be called after the header was
-   *     read, and before the `forget'.
+   *     A function used to read a simple glyph.  It must be called after the
+   *     header was read, and before the 'forget'.
    *
    *   read_composite_glyph ::
-   *     A function used to read a composite glyph.
-   *     It must be called after the header was
-   *     read, and before the `forget'.
+   *     A function used to read a composite glyph.  It must be called after
+   *     the header was read, and before the 'forget'.
    *
    *   sfnt ::
    *     A pointer to the SFNT service.
@@ -1370,38 +1254,33 @@
    *     A pointer to the Multiple Masters service.
    *
    *   var ::
-   *     A pointer to the Metrics Variations
-   *     service.
+   *     A pointer to the Metrics Variations service.
    *
    *   hdmx ::
-   *     The face's horizontal device metrics
-   *     (`hdmx' table).  This table is optional in
-   *     TrueType/OpenType fonts.
+   *     The face's horizontal device metrics ('hdmx' table).  This table is
+   *     optional in TrueType/OpenType fonts.
    *
    *   gasp ::
-   *     The grid-fitting and scaling properties
-   *     table (`gasp').  This table is optional in
-   *     TrueType/OpenType fonts.
+   *     The grid-fitting and scaling properties table ('gasp').  This table
+   *     is optional in TrueType/OpenType fonts.
    *
    *   pclt ::
-   *     The `pclt' SFNT table.
+   *     The 'pclt' SFNT table.
    *
    *   num_sbit_scales ::
    *     The number of sbit scales for this font.
    *
    *   sbit_scales ::
-   *     Array of sbit scales embedded in this
-   *     font.  This table is optional in a
-   *     TrueType/OpenType font.
+   *     Array of sbit scales embedded in this font.  This table is optional
+   *     in a TrueType/OpenType font.
    *
    *   postscript_names ::
-   *     A table used to store the Postscript names
-   *     of  the glyphs for this font.  See the
-   *     file  `ttconfig.h' for comments on the
+   *     A table used to store the Postscript names of the glyphs for this
+   *     font.  See the file `ttconfig.h` for comments on the
    *     TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.
    *
    *   palette_data ::
-   *     Some fields from the `CPAL' table that are directly indexed.
+   *     Some fields from the 'CPAL' table that are directly indexed.
    *
    *   palette_index ::
    *     The current palette index, as set by @FT_Palette_Select.
@@ -1413,109 +1292,97 @@
    *     There was a call to @FT_Palette_Set_Foreground_Color.
    *
    *   foreground_color ::
-   *     The current foreground color corresponding to `CPAL' color index
-   *     0xFFFF.  Only valid if `have_foreground_color' is set.
+   *     The current foreground color corresponding to 'CPAL' color index
+   *     0xFFFF.  Only valid if `have_foreground_color` is set.
    *
    *   font_program_size ::
-   *     Size in bytecodes of the face's font
-   *     program.  0 if none defined.  Ignored for
-   *     Type 2 fonts.
-   *
-   *   font_program ::
-   *     The face's font program (bytecode stream)
-   *     executed at load time, also used during
-   *     glyph rendering.  Comes from the `fpgm'
-   *     table.  Ignored for Type 2 font fonts.
-   *
-   *   cvt_program_size ::
-   *     The size in bytecodes of the face's cvt
-   *     program.  Ignored for Type 2 fonts.
-   *
-   *   cvt_program ::
-   *     The face's cvt program (bytecode stream)
-   *     executed each time an instance/size is
-   *     changed/reset.  Comes from the `prep'
-   *     table.  Ignored for Type 2 fonts.
-   *
-   *   cvt_size ::
-   *     Size of the control value table (in
-   *     entries).   Ignored for Type 2 fonts.
-   *
-   *   cvt ::
-   *     The face's original control value table.
-   *     Coordinates are expressed in unscaled font
-   *     units.  Comes from the `cvt ' table.
+   *     Size in bytecodes of the face's font program.  0 if none defined.
    *     Ignored for Type 2 fonts.
    *
+   *   font_program ::
+   *     The face's font program (bytecode stream) executed at load time,
+   *     also used during glyph rendering.  Comes from the 'fpgm' table.
+   *     Ignored for Type 2 font fonts.
+   *
+   *   cvt_program_size ::
+   *     The size in bytecodes of the face's cvt program.  Ignored for Type 2
+   *     fonts.
+   *
+   *   cvt_program ::
+   *     The face's cvt program (bytecode stream) executed each time an
+   *     instance/size is changed/reset.  Comes from the 'prep' table.
+   *     Ignored for Type 2 fonts.
+   *
+   *   cvt_size ::
+   *     Size of the control value table (in entries).  Ignored for Type 2
+   *     fonts.
+   *
+   *   cvt ::
+   *     The face's original control value table.  Coordinates are expressed
+   *     in unscaled font units (in 26.6 format).  Comes from the 'cvt~'
+   *     table.  Ignored for Type 2 fonts.
+   *
+   *     If varied by the `CVAR' table, non-integer values are possible.
+   *
    *   interpreter ::
-   *     A pointer to the TrueType bytecode
-   *     interpreters field is also used to hook
-   *     the debugger in `ttdebug'.
+   *     A pointer to the TrueType bytecode interpreters field is also used
+   *     to hook the debugger in 'ttdebug'.
    *
    *   extra ::
    *     Reserved for third-party font drivers.
    *
    *   postscript_name ::
-   *     The PS name of the font.  Used by the
-   *     postscript name service.
+   *     The PS name of the font.  Used by the postscript name service.
    *
    *   glyf_len ::
-   *     The length of the `glyf' table.  Needed
-   *     for malformed `loca' tables.
+   *     The length of the 'glyf' table.  Needed for malformed 'loca' tables.
    *
    *   glyf_offset ::
-   *     The file offset of the `glyf' table.
+   *     The file offset of the 'glyf' table.
    *
    *   is_cff2 ::
    *     Set if the font format is CFF2.
    *
    *   doblend ::
-   *     A boolean which is set if the font should
-   *     be blended (this is for GX var).
+   *     A boolean which is set if the font should be blended (this is for GX
+   *     var).
    *
    *   blend ::
-   *     Contains the data needed to control GX
-   *     variation tables (rather like Multiple
-   *     Master data).
+   *     Contains the data needed to control GX variation tables (rather like
+   *     Multiple Master data).
    *
    *   variation_support ::
-   *     Flags that indicate which OpenType
-   *     functionality related to font variation
-   *     support is present, valid, and usable.
-   *     For example, TT_FACE_FLAG_VAR_FVAR is only
-   *     set if we have at least one design axis.
+   *     Flags that indicate which OpenType functionality related to font
+   *     variation support is present, valid, and usable.  For example,
+   *     TT_FACE_FLAG_VAR_FVAR is only set if we have at least one design
+   *     axis.
    *
    *   var_postscript_prefix ::
-   *     The PostScript name prefix needed for
-   *     constructing a variation font instance's
-   *     PS name .
+   *     The PostScript name prefix needed for constructing a variation font
+   *     instance's PS name .
    *
    *   var_postscript_prefix_len ::
-   *     The length of the `var_postscript_prefix'
-   *     string.
+   *     The length of the `var_postscript_prefix` string.
    *
    *   horz_metrics_size ::
-   *     The size of the `hmtx' table.
+   *     The size of the 'hmtx' table.
    *
    *   vert_metrics_size ::
-   *     The size of the `vmtx' table.
+   *     The size of the 'vmtx' table.
    *
    *   num_locations ::
-   *     The number of glyph locations in this
-   *     TrueType file.  This should be
-   *     identical to the number of glyphs.
-   *     Ignored for Type 2 fonts.
+   *     The number of glyph locations in this TrueType file.  This should be
+   *     one more than the number of glyphs.  Ignored for Type 2 fonts.
    *
    *   glyph_locations ::
-   *     An array of longs.  These are offsets to
-   *     glyph data within the `glyf' table.
-   *     Ignored for Type 2 font faces.
+   *     An array of longs.  These are offsets to glyph data within the
+   *     'glyf' table.  Ignored for Type 2 font faces.
    *
    *   hdmx_table ::
-   *     A pointer to the `hdmx' table.
+   *     A pointer to the 'hdmx' table.
    *
    *   hdmx_table_size ::
-   *     The size of the `hdmx' table.
+   *     The size of the 'hdmx' table.
    *
    *   hdmx_record_count ::
    *     The number of hdmx records.
@@ -1523,80 +1390,71 @@
    *   hdmx_record_size ::
    *     The size of a single hdmx record.
    *
-   *   hdmx_record_sizes ::
-   *     An array holding the ppem sizes available
-   *     in the `hdmx' table.
+   *   hdmx_records ::
+   *     A array of pointers to the 'hdmx' table records sorted by ppem.
    *
    *   sbit_table ::
-   *     A pointer to the font's embedded bitmap
-   *     location table.
+   *     A pointer to the font's embedded bitmap location table.
    *
    *   sbit_table_size ::
-   *     The size of `sbit_table'.
+   *     The size of `sbit_table`.
    *
    *   sbit_table_type ::
    *     The sbit table type (CBLC, sbix, etc.).
    *
    *   sbit_num_strikes ::
-   *     The number of sbit strikes exposed by
-   *     FreeType's API, omitting invalid strikes.
+   *     The number of sbit strikes exposed by FreeType's API, omitting
+   *     invalid strikes.
    *
    *   sbit_strike_map ::
-   *     A mapping between the strike indices
-   *     exposed by the API and the indices used in
-   *     the font's sbit table.
+   *     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
+   *     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
+   *     A pointer to data related to the 'COLR' table.  `NULL` if the table
    *     is not available.
    *
    *   kern_table ::
-   *     A pointer to the `kern' table.
+   *     A pointer to the 'kern' table.
    *
    *   kern_table_size ::
-   *     The size of the `kern' table.
+   *     The size of the 'kern' table.
    *
    *   num_kern_tables ::
-   *     The number of supported kern subtables
-   *     (up to 32; FreeType recognizes only
-   *     horizontal ones with format 0).
+   *     The number of supported kern subtables (up to 32; FreeType
+   *     recognizes only horizontal ones with format 0).
    *
    *   kern_avail_bits ::
-   *     The availability status of kern subtables;
-   *     if bit n is set, table n is available.
+   *     The availability status of kern subtables; if bit n is set, table n
+   *     is available.
    *
    *   kern_order_bits ::
-   *     The sortedness status of kern subtables;
-   *     if bit n is set, table n is sorted.
+   *     The sortedness status of kern subtables; if bit n is set, table n is
+   *     sorted.
    *
    *   bdf ::
-   *     Data related to an SFNT font's `bdf'
-   *     table; see `tttypes.h'.
+   *     Data related to an SFNT font's 'bdf' table; see `tttypes.h`.
    *
    *   horz_metrics_offset ::
-   *     The file offset of the `hmtx' table.
+   *     The file offset of the 'hmtx' table.
    *
    *   vert_metrics_offset ::
-   *     The file offset of the `vmtx' table.
+   *     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).
+   *     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).
+   *     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.).
+   *     The file offset of the sbit data table (CBDT, bdat, etc.).
    *
    *   ebdt_size ::
    *     The size of the sbit data table.
@@ -1701,7 +1559,7 @@
 
     /* the original, unscaled, control value table */
     FT_ULong              cvt_size;
-    FT_Short*             cvt;
+    FT_Int32*             cvt;
 
     /* A pointer to the bytecode interpreter to use.  This is also */
     /* used to hook the debugger for the `ttdebug' utility.        */
@@ -1740,14 +1598,14 @@
     FT_ULong              horz_metrics_size;
     FT_ULong              vert_metrics_size;
 
-    FT_ULong              num_locations; /* in broken TTF, gid > 0xFFFF */
+    FT_ULong              num_locations; /* up to 0xFFFF + 1 */
     FT_Byte*              glyph_locations;
 
     FT_Byte*              hdmx_table;
     FT_ULong              hdmx_table_size;
     FT_UInt               hdmx_record_count;
     FT_ULong              hdmx_record_size;
-    FT_Byte*              hdmx_record_sizes;
+    FT_Byte**             hdmx_records;
 
     FT_Byte*              sbit_table;
     FT_ULong              sbit_table_size;
@@ -1786,6 +1644,9 @@
     void*                 cpal;
     void*                 colr;
 
+    /* since 2.12 */
+    void*                 svg;
+
   } TT_FaceRec;
 
 
@@ -1815,8 +1676,7 @@
    *     The current number of contours in the zone.
    *
    *   org ::
-   *     The original glyph coordinates (font
-   *     units/scaled).
+   *     The original glyph coordinates (font units/scaled).
    *
    *   cur ::
    *     The current glyph coordinates (scaled/hinted).
@@ -1877,7 +1737,7 @@
     FT_UInt          glyph_index;
 
     FT_Stream        stream;
-    FT_Int           byte_len;
+    FT_UInt          byte_len;
 
     FT_Short         n_contours;
     FT_BBox          bbox;
@@ -1912,6 +1772,9 @@
     /* since version 2.6.2 */
     FT_ListRec       composites;
 
+    /* since version 2.11.2 */
+    FT_Byte*         widthp;
+
   } TT_LoaderRec;
 
 
diff --git a/include/freetype/internal/wofftypes.h b/include/freetype/internal/wofftypes.h
new file mode 100644
index 0000000..0c1d8ee
--- /dev/null
+++ b/include/freetype/internal/wofftypes.h
@@ -0,0 +1,312 @@
+/****************************************************************************
+ *
+ * wofftypes.h
+ *
+ *   Basic WOFF/WOFF2 type definitions and interface (specification
+ *   only).
+ *
+ * Copyright (C) 1996-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 WOFFTYPES_H_
+#define WOFFTYPES_H_
+
+
+#include <freetype/tttables.h>
+#include <freetype/internal/ftobjs.h>
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF_HeaderRec
+   *
+   * @description:
+   *   WOFF file format header.
+   *
+   * @fields:
+   *   See
+   *
+   *     https://www.w3.org/TR/WOFF/#WOFFHeader
+   */
+  typedef struct  WOFF_HeaderRec_
+  {
+    FT_ULong   signature;
+    FT_ULong   flavor;
+    FT_ULong   length;
+    FT_UShort  num_tables;
+    FT_UShort  reserved;
+    FT_ULong   totalSfntSize;
+    FT_UShort  majorVersion;
+    FT_UShort  minorVersion;
+    FT_ULong   metaOffset;
+    FT_ULong   metaLength;
+    FT_ULong   metaOrigLength;
+    FT_ULong   privOffset;
+    FT_ULong   privLength;
+
+  } WOFF_HeaderRec, *WOFF_Header;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF_TableRec
+   *
+   * @description:
+   *   This structure describes a given table of a WOFF font.
+   *
+   * @fields:
+   *   Tag ::
+   *     A four-bytes tag describing the table.
+   *
+   *   Offset ::
+   *     The offset of the table from the start of the WOFF font in its
+   *     resource.
+   *
+   *   CompLength ::
+   *     Compressed table length (in bytes).
+   *
+   *   OrigLength ::
+   *     Uncompressed table length (in bytes).
+   *
+   *   CheckSum ::
+   *     The table checksum.  This value can be ignored.
+   *
+   *   OrigOffset ::
+   *     The uncompressed table file offset.  This value gets computed while
+   *     constructing the (uncompressed) SFNT header.  It is not contained in
+   *     the WOFF file.
+   */
+  typedef struct  WOFF_TableRec_
+  {
+    FT_Tag    Tag;           /* table ID                  */
+    FT_ULong  Offset;        /* table file offset         */
+    FT_ULong  CompLength;    /* compressed table length   */
+    FT_ULong  OrigLength;    /* uncompressed table length */
+    FT_ULong  CheckSum;      /* uncompressed checksum     */
+
+    FT_ULong  OrigOffset;    /* uncompressed table file offset */
+                             /* (not in the WOFF file)         */
+  } WOFF_TableRec, *WOFF_Table;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF2_TtcFontRec
+   *
+   * @description:
+   *   Metadata for a TTC font entry in WOFF2.
+   *
+   * @fields:
+   *   flavor ::
+   *     TTC font flavor.
+   *
+   *   num_tables ::
+   *     Number of tables in TTC, indicating number of elements in
+   *     `table_indices`.
+   *
+   *   table_indices ::
+   *     Array of table indices for each TTC font.
+   */
+  typedef struct  WOFF2_TtcFontRec_
+  {
+    FT_ULong    flavor;
+    FT_UShort   num_tables;
+    FT_UShort*  table_indices;
+
+  } WOFF2_TtcFontRec, *WOFF2_TtcFont;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF2_HeaderRec
+   *
+   * @description:
+   *   WOFF2 file format header.
+   *
+   * @fields:
+   *   See
+   *
+   *     https://www.w3.org/TR/WOFF2/#woff20Header
+   *
+   * @note:
+   *   We don't care about the fields `reserved`, `majorVersion` and
+   *   `minorVersion`, so they are not included.  The `totalSfntSize` field
+   *   does not necessarily represent the actual size of the uncompressed
+   *   SFNT font stream, so that is used as a reference value instead.
+   */
+  typedef struct  WOFF2_HeaderRec_
+  {
+    FT_ULong   signature;
+    FT_ULong   flavor;
+    FT_ULong   length;
+    FT_UShort  num_tables;
+    FT_ULong   totalSfntSize;
+    FT_ULong   totalCompressedSize;
+    FT_ULong   metaOffset;
+    FT_ULong   metaLength;
+    FT_ULong   metaOrigLength;
+    FT_ULong   privOffset;
+    FT_ULong   privLength;
+
+    FT_ULong   uncompressed_size;    /* uncompressed brotli stream size */
+    FT_ULong   compressed_offset;    /* compressed stream offset        */
+    FT_ULong   header_version;       /* version of original TTC Header  */
+    FT_UShort  num_fonts;            /* number of fonts in TTC          */
+    FT_ULong   actual_sfnt_size;     /* actual size of sfnt stream      */
+
+    WOFF2_TtcFont  ttc_fonts;        /* metadata for fonts in a TTC     */
+
+  } WOFF2_HeaderRec, *WOFF2_Header;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF2_TableRec
+   *
+   * @description:
+   *   This structure describes a given table of a WOFF2 font.
+   *
+   * @fields:
+   *   See
+   *
+   *     https://www.w3.org/TR/WOFF2/#table_dir_format
+   */
+  typedef struct  WOFF2_TableRec_
+  {
+    FT_Byte   FlagByte;           /* table type and flags      */
+    FT_Tag    Tag;                /* table file offset         */
+    FT_ULong  dst_length;         /* uncompressed table length */
+    FT_ULong  TransformLength;    /* transformed length        */
+
+    FT_ULong  flags;              /* calculated flags          */
+    FT_ULong  src_offset;         /* compressed table offset   */
+    FT_ULong  src_length;         /* compressed table length   */
+    FT_ULong  dst_offset;         /* uncompressed table offset */
+
+  } WOFF2_TableRec, *WOFF2_Table;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF2_InfoRec
+   *
+   * @description:
+   *   Metadata for WOFF2 font that may be required for reconstruction of
+   *   sfnt tables.
+   *
+   * @fields:
+   *   header_checksum ::
+   *     Checksum of SFNT offset table.
+   *
+   *   num_glyphs ::
+   *     Number of glyphs in the font.
+   *
+   *   num_hmetrics ::
+   *     `numberOfHMetrics` field in the 'hhea' table.
+   *
+   *   x_mins ::
+   *     `xMin` values of glyph bounding box.
+   *
+   *   glyf_table ::
+   *     A pointer to the `glyf' table record.
+   *
+   *   loca_table ::
+   *     A pointer to the `loca' table record.
+   *
+   *   head_table ::
+   *     A pointer to the `head' table record.
+   */
+  typedef struct  WOFF2_InfoRec_
+  {
+    FT_ULong   header_checksum;
+    FT_UShort  num_glyphs;
+    FT_UShort  num_hmetrics;
+    FT_Short*  x_mins;
+
+    WOFF2_Table  glyf_table;
+    WOFF2_Table  loca_table;
+    WOFF2_Table  head_table;
+
+  } WOFF2_InfoRec, *WOFF2_Info;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF2_SubstreamRec
+   *
+   * @description:
+   *   This structure stores information about a substream in the transformed
+   *   'glyf' table in a WOFF2 stream.
+   *
+   * @fields:
+   *   start ::
+   *     Beginning of the substream relative to uncompressed table stream.
+   *
+   *   offset ::
+   *     Offset of the substream relative to uncompressed table stream.
+   *
+   *   size ::
+   *     Size of the substream.
+   */
+  typedef struct  WOFF2_SubstreamRec_
+  {
+    FT_ULong  start;
+    FT_ULong  offset;
+    FT_ULong  size;
+
+  } WOFF2_SubstreamRec, *WOFF2_Substream;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF2_PointRec
+   *
+   * @description:
+   *   This structure stores information about a point in the transformed
+   *   'glyf' table in a WOFF2 stream.
+   *
+   * @fields:
+   *   x ::
+   *     x-coordinate of point.
+   *
+   *   y ::
+   *     y-coordinate of point.
+   *
+   *   on_curve ::
+   *     Set if point is on-curve.
+   */
+  typedef struct  WOFF2_PointRec_
+  {
+    FT_Int   x;
+    FT_Int   y;
+    FT_Bool  on_curve;
+
+  } WOFF2_PointRec, *WOFF2_Point;
+
+
+FT_END_HEADER
+
+#endif /* WOFFTYPES_H_ */
+
+
+/* END */
diff --git a/include/freetype/otsvg.h b/include/freetype/otsvg.h
new file mode 100644
index 0000000..bfe9a6a
--- /dev/null
+++ b/include/freetype/otsvg.h
@@ -0,0 +1,336 @@
+/****************************************************************************
+ *
+ * otsvg.h
+ *
+ *   Interface for OT-SVG support related things (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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 OTSVG_H_
+#define OTSVG_H_
+
+#include <freetype/freetype.h>
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   svg_fonts
+   *
+   * @title:
+   *   OpenType SVG Fonts
+   *
+   * @abstract:
+   *   OT-SVG API between FreeType and an external SVG rendering library.
+   *
+   * @description:
+   *   This section describes the four hooks necessary to render SVG
+   *   'documents' that are contained in an OpenType font's 'SVG~' table.
+   *
+   *   For more information on the implementation, see our standard hooks
+   *   based on 'librsvg' in the [FreeType Demo
+   *   Programs](https://gitlab.freedesktop.org/freetype/freetype-demos)
+   *   repository.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   SVG_Lib_Init_Func
+   *
+   * @description:
+   *   A callback that is called when the first OT-SVG glyph is rendered in
+   *   the lifetime of an @FT_Library object.  In a typical implementation,
+   *   one would want to allocate a structure and point the `data_pointer`
+   *   to it and perform any library initializations that might be needed.
+   *
+   * @inout:
+   *   data_pointer ::
+   *     The SVG rendering module stores a pointer variable that can be used
+   *     by clients to store any data that needs to be shared across
+   *     different hooks.  `data_pointer` is essentially a pointer to that
+   *     pointer such that it can be written to as well as read from.
+   *
+   * @return:
+   *   FreeType error code.  0 means success.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef FT_Error
+  (*SVG_Lib_Init_Func)( FT_Pointer  *data_pointer );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   SVG_Lib_Free_Func
+   *
+   * @description:
+   *   A callback that is called when the `ot-svg` module is being freed.
+   *   It is only called if the init hook was called earlier.  This means
+   *   that neither the init nor the free hook is called if no OT-SVG glyph
+   *   is rendered.
+   *
+   *   In a typical implementation, one would want to free any state
+   *   structure that was allocated in the init hook and perform any
+   *   library-related closure that might be needed.
+   *
+   * @inout:
+   *   data_pointer ::
+   *     The SVG rendering module stores a pointer variable that can be used
+   *     by clients to store any data that needs to be shared across
+   *     different hooks.  `data_pointer` is essentially a pointer to that
+   *     pointer such that it can be written to as well as read from.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef void
+  (*SVG_Lib_Free_Func)( FT_Pointer  *data_pointer );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   SVG_Lib_Render_Func
+   *
+   * @description:
+   *   A callback that is called to render an OT-SVG glyph.  This callback
+   *   hook is called right after the preset hook @SVG_Lib_Preset_Slot_Func
+   *   has been called with `cache` set to `TRUE`.  The data necessary to
+   *   render is available through the handle @FT_SVG_Document, which is set
+   *   in the `other` field of @FT_GlyphSlotRec.
+   *
+   *   The render hook is expected to render the SVG glyph to the bitmap
+   *   buffer that is allocated already at `slot->bitmap.buffer`.  It also
+   *   sets the `num_grays` value as well as `slot->format`.
+   *
+   * @input:
+   *   slot ::
+   *     The slot to render.
+   *
+   * @inout:
+   *   data_pointer ::
+   *     The SVG rendering module stores a pointer variable that can be used
+   *     by clients to store any data that needs to be shared across
+   *     different hooks.  `data_pointer` is essentially a pointer to that
+   *     pointer such that it can be written to as well as read from.
+   *
+   * @return:
+   *   FreeType error code.  0 means success.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef FT_Error
+  (*SVG_Lib_Render_Func)( FT_GlyphSlot  slot,
+                          FT_Pointer   *data_pointer );
+
+
+  /**************************************************************************
+   *
+   * @functype:
+   *   SVG_Lib_Preset_Slot_Func
+   *
+   * @description:
+   *   A callback that is called to preset the glyph slot.  It is called from
+   *   two places.
+   *
+   *   1. When `FT_Load_Glyph` needs to preset the glyph slot.
+   *
+   *   2. Right before the `svg` module calls the render callback hook.
+   *
+   *   When it is the former, the argument `cache` is set to `FALSE`.  When
+   *   it is the latter, the argument `cache` is set to `TRUE`.  This
+   *   distinction has been made because many calculations that are necessary
+   *   for presetting a glyph slot are the same needed later for the render
+   *   callback hook.  Thus, if `cache` is `TRUE`, the hook can _cache_ those
+   *   calculations in a memory block referenced by the state pointer.
+   *
+   *   This hook is expected to preset the slot by setting parameters such as
+   *   `bitmap_left`, `bitmap_top`, `width`, `rows`, `pitch`, and
+   *   `pixel_mode`.  It is also expected to set all the metrics for the slot
+   *   including the vertical advance if it is not already set.  Typically,
+   *   fonts have horizontal advances but not vertical ones.  If those are
+   *   available, they had already been set, otherwise they have to be
+   *   estimated and set manually.  The hook must take into account the
+   *   transformations that have been set, and translate the transformation
+   *   matrices into the SVG coordinate system, as the original matrix is
+   *   intended for the TTF/CFF coordinate system.
+   *
+   * @input:
+   *   slot ::
+   *     The glyph slot that has the SVG document loaded.
+   *
+   *   cache ::
+   *     See description.
+   *
+   * @inout:
+   *   data_pointer ::
+   *     The SVG rendering module stores a pointer variable that can be used
+   *     by clients to store any data that needs to be shared across
+   *     different hooks.  `data_pointer` is essentially a pointer to that
+   *     pointer such that it can be written to as well as read from.
+   *
+   * @return:
+   *   FreeType error code.  0 means success.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef FT_Error
+  (*SVG_Lib_Preset_Slot_Func)( FT_GlyphSlot  slot,
+                               FT_Bool       cache,
+                               FT_Pointer   *state );
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   SVG_RendererHooks
+   *
+   * @description:
+   *   A structure that stores the four hooks needed to render OT-SVG glyphs
+   *   properly.  The structure is publicly used to set the hooks via the
+   *   @svg-hooks driver property.
+   *
+   *   The behavior of each hook is described in its documentation.  One
+   *   thing to note is that the preset hook and the render hook often need
+   *   to do the same operations; therefore, it's better to cache the
+   *   intermediate data in a state structure to avoid calculating it twice.
+   *   For example, in the preset hook one can draw the glyph on a recorder
+   *   surface and later create a bitmap surface from it in the render hook.
+   *
+   *   All four hooks must be non-NULL.
+   *
+   * @fields:
+   *   init_svg ::
+   *     The initialization hook.
+   *
+   *   free_svg ::
+   *     The cleanup hook.
+   *
+   *   render_hook ::
+   *     The render hook.
+   *
+   *   preset_slot ::
+   *     The preset hook.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef struct SVG_RendererHooks_
+  {
+    SVG_Lib_Init_Func    init_svg;
+    SVG_Lib_Free_Func    free_svg;
+    SVG_Lib_Render_Func  render_svg;
+
+    SVG_Lib_Preset_Slot_Func  preset_slot;
+
+  } SVG_RendererHooks;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_SVG_DocumentRec
+   *
+   * @description:
+   *   A structure that models one SVG document.
+   *
+   * @fields:
+   *   svg_document ::
+   *     A pointer to the SVG document.
+   *
+   *   svg_document_length ::
+   *     The length of `svg_document`.
+   *
+   *   metrics ::
+   *     A metrics object storing the size information.
+   *
+   *   units_per_EM ::
+   *     The size of the EM square.
+   *
+   *   start_glyph_id ::
+   *     The first glyph ID in the glyph range covered by this document.
+   *
+   *   end_glyph_id ::
+   *     The last glyph ID in the glyph range covered by this document.
+   *
+   *   transform ::
+   *     A 2x2 transformation matrix to apply to the glyph while rendering
+   *     it.
+   *
+   *   delta ::
+   *     The translation to apply to the glyph while rendering.
+   *
+   * @note:
+   *   When an @FT_GlyphSlot object `slot` is passed down to a renderer, the
+   *   renderer can only access the `metrics` and `units_per_EM` fields via
+   *   `slot->face`.  However, when @FT_Glyph_To_Bitmap sets up a dummy
+   *   object, it has no way to set a `face` object.  Thus, metrics
+   *   information and `units_per_EM` (which is necessary for OT-SVG) has to
+   *   be stored separately.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef struct  FT_SVG_DocumentRec_
+  {
+    FT_Byte*  svg_document;
+    FT_ULong  svg_document_length;
+
+    FT_Size_Metrics  metrics;
+    FT_UShort        units_per_EM;
+
+    FT_UShort  start_glyph_id;
+    FT_UShort  end_glyph_id;
+
+    FT_Matrix  transform;
+    FT_Vector  delta;
+
+  } FT_SVG_DocumentRec;
+
+
+  /**************************************************************************
+   *
+   * @type:
+   *   FT_SVG_Document
+   *
+   * @description:
+   *   A handle to an @FT_SVG_DocumentRec object.
+   *
+   * @since:
+   *   2.12
+   */
+  typedef struct FT_SVG_DocumentRec_*  FT_SVG_Document;
+
+
+FT_END_HEADER
+
+#endif /* OTSVG_H_ */
+
+
+/* END */
diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h
index 784f1b9..1aecfbb 100644
--- a/include/freetype/t1tables.h
+++ b/include/freetype/t1tables.h
@@ -5,7 +5,7 @@
  *   Basic Type 1/Type 2 tables definitions and interface (specification
  *   only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,8 +21,7 @@
 #define T1TABLES_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -118,9 +117,8 @@
    *   T1_FontInfo
    *
    * @description:
-   *   This type is equivalent to @PS_FontInfoRec.  It is deprecated but
-   *   kept to maintain source compatibility between various versions of
-   *   FreeType.
+   *   This type is equivalent to @PS_FontInfoRec.  It is deprecated but kept
+   *   to maintain source compatibility between various versions of FreeType.
    */
   typedef PS_FontInfoRec  T1_FontInfo;
 
@@ -131,9 +129,9 @@
    *   PS_PrivateRec
    *
    * @description:
-   *   A structure used to model a Type~1 or Type~2 private dictionary.
-   *   Note that for Multiple Master fonts, each instance has its own
-   *   Private dictionary.
+   *   A structure used to model a Type~1 or Type~2 private dictionary.  Note
+   *   that for Multiple Master fonts, each instance has its own Private
+   *   dictionary.
    */
   typedef struct  PS_PrivateRec_
   {
@@ -193,9 +191,8 @@
    *   T1_Private
    *
    * @description:
-   *  This type is equivalent to @PS_PrivateRec.  It is deprecated but
-   *  kept to maintain source compatibility between various versions of
-   *  FreeType.
+   *  This type is equivalent to @PS_PrivateRec.  It is deprecated but kept
+   *  to maintain source compatibility between various versions of FreeType.
    */
   typedef PS_PrivateRec  T1_Private;
 
@@ -206,9 +203,9 @@
    *   T1_Blend_Flags
    *
    * @description:
-   *   A set of flags used to indicate which fields are present in a
-   *   given blend dictionary (font info or private).  Used to support
-   *   Multiple Masters fonts.
+   *   A set of flags used to indicate which fields are present in a given
+   *   blend dictionary (font info or private).  Used to support Multiple
+   *   Masters fonts.
    *
    * @values:
    *   T1_BLEND_UNDERLINE_POSITION ::
@@ -252,7 +249,7 @@
 
 
   /* these constants are deprecated; use the corresponding */
-  /* `T1_Blend_Flags' values instead                       */
+  /* `T1_Blend_Flags` values instead                       */
 #define t1_blend_underline_position   T1_BLEND_UNDERLINE_POSITION
 #define t1_blend_underline_thickness  T1_BLEND_UNDERLINE_THICKNESS
 #define t1_blend_italic_angle         T1_BLEND_ITALIC_ANGLE
@@ -337,14 +334,14 @@
    *
    * @description:
    *   A structure used to represent data in a CID top-level dictionary.  In
-   *   most cases, they are part of the font's `/FDArray' array.  Within a
+   *   most cases, they are part of the font's '/FDArray' array.  Within a
    *   CID font file, such (internal) subfont dictionaries are enclosed by
-   *   `%ADOBeginFontDict' and `%ADOEndFontDict' comments.
+   *   '%ADOBeginFontDict' and '%ADOEndFontDict' comments.
    *
-   *   Note that `CID_FaceDictRec' misses a field for the `/FontName'
+   *   Note that `CID_FaceDictRec` misses a field for the '/FontName'
    *   keyword, specifying the subfont's name (the top-level font name is
-   *   given by the `/CIDFontName' keyword).  This is an oversight, but it
-   *   doesn't limit the `cid' font module's functionality because FreeType
+   *   given by the '/CIDFontName' keyword).  This is an oversight, but it
+   *   doesn't limit the 'cid' font module's functionality because FreeType
    *   neither needs this entry nor gives access to CID subfonts.
    */
   typedef struct  CID_FaceDictRec_
@@ -363,7 +360,7 @@
 
     FT_UInt        num_subrs;
     FT_ULong       subrmap_offset;
-    FT_Int         sd_bytes;
+    FT_UInt        sd_bytes;
 
   } CID_FaceDictRec;
 
@@ -418,11 +415,11 @@
     FT_ULong        xuid[16];
 
     FT_ULong        cidmap_offset;
-    FT_Int          fd_bytes;
-    FT_Int          gd_bytes;
+    FT_UInt         fd_bytes;
+    FT_UInt         gd_bytes;
     FT_ULong        cid_count;
 
-    FT_Int          num_dicts;
+    FT_UInt         num_dicts;
     CID_FaceDict    font_dicts;
 
     FT_ULong        data_offset;
@@ -447,66 +444,74 @@
    *   CID_Info
    *
    * @description:
-   *  This type is equivalent to @CID_FaceInfoRec.  It is deprecated but
-   *  kept to maintain source compatibility between various versions of
-   *  FreeType.
+   *  This type is equivalent to @CID_FaceInfoRec.  It is deprecated but kept
+   *  to maintain source compatibility between various versions of FreeType.
    */
   typedef CID_FaceInfoRec  CID_Info;
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
-   *    FT_Has_PS_Glyph_Names
+   *   FT_Has_PS_Glyph_Names
    *
    * @description:
-   *    Return true if a given face provides reliable PostScript glyph
-   *    names.  This is similar to using the @FT_HAS_GLYPH_NAMES macro,
-   *    except that certain fonts (mostly TrueType) contain incorrect
-   *    glyph name tables.
+   *   Return true if a given face provides reliable PostScript glyph names.
+   *   This is similar to using the @FT_HAS_GLYPH_NAMES macro, except that
+   *   certain fonts (mostly TrueType) contain incorrect glyph name tables.
    *
-   *    When this function returns true, the caller is sure that the glyph
-   *    names returned by @FT_Get_Glyph_Name are reliable.
+   *   When this function returns true, the caller is sure that the glyph
+   *   names returned by @FT_Get_Glyph_Name are reliable.
    *
    * @input:
-   *    face ::
-   *      face handle
+   *   face ::
+   *     face handle
    *
    * @return:
-   *    Boolean.  True if glyph names are reliable.
+   *   Boolean.  True if glyph names are reliable.
    *
    */
   FT_EXPORT( FT_Int )
   FT_Has_PS_Glyph_Names( FT_Face  face );
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
-   *    FT_Get_PS_Font_Info
+   *   FT_Get_PS_Font_Info
    *
    * @description:
-   *    Retrieve the @PS_FontInfoRec structure corresponding to a given
-   *    PostScript font.
+   *   Retrieve the @PS_FontInfoRec structure corresponding to a given
+   *   PostScript font.
    *
    * @input:
-   *    face ::
-   *      PostScript face handle.
+   *   face ::
+   *     PostScript face handle.
    *
    * @output:
-   *    afont_info ::
-   *      Output font info structure pointer.
+   *   afont_info ::
+   *     A pointer to a @PS_FontInfoRec object.
    *
    * @return:
-   *    FreeType error code.  0~means success.
+   *   FreeType error code.  0~means success.
    *
    * @note:
-   *    String pointers within the @PS_FontInfoRec structure are owned by
-   *    the face and don't need to be freed by the caller.  Missing entries
-   *    in the font's FontInfo dictionary are represented by NULL pointers.
+   *   String pointers within the @PS_FontInfoRec structure are owned by the
+   *   face and don't need to be freed by the caller.  Missing entries in the
+   *   font's FontInfo dictionary are represented by `NULL` pointers.
    *
-   *    If the font's format is not PostScript-based, this function will
-   *    return the `FT_Err_Invalid_Argument' error code.
+   *   The following font formats support this feature: 'Type~1', 'Type~42',
+   *   'CFF', 'CID~Type~1'.  For other font formats this function returns the
+   *   `FT_Err_Invalid_Argument` error code.
+   *
+   * @example:
+   *   ```
+   *     PS_FontInfoRec  font_info;
+   *
+   *
+   *     error = FT_Get_PS_Font_Info( face, &font_info );
+   *     ...
+   *   ```
    *
    */
   FT_EXPORT( FT_Error )
@@ -514,32 +519,42 @@
                        PS_FontInfo  afont_info );
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
-   *    FT_Get_PS_Font_Private
+   *   FT_Get_PS_Font_Private
    *
    * @description:
-   *    Retrieve the @PS_PrivateRec structure corresponding to a given
-   *    PostScript font.
+   *   Retrieve the @PS_PrivateRec structure corresponding to a given
+   *   PostScript font.
    *
    * @input:
-   *    face ::
-   *      PostScript face handle.
+   *   face ::
+   *     PostScript face handle.
    *
    * @output:
-   *    afont_private ::
-   *      Output private dictionary structure pointer.
+   *   afont_private ::
+   *     A pointer to a @PS_PrivateRec object.
    *
    * @return:
-   *    FreeType error code.  0~means success.
+   *   FreeType error code.  0~means success.
    *
    * @note:
-   *    The string pointers within the @PS_PrivateRec structure are owned by
-   *    the face and don't need to be freed by the caller.
+   *   The string pointers within the @PS_PrivateRec structure are owned by
+   *   the face and don't need to be freed by the caller.
    *
-   *    If the font's format is not PostScript-based, this function returns
-   *    the `FT_Err_Invalid_Argument' error code.
+   *   Only the 'Type~1' font format supports this feature.  For other font
+   *   formats this function returns the `FT_Err_Invalid_Argument` error
+   *   code.
+   *
+   * @example:
+   *   ```
+   *     PS_PrivateRec  font_private;
+   *
+   *
+   *     error = FT_Get_PS_Font_Private( face, &font_private );
+   *     ...
+   *   ```
    *
    */
   FT_EXPORT( FT_Error )
@@ -553,8 +568,7 @@
    *   T1_EncodingType
    *
    * @description:
-   *   An enumeration describing the `Encoding' entry in a Type 1
-   *   dictionary.
+   *   An enumeration describing the 'Encoding' entry in a Type 1 dictionary.
    *
    * @values:
    *   T1_ENCODING_TYPE_NONE ::
@@ -583,8 +597,8 @@
    *   PS_Dict_Keys
    *
    * @description:
-   *   An enumeration used in calls to @FT_Get_PS_Font_Value to identify
-   *   the Type~1 dictionary entry to retrieve.
+   *   An enumeration used in calls to @FT_Get_PS_Font_Value to identify the
+   *   Type~1 dictionary entry to retrieve.
    *
    * @values:
    *   PS_DICT_FONT_TYPE ::
@@ -696,70 +710,70 @@
   } PS_Dict_Keys;
 
 
-  /************************************************************************
+  /**************************************************************************
    *
    * @function:
-   *    FT_Get_PS_Font_Value
+   *   FT_Get_PS_Font_Value
    *
    * @description:
-   *    Retrieve the value for the supplied key from a PostScript font.
+   *   Retrieve the value for the supplied key from a PostScript font.
    *
    * @input:
-   *    face ::
-   *      PostScript face handle.
+   *   face ::
+   *     PostScript face handle.
    *
-   *    key ::
-   *      An enumeration value representing the dictionary key to retrieve.
+   *   key ::
+   *     An enumeration value representing the dictionary key to retrieve.
    *
-   *    idx ::
-   *      For array values, this specifies the index to be returned.
+   *   idx ::
+   *     For array values, this specifies the index to be returned.
    *
-   *    value ::
-   *      A pointer to memory into which to write the value.
+   *   value ::
+   *     A pointer to memory into which to write the value.
    *
-   *    valen_len ::
-   *      The size, in bytes, of the memory supplied for the value.
+   *   valen_len ::
+   *     The size, in bytes, of the memory supplied for the value.
    *
    * @output:
-   *    value ::
-   *      The value matching the above key, if it exists.
+   *   value ::
+   *     The value matching the above key, if it exists.
    *
    * @return:
-   *    The amount of memory (in bytes) required to hold the requested
-   *    value (if it exists, -1 otherwise).
+   *   The amount of memory (in bytes) required to hold the requested value
+   *   (if it exists, -1 otherwise).
    *
    * @note:
-   *    The values returned are not pointers into the internal structures of
-   *    the face, but are `fresh' copies, so that the memory containing them
-   *    belongs to the calling application.  This also enforces the
-   *    `read-only' nature of these values, i.e., this function cannot be
-   *    used to manipulate the face.
+   *   The values returned are not pointers into the internal structures of
+   *   the face, but are 'fresh' copies, so that the memory containing them
+   *   belongs to the calling application.  This also enforces the
+   *   'read-only' nature of these values, i.e., this function cannot be
+   *   used to manipulate the face.
    *
-   *    `value' is a void pointer because the values returned can be of
-   *    various types.
+   *   `value` is a void pointer because the values returned can be of
+   *   various types.
    *
-   *    If either `value' is NULL or `value_len' is too small, just the
-   *    required memory size for the requested entry is returned.
+   *   If either `value` is `NULL` or `value_len` is too small, just the
+   *   required memory size for the requested entry is returned.
    *
-   *    The `idx' parameter is used, not only to retrieve elements of, for
-   *    example, the FontMatrix or FontBBox, but also to retrieve name keys
-   *    from the CharStrings dictionary, and the charstrings themselves.  It
-   *    is ignored for atomic values.
+   *   The `idx` parameter is used, not only to retrieve elements of, for
+   *   example, the FontMatrix or FontBBox, but also to retrieve name keys
+   *   from the CharStrings dictionary, and the charstrings themselves.  It
+   *   is ignored for atomic values.
    *
-   *    PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000.  To
-   *    get the value as in the font stream, you need to divide by
-   *    65536000.0 (to remove the FT_Fixed scale, and the x1000 scale).
+   *   `PS_DICT_BLUE_SCALE` returns a value that is scaled up by 1000.  To
+   *   get the value as in the font stream, you need to divide by 65536000.0
+   *   (to remove the FT_Fixed scale, and the x1000 scale).
    *
-   *    IMPORTANT: Only key/value pairs read by the FreeType interpreter can
-   *    be retrieved.  So, for example, PostScript procedures such as NP,
-   *    ND, and RD are not available.  Arbitrary keys are, obviously, not be
-   *    available either.
+   *   IMPORTANT: Only key/value pairs read by the FreeType interpreter can
+   *   be retrieved.  So, for example, PostScript procedures such as NP, ND,
+   *   and RD are not available.  Arbitrary keys are, obviously, not be
+   *   available either.
    *
-   *    If the font's format is not PostScript-based, this function returns
-   *    the `FT_Err_Invalid_Argument' error code.
+   *   If the font's format is not PostScript-based, this function returns
+   *   the `FT_Err_Invalid_Argument` error code.
    *
    * @since:
-   *    2.4.8
+   *   2.4.8
    *
    */
   FT_EXPORT( FT_Long )
diff --git a/include/freetype/ttnameid.h b/include/freetype/ttnameid.h
index f71516c..e31c68b 100644
--- a/include/freetype/ttnameid.h
+++ b/include/freetype/ttnameid.h
@@ -4,7 +4,7 @@
  *
  *   TrueType name ID definitions (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define TTNAMEID_H_
 
 
-#include <ft2build.h>
 
 
 FT_BEGIN_HEADER
@@ -35,44 +34,45 @@
 
   /**************************************************************************
    *
-   * Possible values for the `platform' identifier code in the name
-   * records of an SFNT `name' table.
+   * Possible values for the 'platform' identifier code in the name records
+   * of an SFNT 'name' table.
    *
    */
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_PLATFORM_XXX
    *
    * @description:
-   *   A list of valid values for the `platform_id' identifier code in
+   *   A list of valid values for the `platform_id` identifier code in
    *   @FT_CharMapRec and @FT_SfntName structures.
    *
    * @values:
    *   TT_PLATFORM_APPLE_UNICODE ::
    *     Used by Apple to indicate a Unicode character map and/or name entry.
-   *     See @TT_APPLE_ID_XXX for corresponding `encoding_id' values.  Note
+   *     See @TT_APPLE_ID_XXX for corresponding `encoding_id` values.  Note
    *     that name entries in this format are coded as big-endian UCS-2
    *     character codes _only_.
    *
    *   TT_PLATFORM_MACINTOSH ::
-   *     Used by Apple to indicate a MacOS-specific charmap and/or name entry.
-   *     See @TT_MAC_ID_XXX for corresponding `encoding_id' values.  Note that
-   *     most TrueType fonts contain an Apple roman charmap to be usable on
-   *     MacOS systems (even if they contain a Microsoft charmap as well).
+   *     Used by Apple to indicate a MacOS-specific charmap and/or name
+   *     entry.  See @TT_MAC_ID_XXX for corresponding `encoding_id` values.
+   *     Note that most TrueType fonts contain an Apple roman charmap to be
+   *     usable on MacOS systems (even if they contain a Microsoft charmap as
+   *     well).
    *
    *   TT_PLATFORM_ISO ::
-   *     This value was used to specify ISO/IEC 10646 charmaps.  It is however
-   *     now deprecated.  See @TT_ISO_ID_XXX for a list of corresponding
-   *     `encoding_id' values.
+   *     This value was used to specify ISO/IEC 10646 charmaps.  It is
+   *     however now deprecated.  See @TT_ISO_ID_XXX for a list of
+   *     corresponding `encoding_id` values.
    *
    *   TT_PLATFORM_MICROSOFT ::
    *     Used by Microsoft to indicate Windows-specific charmaps.  See
-   *     @TT_MS_ID_XXX for a list of corresponding `encoding_id' values.
+   *     @TT_MS_ID_XXX for a list of corresponding `encoding_id` values.
    *     Note that most fonts contain a Unicode charmap using
-   *     (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS).
+   *     (`TT_PLATFORM_MICROSOFT`, @TT_MS_ID_UNICODE_CS).
    *
    *   TT_PLATFORM_CUSTOM ::
    *     Used to indicate application-specific charmaps.
@@ -91,13 +91,13 @@
 #define TT_PLATFORM_ADOBE          7 /* artificial */
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_APPLE_ID_XXX
    *
    * @description:
-   *   A list of valid values for the `encoding_id' for
+   *   A list of valid values for the `encoding_id` for
    *   @TT_PLATFORM_APPLE_UNICODE charmaps and name entries.
    *
    * @values:
@@ -117,8 +117,8 @@
    *     Unicode 3.1 and beyond, using UTF-32.
    *
    *   TT_APPLE_ID_VARIANT_SELECTOR ::
-   *     From Adobe, not Apple.  Not a normal cmap.  Specifies variations
-   *     on a real cmap.
+   *     From Adobe, not Apple.  Not a normal cmap.  Specifies variations on
+   *     a real cmap.
    *
    *   TT_APPLE_ID_FULL_UNICODE ::
    *     Used for fallback fonts that provide complete Unicode coverage with
@@ -134,13 +134,13 @@
 #define TT_APPLE_ID_FULL_UNICODE      6 /* used with type 13 cmaps       */
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_MAC_ID_XXX
    *
    * @description:
-   *   A list of valid values for the `encoding_id' for
+   *   A list of valid values for the `encoding_id` for
    *   @TT_PLATFORM_MACINTOSH charmaps and name entries.
    */
 
@@ -180,14 +180,14 @@
 #define TT_MAC_ID_UNINTERP             32
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_ISO_ID_XXX
    *
    * @description:
-   *   A list of valid values for the `encoding_id' for
-   *   @TT_PLATFORM_ISO charmaps and name entries.
+   *   A list of valid values for the `encoding_id` for @TT_PLATFORM_ISO
+   *   charmaps and name entries.
    *
    *   Their use is now deprecated.
    *
@@ -205,13 +205,13 @@
 #define TT_ISO_ID_8859_1      2
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_MS_ID_XXX
    *
    * @description:
-   *   A list of valid values for the `encoding_id' for
+   *   A list of valid values for the `encoding_id` for
    *   @TT_PLATFORM_MICROSOFT charmaps and name entries.
    *
    * @values:
@@ -219,16 +219,15 @@
    *     Microsoft symbol encoding.  See @FT_ENCODING_MS_SYMBOL.
    *
    *   TT_MS_ID_UNICODE_CS ::
-   *     Microsoft WGL4 charmap, matching Unicode.  See
-   *     @FT_ENCODING_UNICODE.
+   *     Microsoft WGL4 charmap, matching Unicode.  See @FT_ENCODING_UNICODE.
    *
    *   TT_MS_ID_SJIS ::
    *     Shift JIS Japanese encoding.  See @FT_ENCODING_SJIS.
    *
    *   TT_MS_ID_PRC ::
    *     Chinese encodings as used in the People's Republic of China (PRC).
-   *     This means the encodings GB~2312 and its supersets GBK and
-   *     GB~18030.  See @FT_ENCODING_PRC.
+   *     This means the encodings GB~2312 and its supersets GBK and GB~18030.
+   *     See @FT_ENCODING_PRC.
    *
    *   TT_MS_ID_BIG_5 ::
    *     Traditional Chinese as used in Taiwan and Hong Kong.  See
@@ -258,14 +257,14 @@
 #define TT_MS_ID_GB2312  TT_MS_ID_PRC
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_ADOBE_ID_XXX
    *
    * @description:
-   *   A list of valid values for the `encoding_id' for
-   *   @TT_PLATFORM_ADOBE charmaps.  This is a FreeType-specific extension!
+   *   A list of valid values for the `encoding_id` for @TT_PLATFORM_ADOBE
+   *   charmaps.  This is a FreeType-specific extension!
    *
    * @values:
    *   TT_ADOBE_ID_STANDARD ::
@@ -284,14 +283,14 @@
 #define TT_ADOBE_ID_LATIN_1   3
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_MAC_LANGID_XXX
    *
    * @description:
    *   Possible values of the language identifier field in the name records
-   *   of the SFNT `name' table if the `platform' identifier code is
+   *   of the SFNT 'name' table if the 'platform' identifier code is
    *   @TT_PLATFORM_MACINTOSH.  These values are also used as return values
    *   for function @FT_Get_CMap_Language_ID.
    *
@@ -424,14 +423,14 @@
 #define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT    150
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_MS_LANGID_XXX
    *
    * @description:
    *   Possible values of the language identifier field in the name records
-   *   of the SFNT `name' table if the `platform' identifier code is
+   *   of the SFNT 'name' table if the 'platform' identifier code is
    *   @TT_PLATFORM_MICROSOFT.  These values are also used as return values
    *   for function @FT_Get_CMap_Language_ID.
    *
@@ -441,7 +440,7 @@
    *
    *   however, we only provide macros for language identifiers present in
    *   the OpenType specification: Microsoft has abandoned the concept of
-   *   LCIDs (language code identifiers), and format~1 of the `name' table
+   *   LCIDs (language code identifiers), and format~1 of the 'name' table
    *   provides a better mechanism for languages not covered here.
    *
    *   More legacy values not listed in the reference can be found in the
@@ -592,7 +591,7 @@
 #define TT_MS_LANGID_MALAY_MALAYSIA                    0x043E
 #define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083E
 #define TT_MS_LANGID_KAZAKH_KAZAKHSTAN                 0x043F
-#define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic*/   0x0440
+#define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic */  0x0440
 #define TT_MS_LANGID_KISWAHILI_KENYA                   0x0441
 #define TT_MS_LANGID_TURKMEN_TURKMENISTAN              0x0442
 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN            0x0443
@@ -780,14 +779,14 @@
           TT_MS_LANGID_UIGHUR_PRC
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_NAME_ID_XXX
    *
    * @description:
-   *   Possible values of the `name' identifier field in the name records of
-   *   an SFNT `name' table.  These values are platform independent.
+   *   Possible values of the 'name' identifier field in the name records of
+   *   an SFNT 'name' table.  These values are platform independent.
    */
 
 #define TT_NAME_ID_COPYRIGHT              0
@@ -834,14 +833,14 @@
 #define TT_NAME_ID_PREFERRED_SUBFAMILY  TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY
 
 
-  /***********************************************************************
+  /**************************************************************************
    *
    * @enum:
    *   TT_UCR_XXX
    *
    * @description:
-   *   Possible bit mask values for the `ulUnicodeRangeX' fields in an SFNT
-   *   `OS/2' table.
+   *   Possible bit mask values for the `ulUnicodeRangeX` fields in an SFNT
+   *   'OS/2' table.
    */
 
   /* ulUnicodeRange1 */
diff --git a/include/freetype/tttables.h b/include/freetype/tttables.h
index 8ecc8e2..a9f60e7 100644
--- a/include/freetype/tttables.h
+++ b/include/freetype/tttables.h
@@ -5,7 +5,7 @@
  *   Basic SFNT/TrueType tables definitions and interface
  *   (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,8 +21,7 @@
 #define TTTABLES_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -77,8 +76,10 @@
    *   TT_Header
    *
    * @description:
-   *   A structure to model a TrueType font header table.  All fields
-   *   follow the OpenType specification.
+   *   A structure to model a TrueType font header table.  All fields follow
+   *   the OpenType specification.  The 64-bit timestamps are stored in
+   *   two-element arrays `Created` and `Modified`, first the upper then
+   *   the lower 32~bits.
    */
   typedef struct  TT_Header_
   {
@@ -91,8 +92,8 @@
     FT_UShort  Flags;
     FT_UShort  Units_Per_EM;
 
-    FT_Long    Created [2];
-    FT_Long    Modified[2];
+    FT_ULong   Created [2];
+    FT_ULong   Modified[2];
 
     FT_Short   xMin;
     FT_Short   yMin;
@@ -115,76 +116,61 @@
    *   TT_HoriHeader
    *
    * @description:
-   *   A structure to model a TrueType horizontal header, the `hhea'
-   *   table, as well as the corresponding horizontal metrics table,
-   *   `hmtx'.
+   *   A structure to model a TrueType horizontal header, the 'hhea' table,
+   *   as well as the corresponding horizontal metrics table, 'hmtx'.
    *
    * @fields:
    *   Version ::
    *     The table version.
    *
    *   Ascender ::
-   *     The font's ascender, i.e., the distance
-   *     from the baseline to the top-most of all
-   *     glyph points found in the font.
+   *     The font's ascender, i.e., the distance from the baseline to the
+   *     top-most of all glyph points found in the font.
    *
-   *     This value is invalid in many fonts, as
-   *     it is usually set by the font designer,
-   *     and often reflects only a portion of the
-   *     glyphs found in the font (maybe ASCII).
+   *     This value is invalid in many fonts, as it is usually set by the
+   *     font designer, and often reflects only a portion of the glyphs found
+   *     in the font (maybe ASCII).
    *
-   *     You should use the `sTypoAscender' field
-   *     of the `OS/2' table instead if you want
-   *     the correct one.
+   *     You should use the `sTypoAscender` field of the 'OS/2' table instead
+   *     if you want the correct one.
    *
    *   Descender ::
-   *     The font's descender, i.e., the distance
-   *     from the baseline to the bottom-most of
-   *     all glyph points found in the font.  It
-   *     is negative.
+   *     The font's descender, i.e., the distance from the baseline to the
+   *     bottom-most of all glyph points found in the font.  It is negative.
    *
-   *     This value is invalid in many fonts, as
-   *     it is usually set by the font designer,
-   *     and often reflects only a portion of the
-   *     glyphs found in the font (maybe ASCII).
+   *     This value is invalid in many fonts, as it is usually set by the
+   *     font designer, and often reflects only a portion of the glyphs found
+   *     in the font (maybe ASCII).
    *
-   *     You should use the `sTypoDescender'
-   *     field of the `OS/2' table instead if you
-   *     want the correct one.
+   *     You should use the `sTypoDescender` field of the 'OS/2' table
+   *     instead if you want the correct one.
    *
    *   Line_Gap ::
-   *     The font's line gap, i.e., the distance
-   *     to add to the ascender and descender to
-   *     get the BTB, i.e., the
-   *     baseline-to-baseline distance for the
-   *     font.
+   *     The font's line gap, i.e., the distance to add to the ascender and
+   *     descender to get the BTB, i.e., the baseline-to-baseline distance
+   *     for the font.
    *
    *   advance_Width_Max ::
-   *     This field is the maximum of all advance
-   *     widths found in the font.  It can be
-   *     used to compute the maximum width of an
-   *     arbitrary string of text.
+   *     This field is the maximum of all advance widths found in the font.
+   *     It can be used to compute the maximum width of an arbitrary string
+   *     of text.
    *
    *   min_Left_Side_Bearing ::
-   *     The minimum left side bearing of all
-   *     glyphs within the font.
+   *     The minimum left side bearing of all glyphs within the font.
    *
    *   min_Right_Side_Bearing ::
-   *     The minimum right side bearing of all
-   *     glyphs within the font.
+   *     The minimum right side bearing of all glyphs within the font.
    *
    *   xMax_Extent ::
-   *     The maximum horizontal extent (i.e., the
-   *     `width' of a glyph's bounding box) for
-   *     all glyphs in the font.
+   *     The maximum horizontal extent (i.e., the 'width' of a glyph's
+   *     bounding box) for all glyphs in the font.
    *
    *   caret_Slope_Rise ::
-   *     The rise coefficient of the cursor's
-   *     slope of the cursor (slope=rise/run).
+   *     The rise coefficient of the cursor's slope of the cursor
+   *     (slope=rise/run).
    *
    *   caret_Slope_Run ::
-   *     The run coefficient of the cursor's
-   *     slope.
+   *     The run coefficient of the cursor's slope.
    *
    *   caret_Offset ::
    *     The cursor's offset for slanted fonts.
@@ -196,21 +182,20 @@
    *     Always~0.
    *
    *   number_Of_HMetrics ::
-   *     Number of HMetrics entries in the `hmtx'
-   *     table -- this value can be smaller than
-   *     the total number of glyphs in the font.
+   *     Number of HMetrics entries in the 'hmtx' table -- this value can be
+   *     smaller than the total number of glyphs in the font.
    *
    *   long_metrics ::
-   *     A pointer into the `hmtx' table.
+   *     A pointer into the 'hmtx' table.
    *
    *   short_metrics ::
-   *     A pointer into the `hmtx' table.
+   *     A pointer into the 'hmtx' table.
    *
    * @note:
-   *   For an OpenType variation font, the values of the following fields
-   *   can change after a call to @FT_Set_Var_Design_Coordinates (and
-   *   friends) if the font contains an `MVAR' table: `caret_Slope_Rise',
-   *   `caret_Slope_Run', and `caret_Offset'.
+   *   For an OpenType variation font, the values of the following fields can
+   *   change after a call to @FT_Set_Var_Design_Coordinates (and friends) if
+   *   the font contains an 'MVAR' table: `caret_Slope_Rise`,
+   *   `caret_Slope_Run`, and `caret_Offset`.
    */
   typedef struct  TT_HoriHeader_
   {
@@ -235,7 +220,7 @@
 
     /* The following fields are not defined by the OpenType specification */
     /* but they are used to connect the metrics header to the relevant    */
-    /* `hmtx' table.                                                      */
+    /* 'hmtx' table.                                                      */
 
     void*      long_metrics;
     void*      short_metrics;
@@ -249,78 +234,61 @@
    *   TT_VertHeader
    *
    * @description:
-   *   A structure used to model a TrueType vertical header, the `vhea'
-   *   table, as well as the corresponding vertical metrics table,
-   *   `vmtx'.
+   *   A structure used to model a TrueType vertical header, the 'vhea'
+   *   table, as well as the corresponding vertical metrics table, 'vmtx'.
    *
    * @fields:
    *   Version ::
    *     The table version.
    *
    *   Ascender ::
-   *     The font's ascender, i.e., the distance
-   *     from the baseline to the top-most of
-   *     all glyph points found in the font.
+   *     The font's ascender, i.e., the distance from the baseline to the
+   *     top-most of all glyph points found in the font.
    *
-   *     This value is invalid in many fonts, as
-   *     it is usually set by the font designer,
-   *     and often reflects only a portion of
-   *     the glyphs found in the font (maybe
-   *     ASCII).
+   *     This value is invalid in many fonts, as it is usually set by the
+   *     font designer, and often reflects only a portion of the glyphs found
+   *     in the font (maybe ASCII).
    *
-   *     You should use the `sTypoAscender'
-   *     field of the `OS/2' table instead if
-   *     you want the correct one.
+   *     You should use the `sTypoAscender` field of the 'OS/2' table instead
+   *     if you want the correct one.
    *
    *   Descender ::
-   *     The font's descender, i.e., the
-   *     distance from the baseline to the
-   *     bottom-most of all glyph points found
-   *     in the font.  It is negative.
+   *     The font's descender, i.e., the distance from the baseline to the
+   *     bottom-most of all glyph points found in the font.  It is negative.
    *
-   *     This value is invalid in many fonts, as
-   *     it is usually set by the font designer,
-   *     and often reflects only a portion of
-   *     the glyphs found in the font (maybe
-   *     ASCII).
+   *     This value is invalid in many fonts, as it is usually set by the
+   *     font designer, and often reflects only a portion of the glyphs found
+   *     in the font (maybe ASCII).
    *
-   *     You should use the `sTypoDescender'
-   *     field of the `OS/2' table instead if
-   *     you want the correct one.
+   *     You should use the `sTypoDescender` field of the 'OS/2' table
+   *     instead if you want the correct one.
    *
    *   Line_Gap ::
-   *     The font's line gap, i.e., the distance
-   *     to add to the ascender and descender to
-   *     get the BTB, i.e., the
-   *     baseline-to-baseline distance for the
-   *     font.
+   *     The font's line gap, i.e., the distance to add to the ascender and
+   *     descender to get the BTB, i.e., the baseline-to-baseline distance
+   *     for the font.
    *
    *   advance_Height_Max ::
-   *     This field is the maximum of all
-   *     advance heights found in the font.  It
-   *     can be used to compute the maximum
-   *     height of an arbitrary string of text.
+   *     This field is the maximum of all advance heights found in the font.
+   *     It can be used to compute the maximum height of an arbitrary string
+   *     of text.
    *
    *   min_Top_Side_Bearing ::
-   *     The minimum top side bearing of all
-   *     glyphs within the font.
+   *     The minimum top side bearing of all glyphs within the font.
    *
    *   min_Bottom_Side_Bearing ::
-   *     The minimum bottom side bearing of all
-   *     glyphs within the font.
+   *     The minimum bottom side bearing of all glyphs within the font.
    *
    *   yMax_Extent ::
-   *     The maximum vertical extent (i.e., the
-   *     `height' of a glyph's bounding box) for
-   *     all glyphs in the font.
+   *     The maximum vertical extent (i.e., the 'height' of a glyph's
+   *     bounding box) for all glyphs in the font.
    *
    *   caret_Slope_Rise ::
-   *     The rise coefficient of the cursor's
-   *     slope of the cursor (slope=rise/run).
+   *     The rise coefficient of the cursor's slope of the cursor
+   *     (slope=rise/run).
    *
    *   caret_Slope_Run ::
-   *     The run coefficient of the cursor's
-   *     slope.
+   *     The run coefficient of the cursor's slope.
    *
    *   caret_Offset ::
    *     The cursor's offset for slanted fonts.
@@ -332,23 +300,20 @@
    *     Always~0.
    *
    *   number_Of_VMetrics ::
-   *     Number of VMetrics entries in the
-   *     `vmtx' table -- this value can be
-   *     smaller than the total number of glyphs
-   *     in the font.
+   *     Number of VMetrics entries in the 'vmtx' table -- this value can be
+   *     smaller than the total number of glyphs in the font.
    *
    *   long_metrics ::
-   *     A pointer into the `vmtx' table.
+   *     A pointer into the 'vmtx' table.
    *
    *   short_metrics ::
-   *     A pointer into the `vmtx' table.
+   *     A pointer into the 'vmtx' table.
    *
    * @note:
-   *   For an OpenType variation font, the values of the following fields
-   *   can change after a call to @FT_Set_Var_Design_Coordinates (and
-   *   friends) if the font contains an `MVAR' table: `Ascender',
-   *   `Descender', `Line_Gap', `caret_Slope_Rise', `caret_Slope_Run',
-   *   and `caret_Offset'.
+   *   For an OpenType variation font, the values of the following fields can
+   *   change after a call to @FT_Set_Var_Design_Coordinates (and friends) if
+   *   the font contains an 'MVAR' table: `Ascender`, `Descender`,
+   *   `Line_Gap`, `caret_Slope_Rise`, `caret_Slope_Run`, and `caret_Offset`.
    */
   typedef struct  TT_VertHeader_
   {
@@ -373,7 +338,7 @@
 
     /* The following fields are not defined by the OpenType specification */
     /* but they are used to connect the metrics header to the relevant    */
-    /* `vmtx' table.                                                      */
+    /* 'vmtx' table.                                                      */
 
     void*      long_metrics;
     void*      short_metrics;
@@ -387,26 +352,24 @@
    *   TT_OS2
    *
    * @description:
-   *   A structure to model a TrueType `OS/2' table.  All fields comply
-   *   to the OpenType specification.
+   *   A structure to model a TrueType 'OS/2' table.  All fields comply to
+   *   the OpenType specification.
    *
-   *   Note that we now support old Mac fonts that do not include an
-   *   `OS/2' table.  In this case, the `version' field is always set to
-   *   0xFFFF.
+   *   Note that we now support old Mac fonts that do not include an 'OS/2'
+   *   table.  In this case, the `version` field is always set to 0xFFFF.
    *
    * @note:
-   *   For an OpenType variation font, the values of the following fields
-   *   can change after a call to @FT_Set_Var_Design_Coordinates (and
-   *   friends) if the font contains an `MVAR' table: `sCapHeight',
-   *   `sTypoAscender', `sTypoDescender', `sTypoLineGap', `sxHeight',
-   *   `usWinAscent', `usWinDescent', `yStrikeoutPosition',
-   *   `yStrikeoutSize', `ySubscriptXOffset', `ySubScriptXSize',
-   *   `ySubscriptYOffset', `ySubscriptYSize', `ySuperscriptXOffset',
-   *   `ySuperscriptXSize', `ySuperscriptYOffset', and
-   *   `ySuperscriptYSize'.
+   *   For an OpenType variation font, the values of the following fields can
+   *   change after a call to @FT_Set_Var_Design_Coordinates (and friends) if
+   *   the font contains an 'MVAR' table: `sCapHeight`, `sTypoAscender`,
+   *   `sTypoDescender`, `sTypoLineGap`, `sxHeight`, `usWinAscent`,
+   *   `usWinDescent`, `yStrikeoutPosition`, `yStrikeoutSize`,
+   *   `ySubscriptXOffset`, `ySubScriptXSize`, `ySubscriptYOffset`,
+   *   `ySubscriptYSize`, `ySuperscriptXOffset`, `ySuperscriptXSize`,
+   *   `ySuperscriptYOffset`, and `ySuperscriptYSize`.
    *
-   *   Possible values for bits in the `ulUnicodeRangeX' fields are given
-   *   by the @TT_UCR_XXX macros.
+   *   Possible values for bits in the `ulUnicodeRangeX` fields are given by
+   *   the @TT_UCR_XXX macros.
    */
 
   typedef struct  TT_OS2_
@@ -461,8 +424,8 @@
 
     /* only version 5 and higher: */
 
-    FT_UShort  usLowerOpticalPointSize;       /* in twips (1/20th points) */
-    FT_UShort  usUpperOpticalPointSize;       /* in twips (1/20th points) */
+    FT_UShort  usLowerOpticalPointSize;       /* in twips (1/20 points) */
+    FT_UShort  usUpperOpticalPointSize;       /* in twips (1/20 points) */
 
   } TT_OS2;
 
@@ -473,16 +436,16 @@
    *   TT_Postscript
    *
    * @description:
-   *   A structure to model a TrueType `post' table.  All fields comply
-   *   to the OpenType specification.  This structure does not reference
-   *   a font's PostScript glyph names; use @FT_Get_Glyph_Name to
-   *   retrieve them.
+   *   A structure to model a TrueType 'post' table.  All fields comply to
+   *   the OpenType specification.  This structure does not reference a
+   *   font's PostScript glyph names; use @FT_Get_Glyph_Name to retrieve
+   *   them.
    *
    * @note:
-   *   For an OpenType variation font, the values of the following fields
-   *   can change after a call to @FT_Set_Var_Design_Coordinates (and
-   *   friends) if the font contains an `MVAR' table: `underlinePosition'
-   *   and `underlineThickness'.
+   *   For an OpenType variation font, the values of the following fields can
+   *   change after a call to @FT_Set_Var_Design_Coordinates (and friends) if
+   *   the font contains an 'MVAR' table: `underlinePosition` and
+   *   `underlineThickness`.
    */
   typedef struct  TT_Postscript_
   {
@@ -496,7 +459,7 @@
     FT_ULong  minMemType1;
     FT_ULong  maxMemType1;
 
-    /* Glyph names follow in the `post' table, but we don't */
+    /* Glyph names follow in the 'post' table, but we don't */
     /* load them by default.                                */
 
   } TT_Postscript;
@@ -508,8 +471,8 @@
    *   TT_PCLT
    *
    * @description:
-   *   A structure to model a TrueType `PCLT' table.  All fields comply
-   *   to the OpenType specification.
+   *   A structure to model a TrueType 'PCLT' table.  All fields comply to
+   *   the OpenType specification.
    */
   typedef struct  TT_PCLT_
   {
@@ -538,75 +501,65 @@
    *   TT_MaxProfile
    *
    * @description:
-   *   The maximum profile (`maxp') table contains many max values, which
-   *   can be used to pre-allocate arrays for speeding up glyph loading
-   *   and hinting.
+   *   The maximum profile ('maxp') table contains many max values, which can
+   *   be used to pre-allocate arrays for speeding up glyph loading and
+   *   hinting.
    *
    * @fields:
    *   version ::
    *     The version number.
    *
    *   numGlyphs ::
-   *     The number of glyphs in this TrueType
-   *     font.
+   *     The number of glyphs in this TrueType font.
    *
    *   maxPoints ::
-   *     The maximum number of points in a
-   *     non-composite TrueType glyph.  See also
-   *     `maxCompositePoints'.
+   *     The maximum number of points in a non-composite TrueType glyph.  See
+   *     also `maxCompositePoints`.
    *
    *   maxContours ::
-   *     The maximum number of contours in a
-   *     non-composite TrueType glyph.  See also
-   *     `maxCompositeContours'.
+   *     The maximum number of contours in a non-composite TrueType glyph.
+   *     See also `maxCompositeContours`.
    *
    *   maxCompositePoints ::
-   *     The maximum number of points in a
-   *     composite TrueType glyph.  See also
-   *     `maxPoints'.
+   *     The maximum number of points in a composite TrueType glyph.  See
+   *     also `maxPoints`.
    *
    *   maxCompositeContours ::
-   *     The maximum number of contours in a
-   *     composite TrueType glyph.  See also
-   *     `maxContours'.
+   *     The maximum number of contours in a composite TrueType glyph.  See
+   *     also `maxContours`.
    *
    *   maxZones ::
-   *     The maximum number of zones used for
-   *     glyph hinting.
+   *     The maximum number of zones used for glyph hinting.
    *
    *   maxTwilightPoints ::
-   *     The maximum number of points in the
-   *     twilight zone used for glyph hinting.
+   *     The maximum number of points in the twilight zone used for glyph
+   *     hinting.
    *
    *   maxStorage ::
-   *     The maximum number of elements in the
-   *     storage area used for glyph hinting.
+   *     The maximum number of elements in the storage area used for glyph
+   *     hinting.
    *
    *   maxFunctionDefs ::
-   *     The maximum number of function
-   *     definitions in the TrueType bytecode for
-   *     this font.
+   *     The maximum number of function definitions in the TrueType bytecode
+   *     for this font.
    *
    *   maxInstructionDefs ::
-   *     The maximum number of instruction
-   *     definitions in the TrueType bytecode for
-   *     this font.
+   *     The maximum number of instruction definitions in the TrueType
+   *     bytecode for this font.
    *
    *   maxStackElements ::
-   *     The maximum number of stack elements used
-   *     during bytecode interpretation.
+   *     The maximum number of stack elements used during bytecode
+   *     interpretation.
    *
    *   maxSizeOfInstructions ::
-   *     The maximum number of TrueType opcodes
-   *     used for glyph hinting.
+   *     The maximum number of TrueType opcodes used for glyph hinting.
    *
    *   maxComponentElements ::
-   *     The maximum number of simple (i.e.,
-   *     non-composite) glyphs in a composite glyph.
+   *     The maximum number of simple (i.e., non-composite) glyphs in a
+   *     composite glyph.
    *
    *   maxComponentDepth ::
-   *     The maximum nesting depth of composite
-   *     glyphs.
+   *     The maximum nesting depth of composite glyphs.
    *
    * @note:
    *   This structure is only used during font loading.
@@ -638,8 +591,8 @@
    *   FT_Sfnt_Tag
    *
    * @description:
-   *   An enumeration to specify indices of SFNT tables loaded and parsed
-   *   by FreeType during initialization of an SFNT font.  Used in the
+   *   An enumeration to specify indices of SFNT tables loaded and parsed by
+   *   FreeType during initialization of an SFNT font.  Used in the
    *   @FT_Get_Sfnt_Table API function.
    *
    * @values:
@@ -678,7 +631,7 @@
 
   } FT_Sfnt_Tag;
 
-  /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */
+  /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag` */
   /* values instead                                                      */
 #define ft_sfnt_head  FT_SFNT_HEAD
 #define ft_sfnt_maxp  FT_SFNT_MAXP
@@ -705,30 +658,29 @@
    *     The index of the SFNT table.
    *
    * @return:
-   *   A type-less pointer to the table.  This will be NULL in case of
-   *   error, or if the corresponding table was not found *OR* loaded
-   *   from the file.
+   *   A type-less pointer to the table.  This will be `NULL` in case of
+   *   error, or if the corresponding table was not found **OR** loaded from
+   *   the file.
    *
-   *   Use a typecast according to `tag' to access the structure
-   *   elements.
+   *   Use a typecast according to `tag` to access the structure elements.
    *
    * @note:
    *   The table is owned by the face object and disappears with it.
    *
-   *   This function is only useful to access SFNT tables that are loaded
-   *   by the sfnt, truetype, and opentype drivers.  See @FT_Sfnt_Tag for
-   *   a list.
+   *   This function is only useful to access SFNT tables that are loaded by
+   *   the sfnt, truetype, and opentype drivers.  See @FT_Sfnt_Tag for a
+   *   list.
    *
    * @example:
-   *   Here an example how to access the `vhea' table.
+   *   Here is an example demonstrating access to the 'vhea' table.
    *
-   *   {
+   *   ```
    *     TT_VertHeader*  vert_header;
    *
    *
    *     vert_header =
    *       (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA );
-   *   }
+   *   ```
    */
   FT_EXPORT( void* )
   FT_Get_Sfnt_Table( FT_Face      face,
@@ -748,8 +700,8 @@
    *     A handle to the source face.
    *
    *   tag ::
-   *     The four-byte tag of the table to load.  Use value~0 if you want
-   *     to access the whole font file.  Otherwise, you can use one of the
+   *     The four-byte tag of the table to load.  Use value~0 if you want to
+   *     access the whole font file.  Otherwise, you can use one of the
    *     definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new
    *     one with @FT_MAKE_TAG.
    *
@@ -763,10 +715,10 @@
    *
    * @inout:
    *   length ::
-   *     If the `length' parameter is NULL, try to load the whole table.
+   *     If the `length` parameter is `NULL`, try to load the whole table.
    *     Return an error code if it fails.
    *
-   *     Else, if `*length' is~0, exit immediately while returning the
+   *     Else, if `*length` is~0, exit immediately while returning the
    *     table's (or file) full size in it.
    *
    *     Else the number of bytes to read from the table or file, from the
@@ -777,9 +729,9 @@
    *
    * @note:
    *   If you need to determine the table's length you should first call this
-   *   function with `*length' set to~0, as in the following example:
+   *   function with `*length` set to~0, as in the following example:
    *
-   *   {
+   *   ```
    *     FT_ULong  length = 0;
    *
    *
@@ -791,7 +743,7 @@
    *
    *     error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
    *     if ( error ) { ... could not load table ... }
-   *   }
+   *   ```
    *
    *   Note that structures like @TT_Header or @TT_OS2 can't be used with
    *   this function; they are limited to @FT_Get_Sfnt_Table.  Reason is that
@@ -825,14 +777,14 @@
    *
    * @inout:
    *   tag ::
-   *     The name tag of the SFNT table.  If the value is NULL, `table_index'
-   *     is ignored, and `length' returns the number of SFNT tables in the
-   *     font.
+   *     The name tag of the SFNT table.  If the value is `NULL`,
+   *     `table_index` is ignored, and `length` returns the number of SFNT
+   *     tables in the font.
    *
    * @output:
    *   length ::
-   *     The length of the SFNT table (or the number of SFNT tables, depending
-   *     on `tag').
+   *     The length of the SFNT table (or the number of SFNT tables,
+   *     depending on `tag`).
    *
    * @return:
    *   FreeType error code.  0~means success.
@@ -863,8 +815,8 @@
    *     The target charmap.
    *
    * @return:
-   *   The language ID of `charmap'.  If `charmap' doesn't belong to an
-   *   SFNT face, just return~0 as the default value.
+   *   The language ID of `charmap`.  If `charmap` doesn't belong to an SFNT
+   *   face, just return~0 as the default value.
    *
    *   For a format~14 cmap (to access Unicode IVS), the return value is
    *   0xFFFFFFFF.
@@ -879,15 +831,15 @@
    *   FT_Get_CMap_Format
    *
    * @description:
-   *   Return the format of an SFNT `cmap' table.
+   *   Return the format of an SFNT 'cmap' table.
    *
    * @input:
    *   charmap ::
    *     The target charmap.
    *
    * @return:
-   *   The format of `charmap'.  If `charmap' doesn't belong to an SFNT
-   *   face, return -1.
+   *   The format of `charmap`.  If `charmap` doesn't belong to an SFNT face,
+   *   return -1.
    */
   FT_EXPORT( FT_Long )
   FT_Get_CMap_Format( FT_CharMap  charmap );
diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h
index 5e5d783..9bf4fca 100644
--- a/include/freetype/tttags.h
+++ b/include/freetype/tttags.h
@@ -4,7 +4,7 @@
  *
  *   Tags for TrueType and OpenType tables (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define TTAGS_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
@@ -96,6 +95,7 @@
 #define TTAG_sbix  FT_MAKE_TAG( 's', 'b', 'i', 'x' )
 #define TTAG_sfnt  FT_MAKE_TAG( 's', 'f', 'n', 't' )
 #define TTAG_SING  FT_MAKE_TAG( 'S', 'I', 'N', 'G' )
+#define TTAG_SVG   FT_MAKE_TAG( 'S', 'V', 'G', ' ' )
 #define TTAG_trak  FT_MAKE_TAG( 't', 'r', 'a', 'k' )
 #define TTAG_true  FT_MAKE_TAG( 't', 'r', 'u', 'e' )
 #define TTAG_ttc   FT_MAKE_TAG( 't', 't', 'c', ' ' )
@@ -107,6 +107,7 @@
 #define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )
 #define TTAG_VVAR  FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
 #define TTAG_wOFF  FT_MAKE_TAG( 'w', 'O', 'F', 'F' )
+#define TTAG_wOF2  FT_MAKE_TAG( 'w', 'O', 'F', '2' )
 
 /* used by "Keyboard.dfont" on legacy Mac OS X */
 #define TTAG_0xA5kbd  FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' )
diff --git a/include/ft2build.h b/include/ft2build.h
index 97dbd3c..58491ce 100644
--- a/include/ft2build.h
+++ b/include/ft2build.h
@@ -4,7 +4,7 @@
  *
  *   FreeType 2 build and setup macros.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,17 +18,15 @@
 
   /**************************************************************************
    *
-   * This is the `entry point' for FreeType header file inclusions.  It is
-   * the only header file which should be included directly; all other
-   * FreeType header files should be accessed with macro names (after
-   * including `ft2build.h').
+   * This is the 'entry point' for FreeType header file inclusions, to be
+   * loaded before all other header files.
    *
    * A typical example is
    *
-   * {
+   * ```
    *   #include <ft2build.h>
-   *   #include FT_FREETYPE_H
-   * }
+   *   #include <freetype/freetype.h>
+   * ```
    *
    */
 
diff --git a/libft2.map.txt b/libft2.map.txt
index 4671ad6..14c37fe 100644
--- a/libft2.map.txt
+++ b/libft2.map.txt
@@ -1,13 +1,13 @@
 LIBFT2 {
   global:
-    FT_Done_Face; # vndk
-    FT_Done_FreeType; # vndk
-    FT_Get_Char_Index; # vndk
-    FT_Init_FreeType; # vndk
-    FT_Load_Glyph; # vndk
-    FT_New_Face; # vndk
-    FT_New_Memory_Face; # vndk
-    FT_Set_Char_Size; # vndk
+    FT_Done_Face; # llndk
+    FT_Done_FreeType; # llndk
+    FT_Get_Char_Index; # llndk
+    FT_Init_FreeType; # llndk
+    FT_Load_Glyph; # llndk
+    FT_New_Face; # llndk
+    FT_New_Memory_Face; # llndk
+    FT_Set_Char_Size; # llndk
   local:
     *;
 };
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..f81de3e
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,470 @@
+#
+# Meson project file for FreeType 2
+#
+
+# Copyright (C) 2020-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.
+
+#
+# Say
+#
+#   meson configure
+#
+# to see all configuration options and their default values.  For example,
+# to build only a shared version of FreeType, override the default value
+# with
+#
+#   meson setup -Ddefault_library=shared
+#
+
+project('freetype2', 'c',
+  meson_version: '>= 0.55.0',
+  version: run_command('builds/meson/extract_freetype_version.py',
+                       'include/freetype/freetype.h',
+                       check: true).stdout().strip(),
+)
+
+
+# Only meson >= 0.57 can read a file and assign its contents to a
+# variable; we thus use an external command to have this functionality
+# with older versions, too.
+
+python_exe = find_program('python3')
+
+ft2_so_version = run_command(python_exe,
+  files('builds/meson/extract_libtool_version.py'),
+  '--soversion',
+  files('builds/unix/configure.raw'),
+  check: true).stdout().strip()
+
+ft2_pkgconfig_version = run_command(python_exe,
+  files('builds/meson/extract_libtool_version.py'),
+  files('builds/unix/configure.raw'),
+  check: true).stdout().strip()
+
+ft2_includes = include_directories('include')
+
+freetype_includedir = join_paths(get_option('includedir'), 'freetype2')
+
+ft2_defines = []
+
+# Generate a custom `ftmodule.h` version based on the content of
+# `modules.cfg`.
+
+ftmodule_h = custom_target('ftmodule.h',
+  output: 'ftmodule.h',
+  input: 'modules.cfg',
+  command: [python_exe, files('builds/meson/parse_modules_cfg.py'),
+            '--format=ftmodule.h', '@INPUT@', '--output', '@OUTPUT@'],
+  install: true,
+  install_dir: join_paths(freetype_includedir, 'freetype/config'),
+)
+ft2_sources = [ftmodule_h]
+ft2_defines += ['-DFT_CONFIG_MODULES_H=<ftmodule.h>']
+
+
+# FreeType 2 modules.
+
+ft_main_modules = run_command(python_exe,
+  files('builds/meson/parse_modules_cfg.py'),
+  '--format=main-modules',
+  files('modules.cfg'),
+  check: true).stdout().strip().split()
+
+ft2_sources += files([
+  'src/base/ftbase.c',
+  'src/base/ftinit.c',
+])
+
+foreach mod: ft_main_modules
+  source = mod
+  if mod == 'winfonts'
+    source = 'winfnt'
+  elif mod == 'cid'
+    source = 'type1cid'
+  endif
+  ft2_sources += 'src/@0@/@1@.c'.format(mod, source)
+endforeach
+
+# NOTE: The `bzip2` aux module is handled through options.
+ft_aux_modules = run_command(python_exe,
+  files('builds/meson/parse_modules_cfg.py'),
+  '--format=aux-modules',
+  files('modules.cfg'),
+  check: true).stdout().strip().split()
+
+foreach auxmod: ft_aux_modules
+  source = auxmod
+  # Most sources are named `src/<module>/<module>.c`, but there are a few
+  # exceptions handled here.
+  if auxmod == 'cache'
+    source = 'ftcache'
+  elif auxmod == 'lzw'
+    source = 'ftlzw'
+  elif auxmod == 'gzip'
+    source = 'ftgzip'
+  elif auxmod == 'bzip2'
+    # Handled through options instead, see below.
+    continue
+  endif
+  ft2_sources += 'src/@0@/@1@.c'.format(auxmod, source)
+endforeach
+
+
+# FreeType 2 base extensions.
+# To be configured in `modules.cfg`.
+
+base_extensions = run_command(python_exe,
+  files('builds/meson/parse_modules_cfg.py'),
+  '--format=base-extensions-list',
+  files('modules.cfg'),
+  check: true).stdout().split()
+
+foreach ext: base_extensions
+  ft2_sources += files('src/base/' + ext)
+endforeach
+
+
+# Header files.
+
+ft2_public_headers = files([
+  'include/freetype/freetype.h',
+  'include/freetype/ftadvanc.h',
+  'include/freetype/ftbbox.h',
+  'include/freetype/ftbdf.h',
+  'include/freetype/ftbitmap.h',
+  'include/freetype/ftbzip2.h',
+  'include/freetype/ftcache.h',
+  'include/freetype/ftchapters.h',
+  'include/freetype/ftcid.h',
+  'include/freetype/ftcolor.h',
+  'include/freetype/ftdriver.h',
+  'include/freetype/fterrdef.h',
+  'include/freetype/fterrors.h',
+  'include/freetype/ftfntfmt.h',
+  'include/freetype/ftgasp.h',
+  'include/freetype/ftglyph.h',
+  'include/freetype/ftgxval.h',
+  'include/freetype/ftgzip.h',
+  'include/freetype/ftimage.h',
+  'include/freetype/ftincrem.h',
+  'include/freetype/ftlcdfil.h',
+  'include/freetype/ftlist.h',
+  'include/freetype/ftlzw.h',
+  'include/freetype/ftmac.h',
+  'include/freetype/ftmm.h',
+  'include/freetype/ftmodapi.h',
+  'include/freetype/ftmoderr.h',
+  'include/freetype/ftotval.h',
+  'include/freetype/ftoutln.h',
+  'include/freetype/ftparams.h',
+  'include/freetype/ftpfr.h',
+  'include/freetype/ftrender.h',
+  'include/freetype/ftsizes.h',
+  'include/freetype/ftsnames.h',
+  'include/freetype/ftstroke.h',
+  'include/freetype/ftsynth.h',
+  'include/freetype/ftsystem.h',
+  'include/freetype/fttrigon.h',
+  'include/freetype/fttypes.h',
+  'include/freetype/ftwinfnt.h',
+  'include/freetype/otsvg.h',
+  'include/freetype/t1tables.h',
+  'include/freetype/ttnameid.h',
+  'include/freetype/tttables.h',
+  'include/freetype/tttags.h',
+])
+
+ft2_config_headers = files([
+  'include/freetype/config/ftconfig.h',
+  'include/freetype/config/ftheader.h',
+  'include/freetype/config/ftstdlib.h',
+  'include/freetype/config/integer-types.h',
+  'include/freetype/config/mac-support.h',
+  'include/freetype/config/public-macros.h',
+])
+
+ft2_defines += ['-DFT2_BUILD_LIBRARY=1']
+
+
+# System support file.
+
+cc = meson.get_compiler('c')
+
+# NOTE: msys2 on Windows has `unistd.h` and `fcntl.h` but not `sys/mman.h`!
+has_unistd_h = cc.has_header('unistd.h')
+has_fcntl_h = cc.has_header('fcntl.h')
+has_sys_mman_h = cc.has_header('sys/mman.h')
+
+mmap_option = get_option('mmap')
+
+use_unix_ftsystem_c = false
+if mmap_option.disabled()
+  ft2_sources += files(['src/base/ftsystem.c',])
+elif host_machine.system() == 'windows'
+  ft2_sources += files(['builds/windows/ftsystem.c',])
+else
+  if has_unistd_h and has_fcntl_h and has_sys_mman_h
+    # This version of `ftsystem.c` uses `mmap` to read input font files.
+    ft2_sources += files(['builds/unix/ftsystem.c',])
+    use_unix_ftsystem_c = true
+  elif mmap_option.enabled()
+    error('mmap was enabled via options but is not available,'
+          + ' required headers were not found!')
+  else
+    ft2_sources += files(['src/base/ftsystem.c',])
+  endif
+endif
+
+
+# Debug support file
+#
+# NOTE: Some specialized versions exist for other platforms not supported by
+# Meson.  Most implementation differences are extremely minor, i.e., in the
+# implementation of `FT_Message` and `FT_Panic`, and getting the `FT2_DEBUG`
+# value from the environment, when this is supported.  A smaller refactor
+# might make these platform-specific files much smaller, and could be moved
+# into `ftsystem.c` as well.
+#
+if host_machine.system() == 'windows'
+  winmod = import('windows')
+  ft2_sources += [
+    'builds/windows/ftdebug.c',
+    winmod.compile_resources('src/base/ftver.rc'),
+  ]
+else
+  ft2_sources += 'src/base/ftdebug.c'
+endif
+
+
+ft2_deps = []
+common_ldflags = []
+
+
+# Correct compatibility version for OS x.
+#
+# OSX sets the compatibility_version (aka libtools version) differently from
+# the library name.
+#
+if host_machine.system() == 'darwin'
+  # maintain compatibility with autotools on macOS
+  common_ldflags = [
+    '-compatibility_version', ft2_pkgconfig_version.split('.')[0],
+    '-current_version', ft2_pkgconfig_version
+  ]
+endif
+
+
+# Generate `ftoption.h` based on available dependencies.
+
+process_header_command = [python_exe,
+  files('builds/meson/process_ftoption_h.py'),
+  '@INPUT@', '--output=@OUTPUT@']
+ftoption_command = process_header_command
+
+
+# external GZip support
+zlib_option = get_option('zlib')
+
+# Backwards-compatible aliases.
+if zlib_option == 'disabled'
+  zlib_option = 'none'
+elif zlib_option == 'enabled'
+  zlib_option = 'auto'
+endif
+
+if zlib_option == 'auto'
+  # First try to find a system installation, otherwise fall back to
+  # the subproject.
+  zlib_dep = dependency('zlib',
+    required: false)
+  if zlib_dep.found()
+    zlib_option = 'system'
+  else
+    zlib_option = 'external'
+  endif
+endif
+
+if zlib_option == 'none'
+  ftoption_command += [ '--disable=FT_CONFIG_OPTION_USE_ZLIB' ]
+elif zlib_option == 'internal'
+  ftoption_command += [ '--enable=FT_CONFIG_OPTION_USE_ZLIB' ]
+elif zlib_option == 'external'
+  ftoption_command += [ '--enable=FT_CONFIG_OPTION_USE_ZLIB' ]
+  zlib_project = subproject('zlib',
+    required: true,
+    default_options: 'default_library=static')
+  zlib_dep = zlib_project.get_variable('zlib_dep')
+  ft2_deps += [zlib_dep]
+elif zlib_option == 'system'
+  zlib_dep = dependency('zlib',
+    required: true)
+  assert(zlib_dep.found(), 'Could not find system zlib installation!')
+  ftoption_command += [
+    '--enable=FT_CONFIG_OPTION_USE_ZLIB',
+    '--enable=FT_CONFIG_OPTION_SYSTEM_ZLIB',
+  ]
+  ft2_deps += [zlib_dep]
+else
+  assert(false, 'Invalid zlib option ' + zlib_option)
+endif
+
+# BZip2 support
+bzip2_dep = cc.find_library('bz2',
+  required: get_option('bzip2'))
+
+if bzip2_dep.found()
+  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_BZIP2']
+  ft2_sources += files(['src/bzip2/ftbzip2.c',])
+  ft2_deps += [bzip2_dep]
+endif
+
+# PNG support
+libpng_dep = dependency('libpng',
+  required: get_option('png'),
+  fallback: 'libpng')
+
+if libpng_dep.found()
+  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_PNG']
+  ft2_deps += [libpng_dep]
+endif
+
+# Harfbuzz support
+harfbuzz_dep = dependency('harfbuzz',
+  version: '>= 2.0.0',
+  required: get_option('harfbuzz'),
+  default_options: ['freetype=disabled'])
+
+if harfbuzz_dep.found()
+  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_HARFBUZZ']
+  ft2_deps += [harfbuzz_dep]
+endif
+
+# Brotli decompression support
+brotli_dep = dependency('libbrotlidec',
+  required: get_option('brotli'))
+
+if brotli_dep.found()
+  ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_BROTLI']
+  ft2_deps += [brotli_dep]
+endif
+
+# We can now generate `ftoption.h`.
+ftoption_h = custom_target('ftoption.h',
+  input: 'include/freetype/config/ftoption.h',
+  output: 'ftoption.h',
+  command: ftoption_command,
+  install: true,
+  install_dir: join_paths(freetype_includedir, 'freetype/config'),
+)
+ft2_sources += ftoption_h
+ft2_defines += ['-DFT_CONFIG_OPTIONS_H=<ftoption.h>']
+
+if host_machine.system() == 'windows'
+  ft2_defines += ['-DDLL_EXPORT=1']
+endif
+
+
+# Generate `ftconfig.h`.
+
+ftconfig_command = process_header_command
+if has_unistd_h
+  ftconfig_command += '--enable=HAVE_UNISTD_H'
+endif
+if has_fcntl_h
+  ftconfig_command += '--enable=HAVE_FCNTL_H'
+endif
+
+if use_unix_ftsystem_c
+  ftconfig_h_in = files('builds/unix/ftconfig.h.in')
+  ftconfig_h = custom_target('ftconfig.h',
+    input: ftconfig_h_in,
+    output: 'ftconfig.h',
+    command: ftconfig_command,
+    install: true,
+    install_dir: join_paths(freetype_includedir, 'freetype/config'),
+  )
+  ft2_sources += ftconfig_h
+  ft2_defines += ['-DFT_CONFIG_CONFIG_H=<ftconfig.h>']
+endif
+
+
+ft2_lib = library('freetype',
+  sources: ft2_sources + [ftmodule_h],
+  c_args: ft2_defines,
+  gnu_symbol_visibility: 'hidden',
+  include_directories: ft2_includes,
+  dependencies: ft2_deps,
+  install: true,
+  version: ft2_so_version,
+  link_args: common_ldflags,
+)
+
+
+# To be used by other projects including this one through `subproject`.
+freetype_dep = declare_dependency(
+  include_directories: ft2_includes,
+  link_with: ft2_lib,
+  version: ft2_pkgconfig_version)
+
+meson.override_dependency('freetype2', freetype_dep)
+
+
+# NOTE: Using both `install_dir` and `subdir` doesn't seem to work below,
+# i.e., the subdir value seems to be ignored, contrary to examples in the
+# Meson documentation.
+install_headers('include/ft2build.h',
+  install_dir: freetype_includedir)
+install_headers(ft2_public_headers,
+  install_dir: join_paths(freetype_includedir, 'freetype'))
+install_headers(ft2_config_headers,
+  install_dir: join_paths(freetype_includedir, 'freetype/config'))
+
+
+pkgconfig = import('pkgconfig')
+
+pkgconfig.generate(ft2_lib,
+  filebase: 'freetype2',
+  name: 'FreeType 2',
+  description: 'A free, high-quality, and portable font engine.',
+  url: 'https://freetype.org',
+  subdirs: 'freetype2',
+  version: ft2_pkgconfig_version,
+)
+
+if get_option('tests').enabled()
+  subdir('tests')
+endif
+
+# NOTE: Unlike the old `make refdoc` command, this generates the
+# documentation under `$BUILD/docs/` since Meson doesn't support modifying
+# the source root directory (which is a good thing).
+gen_docs = custom_target('freetype2 reference documentation',
+  output: 'docs',
+  input: ft2_public_headers + ft2_config_headers,
+  command: [python_exe,
+    files('builds/meson/generate_reference_docs.py'),
+    '--version=' + meson.project_version(),
+    '--input-dir=' + meson.current_source_dir(),
+    '--output-dir=@OUTPUT@'
+  ],
+)
+
+
+summary({'OS': host_machine.system(),
+        }, section: 'Operating System')
+
+summary({'Zlib': zlib_option,
+         'Bzip2': bzip2_dep.found() ? 'yes' : 'no',
+         'Png': libpng_dep.found() ? 'yes' : 'no',
+         'Harfbuzz': harfbuzz_dep.found() ? 'yes' : 'no',
+         'Brotli': brotli_dep.found() ? 'yes' : 'no',
+        }, section: 'Used Libraries')
+
+# EOF
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..e4ad50c
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,55 @@
+#
+# meson_options.txt
+#
+
+# Copyright (C) 2020-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.
+
+
+option('brotli',
+  type: 'feature',
+  value: 'auto',
+  description: 'Use Brotli library to support decompressing WOFF2 fonts')
+
+option('bzip2',
+  type: 'feature',
+  value: 'auto',
+  description: 'Support reading bzip2-compressed font files')
+
+option('harfbuzz',
+  type: 'feature',
+  value: 'auto',
+  description: 'Use Harfbuzz library to improve auto-hinting;'
+               + ' if available, many glyphs not directly addressable'
+               + ' by a font\'s character map will be hinted also')
+
+option('mmap',
+  type: 'feature',
+  value: 'auto',
+  description: 'Use mmap() to open font files for faster parsing')
+
+option('png',
+  type: 'feature',
+  value: 'auto',
+  description: 'Support color bitmap glyph formats in the PNG format;'
+               + ' requires libpng')
+
+option('tests',
+  type: 'feature',
+  value: 'disabled',
+  description: 'Enable FreeType unit and regression tests')
+
+option('zlib',
+  type: 'combo',
+  choices: [ 'auto', 'none',
+             'internal', 'external', 'system',
+             'disabled', 'enabled' ],
+  description: 'Support reading gzip-compressed font files')
+
+# EOF
diff --git a/modules.cfg b/modules.cfg
index c46e619..5b6c9b5 100644
--- a/modules.cfg
+++ b/modules.cfg
@@ -1,6 +1,6 @@
 # modules.cfg
 #
-# Copyright 2005-2018 by
+# Copyright (C) 2005-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -93,11 +93,17 @@
 #### raster modules -- at least one is required for vector font formats
 ####
 
+# Anti-aliasing rasterizer.
+RASTER_MODULES += smooth
+
 # Monochrome rasterizer.
 RASTER_MODULES += raster
 
-# Anti-aliasing rasterizer.
-RASTER_MODULES += smooth
+# OT-SVG.
+RASTER_MODULES += svg
+
+# Signed distance field rasterizer.
+RASTER_MODULES += sdf
 
 
 ####
diff --git a/src/Jamfile b/src/Jamfile
deleted file mode 100644
index 562480c..0000000
--- a/src/Jamfile
+++ /dev/null
@@ -1,19 +0,0 @@
-# FreeType 2 src Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) ;
-
-for xx in $(FT2_COMPONENTS)
-{
-  SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ;
-}
-
-# end of src Jamfile
diff --git a/src/autofit/Jamfile b/src/autofit/Jamfile
deleted file mode 100644
index 01b866e..0000000
--- a/src/autofit/Jamfile
+++ /dev/null
@@ -1,53 +0,0 @@
-# FreeType 2 src/autofit Jamfile
-#
-# Copyright 2003-2018 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.
-
-SubDir FT2_TOP src autofit ;
-
-{
-  local  _sources ;
-
-  # define FT2_AUTOFIT2 to enable experimental latin hinter replacement
-  if $(FT2_AUTOFIT2)
-  {
-    CCFLAGS += FT_OPTION_AUTOFIT2 ;
-  }
-  if $(FT2_MULTI)
-  {
-    _sources = afangles
-               afblue
-               afcjk
-               afdummy
-               afglobal
-               afhints
-               afindic
-               aflatin
-               afloader
-               afmodule
-               afpic
-               afranges
-               afshaper
-               afwarp
-               ;
-
-    if $(FT2_AUTOFIT2)
-    {
-      _sources += aflatin2 ;
-    }
-  }
-  else
-  {
-    _sources = autofit ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/autofit Jamfile
diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c
deleted file mode 100644
index f7b1c2c..0000000
--- a/src/autofit/afangles.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/****************************************************************************
- *
- * afangles.c
- *
- *   Routines used to compute vector angles with limited accuracy
- *   and very high speed.  It also contains sorting routines (body).
- *
- * Copyright 2003-2018 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 "aftypes.h"
-
-
-  /*
-   * We are not using `af_angle_atan' anymore, but we keep the source
-   * code below just in case...
-   */
-
-
-#if 0
-
-
-  /*
-   * The trick here is to realize that we don't need a very accurate angle
-   * approximation.  We are going to use the result of `af_angle_atan' to
-   * only compare the sign of angle differences, or check whether its
-   * magnitude is very small.
-   *
-   * The approximation
-   *
-   *   dy * PI / (|dx|+|dy|)
-   *
-   * should be enough, and much faster to compute.
-   */
-  FT_LOCAL_DEF( AF_Angle )
-  af_angle_atan( FT_Fixed  dx,
-                 FT_Fixed  dy )
-  {
-    AF_Angle  angle;
-    FT_Fixed  ax = dx;
-    FT_Fixed  ay = dy;
-
-
-    if ( ax < 0 )
-      ax = -ax;
-    if ( ay < 0 )
-      ay = -ay;
-
-    ax += ay;
-
-    if ( ax == 0 )
-      angle = 0;
-    else
-    {
-      angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
-      if ( dx < 0 )
-      {
-        if ( angle >= 0 )
-          angle = AF_ANGLE_PI - angle;
-        else
-          angle = -AF_ANGLE_PI - angle;
-      }
-    }
-
-    return angle;
-  }
-
-
-#elif 0
-
-
-  /* the following table has been automatically generated with */
-  /* the `mather.py' Python script                             */
-
-#define AF_ATAN_BITS  8
-
-  static const FT_Byte  af_arctan[1L << AF_ATAN_BITS] =
-  {
-     0,  0,  1,  1,  1,  2,  2,  2,
-     3,  3,  3,  3,  4,  4,  4,  5,
-     5,  5,  6,  6,  6,  7,  7,  7,
-     8,  8,  8,  9,  9,  9, 10, 10,
-    10, 10, 11, 11, 11, 12, 12, 12,
-    13, 13, 13, 14, 14, 14, 14, 15,
-    15, 15, 16, 16, 16, 17, 17, 17,
-    18, 18, 18, 18, 19, 19, 19, 20,
-    20, 20, 21, 21, 21, 21, 22, 22,
-    22, 23, 23, 23, 24, 24, 24, 24,
-    25, 25, 25, 26, 26, 26, 26, 27,
-    27, 27, 28, 28, 28, 28, 29, 29,
-    29, 30, 30, 30, 30, 31, 31, 31,
-    31, 32, 32, 32, 33, 33, 33, 33,
-    34, 34, 34, 34, 35, 35, 35, 35,
-    36, 36, 36, 36, 37, 37, 37, 38,
-    38, 38, 38, 39, 39, 39, 39, 40,
-    40, 40, 40, 41, 41, 41, 41, 42,
-    42, 42, 42, 42, 43, 43, 43, 43,
-    44, 44, 44, 44, 45, 45, 45, 45,
-    46, 46, 46, 46, 46, 47, 47, 47,
-    47, 48, 48, 48, 48, 48, 49, 49,
-    49, 49, 50, 50, 50, 50, 50, 51,
-    51, 51, 51, 51, 52, 52, 52, 52,
-    52, 53, 53, 53, 53, 53, 54, 54,
-    54, 54, 54, 55, 55, 55, 55, 55,
-    56, 56, 56, 56, 56, 57, 57, 57,
-    57, 57, 57, 58, 58, 58, 58, 58,
-    59, 59, 59, 59, 59, 59, 60, 60,
-    60, 60, 60, 61, 61, 61, 61, 61,
-    61, 62, 62, 62, 62, 62, 62, 63,
-    63, 63, 63, 63, 63, 64, 64, 64
-  };
-
-
-  FT_LOCAL_DEF( AF_Angle )
-  af_angle_atan( FT_Fixed  dx,
-                 FT_Fixed  dy )
-  {
-    AF_Angle  angle;
-
-
-    /* check trivial cases */
-    if ( dy == 0 )
-    {
-      angle = 0;
-      if ( dx < 0 )
-        angle = AF_ANGLE_PI;
-      return angle;
-    }
-    else if ( dx == 0 )
-    {
-      angle = AF_ANGLE_PI2;
-      if ( dy < 0 )
-        angle = -AF_ANGLE_PI2;
-      return angle;
-    }
-
-    angle = 0;
-    if ( dx < 0 )
-    {
-      dx = -dx;
-      dy = -dy;
-      angle = AF_ANGLE_PI;
-    }
-
-    if ( dy < 0 )
-    {
-      FT_Pos  tmp;
-
-
-      tmp = dx;
-      dx  = -dy;
-      dy  = tmp;
-      angle -= AF_ANGLE_PI2;
-    }
-
-    if ( dx == 0 && dy == 0 )
-      return 0;
-
-    if ( dx == dy )
-      angle += AF_ANGLE_PI4;
-    else if ( dx > dy )
-      angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )];
-    else
-      angle += AF_ANGLE_PI2 -
-               af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )];
-
-    if ( angle > AF_ANGLE_PI )
-      angle -= AF_ANGLE_2PI;
-
-    return angle;
-  }
-
-
-#endif /* 0 */
-
-
-  FT_LOCAL_DEF( void )
-  af_sort_pos( FT_UInt  count,
-               FT_Pos*  table )
-  {
-    FT_UInt  i, j;
-    FT_Pos   swap;
-
-
-    for ( i = 1; i < count; i++ )
-    {
-      for ( j = i; j > 0; j-- )
-      {
-        if ( table[j] >= table[j - 1] )
-          break;
-
-        swap         = table[j];
-        table[j]     = table[j - 1];
-        table[j - 1] = swap;
-      }
-    }
-  }
-
-
-  FT_LOCAL_DEF( void )
-  af_sort_and_quantize_widths( FT_UInt*  count,
-                               AF_Width  table,
-                               FT_Pos    threshold )
-  {
-    FT_UInt      i, j;
-    FT_UInt      cur_idx;
-    FT_Pos       cur_val;
-    FT_Pos       sum;
-    AF_WidthRec  swap;
-
-
-    if ( *count == 1 )
-      return;
-
-    /* sort */
-    for ( i = 1; i < *count; i++ )
-    {
-      for ( j = i; j > 0; j-- )
-      {
-        if ( table[j].org >= table[j - 1].org )
-          break;
-
-        swap         = table[j];
-        table[j]     = table[j - 1];
-        table[j - 1] = swap;
-      }
-    }
-
-    cur_idx = 0;
-    cur_val = table[cur_idx].org;
-
-    /* compute and use mean values for clusters not larger than  */
-    /* `threshold'; this is very primitive and might not yield   */
-    /* the best result, but normally, using reference character  */
-    /* `o', `*count' is 2, so the code below is fully sufficient */
-    for ( i = 1; i < *count; i++ )
-    {
-      if ( table[i].org - cur_val > threshold ||
-           i == *count - 1                    )
-      {
-        sum = 0;
-
-        /* fix loop for end of array */
-        if ( table[i].org - cur_val <= threshold &&
-             i == *count - 1                     )
-          i++;
-
-        for ( j = cur_idx; j < i; j++ )
-        {
-          sum         += table[j].org;
-          table[j].org = 0;
-        }
-        table[cur_idx].org = sum / (FT_Pos)j;
-
-        if ( i < *count - 1 )
-        {
-          cur_idx = i + 1;
-          cur_val = table[cur_idx].org;
-        }
-      }
-    }
-
-    cur_idx = 1;
-
-    /* compress array to remove zero values */
-    for ( i = 1; i < *count; i++ )
-    {
-      if ( table[i].org )
-        table[cur_idx++] = table[i];
-    }
-
-    *count = cur_idx;
-  }
-
-
-/* END */
diff --git a/src/autofit/afangles.h b/src/autofit/afangles.h
deleted file mode 100644
index 18d7dae..0000000
--- a/src/autofit/afangles.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * afangles.h
- *
- * This is a dummy file, used to please the build system.  It is never
- * included by the auto-fitter sources.
- *
- */
diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c
index 9b0ac13..d7655b9 100644
--- a/src/autofit/afblue.c
+++ b/src/autofit/afblue.c
@@ -7,7 +7,7 @@
  *
  *   Auto-fitter data for blue strings (body).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -134,7 +134,7 @@
     '\0',
     '\xF0', '\x90', '\x90', '\xA8', ' ', '\xF0', '\x90', '\x90', '\xAA', ' ', '\xF0', '\x90', '\x90', '\xAC', ' ', '\xF0', '\x90', '\x90', '\xBF', ' ', '\xF0', '\x90', '\x91', '\x83',  /* 𐐨 𐐪 𐐬 𐐿 𐑃 */
     '\0',
-    '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6',  /* क म अ आ थ ध भ श */
+    '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xA8', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x89', ' ', '\xE0', '\xA4', '\x9B', ' ', '\xE0', '\xA4', '\x9F', ' ', '\xE0', '\xA4', '\xA0', ' ', '\xE0', '\xA4', '\xA1',  /* क न म उ छ ट ठ ड */
     '\0',
     '\xE0', '\xA4', '\x88', ' ', '\xE0', '\xA4', '\x90', ' ', '\xE0', '\xA4', '\x93', ' ', '\xE0', '\xA4', '\x94', ' ', '\xE0', '\xA4', '\xBF', ' ', '\xE0', '\xA5', '\x80', ' ', '\xE0', '\xA5', '\x8B', ' ', '\xE0', '\xA5', '\x8C',  /* ई ऐ ओ औ ि ी ो ौ */
     '\0',
@@ -296,6 +296,24 @@
     '\0',
     '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2',  /* ട ഠ ധ ശ ഘ ച ഥ ല */
     '\0',
+    '\xF0', '\x96', '\xB9', '\x80', ' ', '\xF0', '\x96', '\xB9', '\x81', ' ', '\xF0', '\x96', '\xB9', '\x82', ' ', '\xF0', '\x96', '\xB9', '\x83', ' ', '\xF0', '\x96', '\xB9', '\x8F', ' ', '\xF0', '\x96', '\xB9', '\x9A', ' ', '\xF0', '\x96', '\xB9', '\x9F',  /* 𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟 */
+    '\0',
+    '\xF0', '\x96', '\xB9', '\x80', ' ', '\xF0', '\x96', '\xB9', '\x81', ' ', '\xF0', '\x96', '\xB9', '\x82', ' ', '\xF0', '\x96', '\xB9', '\x83', ' ', '\xF0', '\x96', '\xB9', '\x8F', ' ', '\xF0', '\x96', '\xB9', '\x9A', ' ', '\xF0', '\x96', '\xB9', '\x92', ' ', '\xF0', '\x96', '\xB9', '\x93',  /* 𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓 */
+    '\0',
+    '\xF0', '\x96', '\xB9', '\xA4', ' ', '\xF0', '\x96', '\xB9', '\xAC', ' ', '\xF0', '\x96', '\xB9', '\xA7', ' ', '\xF0', '\x96', '\xB9', '\xB4', ' ', '\xF0', '\x96', '\xB9', '\xB6', ' ', '\xF0', '\x96', '\xB9', '\xBE',  /* 𖹤 𖹬 𖹧 𖹴 𖹶 𖹾 */
+    '\0',
+    '\xF0', '\x96', '\xB9', '\xA0', ' ', '\xF0', '\x96', '\xB9', '\xA1', ' ', '\xF0', '\x96', '\xB9', '\xA2', ' ', '\xF0', '\x96', '\xB9', '\xB9', ' ', '\xF0', '\x96', '\xB9', '\xB3', ' ', '\xF0', '\x96', '\xB9', '\xAE',  /* 𖹠 𖹡 𖹢 𖹹 𖹳 𖹮 */
+    '\0',
+    '\xF0', '\x96', '\xB9', '\xA0', ' ', '\xF0', '\x96', '\xB9', '\xA1', ' ', '\xF0', '\x96', '\xB9', '\xA2', ' ', '\xF0', '\x96', '\xB9', '\xB3', ' ', '\xF0', '\x96', '\xB9', '\xAD', ' ', '\xF0', '\x96', '\xB9', '\xBD',  /* 𖹠 𖹡 𖹢 𖹳 𖹭 𖹽 */
+    '\0',
+    '\xF0', '\x96', '\xB9', '\xA5', ' ', '\xF0', '\x96', '\xB9', '\xA8', ' ', '\xF0', '\x96', '\xB9', '\xA9',  /* 𖹥 𖹨 𖹩 */
+    '\0',
+    '\xF0', '\x96', '\xBA', '\x80', ' ', '\xF0', '\x96', '\xBA', '\x85', ' ', '\xF0', '\x96', '\xBA', '\x88', ' ', '\xF0', '\x96', '\xBA', '\x84', ' ', '\xF0', '\x96', '\xBA', '\x8D',  /* 𖺀 𖺅 𖺈 𖺄 𖺍 */
+    '\0',
+    '\xE1', '\xA0', '\xB3', ' ', '\xE1', '\xA0', '\xB4', ' ', '\xE1', '\xA0', '\xB6', ' ', '\xE1', '\xA0', '\xBD', ' ', '\xE1', '\xA1', '\x82', ' ', '\xE1', '\xA1', '\x8A', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xA1', '\xE2', '\x80', '\x8D', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xB3', '\xE2', '\x80', '\x8D',  /* ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍ */
+    '\0',
+    '\xE1', '\xA1', '\x83',  /* ᡃ */
+    '\0',
     '\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B',  /* ခ ဂ င ဒ ဝ ၥ ၊ ။ */
     '\0',
     '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B',  /* င ဎ ဒ ပ ဗ ဝ ၊ ။ */
@@ -336,6 +354,12 @@
     '\0',
     '\xF0', '\x90', '\x92', '\x80', ' ', '\xF0', '\x90', '\x92', '\x82', ' ', '\xF0', '\x90', '\x92', '\x86', ' ', '\xF0', '\x90', '\x92', '\x88', ' ', '\xF0', '\x90', '\x92', '\x8A', ' ', '\xF0', '\x90', '\x92', '\x92', ' ', '\xF0', '\x90', '\x92', '\xA0', ' ', '\xF0', '\x90', '\x92', '\xA9',  /* 𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩 */
     '\0',
+    '\xF0', '\x90', '\xB4', '\x83', ' ', '\xF0', '\x90', '\xB4', '\x80', ' ', '\xF0', '\x90', '\xB4', '\x86', ' ', '\xF0', '\x90', '\xB4', '\x96', ' ', '\xF0', '\x90', '\xB4', '\x95',  /* 𐴃 𐴀 𐴆 𐴖 𐴕 */
+    '\0',
+    '\xF0', '\x90', '\xB4', '\x94', ' ', '\xF0', '\x90', '\xB4', '\x96', ' ', '\xF0', '\x90', '\xB4', '\x95', ' ', '\xF0', '\x90', '\xB4', '\x91', ' ', '\xF0', '\x90', '\xB4', '\x90',  /* 𐴔 𐴖 𐴕 𐴑 𐴐 */
+    '\0',
+    '\xD9', '\x80',  /* ـ */
+    '\0',
     '\xEA', '\xA2', '\x9C', ' ', '\xEA', '\xA2', '\x9E', ' ', '\xEA', '\xA2', '\xB3', ' ', '\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\x96', ' ', '\xEA', '\xA2', '\x92', ' ', '\xEA', '\xA2', '\x9D', ' ', '\xEA', '\xA2', '\x9B',  /* ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ */
     '\0',
     '\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\xA8', ' ', '\xEA', '\xA2', '\xBA', ' ', '\xEA', '\xA2', '\xA4', ' ', '\xEA', '\xA2', '\x8E',  /* ꢂ ꢨ ꢺ ꢤ ꢎ */
@@ -484,14 +508,14 @@
     { AF_BLUE_STRING_CHAKMA_BOTTOM,    0                          },
     { AF_BLUE_STRING_CHAKMA_DESCENDER, 0                          },
     { AF_BLUE_STRING_MAX,              0                          },
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP,             AF_BLUE_PROPERTY_LATIN_TOP        },
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM,          0                                 },
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
-                                                         AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM,    0                                 },
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP,        AF_BLUE_PROPERTY_LATIN_TOP        },
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM,     0                                 },
-    { AF_BLUE_STRING_MAX,                                0                                 },
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP,          AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM,       0                                 },
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP,    AF_BLUE_PROPERTY_LATIN_TOP      |
+                                                      AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM, 0                                 },
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM,  0                                 },
+    { AF_BLUE_STRING_MAX,                             0                                 },
     { AF_BLUE_STRING_CARIAN_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_CARIAN_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,           0                          },
@@ -591,6 +615,9 @@
     { AF_BLUE_STRING_HEBREW_BOTTOM,    0                             },
     { AF_BLUE_STRING_HEBREW_DESCENDER, 0                             },
     { AF_BLUE_STRING_MAX,              0                             },
+    { AF_BLUE_STRING_KANNADA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
+    { AF_BLUE_STRING_KANNADA_BOTTOM, 0                          },
+    { AF_BLUE_STRING_MAX,            0                          },
     { AF_BLUE_STRING_KAYAH_LI_TOP,             AF_BLUE_PROPERTY_LATIN_TOP      |
                                                AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
     { AF_BLUE_STRING_KAYAH_LI_BOTTOM,          0                                 },
@@ -609,9 +636,6 @@
                                                   AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
     { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0                                 },
     { AF_BLUE_STRING_MAX,                         0                                 },
-    { AF_BLUE_STRING_KANNADA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
-    { AF_BLUE_STRING_KANNADA_BOTTOM, 0                          },
-    { AF_BLUE_STRING_MAX,            0                          },
     { AF_BLUE_STRING_LAO_TOP,            AF_BLUE_PROPERTY_LATIN_TOP      |
                                          AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
     { AF_BLUE_STRING_LAO_BOTTOM,         0                                 },
@@ -649,6 +673,18 @@
     { AF_BLUE_STRING_MALAYALAM_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,              0                          },
+    { AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_BOTTOM,  0                                 },
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
+                                                  AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_BOTTOM,    0                                 },
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_DESCENDER, 0                                 },
+    { AF_BLUE_STRING_MEDEFAIDRIN_DIGIT_TOP,       AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_MAX,                         0                                 },
+    { AF_BLUE_STRING_MONGOLIAN_TOP_BASE,    AF_BLUE_PROPERTY_LATIN_TOP },
+    { AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0                          },
+    { AF_BLUE_STRING_MAX,                   0                          },
     { AF_BLUE_STRING_MYANMAR_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
                                         AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
     { AF_BLUE_STRING_MYANMAR_BOTTOM,    0                                 },
@@ -680,6 +716,10 @@
     { AF_BLUE_STRING_OSMANYA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_OSMANYA_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,            0                          },
+    { AF_BLUE_STRING_ROHINGYA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP     },
+    { AF_BLUE_STRING_ROHINGYA_BOTTOM, 0                              },
+    { AF_BLUE_STRING_ROHINGYA_JOIN,   AF_BLUE_PROPERTY_LATIN_NEUTRAL },
+    { AF_BLUE_STRING_MAX,             0                              },
     { AF_BLUE_STRING_SAURASHTRA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,               0                          },
@@ -707,9 +747,6 @@
     { AF_BLUE_STRING_TELUGU_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_TELUGU_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,           0                          },
-    { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP },
-    { AF_BLUE_STRING_TIFINAGH, 0                          },
-    { AF_BLUE_STRING_MAX,      0                          },
     { AF_BLUE_STRING_THAI_TOP,             AF_BLUE_PROPERTY_LATIN_TOP      |
                                            AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
     { AF_BLUE_STRING_THAI_BOTTOM,          0                                 },
@@ -719,6 +756,9 @@
     { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0                                 },
     { AF_BLUE_STRING_THAI_DIGIT_TOP,       0                                 },
     { AF_BLUE_STRING_MAX,                  0                                 },
+    { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP },
+    { AF_BLUE_STRING_TIFINAGH, 0                          },
+    { AF_BLUE_STRING_MAX,      0                          },
     { AF_BLUE_STRING_VAI_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_VAI_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,        0                          },
diff --git a/src/autofit/afblue.cin b/src/autofit/afblue.cin
index b7437e3..d561c50 100644
--- a/src/autofit/afblue.cin
+++ b/src/autofit/afblue.cin
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter data for blue strings (body).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index 1b8d5d7..b7efe8b 100644
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -2,7 +2,7 @@
 //
 //   Auto-fitter data for blue strings.
 //
-// Copyright 2013-2018 by
+// Copyright (C) 2013-2023 by
 // David Turner, Robert Wilhelm, and Werner Lemberg.
 //
 // This file is part of the FreeType project, and may only be used,
@@ -203,7 +203,7 @@
     "𐐨 𐐪 𐐬 𐐿 𐑃"
 
   AF_BLUE_STRING_DEVANAGARI_BASE
-    "क म अ आ थ ध भ श"
+    "क न म उ छ ट ठ ड"
   AF_BLUE_STRING_DEVANAGARI_TOP
     "ई ऐ ओ औ ि ी ो ौ"
   // note that some fonts have extreme variation in the height of the
@@ -392,6 +392,26 @@
   AF_BLUE_STRING_MALAYALAM_BOTTOM
     "ട ഠ ധ ശ ഘ ച ഥ ല"
 
+  AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_TOP
+    "𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟"
+  AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_BOTTOM
+    "𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓"
+  AF_BLUE_STRING_MEDEFAIDRIN_SMALL_F_TOP
+    "𖹤 𖹬 𖹧 𖹴 𖹶 𖹾"
+  AF_BLUE_STRING_MEDEFAIDRIN_SMALL_TOP
+    "𖹠 𖹡 𖹢 𖹹 𖹳 𖹮"
+  AF_BLUE_STRING_MEDEFAIDRIN_SMALL_BOTTOM
+    "𖹠 𖹡 𖹢 𖹳 𖹭 𖹽"
+  AF_BLUE_STRING_MEDEFAIDRIN_SMALL_DESCENDER
+    "𖹥 𖹨 𖹩"
+  AF_BLUE_STRING_MEDEFAIDRIN_DIGIT_TOP
+    "𖺀 𖺅 𖺈 𖺄 𖺍"
+
+  AF_BLUE_STRING_MONGOLIAN_TOP_BASE
+    "ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍"
+  AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE
+    "ᡃ"
+
   AF_BLUE_STRING_MYANMAR_TOP
     "ခ ဂ င ဒ ဝ ၥ ၊ ။"
   AF_BLUE_STRING_MYANMAR_BOTTOM
@@ -438,6 +458,13 @@
   AF_BLUE_STRING_OSMANYA_BOTTOM
     "𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩"
 
+  AF_BLUE_STRING_ROHINGYA_TOP
+    "𐴃 𐴀 𐴆 𐴖 𐴕"
+  AF_BLUE_STRING_ROHINGYA_BOTTOM
+    "𐴔 𐴖 𐴕 𐴑 𐴐"
+  AF_BLUE_STRING_ROHINGYA_JOIN
+    "ـ"
+
   AF_BLUE_STRING_SAURASHTRA_TOP
     "ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ"
   AF_BLUE_STRING_SAURASHTRA_BOTTOM
@@ -729,14 +756,14 @@
     { AF_BLUE_STRING_MAX,              0                          }
 
   AF_BLUE_STRINGSET_CANS
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP,             AF_BLUE_PROPERTY_LATIN_TOP        }
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM,          0                                 }
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
-                                                         AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM,    0                                 }
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP,        AF_BLUE_PROPERTY_LATIN_TOP        }
-    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM,     0                                 }
-    { AF_BLUE_STRING_MAX,                                0                                 }
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP,          AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM,       0                                 }
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP,    AF_BLUE_PROPERTY_LATIN_TOP      |
+                                                      AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM, 0                                 }
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM,  0                                 }
+    { AF_BLUE_STRING_MAX,                             0                                 }
 
   AF_BLUE_STRINGSET_CARI
     { AF_BLUE_STRING_CARIAN_TOP,    AF_BLUE_PROPERTY_LATIN_TOP }
@@ -869,6 +896,11 @@
     { AF_BLUE_STRING_HEBREW_DESCENDER, 0                             }
     { AF_BLUE_STRING_MAX,              0                             }
 
+  AF_BLUE_STRINGSET_KNDA
+    { AF_BLUE_STRING_KANNADA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP }
+    { AF_BLUE_STRING_KANNADA_BOTTOM, 0                          }
+    { AF_BLUE_STRING_MAX,            0                          }
+
   AF_BLUE_STRINGSET_KALI
     { AF_BLUE_STRING_KAYAH_LI_TOP,             AF_BLUE_PROPERTY_LATIN_TOP      |
                                                AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
@@ -893,11 +925,6 @@
     { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0                                 }
     { AF_BLUE_STRING_MAX,                         0                                 }
 
-  AF_BLUE_STRINGSET_KNDA
-    { AF_BLUE_STRING_KANNADA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP }
-    { AF_BLUE_STRING_KANNADA_BOTTOM, 0                          }
-    { AF_BLUE_STRING_MAX,            0                          }
-
   AF_BLUE_STRINGSET_LAO
     { AF_BLUE_STRING_LAO_TOP,            AF_BLUE_PROPERTY_LATIN_TOP      |
                                          AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
@@ -947,6 +974,22 @@
     { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0                          }
     { AF_BLUE_STRING_MAX,              0                          }
 
+  AF_BLUE_STRINGSET_MEDF
+    { AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_BOTTOM,  0                                 }
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
+                                                  AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_BOTTOM,    0                                 }
+    { AF_BLUE_STRING_MEDEFAIDRIN_SMALL_DESCENDER, 0                                 }
+    { AF_BLUE_STRING_MEDEFAIDRIN_DIGIT_TOP,       AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_MAX,                         0                                 }
+
+  AF_BLUE_STRINGSET_MONG
+    { AF_BLUE_STRING_MONGOLIAN_TOP_BASE,    AF_BLUE_PROPERTY_LATIN_TOP }
+    { AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0                          }
+    { AF_BLUE_STRING_MAX,                   0                          }
+
   AF_BLUE_STRINGSET_MYMR
     { AF_BLUE_STRING_MYANMAR_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
                                         AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
@@ -992,6 +1035,12 @@
     { AF_BLUE_STRING_OSMANYA_BOTTOM, 0                          }
     { AF_BLUE_STRING_MAX,            0                          }
 
+  AF_BLUE_STRINGSET_ROHG
+    { AF_BLUE_STRING_ROHINGYA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP     }
+    { AF_BLUE_STRING_ROHINGYA_BOTTOM, 0                              }
+    { AF_BLUE_STRING_ROHINGYA_JOIN,   AF_BLUE_PROPERTY_LATIN_NEUTRAL }
+    { AF_BLUE_STRING_MAX,             0                              }
+
   AF_BLUE_STRINGSET_SAUR
     { AF_BLUE_STRING_SAURASHTRA_TOP,    AF_BLUE_PROPERTY_LATIN_TOP }
     { AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0                          }
@@ -1033,11 +1082,6 @@
     { AF_BLUE_STRING_TELUGU_BOTTOM, 0                          }
     { AF_BLUE_STRING_MAX,           0                          }
 
-  AF_BLUE_STRINGSET_TFNG
-    { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }
-    { AF_BLUE_STRING_TIFINAGH, 0                          }
-    { AF_BLUE_STRING_MAX,      0                          }
-
   AF_BLUE_STRINGSET_THAI
     { AF_BLUE_STRING_THAI_TOP,             AF_BLUE_PROPERTY_LATIN_TOP      |
                                            AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
@@ -1049,6 +1093,11 @@
     { AF_BLUE_STRING_THAI_DIGIT_TOP,       0                                 }
     { AF_BLUE_STRING_MAX,                  0                                 }
 
+  AF_BLUE_STRINGSET_TFNG
+    { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }
+    { AF_BLUE_STRING_TIFINAGH, 0                          }
+    { AF_BLUE_STRING_MAX,      0                          }
+
   AF_BLUE_STRINGSET_VAII
     { AF_BLUE_STRING_VAI_TOP,    AF_BLUE_PROPERTY_LATIN_TOP }
     { AF_BLUE_STRING_VAI_BOTTOM, 0                          }
diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
index 1fbadbe..76f2f47 100644
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -7,7 +7,7 @@
  *
  *   Auto-fitter data for blue strings (specification).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -212,56 +212,68 @@
     AF_BLUE_STRING_LISU_BOTTOM = 3506,
     AF_BLUE_STRING_MALAYALAM_TOP = 3538,
     AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582,
-    AF_BLUE_STRING_MYANMAR_TOP = 3614,
-    AF_BLUE_STRING_MYANMAR_BOTTOM = 3646,
-    AF_BLUE_STRING_MYANMAR_ASCENDER = 3678,
-    AF_BLUE_STRING_MYANMAR_DESCENDER = 3706,
-    AF_BLUE_STRING_NKO_TOP = 3738,
-    AF_BLUE_STRING_NKO_BOTTOM = 3762,
-    AF_BLUE_STRING_NKO_SMALL_TOP = 3777,
-    AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786,
-    AF_BLUE_STRING_OL_CHIKI = 3798,
-    AF_BLUE_STRING_OLD_TURKIC_TOP = 3822,
-    AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837,
-    AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857,
-    AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897,
-    AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927,
-    AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942,
-    AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982,
-    AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022,
-    AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047,
-    AF_BLUE_STRING_OSMANYA_TOP = 4062,
-    AF_BLUE_STRING_OSMANYA_BOTTOM = 4102,
-    AF_BLUE_STRING_SAURASHTRA_TOP = 4142,
-    AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174,
-    AF_BLUE_STRING_SHAVIAN_TOP = 4194,
-    AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204,
-    AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229,
-    AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239,
-    AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274,
-    AF_BLUE_STRING_SINHALA_TOP = 4289,
-    AF_BLUE_STRING_SINHALA_BOTTOM = 4321,
-    AF_BLUE_STRING_SINHALA_DESCENDER = 4353,
-    AF_BLUE_STRING_SUNDANESE_TOP = 4397,
-    AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421,
-    AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453,
-    AF_BLUE_STRING_TAI_VIET_TOP = 4461,
-    AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481,
-    AF_BLUE_STRING_TAMIL_TOP = 4493,
-    AF_BLUE_STRING_TAMIL_BOTTOM = 4525,
-    AF_BLUE_STRING_TELUGU_TOP = 4557,
-    AF_BLUE_STRING_TELUGU_BOTTOM = 4585,
-    AF_BLUE_STRING_THAI_TOP = 4613,
-    AF_BLUE_STRING_THAI_BOTTOM = 4637,
-    AF_BLUE_STRING_THAI_ASCENDER = 4665,
-    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677,
-    AF_BLUE_STRING_THAI_DESCENDER = 4689,
-    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705,
-    AF_BLUE_STRING_THAI_DIGIT_TOP = 4713,
-    AF_BLUE_STRING_TIFINAGH = 4725,
-    AF_BLUE_STRING_VAI_TOP = 4757,
-    AF_BLUE_STRING_VAI_BOTTOM = 4789,
-    af_blue_1_1 = 4820,
+    AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_TOP = 3614,
+    AF_BLUE_STRING_MEDEFAIDRIN_CAPITAL_BOTTOM = 3649,
+    AF_BLUE_STRING_MEDEFAIDRIN_SMALL_F_TOP = 3689,
+    AF_BLUE_STRING_MEDEFAIDRIN_SMALL_TOP = 3719,
+    AF_BLUE_STRING_MEDEFAIDRIN_SMALL_BOTTOM = 3749,
+    AF_BLUE_STRING_MEDEFAIDRIN_SMALL_DESCENDER = 3779,
+    AF_BLUE_STRING_MEDEFAIDRIN_DIGIT_TOP = 3794,
+    AF_BLUE_STRING_MONGOLIAN_TOP_BASE = 3819,
+    AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE = 3863,
+    AF_BLUE_STRING_MYANMAR_TOP = 3867,
+    AF_BLUE_STRING_MYANMAR_BOTTOM = 3899,
+    AF_BLUE_STRING_MYANMAR_ASCENDER = 3931,
+    AF_BLUE_STRING_MYANMAR_DESCENDER = 3959,
+    AF_BLUE_STRING_NKO_TOP = 3991,
+    AF_BLUE_STRING_NKO_BOTTOM = 4015,
+    AF_BLUE_STRING_NKO_SMALL_TOP = 4030,
+    AF_BLUE_STRING_NKO_SMALL_BOTTOM = 4039,
+    AF_BLUE_STRING_OL_CHIKI = 4051,
+    AF_BLUE_STRING_OLD_TURKIC_TOP = 4075,
+    AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 4090,
+    AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 4110,
+    AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 4150,
+    AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 4180,
+    AF_BLUE_STRING_OSAGE_SMALL_TOP = 4195,
+    AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 4235,
+    AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4275,
+    AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4300,
+    AF_BLUE_STRING_OSMANYA_TOP = 4315,
+    AF_BLUE_STRING_OSMANYA_BOTTOM = 4355,
+    AF_BLUE_STRING_ROHINGYA_TOP = 4395,
+    AF_BLUE_STRING_ROHINGYA_BOTTOM = 4420,
+    AF_BLUE_STRING_ROHINGYA_JOIN = 4445,
+    AF_BLUE_STRING_SAURASHTRA_TOP = 4448,
+    AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4480,
+    AF_BLUE_STRING_SHAVIAN_TOP = 4500,
+    AF_BLUE_STRING_SHAVIAN_BOTTOM = 4510,
+    AF_BLUE_STRING_SHAVIAN_DESCENDER = 4535,
+    AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4545,
+    AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4580,
+    AF_BLUE_STRING_SINHALA_TOP = 4595,
+    AF_BLUE_STRING_SINHALA_BOTTOM = 4627,
+    AF_BLUE_STRING_SINHALA_DESCENDER = 4659,
+    AF_BLUE_STRING_SUNDANESE_TOP = 4703,
+    AF_BLUE_STRING_SUNDANESE_BOTTOM = 4727,
+    AF_BLUE_STRING_SUNDANESE_DESCENDER = 4759,
+    AF_BLUE_STRING_TAI_VIET_TOP = 4767,
+    AF_BLUE_STRING_TAI_VIET_BOTTOM = 4787,
+    AF_BLUE_STRING_TAMIL_TOP = 4799,
+    AF_BLUE_STRING_TAMIL_BOTTOM = 4831,
+    AF_BLUE_STRING_TELUGU_TOP = 4863,
+    AF_BLUE_STRING_TELUGU_BOTTOM = 4891,
+    AF_BLUE_STRING_THAI_TOP = 4919,
+    AF_BLUE_STRING_THAI_BOTTOM = 4943,
+    AF_BLUE_STRING_THAI_ASCENDER = 4971,
+    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4983,
+    AF_BLUE_STRING_THAI_DESCENDER = 4995,
+    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 5011,
+    AF_BLUE_STRING_THAI_DIGIT_TOP = 5019,
+    AF_BLUE_STRING_TIFINAGH = 5031,
+    AF_BLUE_STRING_VAI_TOP = 5063,
+    AF_BLUE_STRING_VAI_BOTTOM = 5095,
+    af_blue_1_1 = 5126,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
     AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
@@ -345,34 +357,37 @@
     AF_BLUE_STRINGSET_GUJR = 112,
     AF_BLUE_STRINGSET_GURU = 118,
     AF_BLUE_STRINGSET_HEBR = 124,
-    AF_BLUE_STRINGSET_KALI = 128,
-    AF_BLUE_STRINGSET_KHMR = 134,
-    AF_BLUE_STRINGSET_KHMS = 140,
-    AF_BLUE_STRINGSET_KNDA = 143,
+    AF_BLUE_STRINGSET_KNDA = 128,
+    AF_BLUE_STRINGSET_KALI = 131,
+    AF_BLUE_STRINGSET_KHMR = 137,
+    AF_BLUE_STRINGSET_KHMS = 143,
     AF_BLUE_STRINGSET_LAO = 146,
     AF_BLUE_STRINGSET_LATN = 152,
     AF_BLUE_STRINGSET_LATB = 159,
     AF_BLUE_STRINGSET_LATP = 166,
     AF_BLUE_STRINGSET_LISU = 173,
     AF_BLUE_STRINGSET_MLYM = 176,
-    AF_BLUE_STRINGSET_MYMR = 179,
-    AF_BLUE_STRINGSET_NKOO = 184,
-    AF_BLUE_STRINGSET_NONE = 189,
-    AF_BLUE_STRINGSET_OLCK = 190,
-    AF_BLUE_STRINGSET_ORKH = 193,
-    AF_BLUE_STRINGSET_OSGE = 196,
-    AF_BLUE_STRINGSET_OSMA = 204,
-    AF_BLUE_STRINGSET_SAUR = 207,
-    AF_BLUE_STRINGSET_SHAW = 210,
-    AF_BLUE_STRINGSET_SINH = 216,
-    AF_BLUE_STRINGSET_SUND = 220,
-    AF_BLUE_STRINGSET_TAML = 224,
-    AF_BLUE_STRINGSET_TAVT = 227,
-    AF_BLUE_STRINGSET_TELU = 230,
-    AF_BLUE_STRINGSET_TFNG = 233,
-    AF_BLUE_STRINGSET_THAI = 236,
-    AF_BLUE_STRINGSET_VAII = 244,
-    af_blue_2_1 = 247,
+    AF_BLUE_STRINGSET_MEDF = 179,
+    AF_BLUE_STRINGSET_MONG = 187,
+    AF_BLUE_STRINGSET_MYMR = 190,
+    AF_BLUE_STRINGSET_NKOO = 195,
+    AF_BLUE_STRINGSET_NONE = 200,
+    AF_BLUE_STRINGSET_OLCK = 201,
+    AF_BLUE_STRINGSET_ORKH = 204,
+    AF_BLUE_STRINGSET_OSGE = 207,
+    AF_BLUE_STRINGSET_OSMA = 215,
+    AF_BLUE_STRINGSET_ROHG = 218,
+    AF_BLUE_STRINGSET_SAUR = 222,
+    AF_BLUE_STRINGSET_SHAW = 225,
+    AF_BLUE_STRINGSET_SINH = 231,
+    AF_BLUE_STRINGSET_SUND = 235,
+    AF_BLUE_STRINGSET_TAML = 239,
+    AF_BLUE_STRINGSET_TAVT = 242,
+    AF_BLUE_STRINGSET_TELU = 245,
+    AF_BLUE_STRINGSET_THAI = 248,
+    AF_BLUE_STRINGSET_TFNG = 256,
+    AF_BLUE_STRINGSET_VAII = 259,
+    af_blue_2_1 = 262,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
     af_blue_2_1_1 = af_blue_2_1 + 2,
diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin
index 3f1d311..6a31298 100644
--- a/src/autofit/afblue.hin
+++ b/src/autofit/afblue.hin
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter data for blue strings (specification).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index dc38153..5daefff 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter hinting routines for CJK writing system (body).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,9 +22,8 @@
    *
    */
 
-#include <ft2build.h>
-#include FT_ADVANCES_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/ftadvanc.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "afglobal.h"
 #include "aflatin.h"
@@ -38,11 +37,6 @@
 #include "aferrors.h"
 
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-#include "afwarp.h"
-#endif
-
-
   /**************************************************************************
    *
    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
@@ -50,7 +44,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_afcjk
+#define FT_COMPONENT  afcjk
 
 
   /*************************************************************************/
@@ -73,11 +67,11 @@
     AF_GlyphHintsRec  hints[1];
 
 
-    FT_TRACE5(( "\n"
-                "cjk standard widths computation (style `%s')\n"
-                "===================================================\n"
-                "\n",
+    FT_TRACE5(( "\n" ));
+    FT_TRACE5(( "cjk standard widths computation (style `%s')\n",
                 af_style_names[metrics->root.style_class->style] ));
+    FT_TRACE5(( "===================================================\n" ));
+    FT_TRACE5(( "\n" ));
 
     af_glyph_hints_init( hints, face->memory );
 
@@ -158,7 +152,7 @@
       if ( !glyph_index )
         goto Exit;
 
-      FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
+      FT_TRACE5(( "standard character: U+%04lX (glyph index %ld)\n",
                   ch, glyph_index ));
 
       error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
@@ -261,9 +255,9 @@
                       dim == AF_DIMENSION_VERT ? "horizontal"
                                                : "vertical" ));
 
-          FT_TRACE5(( "  %d (standard)", axis->standard_width ));
+          FT_TRACE5(( "  %ld (standard)", axis->standard_width ));
           for ( i = 1; i < axis->width_count; i++ )
-            FT_TRACE5(( " %d", axis->widths[i].org ));
+            FT_TRACE5(( " %ld", axis->widths[i].org ));
 
           FT_TRACE5(( "\n" ));
         }
@@ -315,9 +309,9 @@
     /* style's entry in the `af_blue_stringset' array, computing its */
     /* extremum points (depending on the string properties)          */
 
-    FT_TRACE5(( "cjk blue zones computation\n"
-                "==========================\n"
-                "\n" ));
+    FT_TRACE5(( "cjk blue zones computation\n" ));
+    FT_TRACE5(( "==========================\n" ));
+    FT_TRACE5(( "\n" ));
 
 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
     shaper_buf = af_shaper_buf_create( face );
@@ -556,9 +550,8 @@
       if ( AF_CJK_IS_TOP_BLUE( bs ) )
         blue->flags |= AF_CJK_BLUE_TOP;
 
-      FT_TRACE5(( "    -> reference = %ld\n"
-                  "       overshoot = %ld\n",
-                  *blue_ref, *blue_shoot ));
+      FT_TRACE5(( "    -> reference = %ld\n", *blue_ref ));
+      FT_TRACE5(( "       overshoot = %ld\n", *blue_shoot ));
 
     } /* end for loop */
 
@@ -657,7 +650,7 @@
       af_cjk_metrics_check_digits( metrics, face );
     }
 
-    FT_Set_Charmap( face, oldmap );
+    face->charmap = oldmap;
     return FT_Err_Ok;
   }
 
@@ -728,7 +721,7 @@
 
         delta2 = FT_MulFix( delta2, scale );
 
-        FT_TRACE5(( "delta: %d", delta1 ));
+        FT_TRACE5(( "delta: %ld", delta1 ));
         if ( delta2 < 32 )
           delta2 = 0;
 #if 0
@@ -737,20 +730,22 @@
 #endif
         else
           delta2 = FT_PIX_ROUND( delta2 );
-        FT_TRACE5(( "/%d\n", delta2 ));
+        FT_TRACE5(( "/%ld\n", delta2 ));
 
         if ( delta1 < 0 )
           delta2 = -delta2;
 
         blue->shoot.fit = blue->ref.fit - delta2;
 
-        FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n"
-                    "     ref:   cur=%.2f fit=%.2f\n"
-                    "     shoot: cur=%.2f fit=%.2f\n",
+        FT_TRACE5(( ">> active cjk blue zone %c%d[%ld/%ld]:\n",
                     ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V',
-                    nn, blue->ref.org, blue->shoot.org,
-                    blue->ref.cur / 64.0, blue->ref.fit / 64.0,
-                    blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 ));
+                    nn, blue->ref.org, blue->shoot.org ));
+        FT_TRACE5(( "     ref:   cur=%.2f fit=%.2f\n",
+                    (double)blue->ref.cur / 64,
+                    (double)blue->ref.fit / 64 ));
+        FT_TRACE5(( "     shoot: cur=%.2f fit=%.2f\n",
+                    (double)blue->shoot.cur / 64,
+                    (double)blue->shoot.fit / 64 ));
 
         blue->flags |= AF_CJK_BLUE_ACTIVE;
       }
@@ -806,7 +801,7 @@
   {
     AF_AxisHints  axis          = &hints->axis[dim];
     AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
+    AF_Segment    segment_limit = FT_OFFSET( segments, axis->num_segments );
     FT_Error      error;
     AF_Segment    seg;
 
@@ -850,7 +845,7 @@
   {
     AF_AxisHints  axis          = &hints->axis[dim];
     AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
+    AF_Segment    segment_limit = FT_OFFSET( segments, axis->num_segments );
     AF_Direction  major_dir     = axis->major_dir;
     AF_Segment    seg1, seg2;
     FT_Pos        len_threshold;
@@ -1012,7 +1007,7 @@
     AF_CJKAxis    laxis  = &((AF_CJKMetrics)hints->metrics)->axis[dim];
 
     AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
+    AF_Segment    segment_limit = FT_OFFSET( segments, axis->num_segments );
     AF_Segment    seg;
 
     FT_Fixed      scale;
@@ -1051,7 +1046,7 @@
     {
       AF_Edge  found = NULL;
       FT_Pos   best  = 0xFFFFU;
-      FT_Int   ee;
+      FT_UInt  ee;
 
 
       /* look for an edge corresponding to the segment */
@@ -1160,7 +1155,7 @@
      */
     {
       AF_Edge  edges      = axis->edges;
-      AF_Edge  edge_limit = edges + axis->num_edges;
+      AF_Edge  edge_limit = FT_OFFSET( edges, axis->num_edges );
       AF_Edge  edge;
 
 
@@ -1184,6 +1179,8 @@
 
 
         seg = edge->first;
+        if ( !seg )
+          goto Skip_Loop;
 
         do
         {
@@ -1198,7 +1195,7 @@
 
           /* check for links -- if seg->serif is set, then seg->link must */
           /* be ignored                                                   */
-          is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
+          is_serif = FT_BOOL( seg->serif && seg->serif->edge != edge );
 
           if ( seg->link || is_serif )
           {
@@ -1239,13 +1236,14 @@
               edge2->flags |= AF_EDGE_SERIF;
             }
             else
-              edge->link  = edge2;
+              edge->link = edge2;
           }
 
           seg = seg->edge_next;
 
         } while ( seg != edge->first );
 
+      Skip_Loop:
         /* set the round/straight flags */
         edge->flags = AF_EDGE_NORMAL;
 
@@ -1295,7 +1293,7 @@
   {
     AF_AxisHints  axis       = &hints->axis[dim];
     AF_Edge       edge       = axis->edges;
-    AF_Edge       edge_limit = edge + axis->num_edges;
+    AF_Edge       edge_limit = FT_OFFSET( edge, axis->num_edges );
     AF_CJKAxis    cjk        = &metrics->axis[dim];
     FT_Fixed      scale      = cjk->scale;
     FT_Pos        best_dist0;  /* initial threshold */
@@ -1399,11 +1397,6 @@
     /* compute flags depending on render mode, etc. */
     mode = metrics->root.scaler.render_mode;
 
-#if 0 /* AF_CONFIG_OPTION_USE_WARPER */
-    if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
-      metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
-#endif
-
     scaler_flags = hints->scaler_flags;
     other_flags  = 0;
 
@@ -1432,12 +1425,6 @@
 
     scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE;
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    /* get (global) warper flag */
-    if ( !metrics->root.globals->module->warping )
-      scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
-#endif
-
     hints->scaler_flags = scaler_flags;
     hints->other_flags  = other_flags;
 
@@ -1641,11 +1628,13 @@
 
     stem_edge->pos = base_edge->pos + fitted_width;
 
-    FT_TRACE5(( "  CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f,"
+    FT_TRACE5(( "  CJKLINK: edge %ld @%d (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
                 stem_edge - hints->axis[dim].edges, stem_edge->fpos,
-                stem_edge->opos / 64.0, stem_edge->pos / 64.0,
-                dist / 64.0, fitted_width / 64.0 ));
+                (double)stem_edge->opos / 64,
+                (double)stem_edge->pos / 64,
+                (double)dist / 64,
+                (double)fitted_width / 64 ));
   }
 
 
@@ -1813,7 +1802,7 @@
   {
     AF_AxisHints  axis       = &hints->axis[dim];
     AF_Edge       edges      = axis->edges;
-    AF_Edge       edge_limit = edges + axis->num_edges;
+    AF_Edge       edge_limit = FT_OFFSET( edges, axis->num_edges );
     FT_PtrDist    n_edges;
     AF_Edge       edge;
     AF_Edge       anchor   = NULL;
@@ -1863,10 +1852,10 @@
           continue;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
-        FT_TRACE5(( "  CJKBLUE: edge %d @%d (opos=%.2f) snapped to %.2f,"
+        FT_TRACE5(( "  CJKBLUE: edge %ld @%d (opos=%.2f) snapped to %.2f,"
                     " was %.2f\n",
-                    edge1 - edges, edge1->fpos, edge1->opos / 64.0,
-                    blue->fit / 64.0, edge1->pos / 64.0 ));
+                    edge1 - edges, edge1->fpos, (double)edge1->opos / 64,
+                    (double)blue->fit / 64, (double)edge1->pos / 64 ));
 
         num_actions++;
 #endif
@@ -1927,7 +1916,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
+        FT_TRACE5(( "ASSERTION FAILED for edge %ld\n", edge2-edges ));
 
         af_cjk_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -2039,8 +2028,8 @@
 #if 0
       printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n",
                edge - edges, edge2 - edges,
-               ( edge->pos - edge->opos ) / 64.0,
-               ( edge2->pos - edge2->opos ) / 64.0 );
+               (double)( edge->pos - edge->opos ) / 64,
+               (double)( edge2->pos - edge2->opos ) / 64 );
 #endif
 
       anchor = edge;
@@ -2192,7 +2181,7 @@
   {
     AF_AxisHints  axis       = & hints->axis[dim];
     AF_Edge       edges      = axis->edges;
-    AF_Edge       edge_limit = edges + axis->num_edges;
+    AF_Edge       edge_limit = FT_OFFSET( edges, axis->num_edges );
     AF_Edge       edge;
     FT_Bool       snapping;
 
@@ -2320,25 +2309,6 @@
       if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
            ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
       {
-
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-        if ( dim == AF_DIMENSION_HORZ                                  &&
-             metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
-             AF_HINTS_DO_WARP( hints )                                 )
-        {
-          AF_WarperRec  warper;
-          FT_Fixed      scale;
-          FT_Pos        delta;
-
-
-          af_warper_compute( &warper, hints, (AF_Dimension)dim,
-                             &scale, &delta );
-          af_glyph_hints_scale_dim( hints, (AF_Dimension)dim,
-                                    scale, delta );
-          continue;
-        }
-#endif /* AF_CONFIG_OPTION_USE_WARPER */
-
         af_cjk_hint_edges( hints, (AF_Dimension)dim );
         af_cjk_align_edge_points( hints, (AF_Dimension)dim );
         af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index 707271b..bd7b81b 100644
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter hinting routines for CJK writing system (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/afcover.h b/src/autofit/afcover.h
index 47f3e47..102ed42 100644
--- a/src/autofit/afcover.h
+++ b/src/autofit/afcover.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter coverages (specification only).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c
index abd9509..a4629b5 100644
--- a/src/autofit/afdummy.c
+++ b/src/autofit/afdummy.c
@@ -5,7 +5,7 @@
  *   Auto-fitter dummy routines to be used if no hinting should be
  *   performed (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -38,13 +38,15 @@
 
 
   static FT_Error
-  af_dummy_hints_apply( FT_UInt        glyph_index,
-                        AF_GlyphHints  hints,
-                        FT_Outline*    outline )
+  af_dummy_hints_apply( FT_UInt          glyph_index,
+                        AF_GlyphHints    hints,
+                        FT_Outline*      outline,
+                        AF_StyleMetrics  metrics )
   {
     FT_Error  error;
 
     FT_UNUSED( glyph_index );
+    FT_UNUSED( metrics );
 
 
     error = af_glyph_hints_reload( hints, outline );
diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h
index e01c49c..a7af3f6 100644
--- a/src/autofit/afdummy.h
+++ b/src/autofit/afdummy.h
@@ -5,7 +5,7 @@
  *   Auto-fitter dummy routines to be used if no hinting should be
  *   performed (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/aferrors.h b/src/autofit/aferrors.h
index 56e00cc..88faf05 100644
--- a/src/autofit/aferrors.h
+++ b/src/autofit/aferrors.h
@@ -4,7 +4,7 @@
  *
  *   Autofitter error codes (specification only).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef AFERRORS_H_
 #define AFERRORS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  AF_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Autofit
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* AFERRORS_H_ */
 
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index 9e7764b..ede27eb 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter routines to compute global hinting values (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,8 @@
 #include "afglobal.h"
 #include "afranges.h"
 #include "afshaper.h"
-#include FT_INTERNAL_DEBUG_H
+#include "afws-decl.h"
+#include <freetype/internal/ftdebug.h>
 
 
   /**************************************************************************
@@ -29,14 +30,9 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_afglobal
+#define FT_COMPONENT  afglobal
 
 
-  /* get writing system specific header files */
-#undef  WRITING_SYSTEM
-#define WRITING_SYSTEM( ws, WS )  /* empty */
-#include "afwrtsys.h"
-
 #include "aferrors.h"
 
 
@@ -74,7 +70,7 @@
   af_writing_system_classes[] =
   {
 
-#include "afwrtsys.h"
+#include "afws-iter.h"
 
     NULL  /* do not remove */
   };
@@ -133,13 +129,13 @@
     FT_Face     face        = globals->face;
     FT_CharMap  old_charmap = face->charmap;
     FT_UShort*  gstyles     = globals->glyph_styles;
-    FT_UInt     ss;
+    FT_UShort   ss;
+    FT_UShort   dflt        = 0xFFFFU; /* a non-valid value */
     FT_UInt     i;
-    FT_UInt     dflt        = ~0U; /* a non-valid value */
 
 
     /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */
-    for ( i = 0; i < (FT_UInt)globals->glyph_count; i++ )
+    for ( i = 0; i < globals->glyph_count; i++ )
       gstyles[i] = AF_STYLE_UNASSIGNED;
 
     error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
@@ -172,8 +168,7 @@
        */
       if ( style_class->coverage == AF_COVERAGE_DEFAULT )
       {
-        if ( (FT_UInt)style_class->script ==
-             globals->module->default_script )
+        if ( style_class->script == globals->module->default_script )
           dflt = ss;
 
         for ( range = script_class->script_uni_ranges;
@@ -187,9 +182,9 @@
           gindex = FT_Get_Char_Index( face, charcode );
 
           if ( gindex != 0                                                &&
-               gindex < (FT_ULong)globals->glyph_count                    &&
+               gindex < globals->glyph_count                              &&
                ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED )
-            gstyles[gindex] = (FT_UShort)ss;
+            gstyles[gindex] = ss;
 
           for (;;)
           {
@@ -198,9 +193,9 @@
             if ( gindex == 0 || charcode > range->last )
               break;
 
-            if ( gindex < (FT_ULong)globals->glyph_count                    &&
+            if ( gindex < globals->glyph_count                              &&
                  ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED )
-              gstyles[gindex] = (FT_UShort)ss;
+              gstyles[gindex] = ss;
           }
         }
 
@@ -215,9 +210,9 @@
 
           gindex = FT_Get_Char_Index( face, charcode );
 
-          if ( gindex != 0                                          &&
-               gindex < (FT_ULong)globals->glyph_count              &&
-               ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss )
+          if ( gindex != 0                               &&
+               gindex < globals->glyph_count             &&
+               ( gstyles[gindex] & AF_STYLE_MASK ) == ss )
             gstyles[gindex] |= AF_NONBASE;
 
           for (;;)
@@ -227,8 +222,8 @@
             if ( gindex == 0 || charcode > range->last )
               break;
 
-            if ( gindex < (FT_ULong)globals->glyph_count              &&
-                 ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss )
+            if ( gindex < globals->glyph_count             &&
+                 ( gstyles[gindex] & AF_STYLE_MASK ) == ss )
               gstyles[gindex] |= AF_NONBASE;
           }
         }
@@ -259,7 +254,7 @@
       FT_UInt  gindex = FT_Get_Char_Index( face, i );
 
 
-      if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count )
+      if ( gindex != 0 && gindex < globals->glyph_count )
         gstyles[gindex] |= AF_DIGIT;
     }
 
@@ -270,7 +265,7 @@
      */
     if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED )
     {
-      FT_Long  nn;
+      FT_UInt  nn;
 
 
       for ( nn = 0; nn < globals->glyph_count; nn++ )
@@ -285,16 +280,16 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-    FT_TRACE4(( "\n"
-                "style coverage\n"
-                "==============\n"
-                "\n" ));
+    FT_TRACE4(( "\n" ));
+    FT_TRACE4(( "style coverage\n" ));
+    FT_TRACE4(( "==============\n" ));
+    FT_TRACE4(( "\n" ));
 
     for ( ss = 0; af_style_classes[ss]; ss++ )
     {
       AF_StyleClass  style_class = af_style_classes[ss];
       FT_UInt        count       = 0;
-      FT_Long        idx;
+      FT_UInt        idx;
 
 
       FT_TRACE4(( "%s:\n", af_style_names[style_class->style] ));
@@ -322,7 +317,7 @@
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
-    FT_Set_Charmap( face, old_charmap );
+    face->charmap = old_charmap;
     return error;
   }
 
@@ -341,13 +336,15 @@
 
     /* we allocate an AF_FaceGlobals structure together */
     /* with the glyph_styles array                      */
-    if ( FT_ALLOC( globals,
-                   sizeof ( *globals ) +
-                     (FT_ULong)face->num_glyphs * sizeof ( FT_UShort ) ) )
+    if ( FT_QALLOC( globals,
+                    sizeof ( *globals ) +
+                      (FT_ULong)face->num_glyphs * sizeof ( FT_UShort ) ) )
       goto Exit;
 
+    FT_ZERO( &globals->metrics );
+
     globals->face                      = face;
-    globals->glyph_count               = face->num_glyphs;
+    globals->glyph_count               = (FT_UInt)face->num_glyphs;
     /* right after the globals structure come the glyph styles */
     globals->glyph_styles              = (FT_UShort*)( globals + 1 );
     globals->module                    = module;
@@ -359,7 +356,7 @@
     globals->scale_down_factor         = 0;
 
 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
-    globals->hb_font = hb_ft_font_create( face, NULL );
+    globals->hb_font = hb_ft_font_create_( face, NULL );
     globals->hb_buf  = hb_buffer_create();
 #endif
 
@@ -431,7 +428,7 @@
     FT_Error  error = FT_Err_Ok;
 
 
-    if ( gindex >= (FT_ULong)globals->glyph_count )
+    if ( gindex >= globals->glyph_count )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
@@ -443,6 +440,7 @@
       style = (AF_Style)( globals->glyph_styles[gindex] &
                           AF_STYLE_UNASSIGNED           );
 
+  Again:
     style_class          = af_style_classes[style];
     writing_system_class = af_writing_system_classes
                              [style_class->writing_system];
@@ -470,6 +468,20 @@
             writing_system_class->style_metrics_done( metrics );
 
           FT_FREE( metrics );
+
+          /* internal error code -1 indicates   */
+          /* that no blue zones have been found */
+          if ( error == -1 )
+          {
+            style = (AF_Style)( globals->glyph_styles[gindex] &
+                                AF_STYLE_UNASSIGNED           );
+            /* IMPORTANT: Clear the error code, see
+             * https://gitlab.freedesktop.org/freetype/freetype/-/issues/1063
+             */
+            error = FT_Err_Ok;
+            goto Again;
+          }
+
           goto Exit;
         }
       }
@@ -488,10 +500,10 @@
   af_face_globals_is_digit( AF_FaceGlobals  globals,
                             FT_UInt         gindex )
   {
-    if ( gindex < (FT_ULong)globals->glyph_count )
-      return (FT_Bool)( globals->glyph_styles[gindex] & AF_DIGIT );
+    if ( gindex < globals->glyph_count )
+      return FT_BOOL( globals->glyph_styles[gindex] & AF_DIGIT );
 
-    return (FT_Bool)0;
+    return FT_BOOL( 0 );
   }
 
 
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index e26ea2f..83a7c2f 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
  *   Auto-fitter routines to compute global hinting values
  *   (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -105,7 +105,7 @@
   typedef struct  AF_FaceGlobalsRec_
   {
     FT_Face          face;
-    FT_Long          glyph_count;    /* same as face->num_glyphs */
+    FT_UInt          glyph_count;    /* unsigned face->num_glyphs */
     FT_UShort*       glyph_styles;
 
 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
@@ -158,7 +158,7 @@
   FT_LOCAL( void )
   af_face_globals_free( AF_FaceGlobals  globals );
 
-  FT_LOCAL_DEF( FT_Bool )
+  FT_LOCAL( FT_Bool )
   af_face_globals_is_digit( AF_FaceGlobals  globals,
                             FT_UInt         gindex );
 
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 65f0e85..6515af9 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter hinting routines (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,8 +18,8 @@
 
 #include "afhints.h"
 #include "aferrors.h"
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
 
 
   /**************************************************************************
@@ -29,9 +29,107 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_afhints
+#define FT_COMPONENT  afhints
 
 
+  FT_LOCAL_DEF( void )
+  af_sort_pos( FT_UInt  count,
+               FT_Pos*  table )
+  {
+    FT_UInt  i, j;
+    FT_Pos   swap;
+
+
+    for ( i = 1; i < count; i++ )
+    {
+      for ( j = i; j > 0; j-- )
+      {
+        if ( table[j] >= table[j - 1] )
+          break;
+
+        swap         = table[j];
+        table[j]     = table[j - 1];
+        table[j - 1] = swap;
+      }
+    }
+  }
+
+
+  FT_LOCAL_DEF( void )
+  af_sort_and_quantize_widths( FT_UInt*  count,
+                               AF_Width  table,
+                               FT_Pos    threshold )
+  {
+    FT_UInt      i, j;
+    FT_UInt      cur_idx;
+    FT_Pos       cur_val;
+    FT_Pos       sum;
+    AF_WidthRec  swap;
+
+
+    if ( *count == 1 )
+      return;
+
+    /* sort */
+    for ( i = 1; i < *count; i++ )
+    {
+      for ( j = i; j > 0; j-- )
+      {
+        if ( table[j].org >= table[j - 1].org )
+          break;
+
+        swap         = table[j];
+        table[j]     = table[j - 1];
+        table[j - 1] = swap;
+      }
+    }
+
+    cur_idx = 0;
+    cur_val = table[cur_idx].org;
+
+    /* compute and use mean values for clusters not larger than  */
+    /* `threshold'; this is very primitive and might not yield   */
+    /* the best result, but normally, using reference character  */
+    /* `o', `*count' is 2, so the code below is fully sufficient */
+    for ( i = 1; i < *count; i++ )
+    {
+      if ( table[i].org - cur_val > threshold ||
+           i == *count - 1                    )
+      {
+        sum = 0;
+
+        /* fix loop for end of array */
+        if ( table[i].org - cur_val <= threshold &&
+             i == *count - 1                     )
+          i++;
+
+        for ( j = cur_idx; j < i; j++ )
+        {
+          sum         += table[j].org;
+          table[j].org = 0;
+        }
+        table[cur_idx].org = sum / (FT_Pos)j;
+
+        if ( i < *count - 1 )
+        {
+          cur_idx = i + 1;
+          cur_val = table[cur_idx].org;
+        }
+      }
+    }
+
+    cur_idx = 1;
+
+    /* compress array to remove zero values */
+    for ( i = 1; i < *count; i++ )
+    {
+      if ( table[i].org )
+        table[cur_idx++] = table[i];
+    }
+
+    *count = cur_idx;
+  }
+
   /* Get new segment for given axis. */
 
   FT_LOCAL_DEF( FT_Error )
@@ -53,9 +151,9 @@
     }
     else if ( axis->num_segments >= axis->max_segments )
     {
-      FT_Int  old_max = axis->max_segments;
-      FT_Int  new_max = old_max;
-      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );
+      FT_UInt  old_max = axis->max_segments;
+      FT_UInt  new_max = old_max;
+      FT_UInt  big_max = FT_INT_MAX / sizeof ( *segment );
 
 
       if ( old_max >= big_max )
@@ -95,7 +193,7 @@
   /* Get new edge for given axis, direction, and position, */
   /* without initializing the edge itself.                 */
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL_DEF( FT_Error )
   af_axis_hints_new_edge( AF_AxisHints  axis,
                           FT_Int        fpos,
                           AF_Direction  dir,
@@ -118,9 +216,9 @@
     }
     else if ( axis->num_edges >= axis->max_edges )
     {
-      FT_Int  old_max = axis->max_edges;
-      FT_Int  new_max = old_max;
-      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );
+      FT_UInt  old_max = axis->max_edges;
+      FT_UInt  new_max = old_max;
+      FT_UInt  big_max = FT_INT_MAX / sizeof ( *edge );
 
 
       if ( old_max >= big_max )
@@ -297,6 +395,19 @@
   }
 
 
+  static int
+  af_get_strong_edge_index( AF_GlyphHints  hints,
+                            AF_Edge*       strong_edges,
+                            int            dimension )
+  {
+    AF_AxisHints  axis  = &hints->axis[dimension];
+    AF_Edge       edges = axis->edges;
+
+
+    return AF_INDEX_NUM( strong_edges[dimension], edges );
+  }
+
+
 #ifdef __cplusplus
   extern "C" {
 #endif
@@ -317,8 +428,10 @@
     {
       AF_DUMP(( "  index  hedge  hseg  vedge  vseg  flags "
              /* "  XXXXX  XXXXX XXXXX  XXXXX XXXXX  XXXXXX" */
-                "  xorg  yorg  xscale  yscale   xfit    yfit" ));
+                "  xorg  yorg  xscale  yscale   xfit    yfit "
              /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */
+                "  hbef  haft  vbef  vaft" ));
+             /* " XXXXX XXXXX XXXXX XXXXX" */
     }
     else
       AF_DUMP(( "  (none)\n" ));
@@ -330,6 +443,7 @@
       int  segment_idx_1 = af_get_segment_index( hints, point_idx, 1 );
 
       char  buf1[16], buf2[16], buf3[16], buf4[16];
+      char  buf5[16], buf6[16], buf7[16], buf8[16];
 
 
       /* insert extra newline at the beginning of a contour */
@@ -340,7 +454,8 @@
       }
 
       AF_DUMP(( "  %5d  %5s %5s  %5s %5s  %s"
-                " %5d %5d %7.2f %7.2f %7.2f %7.2f\n",
+                " %5d %5d %7.2f %7.2f %7.2f %7.2f"
+                " %5s %5s %5s %5s\n",
                 point_idx,
                 af_print_idx( buf1,
                               af_get_edge_index( hints, segment_idx_1, 1 ) ),
@@ -356,10 +471,23 @@
 
                 point->fx,
                 point->fy,
-                point->ox / 64.0,
-                point->oy / 64.0,
-                point->x / 64.0,
-                point->y / 64.0 ));
+                (double)point->ox / 64,
+                (double)point->oy / 64,
+                (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_DUMP(( "\n" ));
   }
@@ -469,7 +597,7 @@
   FT_Error
   af_glyph_hints_get_num_segments( AF_GlyphHints  hints,
                                    FT_Int         dimension,
-                                   FT_Int*        num_segments )
+                                   FT_UInt*       num_segments )
   {
     AF_Dimension  dim;
     AF_AxisHints  axis;
@@ -495,7 +623,7 @@
   FT_Error
   af_glyph_hints_get_segment_offset( AF_GlyphHints  hints,
                                      FT_Int         dimension,
-                                     FT_Int         idx,
+                                     FT_UInt        idx,
                                      FT_Pos        *offset,
                                      FT_Bool       *is_blue,
                                      FT_Pos        *blue_offset )
@@ -512,14 +640,14 @@
 
     axis = &hints->axis[dim];
 
-    if ( idx < 0 || idx >= axis->num_segments )
+    if ( idx >= axis->num_segments )
       return FT_THROW( Invalid_Argument );
 
     seg      = &axis->segments[idx];
     *offset  = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx
                                             : seg->first->fy;
     if ( seg->edge )
-      *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 );
+      *is_blue = FT_BOOL( seg->edge->blue_edge );
     else
       *is_blue = FALSE;
 
@@ -564,13 +692,13 @@
       if ( dimension == AF_DIMENSION_HORZ )
         AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
                   "vertical",
-                  65536.0 * 64.0 / hints->x_scale,
-                  10.0 * hints->x_scale / 65536.0 / 64.0 ));
+                  65536 * 64 / (double)hints->x_scale,
+                  10 * (double)hints->x_scale / 65536 / 64 ));
       else
         AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
                   "horizontal",
-                  65536.0 * 64.0 / hints->y_scale,
-                  10.0 * hints->y_scale / 65536.0 / 64.0 ));
+                  65536 * 64 / (double)hints->y_scale,
+                  10 * (double)hints->y_scale / 65536 / 64 ));
 
       if ( axis->num_edges )
       {
@@ -586,14 +714,14 @@
         AF_DUMP(( "  %5d  %7.2f  %5s  %4s  %5s"
                   "    %c   %7.2f  %7.2f  %11s\n",
                   AF_INDEX_NUM( edge, edges ),
-                  (int)edge->opos / 64.0,
+                  (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 ) ),
 
                   edge->blue_edge ? 'y' : 'n',
-                  edge->opos / 64.0,
-                  edge->pos / 64.0,
+                  (double)edge->opos / 64,
+                  (double)edge->pos / 64,
                   af_edge_flags_to_string( edge->flags ) ));
       AF_DUMP(( "\n" ));
     }
@@ -734,7 +862,7 @@
   {
     FT_Error   error   = FT_Err_Ok;
     AF_Point   points;
-    FT_UInt    old_max, new_max;
+    FT_Int     old_max, new_max;
     FT_Fixed   x_scale = hints->x_scale;
     FT_Fixed   y_scale = hints->y_scale;
     FT_Pos     x_delta = hints->x_delta;
@@ -751,8 +879,8 @@
     hints->axis[1].num_edges    = 0;
 
     /* first of all, reallocate the contours array if necessary */
-    new_max = (FT_UInt)outline->n_contours;
-    old_max = (FT_UInt)hints->max_contours;
+    new_max = outline->n_contours;
+    old_max = hints->max_contours;
 
     if ( new_max <= AF_CONTOURS_EMBEDDED )
     {
@@ -767,12 +895,12 @@
       if ( hints->contours == hints->embedded.contours )
         hints->contours = NULL;
 
-      new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */
+      new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */
 
       if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
         goto Exit;
 
-      hints->max_contours = (FT_Int)new_max;
+      hints->max_contours = new_max;
     }
 
     /*
@@ -780,8 +908,8 @@
      * note that we reserve two additional point positions, used to
      * hint metrics appropriately
      */
-    new_max = (FT_UInt)( outline->n_points + 2 );
-    old_max = (FT_UInt)hints->max_points;
+    new_max = outline->n_points + 2;
+    old_max = hints->max_points;
 
     if ( new_max <= AF_POINTS_EMBEDDED )
     {
@@ -796,12 +924,12 @@
       if ( hints->points == hints->embedded.points )
         hints->points = NULL;
 
-      new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */
+      new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */
 
       if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
         goto Exit;
 
-      hints->max_points = (FT_Int)new_max;
+      hints->max_points = new_max;
     }
 
     hints->num_points   = outline->n_points;
@@ -825,9 +953,6 @@
     hints->x_delta = x_delta;
     hints->y_delta = y_delta;
 
-    hints->xmin_delta = 0;
-    hints->xmax_delta = 0;
-
     points = hints->points;
     if ( hints->num_points == 0 )
       goto Exit;
@@ -898,6 +1023,14 @@
               prev     = end;
             }
           }
+
+#ifdef FT_DEBUG_AUTOFIT
+          point->before[0] = NULL;
+          point->before[1] = NULL;
+          point->after[0]  = NULL;
+          point->after[1]  = NULL;
+#endif
+
         }
       }
 
@@ -1183,7 +1316,7 @@
   {
     AF_AxisHints  axis          = & hints->axis[dim];
     AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
+    AF_Segment    segment_limit = FT_OFFSET( segments, axis->num_segments );
     AF_Segment    seg;
 
 
@@ -1260,7 +1393,7 @@
     AF_Point      point_limit = points + hints->num_points;
     AF_AxisHints  axis        = &hints->axis[dim];
     AF_Edge       edges       = axis->edges;
-    AF_Edge       edge_limit  = edges + axis->num_edges;
+    AF_Edge       edge_limit  = FT_OFFSET( edges, axis->num_edges );
     FT_UInt       touch_flag;
 
 
@@ -1309,6 +1442,12 @@
         if ( delta >= 0 )
         {
           u = edge->pos - ( edge->opos - ou );
+
+#ifdef FT_DEBUG_AUTOFIT
+          point->before[dim] = edge;
+          point->after[dim]  = NULL;
+#endif
+
           goto Store_Point;
         }
 
@@ -1318,6 +1457,12 @@
         if ( delta >= 0 )
         {
           u = edge->pos + ( ou - edge->opos );
+
+#ifdef FT_DEBUG_AUTOFIT
+          point->before[dim] = NULL;
+          point->after[dim]  = edge;
+#endif
+
           goto Store_Point;
         }
 
@@ -1364,6 +1509,12 @@
             {
               /* we are on the edge */
               u = edge->pos;
+
+#ifdef FT_DEBUG_AUTOFIT
+              point->before[dim] = NULL;
+              point->after[dim]  = NULL;
+#endif
+
               goto Store_Point;
             }
           }
@@ -1374,6 +1525,11 @@
             AF_Edge  after  = edges + min + 0;
 
 
+#ifdef FT_DEBUG_AUTOFIT
+            point->before[dim] = before;
+            point->after[dim]  = after;
+#endif
+
             /* assert( before && after && before != after ) */
             if ( before->scale == 0 )
               before->scale = FT_DivFix( after->pos - before->pos,
@@ -1627,33 +1783,4 @@
   }
 
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-
-  /* Apply (small) warp scale and warp delta for given dimension. */
-
-  FT_LOCAL_DEF( void )
-  af_glyph_hints_scale_dim( AF_GlyphHints  hints,
-                            AF_Dimension   dim,
-                            FT_Fixed       scale,
-                            FT_Pos         delta )
-  {
-    AF_Point  points       = hints->points;
-    AF_Point  points_limit = points + hints->num_points;
-    AF_Point  point;
-
-
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      for ( point = points; point < points_limit; point++ )
-        point->x = FT_MulFix( point->fx, scale ) + delta;
-    }
-    else
-    {
-      for ( point = points; point < points_limit; point++ )
-        point->y = FT_MulFix( point->fy, scale ) + delta;
-    }
-  }
-
-#endif /* AF_CONFIG_OPTION_USE_WARPER */
-
 /* END */
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index aee9d46..d1cf952 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter hinting routines (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,8 +21,6 @@
 
 #include "aftypes.h"
 
-#define xxAF_SORT_SEGMENTS
-
 FT_BEGIN_HEADER
 
   /*
@@ -252,6 +250,12 @@
     AF_Point   next;     /* next point in contour     */
     AF_Point   prev;     /* previous point in contour */
 
+#ifdef FT_DEBUG_AUTOFIT
+    /* track `before' and `after' edges for strong points */
+    AF_Edge    before[2];
+    AF_Edge    after[2];
+#endif
+
   } AF_PointRec;
 
 
@@ -304,15 +308,12 @@
 
   typedef struct  AF_AxisHintsRec_
   {
-    FT_Int        num_segments; /* number of used segments      */
-    FT_Int        max_segments; /* number of allocated segments */
+    FT_UInt       num_segments; /* number of used segments      */
+    FT_UInt       max_segments; /* number of allocated segments */
     AF_Segment    segments;     /* segments array               */
-#ifdef AF_SORT_SEGMENTS
-    FT_Int        mid_segments;
-#endif
 
-    FT_Int        num_edges;    /* number of used edges      */
-    FT_Int        max_edges;    /* number of allocated edges */
+    FT_UInt       num_edges;    /* number of used edges      */
+    FT_UInt       max_edges;    /* number of allocated edges */
     AF_Edge       edges;        /* edges array               */
 
     AF_Direction  major_dir;    /* either vertical or horizontal */
@@ -356,9 +357,6 @@
                                     /* implementations         */
     AF_StyleMetrics  metrics;
 
-    FT_Pos           xmin_delta;    /* used for warping */
-    FT_Pos           xmax_delta;
-
     /* Two arrays to avoid allocation penalty.            */
     /* The `embedded' structure must be the last element! */
     struct
@@ -377,14 +375,14 @@
 #ifdef FT_DEBUG_AUTOFIT
 
 #define AF_HINTS_DO_HORIZONTAL( h )                                     \
-          ( !_af_debug_disable_horz_hints                            && \
+          ( !af_debug_disable_horz_hints_                            && \
             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
 
 #define AF_HINTS_DO_VERTICAL( h )                                     \
-          ( !_af_debug_disable_vert_hints                          && \
+          ( !af_debug_disable_vert_hints_                          && \
             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
 
-#define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
+#define AF_HINTS_DO_BLUES( h )  ( !af_debug_disable_blue_hints_ )
 
 #else /* !FT_DEBUG_AUTOFIT */
 
@@ -402,10 +400,6 @@
 #define AF_HINTS_DO_ADVANCE( h )                                \
           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
 
-#define AF_HINTS_DO_WARP( h )                                  \
-          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_WARPER )
-
-
 
   FT_LOCAL( AF_Direction )
   af_direction_compute( FT_Pos  dx,
@@ -453,14 +447,6 @@
   af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
                                     AF_Dimension   dim );
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-  FT_LOCAL( void )
-  af_glyph_hints_scale_dim( AF_GlyphHints  hints,
-                            AF_Dimension   dim,
-                            FT_Fixed       scale,
-                            FT_Pos         delta );
-#endif
-
   FT_LOCAL( void )
   af_glyph_hints_done( AF_GlyphHints  hints );
 
diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c
index 45c1a10..289a09d 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter hinting routines for Indic writing system (body).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -27,11 +27,6 @@
 #include "aferrors.h"
 
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-#include "afwarp.h"
-#endif
-
-
   static FT_Error
   af_indic_metrics_init( AF_CJKMetrics  metrics,
                          FT_Face        face )
@@ -54,8 +49,7 @@
       af_cjk_metrics_check_digits( metrics, face );
     }
 
-    FT_Set_Charmap( face, oldmap );
-
+    face->charmap = oldmap;
     return FT_Err_Ok;
   }
 
diff --git a/src/autofit/afindic.h b/src/autofit/afindic.h
index 94ff764..3eb67f6 100644
--- a/src/autofit/afindic.h
+++ b/src/autofit/afindic.h
@@ -5,7 +5,7 @@
  *   Auto-fitter hinting routines for Indic writing system
  *   (specification).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index a90fc1c..4b3c59b 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter hinting routines for latin writing system (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,20 +16,14 @@
  */
 
 
-#include <ft2build.h>
-#include FT_ADVANCES_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/ftadvanc.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "afglobal.h"
 #include "aflatin.h"
 #include "aferrors.h"
 
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-#include "afwarp.h"
-#endif
-
-
   /**************************************************************************
    *
    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
@@ -37,7 +31,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_aflatin
+#define FT_COMPONENT  aflatin
 
 
   /* needed for computation of round vs. flat segments */
@@ -64,11 +58,11 @@
     AF_GlyphHintsRec  hints[1];
 
 
-    FT_TRACE5(( "\n"
-                "latin standard widths computation (style `%s')\n"
-                "=====================================================\n"
-                "\n",
+    FT_TRACE5(( "\n" ));
+    FT_TRACE5(( "latin standard widths computation (style `%s')\n",
                 af_style_names[metrics->root.style_class->style] ));
+    FT_TRACE5(( "=====================================================\n" ));
+    FT_TRACE5(( "\n" ));
 
     af_glyph_hints_init( hints, face->memory );
 
@@ -149,9 +143,13 @@
       af_shaper_buf_destroy( face, shaper_buf );
 
       if ( !glyph_index )
+      {
+        FT_TRACE5(( "standard character missing;"
+                    " using fallback stem widths\n" ));
         goto Exit;
+      }
 
-      FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
+      FT_TRACE5(( "standard character: U+%04lX (glyph index %ld)\n",
                   ch, glyph_index ));
 
       error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
@@ -202,7 +200,7 @@
                                       (AF_Dimension)dim );
 
         seg   = axhints->segments;
-        limit = seg + axhints->num_segments;
+        limit = FT_OFFSET( seg, axhints->num_segments );
 
         for ( ; seg < limit; seg++ )
         {
@@ -254,9 +252,9 @@
                       dim == AF_DIMENSION_VERT ? "horizontal"
                                                : "vertical" ));
 
-          FT_TRACE5(( "  %d (standard)", axis->standard_width ));
+          FT_TRACE5(( "  %ld (standard)", axis->standard_width ));
           for ( i = 1; i < axis->width_count; i++ )
-            FT_TRACE5(( " %d", axis->widths[i].org ));
+            FT_TRACE5(( " %ld", axis->widths[i].org ));
 
           FT_TRACE5(( "\n" ));
         }
@@ -312,7 +310,7 @@
   /* Find all blue zones.  Flat segments give the reference points, */
   /* round segments the overshoot positions.                        */
 
-  static void
+  static int
   af_latin_metrics_init_blues( AF_LatinMetrics  metrics,
                                FT_Face          face )
   {
@@ -347,9 +345,9 @@
     /* we walk over the blue character strings as specified in the */
     /* style's entry in the `af_blue_stringset' array              */
 
-    FT_TRACE5(( "latin blue zones computation\n"
-                "============================\n"
-                "\n" ));
+    FT_TRACE5(( "latin blue zones computation\n" ));
+    FT_TRACE5(( "============================\n" ));
+    FT_TRACE5(( "\n" ));
 
 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
     shaper_buf = af_shaper_buf_create( face );
@@ -973,18 +971,18 @@
       if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) )
         blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
 
-      FT_TRACE5(( "    -> reference = %ld\n"
-                  "       overshoot = %ld\n",
-                  *blue_ref, *blue_shoot ));
+      FT_TRACE5(( "    -> reference = %ld\n", *blue_ref ));
+      FT_TRACE5(( "       overshoot = %ld\n", *blue_shoot ));
 
     } /* end for loop */
 
     af_shaper_buf_destroy( face, shaper_buf );
 
-    /* we finally check whether blue zones are ordered; */
-    /* `ref' and `shoot' values of two blue zones must not overlap */
     if ( axis->blue_count )
     {
+      /* we finally check whether blue zones are ordered;            */
+      /* `ref' and `shoot' values of two blue zones must not overlap */
+
       FT_UInt       i;
       AF_LatinBlue  blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2];
 
@@ -1027,17 +1025,40 @@
         {
           *a = *b;
           FT_TRACE5(( "blue zone overlap:"
-                      " adjusting %s %d to %ld\n",
+                      " adjusting %s %ld to %ld\n",
                       a_is_top ? "overshoot" : "reference",
                       blue_sorted[i] - axis->blues,
                       *a ));
         }
       }
+
+      FT_TRACE5(( "\n" ));
+
+      return 0;
     }
+    else
+    {
+      /* disable hinting for the current style if there are no blue zones */
 
-    FT_TRACE5(( "\n" ));
+      AF_FaceGlobals  globals = metrics->root.globals;
+      FT_UShort*      gstyles = globals->glyph_styles;
 
-    return;
+      FT_UInt  i;
+
+
+      FT_TRACE5(( "no blue zones found:"
+                  " hinting disabled for this style\n" ));
+
+      for ( i = 0; i < globals->glyph_count; i++ )
+      {
+        if ( ( gstyles[i] & AF_STYLE_MASK ) == sc->style )
+          gstyles[i] = AF_STYLE_NONE_DFLT;
+      }
+
+      FT_TRACE5(( "\n" ));
+
+      return 1;
+    }
   }
 
 
@@ -1116,6 +1137,8 @@
   af_latin_metrics_init( AF_LatinMetrics  metrics,
                          FT_Face          face )
   {
+    FT_Error  error = FT_Err_Ok;
+
     FT_CharMap  oldmap = face->charmap;
 
 
@@ -1124,12 +1147,18 @@
     if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
     {
       af_latin_metrics_init_widths( metrics, face );
-      af_latin_metrics_init_blues( metrics, face );
+      if ( af_latin_metrics_init_blues( metrics, face ) )
+      {
+        /* use internal error code to indicate missing blue zones */
+        error = -1;
+        goto Exit;
+      }
       af_latin_metrics_check_digits( metrics, face );
     }
 
-    FT_Set_Charmap( face, oldmap );
-    return FT_Err_Ok;
+  Exit:
+    face->charmap = oldmap;
+    return error;
   }
 
 
@@ -1240,29 +1269,28 @@
 
             if ( dist == 0 )
             {
-              FT_TRACE5((
-                "af_latin_metrics_scale_dim:"
-                " x height alignment (style `%s'):\n"
-                "                           "
-                " vertical scaling changed from %.5f to %.5f (by %d%%)\n"
-                "\n",
-                af_style_names[metrics->root.style_class->style],
-                scale / 65536.0,
-                new_scale / 65536.0,
-                ( fitted - scaled ) * 100 / scaled ));
+              FT_TRACE5(( "af_latin_metrics_scale_dim:"
+                          " x height alignment (style `%s'):\n",
+                          af_style_names[metrics->root.style_class->style] ));
+              FT_TRACE5(( "                           "
+                          " vertical scaling changed"
+                          " from %.5f to %.5f (by %ld%%)\n",
+                          (double)scale / 65536,
+                          (double)new_scale / 65536,
+                          ( fitted - scaled ) * 100 / scaled ));
+              FT_TRACE5(( "\n" ));
 
               scale = new_scale;
             }
 #ifdef FT_DEBUG_LEVEL_TRACE
             else
             {
-              FT_TRACE5((
-                "af_latin_metrics_scale_dim:"
-                " x height alignment (style `%s'):\n"
-                "                           "
-                " excessive vertical scaling abandoned\n"
-                "\n",
-                af_style_names[metrics->root.style_class->style] ));
+              FT_TRACE5(( "af_latin_metrics_scale_dim:"
+                          " x height alignment (style `%s'):\n",
+                          af_style_names[metrics->root.style_class->style] ));
+              FT_TRACE5(( "                           "
+                          " excessive vertical scaling abandoned\n" ));
+              FT_TRACE5(( "\n" ));
             }
 #endif
           }
@@ -1297,9 +1325,9 @@
       width->cur = FT_MulFix( width->org, scale );
       width->fit = width->cur;
 
-      FT_TRACE5(( "  %d scaled to %.2f\n",
+      FT_TRACE5(( "  %ld scaled to %.2f\n",
                   width->org,
-                  width->cur / 64.0 ));
+                  (double)width->cur / 64 ));
     }
 
     FT_TRACE5(( "\n" ));
@@ -1307,13 +1335,15 @@
     /* an extra-light axis corresponds to a standard width that is */
     /* smaller than 5/8 pixels                                     */
     axis->extra_light =
-      (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
+      FT_BOOL( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( axis->extra_light )
-      FT_TRACE5(( "`%s' style is extra light (at current resolution)\n"
-                  "\n",
+    {
+      FT_TRACE5(( "`%s' style is extra light (at current resolution)\n",
                   af_style_names[metrics->root.style_class->style] ));
+      FT_TRACE5(( "\n" ));
+    }
 #endif
 
     if ( dim == AF_DIMENSION_VERT )
@@ -1438,18 +1468,18 @@
         AF_LatinBlue  blue = &axis->blues[nn];
 
 
-        FT_TRACE5(( "  reference %d: %d scaled to %.2f%s\n"
-                    "  overshoot %d: %d scaled to %.2f%s\n",
+        FT_TRACE5(( "  reference %d: %ld scaled to %.2f%s\n",
                     nn,
                     blue->ref.org,
-                    blue->ref.fit / 64.0,
-                    blue->flags & AF_LATIN_BLUE_ACTIVE ? ""
-                                                       : " (inactive)",
+                    (double)blue->ref.fit / 64,
+                    ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
+                                                           : " (inactive)" ));
+        FT_TRACE5(( "  overshoot %d: %ld scaled to %.2f%s\n",
                     nn,
                     blue->shoot.org,
-                    blue->shoot.fit / 64.0,
-                    blue->flags & AF_LATIN_BLUE_ACTIVE ? ""
-                                                       : " (inactive)" ));
+                    (double)blue->shoot.fit / 64,
+                    ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
+                                                           : " (inactive)" ));
       }
 #endif
     }
@@ -1812,6 +1842,31 @@
              ( FT_ABS( point->out_dir ) == major_dir ||
                point == point->prev                  ) )
         {
+          /*
+           * For efficiency, we restrict the number of segments to 1000,
+           * which is a heuristic value: it is very unlikely that a glyph
+           * with so many segments can be hinted in a sensible way.
+           * Reasons:
+           *
+           * - The glyph has really 1000 segments; this implies that it has
+           *   at least 2000 outline points.  Assuming 'normal' fonts that
+           *   have superfluous points optimized away, viewing such a glyph
+           *   only makes sense at large magnifications where hinting
+           *   isn't applied anyway.
+           *
+           * - We have a broken glyph.  Hinting doesn't make sense in this
+           *   case either.
+           */
+          if ( axis->num_segments > 1000 )
+          {
+            FT_TRACE0(( "af_latin_hints_compute_segments:"
+                        " more than 1000 segments in this glyph;\n" ));
+            FT_TRACE0(( "                                "
+                        " hinting is suppressed\n" ));
+            axis->num_segments = 0;
+            return FT_Err_Ok;
+          }
+
           /* this is the start of a new segment! */
           segment_dir = (AF_Direction)point->out_dir;
 
@@ -1874,7 +1929,7 @@
     /* sense -- this is used to better detect and ignore serifs   */
     {
       AF_Segment  segments     = axis->segments;
-      AF_Segment  segments_end = segments + axis->num_segments;
+      AF_Segment  segments_end = FT_OFFSET( segments, axis->num_segments );
 
 
       for ( segment = segments; segment < segments_end; segment++ )
@@ -1934,7 +1989,7 @@
   {
     AF_AxisHints  axis          = &hints->axis[dim];
     AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
+    AF_Segment    segment_limit = FT_OFFSET( segments, axis->num_segments );
     FT_Pos        len_threshold, len_score, dist_score, max_width;
     AF_Segment    seg1, seg2;
 
@@ -2054,7 +2109,7 @@
       {
         if ( seg2->link != seg1 )
         {
-          seg1->link  = 0;
+          seg1->link  = NULL;
           seg1->serif = seg2->link;
         }
       }
@@ -2079,7 +2134,7 @@
     FT_Bool  top_to_bottom_hinting = 0;
 
     AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
+    AF_Segment    segment_limit = FT_OFFSET( segments, axis->num_segments );
     AF_Segment    seg;
 
 #if 0
@@ -2148,7 +2203,7 @@
     for ( seg = segments; seg < segment_limit; seg++ )
     {
       AF_Edge  found = NULL;
-      FT_Int   ee;
+      FT_UInt  ee;
 
 
       /* ignore too short segments, too wide ones, and, in this loop, */
@@ -2222,7 +2277,7 @@
     for ( seg = segments; seg < segment_limit; seg++ )
     {
       AF_Edge  found = NULL;
-      FT_Int   ee;
+      FT_UInt  ee;
 
 
       if ( seg->dir != AF_DIR_NONE )
@@ -2278,7 +2333,7 @@
      */
     {
       AF_Edge  edges      = axis->edges;
-      AF_Edge  edge_limit = edges + axis->num_edges;
+      AF_Edge  edge_limit = FT_OFFSET( edges, axis->num_edges );
       AF_Edge  edge;
 
 
@@ -2328,9 +2383,9 @@
 
           /* check for links -- if seg->serif is set, then seg->link must */
           /* be ignored                                                   */
-          is_serif = (FT_Bool)( seg->serif               &&
-                                seg->serif->edge         &&
-                                seg->serif->edge != edge );
+          is_serif = FT_BOOL( seg->serif               &&
+                              seg->serif->edge         &&
+                              seg->serif->edge != edge );
 
           if ( ( seg->link && seg->link->edge ) || is_serif )
           {
@@ -2445,7 +2500,7 @@
   {
     AF_AxisHints  axis       = &hints->axis[AF_DIMENSION_VERT];
     AF_Edge       edge       = axis->edges;
-    AF_Edge       edge_limit = edge + axis->num_edges;
+    AF_Edge       edge_limit = FT_OFFSET( edge, axis->num_edges );
     AF_LatinAxis  latin      = &metrics->axis[AF_DIMENSION_VERT];
     FT_Fixed      scale      = latin->scale;
 
@@ -2576,11 +2631,6 @@
     /* compute flags depending on render mode, etc. */
     mode = metrics->root.scaler.render_mode;
 
-#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
-    if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
-      metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
-#endif
-
     scaler_flags = hints->scaler_flags;
     other_flags  = 0;
 
@@ -2618,12 +2668,6 @@
          ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0          )
       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    /* get (global) warper flag */
-    if ( !metrics->root.globals->module->warping )
-      scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
-#endif
-
     hints->scaler_flags = scaler_flags;
     hints->other_flags  = other_flags;
 
@@ -2909,10 +2953,11 @@
 
     stem_edge->pos = base_edge->pos + fitted_width;
 
-    FT_TRACE5(( "  LINK: edge %d (opos=%.2f) linked to %.2f,"
+    FT_TRACE5(( "  LINK: edge %ld (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
-                stem_edge - hints->axis[dim].edges, stem_edge->opos / 64.0,
-                stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
+                stem_edge - hints->axis[dim].edges,
+                (double)stem_edge->opos / 64, (double)stem_edge->pos / 64,
+                (double)dist / 64, (double)fitted_width / 64 ));
   }
 
 
@@ -2949,7 +2994,7 @@
   {
     AF_AxisHints  axis       = &hints->axis[dim];
     AF_Edge       edges      = axis->edges;
-    AF_Edge       edge_limit = edges + axis->num_edges;
+    AF_Edge       edge_limit = FT_OFFSET( edges, axis->num_edges );
     FT_PtrDist    n_edges;
     AF_Edge       edge;
     AF_Edge       anchor     = NULL;
@@ -3033,15 +3078,17 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         if ( !anchor )
-          FT_TRACE5(( "  BLUE_ANCHOR: edge %d (opos=%.2f) snapped to %.2f,"
-                      " was %.2f (anchor=edge %d)\n",
-                      edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
-                      edge1->pos / 64.0, edge - edges ));
+          FT_TRACE5(( "  BLUE_ANCHOR: edge %ld (opos=%.2f) snapped to %.2f,"
+                      " was %.2f (anchor=edge %ld)\n",
+                      edge1 - edges,
+                      (double)edge1->opos / 64, (double)blue->fit / 64,
+                      (double)edge1->pos / 64, edge - edges ));
         else
-          FT_TRACE5(( "  BLUE: edge %d (opos=%.2f) snapped to %.2f,"
+          FT_TRACE5(( "  BLUE: edge %ld (opos=%.2f) snapped to %.2f,"
                       " was %.2f\n",
-                      edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
-                      edge1->pos / 64.0 ));
+                      edge1 - edges,
+                      (double)edge1->opos / 64, (double)blue->fit / 64,
+                      (double)edge1->pos / 64 ));
 
         num_actions++;
 #endif
@@ -3087,7 +3134,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "  ASSERTION FAILED for edge %d\n", edge2 - edges ));
+        FT_TRACE5(( "  ASSERTION FAILED for edge %ld\n", edge2 - edges ));
 
         af_latin_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -3155,11 +3202,11 @@
         anchor       = edge;
         edge->flags |= AF_EDGE_DONE;
 
-        FT_TRACE5(( "  ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
+        FT_TRACE5(( "  ANCHOR: edge %ld (opos=%.2f) and %ld (opos=%.2f)"
                     " snapped to %.2f and %.2f\n",
-                    edge - edges, edge->opos / 64.0,
-                    edge2 - edges, edge2->opos / 64.0,
-                    edge->pos / 64.0, edge2->pos / 64.0 ));
+                    edge - edges, (double)edge->opos / 64,
+                    edge2 - edges, (double)edge2->opos / 64,
+                    (double)edge->pos / 64, (double)edge2->pos / 64 ));
 
         af_latin_align_linked_edge( hints, dim, edge, edge2 );
 
@@ -3184,9 +3231,9 @@
 
         if ( edge2->flags & AF_EDGE_DONE )
         {
-          FT_TRACE5(( "  ADJUST: edge %d (pos=%.2f) moved to %.2f\n",
-                      edge - edges, edge->pos / 64.0,
-                      ( edge2->pos - cur_len ) / 64.0 ));
+          FT_TRACE5(( "  ADJUST: edge %ld (pos=%.2f) moved to %.2f\n",
+                      edge - edges, (double)edge->pos / 64,
+                      (double)( edge2->pos - cur_len ) / 64 ));
 
           edge->pos = edge2->pos - cur_len;
         }
@@ -3225,11 +3272,11 @@
           edge->pos  = cur_pos1 - cur_len / 2;
           edge2->pos = cur_pos1 + cur_len / 2;
 
-          FT_TRACE5(( "  STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
+          FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
                       " snapped to %.2f and %.2f\n",
-                      edge - edges, edge->opos / 64.0,
-                      edge2 - edges, edge2->opos / 64.0,
-                      edge->pos / 64.0, edge2->pos / 64.0 ));
+                      edge - edges, (double)edge->opos / 64,
+                      edge2 - edges, (double)edge2->opos / 64,
+                      (double)edge->pos / 64, (double)edge2->pos / 64 ));
         }
 
         else
@@ -3256,11 +3303,11 @@
           edge->pos  = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
           edge2->pos = edge->pos + cur_len;
 
-          FT_TRACE5(( "  STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
+          FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
                       " snapped to %.2f and %.2f\n",
-                      edge - edges, edge->opos / 64.0,
-                      edge2 - edges, edge2->opos / 64.0,
-                      edge->pos / 64.0, edge2->pos / 64.0 ));
+                      edge - edges, (double)edge->opos / 64,
+                      edge2 - edges, (double)edge2->opos / 64,
+                      (double)edge->pos / 64, (double)edge2->pos / 64 ));
         }
 
 #ifdef FT_DEBUG_LEVEL_TRACE
@@ -3279,10 +3326,10 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
                         edge - edges,
-                        edge->pos / 64.0,
-                        edge[-1].pos / 64.0 ));
+                        (double)edge->pos / 64,
+                        (double)edge[-1].pos / 64 ));
 
             num_actions++;
 #endif
@@ -3381,19 +3428,20 @@
         if ( delta < 64 + 16 )
         {
           af_latin_align_serif_edge( hints, edge->serif, edge );
-          FT_TRACE5(( "  SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
+          FT_TRACE5(( "  SERIF: edge %ld (opos=%.2f) serif to %ld (opos=%.2f)"
                       " aligned to %.2f\n",
-                      edge - edges, edge->opos / 64.0,
-                      edge->serif - edges, edge->serif->opos / 64.0,
-                      edge->pos / 64.0 ));
+                      edge - edges, (double)edge->opos / 64,
+                      edge->serif - edges, (double)edge->serif->opos / 64,
+                      (double)edge->pos / 64 ));
         }
         else if ( !anchor )
         {
           edge->pos = FT_PIX_ROUND( edge->opos );
           anchor    = edge;
-          FT_TRACE5(( "  SERIF_ANCHOR: edge %d (opos=%.2f)"
+          FT_TRACE5(( "  SERIF_ANCHOR: edge %ld (opos=%.2f)"
                       " snapped to %.2f\n",
-                      edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
+                      edge-edges,
+                      (double)edge->opos / 64, (double)edge->pos / 64 ));
         }
         else
         {
@@ -3419,19 +3467,20 @@
                                      after->pos - before->pos,
                                      after->opos - before->opos );
 
-            FT_TRACE5(( "  SERIF_LINK1: edge %d (opos=%.2f) snapped to %.2f"
-                        " from %d (opos=%.2f)\n",
-                        edge - edges, edge->opos / 64.0,
-                        edge->pos / 64.0,
-                        before - edges, before->opos / 64.0 ));
+            FT_TRACE5(( "  SERIF_LINK1: edge %ld (opos=%.2f) snapped to %.2f"
+                        " from %ld (opos=%.2f)\n",
+                        edge - edges, (double)edge->opos / 64,
+                        (double)edge->pos / 64,
+                        before - edges, (double)before->opos / 64 ));
           }
           else
           {
             edge->pos = anchor->pos +
                         ( ( edge->opos - anchor->opos + 16 ) & ~31 );
-            FT_TRACE5(( "  SERIF_LINK2: edge %d (opos=%.2f)"
+            FT_TRACE5(( "  SERIF_LINK2: edge %ld (opos=%.2f)"
                         " snapped to %.2f\n",
-                        edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
+                        edge - edges,
+                        (double)edge->opos / 64, (double)edge->pos / 64 ));
           }
         }
 
@@ -3449,10 +3498,10 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
                         edge - edges,
-                        edge->pos / 64.0,
-                        edge[-1].pos / 64.0 ));
+                        (double)edge->pos / 64,
+                        (double)edge[-1].pos / 64 ));
 
             num_actions++;
 #endif
@@ -3470,10 +3519,10 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %d (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
                         edge - edges,
-                        edge->pos / 64.0,
-                        edge[1].pos / 64.0 ));
+                        (double)edge->pos / 64,
+                        (double)edge[1].pos / 64 ));
 
             num_actions++;
 #endif
@@ -3540,24 +3589,6 @@
     /* grid-fit the outline */
     for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
     {
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-      if ( dim == AF_DIMENSION_HORZ                                  &&
-           metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
-           AF_HINTS_DO_WARP( hints )                                 )
-      {
-        AF_WarperRec  warper;
-        FT_Fixed      scale;
-        FT_Pos        delta;
-
-
-        af_warper_compute( &warper, hints, (AF_Dimension)dim,
-                           &scale, &delta );
-        af_glyph_hints_scale_dim( hints, (AF_Dimension)dim,
-                                  scale, delta );
-        continue;
-      }
-#endif /* AF_CONFIG_OPTION_USE_WARPER */
-
       if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
            ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
       {
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index 6b429bd..3c6a7ee 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -5,7 +5,7 @@
  *   Auto-fitter hinting routines for latin writing system
  *   (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
deleted file mode 100644
index c5ce043..0000000
--- a/src/autofit/aflatin2.c
+++ /dev/null
@@ -1,2427 +0,0 @@
-/* ATTENTION: This file doesn't compile.  It is only here as a reference */
-/*            of an alternative latin hinting algorithm that was always  */
-/*            marked as experimental.                                    */
-
-
-/****************************************************************************
- *
- * aflatin2.c
- *
- *   Auto-fitter hinting routines for latin writing system (body).
- *
- * Copyright 2003-2018 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 FT_ADVANCES_H
-
-
-#ifdef FT_OPTION_AUTOFIT2
-
-#include "afglobal.h"
-#include "aflatin.h"
-#include "aflatin2.h"
-#include "aferrors.h"
-
-
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-#include "afwarp.h"
-#endif
-
-
-  /**************************************************************************
-   *
-   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
-   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
-   * messages during execution.
-   */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_aflatin2
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_latin2_hints_compute_segments( AF_GlyphHints  hints,
-                                    AF_Dimension   dim );
-
-  FT_LOCAL_DEF( void )
-  af_latin2_hints_link_segments( AF_GlyphHints  hints,
-                                 AF_Dimension   dim );
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****            L A T I N   G L O B A L   M E T R I C S            *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  FT_LOCAL_DEF( void )
-  af_latin2_metrics_init_widths( AF_LatinMetrics  metrics,
-                                 FT_Face          face )
-  {
-    /* scan the array of segments in each direction */
-    AF_GlyphHintsRec  hints[1];
-
-
-    af_glyph_hints_init( hints, face->memory );
-
-    metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
-    metrics->axis[AF_DIMENSION_VERT].width_count = 0;
-
-    {
-      FT_Error             error;
-      FT_UInt              glyph_index;
-      int                  dim;
-      AF_LatinMetricsRec   dummy[1];
-      AF_Scaler            scaler = &dummy->root.scaler;
-
-
-      glyph_index = FT_Get_Char_Index(
-                      face,
-                      metrics->root.style_class->standard_char );
-      if ( glyph_index == 0 )
-        goto Exit;
-
-      error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
-      if ( error || face->glyph->outline.n_points <= 0 )
-        goto Exit;
-
-      FT_ZERO( dummy );
-
-      dummy->units_per_em = metrics->units_per_em;
-      scaler->x_scale     = scaler->y_scale = 0x10000L;
-      scaler->x_delta     = scaler->y_delta = 0;
-      scaler->face        = face;
-      scaler->render_mode = FT_RENDER_MODE_NORMAL;
-      scaler->flags       = 0;
-
-      af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy );
-
-      error = af_glyph_hints_reload( hints, &face->glyph->outline );
-      if ( error )
-        goto Exit;
-
-      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
-      {
-        AF_LatinAxis  axis    = &metrics->axis[dim];
-        AF_AxisHints  axhints = &hints->axis[dim];
-        AF_Segment    seg, limit, link;
-        FT_UInt       num_widths = 0;
-
-
-        error = af_latin2_hints_compute_segments( hints,
-                                                 (AF_Dimension)dim );
-        if ( error )
-          goto Exit;
-
-        af_latin2_hints_link_segments( hints,
-                                      (AF_Dimension)dim );
-
-        seg   = axhints->segments;
-        limit = seg + axhints->num_segments;
-
-        for ( ; seg < limit; seg++ )
-        {
-          link = seg->link;
-
-          /* we only consider stem segments there! */
-          if ( link && link->link == seg && link > seg )
-          {
-            FT_Pos  dist;
-
-
-            dist = seg->pos - link->pos;
-            if ( dist < 0 )
-              dist = -dist;
-
-            if ( num_widths < AF_LATIN_MAX_WIDTHS )
-              axis->widths[num_widths++].org = dist;
-          }
-        }
-
-        af_sort_widths( num_widths, axis->widths );
-        axis->width_count = num_widths;
-      }
-
-  Exit:
-      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
-      {
-        AF_LatinAxis  axis = &metrics->axis[dim];
-        FT_Pos        stdw;
-
-
-        stdw = ( axis->width_count > 0 )
-                 ? axis->widths[0].org
-                 : AF_LATIN_CONSTANT( metrics, 50 );
-
-        /* let's try 20% of the smallest width */
-        axis->edge_distance_threshold = stdw / 5;
-        axis->standard_width          = stdw;
-        axis->extra_light             = 0;
-      }
-    }
-
-    af_glyph_hints_done( hints );
-  }
-
-
-
-#define AF_LATIN_MAX_TEST_CHARACTERS  12
-
-
-  static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES]
-                                        [AF_LATIN_MAX_TEST_CHARACTERS+1] =
-  {
-    "THEZOCQS",
-    "HEZLOCUS",
-    "fijkdbh",
-    "xzroesc",
-    "xzroesc",
-    "pqgjy"
-  };
-
-
-  static void
-  af_latin2_metrics_init_blues( AF_LatinMetrics  metrics,
-                                FT_Face          face )
-  {
-    FT_Pos        flats [AF_LATIN_MAX_TEST_CHARACTERS];
-    FT_Pos        rounds[AF_LATIN_MAX_TEST_CHARACTERS];
-    FT_Int        num_flats;
-    FT_Int        num_rounds;
-    FT_Int        bb;
-    AF_LatinBlue  blue;
-    FT_Error      error;
-    AF_LatinAxis  axis  = &metrics->axis[AF_DIMENSION_VERT];
-    FT_GlyphSlot  glyph = face->glyph;
-
-
-    /* we compute the blues simply by loading each character from the     */
-    /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */
-    /* bottom-most points (depending on `AF_IS_TOP_BLUE')                 */
-
-    FT_TRACE5(( "blue zones computation\n"
-                "======================\n\n" ));
-
-    for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
-    {
-      const char*  p     = af_latin2_blue_chars[bb];
-      const char*  limit = p + AF_LATIN_MAX_TEST_CHARACTERS;
-      FT_Pos*      blue_ref;
-      FT_Pos*      blue_shoot;
-
-
-      FT_TRACE5(( "blue zone %d:\n", bb ));
-
-      num_flats  = 0;
-      num_rounds = 0;
-
-      for ( ; p < limit && *p; p++ )
-      {
-        FT_UInt     glyph_index;
-        FT_Int      best_point, best_y, best_first, best_last;
-        FT_Vector*  points;
-        FT_Bool     round;
-
-
-        /* load the character in the face -- skip unknown or empty ones */
-        glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
-        if ( glyph_index == 0 )
-          continue;
-
-        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
-        if ( error || glyph->outline.n_points <= 0 )
-          continue;
-
-        /* now compute min or max point indices and coordinates */
-        points      = glyph->outline.points;
-        best_point  = -1;
-        best_y      = 0;  /* make compiler happy */
-        best_first  = 0;  /* ditto */
-        best_last   = 0;  /* ditto */
-
-        {
-          FT_Int  nn;
-          FT_Int  first = 0;
-          FT_Int  last  = -1;
-
-
-          for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ )
-          {
-            FT_Int  old_best_point = best_point;
-            FT_Int  pp;
-
-
-            last = glyph->outline.contours[nn];
-
-            /* Avoid single-point contours since they are never rasterized. */
-            /* In some fonts, they correspond to mark attachment points     */
-            /* which are way outside of the glyph's real outline.           */
-            if ( last == first )
-                continue;
-
-            if ( AF_LATIN_IS_TOP_BLUE( bb ) )
-            {
-              for ( pp = first; pp <= last; pp++ )
-                if ( best_point < 0 || points[pp].y > best_y )
-                {
-                  best_point = pp;
-                  best_y     = points[pp].y;
-                }
-            }
-            else
-            {
-              for ( pp = first; pp <= last; pp++ )
-                if ( best_point < 0 || points[pp].y < best_y )
-                {
-                  best_point = pp;
-                  best_y     = points[pp].y;
-                }
-            }
-
-            if ( best_point != old_best_point )
-            {
-              best_first = first;
-              best_last  = last;
-            }
-          }
-          FT_TRACE5(( "  %c  %d", *p, best_y ));
-        }
-
-        /* now check whether the point belongs to a straight or round   */
-        /* segment; we first need to find in which contour the extremum */
-        /* lies, then inspect its previous and next points              */
-        {
-          FT_Pos  best_x = points[best_point].x;
-          FT_Int  start, end, prev, next;
-          FT_Pos  dist;
-
-
-          /* now look for the previous and next points that are not on the */
-          /* same Y coordinate.  Threshold the `closeness'...              */
-          start = end = best_point;
-
-          do
-          {
-            prev = start - 1;
-            if ( prev < best_first )
-              prev = best_last;
-
-            dist = FT_ABS( points[prev].y - best_y );
-            /* accept a small distance or a small angle (both values are */
-            /* heuristic; value 20 corresponds to approx. 2.9 degrees)   */
-            if ( dist > 5 )
-              if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist )
-                break;
-
-            start = prev;
-
-          } while ( start != best_point );
-
-          do
-          {
-            next = end + 1;
-            if ( next > best_last )
-              next = best_first;
-
-            dist = FT_ABS( points[next].y - best_y );
-            if ( dist > 5 )
-              if ( FT_ABS( points[next].x - best_x ) <= 20 * dist )
-                break;
-
-            end = next;
-
-          } while ( end != best_point );
-
-          /* now, set the `round' flag depending on the segment's kind */
-          round = FT_BOOL(
-            FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON ||
-            FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON );
-
-          FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
-        }
-
-        if ( round )
-          rounds[num_rounds++] = best_y;
-        else
-          flats[num_flats++]   = best_y;
-      }
-
-      if ( num_flats == 0 && num_rounds == 0 )
-      {
-        /*
-         * we couldn't find a single glyph to compute this blue zone,
-         * we will simply ignore it then
-         */
-        FT_TRACE5(( "  empty\n" ));
-        continue;
-      }
-
-      /* we have computed the contents of the `rounds' and `flats' tables, */
-      /* now determine the reference and overshoot position of the blue -- */
-      /* we simply take the median value after a simple sort               */
-      af_sort_pos( num_rounds, rounds );
-      af_sort_pos( num_flats,  flats );
-
-      blue       = & axis->blues[axis->blue_count];
-      blue_ref   = & blue->ref.org;
-      blue_shoot = & blue->shoot.org;
-
-      axis->blue_count++;
-
-      if ( num_flats == 0 )
-      {
-        *blue_ref   =
-        *blue_shoot = rounds[num_rounds / 2];
-      }
-      else if ( num_rounds == 0 )
-      {
-        *blue_ref   =
-        *blue_shoot = flats[num_flats / 2];
-      }
-      else
-      {
-        *blue_ref   = flats[num_flats / 2];
-        *blue_shoot = rounds[num_rounds / 2];
-      }
-
-      /* there are sometimes problems: if the overshoot position of top     */
-      /* zones is under its reference position, or the opposite for bottom  */
-      /* zones.  We must thus check everything there and correct the errors */
-      if ( *blue_shoot != *blue_ref )
-      {
-        FT_Pos   ref      = *blue_ref;
-        FT_Pos   shoot    = *blue_shoot;
-        FT_Bool  over_ref = FT_BOOL( shoot > ref );
-
-
-        if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
-        {
-          *blue_ref   =
-          *blue_shoot = ( shoot + ref ) / 2;
-
-          FT_TRACE5(( "  [overshoot smaller than reference,"
-                      " taking mean value]\n" ));
-        }
-      }
-
-      blue->flags = 0;
-      if ( AF_LATIN_IS_TOP_BLUE( bb ) )
-        blue->flags |= AF_LATIN_BLUE_TOP;
-
-      /*
-       * The following flag is used later to adjust the y and x scales
-       * in order to optimize the pixel grid alignment of the top of small
-       * letters.
-       */
-      if ( AF_LATIN_IS_X_HEIGHT_BLUE( bb ) )
-        blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
-
-      FT_TRACE5(( "    -> reference = %ld\n"
-                  "       overshoot = %ld\n",
-                  *blue_ref, *blue_shoot ));
-    }
-
-    return;
-  }
-
-
-  FT_LOCAL_DEF( void )
-  af_latin2_metrics_check_digits( AF_LatinMetrics  metrics,
-                                  FT_Face          face )
-  {
-    FT_UInt   i;
-    FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance, old_advance = 0;
-
-
-    /* check whether all ASCII digits have the same advance width; */
-    /* digit `0' is 0x30 in all supported charmaps                 */
-    for ( i = 0x30; i <= 0x39; i++ )
-    {
-      FT_UInt  glyph_index;
-
-
-      glyph_index = FT_Get_Char_Index( face, i );
-      if ( glyph_index == 0 )
-        continue;
-
-      if ( FT_Get_Advance( face, glyph_index,
-                           FT_LOAD_NO_SCALE         |
-                           FT_LOAD_NO_HINTING       |
-                           FT_LOAD_IGNORE_TRANSFORM,
-                           &advance ) )
-        continue;
-
-      if ( started )
-      {
-        if ( advance != old_advance )
-        {
-          same_width = 0;
-          break;
-        }
-      }
-      else
-      {
-        old_advance = advance;
-        started     = 1;
-      }
-    }
-
-    metrics->root.digits_have_same_width = same_width;
-  }
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_latin2_metrics_init( AF_LatinMetrics  metrics,
-                          FT_Face          face )
-  {
-    FT_Error    error  = FT_Err_Ok;
-    FT_CharMap  oldmap = face->charmap;
-    FT_UInt     ee;
-
-    static const FT_Encoding  latin_encodings[] =
-    {
-      FT_ENCODING_UNICODE,
-      FT_ENCODING_APPLE_ROMAN,
-      FT_ENCODING_ADOBE_STANDARD,
-      FT_ENCODING_ADOBE_LATIN_1,
-      FT_ENCODING_NONE  /* end of list */
-    };
-
-
-    metrics->units_per_em = face->units_per_EM;
-
-    /* do we have a latin charmap in there? */
-    for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )
-    {
-      error = FT_Select_Charmap( face, latin_encodings[ee] );
-      if ( !error )
-        break;
-    }
-
-    if ( !error )
-    {
-      af_latin2_metrics_init_widths( metrics, face );
-      af_latin2_metrics_init_blues( metrics, face );
-      af_latin2_metrics_check_digits( metrics, face );
-    }
-
-    FT_Set_Charmap( face, oldmap );
-    return FT_Err_Ok;
-  }
-
-
-  static void
-  af_latin2_metrics_scale_dim( AF_LatinMetrics  metrics,
-                               AF_Scaler        scaler,
-                               AF_Dimension     dim )
-  {
-    FT_Fixed      scale;
-    FT_Pos        delta;
-    AF_LatinAxis  axis;
-    FT_UInt       nn;
-
-
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      scale = scaler->x_scale;
-      delta = scaler->x_delta;
-    }
-    else
-    {
-      scale = scaler->y_scale;
-      delta = scaler->y_delta;
-    }
-
-    axis = &metrics->axis[dim];
-
-    if ( axis->org_scale == scale && axis->org_delta == delta )
-      return;
-
-    axis->org_scale = scale;
-    axis->org_delta = delta;
-
-    /*
-     * correct Y scale to optimize the alignment of the top of small
-     * letters to the pixel grid
-     */
-    if ( dim == AF_DIMENSION_VERT )
-    {
-      AF_LatinAxis  vaxis = &metrics->axis[AF_DIMENSION_VERT];
-      AF_LatinBlue  blue = NULL;
-
-
-      for ( nn = 0; nn < vaxis->blue_count; nn++ )
-      {
-        if ( vaxis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT )
-        {
-          blue = &vaxis->blues[nn];
-          break;
-        }
-      }
-
-      if ( blue )
-      {
-        FT_Pos   scaled;
-        FT_Pos   threshold;
-        FT_Pos   fitted;
-        FT_UInt  limit;
-        FT_UInt  ppem;
-
-
-        scaled    = FT_MulFix( blue->shoot.org, scaler->y_scale );
-        ppem      = metrics->root.scaler.face->size->metrics.x_ppem;
-        limit     = metrics->root.globals->increase_x_height;
-        threshold = 40;
-
-        /* if the `increase-x-height' property is active, */
-        /* we round up much more often                    */
-        if ( limit                                 &&
-             ppem <= limit                         &&
-             ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
-          threshold = 52;
-
-        fitted = ( scaled + threshold ) & ~63;
-
-#if 1
-        if ( scaled != fitted )
-        {
-          scale = FT_MulDiv( scale, fitted, scaled );
-          FT_TRACE5(( "== scaled x-top = %.2g"
-                      "  fitted = %.2g, scaling = %.4g\n",
-                      scaled / 64.0, fitted / 64.0,
-                      ( fitted * 1.0 ) / scaled ));
-        }
-#endif
-      }
-    }
-
-    axis->scale = scale;
-    axis->delta = delta;
-
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      metrics->root.scaler.x_scale = scale;
-      metrics->root.scaler.x_delta = delta;
-    }
-    else
-    {
-      metrics->root.scaler.y_scale = scale;
-      metrics->root.scaler.y_delta = delta;
-    }
-
-    /* scale the standard widths */
-    for ( nn = 0; nn < axis->width_count; nn++ )
-    {
-      AF_Width  width = axis->widths + nn;
-
-
-      width->cur = FT_MulFix( width->org, scale );
-      width->fit = width->cur;
-    }
-
-    /* an extra-light axis corresponds to a standard width that is */
-    /* smaller than 5/8 pixels                                     */
-    axis->extra_light =
-      (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );
-
-    if ( dim == AF_DIMENSION_VERT )
-    {
-      /* scale the blue zones */
-      for ( nn = 0; nn < axis->blue_count; nn++ )
-      {
-        AF_LatinBlue  blue = &axis->blues[nn];
-        FT_Pos        dist;
-
-
-        blue->ref.cur   = FT_MulFix( blue->ref.org, scale ) + delta;
-        blue->ref.fit   = blue->ref.cur;
-        blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta;
-        blue->shoot.fit = blue->shoot.cur;
-        blue->flags    &= ~AF_LATIN_BLUE_ACTIVE;
-
-        /* a blue zone is only active if it is less than 3/4 pixels tall */
-        dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );
-        if ( dist <= 48 && dist >= -48 )
-        {
-          FT_Pos  delta1, delta2;
-
-          delta1 = blue->shoot.org - blue->ref.org;
-          delta2 = delta1;
-          if ( delta1 < 0 )
-            delta2 = -delta2;
-
-          delta2 = FT_MulFix( delta2, scale );
-
-          if ( delta2 < 32 )
-            delta2 = 0;
-          else if ( delta2 < 64 )
-            delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );
-          else
-            delta2 = FT_PIX_ROUND( delta2 );
-
-          if ( delta1 < 0 )
-            delta2 = -delta2;
-
-          blue->ref.fit   = FT_PIX_ROUND( blue->ref.cur );
-          blue->shoot.fit = blue->ref.fit + delta2;
-
-          FT_TRACE5(( ">> activating blue zone %d:"
-                      "  ref.cur=%.2g ref.fit=%.2g"
-                      "  shoot.cur=%.2g shoot.fit=%.2g\n",
-                      nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0,
-                      blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 ));
-
-          blue->flags |= AF_LATIN_BLUE_ACTIVE;
-        }
-      }
-    }
-  }
-
-
-  FT_LOCAL_DEF( void )
-  af_latin2_metrics_scale( AF_LatinMetrics  metrics,
-                           AF_Scaler        scaler )
-  {
-    metrics->root.scaler.render_mode = scaler->render_mode;
-    metrics->root.scaler.face        = scaler->face;
-    metrics->root.scaler.flags       = scaler->flags;
-
-    af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
-    af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
-  }
-
-
-  /* Extract standard_width from writing system/script specific */
-  /* metrics class.                                             */
-
-  FT_LOCAL_DEF( void )
-  af_latin2_get_standard_widths( AF_LatinMetrics  metrics,
-                                 FT_Pos*          stdHW,
-                                 FT_Pos*          stdVW )
-  {
-    if ( stdHW )
-      *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
-
-    if ( stdVW )
-      *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width;
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****           L A T I N   G L Y P H   A N A L Y S I S             *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-#define  SORT_SEGMENTS
-
-  FT_LOCAL_DEF( FT_Error )
-  af_latin2_hints_compute_segments( AF_GlyphHints  hints,
-                                    AF_Dimension   dim )
-  {
-    AF_AxisHints  axis          = &hints->axis[dim];
-    FT_Memory     memory        = hints->memory;
-    FT_Error      error         = FT_Err_Ok;
-    AF_Segment    segment       = NULL;
-    AF_SegmentRec seg0;
-    AF_Point*     contour       = hints->contours;
-    AF_Point*     contour_limit = contour + hints->num_contours;
-    AF_Direction  major_dir, segment_dir;
-
-
-    FT_ZERO( &seg0 );
-    seg0.score = 32000;
-    seg0.flags = AF_EDGE_NORMAL;
-
-    major_dir   = (AF_Direction)FT_ABS( axis->major_dir );
-    segment_dir = major_dir;
-
-    axis->num_segments = 0;
-
-    /* set up (u,v) in each point */
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      AF_Point  point = hints->points;
-      AF_Point  limit = point + hints->num_points;
-
-
-      for ( ; point < limit; point++ )
-      {
-        point->u = point->fx;
-        point->v = point->fy;
-      }
-    }
-    else
-    {
-      AF_Point  point = hints->points;
-      AF_Point  limit = point + hints->num_points;
-
-
-      for ( ; point < limit; point++ )
-      {
-        point->u = point->fy;
-        point->v = point->fx;
-      }
-    }
-
-    /* do each contour separately */
-    for ( ; contour < contour_limit; contour++ )
-    {
-      AF_Point  point   =  contour[0];
-      AF_Point  start   =  point;
-      AF_Point  last    =  point->prev;
-
-
-      if ( point == last )  /* skip singletons -- just in case */
-        continue;
-
-      /* already on an edge ?, backtrack to find its start */
-      if ( FT_ABS( point->in_dir ) == major_dir )
-      {
-        point = point->prev;
-
-        while ( point->in_dir == start->in_dir )
-          point = point->prev;
-      }
-      else  /* otherwise, find first segment start, if any */
-      {
-        while ( FT_ABS( point->out_dir ) != major_dir )
-        {
-          point = point->next;
-
-          if ( point == start )
-            goto NextContour;
-        }
-      }
-
-      start = point;
-
-      for  (;;)
-      {
-        AF_Point  first;
-        FT_Pos    min_u, min_v, max_u, max_v;
-
-        /* we're at the start of a new segment */
-        FT_ASSERT( FT_ABS( point->out_dir ) == major_dir &&
-                           point->in_dir != point->out_dir );
-        first = point;
-
-        min_u = max_u = point->u;
-        min_v = max_v = point->v;
-
-        point = point->next;
-
-        while ( point->out_dir == first->out_dir )
-        {
-          point = point->next;
-
-          if ( point->u < min_u )
-            min_u = point->u;
-
-          if ( point->u > max_u )
-            max_u = point->u;
-        }
-
-        if ( point->v < min_v )
-          min_v = point->v;
-
-        if ( point->v > max_v )
-          max_v = point->v;
-
-        /* record new segment */
-        error = af_axis_hints_new_segment( axis, memory, &segment );
-        if ( error )
-          goto Exit;
-
-        segment[0]         = seg0;
-        segment->dir       = first->out_dir;
-        segment->first     = first;
-        segment->last      = point;
-        segment->pos       = (FT_Short)( ( min_u + max_u ) >> 1 );
-        segment->min_coord = (FT_Short) min_v;
-        segment->max_coord = (FT_Short) max_v;
-        segment->height    = (FT_Short)( max_v - min_v );
-
-        /* a segment is round if it doesn't have successive */
-        /* on-curve points.                                 */
-        {
-          AF_Point  pt   = first;
-          AF_Point  last = point;
-          FT_UInt   f0   = pt->flags & AF_FLAG_CONTROL;
-          FT_UInt   f1;
-
-
-          segment->flags &= ~AF_EDGE_ROUND;
-
-          for ( ; pt != last; f0 = f1 )
-          {
-            pt = pt->next;
-            f1 = pt->flags & AF_FLAG_CONTROL;
-
-            if ( !f0 && !f1 )
-              break;
-
-            if ( pt == last )
-              segment->flags |= AF_EDGE_ROUND;
-          }
-        }
-
-       /* this can happen in the case of a degenerate contour
-        * e.g. a 2-point vertical contour
-        */
-        if ( point == start )
-          break;
-
-        /* jump to the start of the next segment, if any */
-        while ( FT_ABS( point->out_dir ) != major_dir )
-        {
-          point = point->next;
-
-          if ( point == start )
-            goto NextContour;
-        }
-      }
-
-    NextContour:
-      ;
-    } /* contours */
-
-    /* now slightly increase the height of segments when this makes */
-    /* sense -- this is used to better detect and ignore serifs     */
-    {
-      AF_Segment  segments     = axis->segments;
-      AF_Segment  segments_end = segments + axis->num_segments;
-
-
-      for ( segment = segments; segment < segments_end; segment++ )
-      {
-        AF_Point  first   = segment->first;
-        AF_Point  last    = segment->last;
-        AF_Point  p;
-        FT_Pos    first_v = first->v;
-        FT_Pos    last_v  = last->v;
-
-
-        if ( first_v < last_v )
-        {
-          p = first->prev;
-          if ( p->v < first_v )
-            segment->height = (FT_Short)( segment->height +
-                                          ( ( first_v - p->v ) >> 1 ) );
-
-          p = last->next;
-          if ( p->v > last_v )
-            segment->height = (FT_Short)( segment->height +
-                                          ( ( p->v - last_v ) >> 1 ) );
-        }
-        else
-        {
-          p = first->prev;
-          if ( p->v > first_v )
-            segment->height = (FT_Short)( segment->height +
-                                          ( ( p->v - first_v ) >> 1 ) );
-
-          p = last->next;
-          if ( p->v < last_v )
-            segment->height = (FT_Short)( segment->height +
-                                          ( ( last_v - p->v ) >> 1 ) );
-        }
-      }
-    }
-
-#ifdef AF_SORT_SEGMENTS
-   /* place all segments with a negative direction to the start
-    * of the array, used to speed up segment linking later...
-    */
-    {
-      AF_Segment  segments = axis->segments;
-      FT_UInt     count    = axis->num_segments;
-      FT_UInt     ii, jj;
-
-      for ( ii = 0; ii < count; ii++ )
-      {
-        if ( segments[ii].dir > 0 )
-        {
-          for ( jj = ii + 1; jj < count; jj++ )
-          {
-            if ( segments[jj].dir < 0 )
-            {
-              AF_SegmentRec  tmp;
-
-
-              tmp          = segments[ii];
-              segments[ii] = segments[jj];
-              segments[jj] = tmp;
-
-              break;
-            }
-          }
-
-          if ( jj == count )
-            break;
-        }
-      }
-      axis->mid_segments = ii;
-    }
-#endif
-
-  Exit:
-    return error;
-  }
-
-
-  FT_LOCAL_DEF( void )
-  af_latin2_hints_link_segments( AF_GlyphHints  hints,
-                                 AF_Dimension   dim )
-  {
-    AF_AxisHints  axis          = &hints->axis[dim];
-    AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
-#ifdef AF_SORT_SEGMENTS
-    AF_Segment    segment_mid   = segments + axis->mid_segments;
-#endif
-    FT_Pos        len_threshold, len_score;
-    AF_Segment    seg1, seg2;
-
-
-    len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
-    if ( len_threshold == 0 )
-      len_threshold = 1;
-
-    len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
-
-#ifdef AF_SORT_SEGMENTS
-    for ( seg1 = segments; seg1 < segment_mid; seg1++ )
-    {
-      if ( seg1->dir != axis->major_dir )
-        continue;
-
-      for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ )
-#else
-    /* now compare each segment to the others */
-    for ( seg1 = segments; seg1 < segment_limit; seg1++ )
-    {
-      if ( seg1->dir != axis->major_dir )
-        continue;
-
-      for ( seg2 = segments; seg2 < segment_limit; seg2++ )
-        if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos )
-#endif
-        {
-          FT_Pos  pos1 = seg1->pos;
-          FT_Pos  pos2 = seg2->pos;
-          FT_Pos  dist = pos2 - pos1;
-
-
-          if ( dist < 0 )
-            continue;
-
-          {
-            FT_Pos  min = seg1->min_coord;
-            FT_Pos  max = seg1->max_coord;
-            FT_Pos  len, score;
-
-
-            if ( min < seg2->min_coord )
-              min = seg2->min_coord;
-
-            if ( max > seg2->max_coord )
-              max = seg2->max_coord;
-
-            len = max - min;
-            if ( len >= len_threshold )
-            {
-              score = dist + len_score / len;
-              if ( score < seg1->score )
-              {
-                seg1->score = score;
-                seg1->link  = seg2;
-              }
-
-              if ( score < seg2->score )
-              {
-                seg2->score = score;
-                seg2->link  = seg1;
-              }
-            }
-          }
-        }
-    }
-#if 0
-    }
-#endif
-
-    /* now, compute the `serif' segments */
-    for ( seg1 = segments; seg1 < segment_limit; seg1++ )
-    {
-      seg2 = seg1->link;
-
-      if ( seg2 )
-      {
-        if ( seg2->link != seg1 )
-        {
-          seg1->link  = NULL;
-          seg1->serif = seg2->link;
-        }
-      }
-    }
-  }
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_latin2_hints_compute_edges( AF_GlyphHints  hints,
-                                 AF_Dimension   dim )
-  {
-    AF_AxisHints  axis   = &hints->axis[dim];
-    FT_Error      error  = FT_Err_Ok;
-    FT_Memory     memory = hints->memory;
-    AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];
-
-    AF_Segment    segments      = axis->segments;
-    AF_Segment    segment_limit = segments + axis->num_segments;
-    AF_Segment    seg;
-
-    AF_Direction  up_dir;
-    FT_Fixed      scale;
-    FT_Pos        edge_distance_threshold;
-    FT_Pos        segment_length_threshold;
-
-
-    axis->num_edges = 0;
-
-    scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
-                                         : hints->y_scale;
-
-    up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP
-                                          : AF_DIR_RIGHT;
-
-    /*
-     * We want to ignore very small (mostly serif) segments, we do that
-     * by ignoring those that whose length is less than a given fraction
-     * of the standard width. If there is no standard width, we ignore
-     * those that are less than a given size in pixels
-     *
-     * also, unlink serif segments that are linked to segments farther
-     * than 50% of the standard width
-     */
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      if ( laxis->width_count > 0 )
-        segment_length_threshold = ( laxis->standard_width * 10 ) >> 4;
-      else
-        segment_length_threshold = FT_DivFix( 64, hints->y_scale );
-    }
-    else
-      segment_length_threshold = 0;
-
-    /**********************************************************************
-     *
-     * We will begin by generating a sorted table of edges for the
-     * current direction.  To do so, we simply scan each segment and try
-     * to find an edge in our table that corresponds to its position.
-     *
-     * If no edge is found, we create and insert a new edge in the
-     * sorted table.  Otherwise, we simply add the segment to the edge's
-     * list which will be processed in the second step to compute the
-     * edge's properties.
-     *
-     * Note that the edges table is sorted along the segment/edge
-     * position.
-     *
-     */
-
-    edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
-                                         scale );
-    if ( edge_distance_threshold > 64 / 4 )
-      edge_distance_threshold = 64 / 4;
-
-    edge_distance_threshold = FT_DivFix( edge_distance_threshold,
-                                         scale );
-
-    for ( seg = segments; seg < segment_limit; seg++ )
-    {
-      AF_Edge  found = NULL;
-      FT_Int   ee;
-
-
-      if ( seg->height < segment_length_threshold )
-        continue;
-
-      /* A special case for serif edges: If they are smaller than */
-      /* 1.5 pixels we ignore them.                               */
-      if ( seg->serif )
-      {
-        FT_Pos  dist = seg->serif->pos - seg->pos;
-
-
-        if ( dist < 0 )
-          dist = -dist;
-
-        if ( dist >= laxis->standard_width >> 1 )
-        {
-          /* unlink this serif, it is too distant from its reference stem */
-          seg->serif = NULL;
-        }
-        else if ( 2*seg->height < 3 * segment_length_threshold )
-          continue;
-      }
-
-      /* look for an edge corresponding to the segment */
-      for ( ee = 0; ee < axis->num_edges; ee++ )
-      {
-        AF_Edge  edge = axis->edges + ee;
-        FT_Pos   dist;
-
-
-        dist = seg->pos - edge->fpos;
-        if ( dist < 0 )
-          dist = -dist;
-
-        if ( dist < edge_distance_threshold && edge->dir == seg->dir )
-        {
-          found = edge;
-          break;
-        }
-      }
-
-      if ( !found )
-      {
-        AF_Edge   edge;
-
-
-        /* insert a new edge in the list and */
-        /* sort according to the position    */
-        error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, 0,
-                                        memory, &edge );
-        if ( error )
-          goto Exit;
-
-        /* add the segment to the new edge's list */
-        FT_ZERO( edge );
-
-        edge->first    = seg;
-        edge->last     = seg;
-        edge->dir      = seg->dir;
-        edge->fpos     = seg->pos;
-        edge->opos     = FT_MulFix( seg->pos, scale );
-        edge->pos      = edge->opos;
-        seg->edge_next = seg;
-      }
-      else
-      {
-        /* if an edge was found, simply add the segment to the edge's */
-        /* list                                                       */
-        seg->edge_next         = found->first;
-        found->last->edge_next = seg;
-        found->last            = seg;
-      }
-    }
-
-
-    /**********************************************************************
-     *
-     * Good, we will now compute each edge's properties according to
-     * segments found on its position.  Basically, these are:
-     *
-     * - edge's main direction
-     * - stem edge, serif edge or both (which defaults to stem then)
-     * - rounded edge, straight or both (which defaults to straight)
-     * - link for edge
-     *
-     */
-
-    /* first of all, set the `edge' field in each segment -- this is */
-    /* required in order to compute edge links                       */
-
-    /*
-     * Note that removing this loop and setting the `edge' field of each
-     * segment directly in the code above slows down execution speed for
-     * some reasons on platforms like the Sun.
-     */
-    {
-      AF_Edge  edges      = axis->edges;
-      AF_Edge  edge_limit = edges + axis->num_edges;
-      AF_Edge  edge;
-
-
-      for ( edge = edges; edge < edge_limit; edge++ )
-      {
-        seg = edge->first;
-        if ( seg )
-          do
-          {
-            seg->edge = edge;
-            seg       = seg->edge_next;
-
-          } while ( seg != edge->first );
-      }
-
-      /* now, compute each edge properties */
-      for ( edge = edges; edge < edge_limit; edge++ )
-      {
-        FT_Int  is_round    = 0;  /* does it contain round segments?    */
-        FT_Int  is_straight = 0;  /* does it contain straight segments? */
-#if 0
-        FT_Pos  ups         = 0;  /* number of upwards segments         */
-        FT_Pos  downs       = 0;  /* number of downwards segments       */
-#endif
-
-
-        seg = edge->first;
-
-        do
-        {
-          FT_Bool  is_serif;
-
-
-          /* check for roundness of segment */
-          if ( seg->flags & AF_EDGE_ROUND )
-            is_round++;
-          else
-            is_straight++;
-
-#if 0
-          /* check for segment direction */
-          if ( seg->dir == up_dir )
-            ups   += seg->max_coord-seg->min_coord;
-          else
-            downs += seg->max_coord-seg->min_coord;
-#endif
-
-          /* check for links -- if seg->serif is set, then seg->link must */
-          /* be ignored                                                   */
-          is_serif = (FT_Bool)( seg->serif               &&
-                                seg->serif->edge         &&
-                                seg->serif->edge != edge );
-
-          if ( ( seg->link && seg->link->edge ) || is_serif )
-          {
-            AF_Edge     edge2;
-            AF_Segment  seg2;
-
-
-            edge2 = edge->link;
-            seg2  = seg->link;
-
-            if ( is_serif )
-            {
-              seg2  = seg->serif;
-              edge2 = edge->serif;
-            }
-
-            if ( edge2 )
-            {
-              FT_Pos  edge_delta;
-              FT_Pos  seg_delta;
-
-
-              edge_delta = edge->fpos - edge2->fpos;
-              if ( edge_delta < 0 )
-                edge_delta = -edge_delta;
-
-              seg_delta = seg->pos - seg2->pos;
-              if ( seg_delta < 0 )
-                seg_delta = -seg_delta;
-
-              if ( seg_delta < edge_delta )
-                edge2 = seg2->edge;
-            }
-            else
-              edge2 = seg2->edge;
-
-            if ( is_serif )
-            {
-              edge->serif   = edge2;
-              edge2->flags |= AF_EDGE_SERIF;
-            }
-            else
-              edge->link  = edge2;
-          }
-
-          seg = seg->edge_next;
-
-        } while ( seg != edge->first );
-
-        /* set the round/straight flags */
-        edge->flags = AF_EDGE_NORMAL;
-
-        if ( is_round > 0 && is_round >= is_straight )
-          edge->flags |= AF_EDGE_ROUND;
-
-#if 0
-        /* set the edge's main direction */
-        edge->dir = AF_DIR_NONE;
-
-        if ( ups > downs )
-          edge->dir = (FT_Char)up_dir;
-
-        else if ( ups < downs )
-          edge->dir = (FT_Char)-up_dir;
-
-        else if ( ups == downs )
-          edge->dir = 0;  /* both up and down! */
-#endif
-
-        /* gets rid of serifs if link is set                */
-        /* XXX: This gets rid of many unpleasant artefacts! */
-        /*      Example: the `c' in cour.pfa at size 13     */
-
-        if ( edge->serif && edge->link )
-          edge->serif = NULL;
-      }
-    }
-
-  Exit:
-    return error;
-  }
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_latin2_hints_detect_features( AF_GlyphHints  hints,
-                                   AF_Dimension   dim )
-  {
-    FT_Error  error;
-
-
-    error = af_latin2_hints_compute_segments( hints, dim );
-    if ( !error )
-    {
-      af_latin2_hints_link_segments( hints, dim );
-
-      error = af_latin2_hints_compute_edges( hints, dim );
-    }
-    return error;
-  }
-
-
-  static void
-  af_latin2_hints_compute_blue_edges( AF_GlyphHints    hints,
-                                      AF_LatinMetrics  metrics )
-  {
-    AF_AxisHints  axis       = &hints->axis[AF_DIMENSION_VERT];
-    AF_Edge       edge       = axis->edges;
-    AF_Edge       edge_limit = edge + axis->num_edges;
-    AF_LatinAxis  latin      = &metrics->axis[AF_DIMENSION_VERT];
-    FT_Fixed      scale      = latin->scale;
-    FT_Pos        best_dist0;  /* initial threshold */
-
-
-    /* compute the initial threshold as a fraction of the EM size */
-    best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale );
-
-    if ( best_dist0 > 64 / 2 )
-      best_dist0 = 64 / 2;
-
-    /* compute which blue zones are active, i.e. have their scaled */
-    /* size < 3/4 pixels                                           */
-
-    /* for each horizontal edge search the blue zone which is closest */
-    for ( ; edge < edge_limit; edge++ )
-    {
-      FT_Int    bb;
-      AF_Width  best_blue = NULL;
-      FT_Pos    best_dist = best_dist0;
-
-      for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
-      {
-        AF_LatinBlue  blue = latin->blues + bb;
-        FT_Bool       is_top_blue, is_major_dir;
-
-
-        /* skip inactive blue zones (i.e., those that are too small) */
-        if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
-          continue;
-
-        /* if it is a top zone, check for right edges -- if it is a bottom */
-        /* zone, check for left edges                                      */
-        /*                                                                 */
-        /* of course, that's for TrueType                                  */
-        is_top_blue  = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
-        is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
-
-        /* if it is a top zone, the edge must be against the major    */
-        /* direction; if it is a bottom zone, it must be in the major */
-        /* direction                                                  */
-        if ( is_top_blue ^ is_major_dir )
-        {
-          FT_Pos     dist;
-          AF_Width   compare;
-
-
-          /* if it's a rounded edge, compare it to the overshoot position */
-          /* if it's a flat edge, compare it to the reference position    */
-          if ( edge->flags & AF_EDGE_ROUND )
-            compare = &blue->shoot;
-          else
-            compare = &blue->ref;
-
-          dist = edge->fpos - compare->org;
-          if ( dist < 0 )
-            dist = -dist;
-
-          dist = FT_MulFix( dist, scale );
-          if ( dist < best_dist )
-          {
-            best_dist = dist;
-            best_blue = compare;
-          }
-
-#if 0
-          /* now, compare it to the overshoot position if the edge is     */
-          /* rounded, and if the edge is over the reference position of a */
-          /* top zone, or under the reference position of a bottom zone   */
-          if ( edge->flags & AF_EDGE_ROUND && dist != 0 )
-          {
-            FT_Bool  is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
-
-
-            if ( is_top_blue ^ is_under_ref )
-            {
-              blue = latin->blues + bb;
-              dist = edge->fpos - blue->shoot.org;
-              if ( dist < 0 )
-                dist = -dist;
-
-              dist = FT_MulFix( dist, scale );
-              if ( dist < best_dist )
-              {
-                best_dist = dist;
-                best_blue = & blue->shoot;
-              }
-            }
-          }
-#endif
-        }
-      }
-
-      if ( best_blue )
-        edge->blue_edge = best_blue;
-    }
-  }
-
-
-  static FT_Error
-  af_latin2_hints_init( AF_GlyphHints    hints,
-                        AF_LatinMetrics  metrics )
-  {
-    FT_Render_Mode  mode;
-    FT_UInt32       scaler_flags, other_flags;
-    FT_Face         face = metrics->root.scaler.face;
-
-
-    af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
-
-    /*
-     * correct x_scale and y_scale if needed, since they may have
-     * been modified `af_latin2_metrics_scale_dim' above
-     */
-    hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;
-    hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;
-    hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;
-    hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;
-
-    /* compute flags depending on render mode, etc. */
-    mode = metrics->root.scaler.render_mode;
-
-#if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
-    if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
-      metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
-#endif
-
-    scaler_flags = hints->scaler_flags;
-    other_flags  = 0;
-
-    /*
-     * We snap the width of vertical stems for the monochrome and
-     * horizontal LCD rendering targets only.
-     */
-    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )
-      other_flags |= AF_LATIN_HINTS_HORZ_SNAP;
-
-    /*
-     * We snap the width of horizontal stems for the monochrome and
-     * vertical LCD rendering targets only.
-     */
-    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )
-      other_flags |= AF_LATIN_HINTS_VERT_SNAP;
-
-    /*
-     * We adjust stems to full pixels unless in `light' or `lcd' mode.
-     */
-    if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD )
-      other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
-
-    if ( mode == FT_RENDER_MODE_MONO )
-      other_flags |= AF_LATIN_HINTS_MONO;
-
-    /*
-     * In `light' or `lcd' mode we disable horizontal hinting completely.
-     * We also do it if the face is italic.
-     */
-    if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD ||
-         ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0          )
-      scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
-
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    /* get (global) warper flag */
-    if ( !metrics->root.globals->module->warping )
-      scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
-#endif
-
-    hints->scaler_flags = scaler_flags;
-    hints->other_flags  = other_flags;
-
-    return 0;
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****        L A T I N   G L Y P H   G R I D - F I T T I N G        *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* snap a given width in scaled coordinates to one of the */
-  /* current standard widths                                */
-
-  static FT_Pos
-  af_latin2_snap_width( AF_Width  widths,
-                        FT_UInt   count,
-                        FT_Pos    width )
-  {
-    FT_UInt  n;
-    FT_Pos   best      = 64 + 32 + 2;
-    FT_Pos   reference = width;
-    FT_Pos   scaled;
-
-
-    for ( n = 0; n < count; n++ )
-    {
-      FT_Pos  w;
-      FT_Pos  dist;
-
-
-      w = widths[n].cur;
-      dist = width - w;
-      if ( dist < 0 )
-        dist = -dist;
-      if ( dist < best )
-      {
-        best      = dist;
-        reference = w;
-      }
-    }
-
-    scaled = FT_PIX_ROUND( reference );
-
-    if ( width >= reference )
-    {
-      if ( width < scaled + 48 )
-        width = reference;
-    }
-    else
-    {
-      if ( width > scaled - 48 )
-        width = reference;
-    }
-
-    return width;
-  }
-
-
-  /* compute the snapped width of a given stem */
-
-  static FT_Pos
-  af_latin2_compute_stem_width( AF_GlyphHints  hints,
-                                AF_Dimension   dim,
-                                FT_Pos         width,
-                                FT_UInt        base_flags,
-                                FT_UInt        stem_flags )
-  {
-    AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;
-    AF_LatinAxis     axis     = & metrics->axis[dim];
-    FT_Pos           dist     = width;
-    FT_Int           sign     = 0;
-    FT_Int           vertical = ( dim == AF_DIMENSION_VERT );
-
-    FT_UNUSED( base_flags );
-
-
-    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
-          axis->extra_light                      )
-      return width;
-
-    if ( dist < 0 )
-    {
-      dist = -width;
-      sign = 1;
-    }
-
-    if ( (  vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
-         ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )
-    {
-      /* smooth hinting process: very lightly quantize the stem width */
-
-      /* leave the widths of serifs alone */
-
-      if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )
-        goto Done_Width;
-
-#if 0
-      else if ( ( base_flags & AF_EDGE_ROUND ) )
-      {
-        if ( dist < 80 )
-          dist = 64;
-      }
-      else if ( dist < 56 )
-        dist = 56;
-#endif
-      if ( axis->width_count > 0 )
-      {
-        FT_Pos  delta;
-
-
-        /* compare to standard width */
-        if ( axis->width_count > 0 )
-        {
-          delta = dist - axis->widths[0].cur;
-
-          if ( delta < 0 )
-            delta = -delta;
-
-          if ( delta < 40 )
-          {
-            dist = axis->widths[0].cur;
-            if ( dist < 48 )
-              dist = 48;
-
-            goto Done_Width;
-          }
-        }
-
-        if ( dist < 3 * 64 )
-        {
-          delta  = dist & 63;
-          dist  &= -64;
-
-          if ( delta < 10 )
-            dist += delta;
-
-          else if ( delta < 32 )
-            dist += 10;
-
-          else if ( delta < 54 )
-            dist += 54;
-
-          else
-            dist += delta;
-        }
-        else
-          dist = ( dist + 32 ) & ~63;
-      }
-    }
-    else
-    {
-      /* strong hinting process: snap the stem width to integer pixels */
-      FT_Pos  org_dist = dist;
-
-
-      dist = af_latin2_snap_width( axis->widths, axis->width_count, dist );
-
-      if ( vertical )
-      {
-        /* in the case of vertical hinting, always round */
-        /* the stem heights to integer pixels            */
-
-        if ( dist >= 64 )
-          dist = ( dist + 16 ) & ~63;
-        else
-          dist = 64;
-      }
-      else
-      {
-        if ( AF_LATIN_HINTS_DO_MONO( hints ) )
-        {
-          /* monochrome horizontal hinting: snap widths to integer pixels */
-          /* with a different threshold                                   */
-
-          if ( dist < 64 )
-            dist = 64;
-          else
-            dist = ( dist + 32 ) & ~63;
-        }
-        else
-        {
-          /* for horizontal anti-aliased hinting, we adopt a more subtle */
-          /* approach: we strengthen small stems, round stems whose size */
-          /* is between 1 and 2 pixels to an integer, otherwise nothing  */
-
-          if ( dist < 48 )
-            dist = ( dist + 64 ) >> 1;
-
-          else if ( dist < 128 )
-          {
-            /* We only round to an integer width if the corresponding */
-            /* distortion is less than 1/4 pixel.  Otherwise this     */
-            /* makes everything worse since the diagonals, which are  */
-            /* not hinted, appear a lot bolder or thinner than the    */
-            /* vertical stems.                                        */
-
-            FT_Int  delta;
-
-
-            dist = ( dist + 22 ) & ~63;
-            delta = dist - org_dist;
-            if ( delta < 0 )
-              delta = -delta;
-
-            if ( delta >= 16 )
-            {
-              dist = org_dist;
-              if ( dist < 48 )
-                dist = ( dist + 64 ) >> 1;
-            }
-          }
-          else
-            /* round otherwise to prevent color fringes in LCD mode */
-            dist = ( dist + 32 ) & ~63;
-        }
-      }
-    }
-
-  Done_Width:
-    if ( sign )
-      dist = -dist;
-
-    return dist;
-  }
-
-
-  /* align one stem edge relative to the previous stem edge */
-
-  static void
-  af_latin2_align_linked_edge( AF_GlyphHints  hints,
-                               AF_Dimension   dim,
-                               AF_Edge        base_edge,
-                               AF_Edge        stem_edge )
-  {
-    FT_Pos  dist = stem_edge->opos - base_edge->opos;
-
-    FT_Pos  fitted_width = af_latin2_compute_stem_width( hints, dim, dist,
-                                                         base_edge->flags,
-                                                         stem_edge->flags );
-
-
-    stem_edge->pos = base_edge->pos + fitted_width;
-
-    FT_TRACE5(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "
-                "dist was %.2f, now %.2f\n",
-                stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
-                stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
-  }
-
-
-  static void
-  af_latin2_align_serif_edge( AF_GlyphHints  hints,
-                              AF_Edge        base,
-                              AF_Edge        serif )
-  {
-    FT_UNUSED( hints );
-
-    serif->pos = base->pos + ( serif->opos - base->opos );
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                    E D G E   H I N T I N G                      ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  static void
-  af_latin2_hint_edges( AF_GlyphHints  hints,
-                        AF_Dimension   dim )
-  {
-    AF_AxisHints  axis       = &hints->axis[dim];
-    AF_Edge       edges      = axis->edges;
-    AF_Edge       edge_limit = edges + axis->num_edges;
-    AF_Edge       edge;
-    AF_Edge       anchor     = NULL;
-    FT_Int        has_serifs = 0;
-    FT_Pos        anchor_drift = 0;
-
-
-
-    FT_TRACE5(( "==== hinting %s edges =====\n",
-                dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ));
-
-    /* we begin by aligning all stems relative to the blue zone */
-    /* if needed -- that's only for horizontal edges            */
-
-    if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )
-    {
-      for ( edge = edges; edge < edge_limit; edge++ )
-      {
-        AF_Width  blue;
-        AF_Edge   edge1, edge2;
-
-
-        if ( edge->flags & AF_EDGE_DONE )
-          continue;
-
-        blue  = edge->blue_edge;
-        edge1 = NULL;
-        edge2 = edge->link;
-
-        if ( blue )
-        {
-          edge1 = edge;
-        }
-        else if ( edge2 && edge2->blue_edge )
-        {
-          blue  = edge2->blue_edge;
-          edge1 = edge2;
-          edge2 = edge;
-        }
-
-        if ( !edge1 )
-          continue;
-
-        FT_TRACE5(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "
-                    "was (%.2f)\n",
-                    edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,
-                    edge1->pos / 64.0 ));
-
-        edge1->pos    = blue->fit;
-        edge1->flags |= AF_EDGE_DONE;
-
-        if ( edge2 && !edge2->blue_edge )
-        {
-          af_latin2_align_linked_edge( hints, dim, edge1, edge2 );
-          edge2->flags |= AF_EDGE_DONE;
-        }
-
-        if ( !anchor )
-        {
-          anchor = edge;
-
-          anchor_drift = ( anchor->pos - anchor->opos );
-          if ( edge2 )
-            anchor_drift = ( anchor_drift +
-                             ( edge2->pos - edge2->opos ) ) >> 1;
-        }
-      }
-    }
-
-    /* now we will align all stem edges, trying to maintain the */
-    /* relative order of stems in the glyph                     */
-    for ( edge = edges; edge < edge_limit; edge++ )
-    {
-      AF_Edge  edge2;
-
-
-      if ( edge->flags & AF_EDGE_DONE )
-        continue;
-
-      /* skip all non-stem edges */
-      edge2 = edge->link;
-      if ( !edge2 )
-      {
-        has_serifs++;
-        continue;
-      }
-
-      /* now align the stem */
-
-      /* this should not happen, but it's better to be safe */
-      if ( edge2->blue_edge )
-      {
-        FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
-
-        af_latin2_align_linked_edge( hints, dim, edge2, edge );
-        edge->flags |= AF_EDGE_DONE;
-        continue;
-      }
-
-      if ( !anchor )
-      {
-        FT_Pos  org_len, org_center, cur_len;
-        FT_Pos  cur_pos1, error1, error2, u_off, d_off;
-
-
-        org_len = edge2->opos - edge->opos;
-        cur_len = af_latin2_compute_stem_width( hints, dim, org_len,
-                                                edge->flags,
-                                                edge2->flags );
-        if ( cur_len <= 64 )
-          u_off = d_off = 32;
-        else
-        {
-          u_off = 38;
-          d_off = 26;
-        }
-
-        if ( cur_len < 96 )
-        {
-          org_center = edge->opos + ( org_len >> 1 );
-
-          cur_pos1   = FT_PIX_ROUND( org_center );
-
-          error1 = org_center - ( cur_pos1 - u_off );
-          if ( error1 < 0 )
-            error1 = -error1;
-
-          error2 = org_center - ( cur_pos1 + d_off );
-          if ( error2 < 0 )
-            error2 = -error2;
-
-          if ( error1 < error2 )
-            cur_pos1 -= u_off;
-          else
-            cur_pos1 += d_off;
-
-          edge->pos  = cur_pos1 - cur_len / 2;
-          edge2->pos = edge->pos + cur_len;
-        }
-        else
-          edge->pos = FT_PIX_ROUND( edge->opos );
-
-        FT_TRACE5(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
-                    " snapped to (%.2f) (%.2f)\n",
-                    edge-edges, edge->opos / 64.0,
-                    edge2-edges, edge2->opos / 64.0,
-                    edge->pos / 64.0, edge2->pos / 64.0 ));
-        anchor = edge;
-
-        edge->flags |= AF_EDGE_DONE;
-
-        af_latin2_align_linked_edge( hints, dim, edge, edge2 );
-
-        edge2->flags |= AF_EDGE_DONE;
-
-        anchor_drift = ( ( anchor->pos - anchor->opos ) +
-                         ( edge2->pos - edge2->opos ) ) >> 1;
-
-        FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 ));
-      }
-      else
-      {
-        FT_Pos   org_pos, org_len, org_center, cur_center, cur_len;
-        FT_Pos   org_left, org_right;
-
-
-        org_pos    = edge->opos + anchor_drift;
-        org_len    = edge2->opos - edge->opos;
-        org_center = org_pos + ( org_len >> 1 );
-
-        cur_len = af_latin2_compute_stem_width( hints, dim, org_len,
-                                                edge->flags,
-                                                edge2->flags );
-
-        org_left  = org_pos + ( ( org_len - cur_len ) >> 1 );
-        org_right = org_pos + ( ( org_len + cur_len ) >> 1 );
-
-        FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ",
-                    org_left / 64.0, org_right / 64.0 ));
-        cur_center = org_center;
-
-        if ( edge2->flags & AF_EDGE_DONE )
-        {
-          FT_TRACE5(( "\n" ));
-          edge->pos = edge2->pos - cur_len;
-        }
-        else
-        {
-         /* we want to compare several displacement, and choose
-          * the one that increases fitness while minimizing
-          * distortion as well
-          */
-          FT_Pos   displacements[6], scores[6], org, fit, delta;
-          FT_UInt  count = 0;
-
-          /* note: don't even try to fit tiny stems */
-          if ( cur_len < 32 )
-          {
-            FT_TRACE5(( "tiny stem\n" ));
-            goto AlignStem;
-          }
-
-          /* if the span is within a single pixel, don't touch it */
-          if ( FT_PIX_FLOOR( org_left ) == FT_PIX_CEIL( org_right ) )
-          {
-            FT_TRACE5(( "single pixel stem\n" ));
-            goto AlignStem;
-          }
-
-          if ( cur_len <= 96 )
-          {
-           /* we want to avoid the absolute worst case which is
-            * when the left and right edges of the span each represent
-            * about 50% of the gray. we'd better want to change this
-            * to 25/75%, since this is much more pleasant to the eye with
-            * very acceptable distortion
-            */
-            FT_Pos  frac_left  = org_left  & 63;
-            FT_Pos  frac_right = org_right & 63;
-
-            if ( frac_left  >= 22 && frac_left  <= 42 &&
-                 frac_right >= 22 && frac_right <= 42 )
-            {
-              org = frac_left;
-              fit = ( org <= 32 ) ? 16 : 48;
-              delta = FT_ABS( fit - org );
-              displacements[count] = fit - org;
-              scores[count++]      = delta;
-              FT_TRACE5(( "dispA=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
-
-              org = frac_right;
-              fit = ( org <= 32 ) ? 16 : 48;
-              delta = FT_ABS( fit - org );
-              displacements[count] = fit - org;
-              scores[count++]     = delta;
-              FT_TRACE5(( "dispB=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
-            }
-          }
-
-          /* snapping the left edge to the grid */
-          org   = org_left;
-          fit   = FT_PIX_ROUND( org );
-          delta = FT_ABS( fit - org );
-          displacements[count] = fit - org;
-          scores[count++]      = delta;
-          FT_TRACE5(( "dispC=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
-
-          /* snapping the right edge to the grid */
-          org   = org_right;
-          fit   = FT_PIX_ROUND( org );
-          delta = FT_ABS( fit - org );
-          displacements[count] = fit - org;
-          scores[count++]      = delta;
-          FT_TRACE5(( "dispD=%.2f (%d) ", ( fit - org ) / 64.0, delta ));
-
-          /* now find the best displacement */
-          {
-            FT_Pos  best_score = scores[0];
-            FT_Pos  best_disp  = displacements[0];
-            FT_UInt nn;
-
-            for ( nn = 1; nn < count; nn++ )
-            {
-              if ( scores[nn] < best_score )
-              {
-                best_score = scores[nn];
-                best_disp  = displacements[nn];
-              }
-            }
-
-            cur_center = org_center + best_disp;
-          }
-          FT_TRACE5(( "\n" ));
-        }
-
-      AlignStem:
-        edge->pos  = cur_center - ( cur_len >> 1 );
-        edge2->pos = edge->pos + cur_len;
-
-        FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)"
-                    " snapped to (%.2f) and (%.2f),"
-                    " org_len=%.2f cur_len=%.2f\n",
-                    edge-edges, edge->opos / 64.0,
-                    edge2-edges, edge2->opos / 64.0,
-                    edge->pos / 64.0, edge2->pos / 64.0,
-                    org_len / 64.0, cur_len / 64.0 ));
-
-        edge->flags  |= AF_EDGE_DONE;
-        edge2->flags |= AF_EDGE_DONE;
-
-        if ( edge > edges && edge->pos < edge[-1].pos )
-        {
-          FT_TRACE5(( "BOUND: %d (pos=%.2f) to (%.2f)\n",
-                      edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
-          edge->pos = edge[-1].pos;
-        }
-      }
-    }
-
-    /* make sure that lowercase m's maintain their symmetry */
-
-    /* In general, lowercase m's have six vertical edges if they are sans */
-    /* serif, or twelve if they are with serifs.  This implementation is  */
-    /* based on that assumption, and seems to work very well with most    */
-    /* faces.  However, if for a certain face this assumption is not      */
-    /* true, the m is just rendered like before.  In addition, any stem   */
-    /* correction will only be applied to symmetrical glyphs (even if the */
-    /* glyph is not an m), so the potential for unwanted distortion is    */
-    /* relatively low.                                                    */
-
-    /* We don't handle horizontal edges since we can't easily assure that */
-    /* the third (lowest) stem aligns with the base line; it might end up */
-    /* one pixel higher or lower.                                         */
-
-#if 0
-    {
-      FT_Int  n_edges = edge_limit - edges;
-
-
-      if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) )
-      {
-        AF_Edge  edge1, edge2, edge3;
-        FT_Pos   dist1, dist2, span, delta;
-
-
-        if ( n_edges == 6 )
-        {
-          edge1 = edges;
-          edge2 = edges + 2;
-          edge3 = edges + 4;
-        }
-        else
-        {
-          edge1 = edges + 1;
-          edge2 = edges + 5;
-          edge3 = edges + 9;
-        }
-
-        dist1 = edge2->opos - edge1->opos;
-        dist2 = edge3->opos - edge2->opos;
-
-        span = dist1 - dist2;
-        if ( span < 0 )
-          span = -span;
-
-        if ( span < 8 )
-        {
-          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
-          edge3->pos -= delta;
-          if ( edge3->link )
-            edge3->link->pos -= delta;
-
-          /* move the serifs along with the stem */
-          if ( n_edges == 12 )
-          {
-            ( edges + 8 )->pos -= delta;
-            ( edges + 11 )->pos -= delta;
-          }
-
-          edge3->flags |= AF_EDGE_DONE;
-          if ( edge3->link )
-            edge3->link->flags |= AF_EDGE_DONE;
-        }
-      }
-    }
-#endif
-
-    if ( has_serifs || !anchor )
-    {
-      /*
-       * now hint the remaining edges (serifs and single) in order
-       * to complete our processing
-       */
-      for ( edge = edges; edge < edge_limit; edge++ )
-      {
-        FT_Pos  delta;
-
-
-        if ( edge->flags & AF_EDGE_DONE )
-          continue;
-
-        delta = 1000;
-
-        if ( edge->serif )
-        {
-          delta = edge->serif->opos - edge->opos;
-          if ( delta < 0 )
-            delta = -delta;
-        }
-
-        if ( delta < 64 + 16 )
-        {
-          af_latin2_align_serif_edge( hints, edge->serif, edge );
-          FT_TRACE5(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
-                      " aligned to (%.2f)\n",
-                      edge-edges, edge->opos / 64.0,
-                      edge->serif - edges, edge->serif->opos / 64.0,
-                      edge->pos / 64.0 ));
-        }
-        else if ( !anchor )
-        {
-          FT_TRACE5(( "SERIF_ANCHOR: edge %d (opos=%.2f)"
-                      " snapped to (%.2f)\n",
-                      edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
-          edge->pos = FT_PIX_ROUND( edge->opos );
-          anchor    = edge;
-        }
-        else
-        {
-          AF_Edge  before, after;
-
-
-          for ( before = edge - 1; before >= edges; before-- )
-            if ( before->flags & AF_EDGE_DONE )
-              break;
-
-          for ( after = edge + 1; after < edge_limit; after++ )
-            if ( after->flags & AF_EDGE_DONE )
-              break;
-
-          if ( before >= edges && before < edge   &&
-               after < edge_limit && after > edge )
-          {
-            if ( after->opos == before->opos )
-              edge->pos = before->pos;
-            else
-              edge->pos = before->pos +
-                          FT_MulDiv( edge->opos - before->opos,
-                                     after->pos - before->pos,
-                                     after->opos - before->opos );
-            FT_TRACE5(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
-                        " from %d (opos=%.2f)\n",
-                        edge-edges, edge->opos / 64.0, edge->pos / 64.0,
-                        before - edges, before->opos / 64.0 ));
-          }
-          else
-          {
-            edge->pos = anchor->pos +
-                        ( ( edge->opos - anchor->opos + 16 ) & ~31 );
-
-            FT_TRACE5(( "SERIF_LINK2: edge %d (opos=%.2f)"
-                        " snapped to (%.2f)\n",
-                        edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
-          }
-        }
-
-        edge->flags |= AF_EDGE_DONE;
-
-        if ( edge > edges && edge->pos < edge[-1].pos )
-          edge->pos = edge[-1].pos;
-
-        if ( edge + 1 < edge_limit        &&
-             edge[1].flags & AF_EDGE_DONE &&
-             edge->pos > edge[1].pos      )
-          edge->pos = edge[1].pos;
-      }
-    }
-  }
-
-
-  static FT_Error
-  af_latin2_hints_apply( FT_UInt          glyph_index,
-                         AF_GlyphHints    hints,
-                         FT_Outline*      outline,
-                         AF_LatinMetrics  metrics )
-  {
-    FT_Error  error;
-    int       dim;
-
-    FT_UNUSED( glyph_index );
-
-
-    error = af_glyph_hints_reload( hints, outline );
-    if ( error )
-      goto Exit;
-
-    /* analyze glyph outline */
-    if ( AF_HINTS_DO_HORIZONTAL( hints ) )
-    {
-      error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ );
-      if ( error )
-        goto Exit;
-    }
-
-    if ( AF_HINTS_DO_VERTICAL( hints ) )
-    {
-      error = af_latin2_hints_detect_features( hints, AF_DIMENSION_VERT );
-      if ( error )
-        goto Exit;
-
-      af_latin2_hints_compute_blue_edges( hints, metrics );
-    }
-
-    /* grid-fit the outline */
-    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
-    {
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-      if ( dim == AF_DIMENSION_HORZ                                  &&
-           metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL &&
-           AF_HINTS_DO_WARP( hints )                                 )
-      {
-        AF_WarperRec  warper;
-        FT_Fixed      scale;
-        FT_Pos        delta;
-
-
-        af_warper_compute( &warper, hints, dim, &scale, &delta );
-        af_glyph_hints_scale_dim( hints, dim, scale, delta );
-        continue;
-      }
-#endif /* AF_CONFIG_OPTION_USE_WARPER */
-
-      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
-           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
-      {
-        af_latin2_hint_edges( hints, (AF_Dimension)dim );
-        af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );
-        af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
-        af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );
-      }
-    }
-    af_glyph_hints_save( hints, outline );
-
-  Exit:
-    return error;
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****              L A T I N   S C R I P T   C L A S S              *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  AF_DEFINE_WRITING_SYSTEM_CLASS(
-    af_latin2_writing_system_class,
-
-    AF_WRITING_SYSTEM_LATIN2,
-
-    sizeof ( AF_LatinMetricsRec ),
-
-    (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init,        /* style_metrics_init    */
-    (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale,       /* style_metrics_scale   */
-    (AF_WritingSystem_DoneMetricsFunc) NULL,                          /* style_metrics_done    */
-    (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, /* style_metrics_getstdw */
-
-    (AF_WritingSystem_InitHintsFunc)   af_latin2_hints_init,          /* style_hints_init      */
-    (AF_WritingSystem_ApplyHintsFunc)  af_latin2_hints_apply          /* style_hints_apply     */
-  )
-
-#else /* !FT_OPTION_AUTOFIT2 */
-
-  /* ANSI C doesn't like empty source files */
-  typedef int  _af_latin2_dummy;
-
-#endif /* !FT_OPTION_AUTOFIT2 */
-
-
-/* END */
diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h
deleted file mode 100644
index e8e7382..0000000
--- a/src/autofit/aflatin2.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ATTENTION: This file doesn't compile.  It is only here as a reference */
-/*            of an alternative latin hinting algorithm that was always  */
-/*            marked as experimental.                                    */
-
-
-/****************************************************************************
- *
- * aflatin2.h
- *
- *   Auto-fitter hinting routines for latin writing system
- *   (specification).
- *
- * Copyright 2003-2018 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 AFLATIN2_H_
-#define AFLATIN2_H_
-
-#include "afhints.h"
-
-
-FT_BEGIN_HEADER
-
-
-  /* the `latin' writing system */
-
-  AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin2_writing_system_class )
-
-
-/* */
-
-FT_END_HEADER
-
-#endif /* AFLATIN_H_ */
-
-
-/* END */
diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c
index 301f377..c808279 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter glyph loading routines (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,7 +22,7 @@
 #include "aferrors.h"
 #include "afmodule.h"
 
-#include FT_INTERNAL_CALC_H
+#include <freetype/internal/ftcalc.h>
 
 
   /* Initialize glyph loader. */
@@ -105,7 +105,6 @@
                               globals->stem_darkening_for_ppem;
 
     FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
-    FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );
 
     FT_Matrix  scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };
 
@@ -142,12 +141,11 @@
 
 
       darken_by_font_units_x =
-        af_intToFixed( af_loader_compute_darkening( loader,
-                                                    face,
-                                                    stdVW ) );
-      darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
-                                       size_metrics->x_scale ),
-                            em_ratio );
+         af_loader_compute_darkening( loader,
+                                      face,
+                                      stdVW ) ;
+      darken_x = FT_MulFix( darken_by_font_units_x,
+                            size_metrics->x_scale );
 
       globals->standard_vertical_width = stdVW;
       globals->stem_darkening_for_ppem = size_metrics->x_ppem;
@@ -161,12 +159,11 @@
 
 
       darken_by_font_units_y =
-        af_intToFixed( af_loader_compute_darkening( loader,
-                                                    face,
-                                                    stdHW ) );
-      darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
-                                       size_metrics->y_scale ),
-                            em_ratio );
+         af_loader_compute_darkening( loader,
+                                      face,
+                                      stdHW ) ;
+      darken_y = FT_MulFix( darken_by_font_units_y,
+                            size_metrics->y_scale );
 
       globals->standard_horizontal_width = stdHW;
       globals->stem_darkening_for_ppem   = size_metrics->x_ppem;
@@ -232,9 +229,6 @@
     AF_WritingSystemClass  writing_system_class;
 
 
-    if ( !size )
-      return FT_THROW( Invalid_Size_Handle );
-
     FT_ZERO( &scaler );
 
     if ( !size_internal->autohint_metrics.x_scale                          ||
@@ -300,12 +294,6 @@
     if ( error )
       goto Exit;
 
-#ifdef FT_OPTION_AUTOFIT2
-    /* XXX: undocumented hook to activate the latin2 writing system. */
-    if ( load_flags & ( 1UL << 20 ) )
-      style_options = AF_STYLE_LTN2_DFLT;
-#endif
-
     /*
      * Glyphs (really code points) are assigned to scripts.  Script
      * analysis is done lazily: For each glyph that passes through here,
@@ -421,10 +409,15 @@
       /* now load the slot image into the auto-outline */
       /* and run the automatic hinting process         */
       if ( writing_system_class->style_hints_apply )
-        writing_system_class->style_hints_apply( glyph_index,
-                                                 hints,
-                                                 &gloader->base.outline,
-                                                 style_metrics );
+      {
+        error = writing_system_class->style_hints_apply(
+                  glyph_index,
+                  hints,
+                  &gloader->base.outline,
+                  style_metrics );
+        if ( error )
+          goto Exit;
+      }
 
       /* we now need to adjust the metrics according to the change in */
       /* width/positioning that occurred during the hinting process   */
@@ -477,8 +470,8 @@
           FT_Pos  pp2x = loader->pp2.x;
 
 
-          loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
-          loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
+          loader->pp1.x = FT_PIX_ROUND( pp1x );
+          loader->pp2.x = FT_PIX_ROUND( pp2x );
 
           slot->lsb_delta = loader->pp1.x - pp1x;
           slot->rsb_delta = loader->pp2.x - pp2x;
@@ -589,7 +582,7 @@
    *
    * XXX: Currently a crude adaption of the original algorithm.  Do better?
    */
-  FT_LOCAL_DEF( FT_Int32 )
+  FT_LOCAL_DEF( FT_Fixed )
   af_loader_compute_darkening( AF_Loader  loader,
                                FT_Face    face,
                                FT_Pos     standard_width )
@@ -708,7 +701,7 @@
     }
 
     /* Convert darken_amount from per 1000 em to true character space. */
-    return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) );
+    return FT_DivFix( darken_amount, em_ratio );
   }
 
 
diff --git a/src/autofit/afloader.h b/src/autofit/afloader.h
index 773ff60..e4e197e 100644
--- a/src/autofit/afloader.h
+++ b/src/autofit/afloader.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter glyph loading routines (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -75,7 +75,7 @@
                         FT_UInt    gindex,
                         FT_Int32   load_flags );
 
-  FT_LOCAL_DEF( FT_Int32 )
+  FT_LOCAL( FT_Fixed )
   af_loader_compute_darkening( AF_Loader  loader,
                                FT_Face    face,
                                FT_Pos     standard_width );
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index 7f9f043..92e5156 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter module implementation (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -43,20 +43,20 @@
 
 #endif
 
-  int  _af_debug_disable_horz_hints;
-  int  _af_debug_disable_vert_hints;
-  int  _af_debug_disable_blue_hints;
+  int  af_debug_disable_horz_hints_;
+  int  af_debug_disable_vert_hints_;
+  int  af_debug_disable_blue_hints_;
 
   /* we use a global object instead of a local one for debugging */
-  AF_GlyphHintsRec  _af_debug_hints_rec[1];
+  static AF_GlyphHintsRec  af_debug_hints_rec_[1];
 
-  void*  _af_debug_hints = _af_debug_hints_rec;
+  void*  af_debug_hints_ = af_debug_hints_rec_;
 #endif
 
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_DRIVER_H
-#include FT_SERVICE_PROPERTIES_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftdriver.h>
+#include <freetype/internal/services/svprop.h>
 
 
   /**************************************************************************
@@ -66,7 +66,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_afmodule
+#define FT_COMPONENT  afmodule
 
 
   static FT_Error
@@ -119,8 +119,8 @@
 
     if ( !ft_strcmp( property_name, "fallback-script" ) )
     {
-      FT_UInt*  fallback_script;
-      FT_UInt   ss;
+      AF_Script*  fallback_script;
+      FT_UInt     ss;
 
 
 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
@@ -128,7 +128,7 @@
         return FT_THROW( Invalid_Argument );
 #endif
 
-      fallback_script = (FT_UInt*)value;
+      fallback_script = (AF_Script*)value;
 
       /* We translate the fallback script to a fallback style that uses */
       /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its  */
@@ -138,8 +138,8 @@
         AF_StyleClass  style_class = af_style_classes[ss];
 
 
-        if ( (FT_UInt)style_class->script == *fallback_script &&
-             style_class->coverage == AF_COVERAGE_DEFAULT     )
+        if ( style_class->script   == *fallback_script    &&
+             style_class->coverage == AF_COVERAGE_DEFAULT )
         {
           module->fallback_style = ss;
           break;
@@ -148,8 +148,8 @@
 
       if ( !af_style_classes[ss] )
       {
-        FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n",
-                    fallback_script, property_name ));
+        FT_TRACE2(( "af_property_set: Invalid value %d for property `%s'\n",
+                    *fallback_script, property_name ));
         return FT_THROW( Invalid_Argument );
       }
 
@@ -157,7 +157,7 @@
     }
     else if ( !ft_strcmp( property_name, "default-script" ) )
     {
-      FT_UInt*  default_script;
+      AF_Script*  default_script;
 
 
 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
@@ -165,7 +165,7 @@
         return FT_THROW( Invalid_Argument );
 #endif
 
-      default_script = (FT_UInt*)value;
+      default_script = (AF_Script*)value;
 
       module->default_script = *default_script;
 
@@ -190,35 +190,6 @@
 
       return error;
     }
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    else if ( !ft_strcmp( property_name, "warping" ) )
-    {
-#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
-      if ( value_is_string )
-      {
-        const char*  s = (const char*)value;
-        long         w = ft_strtol( s, NULL, 10 );
-
-
-        if ( w == 0 )
-          module->warping = 0;
-        else if ( w == 1 )
-          module->warping = 1;
-        else
-          return FT_THROW( Invalid_Argument );
-      }
-      else
-#endif
-      {
-        FT_Bool*  warping = (FT_Bool*)value;
-
-
-        module->warping = *warping;
-      }
-
-      return error;
-    }
-#endif /* AF_CONFIG_OPTION_USE_WARPER */
     else if ( !ft_strcmp( property_name, "darkening-parameters" ) )
     {
       FT_Int*  darken_params;
@@ -307,7 +278,7 @@
       return error;
     }
 
-    FT_TRACE0(( "af_property_set: missing property `%s'\n",
+    FT_TRACE2(( "af_property_set: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
@@ -320,11 +291,6 @@
   {
     FT_Error   error          = FT_Err_Ok;
     AF_Module  module         = (AF_Module)ft_module;
-    FT_UInt    fallback_style = module->fallback_style;
-    FT_UInt    default_script = module->default_script;
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    FT_Bool    warping        = module->warping;
-#endif
 
 
     if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
@@ -341,9 +307,9 @@
     }
     else if ( !ft_strcmp( property_name, "fallback-script" ) )
     {
-      FT_UInt*  val = (FT_UInt*)value;
+      AF_Script*  val = (AF_Script*)value;
 
-      AF_StyleClass  style_class = af_style_classes[fallback_style];
+      AF_StyleClass  style_class = af_style_classes[module->fallback_style];
 
 
       *val = style_class->script;
@@ -352,10 +318,10 @@
     }
     else if ( !ft_strcmp( property_name, "default-script" ) )
     {
-      FT_UInt*  val = (FT_UInt*)value;
+      AF_Script*  val = (AF_Script*)value;
 
 
-      *val = default_script;
+      *val = module->default_script;
 
       return error;
     }
@@ -371,17 +337,6 @@
 
       return error;
     }
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    else if ( !ft_strcmp( property_name, "warping" ) )
-    {
-      FT_Bool*  val = (FT_Bool*)value;
-
-
-      *val = warping;
-
-      return error;
-    }
-#endif /* AF_CONFIG_OPTION_USE_WARPER */
     else if ( !ft_strcmp( property_name, "darkening-parameters" ) )
     {
       FT_Int*  darken_params = module->darken_params;
@@ -410,7 +365,7 @@
       return error;
     }
 
-    FT_TRACE0(( "af_property_get: missing property `%s'\n",
+    FT_TRACE2(( "af_property_get: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
@@ -447,9 +402,6 @@
 
     module->fallback_style    = AF_STYLE_FALLBACK;
     module->default_script    = AF_SCRIPT_DEFAULT;
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    module->warping           = 0;
-#endif
     module->no_stem_darkening = TRUE;
 
     module->darken_params[0]  = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
@@ -471,8 +423,8 @@
     FT_UNUSED( ft_module );
 
 #ifdef FT_DEBUG_AUTOFIT
-    if ( _af_debug_hints_rec->memory )
-      af_glyph_hints_done( _af_debug_hints_rec );
+    if ( af_debug_hints_rec_->memory )
+      af_glyph_hints_done( af_debug_hints_rec_ );
 #endif
   }
 
@@ -491,7 +443,7 @@
 
     /* in debug mode, we use a global object that survives this routine */
 
-    AF_GlyphHints  hints = _af_debug_hints_rec;
+    AF_GlyphHints  hints = af_debug_hints_rec_;
     AF_LoaderRec   loader[1];
 
     FT_UNUSED( size );
@@ -507,7 +459,7 @@
                                   glyph_index, load_flags );
 
 #ifdef FT_DEBUG_LEVEL_TRACE
-    if ( ft_trace_levels[FT_COMPONENT] )
+    if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] )
     {
 #endif
       af_glyph_hints_dump_points( hints, 0 );
@@ -550,8 +502,8 @@
     NULL,                                                    /* reset_face */
     NULL,                                              /* get_global_hints */
     NULL,                                             /* done_global_hints */
-    (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph )  /* load_glyph */
-
+    (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph    /* load_glyph */
+  )
 
   FT_DEFINE_MODULE(
     autofit_module_class,
diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h
index 0db6ef0..4b8b456 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter module implementation (specification).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,9 +19,8 @@
 #ifndef AFMODULE_H_
 #define AFMODULE_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_MODULE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
@@ -37,16 +36,14 @@
     FT_ModuleRec  root;
 
     FT_UInt       fallback_style;
-    FT_UInt       default_script;
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-    FT_Bool       warping;
-#endif
+    AF_Script     default_script;
     FT_Bool       no_stem_darkening;
     FT_Int        darken_params[8];
 
   } AF_ModuleRec, *AF_Module;
 
 
+FT_DECLARE_AUTOHINTER_INTERFACE( af_autofitter_interface )
 FT_DECLARE_MODULE( autofit_module_class )
 
 
diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c
index b904d51..cfcaf34 100644
--- a/src/autofit/afranges.c
+++ b/src/autofit/afranges.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter Unicode script ranges (body).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -664,6 +664,33 @@
   };
 
 
+  const AF_Script_UniRangeRec  af_medf_uniranges[] =
+  {
+    AF_UNIRANGE_REC( 0x16E40, 0x16E9F ),  /* Medefaidrin */
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+  const AF_Script_UniRangeRec  af_medf_nonbase_uniranges[] =
+  {
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+
+  const AF_Script_UniRangeRec  af_mong_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1800,  0x18AF ),  /* Mongolian            */
+    AF_UNIRANGE_REC( 0x11660, 0x1167F ),  /* Mongolian Supplement */
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+  const AF_Script_UniRangeRec  af_mong_nonbase_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1885,  0x1886 ),
+    AF_UNIRANGE_REC(  0x18A9,  0x18A9 ),
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+
   const AF_Script_UniRangeRec  af_mymr_uniranges[] =
   {
     AF_UNIRANGE_REC(  0x1000,  0x109F ),    /* Myanmar            */
@@ -763,6 +790,18 @@
   };
 
 
+  const AF_Script_UniRangeRec  af_rohg_uniranges[] =
+  {
+    AF_UNIRANGE_REC( 0x10D00, 0x10D3F ),   /* Hanifi Rohingya */
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+  const AF_Script_UniRangeRec  af_rohg_nonbase_uniranges[] =
+  {
+    AF_UNIRANGE_REC( 0, 0 )
+  };
+
+
   const AF_Script_UniRangeRec  af_saur_uniranges[] =
   {
     AF_UNIRANGE_REC(  0xA880,  0xA8DF ),   /* Saurashtra */
diff --git a/src/autofit/afranges.h b/src/autofit/afranges.h
index c137ae2..5775738 100644
--- a/src/autofit/afranges.h
+++ b/src/autofit/afranges.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter Unicode script ranges (specification).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
index 7dd0983..3a10193 100644
--- a/src/autofit/afscript.h
+++ b/src/autofit/afscript.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter scripts (specification only).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -243,6 +243,18 @@
           HINTING_BOTTOM_TO_TOP,
           "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* ഠ റ */
 
+  SCRIPT( medf, MEDF,
+          "Medefaidrin",
+          HB_SCRIPT_MEDEFAIDRIN,
+          HINTING_BOTTOM_TO_TOP,
+          "\xF0\x96\xB9\xA1 \xF0\x96\xB9\x9B \xF0\x96\xB9\xAF" ) /* 𖹡 𖹛 𖹯 */
+
+  SCRIPT( mong, MONG,
+          "Mongolian",
+          HB_SCRIPT_MONGOLIAN,
+          HINTING_TOP_TO_BOTTOM,
+          "\xE1\xA1\x82 \xE1\xA0\xAA" ) /* ᡂ ᠪ */
+
   SCRIPT( mymr, MYMR,
           "Myanmar",
           HB_SCRIPT_MYANMAR,
@@ -285,6 +297,12 @@
           HINTING_BOTTOM_TO_TOP,
           "\xF0\x90\x92\x86 \xF0\x90\x92\xA0" ) /* 𐒆 𐒠 */
 
+  SCRIPT( rohg, ROHG,
+          "Hanifi Rohingya",
+          HB_SCRIPT_HANIFI_ROHINGYA,
+          HINTING_BOTTOM_TO_TOP,
+          "\xF0\x90\xB4\xB0" ) /* 𐴰 */
+
   SCRIPT( saur, SAUR,
           "Saurashtra",
           HB_SCRIPT_SAURASHTRA,
diff --git a/src/autofit/afshaper.c b/src/autofit/afshaper.c
index b2f5d18..1b8b870 100644
--- a/src/autofit/afshaper.c
+++ b/src/autofit/afshaper.c
@@ -4,7 +4,7 @@
  *
  *   HarfBuzz interface for accessing OpenType features (body).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,9 +16,8 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_ADVANCES_H
+#include <freetype/freetype.h>
+#include <freetype/ftadvanc.h>
 #include "afglobal.h"
 #include "aftypes.h"
 #include "afshaper.h"
@@ -33,7 +32,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_afshaper
+#define FT_COMPONENT  afshaper
 
 
   /*
@@ -133,13 +132,24 @@
     /* Convert a HarfBuzz script tag into the corresponding OpenType */
     /* tag or tags -- some Indic scripts like Devanagari have an old */
     /* and a new set of features.                                    */
-    hb_ot_tags_from_script( script,
-                            &script_tags[0],
-                            &script_tags[1] );
+    {
+      unsigned int  tags_count = 3;
+      hb_tag_t      tags[3];
 
-    /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */
-    /* as the second tag.  We change that to HB_TAG_NONE except for the  */
-    /* default script.                                                   */
+
+      hb_ot_tags_from_script_and_language( script,
+                                           HB_LANGUAGE_INVALID,
+                                           &tags_count,
+                                           tags,
+                                           NULL,
+                                           NULL );
+      script_tags[0] = tags_count > 0 ? tags[0] : HB_TAG_NONE;
+      script_tags[1] = tags_count > 1 ? tags[1] : HB_TAG_NONE;
+      script_tags[2] = tags_count > 2 ? tags[2] : HB_TAG_NONE;
+    }
+
+    /* If the second tag is HB_OT_TAG_DEFAULT_SCRIPT, change that to     */
+    /* HB_TAG_NONE except for the default script.                        */
     if ( default_script )
     {
       if ( script_tags[0] == HB_TAG_NONE )
@@ -158,9 +168,6 @@
       /* HarfBuzz maps them to `DFLT', which we don't want to handle here */
       if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT )
         goto Exit;
-
-      if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT )
-        script_tags[1] = HB_TAG_NONE;
     }
 
     gsub_lookups = hb_set_create();
@@ -174,9 +181,9 @@
     if ( hb_set_is_empty( gsub_lookups ) )
       goto Exit; /* nothing to do */
 
-    FT_TRACE4(( "GSUB lookups (style `%s'):\n"
-                " ",
+    FT_TRACE4(( "GSUB lookups (style `%s'):\n",
                 af_style_names[style_class->style] ));
+    FT_TRACE4(( " " ));
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     count = 0;
@@ -203,12 +210,13 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( !count )
       FT_TRACE4(( " (none)" ));
-    FT_TRACE4(( "\n\n" ));
+    FT_TRACE4(( "\n" ));
+    FT_TRACE4(( "\n" ));
 #endif
 
-    FT_TRACE4(( "GPOS lookups (style `%s'):\n"
-                " ",
+    FT_TRACE4(( "GPOS lookups (style `%s'):\n",
                 af_style_names[style_class->style] ));
+    FT_TRACE4(( " " ));
 
     gpos_lookups = hb_set_create();
     hb_ot_layout_collect_lookups( face,
@@ -243,7 +251,8 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( !count )
       FT_TRACE4(( " (none)" ));
-    FT_TRACE4(( "\n\n" ));
+    FT_TRACE4(( "\n" ));
+    FT_TRACE4(( "\n" ));
 #endif
 
     /*
@@ -354,8 +363,10 @@
     {
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( !( count % 10 ) )
-        FT_TRACE4(( "\n"
-                    "   " ));
+      {
+        FT_TRACE4(( "\n" ));
+        FT_TRACE4(( "   " ));
+      }
 
       FT_TRACE4(( " %d", idx ));
       count++;
@@ -377,9 +388,12 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( !count )
-      FT_TRACE4(( "\n"
-                  "    (none)" ));
-    FT_TRACE4(( "\n\n" ));
+    {
+      FT_TRACE4(( "\n" ));
+      FT_TRACE4(( "    (none)" ));
+    }
+    FT_TRACE4(( "\n" ));
+    FT_TRACE4(( "\n" ));
 #endif
 
   Exit:
diff --git a/src/autofit/afshaper.h b/src/autofit/afshaper.h
index 2665fe2..054a18f 100644
--- a/src/autofit/afshaper.h
+++ b/src/autofit/afshaper.h
@@ -4,7 +4,7 @@
  *
  *   HarfBuzz interface for accessing OpenType features (specification).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,15 +20,14 @@
 #define AFSHAPER_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 
 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
 
 #include <hb.h>
 #include <hb-ot.h>
-#include <hb-ft.h>
+#include "ft-hb.h"
 
 #endif
 
diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
index 55d8b23..73ebef0 100644
--- a/src/autofit/afstyles.h
+++ b/src/autofit/afstyles.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter styles (specification only).
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -299,15 +299,6 @@
          AF_BLUE_STRINGSET_LATP,
          AF_COVERAGE_DEFAULT )
 
-#ifdef FT_OPTION_AUTOFIT2
-  STYLE( ltn2_dflt, LTN2_DFLT,
-         "Latin 2 default style",
-         AF_WRITING_SYSTEM_LATIN2,
-         AF_SCRIPT_LATN,
-         AF_BLUE_STRINGSET_LATN,
-         AF_COVERAGE_DEFAULT )
-#endif
-
   STYLE( lisu_dflt, LISU_DFLT,
          "Lisu default style",
          AF_WRITING_SYSTEM_LATIN,
@@ -322,6 +313,20 @@
          AF_BLUE_STRINGSET_MLYM,
          AF_COVERAGE_DEFAULT )
 
+  STYLE( medf_dflt, MEDF_DFLT,
+         "Medefaidrin default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_MEDF,
+         AF_BLUE_STRINGSET_MEDF,
+         AF_COVERAGE_DEFAULT )
+
+  STYLE( mong_dflt, MONG_DFLT,
+         "Mongolian default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_MONG,
+         AF_BLUE_STRINGSET_MONG,
+         AF_COVERAGE_DEFAULT )
+
   STYLE( mymr_dflt, MYMR_DFLT,
          "Myanmar default style",
          AF_WRITING_SYSTEM_LATIN,
@@ -371,6 +376,13 @@
          AF_BLUE_STRINGSET_OSMA,
          AF_COVERAGE_DEFAULT )
 
+  STYLE( rohg_dflt, ROHG_DFLT,
+         "Hanifi Rohingya default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_ROHG,
+         AF_BLUE_STRINGSET_ROHG,
+         AF_COVERAGE_DEFAULT )
+
   STYLE( saur_dflt, SAUR_DFLT,
          "Saurashtra default style",
          AF_WRITING_SYSTEM_LATIN,
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index affb81b..6615194 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter types (specification only).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -32,12 +32,11 @@
 #ifndef AFTYPES_H_
 #define AFTYPES_H_
 
-#include <ft2build.h>
 
-#include FT_FREETYPE_H
-#include FT_OUTLINE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/freetype.h>
+#include <freetype/ftoutln.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "afblue.h"
 
@@ -58,10 +57,10 @@
 
 #ifdef FT_DEBUG_AUTOFIT
 
-extern int    _af_debug_disable_horz_hints;
-extern int    _af_debug_disable_vert_hints;
-extern int    _af_debug_disable_blue_hints;
-extern void*  _af_debug_hints;
+extern int    af_debug_disable_horz_hints_;
+extern int    af_debug_disable_vert_hints_;
+extern int    af_debug_disable_blue_hints_;
+extern void*  af_debug_hints_;
 
 #endif /* FT_DEBUG_AUTOFIT */
 
@@ -93,63 +92,6 @@
                                FT_Pos    threshold );
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                   A N G L E   T Y P E S                       *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /*
-   * The auto-fitter doesn't need a very high angular accuracy;
-   * this allows us to speed up some computations considerably with a
-   * light Cordic algorithm (see afangles.c).
-   */
-
-  typedef FT_Int  AF_Angle;
-
-
-#define AF_ANGLE_PI   256
-#define AF_ANGLE_2PI  ( AF_ANGLE_PI * 2 )
-#define AF_ANGLE_PI2  ( AF_ANGLE_PI / 2 )
-#define AF_ANGLE_PI4  ( AF_ANGLE_PI / 4 )
-
-
-#if 0
-  /*
-   * compute the angle of a given 2-D vector
-   */
-  FT_LOCAL( AF_Angle )
-  af_angle_atan( FT_Pos  dx,
-                 FT_Pos  dy );
-
-
-  /*
-   * compute `angle2 - angle1'; the result is always within
-   * the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]
-   */
-  FT_LOCAL( AF_Angle )
-  af_angle_diff( AF_Angle  angle1,
-                 AF_Angle  angle2 );
-#endif /* 0 */
-
-
-#define AF_ANGLE_DIFF( result, angle1, angle2 ) \
-  FT_BEGIN_STMNT                                \
-    AF_Angle  _delta = (angle2) - (angle1);     \
-                                                \
-                                                \
-    while ( _delta <= -AF_ANGLE_PI )            \
-      _delta += AF_ANGLE_2PI;                   \
-                                                \
-    while ( _delta > AF_ANGLE_PI )              \
-      _delta -= AF_ANGLE_2PI;                   \
-                                                \
-    result = _delta;                            \
-  FT_END_STMNT
-
-
   /*
    * opaque handle to glyph-specific hints -- see `afhints.h' for more
    * details
@@ -173,18 +115,17 @@
 #define AF_SCALER_FLAG_NO_HORIZONTAL  1U /* disable horizontal hinting */
 #define AF_SCALER_FLAG_NO_VERTICAL    2U /* disable vertical hinting   */
 #define AF_SCALER_FLAG_NO_ADVANCE     4U /* disable advance hinting    */
-#define AF_SCALER_FLAG_NO_WARPER      8U /* disable warper             */
 
 
   typedef struct  AF_ScalerRec_
   {
-    FT_Face         face;        /* source font face                        */
-    FT_Fixed        x_scale;     /* from font units to 1/64th device pixels */
-    FT_Fixed        y_scale;     /* from font units to 1/64th device pixels */
-    FT_Pos          x_delta;     /* in 1/64th device pixels                 */
-    FT_Pos          y_delta;     /* in 1/64th device pixels                 */
-    FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.     */
-    FT_UInt32       flags;       /* additional control flags, see above     */
+    FT_Face         face;        /* source font face                      */
+    FT_Fixed        x_scale;     /* from font units to 1/64 device pixels */
+    FT_Fixed        y_scale;     /* from font units to 1/64 device pixels */
+    FT_Pos          x_delta;     /* in 1/64 device pixels                 */
+    FT_Pos          y_delta;     /* in 1/64 device pixels                 */
+    FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.   */
+    FT_UInt32       flags;       /* additional control flags, see above   */
 
   } AF_ScalerRec, *AF_Scaler;
 
@@ -257,7 +198,6 @@
    *   outline according to the results of the glyph analyzer.
    */
 
-#define AFWRTSYS_H_  /* don't load header files */
 #undef  WRITING_SYSTEM
 #define WRITING_SYSTEM( ws, WS )    \
           AF_WRITING_SYSTEM_ ## WS,
@@ -266,14 +206,12 @@
   typedef enum  AF_WritingSystem_
   {
 
-#include "afwrtsys.h"
+#include "afws-iter.h"
 
     AF_WRITING_SYSTEM_MAX   /* do not remove */
 
   } AF_WritingSystem;
 
-#undef  AFWRTSYS_H_
-
 
   typedef struct  AF_WritingSystemClassRec_
   {
diff --git a/src/autofit/afwarp.c b/src/autofit/afwarp.c
deleted file mode 100644
index 636f01f..0000000
--- a/src/autofit/afwarp.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/****************************************************************************
- *
- * afwarp.c
- *
- *   Auto-fitter warping algorithm (body).
- *
- * Copyright 2006-2018 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.
- *
- */
-
-
-  /*
-   * The idea of the warping code is to slightly scale and shift a glyph
-   * within a single dimension so that as much of its segments are aligned
-   * (more or less) on the grid.  To find out the optimal scaling and
-   * shifting value, various parameter combinations are tried and scored.
-   */
-
-#include "afwarp.h"
-
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-
-  /**************************************************************************
-   *
-   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
-   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
-   * messages during execution.
-   */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_afwarp
-
-
-  /* The weights cover the range 0/64 - 63/64 of a pixel.  Obviously, */
-  /* values around a half pixel (which means exactly between two grid */
-  /* lines) gets the worst weight.                                    */
-#if 1
-  static const AF_WarpScore
-  af_warper_weights[64] =
-  {
-    35, 32, 30, 25, 20, 15, 12, 10,  5,  1,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0,  0,  0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30,
-
-   -30,-30,-20,-20,-10,-10, -8, -5, -2, -1,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0,  0,  0,  0,  1,  5, 10, 12, 15, 20, 25, 30, 32,
-  };
-#else
-  static const AF_WarpScore
-  af_warper_weights[64] =
-  {
-    30, 20, 10,  5,  4,  4,  3,  2,  1,  0,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0,  0,  0,  0, -1, -2, -2, -5, -5,-10,-10,-15,-20,
-
-   -20,-15,-15,-10,-10, -5, -5, -2, -2, -1,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  4,  5, 10, 20,
-  };
-#endif
-
-
-  /* Score segments for a given `scale' and `delta' in the range */
-  /* `xx1' to `xx2', and store the best result in `warper'.  If  */
-  /* the new best score is equal to the old one, prefer the      */
-  /* value with a smaller distortion (around `base_distort').    */
-
-  static void
-  af_warper_compute_line_best( AF_Warper     warper,
-                               FT_Fixed      scale,
-                               FT_Pos        delta,
-                               FT_Pos        xx1,
-                               FT_Pos        xx2,
-                               AF_WarpScore  base_distort,
-                               AF_Segment    segments,
-                               FT_Int        num_segments )
-  {
-    FT_Int        idx_min, idx_max, idx0;
-    FT_Int        nn;
-    AF_WarpScore  scores[65];
-
-
-    for ( nn = 0; nn < 65; nn++ )
-      scores[nn] = 0;
-
-    idx0 = xx1 - warper->t1;
-
-    /* compute minimum and maximum indices */
-    {
-      FT_Pos  xx1min = warper->x1min;
-      FT_Pos  xx1max = warper->x1max;
-      FT_Pos  w      = xx2 - xx1;
-
-
-      if ( xx1min + w < warper->x2min )
-        xx1min = warper->x2min - w;
-
-      if ( xx1max + w > warper->x2max )
-        xx1max = warper->x2max - w;
-
-      idx_min = xx1min - warper->t1;
-      idx_max = xx1max - warper->t1;
-
-      if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
-      {
-        FT_TRACE5(( "invalid indices:\n"
-                    "  min=%d max=%d, xx1=%ld xx2=%ld,\n"
-                    "  x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
-                    idx_min, idx_max, xx1, xx2,
-                    warper->x1min, warper->x1max,
-                    warper->x2min, warper->x2max ));
-        return;
-      }
-    }
-
-    for ( nn = 0; nn < num_segments; nn++ )
-    {
-      FT_Pos  len = segments[nn].max_coord - segments[nn].min_coord;
-      FT_Pos  y0  = FT_MulFix( segments[nn].pos, scale ) + delta;
-      FT_Pos  y   = y0 + ( idx_min - idx0 );
-      FT_Int  idx;
-
-
-      /* score the length of the segments for the given range */
-      for ( idx = idx_min; idx <= idx_max; idx++, y++ )
-        scores[idx] += af_warper_weights[y & 63] * len;
-    }
-
-    /* find best score */
-    {
-      FT_Int  idx;
-
-
-      for ( idx = idx_min; idx <= idx_max; idx++ )
-      {
-        AF_WarpScore  score = scores[idx];
-        AF_WarpScore  distort = base_distort + ( idx - idx0 );
-
-
-        if ( score > warper->best_score         ||
-             ( score == warper->best_score    &&
-               distort < warper->best_distort ) )
-        {
-          warper->best_score   = score;
-          warper->best_distort = distort;
-          warper->best_scale   = scale;
-          warper->best_delta   = delta + ( idx - idx0 );
-        }
-      }
-    }
-  }
-
-
-  /* Compute optimal scaling and delta values for a given glyph and */
-  /* dimension.                                                     */
-
-  FT_LOCAL_DEF( void )
-  af_warper_compute( AF_Warper      warper,
-                     AF_GlyphHints  hints,
-                     AF_Dimension   dim,
-                     FT_Fixed      *a_scale,
-                     FT_Pos        *a_delta )
-  {
-    AF_AxisHints  axis;
-    AF_Point      points;
-
-    FT_Fixed      org_scale;
-    FT_Pos        org_delta;
-
-    FT_Int        nn, num_points, num_segments;
-    FT_Int        X1, X2;
-    FT_Int        w;
-
-    AF_WarpScore  base_distort;
-    AF_Segment    segments;
-
-
-    /* get original scaling transformation */
-    if ( dim == AF_DIMENSION_VERT )
-    {
-      org_scale = hints->y_scale;
-      org_delta = hints->y_delta;
-    }
-    else
-    {
-      org_scale = hints->x_scale;
-      org_delta = hints->x_delta;
-    }
-
-    warper->best_scale   = org_scale;
-    warper->best_delta   = org_delta;
-    warper->best_score   = FT_INT_MIN;
-    warper->best_distort = 0;
-
-    axis         = &hints->axis[dim];
-    segments     = axis->segments;
-    num_segments = axis->num_segments;
-    points       = hints->points;
-    num_points   = hints->num_points;
-
-    *a_scale = org_scale;
-    *a_delta = org_delta;
-
-    /* get X1 and X2, minimum and maximum in original coordinates */
-    if ( num_segments < 1 )
-      return;
-
-#if 1
-    X1 = X2 = points[0].fx;
-    for ( nn = 1; nn < num_points; nn++ )
-    {
-      FT_Int  X = points[nn].fx;
-
-
-      if ( X < X1 )
-        X1 = X;
-      if ( X > X2 )
-        X2 = X;
-    }
-#else
-    X1 = X2 = segments[0].pos;
-    for ( nn = 1; nn < num_segments; nn++ )
-    {
-      FT_Int  X = segments[nn].pos;
-
-
-      if ( X < X1 )
-        X1 = X;
-      if ( X > X2 )
-        X2 = X;
-    }
-#endif
-
-    if ( X1 >= X2 )
-      return;
-
-    warper->x1 = FT_MulFix( X1, org_scale ) + org_delta;
-    warper->x2 = FT_MulFix( X2, org_scale ) + org_delta;
-
-    warper->t1 = AF_WARPER_FLOOR( warper->x1 );
-    warper->t2 = AF_WARPER_CEIL( warper->x2 );
-
-    /* examine a half pixel wide range around the maximum coordinates */
-    warper->x1min = warper->x1 & ~31;
-    warper->x1max = warper->x1min + 32;
-    warper->x2min = warper->x2 & ~31;
-    warper->x2max = warper->x2min + 32;
-
-    if ( warper->x1max > warper->x2 )
-      warper->x1max = warper->x2;
-
-    if ( warper->x2min < warper->x1 )
-      warper->x2min = warper->x1;
-
-    warper->w0 = warper->x2 - warper->x1;
-
-    if ( warper->w0 <= 64 )
-    {
-      warper->x1max = warper->x1;
-      warper->x2min = warper->x2;
-    }
-
-    /* examine (at most) a pixel wide range around the natural width */
-    warper->wmin = warper->x2min - warper->x1max;
-    warper->wmax = warper->x2max - warper->x1min;
-
-#if 1
-    /* some heuristics to reduce the number of widths to be examined */
-    {
-      int  margin = 16;
-
-
-      if ( warper->w0 <= 128 )
-      {
-         margin = 8;
-         if ( warper->w0 <= 96 )
-           margin = 4;
-      }
-
-      if ( warper->wmin < warper->w0 - margin )
-        warper->wmin = warper->w0 - margin;
-
-      if ( warper->wmax > warper->w0 + margin )
-        warper->wmax = warper->w0 + margin;
-    }
-
-    if ( warper->wmin < warper->w0 * 3 / 4 )
-      warper->wmin = warper->w0 * 3 / 4;
-
-    if ( warper->wmax > warper->w0 * 5 / 4 )
-      warper->wmax = warper->w0 * 5 / 4;
-#else
-    /* no scaling, just translation */
-    warper->wmin = warper->wmax = warper->w0;
-#endif
-
-    for ( w = warper->wmin; w <= warper->wmax; w++ )
-    {
-      FT_Fixed  new_scale;
-      FT_Pos    new_delta;
-      FT_Pos    xx1, xx2;
-
-
-      /* compute min and max positions for given width,       */
-      /* assuring that they stay within the coordinate ranges */
-      xx1 = warper->x1;
-      xx2 = warper->x2;
-      if ( w >= warper->w0 )
-      {
-        xx1 -= w - warper->w0;
-        if ( xx1 < warper->x1min )
-        {
-          xx2 += warper->x1min - xx1;
-          xx1  = warper->x1min;
-        }
-      }
-      else
-      {
-        xx1 -= w - warper->w0;
-        if ( xx1 > warper->x1max )
-        {
-          xx2 -= xx1 - warper->x1max;
-          xx1  = warper->x1max;
-        }
-      }
-
-      if ( xx1 < warper->x1 )
-        base_distort = warper->x1 - xx1;
-      else
-        base_distort = xx1 - warper->x1;
-
-      if ( xx2 < warper->x2 )
-        base_distort += warper->x2 - xx2;
-      else
-        base_distort += xx2 - warper->x2;
-
-      /* give base distortion a greater weight while scoring */
-      base_distort *= 10;
-
-      new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 );
-      new_delta = xx1 - FT_MulFix( X1, new_scale );
-
-      af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2,
-                                   base_distort,
-                                   segments, num_segments );
-    }
-
-    {
-      FT_Fixed  best_scale = warper->best_scale;
-      FT_Pos    best_delta = warper->best_delta;
-
-
-      hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale )
-                          + best_delta;
-      hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale )
-                          + best_delta;
-
-      *a_scale = best_scale;
-      *a_delta = best_delta;
-    }
-  }
-
-#else /* !AF_CONFIG_OPTION_USE_WARPER */
-
-  /* ANSI C doesn't like empty source files */
-  typedef int  _af_warp_dummy;
-
-#endif /* !AF_CONFIG_OPTION_USE_WARPER */
-
-/* END */
diff --git a/src/autofit/afwarp.h b/src/autofit/afwarp.h
deleted file mode 100644
index d454dfb..0000000
--- a/src/autofit/afwarp.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
- *
- * afwarp.h
- *
- *   Auto-fitter warping algorithm (specification).
- *
- * Copyright 2006-2018 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 AFWARP_H_
-#define AFWARP_H_
-
-#include "afhints.h"
-
-FT_BEGIN_HEADER
-
-#define AF_WARPER_SCALE
-
-#define AF_WARPER_FLOOR( x )  ( (x) & ~FT_TYPEOF( x )63 )
-#define AF_WARPER_CEIL( x )   AF_WARPER_FLOOR( (x) + 63 )
-
-
-  typedef FT_Int32  AF_WarpScore;
-
-  typedef struct  AF_WarperRec_
-  {
-    FT_Pos        x1, x2;
-    FT_Pos        t1, t2;
-    FT_Pos        x1min, x1max;
-    FT_Pos        x2min, x2max;
-    FT_Pos        w0, wmin, wmax;
-
-    FT_Fixed      best_scale;
-    FT_Pos        best_delta;
-    AF_WarpScore  best_score;
-    AF_WarpScore  best_distort;
-
-  } AF_WarperRec, *AF_Warper;
-
-
-#ifdef AF_CONFIG_OPTION_USE_WARPER
-  FT_LOCAL( void )
-  af_warper_compute( AF_Warper      warper,
-                     AF_GlyphHints  hints,
-                     AF_Dimension   dim,
-                     FT_Fixed      *a_scale,
-                     FT_Fixed      *a_delta );
-#endif
-
-
-FT_END_HEADER
-
-
-#endif /* AFWARP_H_ */
-
-
-/* END */
diff --git a/src/autofit/afwrtsys.h b/src/autofit/afwrtsys.h
deleted file mode 100644
index 20311da..0000000
--- a/src/autofit/afwrtsys.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
- *
- * afwrtsys.h
- *
- *   Auto-fitter writing systems (specification only).
- *
- * Copyright 2013-2018 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 AFWRTSYS_H_
-#define AFWRTSYS_H_
-
-  /* Since preprocessor directives can't create other preprocessor */
-  /* directives, we have to include the header files manually.     */
-
-#include "afdummy.h"
-#include "aflatin.h"
-#include "afcjk.h"
-#include "afindic.h"
-#ifdef FT_OPTION_AUTOFIT2
-#include "aflatin2.h"
-#endif
-
-#endif /* AFWRTSYS_H_ */
-
-
-  /* The following part can be included multiple times. */
-  /* Define `WRITING_SYSTEM' as needed.                 */
-
-
-  /* Add new writing systems here.  The arguments are the writing system */
-  /* name in lowercase and uppercase, respectively.                      */
-
-  WRITING_SYSTEM( dummy,  DUMMY  )
-  WRITING_SYSTEM( latin,  LATIN  )
-  WRITING_SYSTEM( cjk,    CJK    )
-  WRITING_SYSTEM( indic,  INDIC  )
-#ifdef FT_OPTION_AUTOFIT2
-  WRITING_SYSTEM( latin2, LATIN2 )
-#endif
-
-
-/* END */
diff --git a/src/autofit/afws-decl.h b/src/autofit/afws-decl.h
new file mode 100644
index 0000000..48c888a
--- /dev/null
+++ b/src/autofit/afws-decl.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ *
+ * afws-decl.h
+ *
+ *   Auto-fitter writing system declarations (specification only).
+ *
+ * Copyright (C) 2013-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 AFWS_DECL_H_
+#define AFWS_DECL_H_
+
+  /* Since preprocessor directives can't create other preprocessor */
+  /* directives, we have to include the header files manually.     */
+
+#include "afdummy.h"
+#include "aflatin.h"
+#include "afcjk.h"
+#include "afindic.h"
+
+#endif /* AFWS_DECL_H_ */
+
+
+/* END */
diff --git a/src/autofit/afws-iter.h b/src/autofit/afws-iter.h
new file mode 100644
index 0000000..a0a686f
--- /dev/null
+++ b/src/autofit/afws-iter.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ *
+ * afws-iter.h
+ *
+ *   Auto-fitter writing systems iterator (specification only).
+ *
+ * Copyright (C) 2013-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.
+ *
+ */
+
+  /* This header may be included multiple times. */
+  /* Define `WRITING_SYSTEM' as needed.          */
+
+
+  /* Add new writing systems here.  The arguments are the writing system */
+  /* name in lowercase and uppercase, respectively.                      */
+
+  WRITING_SYSTEM( dummy, DUMMY )
+  WRITING_SYSTEM( latin, LATIN )
+  WRITING_SYSTEM( cjk,   CJK   )
+  WRITING_SYSTEM( indic, INDIC )
+
+
+/* END */
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index 1fba44a..8bd609b 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -4,7 +4,7 @@
  *
  *   Auto-fitter module (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,9 +17,8 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
-#include "afangles.c"
+#include "ft-hb.c"
 #include "afblue.c"
 #include "afcjk.c"
 #include "afdummy.c"
@@ -27,12 +26,10 @@
 #include "afhints.c"
 #include "afindic.c"
 #include "aflatin.c"
-#include "aflatin2.c"
 #include "afloader.c"
 #include "afmodule.c"
 #include "afranges.c"
 #include "afshaper.c"
-#include "afwarp.c"
 
 
 /* END */
diff --git a/src/autofit/ft-hb.c b/src/autofit/ft-hb.c
new file mode 100644
index 0000000..09a8401
--- /dev/null
+++ b/src/autofit/ft-hb.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2009, 2023  Red Hat, Inc.
+ * Copyright © 2015  Google, Inc.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod, Matthias Clasen
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include <freetype/freetype.h>
+#include <freetype/tttables.h>
+
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+
+#include "ft-hb.h"
+
+/* The following three functions are a more or less verbatim
+ * copy of corresponding HarfBuzz code from hb-ft.cc
+ */
+
+static hb_blob_t *
+hb_ft_reference_table_ (hb_face_t *face, hb_tag_t tag, void *user_data)
+{
+  FT_Face ft_face = (FT_Face) user_data;
+  FT_Byte *buffer;
+  FT_ULong  length = 0;
+  FT_Error error;
+
+  FT_UNUSED (face);
+
+  /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
+
+  error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
+  if (error)
+    return NULL;
+
+  buffer = (FT_Byte *) ft_smalloc (length);
+  if (!buffer)
+    return NULL;
+
+  error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
+  if (error)
+  {
+    free (buffer);
+    return NULL;
+  }
+
+  return hb_blob_create ((const char *) buffer, length,
+                         HB_MEMORY_MODE_WRITABLE,
+                         buffer, ft_sfree);
+}
+
+static hb_face_t *
+hb_ft_face_create_ (FT_Face           ft_face,
+                    hb_destroy_func_t destroy)
+{
+  hb_face_t *face;
+
+  if (!ft_face->stream->read) {
+    hb_blob_t *blob;
+
+    blob = hb_blob_create ((const char *) ft_face->stream->base,
+                           (unsigned int) ft_face->stream->size,
+                           HB_MEMORY_MODE_READONLY,
+                           ft_face, destroy);
+    face = hb_face_create (blob, ft_face->face_index);
+    hb_blob_destroy (blob);
+  } else {
+    face = hb_face_create_for_tables (hb_ft_reference_table_, ft_face, destroy);
+  }
+
+  hb_face_set_index (face, ft_face->face_index);
+  hb_face_set_upem (face, ft_face->units_per_EM);
+
+  return face;
+}
+
+FT_LOCAL_DEF(hb_font_t *)
+hb_ft_font_create_ (FT_Face           ft_face,
+                    hb_destroy_func_t destroy)
+{
+  hb_font_t *font;
+  hb_face_t *face;
+
+  face = hb_ft_face_create_ (ft_face, destroy);
+  font = hb_font_create (face);
+  hb_face_destroy (face);
+  return font;
+}
+
+#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+/* ANSI C doesn't like empty source files */
+typedef int  _ft_hb_dummy;
+
+#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+/* END */
diff --git a/src/autofit/ft-hb.h b/src/autofit/ft-hb.h
new file mode 100644
index 0000000..92a5774
--- /dev/null
+++ b/src/autofit/ft-hb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2009, 2023  Red Hat, Inc.
+ * Copyright © 2015  Google, Inc.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod, Matthias Clasen
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef FT_HB_H
+#define FT_HB_H
+
+#include <hb.h>
+
+#include <freetype/internal/compiler-macros.h>
+#include <freetype/freetype.h>
+
+
+FT_BEGIN_HEADER
+
+FT_LOCAL(hb_font_t *)
+hb_ft_font_create_ (FT_Face           ft_face,
+                    hb_destroy_func_t destroy);
+
+
+FT_END_HEADER
+
+#endif /* FT_HB_H */
+
+
+/* END */
diff --git a/src/autofit/module.mk b/src/autofit/module.mk
index ff05f83..95cb20a 100644
--- a/src/autofit/module.mk
+++ b/src/autofit/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2003-2018 by
+# Copyright (C) 2003-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/autofit/rules.mk b/src/autofit/rules.mk
index 7295dc0..a46ba3f 100644
--- a/src/autofit/rules.mk
+++ b/src/autofit/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2003-2018 by
+# Copyright (C) 2003-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -28,8 +28,7 @@
 
 # AUTOF driver sources (i.e., C files)
 #
-AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \
-                 $(AUTOF_DIR)/afblue.c   \
+AUTOF_DRV_SRC := $(AUTOF_DIR)/afblue.c   \
                  $(AUTOF_DIR)/afcjk.c    \
                  $(AUTOF_DIR)/afdummy.c  \
                  $(AUTOF_DIR)/afglobal.c \
@@ -40,17 +39,18 @@
                  $(AUTOF_DIR)/afmodule.c \
                  $(AUTOF_DIR)/afranges.c \
                  $(AUTOF_DIR)/afshaper.c \
-                 $(AUTOF_DIR)/afwarp.c
+                 $(AUTOF_DIR)/ft-hb.c
 
 # AUTOF driver headers
 #
-AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h)  \
-               $(AUTOF_DIR)/afcover.h  \
-               $(AUTOF_DIR)/aferrors.h \
-               $(AUTOF_DIR)/afscript.h \
-               $(AUTOF_DIR)/afstyles.h \
-               $(AUTOF_DIR)/aftypes.h  \
-               $(AUTOF_DIR)/afwrtsys.h
+AUTOF_DRV_H := $(AUTOF_DRV_SRC:%c=%h)   \
+               $(AUTOF_DIR)/afcover.h   \
+               $(AUTOF_DIR)/aferrors.h  \
+               $(AUTOF_DIR)/afscript.h  \
+               $(AUTOF_DIR)/afstyles.h  \
+               $(AUTOF_DIR)/aftypes.h   \
+               $(AUTOF_DIR)/afws-decl.h \
+               $(AUTOF_DIR)/afws-iter.h
 
 
 # AUTOF driver object(s)
diff --git a/src/base/Jamfile b/src/base/Jamfile
deleted file mode 100644
index 5bee6e2..0000000
--- a/src/base/Jamfile
+++ /dev/null
@@ -1,90 +0,0 @@
-# FreeType 2 src/base Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) base ;
-
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = basepic
-               ftadvanc
-               ftcalc
-               ftcolor
-               ftdbgmem
-               ftfntfmt
-               ftgloadr
-               fthash
-               ftlcdfil
-               ftobjs
-               ftoutln
-               ftpic
-               ftpsprop
-               ftrfork
-               ftsnames
-               ftstream
-               fttrigon
-               ftutil
-               ;
-  }
-  else
-  {
-    _sources = ftbase ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# Add the optional/replaceable files.
-#
-{
-  local  _sources = ftapi
-                    ftbbox
-                    ftbdf
-                    ftbitmap
-                    ftcid
-                    ftdebug
-                    ftfstype
-                    ftgasp
-                    ftglyph
-                    ftgxval
-                    ftinit
-                    ftmm
-                    ftotval
-                    ftpatent
-                    ftpfr
-                    ftstroke
-                    ftsynth
-                    ftsystem
-                    fttype1
-                    ftwinfnt
-                    ;
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# Add Macintosh-specific file to the library when necessary.
-#
-if $(MAC)
-{
-  Library  $(FT2_LIB) : ftmac.c ;
-}
-else if $(OS) = MACOSX
-{
-  if $(FT2_MULTI)
-  {
-    Library  $(FT2_LIB) : ftmac.c ;
-  }
-}
-
-# end of src/base Jamfile
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c
index 22f4ec9..de25476 100644
--- a/src/base/ftadvanc.c
+++ b/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
  *
  *   Quick computation of advance widths (body).
  *
- * Copyright 2008-2018 by
+ * Copyright (C) 2008-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,15 +16,14 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_ADVANCES_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftadvanc.h>
+#include <freetype/internal/ftobjs.h>
 
 
   static FT_Error
-  _ft_face_scale_advances( FT_Face    face,
+  ft_face_scale_advances_( FT_Face    face,
                            FT_Fixed*  advances,
                            FT_UInt    count,
                            FT_Int32   flags )
@@ -97,7 +96,7 @@
 
       error = func( face, gindex, 1, flags, padvance );
       if ( !error )
-        return _ft_face_scale_advances( face, padvance, 1, flags );
+        return ft_face_scale_advances_( face, padvance, 1, flags );
 
       if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
         return error;
@@ -143,7 +142,7 @@
     {
       error = func( face, start, count, flags, padvances );
       if ( !error )
-        return _ft_face_scale_advances( face, padvances, count, flags );
+        return ft_face_scale_advances_( face, padvances, count, flags );
 
       if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
         return error;
diff --git a/src/base/ftapi.c b/src/base/ftapi.c
deleted file mode 100644
index 2e6f942..0000000
--- a/src/base/ftapi.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
- *
- * ftapi.c
- *
- *   The FreeType compatibility functions (body).
- *
- * Copyright 2002-2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- * This file is part of the FreeType project, and may only be used,
- * modified, and distributed under the terms of the FreeType project
- * license, LICENSE.TXT.  By continuing to use, modify, or distribute
- * this file you indicate that you have read the license and
- * understand and accept it fully.
- *
- */
-
-
-#include <ft2build.h>
-#include FT_LIST_H
-#include FT_OUTLINE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_OUTLINE_H
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****                 C O M P A T I B I L I T Y                       ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* backward compatibility API */
-
-  FT_BASE_DEF( void )
-  FT_New_Memory_Stream( FT_Library  library,
-                        FT_Byte*    base,
-                        FT_ULong    size,
-                        FT_Stream   stream )
-  {
-    FT_UNUSED( library );
-
-    FT_Stream_OpenMemory( stream, base, size );
-  }
-
-
-  FT_BASE_DEF( FT_Error )
-  FT_Seek_Stream( FT_Stream  stream,
-                  FT_ULong   pos )
-  {
-    return FT_Stream_Seek( stream, pos );
-  }
-
-
-  FT_BASE_DEF( FT_Error )
-  FT_Skip_Stream( FT_Stream  stream,
-                  FT_Long    distance )
-  {
-    return FT_Stream_Skip( stream, distance );
-  }
-
-
-  FT_BASE_DEF( FT_Error )
-  FT_Read_Stream( FT_Stream  stream,
-                  FT_Byte*   buffer,
-                  FT_ULong   count )
-  {
-    return FT_Stream_Read( stream, buffer, count );
-  }
-
-
-  FT_BASE_DEF( FT_Error )
-  FT_Read_Stream_At( FT_Stream  stream,
-                     FT_ULong   pos,
-                     FT_Byte*   buffer,
-                     FT_ULong   count )
-  {
-    return FT_Stream_ReadAt( stream, pos, buffer, count );
-  }
-
-
-  FT_BASE_DEF( FT_Error )
-  FT_Extract_Frame( FT_Stream  stream,
-                    FT_ULong   count,
-                    FT_Byte**  pbytes )
-  {
-    return FT_Stream_ExtractFrame( stream, count, pbytes );
-  }
-
-
-  FT_BASE_DEF( void )
-  FT_Release_Frame( FT_Stream  stream,
-                    FT_Byte**  pbytes )
-  {
-    FT_Stream_ReleaseFrame( stream, pbytes );
-  }
-
-  FT_BASE_DEF( FT_Error )
-  FT_Access_Frame( FT_Stream  stream,
-                   FT_ULong   count )
-  {
-    return FT_Stream_EnterFrame( stream, count );
-  }
-
-
-  FT_BASE_DEF( void )
-  FT_Forget_Frame( FT_Stream  stream )
-  {
-    FT_Stream_ExitFrame( stream );
-  }
-
-
-/* END */
diff --git a/src/base/ftbase.c b/src/base/ftbase.c
index 5f7d818..156510f 100644
--- a/src/base/ftbase.c
+++ b/src/base/ftbase.c
@@ -4,7 +4,7 @@
  *
  *   Single object library component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,13 +16,13 @@
  */
 
 
-#include <ft2build.h>
 #define  FT_MAKE_OPTION_SINGLE_OBJECT
 
 #include "ftadvanc.c"
 #include "ftcalc.c"
 #include "ftcolor.c"
 #include "ftdbgmem.c"
+#include "fterrors.c"
 #include "ftfntfmt.c"
 #include "ftgloadr.c"
 #include "fthash.c"
diff --git a/src/base/ftbase.h b/src/base/ftbase.h
index feb0f4e..00790d3 100644
--- a/src/base/ftbase.h
+++ b/src/base/ftbase.h
@@ -4,7 +4,7 @@
  *
  *   Private functions used in the `base' module (specification).
  *
- * Copyright 2008-2018 by
+ * Copyright (C) 2008-2023 by
  * David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,13 +20,17 @@
 #define FTBASE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 
 
 FT_BEGIN_HEADER
 
 
+  FT_DECLARE_GLYPH( ft_bitmap_glyph_class )
+  FT_DECLARE_GLYPH( ft_outline_glyph_class )
+  FT_DECLARE_GLYPH( ft_svg_glyph_class )
+
+
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
 
   /* MacOS resource fork cannot exceed 16MB at least for Carbon code; */
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index 86cefe4..7dd7188 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -4,7 +4,7 @@
  *
  *   FreeType bbox computation (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used
@@ -24,14 +24,13 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_BBOX_H
-#include FT_IMAGE_H
-#include FT_OUTLINE_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftbbox.h>
+#include <freetype/ftimage.h>
+#include <freetype/ftoutln.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftobjs.h>
 
 
   typedef struct  TBBox_Rec_
@@ -294,10 +293,10 @@
       if ( shift > 2 )
         shift = 2;
 
-      q1 <<=  shift;
-      q2 <<=  shift;
-      q3 <<=  shift;
-      q4 <<=  shift;
+      q1 *= 1 << shift;
+      q2 *= 1 << shift;
+      q3 *= 1 << shift;
+      q4 *= 1 << shift;
     }
     else
     {
@@ -319,9 +318,9 @@
         q2 = q2 + q1;
         q4 = q4 + q3;
         q3 = q3 + q2;
-        q4 = ( q4 + q3 ) / 8;
-        q3 = q3 / 4;
-        q2 = q2 / 2;
+        q4 = ( q4 + q3 ) >> 3;
+        q3 = q3 >> 2;
+        q2 = q2 >> 1;
       }
       else                     /* second half */
       {
@@ -330,9 +329,9 @@
         q3 = q3 + q4;
         q1 = q1 + q2;
         q2 = q2 + q3;
-        q1 = ( q1 + q2 ) / 8;
-        q2 = q2 / 4;
-        q3 = q3 / 2;
+        q1 = ( q1 + q2 ) >> 3;
+        q2 = q2 >> 2;
+        q3 = q3 >> 1;
       }
 
       /* check whether either end reached the maximum */
diff --git a/src/base/ftbdf.c b/src/base/ftbdf.c
index 8a27c84..f697c00 100644
--- a/src/base/ftbdf.c
+++ b/src/base/ftbdf.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing BDF-specific strings (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_BDF_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svbdf.h>
 
 
   /* documentation is in ftbdf.h */
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index dc28c40..1c93648 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
  *
  *   FreeType utility functions for bitmaps (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_BITMAP_H
-#include FT_IMAGE_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftbitmap.h>
+#include <freetype/ftimage.h>
+#include <freetype/internal/ftobjs.h>
 
 
   /**************************************************************************
@@ -31,7 +30,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_bitmap
+#define FT_COMPONENT  bitmap
 
 
   static
@@ -67,11 +66,8 @@
   {
     FT_Memory  memory;
     FT_Error   error  = FT_Err_Ok;
-
-    FT_Int    pitch;
-    FT_ULong  size;
-
-    FT_Int  source_pitch_sign, target_pitch_sign;
+    FT_Int     pitch;
+    FT_Int     flip;
 
 
     if ( !library )
@@ -83,53 +79,29 @@
     if ( source == target )
       return FT_Err_Ok;
 
-    source_pitch_sign = source->pitch < 0 ? -1 : 1;
-    target_pitch_sign = target->pitch < 0 ? -1 : 1;
-
-    if ( !source->buffer )
-    {
-      *target = *source;
-      if ( source_pitch_sign != target_pitch_sign )
-        target->pitch = -target->pitch;
-
-      return FT_Err_Ok;
-    }
+    flip = ( source->pitch < 0 && target->pitch > 0 ) ||
+           ( source->pitch > 0 && target->pitch < 0 );
 
     memory = library->memory;
-    pitch  = source->pitch;
+    FT_FREE( target->buffer );
 
+    *target = *source;
+
+    if ( flip )
+      target->pitch = -target->pitch;
+
+    if ( !source->buffer )
+      return FT_Err_Ok;
+
+    pitch  = source->pitch;
     if ( pitch < 0 )
       pitch = -pitch;
-    size = (FT_ULong)pitch * source->rows;
 
-    if ( target->buffer )
-    {
-      FT_Int    target_pitch = target->pitch;
-      FT_ULong  target_size;
-
-
-      if ( target_pitch < 0 )
-        target_pitch = -target_pitch;
-      target_size = (FT_ULong)target_pitch * target->rows;
-
-      if ( target_size != size )
-        (void)FT_QREALLOC( target->buffer, target_size, size );
-    }
-    else
-      (void)FT_QALLOC( target->buffer, size );
+    FT_MEM_QALLOC_MULT( target->buffer, target->rows, pitch );
 
     if ( !error )
     {
-      unsigned char *p;
-
-
-      p = target->buffer;
-      *target = *source;
-      target->buffer = p;
-
-      if ( source_pitch_sign == target_pitch_sign )
-        FT_MEM_COPY( target->buffer, source->buffer, size );
-      else
+      if ( flip )
       {
         /* take care of bitmap flow */
         FT_UInt   i;
@@ -147,6 +119,9 @@
           t -= pitch;
         }
       }
+      else
+        FT_MEM_COPY( target->buffer, source->buffer,
+                     (FT_Long)source->rows * pitch );
     }
 
     return error;
@@ -481,7 +456,7 @@
      * A gamma of 2.2 is fair to assume.  And then, we need to
      * undo the premultiplication too.
      *
-     *   https://accessibility.kde.org/hsl-adjusted.php
+     *   http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html#SideNotes
      *
      * We do the computation with integers only, applying a gamma of 2.0.
      * We guarantee 32-bit arithmetic to avoid overflow but the resulting
@@ -489,9 +464,9 @@
      *
      */
 
-    l = (  4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
-          46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
-          13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
+    l = (  4731UL /* 0.072186 * 65536 */ * bgra[0] * bgra[0] +
+          46868UL /* 0.715158 * 65536 */ * bgra[1] * bgra[1] +
+          13937UL /* 0.212656 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
 
     /*
      * Final transparency can be determined as follows.
@@ -543,39 +518,31 @@
     case FT_PIXEL_MODE_LCD_V:
     case FT_PIXEL_MODE_BGRA:
       {
-        FT_Int    pad, old_target_pitch, target_pitch;
-        FT_ULong  old_size;
+        FT_Int  width = (FT_Int)source->width;
+        FT_Int  neg   = ( target->pitch == 0 && source->pitch < 0 ) ||
+                          target->pitch  < 0;
 
 
-        old_target_pitch = target->pitch;
-        if ( old_target_pitch < 0 )
-          old_target_pitch = -old_target_pitch;
-
-        old_size = target->rows * (FT_UInt)old_target_pitch;
+        FT_Bitmap_Done( library, target );
 
         target->pixel_mode = FT_PIXEL_MODE_GRAY;
         target->rows       = source->rows;
         target->width      = source->width;
 
-        pad = 0;
-        if ( alignment > 0 )
+        if ( alignment )
         {
-          pad = (FT_Int)source->width % alignment;
-          if ( pad != 0 )
-            pad = alignment - pad;
+          FT_Int  rem = width % alignment;
+
+
+          if ( rem )
+            width = alignment > 0 ? width - rem + alignment
+                                  : width - rem - alignment;
         }
 
-        target_pitch = (FT_Int)source->width + pad;
-
-        if ( target_pitch > 0                                               &&
-             (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
-          return FT_THROW( Invalid_Argument );
-
-        if ( FT_QREALLOC( target->buffer,
-                          old_size, target->rows * (FT_UInt)target_pitch ) )
+        if ( FT_QALLOC_MULT( target->buffer, target->rows, width ) )
           return error;
 
-        target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
+        target->pitch = neg ? -width : width;
       }
       break;
 
@@ -811,7 +778,6 @@
 
     FT_Vector  source_offset;
     FT_Vector  target_offset;
-    FT_Vector  frac_offset;
 
     FT_Bool  free_source_bitmap          = 0;
     FT_Bool  free_target_bitmap_on_error = 0;
@@ -845,16 +811,9 @@
     if ( !( source_->width && source_->rows ) )
       return FT_Err_Ok;               /* nothing to do */
 
-    /* we isolate a fractional shift of `source',        */
-    /* to be less than one pixel and always positive;    */
-    /* `source_offset' now holds full-pixel shift values */
+    /* assure integer pixel offsets */
     source_offset.x = FT_PIX_FLOOR( source_offset_.x );
-    frac_offset.x   = source_offset_.x - source_offset.x;
-
     source_offset.y = FT_PIX_FLOOR( source_offset_.y );
-    frac_offset.y   = source_offset_.y - source_offset.y;
-
-    /* assure integer pixel offset for target bitmap */
     target_offset.x = FT_PIX_FLOOR( atarget_offset->x );
     target_offset.y = FT_PIX_FLOOR( atarget_offset->y );
 
@@ -906,13 +865,6 @@
       target_ury = FT_LONG_MIN;
     }
 
-    /* move upper right corner up and to the right */
-    /* if we have a fractional offset              */
-    if ( source_urx >= target_urx && frac_offset.x )
-      source_urx += 64;
-    if ( source_ury >= target_ury && frac_offset.y )
-      source_ury += 64;
-
     /* compute final bitmap dimensions */
     final_llx = FT_MIN( source_llx, target_llx );
     final_lly = FT_MIN( source_lly, target_lly );
@@ -923,30 +875,32 @@
     final_rows  = ( final_ury - final_lly ) >> 6;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
-    FT_TRACE5(( "FT_Bitmap_Blend:\n"
-                "  source bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
+    FT_TRACE5(( "FT_Bitmap_Blend:\n" ));
+    FT_TRACE5(( "  source bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
       source_llx / 64, source_lly / 64,
       source_urx / 64, source_ury / 64,
       source_->width, source_->rows ));
 
-    if ( frac_offset.x || frac_offset.y )
-      FT_TRACE5(( "    fractional offset: (%d/64, %d/64)\n",
-                  frac_offset.x, frac_offset.y ));
-
     if ( target->width && target->rows )
-      FT_TRACE5(( "  target bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
+      FT_TRACE5(( "  target bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
         target_llx / 64, target_lly / 64,
         target_urx / 64, target_ury / 64,
         target->width, target->rows ));
     else
       FT_TRACE5(( "  target bitmap: empty\n" ));
 
-    FT_TRACE5(( "  final bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
-      final_llx / 64, final_lly / 64,
-      final_urx / 64, final_ury / 64,
-      final_width, final_rows ));
+    if ( final_width && final_rows )
+      FT_TRACE5(( "  final bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
+        final_llx / 64, final_lly / 64,
+        final_urx / 64, final_ury / 64,
+        final_width, final_rows ));
+    else
+      FT_TRACE5(( "  final bitmap: empty\n" ));
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
+    if ( !( final_width && final_rows ) )
+      return FT_Err_Ok;               /* nothing to do */
+
     /* for blending, set offset vector of final bitmap */
     /* temporarily to (0,0)                            */
     source_llx -= final_llx;
@@ -990,6 +944,7 @@
 
 
       pitch = target->pitch;
+
       if ( pitch < 0 )
         pitch = -pitch;
 
@@ -1070,8 +1025,6 @@
     x = source_llx >> 6;
     y = source_lly >> 6;
 
-    /* XXX handle `frac_offset' */
-
     /* the bitmap flow is from top to bottom, */
     /* but y is measured from bottom to top   */
     if ( target->pitch < 0 )
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index c96d5d2..13e74f3 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -4,7 +4,7 @@
  *
  *   Arithmetic computations (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -32,12 +32,11 @@
    */
 
 
-#include <ft2build.h>
-#include FT_GLYPH_H
-#include FT_TRIGONOMETRY_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftglyph.h>
+#include <freetype/fttrigon.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
 
 
 #ifdef FT_MULFIX_ASSEMBLER
@@ -46,7 +45,7 @@
 
 /* we need to emulate a 64-bit data type if a real one isn't available */
 
-#ifndef FT_LONG64
+#ifndef FT_INT64
 
   typedef struct  FT_Int64_
   {
@@ -55,7 +54,7 @@
 
   } FT_Int64;
 
-#endif /* !FT_LONG64 */
+#endif /* !FT_INT64 */
 
 
   /**************************************************************************
@@ -65,7 +64,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_calc
+#define FT_COMPONENT  calc
 
 
   /* transfer sign, leaving a positive number;                        */
@@ -80,7 +79,7 @@
   FT_END_STMNT
 
   /* The following three functions are available regardless of whether */
-  /* FT_LONG64 is defined.                                             */
+  /* FT_INT64 is defined.                                              */
 
   /* documentation is in freetype.h */
 
@@ -110,7 +109,7 @@
 
 #ifndef FT_MSB
 
-  FT_BASE_DEF ( FT_Int )
+  FT_BASE_DEF( FT_Int )
   FT_MSB( FT_UInt32 z )
   {
     FT_Int  shift = 0;
@@ -165,7 +164,7 @@
   }
 
 
-#ifdef FT_LONG64
+#ifdef FT_INT64
 
 
   /* documentation is in freetype.h */
@@ -273,7 +272,7 @@
   }
 
 
-#else /* !FT_LONG64 */
+#else /* !FT_INT64 */
 
 
   static void
@@ -652,7 +651,7 @@
   }
 
 
-#endif /* !FT_LONG64 */
+#endif /* !FT_INT64 */
 
 
   /* documentation is in ftglyph.h */
@@ -701,8 +700,8 @@
     if ( !delta )
       return FT_THROW( Invalid_Argument );  /* matrix can't be inverted */
 
-    matrix->xy = - FT_DivFix( matrix->xy, delta );
-    matrix->yx = - FT_DivFix( matrix->yx, delta );
+    matrix->xy = -FT_DivFix( matrix->xy, delta );
+    matrix->yx = -FT_DivFix( matrix->yx, delta );
 
     xx = matrix->xx;
     yy = matrix->yy;
@@ -784,6 +783,10 @@
         nonzero_minval = val[i];
     }
 
+    /* we only handle 32bit values */
+    if ( maxval > 0x7FFFFFFFL )
+      return 0;
+
     if ( maxval > 23170 )
     {
       FT_Fixed  scale = FT_DivFix( maxval, 23170 );
@@ -979,9 +982,13 @@
                          FT_Pos  out_x,
                          FT_Pos  out_y )
   {
-#ifdef FT_LONG64
+    /* we silently ignore overflow errors since such large values */
+    /* lead to even more (harmless) rendering errors later on     */
 
-    FT_Int64  delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
+#ifdef FT_INT64
+
+    FT_Int64  delta = SUB_INT64( MUL_INT64( in_x, out_y ),
+                                 MUL_INT64( in_y, out_x ) );
 
 
     return ( delta > 0 ) - ( delta < 0 );
@@ -991,8 +998,6 @@
     FT_Int  result;
 
 
-    /* we silently ignore overflow errors, since such large values */
-    /* lead to even more (harmless) rendering errors later on      */
     if ( ADD_LONG( FT_ABS( in_x ), FT_ABS( out_y ) ) <= 131071L &&
          ADD_LONG( FT_ABS( in_y ), FT_ABS( out_x ) ) <= 131071L )
     {
@@ -1080,4 +1085,71 @@
   }
 
 
+  FT_BASE_DEF( FT_Int32 )
+  FT_MulAddFix( FT_Fixed*  s,
+                FT_Int32*  f,
+                FT_UInt    count )
+  {
+    FT_UInt   i;
+    FT_Int64  temp;
+#ifndef FT_INT64
+    FT_Int64  halfUnit;
+#endif
+
+
+#ifdef FT_INT64
+    temp = 0;
+
+    for ( i = 0; i < count; ++i )
+      temp += (FT_Int64)s[i] * f[i];
+
+    return ( temp + 0x8000 ) >> 16;
+#else
+    temp.hi = 0;
+    temp.lo = 0;
+
+    for ( i = 0; i < count; ++i )
+    {
+      FT_Int64  multResult;
+
+      FT_Int     sign  = 1;
+      FT_UInt32  carry = 0;
+
+      FT_UInt32  scalar;
+      FT_UInt32  factor;
+
+
+      scalar = (FT_UInt32)s[i];
+      factor = (FT_UInt32)f[i];
+
+      FT_MOVE_SIGN( s[i], scalar, sign );
+      FT_MOVE_SIGN( f[i], factor, sign );
+
+      ft_multo64( scalar, factor, &multResult );
+
+      if ( sign < 0 )
+      {
+        /* Emulated `FT_Int64` negation. */
+        carry = ( multResult.lo == 0 );
+
+        multResult.lo = ~multResult.lo + 1;
+        multResult.hi = ~multResult.hi + carry;
+      }
+
+      FT_Add64( &temp, &multResult, &temp );
+    }
+
+    /* Round value. */
+    halfUnit.hi = 0;
+    halfUnit.lo = 0x8000;
+    FT_Add64( &temp, &halfUnit, &temp );
+
+    return (FT_Int32)( ( (FT_Int32)( temp.hi & 0xFFFF ) << 16 ) |
+                                   ( temp.lo >> 16 )            );
+
+#endif /* !FT_INT64 */
+
+  }
+
+
 /* END */
diff --git a/src/base/ftcid.c b/src/base/ftcid.c
index 944e3e4..866cd23 100644
--- a/src/base/ftcid.c
+++ b/src/base/ftcid.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing CID font information.
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * Derek Clegg and Michael Toftdal.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_CID_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_CID_H
+#include <freetype/ftcid.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svcid.h>
 
 
   /* documentation is in ftcid.h */
diff --git a/src/base/ftcolor.c b/src/base/ftcolor.c
index 101e53e..bcd6e89 100644
--- a/src/base/ftcolor.c
+++ b/src/base/ftcolor.c
@@ -4,7 +4,7 @@
  *
  *   FreeType's glyph color management (body).
  *
- * Copyright 2018 by
+ * Copyright (C) 2018-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_SFNT_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
-#include FT_COLOR_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/tttypes.h>
+#include <freetype/ftcolor.h>
 
 
 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS
diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c
index 6e0a074..6730c4c 100644
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -4,7 +4,7 @@
  *
  *   Memory debugger (body).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,11 +18,11 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_MEMORY_H
-#include FT_SYSTEM_H
-#include FT_ERRORS_H
-#include FT_TYPES_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftmemory.h>
+#include <freetype/ftsystem.h>
+#include <freetype/fterrors.h>
+#include <freetype/fttypes.h>
 
 
 #ifdef FT_DEBUG_MEMORY
@@ -35,8 +35,8 @@
 
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
-  FT_BASE_DEF( const char* )  _ft_debug_file   = NULL;
-  FT_BASE_DEF( long )         _ft_debug_lineno = 0;
+  FT_BASE_DEF( const char* )  ft_debug_file_   = NULL;
+  FT_BASE_DEF( long )         ft_debug_lineno_ = 0;
 
   extern void
   FT_DumpMemory( FT_Memory  memory );
@@ -302,46 +302,6 @@
   }
 
 
-  static FT_MemTable
-  ft_mem_table_new( FT_Memory  memory )
-  {
-    FT_MemTable  table;
-
-
-    table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
-    if ( !table )
-      goto Exit;
-
-    FT_ZERO( table );
-
-    table->size  = FT_MEM_SIZE_MIN;
-    table->nodes = 0;
-
-    table->memory = memory;
-
-    table->memory_user = memory->user;
-
-    table->alloc   = memory->alloc;
-    table->realloc = memory->realloc;
-    table->free    = memory->free;
-
-    table->buckets = (FT_MemNode *)
-                       memory->alloc(
-                         memory,
-                         table->size * (FT_Long)sizeof ( FT_MemNode ) );
-    if ( table->buckets )
-      FT_ARRAY_ZERO( table->buckets, table->size );
-    else
-    {
-      memory->free( memory, table );
-      table = NULL;
-    }
-
-  Exit:
-    return table;
-  }
-
-
   static void
   ft_mem_table_destroy( FT_MemTable  table )
   {
@@ -350,8 +310,6 @@
     FT_Long  leaks      = 0;
 
 
-    FT_DumpMemory( table->memory );
-
     /* remove all blocks from the table, revealing leaked ones */
     for ( i = 0; i < table->size; i++ )
     {
@@ -413,8 +371,6 @@
     printf( "FreeType: maximum memory footprint = %ld\n",
             table->alloc_max );
 
-    ft_mem_table_free( table, table );
-
     if ( leak_count > 0 )
       ft_mem_debug_panic(
         "FreeType: %ld bytes of memory leaked in %ld blocks\n",
@@ -459,8 +415,8 @@
 
     /* cast to FT_PtrDist first since void* can be larger */
     /* than FT_UInt32 and GCC 4.1.1 emits a warning       */
-    hash  = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
-              (FT_UInt32)( 5 * _ft_debug_lineno );
+    hash  = (FT_UInt32)(FT_PtrDist)(void*)ft_debug_file_ +
+              (FT_UInt32)( 5 * ft_debug_lineno_ );
     pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
 
     for (;;)
@@ -469,8 +425,8 @@
       if ( !node )
         break;
 
-      if ( node->file_name == _ft_debug_file   &&
-           node->line_no   == _ft_debug_lineno )
+      if ( node->file_name == ft_debug_file_   &&
+           node->line_no   == ft_debug_lineno_ )
         goto Exit;
 
       pnode = &node->link;
@@ -481,8 +437,8 @@
       ft_mem_debug_panic(
         "not enough memory to perform memory debugging\n" );
 
-    node->file_name = _ft_debug_file;
-    node->line_no   = _ft_debug_lineno;
+    node->file_name = ft_debug_file_;
+    node->line_no   = ft_debug_lineno_;
 
     node->cur_blocks = 0;
     node->max_blocks = 0;
@@ -539,7 +495,7 @@
             "org=%s:%d new=%s:%d\n",
             node->address, node->size,
             FT_FILENAME( node->source->file_name ), node->source->line_no,
-            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
+            FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_ );
         }
       }
 
@@ -621,10 +577,12 @@
 
         if ( node->size < 0 )
           ft_mem_debug_panic(
-            "freeing memory block at %p more than once at (%s:%ld)\n"
-            "block allocated at (%s:%ld) and released at (%s:%ld)",
+            "freeing memory block at %p more than once\n"
+            "  at (%s:%ld)!\n"
+            "  Block was allocated at (%s:%ld)\n"
+            "  and released at (%s:%ld).",
             address,
-            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
+            FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_,
             FT_FILENAME( node->source->file_name ), node->source->line_no,
             FT_FILENAME( node->free_file_name ), node->free_line_no );
 
@@ -646,8 +604,8 @@
           /* we simply invert the node's size to indicate that the node */
           /* was freed.                                                 */
           node->size           = -node->size;
-          node->free_file_name = _ft_debug_file;
-          node->free_line_no   = _ft_debug_lineno;
+          node->free_file_name = ft_debug_file_;
+          node->free_line_no   = ft_debug_lineno_;
         }
         else
         {
@@ -669,7 +627,7 @@
         ft_mem_debug_panic(
           "trying to free unknown block at %p in (%s:%ld)\n",
           address,
-          FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
+          FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_ );
     }
   }
 
@@ -703,8 +661,8 @@
       table->alloc_count++;
     }
 
-    _ft_debug_file   = "<unknown>";
-    _ft_debug_lineno = 0;
+    ft_debug_file_   = "<unknown>";
+    ft_debug_lineno_ = 0;
 
     return (FT_Pointer)block;
   }
@@ -719,8 +677,8 @@
 
     if ( !block )
       ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
-                          FT_FILENAME( _ft_debug_file ),
-                          _ft_debug_lineno );
+                          FT_FILENAME( ft_debug_file_ ),
+                          ft_debug_lineno_ );
 
     ft_mem_table_remove( table, (FT_Byte*)block, 0 );
 
@@ -729,8 +687,8 @@
 
     table->alloc_count--;
 
-    _ft_debug_file   = "<unknown>";
-    _ft_debug_lineno = 0;
+    ft_debug_file_   = "<unknown>";
+    ft_debug_lineno_ = 0;
   }
 
 
@@ -745,8 +703,8 @@
     FT_Pointer   new_block;
     FT_Long      delta;
 
-    const char*  file_name = FT_FILENAME( _ft_debug_file );
-    FT_Long      line_no   = _ft_debug_lineno;
+    const char*  file_name = FT_FILENAME( ft_debug_file_ );
+    FT_Long      line_no   = ft_debug_lineno_;
 
 
     /* unlikely, but possible */
@@ -809,8 +767,8 @@
 
     ft_mem_table_remove( table, (FT_Byte*)block, delta );
 
-    _ft_debug_file   = "<unknown>";
-    _ft_debug_lineno = 0;
+    ft_debug_file_   = "<unknown>";
+    ft_debug_lineno_ = 0;
 
     if ( !table->keep_alive )
       ft_mem_table_free( table, block );
@@ -819,17 +777,30 @@
   }
 
 
-  extern FT_Int
+  extern void
   ft_mem_debug_init( FT_Memory  memory )
   {
     FT_MemTable  table;
-    FT_Int       result = 0;
 
 
-    if ( ft_getenv( "FT2_DEBUG_MEMORY" ) )
+    if ( !ft_getenv( "FT2_DEBUG_MEMORY" ) )
+      return;
+
+    table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
+
+    if ( table )
     {
-      table = ft_mem_table_new( memory );
-      if ( table )
+      FT_ZERO( table );
+
+      table->memory      = memory;
+      table->memory_user = memory->user;
+      table->alloc       = memory->alloc;
+      table->realloc     = memory->realloc;
+      table->free        = memory->free;
+
+      ft_mem_table_resize( table );
+
+      if ( table->size )
       {
         const char*  p;
 
@@ -874,33 +845,36 @@
           if ( keep_alive > 0 )
             table->keep_alive = 1;
         }
-
-        result = 1;
       }
+      else
+        memory->free( memory, table );
     }
-    return result;
   }
 
 
   extern void
   ft_mem_debug_done( FT_Memory  memory )
   {
-    FT_MemTable  table = (FT_MemTable)memory->user;
-
-
-    if ( table )
+    if ( memory->free == ft_mem_debug_free )
     {
+      FT_MemTable  table = (FT_MemTable)memory->user;
+
+
+      FT_DumpMemory( memory );
+
+      ft_mem_table_destroy( table );
+
       memory->free    = table->free;
       memory->realloc = table->realloc;
       memory->alloc   = table->alloc;
+      memory->user    = table->memory_user;
 
-      ft_mem_table_destroy( table );
-      memory->user = NULL;
+      memory->free( memory, table );
     }
   }
 
 
-  static int
+  FT_COMPARE_DEF( int )
   ft_mem_source_compare( const void*  p1,
                          const void*  p2 )
   {
@@ -920,11 +894,9 @@
   extern void
   FT_DumpMemory( FT_Memory  memory )
   {
-    FT_MemTable  table = (FT_MemTable)memory->user;
-
-
-    if ( table )
+    if ( memory->free == ft_mem_debug_free )
     {
+      FT_MemTable    table = (FT_MemTable)memory->user;
       FT_MemSource*  bucket = table->sources;
       FT_MemSource*  limit  = bucket + FT_MEM_SOURCE_BUCKETS;
       FT_MemSource*  sources;
diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c
index 19b0058..61c4563 100644
--- a/src/base/ftdebug.c
+++ b/src/base/ftdebug.c
@@ -4,7 +4,7 @@
  *
  *   Debugging and logging component (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -41,9 +41,54 @@
    */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/freetype.h>
+#include <freetype/ftlogging.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+
+
+#ifdef FT_DEBUG_LOGGING
+
+  /**************************************************************************
+   *
+   * Variables used to control logging.
+   *
+   * 1. `ft_default_trace_level` stores the value of trace levels, which are
+   *    provided to FreeType using the `FT2_DEBUG` environment variable.
+   *
+   * 2. `ft_fileptr` stores the `FILE*` handle.
+   *
+   * 3. `ft_component` is a string that holds the name of `FT_COMPONENT`.
+   *
+   * 4. The flag `ft_component_flag` prints the name of `FT_COMPONENT` along
+   *    with the actual log message if set to true.
+   *
+   * 5. The flag `ft_timestamp_flag` prints time along with the actual log
+   *    message if set to ture.
+   *
+   * 6. `ft_have_newline_char` is used to differentiate between a log
+   *    message with and without a trailing newline character.
+   *
+   * 7. `ft_custom_trace_level` stores the custom trace level value, which
+   *    is provided by the user at run-time.
+   *
+   * We use `static` to avoid 'unused variable' warnings.
+   *
+   */
+  static const char*  ft_default_trace_level = NULL;
+  static FILE*        ft_fileptr             = NULL;
+  static const char*  ft_component           = NULL;
+  static FT_Bool      ft_component_flag      = FALSE;
+  static FT_Bool      ft_timestamp_flag      = FALSE;
+  static FT_Bool      ft_have_newline_char   = TRUE;
+  static const char*  ft_custom_trace_level  = NULL;
+
+  /* declared in ftdebug.h */
+
+  dlg_handler            ft_default_log_handler = NULL;
+  FT_Custom_Log_Handler  custom_output_handler  = NULL;
+
+#endif /* FT_DEBUG_LOGGING */
 
 
 #ifdef FT_DEBUG_LEVEL_ERROR
@@ -87,9 +132,19 @@
             int          line,
             const char*  file )
   {
+#if 0
+    /* activating the code in this block makes FreeType very chatty */
+    fprintf( stderr,
+             "%s:%d: error 0x%02x: %s\n",
+             file,
+             line,
+             error,
+             FT_Error_String( error ) );
+#else
     FT_UNUSED( error );
     FT_UNUSED( line );
     FT_UNUSED( file );
+#endif
 
     return 0;
   }
@@ -97,7 +152,6 @@
 #endif /* FT_DEBUG_LEVEL_ERROR */
 
 
-
 #ifdef FT_DEBUG_LEVEL_TRACE
 
   /* array of trace levels, initialized to 0; */
@@ -116,7 +170,7 @@
 
   static const char*  ft_trace_toggles[trace_count + 1] =
   {
-#include FT_INTERNAL_TRACE_H
+#include <freetype/internal/fttrace.h>
     NULL
   };
 
@@ -186,9 +240,18 @@
   FT_BASE_DEF( void )
   ft_debug_init( void )
   {
-    const char*  ft2_debug = ft_getenv( "FT2_DEBUG" );
+    const char*  ft2_debug = NULL;
 
 
+#ifdef FT_DEBUG_LOGGING
+    if ( ft_custom_trace_level != NULL )
+      ft2_debug = ft_custom_trace_level;
+    else
+      ft2_debug = ft_default_trace_level;
+#else
+    ft2_debug = ft_getenv( "FT2_DEBUG" );
+#endif
+
     if ( ft2_debug )
     {
       const char*  p = ft2_debug;
@@ -201,6 +264,49 @@
         if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
           continue;
 
+#ifdef FT_DEBUG_LOGGING
+
+        /* check extra arguments for logging */
+        if ( *p == '-' )
+        {
+          const char*  r = ++p;
+
+
+          if ( *r == 'v' )
+          {
+            const char*  s = ++r;
+
+
+            ft_component_flag = TRUE;
+
+            if ( *s == 't' )
+            {
+              ft_timestamp_flag = TRUE;
+              p++;
+            }
+
+            p++;
+          }
+
+          else if ( *r == 't' )
+          {
+            const char*  s = ++r;
+
+
+            ft_timestamp_flag = TRUE;
+
+            if ( *s == 'v' )
+            {
+              ft_component_flag = TRUE;
+              p++;
+            }
+
+            p++;
+          }
+        }
+
+#endif /* FT_DEBUG_LOGGING */
+
         /* read toggle name, followed by ':' */
         q = p;
         while ( *p && *p != ':' )
@@ -302,8 +408,237 @@
     /* nothing */
   }
 
-
 #endif /* !FT_DEBUG_LEVEL_TRACE */
 
 
+#ifdef FT_DEBUG_LOGGING
+
+  /**************************************************************************
+   *
+   * Initialize and de-initialize 'dlg' library.
+   *
+   */
+
+  FT_BASE_DEF( void )
+  ft_logging_init( void )
+  {
+    ft_default_log_handler = ft_log_handler;
+    ft_default_trace_level = ft_getenv( "FT2_DEBUG" );
+
+    if ( ft_getenv( "FT_LOGGING_FILE" ) )
+      ft_fileptr = ft_fopen( ft_getenv( "FT_LOGGING_FILE" ), "w" );
+    else
+      ft_fileptr = stderr;
+
+    ft_debug_init();
+
+    /* Set the default output handler for 'dlg'. */
+    dlg_set_handler( ft_default_log_handler, NULL );
+  }
+
+
+  FT_BASE_DEF( void )
+  ft_logging_deinit( void )
+  {
+    if ( ft_fileptr != stderr )
+      ft_fclose( ft_fileptr );
+  }
+
+
+  /**************************************************************************
+   *
+   * An output log handler for FreeType.
+   *
+   */
+  FT_BASE_DEF( void )
+  ft_log_handler( const struct dlg_origin*  origin,
+                  const char*               string,
+                  void*                     data )
+  {
+    char         features_buf[128];
+    char*        bufp = features_buf;
+
+    FT_UNUSED( data );
+
+
+    if ( ft_have_newline_char )
+    {
+      const char*  features        = NULL;
+      size_t       features_length = 0;
+
+
+#define FEATURES_TIMESTAMP            "[%h:%m] "
+#define FEATURES_COMPONENT            "[%t] "
+#define FEATURES_TIMESTAMP_COMPONENT  "[%h:%m %t] "
+
+      if ( ft_timestamp_flag && ft_component_flag )
+      {
+        features        = FEATURES_TIMESTAMP_COMPONENT;
+        features_length = sizeof ( FEATURES_TIMESTAMP_COMPONENT );
+      }
+      else if ( ft_timestamp_flag )
+      {
+        features        = FEATURES_TIMESTAMP;
+        features_length = sizeof ( FEATURES_TIMESTAMP );
+      }
+      else if ( ft_component_flag )
+      {
+        features        = FEATURES_COMPONENT;
+        features_length = sizeof ( FEATURES_COMPONENT );
+      }
+
+      if ( ft_component_flag || ft_timestamp_flag )
+      {
+        ft_strncpy( features_buf, features, features_length );
+        bufp += features_length - 1;
+      }
+
+      if ( ft_component_flag )
+      {
+        size_t  tag_length = ft_strlen( *origin->tags );
+        size_t  i;
+
+
+        /* To vertically align tracing messages we compensate the */
+        /* different FT_COMPONENT string lengths by inserting an  */
+        /* appropriate amount of space characters.                */
+        for ( i = 0;
+              i < FT_MAX_TRACE_LEVEL_LENGTH - tag_length;
+              i++ )
+          *bufp++ = ' ';
+      }
+    }
+
+    /* Finally add the format string for the tracing message. */
+    *bufp++ = '%';
+    *bufp++ = 'c';
+    *bufp   = '\0';
+
+    dlg_generic_outputf_stream( ft_fileptr,
+                                (const char*)features_buf,
+                                origin,
+                                string,
+                                dlg_default_output_styles,
+                                true );
+
+    if ( ft_strrchr( string, '\n' ) )
+      ft_have_newline_char = TRUE;
+    else
+      ft_have_newline_char = FALSE;
+  }
+
+
+  /* documentation is in ftdebug.h */
+  FT_BASE_DEF( void )
+  ft_add_tag( const char*  tag )
+  {
+    ft_component = tag;
+
+    dlg_add_tag( tag, NULL );
+  }
+
+
+  /* documentation is in ftdebug.h */
+  FT_BASE_DEF( void )
+  ft_remove_tag( const char*  tag )
+  {
+    dlg_remove_tag( tag, NULL );
+  }
+
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Level( const char*  level )
+  {
+    ft_component_flag     = FALSE;
+    ft_timestamp_flag     = FALSE;
+    ft_custom_trace_level = level;
+
+    ft_debug_init();
+  }
+
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Default_Level( void )
+  {
+    ft_component_flag     = FALSE;
+    ft_timestamp_flag     = FALSE;
+    ft_custom_trace_level = NULL;
+
+    ft_debug_init();
+  }
+
+
+  /**************************************************************************
+   *
+   * Functions to handle a custom log handler.
+   *
+   */
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Log_Handler( FT_Custom_Log_Handler  handler )
+  {
+    custom_output_handler = handler;
+  }
+
+
+  /* documentation is in ftlogging.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Default_Log_Handler( void )
+  {
+    custom_output_handler = NULL;
+  }
+
+
+  /* documentation is in ftdebug.h */
+  FT_BASE_DEF( void )
+  FT_Logging_Callback( const char*  fmt,
+                       ... )
+  {
+    va_list  ap;
+
+
+    va_start( ap, fmt );
+    custom_output_handler( ft_component, fmt, ap );
+    va_end( ap );
+  }
+
+#else /* !FT_DEBUG_LOGGING */
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Level( const char*  level )
+  {
+    FT_UNUSED( level );
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Trace_Set_Default_Level( void )
+  {
+    /* nothing */
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Log_Handler( FT_Custom_Log_Handler  handler )
+  {
+    FT_UNUSED( handler );
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Default_Log_Handler( void )
+  {
+    /* nothing */
+  }
+
+#endif /* !FT_DEBUG_LOGGING */
+
+
 /* END */
diff --git a/src/base/fterrors.c b/src/base/fterrors.c
new file mode 100644
index 0000000..5ad9709
--- /dev/null
+++ b/src/base/fterrors.c
@@ -0,0 +1,45 @@
+/****************************************************************************
+ *
+ * fterrors.c
+ *
+ *   FreeType API for error code handling.
+ *
+ * Copyright (C) 2018-2023 by
+ * Armin Hasitzka, 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/fterrors.h>
+
+
+  /* documentation is in fterrors.h */
+
+  FT_EXPORT_DEF( const char* )
+  FT_Error_String( FT_Error  error_code )
+  {
+    if ( error_code <  0                                ||
+         error_code >= FT_ERR_CAT( FT_ERR_PREFIX, Max ) )
+      return NULL;
+
+#if defined( FT_CONFIG_OPTION_ERROR_STRINGS ) || \
+    defined( FT_DEBUG_LEVEL_ERROR )
+
+#undef FTERRORS_H_
+#define FT_ERROR_START_LIST     switch ( FT_ERROR_BASE( error_code ) ) {
+#define FT_ERRORDEF( e, v, s )    case v: return s;
+#define FT_ERROR_END_LIST       }
+
+#include <freetype/fterrors.h>
+
+#endif /* defined( FT_CONFIG_OPTION_ERROR_STRINGS ) || ... */
+
+    return NULL;
+  }
diff --git a/src/base/ftfntfmt.c b/src/base/ftfntfmt.c
index 610b6cf..0b41f7c 100644
--- a/src/base/ftfntfmt.c
+++ b/src/base/ftfntfmt.c
@@ -4,7 +4,7 @@
  *
  *   FreeType utility file for font formats (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FONT_FORMATS_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_FONT_FORMAT_H
+#include <freetype/ftfntfmt.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svfntfmt.h>
 
 
   /* documentation is in ftfntfmt.h */
diff --git a/src/base/ftfstype.c b/src/base/ftfstype.c
index 74e9e56..ea24e64 100644
--- a/src/base/ftfstype.c
+++ b/src/base/ftfstype.c
@@ -4,7 +4,7 @@
  *
  *   FreeType utility file to access FSType data (body).
  *
- * Copyright 2008-2018 by
+ * Copyright (C) 2008-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -15,11 +15,10 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include <freetype/t1tables.h>
+#include <freetype/tttables.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/services/svpsinfo.h>
 
 
   /* documentation is in freetype.h */
diff --git a/src/base/ftgasp.c b/src/base/ftgasp.c
index 15e0ef0..29b7b08 100644
--- a/src/base/ftgasp.c
+++ b/src/base/ftgasp.c
@@ -4,7 +4,7 @@
  *
  *   Access of TrueType's `gasp' table (body).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,9 +16,8 @@
  */
 
 
-#include <ft2build.h>
-#include FT_GASP_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/ftgasp.h>
+#include <freetype/internal/tttypes.h>
 
 
   FT_EXPORT_DEF( FT_Int )
diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c
index 475d5cc..9823d09 100644
--- a/src/base/ftgloadr.c
+++ b/src/base/ftgloadr.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph loader (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,14 +16,13 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_GLYPH_LOADER_H
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftgloadr.h>
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftobjs.h>
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gloader
+#define FT_COMPONENT  gloader
 
 
   /*************************************************************************/
@@ -93,6 +92,7 @@
 
     base->outline.n_points   = 0;
     base->outline.n_contours = 0;
+    base->outline.flags      = 0;
     base->num_subglyphs      = 0;
 
     *current = *base;
@@ -146,9 +146,9 @@
     FT_Outline*  current = &loader->current.outline;
 
 
-    current->points   = base->points   + base->n_points;
-    current->tags     = base->tags     + base->n_points;
-    current->contours = base->contours + base->n_contours;
+    current->points   = FT_OFFSET( base->points,   base->n_points );
+    current->tags     = FT_OFFSET( base->tags,     base->n_points );
+    current->contours = FT_OFFSET( base->contours, base->n_contours );
 
     /* handle extra points table - if any */
     if ( loader->use_extra )
@@ -169,6 +169,10 @@
     FT_Memory  memory = loader->memory;
 
 
+    if ( loader->max_points == 0           ||
+         loader->base.extra_points != NULL )
+      return FT_Err_Ok;
+
     if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
     {
       loader->use_extra          = 1;
@@ -189,7 +193,7 @@
     FT_GlyphLoad  current = &loader->current;
 
 
-    current->subglyphs = base->subglyphs + base->num_subglyphs;
+    current->subglyphs = FT_OFFSET( base->subglyphs, base->num_subglyphs );
   }
 
 
@@ -208,9 +212,13 @@
     FT_Outline*  current = &loader->current.outline;
     FT_Bool      adjust  = 0;
 
-    FT_UInt      new_max, old_max;
+    FT_UInt  new_max, old_max, min_new_max;
 
 
+    error = FT_GlyphLoader_CreateExtra( loader );
+    if ( error )
+      goto Exit;
+
     /* check points & tags */
     new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points +
               n_points;
@@ -218,10 +226,18 @@
 
     if ( new_max > old_max )
     {
-      new_max = FT_PAD_CEIL( new_max, 8 );
-
       if ( new_max > FT_OUTLINE_POINTS_MAX )
-        return FT_THROW( Array_Too_Large );
+      {
+        error = FT_THROW( Array_Too_Large );
+        goto Exit;
+      }
+
+      min_new_max = old_max + ( old_max >> 1 );
+      if ( new_max < min_new_max )
+        new_max = min_new_max;
+      new_max = FT_PAD_CEIL( new_max, 8 );
+      if ( new_max > FT_OUTLINE_POINTS_MAX )
+        new_max = FT_OUTLINE_POINTS_MAX;
 
       if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
            FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
@@ -244,16 +260,28 @@
       loader->max_points = new_max;
     }
 
+    error = FT_GlyphLoader_CreateExtra( loader );
+    if ( error )
+      goto Exit;
+
     /* check contours */
     old_max = loader->max_contours;
     new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours +
               n_contours;
     if ( new_max > old_max )
     {
-      new_max = FT_PAD_CEIL( new_max, 4 );
-
       if ( new_max > FT_OUTLINE_CONTOURS_MAX )
-        return FT_THROW( Array_Too_Large );
+      {
+        error = FT_THROW( Array_Too_Large );
+        goto Exit;
+      }
+
+      min_new_max = old_max + ( old_max >> 1 );
+      if ( new_max < min_new_max )
+        new_max = min_new_max;
+      new_max = FT_PAD_CEIL( new_max, 4 );
+      if ( new_max > FT_OUTLINE_CONTOURS_MAX )
+        new_max = FT_OUTLINE_CONTOURS_MAX;
 
       if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
         goto Exit;
@@ -361,46 +389,4 @@
   }
 
 
-  FT_BASE_DEF( FT_Error )
-  FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,
-                             FT_GlyphLoader  source )
-  {
-    FT_Error  error;
-    FT_UInt   num_points   = (FT_UInt)source->base.outline.n_points;
-    FT_UInt   num_contours = (FT_UInt)source->base.outline.n_contours;
-
-
-    error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
-    if ( !error )
-    {
-      FT_Outline*  out = &target->base.outline;
-      FT_Outline*  in  = &source->base.outline;
-
-
-      FT_ARRAY_COPY( out->points, in->points,
-                     num_points );
-      FT_ARRAY_COPY( out->tags, in->tags,
-                     num_points );
-      FT_ARRAY_COPY( out->contours, in->contours,
-                     num_contours );
-
-      /* do we need to copy the extra points? */
-      if ( target->use_extra && source->use_extra )
-      {
-        FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,
-                       num_points );
-        FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,
-                       num_points );
-      }
-
-      out->n_points   = (short)num_points;
-      out->n_contours = (short)num_contours;
-
-      FT_GlyphLoader_Adjust_Points( target );
-    }
-
-    return error;
-  }
-
-
 /* END */
diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index 8bc86a5..393d494 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -4,7 +4,7 @@
  *
  *   FreeType convenience functions to handle glyphs (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -28,13 +28,15 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_GLYPH_H
-#include FT_OUTLINE_H
-#include FT_BITMAP_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftglyph.h>
+#include <freetype/ftoutln.h>
+#include <freetype/ftbitmap.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/otsvg.h>
+
+#include "ftbase.h"
 
 
   /**************************************************************************
@@ -44,7 +46,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_glyph
+#define FT_COMPONENT  glyph
 
 
   /*************************************************************************/
@@ -76,7 +78,7 @@
     /* do lazy copying whenever possible */
     if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
     {
-      glyph->bitmap = slot->bitmap;
+      glyph->bitmap          = slot->bitmap;
       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     }
     else
@@ -276,6 +278,240 @@
   )
 
 
+#ifdef FT_CONFIG_OPTION_SVG
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****   FT_SvgGlyph support                                           ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ft_svg_glyph_init( FT_Glyph      svg_glyph,
+                     FT_GlyphSlot  slot )
+  {
+    FT_ULong         doc_length;
+    FT_SVG_Document  document;
+    FT_SvgGlyph      glyph = (FT_SvgGlyph)svg_glyph;
+
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = FT_GLYPH( glyph )->library->memory;
+
+
+    if ( slot->format != FT_GLYPH_FORMAT_SVG )
+    {
+      error = FT_THROW( Invalid_Glyph_Format );
+      goto Exit;
+    }
+
+    if ( slot->other == NULL )
+    {
+      error = FT_THROW( Invalid_Slot_Handle );
+      goto Exit;
+    }
+
+    document = (FT_SVG_Document)slot->other;
+
+    if ( document->svg_document_length == 0 )
+    {
+      error = FT_THROW( Invalid_Slot_Handle );
+      goto Exit;
+    }
+
+    /* allocate a new document */
+    doc_length = document->svg_document_length;
+    if ( FT_QALLOC( glyph->svg_document, doc_length ) )
+      goto Exit;
+    glyph->svg_document_length = doc_length;
+
+    glyph->glyph_index = slot->glyph_index;
+
+    glyph->metrics      = document->metrics;
+    glyph->units_per_EM = document->units_per_EM;
+
+    glyph->start_glyph_id = document->start_glyph_id;
+    glyph->end_glyph_id   = document->end_glyph_id;
+
+    glyph->transform = document->transform;
+    glyph->delta     = document->delta;
+
+    /* copy the document into glyph */
+    FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
+
+  Exit:
+    return error;
+  }
+
+
+  FT_CALLBACK_DEF( void )
+  ft_svg_glyph_done( FT_Glyph  svg_glyph )
+  {
+    FT_SvgGlyph  glyph  = (FT_SvgGlyph)svg_glyph;
+    FT_Memory    memory = svg_glyph->library->memory;
+
+
+    /* just free the memory */
+    FT_FREE( glyph->svg_document );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ft_svg_glyph_copy( FT_Glyph  svg_source,
+                     FT_Glyph  svg_target )
+  {
+    FT_SvgGlyph  source = (FT_SvgGlyph)svg_source;
+    FT_SvgGlyph  target = (FT_SvgGlyph)svg_target;
+
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = FT_GLYPH( source )->library->memory;
+
+
+    if ( svg_source->format != FT_GLYPH_FORMAT_SVG )
+    {
+      error = FT_THROW( Invalid_Glyph_Format );
+      goto Exit;
+    }
+
+    if ( source->svg_document_length == 0 )
+    {
+      error = FT_THROW( Invalid_Slot_Handle );
+      goto Exit;
+    }
+
+    target->glyph_index = source->glyph_index;
+
+    target->svg_document_length = source->svg_document_length;
+
+    target->metrics      = source->metrics;
+    target->units_per_EM = source->units_per_EM;
+
+    target->start_glyph_id = source->start_glyph_id;
+    target->end_glyph_id   = source->end_glyph_id;
+
+    target->transform = source->transform;
+    target->delta     = source->delta;
+
+    /* allocate space for the SVG document */
+    if ( FT_QALLOC( target->svg_document, target->svg_document_length ) )
+      goto Exit;
+
+    /* copy the document */
+    FT_MEM_COPY( target->svg_document,
+                 source->svg_document,
+                 target->svg_document_length );
+
+  Exit:
+    return error;
+  }
+
+
+  FT_CALLBACK_DEF( void )
+  ft_svg_glyph_transform( FT_Glyph          svg_glyph,
+                          const FT_Matrix*  _matrix,
+                          const FT_Vector*  _delta )
+  {
+    FT_SvgGlyph  glyph  = (FT_SvgGlyph)svg_glyph;
+    FT_Matrix*   matrix = (FT_Matrix*)_matrix;
+    FT_Vector*   delta  = (FT_Vector*)_delta;
+
+    FT_Matrix  tmp_matrix;
+    FT_Vector  tmp_delta;
+
+    FT_Matrix  a, b;
+    FT_Pos     x, y;
+
+
+    if ( !matrix )
+    {
+      tmp_matrix.xx = 0x10000;
+      tmp_matrix.xy = 0;
+      tmp_matrix.yx = 0;
+      tmp_matrix.yy = 0x10000;
+
+      matrix = &tmp_matrix;
+    }
+
+    if ( !delta )
+    {
+      tmp_delta.x = 0;
+      tmp_delta.y = 0;
+
+      delta = &tmp_delta;
+    }
+
+    a = glyph->transform;
+    b = *matrix;
+    FT_Matrix_Multiply( &b, &a );
+
+    x = ADD_LONG( ADD_LONG( FT_MulFix( matrix->xx, glyph->delta.x ),
+                            FT_MulFix( matrix->xy, glyph->delta.y ) ),
+                  delta->x );
+    y = ADD_LONG( ADD_LONG( FT_MulFix( matrix->yx, glyph->delta.x ),
+                            FT_MulFix( matrix->yy, glyph->delta.y ) ),
+                  delta->y );
+
+    glyph->delta.x = x;
+    glyph->delta.y = y;
+
+    glyph->transform = a;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ft_svg_glyph_prepare( FT_Glyph      svg_glyph,
+                        FT_GlyphSlot  slot )
+  {
+    FT_SvgGlyph  glyph = (FT_SvgGlyph)svg_glyph;
+
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = svg_glyph->library->memory;
+
+    FT_SVG_Document  document = NULL;
+
+
+    if ( FT_NEW( document ) )
+      return error;
+
+    document->svg_document        = glyph->svg_document;
+    document->svg_document_length = glyph->svg_document_length;
+
+    document->metrics      = glyph->metrics;
+    document->units_per_EM = glyph->units_per_EM;
+
+    document->start_glyph_id = glyph->start_glyph_id;
+    document->end_glyph_id   = glyph->end_glyph_id;
+
+    document->transform = glyph->transform;
+    document->delta     = glyph->delta;
+
+    slot->format      = FT_GLYPH_FORMAT_SVG;
+    slot->glyph_index = glyph->glyph_index;
+    slot->other       = document;
+
+    return error;
+  }
+
+
+  FT_DEFINE_GLYPH(
+    ft_svg_glyph_class,
+
+    sizeof ( FT_SvgGlyphRec ),
+    FT_GLYPH_FORMAT_SVG,
+
+    ft_svg_glyph_init,      /* FT_Glyph_InitFunc       glyph_init      */
+    ft_svg_glyph_done,      /* FT_Glyph_DoneFunc       glyph_done      */
+    ft_svg_glyph_copy,      /* FT_Glyph_CopyFunc       glyph_copy      */
+    ft_svg_glyph_transform, /* FT_Glyph_TransformFunc  glyph_transform */
+    NULL,                   /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
+    ft_svg_glyph_prepare    /* FT_Glyph_PrepareFunc    glyph_prepare   */
+  )
+
+#endif /* FT_CONFIG_OPTION_SVG */
+
+
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
@@ -376,6 +612,12 @@
     else if ( format == FT_GLYPH_FORMAT_OUTLINE )
       clazz = &ft_outline_glyph_class;
 
+#ifdef FT_CONFIG_OPTION_SVG
+    /* if it is an SVG glyph */
+    else if ( format == FT_GLYPH_FORMAT_SVG )
+      clazz = &ft_svg_glyph_class;
+#endif
+
     else
     {
       /* try to find a renderer that supports the glyph image format */
@@ -400,8 +642,8 @@
   FT_Get_Glyph( FT_GlyphSlot  slot,
                 FT_Glyph     *aglyph )
   {
-    FT_Error    error;
-    FT_Glyph    glyph;
+    FT_Error  error;
+    FT_Glyph  glyph;
 
 
     if ( !slot )
@@ -440,7 +682,10 @@
   Exit2:
     /* if an error occurred, destroy the glyph */
     if ( error )
+    {
       FT_Done_Glyph( glyph );
+      *aglyph = NULL;
+    }
     else
       *aglyph = glyph;
 
@@ -452,9 +697,9 @@
   /* documentation is in ftglyph.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_Glyph_Transform( FT_Glyph    glyph,
-                      FT_Matrix*  matrix,
-                      FT_Vector*  delta )
+  FT_Glyph_Transform( FT_Glyph          glyph,
+                      const FT_Matrix*  matrix,
+                      const FT_Vector*  delta )
   {
     FT_Error  error = FT_Err_Ok;
 
@@ -513,8 +758,8 @@
     {
       acbox->xMin = FT_PIX_FLOOR( acbox->xMin );
       acbox->yMin = FT_PIX_FLOOR( acbox->yMin );
-      acbox->xMax = FT_PIX_CEIL( acbox->xMax );
-      acbox->yMax = FT_PIX_CEIL( acbox->yMax );
+      acbox->xMax = FT_PIX_CEIL_LONG( acbox->xMax );
+      acbox->yMax = FT_PIX_CEIL_LONG( acbox->yMax );
     }
 
     /* convert to integer pixels if needed */
@@ -532,10 +777,10 @@
   /* documentation is in ftglyph.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,
-                      FT_Render_Mode  render_mode,
-                      FT_Vector*      origin,
-                      FT_Bool         destroy )
+  FT_Glyph_To_Bitmap( FT_Glyph*         the_glyph,
+                      FT_Render_Mode    render_mode,
+                      const FT_Vector*  origin,
+                      FT_Bool           destroy )
   {
     FT_GlyphSlotRec           dummy;
     FT_GlyphSlot_InternalRec  dummy_internal;
@@ -584,7 +829,7 @@
 #if 1
     /* if `origin' is set, translate the glyph image */
     if ( origin )
-      FT_Glyph_Transform( glyph, 0, origin );
+      FT_Glyph_Transform( glyph, NULL, origin );
 #else
     FT_UNUSED( origin );
 #endif
@@ -594,6 +839,16 @@
     if ( !error )
       error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
 
+#ifdef FT_CONFIG_OPTION_SVG
+    if ( clazz == &ft_svg_glyph_class )
+    {
+      FT_Memory  memory = library->memory;
+
+
+      FT_FREE( dummy.other );
+    }
+#endif
+
 #if 1
     if ( !destroy && origin )
     {
@@ -602,7 +857,7 @@
 
       v.x = -origin->x;
       v.y = -origin->y;
-      FT_Glyph_Transform( glyph, 0, &v );
+      FT_Glyph_Transform( glyph, NULL, &v );
     }
 #endif
 
diff --git a/src/base/ftgxval.c b/src/base/ftgxval.c
index f3961e2..6b3c5d2 100644
--- a/src/base/ftgxval.c
+++ b/src/base/ftgxval.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for validating TrueTypeGX/AAT tables (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Masatake YAMATO, Redhat K.K,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -25,11 +25,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_GX_VALIDATE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svgxval.h>
 
 
   /* documentation is in ftgxval.h */
diff --git a/src/base/fthash.c b/src/base/fthash.c
index 387e6d2..313bbbb 100644
--- a/src/base/fthash.c
+++ b/src/base/fthash.c
@@ -39,9 +39,8 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_HASH_H
-#include FT_INTERNAL_MEMORY_H
+#include <freetype/internal/fthash.h>
+#include <freetype/internal/ftmemory.h>
 
 
 #define INITIAL_HT_SIZE  241
@@ -244,7 +243,7 @@
     nn = *bp;
     if ( !nn )
     {
-      if ( FT_NEW( nn ) )
+      if ( FT_QNEW( nn ) )
         goto Exit;
       *bp = nn;
 
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index e0f2ccd..c9c71d2 100644
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -4,7 +4,7 @@
  *
  *   FreeType initialization layer (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -39,9 +39,9 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_MODULE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftmodapi.h>
 
 
   /**************************************************************************
@@ -51,7 +51,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_init
+#define FT_COMPONENT  init
 
 
 #undef  FT_USE_MODULE
@@ -176,6 +176,9 @@
                               module_name,
                               property_name,
                               property_value );
+
+      if ( !*p )
+        break;
     }
   }
 
@@ -199,6 +202,10 @@
     FT_Memory  memory;
 
 
+#ifdef FT_DEBUG_LOGGING
+    ft_logging_init();
+#endif
+
     /* check of `alibrary' delayed to `FT_New_Library' */
 
     /* First of all, allocate a new system object -- this function is part */
@@ -245,6 +252,10 @@
     /* discard memory manager */
     FT_Done_Memory( memory );
 
+#ifdef FT_DEBUG_LOGGING
+    ft_logging_deinit();
+#endif
+
     return FT_Err_Ok;
   }
 
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 65eff93..6c3fd66 100644
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for color filtering of subpixel bitmap glyphs (body).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_LCD_FILTER_H
-#include FT_IMAGE_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftlcdfil.h>
+#include <freetype/ftimage.h>
+#include <freetype/internal/ftobjs.h>
 
 
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
@@ -33,7 +32,7 @@
 
 
   /* add padding according to filter weights */
-  FT_BASE_DEF (void)
+  FT_BASE_DEF( void )
   ft_lcd_padding( FT_BBox*        cbox,
                   FT_GlyphSlot    slot,
                   FT_Render_Mode  mode )
@@ -77,13 +76,13 @@
   /* FIR filter used by the default and light filters */
   FT_BASE_DEF( void )
   ft_lcd_filter_fir( FT_Bitmap*           bitmap,
-                     FT_Render_Mode       mode,
                      FT_LcdFiveTapFilter  weights )
   {
     FT_UInt   width  = (FT_UInt)bitmap->width;
     FT_UInt   height = (FT_UInt)bitmap->rows;
     FT_Int    pitch  = bitmap->pitch;
     FT_Byte*  origin = bitmap->buffer;
+    FT_Byte   mode   = bitmap->pixel_mode;
 
 
     /* take care of bitmap flow */
@@ -91,7 +90,7 @@
       origin += pitch * (FT_Int)( height - 1 );
 
     /* horizontal in-place FIR filter */
-    if ( mode == FT_RENDER_MODE_LCD && width >= 2 )
+    if ( mode == FT_PIXEL_MODE_LCD && width >= 2 )
     {
       FT_Byte*  line = origin;
 
@@ -134,7 +133,7 @@
     }
 
     /* vertical in-place FIR filter */
-    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 )
+    else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 2 )
     {
       FT_Byte*  column = origin;
 
@@ -183,13 +182,13 @@
   /* intra-pixel filter used by the legacy filter */
   static void
   _ft_lcd_filter_legacy( FT_Bitmap*      bitmap,
-                         FT_Render_Mode  mode,
                          FT_Byte*        weights )
   {
     FT_UInt   width  = (FT_UInt)bitmap->width;
     FT_UInt   height = (FT_UInt)bitmap->rows;
     FT_Int    pitch  = bitmap->pitch;
     FT_Byte*  origin = bitmap->buffer;
+    FT_Byte   mode   = bitmap->pixel_mode;
 
     static const unsigned int  filters[3][3] =
     {
@@ -206,7 +205,7 @@
       origin += pitch * (FT_Int)( height - 1 );
 
     /* horizontal in-place intra-pixel filter */
-    if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
+    if ( mode == FT_PIXEL_MODE_LCD && width >= 3 )
     {
       FT_Byte*  line = origin;
 
@@ -243,7 +242,7 @@
         }
       }
     }
-    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
+    else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 3 )
     {
       FT_Byte*  column = origin;
 
@@ -358,7 +357,7 @@
 
   FT_EXPORT_DEF( FT_Error )
   FT_Library_SetLcdGeometry( FT_Library  library,
-                             FT_Vector*  sub )
+                             FT_Vector   sub[3] )
   {
     FT_UNUSED( library );
     FT_UNUSED( sub );
@@ -369,7 +368,7 @@
 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
 
   /* add padding to accommodate outline shifts */
-  FT_BASE_DEF (void)
+  FT_BASE_DEF( void )
   ft_lcd_padding( FT_BBox*        cbox,
                   FT_GlyphSlot    slot,
                   FT_Render_Mode  mode )
@@ -429,7 +428,7 @@
 
     ft_memcpy( library->lcd_geometry, sub, 3 * sizeof( FT_Vector ) );
 
-    return FT_THROW( Unimplemented_Feature );
+    return FT_Err_Ok;
   }
 
 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
diff --git a/src/base/ftmac.c b/src/base/ftmac.c
index 79e3fe4..de34e83 100644
--- a/src/base/ftmac.c
+++ b/src/base/ftmac.c
@@ -8,7 +8,7 @@
  * This file is for Mac OS X only; see builds/mac/ftoldmac.c for
  * classic platforms built by MPW.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -65,10 +65,10 @@
   */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/freetype.h>
+#include <freetype/tttags.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
 #include "ftbase.h"
 
 
@@ -106,7 +106,7 @@
   /* Don't want warnings about our own use of deprecated functions. */
 #define FT_DEPRECATED_ATTRIBUTE
 
-#include FT_MAC_H
+#include <freetype/ftmac.h>
 
 #ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */
 #define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault
@@ -315,7 +315,7 @@
                                     NULL, NULL, NULL ) )
       return ( OSType ) 0;
 
-    return ((FInfo *)(info.finderInfo))->fdType;
+    return ( (FInfo *)( info.finderInfo ) )->fdType;
   }
 
 
@@ -463,7 +463,7 @@
 
         if ( ps_name_len != 0 )
         {
-          ft_memcpy(ps_name, names[0] + 1, ps_name_len);
+          ft_memcpy( ps_name, names[0] + 1, ps_name_len );
           ps_name[ps_name_len] = 0;
         }
         if ( style->indexes[face_index] > 1 &&
@@ -561,7 +561,7 @@
     if ( lwfn_file_name[0] )
     {
       err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
-                                 buff, sizeof ( buff )  );
+                                 buff, sizeof ( buff ) );
       if ( !err )
         have_lwfn = 1;
     }
@@ -632,7 +632,7 @@
       old_total_size = total_size;
     }
 
-    if ( FT_ALLOC( buffer, (FT_Long)total_size ) )
+    if ( FT_QALLOC( buffer, (FT_Long)total_size ) )
       goto Error;
 
     /* Second pass: append all POST data to the buffer, add PFB fields. */
@@ -753,7 +753,7 @@
     if ( FT_MAC_RFORK_MAX_LEN < sfnt_size )
       return FT_THROW( Array_Too_Large );
 
-    if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
+    if ( FT_QALLOC( sfnt_data, (FT_Long)sfnt_size ) )
     {
       ReleaseResource( sfnt );
       return error;
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index b0d9d4b..a2b4bd0 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -4,7 +4,7 @@
  *
  *   Multiple Master font support (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,13 +16,12 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_MULTIPLE_MASTERS_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_MULTIPLE_MASTERS_H
-#include FT_SERVICE_METRICS_VARIATIONS_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svmm.h>
+#include <freetype/internal/services/svmetric.h>
 
 
   /**************************************************************************
@@ -32,7 +31,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_mm
+#define FT_COMPONENT  mm
 
 
   static FT_Error
@@ -202,6 +201,67 @@
   /* documentation is in ftmm.h */
 
   FT_EXPORT_DEF( FT_Error )
+  FT_Set_MM_WeightVector( FT_Face    face,
+                          FT_UInt    len,
+                          FT_Fixed*  weightvector )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( len && !weightvector )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service->set_mm_weightvector )
+        error = service->set_mm_weightvector( face, len, weightvector );
+    }
+
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_MM_WeightVector( FT_Face    face,
+                          FT_UInt*   len,
+                          FT_Fixed*  weightvector )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( len && !weightvector )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service->get_mm_weightvector )
+        error = service->get_mm_weightvector( face, len, weightvector );
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
   FT_Set_Var_Design_Coordinates( FT_Face    face,
                                  FT_UInt    num_coords,
                                  FT_Fixed*  coords )
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 2b44405..ad6ef0a 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType private base classes (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,32 +16,33 @@
  */
 
 
-#include <ft2build.h>
-#include FT_LIST_H
-#include FT_OUTLINE_H
-#include FT_FONT_FORMATS_H
+#include <freetype/ftlist.h>
+#include <freetype/ftoutln.h>
+#include <freetype/ftfntfmt.h>
+#include <freetype/otsvg.h>
 
-#include FT_INTERNAL_VALIDATE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_RFORK_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H            /* for SFNT_Load_Table_Func */
-#include FT_INTERNAL_POSTSCRIPT_AUX_H  /* for PS_Driver            */
+#include <freetype/internal/ftvalid.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftrfork.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/sfnt.h>          /* for SFNT_Load_Table_Func */
+#include <freetype/internal/psaux.h>         /* for PS_Driver            */
+#include <freetype/internal/svginterface.h>
 
-#include FT_TRUETYPE_TABLES_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/tttables.h>
+#include <freetype/tttags.h>
+#include <freetype/ttnameid.h>
 
-#include FT_SERVICE_PROPERTIES_H
-#include FT_SERVICE_SFNT_H
-#include FT_SERVICE_POSTSCRIPT_NAME_H
-#include FT_SERVICE_GLYPH_DICT_H
-#include FT_SERVICE_TT_CMAP_H
-#include FT_SERVICE_KERNING_H
-#include FT_SERVICE_TRUETYPE_ENGINE_H
+#include <freetype/internal/services/svprop.h>
+#include <freetype/internal/services/svsfnt.h>
+#include <freetype/internal/services/svpostnm.h>
+#include <freetype/internal/services/svgldict.h>
+#include <freetype/internal/services/svttcmap.h>
+#include <freetype/internal/services/svkern.h>
+#include <freetype/internal/services/svtteng.h>
 
-#include FT_DRIVER_H
+#include <freetype/ftdriver.h>
 
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
 #include "ftbase.h"
@@ -50,7 +51,7 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-#include FT_BITMAP_H
+#include <freetype/ftbitmap.h>
 
 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++)   */
   /* We disable the warning `conversion from XXX to YYY,     */
@@ -79,6 +80,9 @@
 #pragma warning( pop )
 #endif
 
+  /* This array must stay in sync with the @FT_Pixel_Mode enumeration */
+  /* (in file `ftimage.h`).                                           */
+
   static const char* const  pixel_modes[] =
   {
     "none",
@@ -88,7 +92,8 @@
     "gray 4-bit bitmap",
     "LCD 8-bit bitmap",
     "vertical LCD 8-bit bitmap",
-    "BGRA 32-bit color image bitmap"
+    "BGRA 32-bit color image bitmap",
+    "SDF 8-bit bitmap"
   };
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
@@ -194,6 +199,7 @@
     FT_Error   error;
     FT_Memory  memory;
     FT_Stream  stream = NULL;
+    FT_UInt    mode;
 
 
     *astream = NULL;
@@ -205,49 +211,56 @@
       return FT_THROW( Invalid_Argument );
 
     memory = library->memory;
+    mode   = args->flags &
+               ( FT_OPEN_MEMORY | FT_OPEN_STREAM | FT_OPEN_PATHNAME );
 
-    if ( FT_NEW( stream ) )
-      goto Exit;
-
-    stream->memory = memory;
-
-    if ( args->flags & FT_OPEN_MEMORY )
+    if ( mode == FT_OPEN_MEMORY )
     {
       /* create a memory-based stream */
+      if ( FT_NEW( stream ) )
+        goto Exit;
+
       FT_Stream_OpenMemory( stream,
                             (const FT_Byte*)args->memory_base,
                             (FT_ULong)args->memory_size );
+      stream->memory = memory;
     }
 
 #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
 
-    else if ( args->flags & FT_OPEN_PATHNAME )
+    else if ( mode == FT_OPEN_PATHNAME )
     {
       /* create a normal system stream */
+      if ( FT_NEW( stream ) )
+        goto Exit;
+
+      stream->memory = memory;
       error = FT_Stream_Open( stream, args->pathname );
-      stream->pathname.pointer = args->pathname;
+      if ( error )
+        FT_FREE( stream );
     }
-    else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
+    else if ( ( mode == FT_OPEN_STREAM ) && args->stream )
     {
       /* use an existing, user-provided stream */
 
       /* in this case, we do not need to allocate a new stream object */
       /* since the caller is responsible for closing it himself       */
-      FT_FREE( stream );
-      stream = args->stream;
+      stream         = args->stream;
+      stream->memory = memory;
+      error          = FT_Err_Ok;
     }
 
 #endif
 
     else
+    {
       error = FT_THROW( Invalid_Argument );
+      if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
+        FT_Stream_Close( args->stream );
+    }
 
-    if ( error )
-      FT_FREE( stream );
-    else
-      stream->memory = memory;  /* just to be certain */
-
-    *astream = stream;
+    if ( !error )
+      *astream       = stream;
 
   Exit:
     return error;
@@ -278,7 +291,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_objs
+#define FT_COMPONENT  objs
 
 
   /*************************************************************************/
@@ -317,6 +330,19 @@
     if ( !error && clazz->init_slot )
       error = clazz->init_slot( slot );
 
+#ifdef FT_CONFIG_OPTION_SVG
+    /* if SVG table exists, allocate the space in `slot->other` */
+    if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
+    {
+      FT_SVG_Document  document = NULL;
+
+
+      if ( FT_NEW( document ) )
+        goto Exit;
+      slot->other = document;
+    }
+#endif
+
   Exit:
     return error;
   }
@@ -342,7 +368,9 @@
   }
 
 
-  FT_BASE_DEF( void )
+  /* overflow-resistant presetting of bitmap position and dimensions; */
+  /* also check whether the size is too large for rendering           */
+  FT_BASE_DEF( FT_Bool )
   ft_glyphslot_preset_bitmap( FT_GlyphSlot      slot,
                               FT_Render_Mode    mode,
                               const FT_Vector*  origin )
@@ -352,15 +380,26 @@
 
     FT_Pixel_Mode  pixel_mode;
 
-    FT_BBox  cbox;
+    FT_BBox  cbox, pbox;
     FT_Pos   x_shift = 0;
     FT_Pos   y_shift = 0;
     FT_Pos   x_left, y_top;
     FT_Pos   width, height, pitch;
 
 
-    if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
-      return;
+    if ( slot->format == FT_GLYPH_FORMAT_SVG )
+    {
+      FT_Module    module;
+      SVG_Service  svg_service;
+
+
+      module      = FT_Get_Module( slot->library, "ot-svg" );
+      svg_service = (SVG_Service)module->clazz->module_interface;
+
+      return (FT_Bool)svg_service->preset_slot( module, slot, FALSE );
+    }
+    else if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
+      return 1;
 
     if ( origin )
     {
@@ -372,70 +411,89 @@
     /* taking into account the origin shift      */
     FT_Outline_Get_CBox( outline, &cbox );
 
-    cbox.xMin += x_shift;
-    cbox.yMin += y_shift;
-    cbox.xMax += x_shift;
-    cbox.yMax += y_shift;
+    /* rough estimate of pixel box */
+    pbox.xMin = ( cbox.xMin >> 6 ) + ( x_shift >> 6 );
+    pbox.yMin = ( cbox.yMin >> 6 ) + ( y_shift >> 6 );
+    pbox.xMax = ( cbox.xMax >> 6 ) + ( x_shift >> 6 );
+    pbox.yMax = ( cbox.yMax >> 6 ) + ( y_shift >> 6 );
+
+    /* tiny remainder box */
+    cbox.xMin = ( cbox.xMin & 63 ) + ( x_shift & 63 );
+    cbox.yMin = ( cbox.yMin & 63 ) + ( y_shift & 63 );
+    cbox.xMax = ( cbox.xMax & 63 ) + ( x_shift & 63 );
+    cbox.yMax = ( cbox.yMax & 63 ) + ( y_shift & 63 );
 
     switch ( mode )
     {
     case FT_RENDER_MODE_MONO:
       pixel_mode = FT_PIXEL_MODE_MONO;
 #if 1
-      /* undocumented but confirmed: bbox values get rounded    */
-      /* unless the rounded box can collapse for a narrow glyph */
-      if ( cbox.xMax - cbox.xMin < 64 )
+      /* x */
+
+      /* undocumented but confirmed: bbox values get rounded;    */
+      /* we do asymmetric rounding so that the center of a pixel */
+      /* gets always included                                    */
+
+      pbox.xMin += ( cbox.xMin + 31 ) >> 6;
+      pbox.xMax += ( cbox.xMax + 32 ) >> 6;
+
+      /* if the bbox collapsed, we add a pixel based on the total */
+      /* rounding remainder to cover most of the original cbox    */
+
+      if ( pbox.xMin == pbox.xMax )
       {
-        cbox.xMin = ( cbox.xMin + cbox.xMax ) / 2 - 32;
-        cbox.xMax = cbox.xMin + 64;
+        if ( ( ( cbox.xMin + 31 ) & 63 ) - 31 +
+             ( ( cbox.xMax + 32 ) & 63 ) - 32 < 0 )
+          pbox.xMin -= 1;
+        else
+          pbox.xMax += 1;
       }
 
-      cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin );
-      cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax );
+      /* y */
 
-      if ( cbox.yMax - cbox.yMin < 64 )
+      pbox.yMin += ( cbox.yMin + 31 ) >> 6;
+      pbox.yMax += ( cbox.yMax + 32 ) >> 6;
+
+      if ( pbox.yMin == pbox.yMax )
       {
-        cbox.yMin = ( cbox.yMin + cbox.yMax ) / 2 - 32;
-        cbox.yMax = cbox.yMin + 64;
+        if ( ( ( cbox.yMin + 31 ) & 63 ) - 31 +
+             ( ( cbox.yMax + 32 ) & 63 ) - 32 < 0 )
+          pbox.yMin -= 1;
+        else
+          pbox.yMax += 1;
       }
 
-      cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin );
-      cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax );
-
       break;
 #else
-      goto Round;
+      goto Adjust;
 #endif
 
     case FT_RENDER_MODE_LCD:
       pixel_mode = FT_PIXEL_MODE_LCD;
       ft_lcd_padding( &cbox, slot, mode );
-      goto Round;
+      goto Adjust;
 
     case FT_RENDER_MODE_LCD_V:
       pixel_mode = FT_PIXEL_MODE_LCD_V;
       ft_lcd_padding( &cbox, slot, mode );
-      goto Round;
+      goto Adjust;
 
     case FT_RENDER_MODE_NORMAL:
     case FT_RENDER_MODE_LIGHT:
     default:
       pixel_mode = FT_PIXEL_MODE_GRAY;
-    Round:
-      cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
-      cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
-      cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
-      cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
+    Adjust:
+      pbox.xMin += cbox.xMin >> 6;
+      pbox.yMin += cbox.yMin >> 6;
+      pbox.xMax += ( cbox.xMax + 63 ) >> 6;
+      pbox.yMax += ( cbox.yMax + 63 ) >> 6;
     }
 
-    x_shift = SUB_LONG( x_shift, cbox.xMin );
-    y_shift = SUB_LONG( y_shift, cbox.yMin );
+    x_left = pbox.xMin;
+    y_top  = pbox.yMax;
 
-    x_left = cbox.xMin >> 6;
-    y_top  = cbox.yMax >> 6;
-
-    width  = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6;
-    height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6;
+    width  = pbox.xMax - pbox.xMin;
+    height = pbox.yMax - pbox.yMin;
 
     switch ( pixel_mode )
     {
@@ -450,7 +508,7 @@
 
     case FT_PIXEL_MODE_LCD_V:
       height *= 3;
-      /* fall through */
+      FALL_THROUGH;
 
     case FT_PIXEL_MODE_GRAY:
     default:
@@ -465,6 +523,16 @@
     bitmap->width      = (unsigned int)width;
     bitmap->rows       = (unsigned int)height;
     bitmap->pitch      = pitch;
+
+    if ( pbox.xMin < -0x8000 || pbox.xMax > 0x7FFF ||
+         pbox.yMin < -0x8000 || pbox.yMax > 0x7FFF )
+    {
+      FT_TRACE3(( "ft_glyphslot_preset_bitmap: [%ld %ld %ld %ld]\n",
+                  pbox.xMin, pbox.yMin, pbox.xMax, pbox.yMax ));
+      return 1;
+    }
+
+    return 0;
   }
 
 
@@ -493,7 +561,7 @@
     else
       slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
 
-    (void)FT_ALLOC( slot->bitmap.buffer, size );
+    FT_MEM_ALLOC( slot->bitmap.buffer, size );
     return error;
   }
 
@@ -505,6 +573,8 @@
     ft_glyphslot_free_bitmap( slot );
 
     /* clear all public fields in the glyph slot */
+    slot->glyph_index = 0;
+
     FT_ZERO( &slot->metrics );
     FT_ZERO( &slot->outline );
 
@@ -520,11 +590,32 @@
     slot->subglyphs     = NULL;
     slot->control_data  = NULL;
     slot->control_len   = 0;
-    slot->other         = NULL;
-    slot->format        = FT_GLYPH_FORMAT_NONE;
+
+#ifndef FT_CONFIG_OPTION_SVG
+    slot->other = NULL;
+#else
+    if ( !( slot->face->face_flags & FT_FACE_FLAG_SVG ) )
+      slot->other = NULL;
+    else
+    {
+      if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
+      {
+        FT_Memory        memory = slot->face->memory;
+        FT_SVG_Document  doc    = (FT_SVG_Document)slot->other;
+
+
+        FT_FREE( doc->svg_document );
+        slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG;
+      }
+    }
+#endif
+
+    slot->format = FT_GLYPH_FORMAT_NONE;
 
     slot->linearHoriAdvance = 0;
     slot->linearVertAdvance = 0;
+    slot->advance.x         = 0;
+    slot->advance.y         = 0;
     slot->lsb_delta         = 0;
     slot->rsb_delta         = 0;
   }
@@ -537,6 +628,24 @@
     FT_Driver_Class  clazz  = driver->clazz;
     FT_Memory        memory = driver->root.memory;
 
+#ifdef FT_CONFIG_OPTION_SVG
+    if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
+    {
+      /* Free memory in case SVG was there.                          */
+      /* `slot->internal` might be NULL in out-of-memory situations. */
+      if ( slot->internal && slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
+      {
+        FT_SVG_Document  doc = (FT_SVG_Document)slot->other;
+
+
+        FT_FREE( doc->svg_document );
+
+        slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG;
+      }
+
+      FT_FREE( slot->other );
+    }
+#endif
 
     if ( clazz->done_slot )
       clazz->done_slot( slot );
@@ -704,6 +813,29 @@
   }
 
 
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Get_Transform( FT_Face     face,
+                    FT_Matrix*  matrix,
+                    FT_Vector*  delta )
+  {
+    FT_Face_Internal  internal;
+
+
+    if ( !face )
+      return;
+
+    internal = face->internal;
+
+    if ( matrix )
+      *matrix = internal->transform_matrix;
+
+    if ( delta )
+      *delta = internal->transform_delta;
+  }
+
+
   static FT_Renderer
   ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
 
@@ -789,6 +921,11 @@
     library = driver->root.library;
     hinter  = library->auto_hinter;
 
+    /* undefined scale means no scale */
+    if ( face->size->metrics.x_ppem == 0 ||
+         face->size->metrics.y_ppem == 0 )
+      load_flags |= FT_LOAD_NO_SCALE;
+
     /* resolve load flags dependencies */
 
     if ( load_flags & FT_LOAD_NO_RECURSE )
@@ -813,7 +950,7 @@
      * - Do only auto-hinting if we have
      *
      *   - a hinter module,
-     *   - a scalable font format dealing with outlines,
+     *   - a scalable font,
      *   - not a tricky font, and
      *   - no transforms except simple slants and/or rotations by
      *     integer multiples of 90 degrees.
@@ -831,8 +968,7 @@
     if ( hinter                                           &&
          !( load_flags & FT_LOAD_NO_HINTING )             &&
          !( load_flags & FT_LOAD_NO_AUTOHINT )            &&
-         FT_DRIVER_IS_SCALABLE( driver )                  &&
-         FT_DRIVER_USES_OUTLINES( driver )                &&
+         FT_IS_SCALABLE( face )                           &&
          !FT_IS_TRICKY( face )                            &&
          ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM )    ||
            ( face->internal->transform_matrix.yx == 0 &&
@@ -852,7 +988,7 @@
         /* only the new Adobe engine (for both CFF and Type 1) is `light'; */
         /* we use `strstr' to catch both `Type 1' and `CID Type 1'         */
         is_light_type1 =
-          ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL   &&
+          ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL &&
           ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE;
 
         /* the check for `num_locations' assures that we actually    */
@@ -879,11 +1015,21 @@
       FT_AutoHinter_Interface  hinting;
 
 
-      /* try to load embedded bitmaps first if available            */
-      /*                                                            */
-      /* XXX: This is really a temporary hack that should disappear */
-      /*      promptly with FreeType 2.1!                           */
-      /*                                                            */
+      /* XXX: The use of the `FT_LOAD_XXX_ONLY` flags is not very */
+      /*      elegant.                                            */
+
+      /* try to load SVG documents if available */
+      if ( FT_HAS_SVG( face ) )
+      {
+        error = driver->clazz->load_glyph( slot, face->size,
+                                           glyph_index,
+                                           load_flags | FT_LOAD_SVG_ONLY );
+
+        if ( !error && slot->format == FT_GLYPH_FORMAT_SVG )
+          goto Load_Ok;
+      }
+
+      /* try to load embedded bitmaps if available */
       if ( FT_HAS_FIXED_SIZES( face )              &&
            ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
       {
@@ -932,8 +1078,9 @@
 
 #ifdef GRID_FIT_METRICS
         if ( !( load_flags & FT_LOAD_NO_HINTING ) )
-          ft_glyphslot_grid_fit_metrics( slot,
-              FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
+          ft_glyphslot_grid_fit_metrics(
+            slot,
+            FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
 #endif
       }
     }
@@ -1026,17 +1173,47 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
     FT_TRACE5(( "FT_Load_Glyph: index %d, flags 0x%x\n",
                 glyph_index, load_flags ));
-    FT_TRACE5(( "  x advance: %f\n", slot->advance.x / 64.0 ));
-    FT_TRACE5(( "  y advance: %f\n", slot->advance.y / 64.0 ));
-    FT_TRACE5(( "  linear x advance: %f\n",
-                slot->linearHoriAdvance / 65536.0 ));
-    FT_TRACE5(( "  linear y advance: %f\n",
-                slot->linearVertAdvance / 65536.0 ));
-    FT_TRACE5(( "  bitmap %dx%d, %s (mode %d)\n",
+    FT_TRACE5(( "  bitmap %dx%d %s, %s (mode %d)\n",
                 slot->bitmap.width,
                 slot->bitmap.rows,
+                slot->outline.points ?
+                  slot->bitmap.buffer ? "rendered"
+                                      : "preset"
+                                     :
+                  slot->internal->flags & FT_GLYPH_OWN_BITMAP ? "owned"
+                                                              : "unowned",
                 pixel_modes[slot->bitmap.pixel_mode],
                 slot->bitmap.pixel_mode ));
+    FT_TRACE5(( "\n" ));
+    FT_TRACE5(( "  x advance: %f\n", (double)slot->advance.x / 64 ));
+    FT_TRACE5(( "  y advance: %f\n", (double)slot->advance.y / 64 ));
+    FT_TRACE5(( "  linear x advance: %f\n",
+                (double)slot->linearHoriAdvance / 65536 ));
+    FT_TRACE5(( "  linear y advance: %f\n",
+                (double)slot->linearVertAdvance / 65536 ));
+
+    {
+      FT_Glyph_Metrics*  metrics = &slot->metrics;
+
+
+      FT_TRACE5(( "  metrics:\n" ));
+      FT_TRACE5(( "    width:  %f\n", (double)metrics->width / 64 ));
+      FT_TRACE5(( "    height: %f\n", (double)metrics->height / 64 ));
+      FT_TRACE5(( "\n" ));
+      FT_TRACE5(( "    horiBearingX: %f\n",
+                  (double)metrics->horiBearingX / 64 ));
+      FT_TRACE5(( "    horiBearingY: %f\n",
+                  (double)metrics->horiBearingY / 64 ));
+      FT_TRACE5(( "    horiAdvance:  %f\n",
+                  (double)metrics->horiAdvance / 64 ));
+      FT_TRACE5(( "\n" ));
+      FT_TRACE5(( "    vertBearingX: %f\n",
+                  (double)metrics->vertBearingX / 64 ));
+      FT_TRACE5(( "    vertBearingY: %f\n",
+                  (double)metrics->vertBearingY / 64 ));
+      FT_TRACE5(( "    vertAdvance:  %f\n",
+                  (double)metrics->vertAdvance / 64 ));
+    }
 #endif
 
   Exit:
@@ -1318,7 +1495,7 @@
   static FT_Error
   open_face( FT_Driver      driver,
              FT_Stream      *astream,
-             FT_Bool        external_stream,
+             FT_Bool        *anexternal_stream,
              FT_Long        face_index,
              FT_Int         num_params,
              FT_Parameter*  params,
@@ -1344,7 +1521,7 @@
     face->stream = *astream;
 
     /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
-    if ( external_stream )
+    if ( *anexternal_stream )
       face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
 
     if ( FT_NEW( internal ) )
@@ -1374,7 +1551,10 @@
                                 (FT_Int)face_index,
                                 num_params,
                                 params );
-    *astream = face->stream; /* Stream may have been changed. */
+    /* Stream may have been changed. */
+    *astream = face->stream;
+    *anexternal_stream =
+      ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0;
     if ( error )
       goto Fail;
 
@@ -1498,14 +1678,13 @@
   static void
   memory_stream_close( FT_Stream  stream )
   {
-    FT_Memory  memory = stream->memory;
+    FT_Memory  memory = (FT_Memory)stream->descriptor.pointer;
 
 
     FT_FREE( stream->base );
-
     stream->size  = 0;
-    stream->base  = NULL;
     stream->close = NULL;
+    FT_FREE( stream );
   }
 
 
@@ -1536,7 +1715,8 @@
 
     FT_Stream_OpenMemory( stream, base, size );
 
-    stream->close = close;
+    stream->descriptor.pointer = memory;
+    stream->close              = close;
 
     *astream = stream;
 
@@ -1557,28 +1737,36 @@
   {
     FT_Open_Args  args;
     FT_Error      error;
-    FT_Stream     stream = NULL;
     FT_Memory     memory = library->memory;
 
 
+    args.flags = 0;
+
+    if ( driver_name )
+    {
+      args.driver = FT_Get_Module( library, driver_name );
+      if ( !args.driver )
+      {
+        FT_FREE( base );
+        return FT_THROW( Missing_Module );
+      }
+
+      args.flags = args.flags | FT_OPEN_DRIVER;
+    }
+
+    /* `memory_stream_close` also frees the stream object. */
     error = new_memory_stream( library,
                                base,
                                size,
                                memory_stream_close,
-                               &stream );
+                               &args.stream );
     if ( error )
     {
       FT_FREE( base );
       return error;
     }
 
-    args.flags  = FT_OPEN_STREAM;
-    args.stream = stream;
-    if ( driver_name )
-    {
-      args.flags  = args.flags | FT_OPEN_DRIVER;
-      args.driver = FT_Get_Module( library, driver_name );
-    }
+    args.flags |= FT_OPEN_STREAM;
 
 #ifdef FT_MACINTOSH
     /* At this point, the face index has served its purpose;  */
@@ -1590,21 +1778,7 @@
       face_index &= 0x7FFF0000L; /* retain GX data */
 #endif
 
-    error = ft_open_face_internal( library, &args, face_index, aface, 0 );
-
-    if ( !error )
-      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
-    else
-#ifdef FT_MACINTOSH
-      FT_Stream_Free( stream, 0 );
-#else
-    {
-      FT_Stream_Close( stream );
-      FT_FREE( stream );
-    }
-#endif
-
-    return error;
+    return ft_open_face_internal( library, &args, face_index, aface, 0 );
   }
 
 
@@ -1733,7 +1907,7 @@
     if ( error )
       goto Exit;
 
-    if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
+    if ( FT_QALLOC( sfnt_ps, (FT_Long)length ) )
       goto Exit;
 
     error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
@@ -1747,7 +1921,7 @@
                                    sfnt_ps,
                                    length,
                                    FT_MIN( face_index, 0 ),
-                                   is_sfnt_cid ? "cid" : "type1",
+                                   is_sfnt_cid ? "t1cid" : "type1",
                                    aface );
   Exit:
     {
@@ -1811,15 +1985,15 @@
       /* FT2 allocator takes signed long buffer length,
        * too large value causing overflow should be checked
        */
-      FT_TRACE4(( "                 POST fragment #%d: length=0x%08x"
-                  " total pfb_len=0x%08x\n",
+      FT_TRACE4(( "                 POST fragment #%d: length=0x%08lx"
+                  " total pfb_len=0x%08lx\n",
                   i, temp, pfb_len + temp + 6 ));
 
       if ( FT_MAC_RFORK_MAX_LEN < temp               ||
            FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 )
       {
         FT_TRACE2(( "             MacOS resource length cannot exceed"
-                    " 0x%08x\n",
+                    " 0x%08lx\n",
                     FT_MAC_RFORK_MAX_LEN ));
 
         error = FT_THROW( Invalid_Offset );
@@ -1830,20 +2004,20 @@
     }
 
     FT_TRACE2(( "             total buffer size to concatenate"
-                " %d POST fragments: 0x%08x\n",
+                " %ld POST fragments: 0x%08lx\n",
                  resource_cnt, pfb_len + 2 ));
 
     if ( pfb_len + 2 < 6 )
     {
       FT_TRACE2(( "             too long fragment length makes"
-                  " pfb_len confused: pfb_len=0x%08x\n",
+                  " pfb_len confused: pfb_len=0x%08lx\n",
                   pfb_len ));
 
       error = FT_THROW( Array_Too_Large );
       goto Exit;
     }
 
-    if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
+    if ( FT_QALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
       goto Exit;
 
     pfb_data[0] = 0x80;
@@ -1879,7 +2053,7 @@
         goto Exit2;
 
       FT_TRACE3(( "POST fragment[%d]:"
-                  " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
+                  " offsets=0x%08lx, rlen=0x%08lx, flags=0x%04x\n",
                   i, offsets[i], rlen, flags ));
 
       error = FT_ERR( Array_Too_Large );
@@ -1906,8 +2080,8 @@
       else
       {
         FT_TRACE3(( "    Write POST fragment #%d header (4-byte) to buffer"
-                    " %p + 0x%08x\n",
-                    i, pfb_data, pfb_lenpos ));
+                    " %p + 0x%08lx\n",
+                    i, (void*)pfb_data, pfb_lenpos ));
 
         if ( pfb_lenpos + 3 > pfb_len + 2 )
           goto Exit2;
@@ -1921,8 +2095,8 @@
           break;
 
         FT_TRACE3(( "    Write POST fragment #%d header (6-byte) to buffer"
-                    " %p + 0x%08x\n",
-                    i, pfb_data, pfb_pos ));
+                    " %p + 0x%08lx\n",
+                    i, (void*)pfb_data, pfb_pos ));
 
         if ( pfb_pos + 6 > pfb_len + 2 )
           goto Exit2;
@@ -1943,9 +2117,9 @@
       if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
         goto Exit2;
 
-      FT_TRACE3(( "    Load POST fragment #%d (%d byte) to buffer"
-                  " %p + 0x%08x\n",
-                  i, rlen, pfb_data, pfb_pos ));
+      FT_TRACE3(( "    Load POST fragment #%d (%ld byte) to buffer"
+                  " %p + 0x%08lx\n",
+                  i, rlen, (void*)pfb_data, pfb_pos ));
 
       error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
       if ( error )
@@ -2008,7 +2182,7 @@
     FT_Byte*   sfnt_data = NULL;
     FT_Error   error;
     FT_ULong   flag_offset;
-    FT_Long    rlen;
+    FT_ULong   rlen;
     int        is_cff;
     FT_Long    face_index_in_resource = 0;
 
@@ -2023,11 +2197,11 @@
     if ( error )
       goto Exit;
 
-    if ( FT_READ_LONG( rlen ) )
+    if ( FT_READ_ULONG( rlen ) )
       goto Exit;
-    if ( rlen < 1 )
+    if ( !rlen )
       return FT_THROW( Cannot_Open_Resource );
-    if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN )
+    if ( rlen > FT_MAC_RFORK_MAX_LEN )
       return FT_THROW( Invalid_Offset );
 
     error = open_face_PS_from_sfnt_stream( library,
@@ -2043,10 +2217,11 @@
     if ( error )
       goto Exit;
 
-    if ( FT_ALLOC( sfnt_data, rlen ) )
+    if ( FT_QALLOC( sfnt_data, rlen ) )
       return error;
-    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen );
-    if ( error ) {
+    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
+    if ( error )
+    {
       FT_FREE( sfnt_data );
       goto Exit;
     }
@@ -2054,7 +2229,7 @@
     is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
     error = open_face_from_buffer( library,
                                    sfnt_data,
-                                   (FT_ULong)rlen,
+                                   rlen,
                                    face_index_in_resource,
                                    is_cff ? "cff" : "truetype",
                                    aface );
@@ -2189,7 +2364,7 @@
   {
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_raccess
+#define FT_COMPONENT  raccess
 
     FT_Memory  memory = library->memory;
     FT_Error   error  = FT_ERR( Unknown_File_Format );
@@ -2229,7 +2404,7 @@
       args2.flags    = FT_OPEN_PATHNAME;
       args2.pathname = file_names[i] ? file_names[i] : args->pathname;
 
-      FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
+      FT_TRACE3(( "Try rule %d: %s (offset=%ld) ...",
                   i, args2.pathname, offsets[i] ));
 
       error = FT_Stream_New( library, &args2, &stream2 );
@@ -2267,7 +2442,7 @@
     return error;
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_objs
+#define FT_COMPONENT  objs
 
   }
 
@@ -2295,7 +2470,7 @@
     {
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_raccess
+#define FT_COMPONENT  raccess
 
 #ifdef FT_DEBUG_LEVEL_TRACE
       FT_TRACE3(( "Try as dfont: " ));
@@ -2308,7 +2483,7 @@
       FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_objs
+#define FT_COMPONENT  objs
 
     }
 
@@ -2358,6 +2533,16 @@
 #endif
 
 
+    /* only use lower 31 bits together with sign bit */
+    if ( face_index > 0 )
+      face_index &= 0x7FFFFFFFL;
+    else
+    {
+      face_index  = -face_index;
+      face_index &= 0x7FFFFFFFL;
+      face_index  = -face_index;
+    }
+
 #ifdef FT_DEBUG_LEVEL_TRACE
     FT_TRACE3(( "FT_Open_Face: " ));
     if ( face_index < 0 )
@@ -2373,7 +2558,7 @@
 
     /* test for valid `library' delayed to `FT_Stream_New' */
 
-    if ( ( !aface && face_index >= 0 ) || !args )
+    if ( !args )
       return FT_THROW( Invalid_Argument );
 
     external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
@@ -2384,6 +2569,14 @@
     if ( error )
       goto Fail3;
 
+    /* Do this error check after `FT_Stream_New` to ensure that the */
+    /* 'close' callback is called.                                  */
+    if ( !aface && face_index >= 0 )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Fail3;
+    }
+
     memory = library->memory;
 
     /* If the font driver is specified in the `args' structure, use */
@@ -2405,7 +2598,7 @@
           params     = args->params;
         }
 
-        error = open_face( driver, &stream, external_stream, face_index,
+        error = open_face( driver, &stream, &external_stream, face_index,
                            num_params, params, &face );
         if ( !error )
           goto Success;
@@ -2441,7 +2634,7 @@
             params     = args->params;
           }
 
-          error = open_face( driver, &stream, external_stream, face_index,
+          error = open_face( driver, &stream, &external_stream, face_index,
                              num_params, params, &face );
           if ( !error )
             goto Success;
@@ -2517,7 +2710,7 @@
     FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
 
     /* add the face object to its driver's list */
-    if ( FT_NEW( node ) )
+    if ( FT_QNEW( node ) )
       goto Fail;
 
     node->data = face;
@@ -2632,10 +2825,10 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( !error && face_index < 0 )
     {
-      FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n"
-                  "              and %ld named instance%s for face %ld\n",
+      FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n",
                   face->num_faces,
-                  face->num_faces == 1 ? "" : "s",
+                  face->num_faces == 1 ? "" : "s" ));
+      FT_TRACE3(( "              and %ld named instance%s for face %ld\n",
                   face->style_flags >> 16,
                   ( face->style_flags >> 16 ) == 1 ? "" : "s",
                   -face_index - 1 ));
@@ -2673,8 +2866,8 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_Attach_Stream( FT_Face        face,
-                    FT_Open_Args*  parameters )
+  FT_Attach_Stream( FT_Face              face,
+                    const FT_Open_Args*  parameters )
   {
     FT_Stream  stream;
     FT_Error   error;
@@ -2706,8 +2899,8 @@
 
     /* close the attached stream */
     FT_Stream_Free( stream,
-                    (FT_Bool)( parameters->stream &&
-                               ( parameters->flags & FT_OPEN_STREAM ) ) );
+                    FT_BOOL( parameters->stream                     &&
+                             ( parameters->flags & FT_OPEN_STREAM ) ) );
 
   Exit:
     return error;
@@ -2802,7 +2995,7 @@
     memory = face->memory;
 
     /* Allocate new size object and perform basic initialisation */
-    if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
+    if ( FT_ALLOC( size, clazz->size_object_size ) || FT_QNEW( node ) )
       goto Exit;
 
     size->face = face;
@@ -2827,6 +3020,8 @@
     if ( error )
     {
       FT_FREE( node );
+      if ( size )
+        FT_FREE( size->internal );
       FT_FREE( size );
     }
 
@@ -3037,10 +3232,12 @@
   }
 
 
-  FT_BASE_DEF( void )
+  FT_BASE_DEF( FT_Error )
   FT_Request_Metrics( FT_Face          face,
                       FT_Size_Request  req )
   {
+    FT_Error  error = FT_Err_Ok;
+
     FT_Size_Metrics*  metrics;
 
 
@@ -3095,34 +3292,49 @@
       scaled_h = FT_REQUEST_HEIGHT( req );
 
       /* determine scales */
+      if ( req->height || !req->width )
+      {
+        if ( h == 0 )
+        {
+          FT_ERROR(( "FT_Request_Metrics: Divide by zero\n" ));
+          error = FT_ERR( Divide_By_Zero );
+          goto Exit;
+        }
+
+        metrics->y_scale = FT_DivFix( scaled_h, h );
+      }
+
       if ( req->width )
       {
+        if ( w == 0 )
+        {
+          FT_ERROR(( "FT_Request_Metrics: Divide by zero\n" ));
+          error = FT_ERR( Divide_By_Zero );
+          goto Exit;
+        }
+
         metrics->x_scale = FT_DivFix( scaled_w, w );
-
-        if ( req->height )
-        {
-          metrics->y_scale = FT_DivFix( scaled_h, h );
-
-          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
-          {
-            if ( metrics->y_scale > metrics->x_scale )
-              metrics->y_scale = metrics->x_scale;
-            else
-              metrics->x_scale = metrics->y_scale;
-          }
-        }
-        else
-        {
-          metrics->y_scale = metrics->x_scale;
-          scaled_h = FT_MulDiv( scaled_w, h, w );
-        }
       }
       else
       {
-        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
+        metrics->x_scale = metrics->y_scale;
         scaled_w = FT_MulDiv( scaled_h, w, h );
       }
 
+      if ( !req->height )
+      {
+        metrics->y_scale = metrics->x_scale;
+        scaled_h = FT_MulDiv( scaled_w, h, w );
+      }
+
+      if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
+      {
+        if ( metrics->y_scale > metrics->x_scale )
+          metrics->y_scale = metrics->x_scale;
+        else
+          metrics->x_scale = metrics->y_scale;
+      }
+
   Calculate_Ppem:
       /* calculate the ppems */
       if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
@@ -3131,8 +3343,18 @@
         scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
       }
 
-      metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
-      metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
+      scaled_w = ( scaled_w + 32 ) >> 6;
+      scaled_h = ( scaled_h + 32 ) >> 6;
+      if ( scaled_w > (FT_Long)FT_USHORT_MAX ||
+           scaled_h > (FT_Long)FT_USHORT_MAX )
+      {
+        FT_ERROR(( "FT_Request_Metrics: Resulting ppem size too large\n" ));
+        error = FT_ERR( Invalid_Pixel_Size );
+        goto Exit;
+      }
+
+      metrics->x_ppem = (FT_UShort)scaled_w;
+      metrics->y_ppem = (FT_UShort)scaled_h;
 
       ft_recompute_scaled_metrics( face, metrics );
     }
@@ -3142,6 +3364,9 @@
       metrics->x_scale = 1L << 16;
       metrics->y_scale = 1L << 16;
     }
+
+  Exit:
+    return error;
   }
 
 
@@ -3182,16 +3407,20 @@
       FT_Size_Metrics*  metrics = &face->size->metrics;
 
 
-      FT_TRACE5(( "  x scale: %d (%f)\n",
-                  metrics->x_scale, metrics->x_scale / 65536.0 ));
-      FT_TRACE5(( "  y scale: %d (%f)\n",
-                  metrics->y_scale, metrics->y_scale / 65536.0 ));
-      FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
-      FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
-      FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
-      FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
-      FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
-      FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
+      FT_TRACE5(( "  x scale: %ld (%f)\n",
+                  metrics->x_scale, (double)metrics->x_scale / 65536 ));
+      FT_TRACE5(( "  y scale: %ld (%f)\n",
+                  metrics->y_scale, (double)metrics->y_scale / 65536 ));
+      FT_TRACE5(( "  ascender: %f\n",
+                  (double)metrics->ascender / 64 ));
+      FT_TRACE5(( "  descender: %f\n",
+                  (double)metrics->descender / 64 ));
+      FT_TRACE5(( "  height: %f\n",
+                  (double)metrics->height / 64 ));
+      FT_TRACE5(( "  max advance: %f\n",
+                  (double)metrics->max_advance / 64 ));
+      FT_TRACE5(( "  x ppem: %d\n", metrics->x_ppem ));
+      FT_TRACE5(( "  y ppem: %d\n", metrics->y_ppem ));
     }
 #endif
 
@@ -3205,7 +3434,7 @@
   FT_Request_Size( FT_Face          face,
                    FT_Size_Request  req )
   {
-    FT_Error         error = FT_Err_Ok;
+    FT_Error         error;
     FT_Driver_Class  clazz;
     FT_ULong         strike_index;
 
@@ -3213,6 +3442,9 @@
     if ( !face )
       return FT_THROW( Invalid_Face_Handle );
 
+    if ( !face->size )
+      return FT_THROW( Invalid_Size_Handle );
+
     if ( !req || req->width < 0 || req->height < 0 ||
          req->type >= FT_SIZE_REQUEST_TYPE_MAX )
       return FT_THROW( Invalid_Argument );
@@ -3241,13 +3473,15 @@
        */
       error = FT_Match_Size( face, req, 0, &strike_index );
       if ( error )
-        return error;
+        goto Exit;
 
       return FT_Select_Size( face, (FT_Int)strike_index );
     }
     else
     {
-      FT_Request_Metrics( face, req );
+      error = FT_Request_Metrics( face, req );
+      if ( error )
+        goto Exit;
 
       FT_TRACE5(( "FT_Request_Size:\n" ));
     }
@@ -3257,19 +3491,24 @@
       FT_Size_Metrics*  metrics = &face->size->metrics;
 
 
-      FT_TRACE5(( "  x scale: %d (%f)\n",
-                  metrics->x_scale, metrics->x_scale / 65536.0 ));
-      FT_TRACE5(( "  y scale: %d (%f)\n",
-                  metrics->y_scale, metrics->y_scale / 65536.0 ));
-      FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
-      FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
-      FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
-      FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
-      FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
-      FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
+      FT_TRACE5(( "  x scale: %ld (%f)\n",
+                  metrics->x_scale, (double)metrics->x_scale / 65536 ));
+      FT_TRACE5(( "  y scale: %ld (%f)\n",
+                  metrics->y_scale, (double)metrics->y_scale / 65536 ));
+      FT_TRACE5(( "  ascender: %f\n",
+                  (double)metrics->ascender / 64 ));
+      FT_TRACE5(( "  descender: %f\n",
+                  (double)metrics->descender / 64 ));
+      FT_TRACE5(( "  height: %f\n",
+                  (double)metrics->height / 64 ));
+      FT_TRACE5(( "  max advance: %f\n",
+                  (double)metrics->max_advance / 64 ));
+      FT_TRACE5(( "  x ppem: %d\n", metrics->x_ppem ));
+      FT_TRACE5(( "  y ppem: %d\n", metrics->y_ppem ));
     }
 #endif
 
+  Exit:
     return error;
   }
 
@@ -3419,7 +3658,7 @@
               if ( akerning->x != orig_x_rounded ||
                    akerning->y != orig_y_rounded )
                 FT_TRACE5(( "FT_Get_Kerning: horizontal kerning"
-                            " (%d, %d) scaled down to (%d, %d) pixels\n",
+                            " (%ld, %ld) scaled down to (%ld, %ld) pixels\n",
                             orig_x_rounded / 64, orig_y_rounded / 64,
                             akerning->x / 64, akerning->y / 64 ));
             }
@@ -3594,9 +3833,9 @@
           FT_CharMap  last_charmap = face->charmaps[face->num_charmaps - 1];
 
 
-          if ( FT_RENEW_ARRAY( face->charmaps,
-                               face->num_charmaps,
-                               face->num_charmaps - 1 ) )
+          if ( FT_QRENEW_ARRAY( face->charmaps,
+                                face->num_charmaps,
+                                face->num_charmaps - 1 ) )
             return;
 
           /* remove it from our list of charmaps */
@@ -3628,7 +3867,7 @@
                FT_CharMap     charmap,
                FT_CMap       *acmap )
   {
-    FT_Error   error = FT_Err_Ok;
+    FT_Error   error;
     FT_Face    face;
     FT_Memory  memory;
     FT_CMap    cmap = NULL;
@@ -3653,9 +3892,9 @@
       }
 
       /* add it to our list of charmaps */
-      if ( FT_RENEW_ARRAY( face->charmaps,
-                           face->num_charmaps,
-                           face->num_charmaps + 1 ) )
+      if ( FT_QRENEW_ARRAY( face->charmaps,
+                            face->num_charmaps,
+                            face->num_charmaps + 1 ) )
         goto Fail;
 
       face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;
@@ -3691,7 +3930,7 @@
       if ( charcode > 0xFFFFFFFFUL )
       {
         FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
-        FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+        FT_TRACE1(( " 0x%lx is truncated\n", charcode ));
       }
 
       result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
@@ -3867,13 +4106,13 @@
         {
           FT_TRACE1(( "FT_Face_GetCharVariantIndex:"
                       " too large charcode" ));
-          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+          FT_TRACE1(( " 0x%lx is truncated\n", charcode ));
         }
         if ( variantSelector > 0xFFFFFFFFUL )
         {
           FT_TRACE1(( "FT_Face_GetCharVariantIndex:"
                       " too large variantSelector" ));
-          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
+          FT_TRACE1(( " 0x%lx is truncated\n", variantSelector ));
         }
 
         result = vcmap->clazz->char_var_index( vcmap, ucmap,
@@ -3910,13 +4149,13 @@
         {
           FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:"
                       " too large charcode" ));
-          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+          FT_TRACE1(( " 0x%lx is truncated\n", charcode ));
         }
         if ( variantSelector > 0xFFFFFFFFUL )
         {
           FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:"
                       " too large variantSelector" ));
-          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
+          FT_TRACE1(( " 0x%lx is truncated\n", variantSelector ));
         }
 
         result = vcmap->clazz->char_var_default( vcmap,
@@ -3979,7 +4218,7 @@
         if ( charcode > 0xFFFFFFFFUL )
         {
           FT_TRACE1(( "FT_Face_GetVariantsOfChar: too large charcode" ));
-          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+          FT_TRACE1(( " 0x%lx is truncated\n", charcode ));
         }
 
         result = vcmap->clazz->charvariant_list( vcmap, memory,
@@ -4013,7 +4252,7 @@
         if ( variantSelector > 0xFFFFFFFFUL )
         {
           FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
-          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
+          FT_TRACE1(( " 0x%lx is truncated\n", variantSelector ));
         }
 
         result = vcmap->clazz->variantchar_list( vcmap, memory,
@@ -4028,8 +4267,8 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_UInt )
-  FT_Get_Name_Index( FT_Face     face,
-                     FT_String*  glyph_name )
+  FT_Get_Name_Index( FT_Face           face,
+                     const FT_String*  glyph_name )
   {
     FT_UInt  result = 0;
 
@@ -4349,7 +4588,7 @@
     FT_ListNode  node    = NULL;
 
 
-    if ( FT_NEW( node ) )
+    if ( FT_QNEW( node ) )
       goto Exit;
 
     {
@@ -4361,8 +4600,7 @@
       render->glyph_format = clazz->glyph_format;
 
       /* allocate raster object if needed */
-      if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
-           clazz->raster_class->raster_new                )
+      if ( clazz->raster_class && clazz->raster_class->raster_new )
       {
         error = clazz->raster_class->raster_new( memory, &render->raster );
         if ( error )
@@ -4372,6 +4610,11 @@
         render->render        = clazz->render_glyph;
       }
 
+#ifdef FT_CONFIG_OPTION_SVG
+      if ( clazz->glyph_format == FT_GLYPH_FORMAT_SVG )
+        render->render = clazz->render_glyph;
+#endif
+
       /* add to list */
       node->data = module;
       FT_List_Add( &library->renderers, node );
@@ -4409,8 +4652,7 @@
 
 
       /* release raster object, if any */
-      if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
-           render->raster                                         )
+      if ( render->raster )
         render->clazz->raster_class->raster_done( render->raster );
 
       /* remove from list */
@@ -4505,9 +4747,6 @@
 
     switch ( slot->format )
     {
-    case FT_GLYPH_FORMAT_BITMAP:   /* already a bitmap, don't do anything */
-      break;
-
     default:
       if ( slot->internal->load_flags & FT_LOAD_COLOR )
       {
@@ -4595,7 +4834,7 @@
         else
           renderer = FT_Lookup_Renderer( library, slot->format, &node );
 
-        error = FT_ERR( Unimplemented_Feature );
+        error = FT_ERR( Cannot_Render_Glyph );
         while ( renderer )
         {
           error = renderer->render( renderer, slot, render_mode, NULL );
@@ -4611,13 +4850,18 @@
           /* format.                                               */
           renderer = FT_Lookup_Renderer( library, slot->format, &node );
         }
+
+        /* it is not an error if we cannot render a bitmap glyph */
+        if ( FT_ERR_EQ( error, Cannot_Render_Glyph ) &&
+             slot->format == FT_GLYPH_FORMAT_BITMAP  )
+          error = FT_Err_Ok;
       }
     }
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_checksum
+#define FT_COMPONENT  checksum
 
     /*
      * Computing the MD5 checksum is expensive, unnecessarily distorting a
@@ -4683,11 +4927,11 @@
 
     /* we use FT_TRACE7 in this block */
     if ( !error                               &&
-         ft_trace_levels[trace_checksum] >= 7 )
+         ft_trace_levels[trace_checksum] >= 7 &&
+         slot->bitmap.buffer                  )
     {
       if ( slot->bitmap.rows  < 128U &&
-           slot->bitmap.width < 128U &&
-           slot->bitmap.buffer       )
+           slot->bitmap.width < 128U )
       {
         int  rows  = (int)slot->bitmap.rows;
         int  width = (int)slot->bitmap.width;
@@ -4731,7 +4975,7 @@
     }
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_objs
+#define FT_COMPONENT  objs
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
@@ -5098,16 +5342,16 @@
 
     if ( cur == limit )
     {
-      FT_ERROR(( "%s: can't find module `%s'\n",
-                 func_name, module_name ));
+      FT_TRACE2(( "%s: can't find module `%s'\n",
+                  func_name, module_name ));
       return FT_THROW( Missing_Module );
     }
 
     /* check whether we have a service interface */
     if ( !cur[0]->clazz->get_interface )
     {
-      FT_ERROR(( "%s: module `%s' doesn't support properties\n",
-                 func_name, module_name ));
+      FT_TRACE2(( "%s: module `%s' doesn't support properties\n",
+                  func_name, module_name ));
       return FT_THROW( Unimplemented_Feature );
     }
 
@@ -5116,22 +5360,22 @@
                                               FT_SERVICE_ID_PROPERTIES );
     if ( !interface )
     {
-      FT_ERROR(( "%s: module `%s' doesn't support properties\n",
-                 func_name, module_name ));
+      FT_TRACE2(( "%s: module `%s' doesn't support properties\n",
+                  func_name, module_name ));
       return FT_THROW( Unimplemented_Feature );
     }
 
     service = (FT_Service_Properties)interface;
 
     if ( set )
-      missing_func = (FT_Bool)( !service->set_property );
+      missing_func = FT_BOOL( !service->set_property );
     else
-      missing_func = (FT_Bool)( !service->get_property );
+      missing_func = FT_BOOL( !service->get_property );
 
     if ( missing_func )
     {
-      FT_ERROR(( "%s: property service of module `%s' is broken\n",
-                 func_name, module_name ));
+      FT_TRACE2(( "%s: property service of module `%s' is broken\n",
+                  func_name, module_name ));
       return FT_THROW( Unimplemented_Feature );
     }
 
@@ -5241,10 +5485,12 @@
     if ( !memory || !alibrary )
       return FT_THROW( Invalid_Argument );
 
+#ifndef FT_DEBUG_LOGGING
 #ifdef FT_DEBUG_LEVEL_ERROR
     /* init debugging support */
     ft_debug_init();
-#endif
+#endif /* FT_DEBUG_LEVEL_ERROR */
+#endif /* !FT_DEBUG_LOGGING */
 
     /* first of all, allocate the library object */
     if ( FT_NEW( library ) )
@@ -5516,4 +5762,145 @@
   }
 
 
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Get_Color_Glyph_Paint( FT_Face                  face,
+                            FT_UInt                  base_glyph,
+                            FT_Color_Root_Transform  root_transform,
+                            FT_OpaquePaint*          paint )
+  {
+    TT_Face       ttface;
+    SFNT_Service  sfnt;
+
+
+    if ( !face || !paint )
+      return 0;
+
+    if ( !FT_IS_SFNT( face ) )
+      return 0;
+
+    ttface = (TT_Face)face;
+    sfnt   = (SFNT_Service)ttface->sfnt;
+
+    if ( sfnt->get_colr_layer )
+      return sfnt->get_colr_glyph_paint( ttface,
+                                         base_glyph,
+                                         root_transform,
+                                         paint );
+    else
+      return 0;
+  }
+
+
+  /* documentation is in ftcolor.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Get_Color_Glyph_ClipBox( FT_Face      face,
+                              FT_UInt      base_glyph,
+                              FT_ClipBox*  clip_box )
+  {
+    TT_Face       ttface;
+    SFNT_Service  sfnt;
+
+
+    if ( !face || !clip_box )
+      return 0;
+
+    if ( !FT_IS_SFNT( face ) )
+      return 0;
+
+    ttface = (TT_Face)face;
+    sfnt   = (SFNT_Service)ttface->sfnt;
+
+    if ( sfnt->get_color_glyph_clipbox )
+      return sfnt->get_color_glyph_clipbox( ttface,
+                                            base_glyph,
+                                            clip_box );
+    else
+      return 0;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Get_Paint_Layers( FT_Face            face,
+                       FT_LayerIterator*  layer_iterator,
+                       FT_OpaquePaint*    paint )
+  {
+    TT_Face       ttface;
+    SFNT_Service  sfnt;
+
+
+    if ( !face || !paint || !layer_iterator )
+      return 0;
+
+    if ( !FT_IS_SFNT( face ) )
+      return 0;
+
+    ttface = (TT_Face)face;
+    sfnt   = (SFNT_Service)ttface->sfnt;
+
+    if ( sfnt->get_paint_layers )
+      return sfnt->get_paint_layers( ttface, layer_iterator, paint );
+    else
+      return 0;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Get_Paint( FT_Face face,
+                FT_OpaquePaint  opaque_paint,
+                FT_COLR_Paint*  paint )
+  {
+    TT_Face       ttface;
+    SFNT_Service  sfnt;
+
+
+    if ( !face || !paint )
+      return 0;
+
+    if ( !FT_IS_SFNT( face ) )
+      return 0;
+
+    ttface = (TT_Face)face;
+    sfnt   = (SFNT_Service)ttface->sfnt;
+
+    if ( sfnt->get_paint )
+      return sfnt->get_paint( ttface, opaque_paint, paint );
+    else
+      return 0;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Get_Colorline_Stops ( FT_Face                face,
+                           FT_ColorStop *         color_stop,
+                           FT_ColorStopIterator  *iterator )
+  {
+    TT_Face       ttface;
+    SFNT_Service  sfnt;
+
+
+    if ( !face || !color_stop || !iterator )
+      return 0;
+
+    if ( !FT_IS_SFNT( face ) )
+      return 0;
+
+    ttface = (TT_Face)face;
+    sfnt   = (SFNT_Service)ttface->sfnt;
+
+    if ( sfnt->get_colorline_stops )
+      return sfnt->get_colorline_stops ( ttface, color_stop, iterator );
+    else
+      return 0;
+  }
+
+
 /* END */
diff --git a/src/base/ftotval.c b/src/base/ftotval.c
index 50825bd..192e12a 100644
--- a/src/base/ftotval.c
+++ b/src/base/ftotval.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for validating OpenType tables (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -15,12 +15,11 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_OPENTYPE_VALIDATE_H
-#include FT_OPENTYPE_VALIDATE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svotval.h>
+#include <freetype/ftotval.h>
 
 
   /* documentation is in ftotval.h */
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 611b4f6..30ff21f 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -4,7 +4,7 @@
  *
  *   FreeType outline management (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,19 +16,11 @@
  */
 
 
-  /**************************************************************************
-   *
-   * All functions are declared in freetype.h.
-   *
-   */
-
-
-#include <ft2build.h>
-#include FT_OUTLINE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_TRIGONOMETRY_H
+#include <freetype/ftoutln.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/fttrigon.h>
 
 
   /**************************************************************************
@@ -38,7 +30,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_outline
+#define FT_COMPONENT  outline
 
 
   static
@@ -53,8 +45,7 @@
                         void*                    user )
   {
 #undef  SCALED
-#define SCALED( x )  ( ( (x) < 0 ? -( -(x) << shift )             \
-                                 :  (  (x) << shift ) ) - delta )
+#define SCALED( x )  ( (x) * ( 1L << shift ) - delta )
 
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -139,7 +130,7 @@
       }
 
       FT_TRACE5(( "  move to (%.2f, %.2f)\n",
-                  v_start.x / 64.0, v_start.y / 64.0 ));
+                  (double)v_start.x / 64, (double)v_start.y / 64 ));
       error = func_interface->move_to( &v_start, user );
       if ( error )
         goto Exit;
@@ -161,7 +152,7 @@
             vec.y = SCALED( point->y );
 
             FT_TRACE5(( "  line to (%.2f, %.2f)\n",
-                        vec.x / 64.0, vec.y / 64.0 ));
+                        (double)vec.x / 64, (double)vec.y / 64 ));
             error = func_interface->line_to( &vec, user );
             if ( error )
               goto Exit;
@@ -190,8 +181,10 @@
             {
               FT_TRACE5(( "  conic to (%.2f, %.2f)"
                           " with control (%.2f, %.2f)\n",
-                          vec.x / 64.0, vec.y / 64.0,
-                          v_control.x / 64.0, v_control.y / 64.0 ));
+                          (double)vec.x / 64,
+                          (double)vec.y / 64,
+                          (double)v_control.x / 64,
+                          (double)v_control.y / 64 ));
               error = func_interface->conic_to( &v_control, &vec, user );
               if ( error )
                 goto Exit;
@@ -206,8 +199,10 @@
 
             FT_TRACE5(( "  conic to (%.2f, %.2f)"
                         " with control (%.2f, %.2f)\n",
-                        v_middle.x / 64.0, v_middle.y / 64.0,
-                        v_control.x / 64.0, v_control.y / 64.0 ));
+                        (double)v_middle.x / 64,
+                        (double)v_middle.y / 64,
+                        (double)v_control.x / 64,
+                        (double)v_control.y / 64 ));
             error = func_interface->conic_to( &v_control, &v_middle, user );
             if ( error )
               goto Exit;
@@ -218,8 +213,10 @@
 
           FT_TRACE5(( "  conic to (%.2f, %.2f)"
                       " with control (%.2f, %.2f)\n",
-                      v_start.x / 64.0, v_start.y / 64.0,
-                      v_control.x / 64.0, v_control.y / 64.0 ));
+                      (double)v_start.x / 64,
+                      (double)v_start.y / 64,
+                      (double)v_control.x / 64,
+                      (double)v_control.y / 64 ));
           error = func_interface->conic_to( &v_control, &v_start, user );
           goto Close;
 
@@ -251,9 +248,12 @@
 
               FT_TRACE5(( "  cubic to (%.2f, %.2f)"
                           " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
-                          vec.x / 64.0, vec.y / 64.0,
-                          vec1.x / 64.0, vec1.y / 64.0,
-                          vec2.x / 64.0, vec2.y / 64.0 ));
+                          (double)vec.x / 64,
+                          (double)vec.y / 64,
+                          (double)vec1.x / 64,
+                          (double)vec1.y / 64,
+                          (double)vec2.x / 64,
+                          (double)vec2.y / 64 ));
               error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
               if ( error )
                 goto Exit;
@@ -262,9 +262,12 @@
 
             FT_TRACE5(( "  cubic to (%.2f, %.2f)"
                         " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
-                        v_start.x / 64.0, v_start.y / 64.0,
-                        vec1.x / 64.0, vec1.y / 64.0,
-                        vec2.x / 64.0, vec2.y / 64.0 ));
+                        (double)v_start.x / 64,
+                        (double)v_start.y / 64,
+                        (double)vec1.x / 64,
+                        (double)vec1.y / 64,
+                        (double)vec2.x / 64,
+                        (double)vec2.y / 64 ));
             error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
             goto Close;
           }
@@ -273,7 +276,7 @@
 
       /* close the contour with a line segment */
       FT_TRACE5(( "  line to (%.2f, %.2f)\n",
-                  v_start.x / 64.0, v_start.y / 64.0 ));
+                  (double)v_start.x / 64, (double)v_start.y / 64 ));
       error = func_interface->line_to( &v_start, user );
 
     Close:
@@ -283,7 +286,7 @@
       first = (FT_UInt)last + 1;
     }
 
-    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
+    FT_TRACE5(( "FT_Outline_Decompose: Done\n" ));
     return FT_Err_Ok;
 
   Invalid_Outline:
@@ -296,14 +299,22 @@
   }
 
 
-  FT_EXPORT_DEF( FT_Error )
-  FT_Outline_New_Internal( FT_Memory    memory,
-                           FT_UInt      numPoints,
-                           FT_Int       numContours,
-                           FT_Outline  *anoutline )
-  {
-    FT_Error  error;
+  /* documentation is in ftoutln.h */
 
+  FT_EXPORT_DEF( FT_Error )
+  FT_Outline_New( FT_Library   library,
+                  FT_UInt      numPoints,
+                  FT_Int       numContours,
+                  FT_Outline  *anoutline )
+  {
+    FT_Error   error;
+    FT_Memory  memory;
+
+
+    if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
+
+    memory = library->memory;
 
     if ( !anoutline || !memory )
       return FT_THROW( Invalid_Argument );
@@ -330,7 +341,7 @@
 
   Fail:
     anoutline->flags |= FT_OUTLINE_OWNER;
-    FT_Outline_Done_Internal( memory, anoutline );
+    FT_Outline_Done( library, anoutline );
 
     return error;
   }
@@ -339,22 +350,6 @@
   /* documentation is in ftoutln.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_Outline_New( FT_Library   library,
-                  FT_UInt      numPoints,
-                  FT_Int       numContours,
-                  FT_Outline  *anoutline )
-  {
-    if ( !library )
-      return FT_THROW( Invalid_Library_Handle );
-
-    return FT_Outline_New_Internal( library->memory, numPoints,
-                                    numContours, anoutline );
-  }
-
-
-  /* documentation is in ftoutln.h */
-
-  FT_EXPORT_DEF( FT_Error )
   FT_Outline_Check( FT_Outline*  outline )
   {
     if ( outline )
@@ -436,13 +431,23 @@
   }
 
 
+  /* documentation is in ftoutln.h */
+
   FT_EXPORT_DEF( FT_Error )
-  FT_Outline_Done_Internal( FT_Memory    memory,
-                            FT_Outline*  outline )
+  FT_Outline_Done( FT_Library   library,
+                   FT_Outline*  outline )
   {
+    FT_Memory  memory;
+
+
+    if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
+
     if ( !outline )
       return FT_THROW( Invalid_Outline );
 
+    memory = library->memory;
+
     if ( !memory )
       return FT_THROW( Invalid_Argument );
 
@@ -460,21 +465,6 @@
 
   /* documentation is in ftoutln.h */
 
-  FT_EXPORT_DEF( FT_Error )
-  FT_Outline_Done( FT_Library   library,
-                   FT_Outline*  outline )
-  {
-    /* check for valid `outline' in FT_Outline_Done_Internal() */
-
-    if ( !library )
-      return FT_THROW( Invalid_Library_Handle );
-
-    return FT_Outline_Done_Internal( library->memory, outline );
-  }
-
-
-  /* documentation is in ftoutln.h */
-
   FT_EXPORT_DEF( void )
   FT_Outline_Get_CBox( const FT_Outline*  outline,
                        FT_BBox           *acbox )
@@ -641,6 +631,16 @@
 
     params->source = (void*)outline;
 
+    /* preset clip_box for direct mode */
+    if ( params->flags & FT_RASTER_FLAG_DIRECT    &&
+         !( params->flags & FT_RASTER_FLAG_CLIP ) )
+    {
+      params->clip_box.xMin = cbox.xMin >> 6;
+      params->clip_box.yMin = cbox.yMin >> 6;
+      params->clip_box.xMax = ( cbox.xMax + 63 ) >> 6;
+      params->clip_box.yMax = ( cbox.yMax + 63 ) >> 6;
+    }
+
     error = FT_ERR( Cannot_Render_Glyph );
     while ( renderer )
     {
@@ -722,7 +722,7 @@
     FT_Vector*  limit;
 
 
-    if ( !outline || !matrix )
+    if ( !outline || !matrix || !outline->points )
       return;
 
     vec   = outline->points;
@@ -1072,6 +1072,11 @@
     if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax )
       return FT_ORIENTATION_NONE;
 
+    /* Reject values large outlines. */
+    if ( cbox.xMin < -0x1000000L || cbox.yMin < -0x1000000L ||
+         cbox.xMax >  0x1000000L || cbox.yMax >  0x1000000L )
+      return FT_ORIENTATION_NONE;
+
     xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) |
                                   FT_ABS( cbox.xMin ) ) ) - 14;
     xshift = FT_MAX( xshift, 0 );
@@ -1096,7 +1101,8 @@
         v_cur.y = points[n].y >> yshift;
 
         area = ADD_LONG( area,
-                         ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) );
+                         MUL_LONG( v_cur.y - v_prev.y,
+                                   v_cur.x + v_prev.x ) );
 
         v_prev = v_cur;
       }
diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c
index 24331c1..cb5efad 100644
--- a/src/base/ftpatent.c
+++ b/src/base/ftpatent.c
@@ -5,7 +5,7 @@
  *   FreeType API for checking patented TrueType bytecode instructions
  *   (body).  Obsolete, retained for backward compatibility.
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * David Turner.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,13 +16,12 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_STREAM_H
-#include FT_SERVICE_SFNT_H
-#include FT_SERVICE_TRUETYPE_GLYF_H
+#include <freetype/freetype.h>
+#include <freetype/tttags.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/services/svsfnt.h>
+#include <freetype/internal/services/svttglyf.h>
 
 
   /* documentation is in freetype.h */
diff --git a/src/base/ftpfr.c b/src/base/ftpfr.c
index 2761ad0..378385a 100644
--- a/src/base/ftpfr.c
+++ b/src/base/ftpfr.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing PFR-specific data (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -15,11 +15,10 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_PFR_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svpfr.h>
 
 
   /* check the format */
diff --git a/src/base/ftpsprop.c b/src/base/ftpsprop.c
index 9c5344a..cefdf48 100644
--- a/src/base/ftpsprop.c
+++ b/src/base/ftpsprop.c
@@ -5,7 +5,7 @@
  *   Get and set properties of PostScript drivers (body).
  *   See `ftdriver.h' for available properties.
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,12 +17,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_DRIVER_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_POSTSCRIPT_PROPS_H
+#include <freetype/ftdriver.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftpsprop.h>
 
 
   /**************************************************************************
@@ -32,7 +31,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_psprops
+#define FT_COMPONENT  psprops
 
 
   FT_BASE_CALLBACK_DEF( FT_Error )
@@ -165,9 +164,9 @@
           driver->hinting_engine = *hinting_engine;
         else
           error = FT_ERR( Unimplemented_Feature );
-
-        return error;
       }
+
+      return error;
     }
 
     else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
@@ -221,7 +220,7 @@
       return error;
     }
 
-    FT_TRACE0(( "ps_property_set: missing property `%s'\n",
+    FT_TRACE2(( "ps_property_set: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
@@ -276,7 +275,7 @@
       return error;
     }
 
-    FT_TRACE0(( "ps_property_get: missing property `%s'\n",
+    FT_TRACE2(( "ps_property_get: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index c61765b..2ab4301 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -4,7 +4,7 @@
  *
  *   Embedded resource forks accessor (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Masatake YAMATO and Redhat K.K.
  *
  * FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are
@@ -24,15 +24,14 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_RFORK_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftrfork.h>
 
 #include "ftbase.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_raccess
+#define FT_COMPONENT  raccess
 
 
   /*************************************************************************/
@@ -168,16 +167,11 @@
   }
 
 
-  static int
-  ft_raccess_sort_ref_by_id( FT_RFork_Ref*  a,
-                             FT_RFork_Ref*  b )
+  FT_COMPARE_DEF( int )
+  ft_raccess_sort_ref_by_id( const void*  a,
+                             const void*  b )
   {
-    if ( a->res_id < b->res_id )
-      return -1;
-    else if ( a->res_id > b->res_id )
-      return 1;
-    else
-      return 0;
+    return  ( (FT_RFork_Ref*)a )->res_id - ( (FT_RFork_Ref*)b )->res_id;
   }
 
 
@@ -240,7 +234,7 @@
                   (char)( 0xFF & ( tag_internal >> 16 ) ),
                   (char)( 0xFF & ( tag_internal >>  8 ) ),
                   (char)( 0xFF & ( tag_internal >>  0 ) ) ));
-      FT_TRACE3(( "             : subcount=%d, suboffset=0x%04x\n",
+      FT_TRACE3(( "             : subcount=%d, suboffset=0x%04lx\n",
                   subcnt, rpos ));
 
       if ( tag_internal == tag )
@@ -257,7 +251,7 @@
         if ( error )
           return error;
 
-        if ( FT_NEW_ARRAY( ref, *count ) )
+        if ( FT_QNEW_ARRAY( ref, *count ) )
           return error;
 
         for ( j = 0; j < *count; j++ )
@@ -286,7 +280,7 @@
           ref[j].offset = temp & 0xFFFFFFL;
 
           FT_TRACE3(( "             [%d]:"
-                      " resource_id=0x%04x, offset=0x%08x\n",
+                      " resource_id=0x%04x, offset=0x%08lx\n",
                       j, (FT_UShort)ref[j].res_id, ref[j].offset ));
         }
 
@@ -295,18 +289,17 @@
           ft_qsort( ref,
                     (size_t)*count,
                     sizeof ( FT_RFork_Ref ),
-                    ( int(*)(const void*,
-                             const void*) )ft_raccess_sort_ref_by_id );
+                    ft_raccess_sort_ref_by_id );
 
           FT_TRACE3(( "             -- sort resources by their ids --\n" ));
 
           for ( j = 0; j < *count; j++ )
             FT_TRACE3(( "             [%d]:"
-                        " resource_id=0x%04x, offset=0x%08x\n",
+                        " resource_id=0x%04x, offset=0x%08lx\n",
                         j, ref[j].res_id, ref[j].offset ));
         }
 
-        if ( FT_NEW_ARRAY( offsets_internal, *count ) )
+        if ( FT_QNEW_ARRAY( offsets_internal, *count ) )
           goto Exit;
 
         /* XXX: duplicated reference ID,
@@ -409,17 +402,17 @@
                                 FT_Long    *result_offset );
 
 
-  CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table,
-                                  ft_raccess_guess_rec)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double,      apple_double)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single,      apple_single)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs,     darwin_newvfs)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus,    darwin_hfsplus)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat,              vfat)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap,         linux_cap)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double,      linux_double)
-  CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk,    linux_netatalk)
+  CONST_FT_RFORK_RULE_ARRAY_BEGIN( ft_raccess_guess_table,
+                                                      ft_raccess_guess_rec )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( apple_double,      apple_double )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( apple_single,      apple_single )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_ufs_export, darwin_ufs_export )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_newvfs,     darwin_newvfs )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_hfsplus,    darwin_hfsplus )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( vfat,              vfat )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_cap,         linux_cap )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_double,      linux_double )
+  CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_netatalk,    linux_netatalk )
   CONST_FT_RFORK_RULE_ARRAY_END
 
 
@@ -609,7 +602,7 @@
     if ( base_file_len + 6 > FT_INT_MAX )
       return FT_THROW( Array_Too_Large );
 
-    if ( FT_ALLOC( newpath, base_file_len + 6 ) )
+    if ( FT_QALLOC( newpath, base_file_len + 6 ) )
       return error;
 
     FT_MEM_COPY( newpath, base_file_name, base_file_len );
@@ -645,7 +638,7 @@
     if ( base_file_len + 18 > FT_INT_MAX )
       return FT_THROW( Array_Too_Large );
 
-    if ( FT_ALLOC( newpath, base_file_len + 18 ) )
+    if ( FT_QALLOC( newpath, base_file_len + 18 ) )
       return error;
 
     FT_MEM_COPY( newpath, base_file_name, base_file_len );
@@ -875,13 +868,11 @@
     const char*  tmp;
     const char*  slash;
     size_t       new_length;
-    FT_Error     error = FT_Err_Ok;
-
-    FT_UNUSED( error );
+    FT_Error     error;
 
 
     new_length = ft_strlen( original_name ) + ft_strlen( insertion );
-    if ( FT_ALLOC( new_name, new_length + 1 ) )
+    if ( FT_QALLOC( new_name, new_length + 1 ) )
       return NULL;
 
     tmp = ft_strrchr( original_name, '/' );
diff --git a/src/base/ftsnames.c b/src/base/ftsnames.c
index 9135e48..1917a3f 100644
--- a/src/base/ftsnames.c
+++ b/src/base/ftsnames.c
@@ -7,7 +7,7 @@
  *
  *   This is _not_ used to retrieve glyph names!
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,12 +19,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_SFNT_NAMES_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/ftsnames.h>
+#include <freetype/internal/tttypes.h>
+#include <freetype/internal/ftstream.h>
 
 
 #ifdef TT_CONFIG_OPTION_SFNT_NAMES
@@ -66,7 +65,7 @@
           FT_Stream  stream = face->stream;
 
 
-          if ( FT_NEW_ARRAY  ( entry->string, entry->stringLength ) ||
+          if ( FT_QNEW_ARRAY ( entry->string, entry->stringLength ) ||
                FT_STREAM_SEEK( entry->stringOffset )                ||
                FT_STREAM_READ( entry->string, entry->stringLength ) )
           {
@@ -122,7 +121,7 @@
           FT_Stream  stream = face->stream;
 
 
-          if ( FT_NEW_ARRAY  ( entry->string, entry->stringLength ) ||
+          if ( FT_QNEW_ARRAY ( entry->string, entry->stringLength ) ||
                FT_STREAM_SEEK( entry->stringOffset )                ||
                FT_STREAM_READ( entry->string, entry->stringLength ) )
           {
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index 9c8cab3..05c5637 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -4,7 +4,7 @@
  *
  *   I/O stream support (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,9 +16,8 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
 
 
   /**************************************************************************
@@ -28,7 +27,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_stream
+#define FT_COMPONENT  stream
 
 
   FT_BASE_DEF( void )
@@ -62,7 +61,7 @@
 
     if ( stream->read )
     {
-      if ( stream->read( stream, pos, 0, 0 ) )
+      if ( stream->read( stream, pos, NULL, 0 ) )
       {
         FT_ERROR(( "FT_Stream_Seek:"
                    " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
@@ -222,11 +221,11 @@
 
 #ifdef FT_DEBUG_MEMORY
       ft_mem_free( memory, *pbytes );
-      *pbytes = NULL;
 #else
       FT_FREE( *pbytes );
 #endif
     }
+
     *pbytes = NULL;
   }
 
@@ -239,6 +238,8 @@
     FT_ULong  read_bytes;
 
 
+    FT_TRACE7(( "FT_Stream_EnterFrame: %ld bytes\n", count ));
+
     /* check for nested frame access */
     FT_ASSERT( stream && stream->cursor == 0 );
 
@@ -260,7 +261,7 @@
       }
 
 #ifdef FT_DEBUG_MEMORY
-      /* assume _ft_debug_file and _ft_debug_lineno are already set */
+      /* assume `ft_debug_file_` and `ft_debug_lineno_` are already set */
       stream->base = (unsigned char*)ft_mem_qalloc( memory,
                                                     (FT_Long)count,
                                                     &error );
@@ -282,8 +283,9 @@
         FT_FREE( stream->base );
         error = FT_THROW( Invalid_Stream_Operation );
       }
+
       stream->cursor = stream->base;
-      stream->limit  = stream->cursor + count;
+      stream->limit  = FT_OFFSET( stream->cursor, count );
       stream->pos   += read_bytes;
     }
     else
@@ -322,13 +324,16 @@
     /*  In this case, the loader code handles the 0-length table          */
     /*  gracefully; however, stream.cursor is really set to 0 by the      */
     /*  FT_Stream_EnterFrame() call, and this is not an error.            */
-    /*                                                                    */
+
+    FT_TRACE7(( "FT_Stream_ExitFrame\n" ));
+
     FT_ASSERT( stream );
 
     if ( stream->read )
     {
       FT_Memory  memory = stream->memory;
 
+
 #ifdef FT_DEBUG_MEMORY
       ft_mem_free( memory, stream->base );
       stream->base = NULL;
@@ -336,32 +341,33 @@
       FT_FREE( stream->base );
 #endif
     }
+
     stream->cursor = NULL;
     stream->limit  = NULL;
   }
 
 
-  FT_BASE_DEF( FT_Char )
-  FT_Stream_GetChar( FT_Stream  stream )
+  FT_BASE_DEF( FT_Byte )
+  FT_Stream_GetByte( FT_Stream  stream )
   {
-    FT_Char  result;
+    FT_Byte  result;
 
 
     FT_ASSERT( stream && stream->cursor );
 
     result = 0;
     if ( stream->cursor < stream->limit )
-      result = (FT_Char)*stream->cursor++;
+      result = *stream->cursor++;
 
     return result;
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_GetUShort( FT_Stream  stream )
   {
     FT_Byte*   p;
-    FT_UShort  result;
+    FT_UInt16  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -376,11 +382,11 @@
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_GetUShortLE( FT_Stream  stream )
   {
     FT_Byte*   p;
-    FT_UShort  result;
+    FT_UInt16  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -395,11 +401,11 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_GetUOffset( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_ULong  result;
+    FT_UInt32 result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -413,11 +419,11 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_GetULong( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_ULong  result;
+    FT_UInt32 result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -431,11 +437,11 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_GetULongLE( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_ULong  result;
+    FT_UInt32 result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -449,8 +455,8 @@
   }
 
 
-  FT_BASE_DEF( FT_Char )
-  FT_Stream_ReadChar( FT_Stream  stream,
+  FT_BASE_DEF( FT_Byte )
+  FT_Stream_ReadByte( FT_Stream  stream,
                       FT_Error*  error )
   {
     FT_Byte  result = 0;
@@ -458,47 +464,46 @@
 
     FT_ASSERT( stream );
 
-    *error = FT_Err_Ok;
-
-    if ( stream->read )
+    if ( stream->pos < stream->size )
     {
-      if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
-        goto Fail;
+      if ( stream->read )
+      {
+        if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
+          goto Fail;
+      }
+      else
+        result = stream->base[stream->pos];
     }
     else
-    {
-      if ( stream->pos < stream->size )
-        result = stream->base[stream->pos];
-      else
-        goto Fail;
-    }
+      goto Fail;
+
     stream->pos++;
 
-    return (FT_Char)result;
+    *error = FT_Err_Ok;
+
+    return result;
 
   Fail:
     *error = FT_THROW( Invalid_Stream_Operation );
-    FT_ERROR(( "FT_Stream_ReadChar:"
+    FT_ERROR(( "FT_Stream_ReadByte:"
                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
-    return 0;
+    return result;
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_ReadUShort( FT_Stream  stream,
                         FT_Error*  error )
   {
     FT_Byte    reads[2];
-    FT_Byte*   p      = 0;
-    FT_UShort  result = 0;
+    FT_Byte*   p;
+    FT_UInt16  result = 0;
 
 
     FT_ASSERT( stream );
 
-    *error = FT_Err_Ok;
-
     if ( stream->pos + 1 < stream->size )
     {
       if ( stream->read )
@@ -519,6 +524,8 @@
 
     stream->pos += 2;
 
+    *error = FT_Err_Ok;
+
     return result;
 
   Fail:
@@ -527,23 +534,21 @@
                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
-    return 0;
+    return result;
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_ReadUShortLE( FT_Stream  stream,
                           FT_Error*  error )
   {
     FT_Byte    reads[2];
-    FT_Byte*   p      = 0;
-    FT_UShort  result = 0;
+    FT_Byte*   p;
+    FT_UInt16  result = 0;
 
 
     FT_ASSERT( stream );
 
-    *error = FT_Err_Ok;
-
     if ( stream->pos + 1 < stream->size )
     {
       if ( stream->read )
@@ -564,6 +569,8 @@
 
     stream->pos += 2;
 
+    *error = FT_Err_Ok;
+
     return result;
 
   Fail:
@@ -572,7 +579,7 @@
                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
-    return 0;
+    return result;
   }
 
 
@@ -581,14 +588,12 @@
                          FT_Error*  error )
   {
     FT_Byte   reads[3];
-    FT_Byte*  p      = 0;
+    FT_Byte*  p;
     FT_ULong  result = 0;
 
 
     FT_ASSERT( stream );
 
-    *error = FT_Err_Ok;
-
     if ( stream->pos + 2 < stream->size )
     {
       if ( stream->read )
@@ -609,6 +614,8 @@
 
     stream->pos += 3;
 
+    *error = FT_Err_Ok;
+
     return result;
 
   Fail:
@@ -617,23 +624,21 @@
                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
-    return 0;
+    return result;
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_ReadULong( FT_Stream  stream,
                        FT_Error*  error )
   {
     FT_Byte   reads[4];
-    FT_Byte*  p      = 0;
-    FT_ULong  result = 0;
+    FT_Byte*  p;
+    FT_UInt32 result = 0;
 
 
     FT_ASSERT( stream );
 
-    *error = FT_Err_Ok;
-
     if ( stream->pos + 3 < stream->size )
     {
       if ( stream->read )
@@ -654,6 +659,8 @@
 
     stream->pos += 4;
 
+    *error = FT_Err_Ok;
+
     return result;
 
   Fail:
@@ -662,23 +669,21 @@
                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
-    return 0;
+    return result;
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_ReadULongLE( FT_Stream  stream,
                          FT_Error*  error )
   {
     FT_Byte   reads[4];
-    FT_Byte*  p      = 0;
-    FT_ULong  result = 0;
+    FT_Byte*  p;
+    FT_UInt32 result = 0;
 
 
     FT_ASSERT( stream );
 
-    *error = FT_Err_Ok;
-
     if ( stream->pos + 3 < stream->size )
     {
       if ( stream->read )
@@ -699,6 +704,8 @@
 
     stream->pos += 4;
 
+    *error = FT_Err_Ok;
+
     return result;
 
   Fail:
@@ -707,7 +714,7 @@
                " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
-    return 0;
+    return result;
   }
 
 
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 4455e7c..db358e7 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -4,7 +4,7 @@
  *
  *   FreeType path stroker (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,13 +16,12 @@
  */
 
 
-#include <ft2build.h>
-#include FT_STROKER_H
-#include FT_TRIGONOMETRY_H
-#include FT_OUTLINE_H
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/ftstroke.h>
+#include <freetype/fttrigon.h>
+#include <freetype/ftoutln.h>
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
 
 
   /* declare an extern to access `ft_outline_glyph_class' globally */
@@ -86,16 +85,18 @@
 
 
     base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b ) / 2;
-    b = base[1].x = ( base[0].x + b ) / 2;
-    base[2].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    base[3].x = b >> 1;
+    base[2].x = ( a + b ) >> 2;
+    base[1].x = a >> 1;
 
     base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b ) / 2;
-    b = base[1].y = ( base[0].y + b ) / 2;
-    base[2].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    base[3].y = b >> 1;
+    base[2].y = ( a + b ) >> 2;
+    base[1].y = a >> 1;
   }
 
 
@@ -153,28 +154,32 @@
   static void
   ft_cubic_split( FT_Vector*  base )
   {
-    FT_Pos  a, b, c, d;
+    FT_Pos  a, b, c;
 
 
     base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c ) / 2;
-    base[5].x = b = ( base[3].x + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].x = a = ( a + c ) / 2;
-    base[4].x = b = ( b + c ) / 2;
-    base[3].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c >> 1;
+    c += b;
+    base[4].x = c >> 2;
+    base[1].x = a >> 1;
+    a += b;
+    base[2].x = a >> 2;
+    base[3].x = ( a + c ) >> 3;
 
     base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c ) / 2;
-    base[5].y = b = ( base[3].y + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].y = a = ( a + c ) / 2;
-    base[4].y = b = ( b + c ) / 2;
-    base[3].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c >> 1;
+    c += b;
+    base[4].y = c >> 2;
+    base[1].y = a >> 1;
+    a += b;
+    base[2].y = a >> 2;
+    base[3].y = ( a + c ) >> 3;
   }
 
 
@@ -367,6 +372,7 @@
       /* it contains the `adjusted' starting coordinates          */
       border->num_points    = --count;
       border->points[start] = border->points[count];
+      border->tags[start]   = border->tags[count];
 
       if ( reverse )
       {
@@ -431,8 +437,8 @@
     }
     else
     {
-      /* don't add zero-length lineto */
-      if ( border->num_points > 0                                          &&
+      /* don't add zero-length lineto, but always add moveto */
+      if ( border->num_points > (FT_UInt)border->start                     &&
            FT_IS_SMALL( border->points[border->num_points - 1].x - to->x ) &&
            FT_IS_SMALL( border->points[border->num_points - 1].y - to->y ) )
         return error;
@@ -533,63 +539,52 @@
                           FT_Angle         angle_start,
                           FT_Angle         angle_diff )
   {
-    FT_Angle   total, angle, step, rotate, next, theta;
-    FT_Vector  a, b, a2, b2;
-    FT_Fixed   length;
+    FT_Fixed   coef;
+    FT_Vector  a0, a1, a2, a3;
+    FT_Int     i, arcs = 1;
     FT_Error   error = FT_Err_Ok;
 
 
-    /* compute start point */
-    FT_Vector_From_Polar( &a, radius, angle_start );
-    a.x += center->x;
-    a.y += center->y;
+    /* number of cubic arcs to draw */
+    while (  angle_diff > FT_ARC_CUBIC_ANGLE * arcs ||
+            -angle_diff > FT_ARC_CUBIC_ANGLE * arcs )
+      arcs++;
 
-    total  = angle_diff;
-    angle  = angle_start;
-    rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2;
+    /* control tangents */
+    coef  = FT_Tan( angle_diff / ( 4 * arcs ) );
+    coef += coef / 3;
 
-    while ( total != 0 )
+    /* compute start and first control point */
+    FT_Vector_From_Polar( &a0, radius, angle_start );
+    a1.x = FT_MulFix( -a0.y, coef );
+    a1.y = FT_MulFix(  a0.x, coef );
+
+    a0.x += center->x;
+    a0.y += center->y;
+    a1.x += a0.x;
+    a1.y += a0.y;
+
+    for ( i = 1; i <= arcs; i++ )
     {
-      step = total;
-      if ( step > FT_ARC_CUBIC_ANGLE )
-        step = FT_ARC_CUBIC_ANGLE;
+      /* compute end and second control point */
+      FT_Vector_From_Polar( &a3, radius,
+                            angle_start + i * angle_diff / arcs );
+      a2.x = FT_MulFix(  a3.y, coef );
+      a2.y = FT_MulFix( -a3.x, coef );
 
-      else if ( step < -FT_ARC_CUBIC_ANGLE )
-        step = -FT_ARC_CUBIC_ANGLE;
-
-      next  = angle + step;
-      theta = step;
-      if ( theta < 0 )
-        theta = -theta;
-
-      theta >>= 1;
-
-      /* compute end point */
-      FT_Vector_From_Polar( &b, radius, next );
-      b.x += center->x;
-      b.y += center->y;
-
-      /* compute first and second control points */
-      length = FT_MulDiv( radius, FT_Sin( theta ) * 4,
-                          ( 0x10000L + FT_Cos( theta ) ) * 3 );
-
-      FT_Vector_From_Polar( &a2, length, angle + rotate );
-      a2.x += a.x;
-      a2.y += a.y;
-
-      FT_Vector_From_Polar( &b2, length, next - rotate );
-      b2.x += b.x;
-      b2.y += b.y;
+      a3.x += center->x;
+      a3.y += center->y;
+      a2.x += a3.x;
+      a2.y += a3.y;
 
       /* add cubic arc */
-      error = ft_stroke_border_cubicto( border, &a2, &b2, &b );
+      error = ft_stroke_border_cubicto( border, &a1, &a2, &a3 );
       if ( error )
         break;
 
-      /* process the rest of the arc ?? */
-      a      = b;
-      total -= step;
-      angle  = next;
+      /* a0 = a3; */
+      a1.x = a3.x - a2.x + a3.x;
+      a1.y = a3.y - a2.y + a3.y;
     }
 
     return error;
@@ -927,55 +922,40 @@
 
       error = ft_stroker_arcto( stroker, side );
     }
-    else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )
+    else
     {
-      /* add a square cap */
-      FT_Vector        delta, delta2;
-      FT_Angle         rotate = FT_SIDE_TO_ROTATE( side );
+      /* add a square or butt cap */
+      FT_Vector        middle, delta;
       FT_Fixed         radius = stroker->radius;
       FT_StrokeBorder  border = stroker->borders + side;
 
 
-      FT_Vector_From_Polar( &delta2, radius, angle + rotate );
-      FT_Vector_From_Polar( &delta,  radius, angle );
+      /* compute middle point and first angle point */
+      FT_Vector_From_Polar( &middle, radius, angle );
+      delta.x = side ?  middle.y : -middle.y;
+      delta.y = side ? -middle.x :  middle.x;
 
-      delta.x += stroker->center.x + delta2.x;
-      delta.y += stroker->center.y + delta2.y;
+      if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )
+      {
+        middle.x += stroker->center.x;
+        middle.y += stroker->center.y;
+      }
+      else  /* FT_STROKER_LINECAP_BUTT */
+      {
+        middle.x  = stroker->center.x;
+        middle.y  = stroker->center.y;
+      }
+
+      delta.x  += middle.x;
+      delta.y  += middle.y;
 
       error = ft_stroke_border_lineto( border, &delta, FALSE );
       if ( error )
         goto Exit;
 
-      FT_Vector_From_Polar( &delta2, radius, angle - rotate );
-      FT_Vector_From_Polar( &delta,  radius, angle );
-
-      delta.x += delta2.x + stroker->center.x;
-      delta.y += delta2.y + stroker->center.y;
-
-      error = ft_stroke_border_lineto( border, &delta, FALSE );
-    }
-    else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT )
-    {
-      /* add a butt ending */
-      FT_Vector        delta;
-      FT_Angle         rotate = FT_SIDE_TO_ROTATE( side );
-      FT_Fixed         radius = stroker->radius;
-      FT_StrokeBorder  border = stroker->borders + side;
-
-
-      FT_Vector_From_Polar( &delta, radius, angle + rotate );
-
-      delta.x += stroker->center.x;
-      delta.y += stroker->center.y;
-
-      error = ft_stroke_border_lineto( border, &delta, FALSE );
-      if ( error )
-        goto Exit;
-
-      FT_Vector_From_Polar( &delta, radius, angle - rotate );
-
-      delta.x += stroker->center.x;
-      delta.y += stroker->center.y;
+      /* compute second angle point */
+      delta.x = middle.x - delta.x + middle.x;
+      delta.y = middle.y - delta.y + middle.y;
 
       error = ft_stroke_border_lineto( border, &delta, FALSE );
     }
@@ -993,7 +973,8 @@
   {
     FT_StrokeBorder  border = stroker->borders + side;
     FT_Angle         phi, theta, rotate;
-    FT_Fixed         length, thcos;
+    FT_Fixed         length;
+    FT_Vector        sigma = { 0, 0 };
     FT_Vector        delta;
     FT_Error         error = FT_Err_Ok;
     FT_Bool          intersect;          /* use intersection of lines? */
@@ -1012,10 +993,13 @@
     else
     {
       /* compute minimum required length of lines */
-      FT_Fixed  min_length = ft_pos_abs( FT_MulFix( stroker->radius,
-                                                    FT_Tan( theta ) ) );
+      FT_Fixed  min_length;
 
 
+      FT_Vector_Unit( &sigma, theta );
+      min_length =
+        ft_pos_abs( FT_MulDiv( stroker->radius, sigma.y, sigma.x ) );
+
       intersect = FT_BOOL( min_length                         &&
                            stroker->line_length >= min_length &&
                            line_length          >= min_length );
@@ -1033,13 +1017,11 @@
     else
     {
       /* compute median angle */
-      phi = stroker->angle_in + theta;
+      phi = stroker->angle_in + theta + rotate;
 
-      thcos = FT_Cos( theta );
+      length = FT_DivFix( stroker->radius, sigma.x );
 
-      length = FT_DivFix( stroker->radius, thcos );
-
-      FT_Vector_From_Polar( &delta, length, phi + rotate );
+      FT_Vector_From_Polar( &delta, length, phi );
       delta.x += stroker->center.x;
       delta.y += stroker->center.y;
     }
@@ -1066,10 +1048,10 @@
     else
     {
       /* this is a mitered (pointed) or beveled (truncated) corner */
-      FT_Fixed  sigma = 0, radius = stroker->radius;
-      FT_Angle  theta = 0, phi = 0;
-      FT_Fixed  thcos = 0;
-      FT_Bool   bevel, fixed_bevel;
+      FT_Fixed   radius = stroker->radius;
+      FT_Vector  sigma = { 0, 0 };
+      FT_Angle   theta = 0, phi = 0;
+      FT_Bool    bevel, fixed_bevel;
 
 
       rotate = FT_SIDE_TO_ROTATE( side );
@@ -1080,26 +1062,20 @@
       fixed_bevel =
         FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_MITER_VARIABLE );
 
+      /* check miter limit first */
       if ( !bevel )
       {
-        theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );
+        theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2;
 
-        if ( theta == FT_ANGLE_PI )
-        {
-          theta = rotate;
-          phi   = stroker->angle_in;
-        }
-        else
-        {
-          theta /= 2;
-          phi    = stroker->angle_in + theta + rotate;
-        }
+        if ( theta == FT_ANGLE_PI2 )
+          theta = -rotate;
 
-        thcos = FT_Cos( theta );
-        sigma = FT_MulFix( stroker->miter_limit, thcos );
+        phi    = stroker->angle_in + theta + rotate;
+
+        FT_Vector_From_Polar( &sigma, stroker->miter_limit, theta );
 
         /* is miter limit exceeded? */
-        if ( sigma < 0x10000L )
+        if ( sigma.x < 0x10000L )
         {
           /* don't create variable bevels for very small deviations; */
           /* FT_Sin(x) = 0 for x <= 57                               */
@@ -1126,36 +1102,34 @@
           border->movable = FALSE;
           error = ft_stroke_border_lineto( border, &delta, FALSE );
         }
-        else /* variable bevel */
+        else /* variable bevel or clipped miter */
         {
           /* the miter is truncated */
           FT_Vector  middle, delta;
-          FT_Fixed   length;
+          FT_Fixed   coef;
 
 
-          /* compute middle point */
+          /* compute middle point and first angle point */
           FT_Vector_From_Polar( &middle,
                                 FT_MulFix( radius, stroker->miter_limit ),
                                 phi );
+
+          coef    = FT_DivFix(  0x10000L - sigma.x, sigma.y );
+          delta.x = FT_MulFix(  middle.y, coef );
+          delta.y = FT_MulFix( -middle.x, coef );
+
           middle.x += stroker->center.x;
           middle.y += stroker->center.y;
-
-          /* compute first angle point */
-          length = FT_MulDiv( radius, 0x10000L - sigma,
-                              ft_pos_abs( FT_Sin( theta ) ) );
-
-          FT_Vector_From_Polar( &delta, length, phi + rotate );
-          delta.x += middle.x;
-          delta.y += middle.y;
+          delta.x  += middle.x;
+          delta.y  += middle.y;
 
           error = ft_stroke_border_lineto( border, &delta, FALSE );
           if ( error )
             goto Exit;
 
           /* compute second angle point */
-          FT_Vector_From_Polar( &delta, length, phi - rotate );
-          delta.x += middle.x;
-          delta.y += middle.y;
+          delta.x = middle.x - delta.x + middle.x;
+          delta.y = middle.y - delta.y + middle.y;
 
           error = ft_stroke_border_lineto( border, &delta, FALSE );
           if ( error )
@@ -1182,7 +1156,7 @@
         FT_Vector  delta;
 
 
-        length = FT_DivFix( stroker->radius, thcos );
+        length = FT_MulDiv( stroker->radius, stroker->miter_limit, sigma.x );
 
         FT_Vector_From_Polar( &delta, length, phi );
         delta.x += stroker->center.x;
@@ -1555,7 +1529,8 @@
       stroker->angle_in = angle_out;
     }
 
-    stroker->center = *to;
+    stroker->center      = *to;
+    stroker->line_length = 0;
 
   Exit:
     return error;
@@ -1771,7 +1746,8 @@
       stroker->angle_in = angle_out;
     }
 
-    stroker->center = *to;
+    stroker->center      = *to;
+    stroker->line_length = 0;
 
   Exit:
     return error;
@@ -1924,13 +1900,9 @@
     }
     else
     {
-      FT_Angle  turn;
-      FT_Int    inside_side;
-
-
       /* close the path if needed */
-      if ( stroker->center.x != stroker->subpath_start.x ||
-           stroker->center.y != stroker->subpath_start.y )
+      if ( !FT_IS_SMALL( stroker->center.x - stroker->subpath_start.x ) ||
+           !FT_IS_SMALL( stroker->center.y - stroker->subpath_start.y ) )
       {
          error = FT_Stroker_LineTo( stroker, &stroker->subpath_start );
          if ( error )
@@ -1939,29 +1911,11 @@
 
       /* process the corner */
       stroker->angle_out = stroker->subpath_angle;
-      turn               = FT_Angle_Diff( stroker->angle_in,
-                                          stroker->angle_out );
 
-      /* no specific corner processing is required if the turn is 0 */
-      if ( turn != 0 )
-      {
-        /* when we turn to the right, the inside side is 0 */
-        /* otherwise, the inside side is 1 */
-        inside_side = ( turn < 0 );
-
-        error = ft_stroker_inside( stroker,
-                                   inside_side,
-                                   stroker->subpath_line_length );
-        if ( error )
-          goto Exit;
-
-        /* process the outside side */
-        error = ft_stroker_outside( stroker,
-                                    !inside_side,
-                                    stroker->subpath_line_length );
-        if ( error )
-          goto Exit;
-      }
+      error = ft_stroker_process_corner( stroker,
+                                         stroker->subpath_line_length );
+      if ( error )
+        goto Exit;
 
       /* then end our two subpaths */
       ft_stroke_border_close( stroker->borders + 0, FALSE );
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index 5539105..6ec25e1 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
  *
  *   FreeType synthesizing code for emboldening and slanting (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_SYNTHESIS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_OUTLINE_H
-#include FT_BITMAP_H
+#include <freetype/ftsynth.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftoutln.h>
+#include <freetype/ftbitmap.h>
 
 
   /**************************************************************************
@@ -31,7 +30,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_synth
+#define FT_COMPONENT  synth
 
 
   /*************************************************************************/
@@ -47,6 +46,18 @@
   FT_EXPORT_DEF( void )
   FT_GlyphSlot_Oblique( FT_GlyphSlot  slot )
   {
+    /* Value '0x0366A' corresponds to a shear angle of about 12 degrees. */
+    FT_GlyphSlot_Slant( slot, 0x0366A, 0 );
+  }
+
+
+  /* documentation is in ftsynth.h */
+
+  FT_EXPORT_DEF( void )
+  FT_GlyphSlot_Slant( FT_GlyphSlot  slot,
+                      FT_Fixed      xslant,
+                      FT_Fixed      yslant )
+  {
     FT_Matrix    transform;
     FT_Outline*  outline;
 
@@ -62,13 +73,11 @@
 
     /* we don't touch the advance width */
 
-    /* For italic, simply apply a shear transform, with an angle */
-    /* of about 12 degrees.                                      */
-
+    /* For italic, simply apply a shear transform */
     transform.xx = 0x10000L;
-    transform.yx = 0x00000L;
+    transform.yx = -yslant;
 
-    transform.xy = 0x0366AL;
+    transform.xy = xslant;
     transform.yy = 0x10000L;
 
     FT_Outline_Transform( outline, &transform );
@@ -130,7 +139,7 @@
       if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
       {
         FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));
-        FT_TRACE1(( "too strong emboldening parameter ystr=%d\n", ystr ));
+        FT_TRACE1(( "too strong emboldening parameter ystr=%ld\n", ystr ));
         return;
       }
       error = FT_GlyphSlot_Own_Bitmap( slot );
diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c
index d761ad9..fcd289d 100644
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -4,7 +4,7 @@
  *
  *   ANSI-specific FreeType low-level system interface (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -27,11 +27,11 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_SYSTEM_H
-#include FT_ERRORS_H
-#include FT_TYPES_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/ftsystem.h>
+#include <freetype/fterrors.h>
+#include <freetype/fttypes.h>
 
 
   /**************************************************************************
@@ -154,7 +154,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_io
+#define FT_COMPONENT  io
 
   /* We use the macro STREAM_FILE for convenience to extract the       */
   /* system-specific stream handle from a given FreeType stream object */
@@ -275,7 +275,7 @@
     stream->close = ft_ansi_stream_close;
 
     FT_TRACE1(( "FT_Stream_Open:" ));
-    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
+    FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
                 filepathname, stream->size ));
 
     return FT_Err_Ok;
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index d375bd7..2dd2c34 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -4,7 +4,7 @@
  *
  *   FreeType trigonometric functions (body).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -29,10 +29,9 @@
    *
    */
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_CALC_H
-#include FT_TRIGONOMETRY_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/fttrigon.h>
 
 
   /* the Cordic shrink factor 0.858785336480436 * 2^32 */
@@ -54,7 +53,7 @@
   };
 
 
-#ifdef FT_LONG64
+#ifdef FT_INT64
 
   /* multiply a given value by the CORDIC shrink factor */
   static FT_Fixed
@@ -77,7 +76,7 @@
     return s < 0 ? -val : val;
   }
 
-#else /* !FT_LONG64 */
+#else /* !FT_INT64 */
 
   /* multiply a given value by the CORDIC shrink factor */
   static FT_Fixed
@@ -126,7 +125,7 @@
     return s < 0 ? -val : val;
   }
 
-#endif /* !FT_LONG64 */
+#endif /* !FT_INT64 */
 
 
   /* undefined and never called for zero vector */
diff --git a/src/base/fttype1.c b/src/base/fttype1.c
index 229b0ac..637c5cf 100644
--- a/src/base/fttype1.c
+++ b/src/base/fttype1.c
@@ -4,7 +4,7 @@
  *
  *   FreeType utility file for PS names support (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/services/svpsinfo.h>
 
 
   /* documentation is in t1tables.h */
diff --git a/src/base/ftutil.c b/src/base/ftutil.c
index eced7bb..6120846 100644
--- a/src/base/ftutil.c
+++ b/src/base/ftutil.c
@@ -4,7 +4,7 @@
  *
  *   FreeType utility file for memory and list management (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_LIST_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftlist.h>
 
 
   /**************************************************************************
@@ -30,7 +29,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_memory
+#define FT_COMPONENT  memory
 
 
   /*************************************************************************/
@@ -236,7 +235,7 @@
   /*************************************************************************/
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_list
+#define FT_COMPONENT  list
 
   /* documentation is in ftlist.h */
 
diff --git a/src/base/ftver.rc b/src/base/ftver.rc
index b0b6e00..f113cb8 100644
--- a/src/base/ftver.rc
+++ b/src/base/ftver.rc
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType VERSIONINFO resource for Windows DLLs.                      */
 /*                                                                         */
-/*  Copyright 2018 by                                                      */
+/*  Copyright (C) 2018-2023 by                                             */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -18,8 +18,8 @@
 
 #include<windows.h>
 
-#define FT_VERSION      2,9,1,0
-#define FT_VERSION_STR  "2.9.1"
+#define FT_VERSION      2,13,0,0
+#define FT_VERSION_STR  "2.13.0"
 
 VS_VERSION_INFO      VERSIONINFO
 FILEVERSION          FT_VERSION
@@ -38,14 +38,14 @@
 BEGIN
   BLOCK "StringFileInfo"
   BEGIN
-    BLOCK "040904E4"
+    BLOCK "040904B0"
     BEGIN
       VALUE "CompanyName",      "The FreeType Project"
       VALUE "FileDescription",  "Font Rendering Library"
       VALUE "FileVersion",      FT_VERSION_STR
       VALUE "ProductName",      "FreeType"
       VALUE "ProductVersion",   FT_VERSION_STR
-      VALUE "LegalCopyright",   "\251 2018 The FreeType Project www.freetype.org. All rights reserved."
+      VALUE "LegalCopyright",   L"\x00A9 2000-2023 The FreeType Project www.freetype.org. All rights reserved."
       VALUE "InternalName",     "freetype"
       VALUE "OriginalFilename", FT_FILENAME
     END
@@ -56,6 +56,6 @@
     /* The following line should only be modified for localized versions.  */
     /* It consists of any number of WORD,WORD pairs, with each pair        */
     /* describing a "language,codepage" combination supported by the file. */
-    VALUE "Translation", 0x409, 1252
+    VALUE "Translation", 0x409, 1200
   END
 END
diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c
index bd6548f..03b023e 100644
--- a/src/base/ftwinfnt.c
+++ b/src/base/ftwinfnt.c
@@ -4,7 +4,7 @@
  *
  *   FreeType API for accessing Windows FNT specific info (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_WINFONTS_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_WINFNT_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftwinfnt.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svwinfnt.h>
 
 
   /* documentation is in ftwinfnt.h */
diff --git a/src/base/rules.mk b/src/base/rules.mk
index 214fd77..b7de9b5 100644
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -40,6 +40,7 @@
             $(BASE_DIR)/ftcalc.c   \
             $(BASE_DIR)/ftcolor.c  \
             $(BASE_DIR)/ftdbgmem.c \
+            $(BASE_DIR)/fterrors.c \
             $(BASE_DIR)/ftfntfmt.c \
             $(BASE_DIR)/ftgloadr.c \
             $(BASE_DIR)/fthash.c   \
diff --git a/src/bdf/Jamfile b/src/bdf/Jamfile
deleted file mode 100644
index d9e441c..0000000
--- a/src/bdf/Jamfile
+++ /dev/null
@@ -1,31 +0,0 @@
-# FreeType 2 src/bdf Jamfile
-#
-# Copyright 2002-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) bdf ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = bdfdrivr
-               bdflib
-               ;
-  }
-  else
-  {
-    _sources = bdf ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/bdf Jamfile
diff --git a/src/bdf/README b/src/bdf/README
index 996ac2d..d7cb8c1 100644
--- a/src/bdf/README
+++ b/src/bdf/README
@@ -13,7 +13,7 @@
 Adobe Specification V 2.2.  The specification of the BDF font format is
 available from Adobe's web site:
 
-  https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5005.BDF_Spec.pdf
+  https://adobe-type-tools.github.io/font-tech-notes/pdfs/5005.BDF_Spec.pdf
 
 Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org).
 They do not define vertical metrics, because the X Consortium BDF
@@ -23,6 +23,10 @@
 Encodings
 *********
 
+[This section is out of date, retained for historical reasons.  BDF
+ properties can be retrieved with `FT_Get_BDF_Property`, character set ID
+ values with `FT_Get_BDF_Charset_ID`.]
+
 The variety of encodings that accompanies bdf fonts appears to encompass the
 small set defined in freetype.h.  On the other hand, two properties that
 specify encoding and registry are usually defined in bdf fonts.
diff --git a/src/bdf/bdf.c b/src/bdf/bdf.c
index e54df66..249012e 100644
--- a/src/bdf/bdf.c
+++ b/src/bdf/bdf.c
@@ -26,7 +26,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "bdflib.c"
 #include "bdfdrivr.c"
diff --git a/src/bdf/bdf.h b/src/bdf/bdf.h
index a6ba82e..5acbd5f 100644
--- a/src/bdf/bdf.h
+++ b/src/bdf/bdf.h
@@ -30,10 +30,9 @@
  * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher
  */
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_HASH_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/fthash.h>
 
 
 FT_BEGIN_HEADER
@@ -109,9 +108,9 @@
   /* There are a set of defaults and each font has their own.   */
   typedef struct  bdf_property_t_
   {
-    char*  name;         /* Name of the property.   */
-    int    format;       /* Format of the property. */
-    int    builtin;      /* A builtin property.     */
+    const char*  name;         /* Name of the property.   */
+    int          format;       /* Format of the property. */
+    int          builtin;      /* A builtin property.     */
     union
     {
       char*          atom;
@@ -147,7 +146,7 @@
   typedef struct  bdf_glyph_t_
   {
     char*           name;        /* Glyph name.                          */
-    long            encoding;    /* Glyph encoding.                      */
+    unsigned long   encoding;    /* Glyph encoding.                      */
     unsigned short  swidth;      /* Scalable width.                      */
     unsigned short  dwidth;      /* Device width.                        */
     bdf_bbx_t       bbx;         /* Glyph bounding box.                  */
@@ -158,20 +157,6 @@
   } bdf_glyph_t;
 
 
-  typedef struct  bdf_glyphlist_t_
-  {
-    unsigned short  pad;          /* Pad to 4-byte boundary.              */
-    unsigned short  bpp;          /* Bits per pixel.                      */
-    long            start;        /* Beginning encoding value of glyphs.  */
-    long            end;          /* Ending encoding value of glyphs.     */
-    bdf_glyph_t*    glyphs;       /* Glyphs themselves.                   */
-    unsigned long   glyphs_size;  /* Glyph structures allocated.          */
-    unsigned long   glyphs_used;  /* Glyph structures used.               */
-    bdf_bbx_t       bbx;          /* Overall bounding box of glyphs.      */
-
-  } bdf_glyphlist_t;
-
-
   typedef struct  bdf_font_t_
   {
     char*            name;           /* Name of the font.                   */
@@ -185,7 +170,7 @@
 
     unsigned short   monowidth;      /* Logical width for monowidth font.   */
 
-    long             default_char;   /* Encoding of the default glyph.      */
+    unsigned long    default_char;   /* Encoding of the default glyph.      */
 
     long             font_ascent;    /* Font ascent.                        */
     long             font_descent;   /* Font descent.                       */
@@ -205,16 +190,8 @@
     char*            comments;       /* Font comments.                      */
     unsigned long    comments_len;   /* Length of comment string.           */
 
-    bdf_glyphlist_t  overflow;       /* Storage used for glyph insertion.   */
-
     void*            internal;       /* Internal data for the font.         */
 
-    /* The size of the next two arrays must be in sync with the */
-    /* size of the `have' array in the `bdf_parse_t' structure. */
-    unsigned long    nmod[34816];    /* Bitmap indicating modified glyphs.  */
-    unsigned long    umod[34816];    /* Bitmap indicating modified          */
-                                     /* unencoded glyphs.                   */
-    unsigned short   modified;       /* Boolean indicating font modified.   */
     unsigned short   bpp;            /* Bits per pixel.                     */
 
     FT_Memory        memory;
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index 1e272b0..d7e8e0e 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -24,16 +24,15 @@
 THE SOFTWARE.
 */
 
-#include <ft2build.h>
 
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_BDF_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftbdf.h>
+#include <freetype/ttnameid.h>
 
-#include FT_SERVICE_BDF_H
-#include FT_SERVICE_FONT_FORMAT_H
+#include <freetype/internal/services/svbdf.h>
+#include <freetype/internal/services/svfntfmt.h>
 
 #include "bdf.h"
 #include "bdfdrivr.h"
@@ -48,7 +47,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_bdfdriver
+#define FT_COMPONENT  bdfdriver
 
 
   typedef struct  BDF_CMapRec_
@@ -93,21 +92,18 @@
   {
     BDF_CMap          cmap      = (BDF_CMap)bdfcmap;
     BDF_encoding_el*  encodings = cmap->encodings;
-    FT_ULong          min, max, mid; /* num_encodings */
     FT_UShort         result    = 0; /* encodings->glyph */
 
+    FT_ULong  min = 0;
+    FT_ULong  max = cmap->num_encodings;
+    FT_ULong  mid = ( min + max ) >> 1;
 
-    min = 0;
-    max = cmap->num_encodings;
 
     while ( min < max )
     {
-      FT_ULong  code;
+      FT_ULong  code = encodings[mid].enc;
 
 
-      mid  = ( min + max ) >> 1;
-      code = (FT_ULong)encodings[mid].enc;
-
       if ( charcode == code )
       {
         /* increase glyph index by 1 --              */
@@ -120,6 +116,11 @@
         max = mid;
       else
         min = mid + 1;
+
+      /* reasonable prediction in a continuous block */
+      mid += charcode - code;
+      if ( mid >= max || mid < min )
+        mid = ( min + max ) >> 1;
     }
 
     return result;
@@ -132,22 +133,19 @@
   {
     BDF_CMap          cmap      = (BDF_CMap)bdfcmap;
     BDF_encoding_el*  encodings = cmap->encodings;
-    FT_ULong          min, max, mid; /* num_encodings */
     FT_UShort         result   = 0;  /* encodings->glyph */
     FT_ULong          charcode = *acharcode + 1;
 
+    FT_ULong  min = 0;
+    FT_ULong  max = cmap->num_encodings;
+    FT_ULong  mid = ( min + max ) >> 1;
 
-    min = 0;
-    max = cmap->num_encodings;
 
     while ( min < max )
     {
-      FT_ULong  code; /* same as BDF_encoding_el.enc */
+      FT_ULong  code = encodings[mid].enc;
 
 
-      mid  = ( min + max ) >> 1;
-      code = (FT_ULong)encodings[mid].enc;
-
       if ( charcode == code )
       {
         /* increase glyph index by 1 --              */
@@ -160,19 +158,25 @@
         max = mid;
       else
         min = mid + 1;
+
+      /* prediction in a continuous block */
+      mid += charcode - code;
+      if ( mid >= max || mid < min )
+        mid = ( min + max ) >> 1;
     }
 
     charcode = 0;
     if ( min < cmap->num_encodings )
     {
-      charcode = (FT_ULong)encodings[min].enc;
+      charcode = encodings[min].enc;
       result   = encodings[min].glyph + 1;
     }
 
   Exit:
     if ( charcode > 0xFFFFFFFFUL )
     {
-      FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" ));
+      FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%lx > 32bit API",
+                  charcode ));
       *acharcode = 0;
       /* XXX: result should be changed to indicate an overflow error */
     }
@@ -204,13 +208,13 @@
     bdf_font_t*      font   = bdf->bdffont;
     bdf_property_t*  prop;
 
-    char*   strings[4] = { NULL, NULL, NULL, NULL };
-    size_t  nn, len, lengths[4];
+    const char*   strings[4] = { NULL, NULL, NULL, NULL };
+    size_t        lengths[4], nn, len;
 
 
     face->style_flags = 0;
 
-    prop = bdf_get_font_property( font, (char *)"SLANT" );
+    prop = bdf_get_font_property( font, "SLANT" );
     if ( prop && prop->format == BDF_ATOM                             &&
          prop->value.atom                                             &&
          ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
@@ -218,30 +222,30 @@
     {
       face->style_flags |= FT_STYLE_FLAG_ITALIC;
       strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
-                   ? (char *)"Oblique"
-                   : (char *)"Italic";
+                   ? "Oblique"
+                   : "Italic";
     }
 
-    prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
+    prop = bdf_get_font_property( font, "WEIGHT_NAME" );
     if ( prop && prop->format == BDF_ATOM                             &&
          prop->value.atom                                             &&
          ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
     {
       face->style_flags |= FT_STYLE_FLAG_BOLD;
-      strings[1] = (char *)"Bold";
+      strings[1] = "Bold";
     }
 
-    prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );
+    prop = bdf_get_font_property( font, "SETWIDTH_NAME" );
     if ( prop && prop->format == BDF_ATOM                              &&
          prop->value.atom && *(prop->value.atom)                       &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[3] = (char *)(prop->value.atom);
+      strings[3] = (const char *)(prop->value.atom);
 
-    prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );
+    prop = bdf_get_font_property( font, "ADD_STYLE_NAME" );
     if ( prop && prop->format == BDF_ATOM                              &&
          prop->value.atom && *(prop->value.atom)                       &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[0] = (char *)(prop->value.atom);
+      strings[0] = (const char *)(prop->value.atom);
 
     for ( len = 0, nn = 0; nn < 4; nn++ )
     {
@@ -255,7 +259,7 @@
 
     if ( len == 0 )
     {
-      strings[0] = (char *)"Regular";
+      strings[0] = "Regular";
       lengths[0] = ft_strlen( strings[0] );
       len        = lengths[0] + 1;
     }
@@ -264,14 +268,14 @@
       char*  s;
 
 
-      if ( FT_ALLOC( face->style_name, len ) )
+      if ( FT_QALLOC( face->style_name, len ) )
         return error;
 
       s = face->style_name;
 
       for ( nn = 0; nn < 4; nn++ )
       {
-        char*  src = strings[nn];
+        const char*  src = strings[nn];
 
 
         len = lengths[nn];
@@ -390,10 +394,10 @@
       bdf_property_t*  prop = NULL;
 
 
-      FT_TRACE4(( "  number of glyphs: allocated %d (used %d)\n",
+      FT_TRACE4(( "  number of glyphs: allocated %ld (used %ld)\n",
                   font->glyphs_size,
                   font->glyphs_used ));
-      FT_TRACE4(( "  number of unencoded glyphs: allocated %d (used %d)\n",
+      FT_TRACE4(( "  number of unencoded glyphs: allocated %ld (used %ld)\n",
                   font->unencoded_size,
                   font->unencoded_used ));
 
@@ -430,7 +434,7 @@
       bdfface->num_glyphs = (FT_Long)( font->glyphs_size + 1 );
 
       bdfface->num_fixed_sizes = 1;
-      if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) )
+      if ( FT_NEW( bdfface->available_sizes ) )
         goto Exit;
 
       {
@@ -439,19 +443,17 @@
         long             value;
 
 
-        FT_ZERO( bsize );
-
         /* sanity checks */
         if ( font->font_ascent > 0x7FFF || font->font_ascent < -0x7FFF )
         {
           font->font_ascent = font->font_ascent < 0 ? -0x7FFF : 0x7FFF;
-          FT_TRACE0(( "BDF_Face_Init: clamping font ascent to value %d\n",
+          FT_TRACE0(( "BDF_Face_Init: clamping font ascent to value %ld\n",
                       font->font_ascent ));
         }
         if ( font->font_descent > 0x7FFF || font->font_descent < -0x7FFF )
         {
           font->font_descent = font->font_descent < 0 ? -0x7FFF : 0x7FFF;
-          FT_TRACE0(( "BDF_Face_Init: clamping font descent to value %d\n",
+          FT_TRACE0(( "BDF_Face_Init: clamping font descent to value %ld\n",
                       font->font_descent ));
         }
 
@@ -477,7 +479,7 @@
         else
         {
           /* this is a heuristical value */
-          bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 );
+          bsize->width = ( bsize->height * 2 + 1 ) / 3;
         }
 
         prop = bdf_get_font_property( font, "POINT_SIZE" );
@@ -492,7 +494,7 @@
                prop->value.l < -0x504C2L )
           {
             bsize->size = 0x7FFF;
-            FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n",
+            FT_TRACE0(( "BDF_Face_Init: clamping point size to value %ld\n",
                         bsize->size ));
           }
           else
@@ -505,7 +507,7 @@
           if ( font->point_size > 0x7FFF )
           {
             bsize->size = 0x7FFF;
-            FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n",
+            FT_TRACE0(( "BDF_Face_Init: clamping point size to value %ld\n",
                         bsize->size ));
           }
           else
@@ -527,7 +529,7 @@
           if ( prop->value.l > 0x7FFF || prop->value.l < -0x7FFF )
           {
             bsize->y_ppem = 0x7FFF << 6;
-            FT_TRACE0(( "BDF_Face_Init: clamping pixel size to value %d\n",
+            FT_TRACE0(( "BDF_Face_Init: clamping pixel size to value %ld\n",
                         bsize->y_ppem ));
           }
           else
@@ -596,14 +598,14 @@
         unsigned long  n;
 
 
-        if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) )
+        if ( FT_QNEW_ARRAY( face->en_table, font->glyphs_size ) )
           goto Exit;
 
         face->default_glyph = 0;
         for ( n = 0; n < font->glyphs_size; n++ )
         {
           (face->en_table[n]).enc = cur[n].encoding;
-          FT_TRACE4(( "  idx %d, val 0x%lX\n", n, cur[n].encoding ));
+          FT_TRACE4(( "  idx %ld, val 0x%lX\n", n, cur[n].encoding ));
           (face->en_table[n]).glyph = (FT_UShort)n;
 
           if ( cur[n].encoding == font->default_char )
@@ -612,7 +614,7 @@
               face->default_glyph = (FT_UInt)n;
             else
               FT_TRACE1(( "BDF_Face_Init:"
-                          " idx %d is too large for this system\n", n ));
+                          " idx %ld is too large for this system\n", n ));
           }
         }
       }
@@ -813,7 +815,7 @@
     bitmap->rows  = glyph.bbx.height;
     bitmap->width = glyph.bbx.width;
     if ( glyph.bpr > FT_INT_MAX )
-      FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n",
+      FT_TRACE1(( "BDF_Glyph_Load: too large pitch %ld is truncated\n",
                    glyph.bpr ));
     bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */
 
@@ -890,7 +892,8 @@
         if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )
         {
           FT_TRACE1(( "bdf_get_bdf_property:"
-                      " too large integer 0x%x is truncated\n" ));
+                      " too large integer 0x%lx is truncated\n",
+                      prop->value.l ));
         }
         aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;
         aproperty->u.integer = (FT_Int32)prop->value.l;
@@ -900,7 +903,8 @@
         if ( prop->value.ul > 0xFFFFFFFFUL )
         {
           FT_TRACE1(( "bdf_get_bdf_property:"
-                      " too large cardinal 0x%x is truncated\n" ));
+                      " too large cardinal 0x%lx is truncated\n",
+                      prop->value.ul ));
         }
         aproperty->type       = BDF_PROPERTY_TYPE_CARDINAL;
         aproperty->u.cardinal = (FT_UInt32)prop->value.ul;
diff --git a/src/bdf/bdfdrivr.h b/src/bdf/bdfdrivr.h
index 4857316..54aaa33 100644
--- a/src/bdf/bdfdrivr.h
+++ b/src/bdf/bdfdrivr.h
@@ -28,8 +28,7 @@
 #ifndef BDFDRIVR_H_
 #define BDFDRIVR_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 #include "bdf.h"
 
@@ -39,7 +38,7 @@
 
   typedef struct  BDF_encoding_el_
   {
-    FT_Long    enc;
+    FT_ULong   enc;
     FT_UShort  glyph;
 
   } BDF_encoding_el;
@@ -56,9 +55,6 @@
 
     BDF_encoding_el*  en_table;
 
-    FT_CharMap        charmap_handle;
-    FT_CharMapRec     charmap;  /* a single charmap per face */
-
     FT_UInt           default_glyph;
 
   } BDF_FaceRec, *BDF_Face;
diff --git a/src/bdf/bdferror.h b/src/bdf/bdferror.h
index dbe41c0..c1b5444 100644
--- a/src/bdf/bdferror.h
+++ b/src/bdf/bdferror.h
@@ -29,7 +29,7 @@
 #ifndef BDFERROR_H_
 #define BDFERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -37,7 +37,7 @@
 #define FT_ERR_PREFIX  BDF_Err_
 #define FT_ERR_BASE    FT_Mod_Err_BDF
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* BDFERROR_H_ */
 
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 5c09591..2224698 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -31,12 +31,11 @@
    */
 
 
-#include <ft2build.h>
 
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
 
 #include "bdf.h"
 #include "bdferror.h"
@@ -49,7 +48,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_bdflib
+#define FT_COMPONENT  bdflib
 
 
   /**************************************************************************
@@ -59,7 +58,7 @@
    */
 
 
-  static const bdf_options_t  _bdf_opts =
+  static const bdf_options_t  bdf_opts_ =
   {
     1,                /* Correct metrics.               */
     1,                /* Preserve unencoded glyphs.     */
@@ -77,101 +76,101 @@
   /* List of most properties that might appear in a font.  Doesn't include */
   /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts.           */
 
-  static const bdf_property_t  _bdf_properties[] =
+  static const bdf_property_t  bdf_properties_[] =
   {
-    { (char *)"ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },
-    { (char *)"AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },
-    { (char *)"CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },
-    { (char *)"CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },
-    { (char *)"CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },
-    { (char *)"COMMENT",                 BDF_ATOM,     1, { 0 } },
-    { (char *)"COPYRIGHT",               BDF_ATOM,     1, { 0 } },
-    { (char *)"DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },
-    { (char *)"DESTINATION",             BDF_CARDINAL, 1, { 0 } },
-    { (char *)"DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },
-    { (char *)"END_SPACE",               BDF_INTEGER,  1, { 0 } },
-    { (char *)"FACE_NAME",               BDF_ATOM,     1, { 0 } },
-    { (char *)"FAMILY_NAME",             BDF_ATOM,     1, { 0 } },
-    { (char *)"FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"FONT",                    BDF_ATOM,     1, { 0 } },
-    { (char *)"FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },
-    { (char *)"FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"FOUNDRY",                 BDF_ATOM,     1, { 0 } },
-    { (char *)"FULL_NAME",               BDF_ATOM,     1, { 0 } },
-    { (char *)"ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"MAX_SPACE",               BDF_INTEGER,  1, { 0 } },
-    { (char *)"MIN_SPACE",               BDF_INTEGER,  1, { 0 } },
-    { (char *)"NORM_SPACE",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"NOTICE",                  BDF_ATOM,     1, { 0 } },
-    { (char *)"PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"POINT_SIZE",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },
-    { (char *)"RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },
-    { (char *)"RESOLUTION",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },
-    { (char *)"RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },
-    { (char *)"SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },
-    { (char *)"SLANT",                   BDF_ATOM,     1, { 0 } },
-    { (char *)"SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"SPACING",                 BDF_ATOM,     1, { 0 } },
-    { (char *)"STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },
-    { (char *)"STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },
-    { (char *)"UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },
-    { (char *)"WEIGHT",                  BDF_CARDINAL, 1, { 0 } },
-    { (char *)"WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },
-    { (char *)"X_HEIGHT",                BDF_INTEGER,  1, { 0 } },
-    { (char *)"_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },
-    { (char *)"_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },
+    { "ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },
+    { "AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },
+    { "AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },
+    { "AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },
+    { "CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },
+    { "CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },
+    { "CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },
+    { "CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },
+    { "COMMENT",                 BDF_ATOM,     1, { 0 } },
+    { "COPYRIGHT",               BDF_ATOM,     1, { 0 } },
+    { "DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },
+    { "DESTINATION",             BDF_CARDINAL, 1, { 0 } },
+    { "DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },
+    { "END_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { "FACE_NAME",               BDF_ATOM,     1, { 0 } },
+    { "FAMILY_NAME",             BDF_ATOM,     1, { 0 } },
+    { "FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },
+    { "FONT",                    BDF_ATOM,     1, { 0 } },
+    { "FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },
+    { "FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },
+    { "FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },
+    { "FOUNDRY",                 BDF_ATOM,     1, { 0 } },
+    { "FULL_NAME",               BDF_ATOM,     1, { 0 } },
+    { "ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },
+    { "MAX_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { "MIN_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { "NORM_SPACE",              BDF_INTEGER,  1, { 0 } },
+    { "NOTICE",                  BDF_ATOM,     1, { 0 } },
+    { "PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },
+    { "POINT_SIZE",              BDF_INTEGER,  1, { 0 } },
+    { "QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },
+    { "RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },
+    { "RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },
+    { "RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },
+    { "RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },
+    { "RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },
+    { "RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },
+    { "RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },
+    { "RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },
+    { "RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },
+    { "RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },
+    { "RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },
+    { "RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },
+    { "RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },
+    { "RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },
+    { "RESOLUTION",              BDF_INTEGER,  1, { 0 } },
+    { "RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },
+    { "RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },
+    { "SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },
+    { "SLANT",                   BDF_ATOM,     1, { 0 } },
+    { "SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "SPACING",                 BDF_ATOM,     1, { 0 } },
+    { "STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },
+    { "STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },
+    { "SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },
+    { "SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },
+    { "SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },
+    { "SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },
+    { "SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },
+    { "UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },
+    { "UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },
+    { "WEIGHT",                  BDF_CARDINAL, 1, { 0 } },
+    { "WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },
+    { "X_HEIGHT",                BDF_INTEGER,  1, { 0 } },
+    { "_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },
+    { "_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },
   };
 
   static const unsigned long
-  _num_bdf_properties = sizeof ( _bdf_properties ) /
-                        sizeof ( _bdf_properties[0] );
+  num_bdf_properties_ = sizeof ( bdf_properties_ ) /
+                        sizeof ( bdf_properties_[0] );
 
 
   /* An auxiliary macro to parse properties, to be used in conditionals. */
   /* It behaves like `strncmp' but also tests the following character    */
-  /* whether it is a whitespace or NULL.                                 */
+  /* whether it is a whitespace or null.                                 */
   /* `property' is a constant string of length `n' to compare with.      */
 #define _bdf_strncmp( name, property, n )      \
           ( ft_strncmp( name, property, n ) || \
@@ -186,21 +185,20 @@
                  "Added `FONT_ASCENT %hd'.\n"
 #define ACMSG2   "FONT_DESCENT property missing.  " \
                  "Added `FONT_DESCENT %hd'.\n"
-#define ACMSG3   "Font width != actual width.  Old: %hd New: %hd.\n"
+#define ACMSG3   "Font width != actual width.  Old: %d New: %d.\n"
 #define ACMSG4   "Font left bearing != actual left bearing.  " \
                  "Old: %hd New: %hd.\n"
 #define ACMSG5   "Font ascent != actual ascent.  Old: %hd New: %hd.\n"
-#define ACMSG6   "Font descent != actual descent.  Old: %hd New: %hd.\n"
-#define ACMSG7   "Font height != actual height. Old: %hd New: %hd.\n"
+#define ACMSG6   "Font descent != actual descent.  Old: %d New: %d.\n"
+#define ACMSG7   "Font height != actual height. Old: %d New: %d.\n"
 #define ACMSG8   "Glyph scalable width (SWIDTH) adjustments made.\n"
 #define ACMSG9   "SWIDTH field missing at line %ld.  Set automatically.\n"
 #define ACMSG10  "DWIDTH field missing at line %ld.  Set to glyph width.\n"
 #define ACMSG11  "SIZE bits per pixel field adjusted to %hd.\n"
-#define ACMSG12  "Duplicate encoding %ld (%s) changed to unencoded.\n"
-#define ACMSG13  "Glyph %ld extra rows removed.\n"
-#define ACMSG14  "Glyph %ld extra columns removed.\n"
+#define ACMSG13  "Glyph %lu extra rows removed.\n"
+#define ACMSG14  "Glyph %lu extra columns removed.\n"
 #define ACMSG15  "Incorrect glyph count: %ld indicated but %ld found.\n"
-#define ACMSG16  "Glyph %ld missing columns padded with zero bits.\n"
+#define ACMSG16  "Glyph %lu missing columns padded with zero bits.\n"
 #define ACMSG17  "Adjusting number of glyphs to %ld.\n"
 
   /* Error messages. */
@@ -229,7 +227,7 @@
   /* Function type for parsing lines of a BDF font. */
 
   typedef FT_Error
-  (*_bdf_line_func_t)( char*          line,
+  (*bdf_line_func_t_)( char*          line,
                        unsigned long  linelen,
                        unsigned long  lineno,
                        void*          call_data,
@@ -238,19 +236,19 @@
 
   /* List structure for splitting lines into fields. */
 
-  typedef struct  _bdf_list_t_
+  typedef struct  bdf_list_t__
   {
     char**         field;
     unsigned long  size;
     unsigned long  used;
     FT_Memory      memory;
 
-  } _bdf_list_t;
+  } bdf_list_t_;
 
 
   /* Structure used while loading BDF fonts. */
 
-  typedef struct  _bdf_parse_t_
+  typedef struct  bdf_parse_t__
   {
     unsigned long   flags;
     unsigned long   cnt;
@@ -270,14 +268,12 @@
     bdf_font_t*     font;
     bdf_options_t*  opts;
 
-    unsigned long   have[34816]; /* must be in sync with `nmod' and `umod' */
-                                 /* arrays from `bdf_font_t' structure     */
-    _bdf_list_t     list;
+    bdf_list_t_     list;
 
     FT_Memory       memory;
     unsigned long   size;        /* the stream size */
 
-  } _bdf_parse_t;
+  } bdf_parse_t_;
 
 
 #define setsbit( m, cc ) \
@@ -287,7 +283,7 @@
 
 
   static void
-  _bdf_list_init( _bdf_list_t*  list,
+  bdf_list_init_( bdf_list_t_*  list,
                   FT_Memory     memory )
   {
     FT_ZERO( list );
@@ -296,7 +292,7 @@
 
 
   static void
-  _bdf_list_done( _bdf_list_t*  list )
+  bdf_list_done_( bdf_list_t_*  list )
   {
     FT_Memory  memory = list->memory;
 
@@ -310,15 +306,15 @@
 
 
   static FT_Error
-  _bdf_list_ensure( _bdf_list_t*   list,
-                    unsigned long  num_items ) /* same as _bdf_list_t.used */
+  bdf_list_ensure_( bdf_list_t_*   list,
+                    unsigned long  num_items ) /* same as bdf_list_t_.used */
   {
     FT_Error  error = FT_Err_Ok;
 
 
     if ( num_items > list->size )
     {
-      unsigned long  oldsize = list->size; /* same as _bdf_list_t.size */
+      unsigned long  oldsize = list->size; /* same as bdf_list_t_.size */
       unsigned long  newsize = oldsize + ( oldsize >> 1 ) + 5;
       unsigned long  bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) );
       FT_Memory      memory  = list->memory;
@@ -332,7 +328,7 @@
       else if ( newsize < oldsize || newsize > bigsize )
         newsize = bigsize;
 
-      if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) )
+      if ( FT_QRENEW_ARRAY( list->field, oldsize, newsize ) )
         goto Exit;
 
       list->size = newsize;
@@ -344,13 +340,13 @@
 
 
   static void
-  _bdf_list_shift( _bdf_list_t*   list,
+  bdf_list_shift_( bdf_list_t_*   list,
                    unsigned long  n )
   {
     unsigned long  i, u;
 
 
-    if ( list == 0 || list->used == 0 || n == 0 )
+    if ( list == NULL || list->used == 0 || n == 0 )
       return;
 
     if ( n >= list->used )
@@ -367,11 +363,11 @@
 
   /* An empty string for empty fields. */
 
-  static const char  empty[1] = { 0 };      /* XXX eliminate this */
+  static const char  empty[] = "";      /* XXX eliminate this */
 
 
   static char *
-  _bdf_list_join( _bdf_list_t*    list,
+  bdf_list_join_( bdf_list_t_*    list,
                   int             c,
                   unsigned long  *alen )
   {
@@ -381,7 +377,7 @@
 
     *alen = 0;
 
-    if ( list == 0 || list->used == 0 )
+    if ( list == NULL || list->used == 0 )
       return 0;
 
     dp = list->field[0];
@@ -409,14 +405,15 @@
   /* don't have to check the number of fields in most cases.    */
 
   static FT_Error
-  _bdf_list_split( _bdf_list_t*   list,
-                   char*          separators,
+  bdf_list_split_( bdf_list_t_*   list,
+                   const char*    separators,
                    char*          line,
                    unsigned long  linelen )
   {
     unsigned long  final_empty;
     int            mult;
-    char           *sp, *ep, *end;
+    const char     *sp, *end;
+    char           *ep;
     char           seps[32];
     FT_Error       error = FT_Err_Ok;
 
@@ -439,7 +436,7 @@
     /* In the original code, if the `separators' parameter is NULL or */
     /* empty, the list is split into individual bytes.  We don't need */
     /* this, so an error is signaled.                                 */
-    if ( separators == 0 || *separators == 0 )
+    if ( separators == NULL || *separators == 0 )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
@@ -470,13 +467,13 @@
       /* Resize the list if necessary. */
       if ( list->used == list->size )
       {
-        error = _bdf_list_ensure( list, list->used + 1 );
+        error = bdf_list_ensure_( list, list->used + 1 );
         if ( error )
           goto Exit;
       }
 
       /* Assign the field appropriately. */
-      list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty;
+      list->field[list->used++] = ( ep > sp ) ? (char*)sp : (char*)empty;
 
       sp = ep;
 
@@ -499,7 +496,7 @@
     /* Finally, NULL-terminate the list. */
     if ( list->used + final_empty >= list->size )
     {
-      error = _bdf_list_ensure( list, list->used + final_empty + 1 );
+      error = bdf_list_ensure_( list, list->used + final_empty + 1 );
       if ( error )
         goto Exit;
     }
@@ -507,7 +504,7 @@
     if ( final_empty )
       list->field[list->used++] = (char*)empty;
 
-    list->field[list->used] = 0;
+    list->field[list->used] = NULL;
 
   Exit:
     return error;
@@ -518,12 +515,12 @@
 
 
   static FT_Error
-  _bdf_readstream( FT_Stream         stream,
-                   _bdf_line_func_t  callback,
+  bdf_readstream_( FT_Stream         stream,
+                   bdf_line_func_t_  callback,
                    void*             client_data,
                    unsigned long    *lno )
   {
-    _bdf_line_func_t  cb;
+    bdf_line_func_t_  cb;
     unsigned long     lineno, buf_size;
     int               refill, hold, to_skip;
     ptrdiff_t         bytes, start, end, cursor, avail;
@@ -532,7 +529,7 @@
     FT_Error          error  = FT_Err_Ok;
 
 
-    if ( callback == 0 )
+    if ( callback == NULL )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
@@ -541,7 +538,7 @@
     /* initial size and allocation of the input buffer */
     buf_size = 1024;
 
-    if ( FT_NEW_ARRAY( buf, buf_size ) )
+    if ( FT_QALLOC( buf, buf_size ) )
       goto Exit;
 
     cb      = callback;
@@ -584,8 +581,14 @@
       /* or even resizing it                                       */
       if ( end >= avail )
       {
-        if ( bytes == 0 )  /* last line in file doesn't end in \r or \n */
-          break;           /* ignore it then exit                       */
+        if ( bytes == 0 )
+        {
+          /* last line in file doesn't end in \r or \n; */
+          /* ignore it then exit                        */
+          if ( lineno == 1 )
+            error = FT_THROW( Missing_Startfont_Field );
+          break;
+        }
 
         if ( start == 0 )
         {
@@ -596,16 +599,21 @@
 
           if ( buf_size >= 65536UL )  /* limit ourselves to 64KByte */
           {
-            FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno ));
-            error = FT_THROW( Invalid_Argument );
+            if ( lineno == 1 )
+              error = FT_THROW( Missing_Startfont_Field );
+            else
+            {
+              FT_ERROR(( "bdf_readstream_: " ERRMSG6, lineno ));
+              error = FT_THROW( Invalid_Argument );
+            }
             goto Exit;
           }
 
           new_size = buf_size * 2;
-          if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) )
+          if ( FT_QREALLOC( buf, buf_size, new_size ) )
             goto Exit;
 
-          cursor   = (ptrdiff_t)buf_size;
+          cursor   = avail;
           buf_size = new_size;
         }
         else
@@ -615,7 +623,6 @@
           FT_MEM_MOVE( buf, buf + start, bytes );
 
           cursor = bytes;
-          avail -= bytes;
           start  = 0;
         }
         refill = 1;
@@ -695,12 +702,12 @@
 
   /* Routine to convert a decimal ASCII string to an unsigned long integer. */
   static unsigned long
-  _bdf_atoul( char*  s )
+  bdf_atoul_( const char*  s )
   {
     unsigned long  v;
 
 
-    if ( s == 0 || *s == 0 )
+    if ( s == NULL || *s == 0 )
       return 0;
 
     for ( v = 0; sbitset( ddigits, *s ); s++ )
@@ -720,12 +727,12 @@
 
   /* Routine to convert a decimal ASCII string to a signed long integer. */
   static long
-  _bdf_atol( char*  s )
+  bdf_atol_( const char*  s )
   {
     long  v, neg;
 
 
-    if ( s == 0 || *s == 0 )
+    if ( s == NULL || *s == 0 )
       return 0;
 
     /* Check for a minus sign. */
@@ -753,12 +760,12 @@
 
   /* Routine to convert a decimal ASCII string to an unsigned short integer. */
   static unsigned short
-  _bdf_atous( char*  s )
+  bdf_atous_( const char*  s )
   {
     unsigned short  v;
 
 
-    if ( s == 0 || *s == 0 )
+    if ( s == NULL || *s == 0 )
       return 0;
 
     for ( v = 0; sbitset( ddigits, *s ); s++ )
@@ -778,12 +785,12 @@
 
   /* Routine to convert a decimal ASCII string to a signed short integer. */
   static short
-  _bdf_atos( char*  s )
+  bdf_atos_( const char*  s )
   {
     short  v, neg;
 
 
-    if ( s == 0 || *s == 0 )
+    if ( s == NULL || *s == 0 )
       return 0;
 
     /* Check for a minus. */
@@ -810,7 +817,7 @@
 
 
   /* Routine to compare two glyphs by encoding so they can be sorted. */
-  static int
+  FT_COMPARE_DEF( int )
   by_encoding( const void*  a,
                const void*  b )
   {
@@ -831,7 +838,7 @@
 
 
   static FT_Error
-  bdf_create_property( char*        name,
+  bdf_create_property( const char*  name,
                        int          format,
                        bdf_font_t*  font )
   {
@@ -847,27 +854,27 @@
     if ( ft_hash_str_lookup( name, &(font->proptbl) ) )
       goto Exit;
 
-    if ( FT_RENEW_ARRAY( font->user_props,
-                         font->nuser_props,
-                         font->nuser_props + 1 ) )
+    if ( FT_QRENEW_ARRAY( font->user_props,
+                          font->nuser_props,
+                          font->nuser_props + 1 ) )
       goto Exit;
 
     p = font->user_props + font->nuser_props;
-    FT_ZERO( p );
 
     n = ft_strlen( name ) + 1;
-    if ( n > FT_ULONG_MAX )
+    if ( n > FT_LONG_MAX )
       return FT_THROW( Invalid_Argument );
 
-    if ( FT_NEW_ARRAY( p->name, n ) )
+    if ( FT_QALLOC( p->name, n ) )
       goto Exit;
 
     FT_MEM_COPY( (char *)p->name, name, n );
 
-    p->format  = format;
-    p->builtin = 0;
+    p->format     = format;
+    p->builtin    = 0;
+    p->value.atom = NULL;  /* nothing is ever stored here */
 
-    n = _num_bdf_properties + font->nuser_props;
+    n = num_bdf_properties_ + font->nuser_props;
 
     error = ft_hash_str_insert( p->name, n, &(font->proptbl), memory );
     if ( error )
@@ -887,16 +894,16 @@
     size_t*  propid;
 
 
-    if ( name == 0 || *name == 0 )
+    if ( name == NULL || *name == 0 )
       return 0;
 
     if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL )
       return 0;
 
-    if ( *propid >= _num_bdf_properties )
-      return font->user_props + ( *propid - _num_bdf_properties );
+    if ( *propid >= num_bdf_properties_ )
+      return font->user_props + ( *propid - num_bdf_properties_ );
 
-    return (bdf_property_t*)_bdf_properties + *propid;
+    return (bdf_property_t*)bdf_properties_ + *propid;
   }
 
 
@@ -936,7 +943,7 @@
 
 
   static FT_Error
-  _bdf_add_comment( bdf_font_t*    font,
+  bdf_add_comment_( bdf_font_t*    font,
                     char*          comment,
                     unsigned long  len )
   {
@@ -945,15 +952,15 @@
     FT_Error   error  = FT_Err_Ok;
 
 
-    if ( FT_RENEW_ARRAY( font->comments,
-                         font->comments_len,
-                         font->comments_len + len + 1 ) )
+    if ( FT_QRENEW_ARRAY( font->comments,
+                          font->comments_len,
+                          font->comments_len + len + 1 ) )
       goto Exit;
 
     cp = font->comments + font->comments_len;
 
     FT_MEM_COPY( cp, comment, len );
-    cp[len] = '\n';
+    cp[len] = '\0';
 
     font->comments_len += len + 1;
 
@@ -965,20 +972,20 @@
   /* Set the spacing from the font name if it exists, or set it to the */
   /* default specified in the options.                                 */
   static FT_Error
-  _bdf_set_default_spacing( bdf_font_t*     font,
+  bdf_set_default_spacing_( bdf_font_t*     font,
                             bdf_options_t*  opts,
                             unsigned long   lineno )
   {
     size_t       len;
     char         name[256];
-    _bdf_list_t  list;
+    bdf_list_t_  list;
     FT_Memory    memory;
     FT_Error     error = FT_Err_Ok;
 
     FT_UNUSED( lineno );        /* only used in debug mode */
 
 
-    if ( font == 0 || font->name == 0 || font->name[0] == 0 )
+    if ( font == NULL || font->name == NULL || font->name[0] == 0 )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
@@ -986,7 +993,7 @@
 
     memory = font->memory;
 
-    _bdf_list_init( &list, memory );
+    bdf_list_init_( &list, memory );
 
     font->spacing = opts->font_spacing;
 
@@ -994,14 +1001,14 @@
     /* Limit ourselves to 256 characters in the font name. */
     if ( len >= 256 )
     {
-      FT_ERROR(( "_bdf_set_default_spacing: " ERRMSG7, lineno ));
+      FT_ERROR(( "bdf_set_default_spacing_: " ERRMSG7, lineno ));
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
 
     FT_MEM_COPY( name, font->name, len );
 
-    error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len );
+    error = bdf_list_split_( &list, "-", name, (unsigned long)len );
     if ( error )
       goto Fail;
 
@@ -1025,7 +1032,7 @@
     }
 
   Fail:
-    _bdf_list_done( &list );
+    bdf_list_done_( &list );
 
   Exit:
     return error;
@@ -1035,7 +1042,7 @@
   /* Determine whether the property is an atom or not.  If it is, then */
   /* clean it up so the double quotes are removed if they exist.       */
   static int
-  _bdf_is_atom( char*          line,
+  bdf_is_atom_( char*          line,
                 unsigned long  linelen,
                 char**         name,
                 char**         value,
@@ -1099,8 +1106,8 @@
 
 
   static FT_Error
-  _bdf_add_property( bdf_font_t*    font,
-                     char*          name,
+  bdf_add_property_( bdf_font_t*    font,
+                     const char*    name,
                      char*          value,
                      unsigned long  lineno )
   {
@@ -1134,11 +1141,11 @@
         break;
 
       case BDF_INTEGER:
-        fp->value.l = _bdf_atol( value );
+        fp->value.l = bdf_atol_( value );
         break;
 
       case BDF_CARDINAL:
-        fp->value.ul = _bdf_atoul( value );
+        fp->value.ul = bdf_atoul_( value );
         break;
 
       default:
@@ -1162,28 +1169,18 @@
     /* Allocate another property if this is overflowing. */
     if ( font->props_used == font->props_size )
     {
-      if ( font->props_size == 0 )
-      {
-        if ( FT_NEW_ARRAY( font->props, 1 ) )
-          goto Exit;
-      }
-      else
-      {
-        if ( FT_RENEW_ARRAY( font->props,
-                             font->props_size,
-                             font->props_size + 1 ) )
-          goto Exit;
-      }
+      if ( FT_QRENEW_ARRAY( font->props,
+                            font->props_size,
+                            font->props_size + 1 ) )
+        goto Exit;
 
-      fp = font->props + font->props_size;
-      FT_ZERO( fp );
       font->props_size++;
     }
 
-    if ( *propid >= _num_bdf_properties )
-      prop = font->user_props + ( *propid - _num_bdf_properties );
+    if ( *propid >= num_bdf_properties_ )
+      prop = font->user_props + ( *propid - num_bdf_properties_ );
     else
-      prop = (bdf_property_t*)_bdf_properties + *propid;
+      prop = (bdf_property_t*)bdf_properties_ + *propid;
 
     fp = font->props + font->props_used;
 
@@ -1194,8 +1191,8 @@
     switch ( prop->format )
     {
     case BDF_ATOM:
-      fp->value.atom = 0;
-      if ( value != 0 && value[0] )
+      fp->value.atom = NULL;
+      if ( value && value[0] )
       {
         if ( FT_STRDUP( fp->value.atom, value ) )
           goto Exit;
@@ -1203,11 +1200,11 @@
       break;
 
     case BDF_INTEGER:
-      fp->value.l = _bdf_atol( value );
+      fp->value.l = bdf_atol_( value );
       break;
 
     case BDF_CARDINAL:
-      fp->value.ul = _bdf_atoul( value );
+      fp->value.ul = bdf_atoul_( value );
       break;
     }
 
@@ -1232,7 +1229,7 @@
     /* present, and the SPACING property should override the default       */
     /* spacing.                                                            */
     if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 )
-      font->default_char = fp->value.l;
+      font->default_char = fp->value.ul;
     else if ( _bdf_strncmp( name, "FONT_ASCENT", 11 ) == 0 )
       font->font_ascent = fp->value.l;
     else if ( _bdf_strncmp( name, "FONT_DESCENT", 12 ) == 0 )
@@ -1241,7 +1238,7 @@
     {
       if ( !fp->value.atom )
       {
-        FT_ERROR(( "_bdf_add_property: " ERRMSG8, lineno, "SPACING" ));
+        FT_ERROR(( "bdf_add_property_: " ERRMSG8, lineno, "SPACING" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
@@ -1265,9 +1262,28 @@
   };
 
 
+  static FT_Error
+  bdf_parse_end_( char*          line,
+                  unsigned long  linelen,
+                  unsigned long  lineno,
+                  void*          call_data,
+                  void*          client_data )
+  {
+    /* a no-op; we ignore everything after `ENDFONT' */
+
+    FT_UNUSED( line );
+    FT_UNUSED( linelen );
+    FT_UNUSED( lineno );
+    FT_UNUSED( call_data );
+    FT_UNUSED( client_data );
+
+    return FT_Err_Ok;
+  }
+
+
   /* Actually parse the glyph info and bitmaps. */
   static FT_Error
-  _bdf_parse_glyphs( char*          line,
+  bdf_parse_glyphs_( char*          line,
                      unsigned long  linelen,
                      unsigned long  lineno,
                      void*          call_data,
@@ -1278,18 +1294,19 @@
     unsigned char*     bp;
     unsigned long      i, slen, nibbles;
 
-    _bdf_parse_t*      p;
+    bdf_line_func_t_*  next;
+    bdf_parse_t_*      p;
     bdf_glyph_t*       glyph;
     bdf_font_t*        font;
 
     FT_Memory          memory;
     FT_Error           error = FT_Err_Ok;
 
-    FT_UNUSED( call_data );
     FT_UNUSED( lineno );        /* only used in debug mode */
 
 
-    p = (_bdf_parse_t *)client_data;
+    next = (bdf_line_func_t_ *)call_data;
+    p    = (bdf_parse_t_ *)    client_data;
 
     font   = p->font;
     memory = font->memory;
@@ -1297,15 +1314,18 @@
     /* Check for a comment. */
     if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
     {
-      linelen -= 7;
-
-      s = line + 7;
-      if ( *s != 0 )
+      if ( p->opts->keep_comments )
       {
-        s++;
-        linelen--;
+        linelen -= 7;
+
+        s = line + 7;
+        if ( *s != 0 )
+        {
+          s++;
+          linelen--;
+        }
+        error = bdf_add_comment_( p->font, s, linelen );
       }
-      error = _bdf_add_comment( p->font, s, linelen );
       goto Exit;
     }
 
@@ -1314,21 +1334,21 @@
     {
       if ( _bdf_strncmp( line, "CHARS", 5 ) != 0 )
       {
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "CHARS" ));
         error = FT_THROW( Missing_Chars_Field );
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
-      p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] );
+      p->cnt = font->glyphs_size = bdf_atoul_( p->list.field[1] );
 
       /* We need at least 20 bytes per glyph. */
       if ( p->cnt > p->size / 20 )
       {
         p->cnt = font->glyphs_size = p->size / 20;
-        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG17, p->cnt ));
+        FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG17, p->cnt ));
       }
 
       /* Make sure the number of glyphs is non-zero. */
@@ -1339,7 +1359,7 @@
       /* number of code points available in Unicode).                 */
       if ( p->cnt >= 0x110000UL )
       {
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "CHARS" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG5, lineno, "CHARS" ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
@@ -1358,7 +1378,7 @@
       if ( p->flags & BDF_GLYPH_BITS_ )
       {
         /* Missing ENDCHAR field. */
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "ENDCHAR" ));
         error = FT_THROW( Corrupted_Font_Glyphs );
         goto Exit;
       }
@@ -1370,6 +1390,7 @@
                 by_encoding );
 
       p->flags &= ~BDF_START_;
+      *next     = bdf_parse_end_;
 
       goto Exit;
     }
@@ -1396,7 +1417,7 @@
       if ( p->flags & BDF_GLYPH_BITS_ )
       {
         /* Missing ENDCHAR field. */
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "ENDCHAR" ));
         error = FT_THROW( Missing_Startchar_Field );
         goto Exit;
       }
@@ -1405,22 +1426,22 @@
       /* encoding can be checked for an unencoded character.      */
       FT_FREE( p->glyph_name );
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      _bdf_list_shift( &p->list, 1 );
+      bdf_list_shift_( &p->list, 1 );
 
-      s = _bdf_list_join( &p->list, ' ', &slen );
+      s = bdf_list_join_( &p->list, ' ', &slen );
 
       if ( !s )
       {
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG8, lineno, "STARTCHAR" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG8, lineno, "STARTCHAR" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
 
-      if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) )
+      if ( FT_QALLOC( p->glyph_name, slen + 1 ) )
         goto Exit;
 
       FT_MEM_COPY( p->glyph_name, s, slen + 1 );
@@ -1438,16 +1459,16 @@
       if ( !( p->flags & BDF_GLYPH_ ) )
       {
         /* Missing STARTCHAR field. */
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "STARTCHAR" ));
         error = FT_THROW( Missing_Startchar_Field );
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      p->glyph_enc = _bdf_atol( p->list.field[1] );
+      p->glyph_enc = bdf_atol_( p->list.field[1] );
 
       /* Normalize negative encoding values.  The specification only */
       /* allows -1, but we can be more generous here.                */
@@ -1456,42 +1477,13 @@
 
       /* Check for alternative encoding format. */
       if ( p->glyph_enc == -1 && p->list.used > 2 )
-        p->glyph_enc = _bdf_atol( p->list.field[2] );
+        p->glyph_enc = bdf_atol_( p->list.field[2] );
 
-      if ( p->glyph_enc < -1 )
+      if ( p->glyph_enc < -1 || p->glyph_enc >= 0x110000L )
         p->glyph_enc = -1;
 
       FT_TRACE4(( DBGMSG2, p->glyph_enc ));
 
-      /* Check that the encoding is in the Unicode range because  */
-      /* otherwise p->have (a bitmap with static size) overflows. */
-      if ( p->glyph_enc > 0                                      &&
-           (size_t)p->glyph_enc >= sizeof ( p->have ) /
-                                   sizeof ( unsigned long ) * 32 )
-      {
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "ENCODING" ));
-        error = FT_THROW( Invalid_File_Format );
-        goto Exit;
-      }
-
-      /* Check whether this encoding has already been encountered. */
-      /* If it has then change it to unencoded so it gets added if */
-      /* indicated.                                                */
-      if ( p->glyph_enc >= 0 )
-      {
-        if ( _bdf_glyph_modified( p->have, p->glyph_enc ) )
-        {
-          /* Emit a message saying a glyph has been moved to the */
-          /* unencoded area.                                     */
-          FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12,
-                      p->glyph_enc, p->glyph_name ));
-          p->glyph_enc = -1;
-          font->modified = 1;
-        }
-        else
-          _bdf_set_glyph_modified( p->have, p->glyph_enc );
-      }
-
       if ( p->glyph_enc >= 0 )
       {
         /* Make sure there are enough glyphs allocated in case the */
@@ -1508,7 +1500,7 @@
 
         glyph           = font->glyphs + font->glyphs_used++;
         glyph->name     = p->glyph_name;
-        glyph->encoding = p->glyph_enc;
+        glyph->encoding = (unsigned long)p->glyph_enc;
 
         /* Reset the initial glyph info. */
         p->glyph_name = NULL;
@@ -1517,7 +1509,7 @@
       {
         /* Unencoded glyph.  Check whether it should */
         /* be added or not.                          */
-        if ( p->opts->keep_unencoded != 0 )
+        if ( p->opts->keep_unencoded )
         {
           /* Allocate the next unencoded glyph. */
           if ( font->unencoded_used == font->unencoded_size )
@@ -1532,7 +1524,7 @@
 
           glyph           = font->unencoded + font->unencoded_used;
           glyph->name     = p->glyph_name;
-          glyph->encoding = (long)font->unencoded_used++;
+          glyph->encoding = font->unencoded_used++;
 
           /* Reset the initial glyph info. */
           p->glyph_name = NULL;
@@ -1543,8 +1535,6 @@
           /* kept.                                                */
           FT_FREE( p->glyph_name );
         }
-
-        p->glyph_name = NULL;
       }
 
       /* Clear the flags that might be added when width and height are */
@@ -1574,9 +1564,8 @@
       {
         if ( !( p->flags & BDF_GLYPH_HEIGHT_CHECK_ ) )
         {
-          FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding ));
+          FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG13, glyph->encoding ));
           p->flags |= BDF_GLYPH_HEIGHT_CHECK_;
-          font->modified = 1;
         }
 
         goto Exit;
@@ -1602,9 +1591,8 @@
       if ( i < nibbles                            &&
            !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) )
       {
-        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding ));
+        FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG16, glyph->encoding ));
         p->flags       |= BDF_GLYPH_WIDTH_CHECK_;
-        font->modified  = 1;
       }
 
       /* Remove possible garbage at the right. */
@@ -1617,9 +1605,8 @@
            sbitset( hdigits, line[nibbles] )      &&
            !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) )
       {
-        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding ));
+        FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG14, glyph->encoding ));
         p->flags       |= BDF_GLYPH_WIDTH_CHECK_;
-        font->modified  = 1;
       }
 
       p->row++;
@@ -1629,30 +1616,30 @@
     /* Expect the SWIDTH (scalable width) field next. */
     if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1] );
+      glyph->swidth = bdf_atous_( p->list.field[1] );
       p->flags |= BDF_SWIDTH_;
 
       goto Exit;
     }
 
-    /* Expect the DWIDTH (scalable width) field next. */
+    /* Expect the DWIDTH (device width) field next. */
     if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1] );
+      glyph->dwidth = bdf_atous_( p->list.field[1] );
 
       if ( !( p->flags & BDF_SWIDTH_ ) )
       {
         /* Missing SWIDTH field.  Emit an auto correction message and set */
         /* the scalable width from the device width.                      */
-        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno ));
+        FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG9, lineno ));
 
         glyph->swidth = (unsigned short)FT_MulDiv(
                           glyph->dwidth, 72000L,
@@ -1667,14 +1654,14 @@
     /* Expect the BBX field next. */
     if ( _bdf_strncmp( line, "BBX", 3 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      glyph->bbx.width    = _bdf_atous( p->list.field[1] );
-      glyph->bbx.height   = _bdf_atous( p->list.field[2] );
-      glyph->bbx.x_offset = _bdf_atos( p->list.field[3] );
-      glyph->bbx.y_offset = _bdf_atos( p->list.field[4] );
+      glyph->bbx.width    = bdf_atous_( p->list.field[1] );
+      glyph->bbx.height   = bdf_atous_( p->list.field[2] );
+      glyph->bbx.x_offset = bdf_atos_( p->list.field[3] );
+      glyph->bbx.y_offset = bdf_atos_( p->list.field[4] );
 
       /* Generate the ascent and descent of the character. */
       glyph->bbx.ascent  = (short)( glyph->bbx.height + glyph->bbx.y_offset );
@@ -1695,13 +1682,13 @@
       {
         /* Missing DWIDTH field.  Emit an auto correction message and set */
         /* the device width to the glyph width.                           */
-        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno ));
+        FT_TRACE2(( "bdf_parse_glyphs_: " ACMSG10, lineno ));
         glyph->dwidth = glyph->bbx.width;
       }
 
       /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */
       /* value if necessary.                                            */
-      if ( p->opts->correct_metrics != 0 )
+      if ( p->opts->correct_metrics )
       {
         /* Determine the point size of the glyph. */
         unsigned short  sw = (unsigned short)FT_MulDiv(
@@ -1714,14 +1701,7 @@
         {
           glyph->swidth = sw;
 
-          if ( p->glyph_enc == -1 )
-            _bdf_set_glyph_modified( font->umod,
-                                     font->unencoded_used - 1 );
-          else
-            _bdf_set_glyph_modified( font->nmod, glyph->encoding );
-
           p->flags       |= BDF_SWIDTH_ADJ_;
-          font->modified  = 1;
         }
       }
 
@@ -1738,7 +1718,7 @@
       if ( !( p->flags & BDF_BBX_ ) )
       {
         /* Missing BBX field. */
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "BBX" ));
         error = FT_THROW( Missing_Bbx_Field );
         goto Exit;
       }
@@ -1749,14 +1729,14 @@
       bitmap_size = glyph->bpr * glyph->bbx.height;
       if ( glyph->bpr > 0xFFFFU || bitmap_size > 0xFFFFU )
       {
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG4, lineno ));
         error = FT_THROW( Bbx_Too_Big );
         goto Exit;
       }
       else
         glyph->bytes = (unsigned short)bitmap_size;
 
-      if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) )
+      if ( FT_ALLOC( glyph->bitmap, glyph->bytes ) )
         goto Exit;
 
       p->row    = 0;
@@ -1765,13 +1745,13 @@
       goto Exit;
     }
 
-    FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG9, lineno ));
+    FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG9, lineno ));
     error = FT_THROW( Invalid_File_Format );
     goto Exit;
 
   Missing_Encoding:
     /* Missing ENCODING field. */
-    FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" ));
+    FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG1, lineno, "ENCODING" ));
     error = FT_THROW( Missing_Encoding_Field );
 
   Exit:
@@ -1784,15 +1764,15 @@
 
   /* Load the font properties. */
   static FT_Error
-  _bdf_parse_properties( char*          line,
+  bdf_parse_properties_( char*          line,
                          unsigned long  linelen,
                          unsigned long  lineno,
                          void*          call_data,
                          void*          client_data )
   {
     unsigned long      vlen;
-    _bdf_line_func_t*  next;
-    _bdf_parse_t*      p;
+    bdf_line_func_t_*  next;
+    bdf_parse_t_*      p;
     char*              name;
     char*              value;
     char               nbuf[128];
@@ -1801,8 +1781,8 @@
     FT_UNUSED( lineno );
 
 
-    next = (_bdf_line_func_t *)call_data;
-    p    = (_bdf_parse_t *)    client_data;
+    next = (bdf_line_func_t_ *)call_data;
+    p    = (bdf_parse_t_ *)    client_data;
 
     /* Check for the end of the properties. */
     if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 )
@@ -1817,30 +1797,28 @@
       {
         p->font->font_ascent = p->font->bbx.ascent;
         ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
-        error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
+        error = bdf_add_property_( p->font, "FONT_ASCENT",
                                    nbuf, lineno );
         if ( error )
           goto Exit;
 
-        FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));
-        p->font->modified = 1;
+        FT_TRACE2(( "bdf_parse_properties_: " ACMSG1, p->font->bbx.ascent ));
       }
 
       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 );
-        error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
+        error = bdf_add_property_( p->font, "FONT_DESCENT",
                                    nbuf, lineno );
         if ( error )
           goto Exit;
 
-        FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));
-        p->font->modified = 1;
+        FT_TRACE2(( "bdf_parse_properties_: " ACMSG2, p->font->bbx.descent ));
       }
 
       p->flags &= ~BDF_PROPS_;
-      *next     = _bdf_parse_glyphs;
+      *next     = bdf_parse_glyphs_;
 
       goto Exit;
     }
@@ -1857,27 +1835,27 @@
       value += 7;
       if ( *value )
         *value++ = 0;
-      error = _bdf_add_property( p->font, name, value, lineno );
+      error = bdf_add_property_( p->font, name, value, lineno );
       if ( error )
         goto Exit;
     }
-    else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) )
+    else if ( bdf_is_atom_( line, linelen, &name, &value, p->font ) )
     {
-      error = _bdf_add_property( p->font, name, value, lineno );
+      error = bdf_add_property_( p->font, name, value, lineno );
       if ( error )
         goto Exit;
     }
     else
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
       name = p->list.field[0];
 
-      _bdf_list_shift( &p->list, 1 );
-      value = _bdf_list_join( &p->list, ' ', &vlen );
+      bdf_list_shift_( &p->list, 1 );
+      value = bdf_list_join_( &p->list, ' ', &vlen );
 
-      error = _bdf_add_property( p->font, name, value, lineno );
+      error = bdf_add_property_( p->font, name, value, lineno );
       if ( error )
         goto Exit;
     }
@@ -1889,15 +1867,15 @@
 
   /* Load the font header. */
   static FT_Error
-  _bdf_parse_start( char*          line,
+  bdf_parse_start_( char*          line,
                     unsigned long  linelen,
                     unsigned long  lineno,
                     void*          call_data,
                     void*          client_data )
   {
     unsigned long      slen;
-    _bdf_line_func_t*  next;
-    _bdf_parse_t*      p;
+    bdf_line_func_t_*  next;
+    bdf_parse_t_*      p;
     bdf_font_t*        font;
     char               *s;
 
@@ -1907,8 +1885,8 @@
     FT_UNUSED( lineno );            /* only used in debug mode */
 
 
-    next = (_bdf_line_func_t *)call_data;
-    p    = (_bdf_parse_t *)    client_data;
+    next = (bdf_line_func_t_ *)call_data;
+    p    = (bdf_parse_t_ *)    client_data;
 
     if ( p->font )
       memory = p->font->memory;
@@ -1917,7 +1895,7 @@
     /* comments before the STARTFONT line for some reason.                */
     if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
     {
-      if ( p->opts->keep_comments != 0 && p->font != 0 )
+      if ( p->opts->keep_comments && p->font )
       {
         linelen -= 7;
 
@@ -1927,13 +1905,8 @@
           s++;
           linelen--;
         }
-
-        error = _bdf_add_comment( p->font, s, linelen );
-        if ( error )
-          goto Exit;
-        /* here font is not defined! */
+        error = bdf_add_comment_( p->font, s, linelen );
       }
-
       goto Exit;
     }
 
@@ -1950,14 +1923,13 @@
       }
 
       p->flags = BDF_START_;
-      font = p->font = 0;
+      font = p->font = NULL;
 
       if ( FT_NEW( font ) )
         goto Exit;
       p->font = font;
 
       font->memory = p->memory;
-      p->memory    = 0;
 
       { /* setup */
         size_t           i;
@@ -1967,8 +1939,8 @@
         error = ft_hash_str_init( &(font->proptbl), memory );
         if ( error )
           goto Exit;
-        for ( i = 0, prop = (bdf_property_t*)_bdf_properties;
-              i < _num_bdf_properties; i++, prop++ )
+        for ( i = 0, prop = (bdf_property_t*)bdf_properties_;
+              i < num_bdf_properties_; i++, prop++ )
         {
           error = ft_hash_str_insert( prop->name, i,
                                       &(font->proptbl), memory );
@@ -1977,13 +1949,13 @@
         }
       }
 
-      if ( FT_ALLOC( p->font->internal, sizeof ( FT_HashRec ) ) )
+      if ( FT_QALLOC( p->font->internal, sizeof ( FT_HashRec ) ) )
         goto Exit;
       error = ft_hash_str_init( (FT_Hash)p->font->internal, memory );
       if ( error )
         goto Exit;
       p->font->spacing      = p->opts->font_spacing;
-      p->font->default_char = -1;
+      p->font->default_char = ~0UL;
 
       goto Exit;
     }
@@ -1994,23 +1966,23 @@
       if ( !( p->flags & BDF_FONT_BBX_ ) )
       {
         /* Missing the FONTBOUNDINGBOX field. */
-        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
+        FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
         error = FT_THROW( Missing_Fontboundingbox_Field );
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
       /* at this point, `p->font' can't be NULL */
-      p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1] );
+      p->cnt = p->font->props_size = bdf_atoul_( p->list.field[1] );
       /* We need at least 4 bytes per property. */
       if ( p->cnt > p->size / 4 )
       {
         p->font->props_size = 0;
 
-        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "STARTPROPERTIES" ));
+        FT_ERROR(( "bdf_parse_glyphs_: " ERRMSG5, lineno, "STARTPROPERTIES" ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
@@ -2022,7 +1994,7 @@
       }
 
       p->flags |= BDF_PROPS_;
-      *next     = _bdf_parse_properties;
+      *next     = bdf_parse_properties_;
 
       goto Exit;
     }
@@ -2033,20 +2005,20 @@
       if ( !( p->flags & BDF_SIZE_ ) )
       {
         /* Missing the SIZE field. */
-        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" ));
+        FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "SIZE" ));
         error = FT_THROW( Missing_Size_Field );
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      p->font->bbx.width  = _bdf_atous( p->list.field[1] );
-      p->font->bbx.height = _bdf_atous( p->list.field[2] );
+      p->font->bbx.width  = bdf_atous_( p->list.field[1] );
+      p->font->bbx.height = bdf_atous_( p->list.field[2] );
 
-      p->font->bbx.x_offset = _bdf_atos( p->list.field[3] );
-      p->font->bbx.y_offset = _bdf_atos( p->list.field[4] );
+      p->font->bbx.x_offset = bdf_atos_( p->list.field[3] );
+      p->font->bbx.y_offset = bdf_atos_( p->list.field[4] );
 
       p->font->bbx.ascent  = (short)( p->font->bbx.height +
                                       p->font->bbx.y_offset );
@@ -2061,16 +2033,16 @@
     /* The next thing to check for is the FONT field. */
     if ( _bdf_strncmp( line, "FONT", 4 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
-      _bdf_list_shift( &p->list, 1 );
+      bdf_list_shift_( &p->list, 1 );
 
-      s = _bdf_list_join( &p->list, ' ', &slen );
+      s = bdf_list_join_( &p->list, ' ', &slen );
 
       if ( !s )
       {
-        FT_ERROR(( "_bdf_parse_start: " ERRMSG8, lineno, "FONT" ));
+        FT_ERROR(( "bdf_parse_start_: " ERRMSG8, lineno, "FONT" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
@@ -2078,13 +2050,13 @@
       /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */
       FT_FREE( p->font->name );
 
-      if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) )
+      if ( FT_QALLOC( p->font->name, slen + 1 ) )
         goto Exit;
       FT_MEM_COPY( p->font->name, s, slen + 1 );
 
       /* If the font name is an XLFD name, set the spacing to the one in  */
       /* the font name.  If there is no spacing fall back on the default. */
-      error = _bdf_set_default_spacing( p->font, p->opts, lineno );
+      error = bdf_set_default_spacing_( p->font, p->opts, lineno );
       if ( error )
         goto Exit;
 
@@ -2099,18 +2071,18 @@
       if ( !( p->flags & BDF_FONT_NAME_ ) )
       {
         /* Missing the FONT field. */
-        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" ));
+        FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "FONT" ));
         error = FT_THROW( Missing_Font_Field );
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = bdf_list_split_( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
-      p->font->point_size   = _bdf_atoul( p->list.field[1] );
-      p->font->resolution_x = _bdf_atoul( p->list.field[2] );
-      p->font->resolution_y = _bdf_atoul( p->list.field[3] );
+      p->font->point_size   = bdf_atoul_( p->list.field[1] );
+      p->font->resolution_x = bdf_atoul_( p->list.field[2] );
+      p->font->resolution_y = bdf_atoul_( p->list.field[3] );
 
       /* Check for the bits per pixel field. */
       if ( p->list.used == 5 )
@@ -2118,7 +2090,7 @@
         unsigned short bpp;
 
 
-        bpp = (unsigned short)_bdf_atos( p->list.field[4] );
+        bpp = bdf_atous_( p->list.field[4] );
 
         /* Only values 1, 2, 4, 8 are allowed for greymap fonts. */
         if ( bpp > 4 )
@@ -2131,7 +2103,7 @@
           p->font->bpp = 1;
 
         if ( p->font->bpp != bpp )
-          FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp ));
+          FT_TRACE2(( "bdf_parse_start_: " ACMSG11, p->font->bpp ));
       }
       else
         p->font->bpp = 1;
@@ -2150,7 +2122,7 @@
       if ( !( p->flags & BDF_FONT_BBX_ ) )
       {
         /* Missing the FONTBOUNDINGBOX field. */
-        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
+        FT_ERROR(( "bdf_parse_start_: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
         error = FT_THROW( Missing_Fontboundingbox_Field );
         goto Exit;
       }
@@ -2159,30 +2131,28 @@
       /* for compiling fonts.                                   */
       p->font->font_ascent = p->font->bbx.ascent;
       ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
-      error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
+      error = bdf_add_property_( p->font, "FONT_ASCENT",
                                  nbuf, lineno );
       if ( error )
         goto Exit;
-      FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));
+      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 );
-      error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
+      error = bdf_add_property_( p->font, "FONT_DESCENT",
                                  nbuf, lineno );
       if ( error )
         goto Exit;
-      FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));
+      FT_TRACE2(( "bdf_parse_properties_: " ACMSG2, p->font->bbx.descent ));
 
-      p->font->modified = 1;
-
-      *next = _bdf_parse_glyphs;
+      *next = bdf_parse_glyphs_;
 
       /* A special return value. */
       error = -1;
       goto Exit;
     }
 
-    FT_ERROR(( "_bdf_parse_start: " ERRMSG9, lineno ));
+    FT_ERROR(( "bdf_parse_start_: " ERRMSG9, lineno ));
     error = FT_THROW( Invalid_File_Format );
 
   Exit:
@@ -2199,34 +2169,32 @@
 
   FT_LOCAL_DEF( FT_Error )
   bdf_load_font( FT_Stream       stream,
-                 FT_Memory       extmemory,
+                 FT_Memory       memory,
                  bdf_options_t*  opts,
                  bdf_font_t*    *font )
   {
     unsigned long  lineno = 0; /* make compiler happy */
-    _bdf_parse_t   *p     = NULL;
+    bdf_parse_t_   *p     = NULL;
 
-    FT_Memory  memory = extmemory; /* needed for FT_NEW */
-    FT_Error   error  = FT_Err_Ok;
+    FT_Error  error = FT_Err_Ok;
 
 
     if ( FT_NEW( p ) )
       goto Exit;
 
-    memory    = NULL;
-    p->opts   = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts );
+    p->opts   = (bdf_options_t*)( opts ? opts : &bdf_opts_ );
     p->minlb  = 32767;
     p->size   = stream->size;
-    p->memory = extmemory;  /* only during font creation */
+    p->memory = memory;  /* only during font creation */
 
-    _bdf_list_init( &p->list, extmemory );
+    bdf_list_init_( &p->list, memory );
 
-    error = _bdf_readstream( stream, _bdf_parse_start,
+    error = bdf_readstream_( stream, bdf_parse_start_,
                              (void *)p, &lineno );
     if ( error )
       goto Fail;
 
-    if ( p->font != 0 )
+    if ( p->font )
     {
       /* If the font is not proportional, set the font's monowidth */
       /* field to the width of the font bounding box.              */
@@ -2240,7 +2208,6 @@
       {
         FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt,
                     p->font->glyphs_used + p->font->unencoded_used ));
-        p->font->modified = 1;
       }
 
       /* Once the font has been loaded, adjust the overall font metrics if */
@@ -2253,7 +2220,6 @@
           FT_TRACE2(( "bdf_load_font: " ACMSG3,
                       p->font->bbx.width, p->maxrb - p->minlb ));
           p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb );
-          p->font->modified  = 1;
         }
 
         if ( p->font->bbx.x_offset != p->minlb )
@@ -2261,7 +2227,6 @@
           FT_TRACE2(( "bdf_load_font: " ACMSG4,
                       p->font->bbx.x_offset, p->minlb ));
           p->font->bbx.x_offset = p->minlb;
-          p->font->modified     = 1;
         }
 
         if ( p->font->bbx.ascent != p->maxas )
@@ -2269,7 +2234,6 @@
           FT_TRACE2(( "bdf_load_font: " ACMSG5,
                       p->font->bbx.ascent, p->maxas ));
           p->font->bbx.ascent = p->maxas;
-          p->font->modified   = 1;
         }
 
         if ( p->font->bbx.descent != p->maxds )
@@ -2278,7 +2242,6 @@
                       p->font->bbx.descent, p->maxds ));
           p->font->bbx.descent  = p->maxds;
           p->font->bbx.y_offset = (short)( -p->maxds );
-          p->font->modified     = 1;
         }
 
         if ( p->maxas + p->maxds != p->font->bbx.height )
@@ -2312,22 +2275,7 @@
       }
     }
 
-    if ( p->font != 0 )
-    {
-      /* Make sure the comments are NULL terminated if they exist. */
-      memory = p->font->memory;
-
-      if ( p->font->comments_len > 0 )
-      {
-        if ( FT_RENEW_ARRAY( p->font->comments,
-                             p->font->comments_len,
-                             p->font->comments_len + 1 ) )
-          goto Fail;
-
-        p->font->comments[p->font->comments_len] = 0;
-      }
-    }
-    else if ( !error )
+    if ( !p->font && !error )
       error = FT_THROW( Invalid_File_Format );
 
     *font = p->font;
@@ -2335,9 +2283,7 @@
   Exit:
     if ( p )
     {
-      _bdf_list_done( &p->list );
-
-      memory = extmemory;
+      bdf_list_done_( &p->list );
 
       FT_FREE( p->glyph_name );
       FT_FREE( p );
@@ -2348,8 +2294,6 @@
   Fail:
     bdf_free_font( p->font );
 
-    memory = extmemory;
-
     FT_FREE( p->font );
 
     goto Exit;
@@ -2365,7 +2309,7 @@
     FT_Memory        memory;
 
 
-    if ( font == 0 )
+    if ( font == NULL )
       return;
 
     memory = font->memory;
@@ -2409,27 +2353,13 @@
     FT_FREE( font->glyphs );
     FT_FREE( font->unencoded );
 
-    /* Free up the overflow storage if it was used. */
-    for ( i = 0, glyphs = font->overflow.glyphs;
-          i < font->overflow.glyphs_used; i++, glyphs++ )
-    {
-      FT_FREE( glyphs->name );
-      FT_FREE( glyphs->bitmap );
-    }
-
-    FT_FREE( font->overflow.glyphs );
-
     /* bdf_cleanup */
     ft_hash_str_free( &(font->proptbl), memory );
 
     /* Free up the user defined properties. */
     for ( prop = font->user_props, i = 0;
           i < font->nuser_props; i++, prop++ )
-    {
       FT_FREE( prop->name );
-      if ( prop->format == BDF_ATOM )
-        FT_FREE( prop->value.atom );
-    }
 
     FT_FREE( font->user_props );
 
@@ -2444,7 +2374,7 @@
     size_t*  propid;
 
 
-    if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 )
+    if ( font == NULL || font->props_size == 0 || name == NULL || *name == 0 )
       return 0;
 
     propid = ft_hash_str_lookup( name, (FT_Hash)font->internal );
diff --git a/src/bzip2/Jamfile b/src/bzip2/Jamfile
deleted file mode 100644
index 3548eab..0000000
--- a/src/bzip2/Jamfile
+++ /dev/null
@@ -1,18 +0,0 @@
-# FreeType 2 src/bzip2 Jamfile
-#
-# Copyright 2010-2018 by
-# Joel Klinghed
-#
-# based on `src/lzw/Jamfile'
-#
-# 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) bzip2 ;
-
-Library  $(FT2_LIB) : ftbzip2.c ;
-
-# end of src/bzip2 Jamfile
diff --git a/src/bzip2/ftbzip2.c b/src/bzip2/ftbzip2.c
index 0f6ab15..6cf1067 100644
--- a/src/bzip2/ftbzip2.c
+++ b/src/bzip2/ftbzip2.c
@@ -8,7 +8,7 @@
  * parse compressed PCF fonts, as found with many X11 server
  * distributions.
  *
- * Copyright 2010-2018 by
+ * Copyright (C) 2010-2023 by
  * Joel Klinghed.
  *
  * based on `src/gzip/ftgzip.c'
@@ -22,15 +22,14 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_BZIP2_H
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftbzip2.h>
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -38,7 +37,7 @@
 #define FT_ERR_PREFIX  Bzip2_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Bzip2
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 
 #ifdef FT_CONFIG_OPTION_USE_BZIP2
@@ -58,8 +57,9 @@
   /* it is better to use FreeType memory routines instead of raw
      'malloc/free' */
 
-  typedef void *(* alloc_func)(void*, int, int);
-  typedef void (* free_func)(void*, void*);
+  typedef void* (*alloc_func)( void*, int, int );
+  typedef void  (*free_func) ( void*, void* );
+
 
   static void*
   ft_bzip2_alloc( FT_Memory  memory,
@@ -71,7 +71,7 @@
     FT_Pointer  p  = NULL;
 
 
-    (void)FT_ALLOC( p, sz );
+    FT_MEM_QALLOC( p, sz );
     return p;
   }
 
@@ -103,10 +103,11 @@
 
     FT_Byte    input[FT_BZIP2_BUFFER_SIZE];  /* input read buffer  */
 
-    FT_Byte    buffer[FT_BZIP2_BUFFER_SIZE]; /* output buffer      */
-    FT_ULong   pos;                          /* position in output */
+    FT_Byte    buffer[FT_BZIP2_BUFFER_SIZE]; /* output buffer          */
+    FT_ULong   pos;                          /* position in output     */
     FT_Byte*   cursor;
     FT_Byte*   limit;
+    FT_Bool    reset;                        /* reset before next read */
 
   } FT_BZip2FileRec, *FT_BZip2File;
 
@@ -154,6 +155,7 @@
     zip->limit  = zip->buffer + FT_BZIP2_BUFFER_SIZE;
     zip->cursor = zip->limit;
     zip->pos    = 0;
+    zip->reset  = 0;
 
     /* check .bz2 header */
     {
@@ -229,6 +231,7 @@
       zip->limit  = zip->buffer + FT_BZIP2_BUFFER_SIZE;
       zip->cursor = zip->limit;
       zip->pos    = 0;
+      zip->reset  = 0;
 
       BZ2_bzDecompressInit( bzstream, 0, 0 );
     }
@@ -303,18 +306,23 @@
 
       err = BZ2_bzDecompress( bzstream );
 
-      if ( err == BZ_STREAM_END )
+      if ( err != BZ_OK )
       {
-        zip->limit = (FT_Byte*)bzstream->next_out;
-        if ( zip->limit == zip->cursor )
-          error = FT_THROW( Invalid_Stream_Operation );
-        break;
-      }
-      else if ( err != BZ_OK )
-      {
-        zip->limit = zip->cursor;
-        error      = FT_THROW( Invalid_Stream_Operation );
-        break;
+        zip->reset = 1;
+
+        if ( err == BZ_STREAM_END )
+        {
+          zip->limit = (FT_Byte*)bzstream->next_out;
+          if ( zip->limit == zip->cursor )
+            error = FT_THROW( Invalid_Stream_Operation );
+          break;
+        }
+        else
+        {
+          zip->limit = zip->cursor;
+          error      = FT_THROW( Invalid_Stream_Operation );
+          break;
+        }
       }
     }
 
@@ -328,12 +336,13 @@
                              FT_ULong      count )
   {
     FT_Error  error = FT_Err_Ok;
-    FT_ULong  delta;
 
 
     for (;;)
     {
-      delta = (FT_ULong)( zip->limit - zip->cursor );
+      FT_ULong  delta = (FT_ULong)( zip->limit - zip->cursor );
+
+
       if ( delta >= count )
         delta = count;
 
@@ -363,9 +372,9 @@
     FT_Error  error;
 
 
-    /* Reset inflate stream if we're seeking backwards.        */
-    /* Yes, that is not too efficient, but it saves memory :-) */
-    if ( pos < zip->pos )
+    /* Reset inflate stream if seeking backwards or bzip reported an error. */
+    /* Yes, that is not too efficient, but it saves memory :-)              */
+    if ( pos < zip->pos || zip->reset )
     {
       error = ft_bzip2_file_reset( zip );
       if ( error )
@@ -495,7 +504,7 @@
 
     stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
     stream->pos   = 0;
-    stream->base  = 0;
+    stream->base  = NULL;
     stream->read  = ft_bzip2_stream_io;
     stream->close = ft_bzip2_stream_close;
 
diff --git a/src/bzip2/rules.mk b/src/bzip2/rules.mk
index 95954d7..f4d3733 100644
--- a/src/bzip2/rules.mk
+++ b/src/bzip2/rules.mk
@@ -2,7 +2,7 @@
 # FreeType 2 BZIP2 support configuration rules
 #
 
-# Copyright 2010-2018 by
+# Copyright (C) 2010-2023 by
 # Joel Klinghed.
 #
 # based on `src/lzw/rules.mk'
diff --git a/src/cache/Jamfile b/src/cache/Jamfile
deleted file mode 100644
index 53f4c7b..0000000
--- a/src/cache/Jamfile
+++ /dev/null
@@ -1,37 +0,0 @@
-# FreeType 2 src/cache Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) cache ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = ftcbasic
-               ftccache
-               ftcglyph
-               ftcimage
-               ftcmanag
-               ftccmap
-               ftcmru
-               ftcsbits
-               ;
-  }
-  else
-  {
-    _sources = ftcache ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/cache Jamfile
diff --git a/src/cache/ftcache.c b/src/cache/ftcache.c
index fb78b81..1af2e67 100644
--- a/src/cache/ftcache.c
+++ b/src/cache/ftcache.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType Caching sub-system (body only).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "ftcbasic.c"
 #include "ftccache.c"
diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
index f2b75ee..4c6d41b 100644
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType basic cache interface (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_CACHE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftcache.h>
 #include "ftcglyph.h"
 #include "ftcimage.h"
 #include "ftcsbits.h"
@@ -27,7 +26,8 @@
 #include "ftccback.h"
 #include "ftcerror.h"
 
-#define FT_COMPONENT  trace_cache
+#undef  FT_COMPONENT
+#define FT_COMPONENT  cache
 
 
   /*
@@ -109,13 +109,18 @@
     if ( error || !face )
       return result;
 
+#ifdef FT_DEBUG_LEVEL_TRACE
     if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
+    {
       FT_TRACE1(( "ftc_basic_family_get_count:"
-                  " too large number of glyphs in this face, truncated\n",
+                  " the number of glyphs in this face is %ld,\n",
                   face->num_glyphs ));
+      FT_TRACE1(( "                           "
+                  " which is too much and thus truncated\n" ));
+    }
+#endif
 
-    if ( !error )
-      result = (FT_UInt)face->num_glyphs;
+    result = (FT_UInt)face->num_glyphs;
 
     return result;
   }
@@ -177,7 +182,8 @@
       if ( !error )
       {
         if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
-             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
+             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ||
+             face->glyph->format == FT_GLYPH_FORMAT_SVG     )
         {
           /* ok, copy it */
           FT_Glyph  glyph;
@@ -313,7 +319,7 @@
 #if 0xFFFFFFFFUL > FT_UINT_MAX
     if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
       FT_TRACE1(( "FTC_ImageCache_Lookup:"
-                  " higher bits in load_flags 0x%x are dropped\n",
+                  " higher bits in load_flags 0x%lx are dropped\n",
                   (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
 #endif
 
@@ -394,7 +400,7 @@
 #if FT_ULONG_MAX > FT_UINT_MAX
     if ( load_flags > FT_UINT_MAX )
       FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
-                  " higher bits in load_flags 0x%x are dropped\n",
+                  " higher bits in load_flags 0x%lx are dropped\n",
                   load_flags & ~((FT_ULong)FT_UINT_MAX) ));
 #endif
 
@@ -511,7 +517,7 @@
 #if 0xFFFFFFFFUL > FT_UINT_MAX
     if ( (type->flags & (FT_ULong)FT_UINT_MAX) )
       FT_TRACE1(( "FTC_ImageCache_Lookup:"
-                  " higher bits in load_flags 0x%x are dropped\n",
+                  " higher bits in load_flags 0x%lx are dropped\n",
                   (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
 #endif
 
@@ -594,7 +600,7 @@
 #if FT_ULONG_MAX > FT_UINT_MAX
     if ( load_flags > FT_UINT_MAX )
       FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
-                  " higher bits in load_flags 0x%x are dropped\n",
+                  " higher bits in load_flags 0x%lx are dropped\n",
                   load_flags & ~((FT_ULong)FT_UINT_MAX) ));
 #endif
 
diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c
index a9aa5d4..d54e68c 100644
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType internal cache interface (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,16 +16,15 @@
  */
 
 
-#include <ft2build.h>
 #include "ftcmanag.h"
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "ftccback.h"
 #include "ftcerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cache
+#define FT_COMPONENT  cache
 
 
 #define FTC_HASH_MAX_LOAD  2
@@ -91,15 +90,14 @@
   ftc_get_top_node_for_hash( FTC_Cache  cache,
                              FT_Offset  hash )
   {
-    FTC_Node*  pnode;
     FT_Offset  idx;
 
 
     idx = hash & cache->mask;
     if ( idx < cache->p )
       idx = hash & ( 2 * cache->mask + 1 );
-    pnode = cache->buckets + idx;
-    return pnode;
+
+    return cache->buckets + idx;
   }
 
 #endif /* !FTC_INLINE */
@@ -120,7 +118,7 @@
       FT_UFast  count = mask + p + 1;    /* number of buckets */
 
 
-      /* do we need to shrink the buckets array? */
+      /* do we need to expand the buckets array? */
       if ( cache->slack < 0 )
       {
         FTC_Node  new_list = NULL;
@@ -173,7 +171,7 @@
           cache->p = p + 1;
       }
 
-      /* do we need to expand the buckets array? */
+      /* do we need to shrink the buckets array? */
       else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
       {
         FT_UFast   old_index = p + mask;
@@ -190,7 +188,7 @@
 
 
           /* if we can't shrink the array, leave immediately */
-          if ( FT_RENEW_ARRAY( cache->buckets,
+          if ( FT_QRENEW_ARRAY( cache->buckets,
                                ( mask + 1 ) * 2, mask + 1 ) )
             break;
 
@@ -309,7 +307,7 @@
 #if 0
     /* check, just in case of general corruption :-) */
     if ( manager->num_nodes == 0 )
-      FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n",
+      FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%u)\n",
                   manager->num_nodes ));
 #endif
   }
@@ -342,7 +340,7 @@
     cache->mask  = FTC_HASH_INITIAL_SIZE - 1;
     cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
 
-    (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );
+    FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );
     return error;
   }
 
@@ -361,7 +359,7 @@
 
       for ( i = 0; i < count; i++ )
       {
-        FTC_Node  *pnode = cache->buckets + i, next, node = *pnode;
+        FTC_Node  node = cache->buckets[i], next;
 
 
         while ( node )
@@ -418,7 +416,7 @@
                  FTC_Node   node )
   {
     node->hash        = hash;
-    node->cache_index = (FT_UInt16)cache->index;
+    node->cache_index = (FT_UShort)cache->index;
     node->ref_count   = 0;
 
     ftc_node_hash_link( node, cache );
@@ -460,7 +458,7 @@
     {
       error = cache->clazz.node_new( &node, query, cache );
     }
-    FTC_CACHE_TRYLOOP_END( NULL );
+    FTC_CACHE_TRYLOOP_END( NULL )
 
     if ( error )
       node = NULL;
@@ -529,7 +527,7 @@
           goto NewNode;
         }
         else
-          pnode = &((*pnode)->link);
+          pnode = &(*pnode)->link;
       }
     }
 
@@ -572,8 +570,7 @@
     count = cache->p + cache->mask + 1;
     for ( i = 0; i < count; i++ )
     {
-      FTC_Node*  bucket = cache->buckets + i;
-      FTC_Node*  pnode  = bucket;
+      FTC_Node*  pnode = cache->buckets + i;
 
 
       for (;;)
diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h
index c1f8c29..23bcb65 100644
--- a/src/cache/ftccache.h
+++ b/src/cache/ftccache.h
@@ -4,7 +4,7 @@
  *
  *   FreeType internal cache interface (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef FTCCACHE_H_
 #define FTCCACHE_H_
 
-
+#include <freetype/internal/compiler-macros.h>
 #include "ftcmru.h"
 
 FT_BEGIN_HEADER
@@ -210,7 +210,7 @@
 #define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
   FT_BEGIN_STMNT                                                         \
     FTC_Node             *_bucket, *_pnode, _node;                       \
-    FTC_Cache             _cache   = FTC_CACHE(cache);                   \
+    FTC_Cache             _cache   = FTC_CACHE( cache );                 \
     FT_Offset             _hash    = (FT_Offset)(hash);                  \
     FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);    \
     FT_Bool               _list_changed = FALSE;                         \
@@ -251,7 +251,7 @@
           goto NewNode_;                                                 \
         }                                                                \
         else                                                             \
-          _pnode = &((*_pnode)->link);                                   \
+          _pnode = &(*_pnode)->link;                                     \
       }                                                                  \
     }                                                                    \
                                                                          \
diff --git a/src/cache/ftccback.h b/src/cache/ftccback.h
index 1e414aa..5f9db21 100644
--- a/src/cache/ftccback.h
+++ b/src/cache/ftccback.h
@@ -4,7 +4,7 @@
  *
  *   Callback functions of the caching sub-system (specification only).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,14 +18,14 @@
 #ifndef FTCCBACK_H_
 #define FTCCBACK_H_
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcmru.h"
 #include "ftcimage.h"
 #include "ftcmanag.h"
 #include "ftcglyph.h"
 #include "ftcsbits.h"
 
+FT_BEGIN_HEADER
 
   FT_LOCAL( void )
   ftc_inode_free( FTC_Node   inode,
@@ -85,6 +85,7 @@
   ftc_node_destroy( FTC_Node     node,
                     FTC_Manager  manager );
 
+FT_END_HEADER
 
 #endif /* FTCCBACK_H_ */
 
diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c
index 47b8b76..84f22a6 100644
--- a/src/cache/ftccmap.c
+++ b/src/cache/ftccmap.c
@@ -4,7 +4,7 @@
  *
  *   FreeType CharMap cache (body)
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,19 +16,18 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_CACHE_H
+#include <freetype/freetype.h>
+#include <freetype/ftcache.h>
 #include "ftcmanag.h"
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "ftccback.h"
 #include "ftcerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cache
+#define FT_COMPONENT  cache
 
 
   /**************************************************************************
@@ -117,7 +116,7 @@
     FT_UInt        nn;
 
 
-    if ( !FT_NEW( node ) )
+    if ( !FT_QNEW( node ) )
     {
       node->face_id    = query->face_id;
       node->cmap_index = query->cmap_index;
@@ -274,12 +273,11 @@
     if ( error )
       goto Exit;
 
-    FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
-                FTC_CMAP_INDICES_MAX );
+    FT_ASSERT( char_code - FTC_CMAP_NODE( node )->first <
+               FTC_CMAP_INDICES_MAX );
 
     /* something rotten can happen with rogue clients */
-    if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
-                    FTC_CMAP_INDICES_MAX ) )
+    if ( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX )
       return 0; /* XXX: should return appropriate error */
 
     gindex = FTC_CMAP_NODE( node )->indices[char_code -
@@ -297,21 +295,19 @@
       if ( error )
         goto Exit;
 
-      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
+      if ( cmap_index < face->num_charmaps )
       {
-        FT_CharMap  old, cmap  = NULL;
+        FT_CharMap  old  = face->charmap;
+        FT_CharMap  cmap = face->charmaps[cmap_index];
 
 
-        old  = face->charmap;
-        cmap = face->charmaps[cmap_index];
-
-        if ( old != cmap && !no_cmap_change )
-          FT_Set_Charmap( face, cmap );
+        if ( !no_cmap_change )
+          face->charmap = cmap;
 
         gindex = FT_Get_Char_Index( face, char_code );
 
-        if ( old != cmap && !no_cmap_change )
-          FT_Set_Charmap( face, old );
+        if ( !no_cmap_change )
+          face->charmap = old;
       }
 
       FTC_CMAP_NODE( node )->indices[char_code -
diff --git a/src/cache/ftcerror.h b/src/cache/ftcerror.h
index 6ed9e9e..dc1a620 100644
--- a/src/cache/ftcerror.h
+++ b/src/cache/ftcerror.h
@@ -4,7 +4,7 @@
  *
  *   Caching sub-system error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef FTCERROR_H_
 #define FTCERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  FTC_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Cache
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* FTCERROR_H_ */
 
diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c
index 1b86429..b3fb2f2 100644
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -4,7 +4,7 @@
  *
  *   FreeType Glyph Image (FT_Glyph) cache (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_CACHE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftcache.h>
 #include "ftcglyph.h"
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #include "ftccback.h"
 #include "ftcerror.h"
diff --git a/src/cache/ftcglyph.h b/src/cache/ftcglyph.h
index 234ec89..728d4db 100644
--- a/src/cache/ftcglyph.h
+++ b/src/cache/ftcglyph.h
@@ -4,7 +4,7 @@
  *
  *   FreeType abstract glyph cache (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -117,7 +117,6 @@
 #define FTCGLYPH_H_
 
 
-#include <ft2build.h>
 #include "ftcmanag.h"
 
 
@@ -141,8 +140,8 @@
 
   } FTC_FamilyRec, *FTC_Family;
 
-#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
-#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
+#define  FTC_FAMILY( x )    ( (FTC_Family)(x) )
+#define  FTC_FAMILY_P( x )  ( (FTC_Family*)(x) )
 
 
   typedef struct  FTC_GNodeRec_
@@ -246,7 +245,7 @@
 #define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))
 
 #define FTC_CACHE_GCACHE_CLASS( x ) \
-          FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
+          FTC_GCACHE_CLASS( FTC_CACHE( x )->org_class )
 #define FTC_CACHE_FAMILY_CLASS( x ) \
           ( (FTC_MruListClass)FTC_CACHE_GCACHE_CLASS( x )->family_class )
 
diff --git a/src/cache/ftcimage.c b/src/cache/ftcimage.c
index 597e341..428e5e1 100644
--- a/src/cache/ftcimage.c
+++ b/src/cache/ftcimage.c
@@ -4,7 +4,7 @@
  *
  *   FreeType Image cache (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcimage.h"
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftobjs.h>
 
 #include "ftccback.h"
 #include "ftcerror.h"
@@ -65,7 +64,7 @@
     FTC_INode  inode  = NULL;
 
 
-    if ( !FT_NEW( inode ) )
+    if ( !FT_QNEW( inode ) )
     {
       FTC_GNode         gnode  = FTC_GNODE( inode );
       FTC_Family        family = gquery->family;
@@ -75,6 +74,7 @@
 
       /* initialize its inner fields */
       FTC_GNode_Init( gnode, gindex, family );
+      inode->glyph = NULL;
 
       /* we will now load the glyph image */
       error = clazz->family_load_glyph( family, gindex, cache,
diff --git a/src/cache/ftcimage.h b/src/cache/ftcimage.h
index ad47f8d..d2a807f 100644
--- a/src/cache/ftcimage.h
+++ b/src/cache/ftcimage.h
@@ -4,7 +4,7 @@
  *
  *   FreeType Generic Image cache (specification)
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -36,8 +36,7 @@
 #define FTCIMAGE_H_
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcglyph.h"
 
 FT_BEGIN_HEADER
@@ -52,8 +51,8 @@
   } FTC_INodeRec, *FTC_INode;
 
 #define FTC_INODE( x )         ( (FTC_INode)( x ) )
-#define FTC_INODE_GINDEX( x )  FTC_GNODE(x)->gindex
-#define FTC_INODE_FAMILY( x )  FTC_GNODE(x)->family
+#define FTC_INODE_GINDEX( x )  FTC_GNODE( x )->gindex
+#define FTC_INODE_FAMILY( x )  FTC_GNODE( x )->family
 
   typedef FT_Error
   (*FTC_IFamily_LoadGlyphFunc)( FTC_Family  family,
@@ -73,7 +72,7 @@
 #define FTC_IFAMILY_CLASS( x )  ((FTC_IFamilyClass)(x))
 
 #define FTC_CACHE_IFAMILY_CLASS( x ) \
-          FTC_IFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS(x)->family_class )
+          FTC_IFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class )
 
 
   /* can be used as a @FTC_Node_FreeFunc */
diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c
index 9be1773..6c84339 100644
--- a/src/cache/ftcmanag.c
+++ b/src/cache/ftcmanag.c
@@ -4,7 +4,7 @@
  *
  *   FreeType Cache Manager (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,19 +16,18 @@
  */
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcmanag.h"
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_SIZES_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftsizes.h>
 
 #include "ftccback.h"
 #include "ftcerror.h"
 
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cache
+#define FT_COMPONENT  cache
 
 
   static FT_Error
@@ -358,7 +357,7 @@
   {
     FT_Error     error;
     FT_Memory    memory;
-    FTC_Manager  manager = 0;
+    FTC_Manager  manager = NULL;
 
 
     if ( !library )
@@ -369,7 +368,7 @@
 
     memory = library->memory;
 
-    if ( FT_NEW( manager ) )
+    if ( FT_QNEW( manager ) )
       goto Exit;
 
     if ( max_faces == 0 )
@@ -384,6 +383,7 @@
     manager->library      = library;
     manager->memory       = memory;
     manager->max_weight   = max_bytes;
+    manager->cur_weight   = 0;
 
     manager->request_face = requester;
     manager->request_data = req_data;
@@ -400,6 +400,10 @@
                       manager,
                       memory );
 
+    manager->nodes_list = NULL;
+    manager->num_nodes  = 0;
+    manager->num_caches = 0;
+
     *amanager = manager;
 
   Exit:
@@ -485,8 +489,8 @@
         FTC_Cache  cache = manager->caches[node->cache_index];
 
 
-        if ( (FT_UInt)node->cache_index >= manager->num_caches )
-          FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n",
+        if ( node->cache_index >= manager->num_caches )
+          FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %hu\n",
                       node->cache_index ));
         else
           weight += cache->clazz.node_weight( node, cache );
@@ -516,7 +520,7 @@
 
       if ( count != manager->num_nodes )
         FT_TRACE0(( "FTC_Manager_Check:"
-                    " invalid cache node count %d instead of %d\n",
+                    " invalid cache node count %u instead of %u\n",
                     manager->num_nodes, count ));
     }
   }
@@ -544,7 +548,7 @@
 #ifdef FT_DEBUG_ERROR
     FTC_Manager_Check( manager );
 
-    FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n",
+    FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %u\n",
                 manager->cur_weight, manager->max_weight,
                 manager->num_nodes ));
 #endif
@@ -594,7 +598,7 @@
         goto Exit;
       }
 
-      if ( !FT_ALLOC( cache, clazz->cache_size ) )
+      if ( !FT_QALLOC( cache, clazz->cache_size ) )
       {
         cache->manager   = manager;
         cache->memory    = memory;
@@ -690,9 +694,9 @@
   FTC_Node_Unref( FTC_Node     node,
                   FTC_Manager  manager )
   {
-    if ( node                                             &&
-         manager                                          &&
-         (FT_UInt)node->cache_index < manager->num_caches )
+    if ( node                                    &&
+         manager                                 &&
+         node->cache_index < manager->num_caches )
       node->ref_count--;
   }
 
diff --git a/src/cache/ftcmanag.h b/src/cache/ftcmanag.h
index 8d0a1e1..5b30929 100644
--- a/src/cache/ftcmanag.h
+++ b/src/cache/ftcmanag.h
@@ -4,7 +4,7 @@
  *
  *   FreeType Cache Manager (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -63,8 +63,7 @@
 #define FTCMANAG_H_
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcmru.h"
 #include "ftccache.h"
 
diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c
index c704f4e..6722703 100644
--- a/src/cache/ftcmru.c
+++ b/src/cache/ftcmru.c
@@ -4,7 +4,7 @@
  *
  *   FreeType MRU support (body).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcmru.h"
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "ftcerror.h"
 
@@ -263,6 +262,8 @@
       if ( list->clazz.node_done )
         list->clazz.node_done( node, list->data );
     }
+
+    /* zero new node in case of node_init failure */
     else if ( FT_ALLOC( node, list->clazz.node_size ) )
       goto Exit;
 
diff --git a/src/cache/ftcmru.h b/src/cache/ftcmru.h
index 936c66e..45e5249 100644
--- a/src/cache/ftcmru.h
+++ b/src/cache/ftcmru.h
@@ -4,7 +4,7 @@
  *
  *   Simple MRU list-cache (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -44,8 +44,8 @@
 #define FTCMRU_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
+#include <freetype/internal/compiler-macros.h>
 
 #ifdef FREETYPE_H
 #error "freetype.h of FreeType 1 has been loaded!"
diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c
index c802bf0..ee9dab2 100644
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -4,7 +4,7 @@
  *
  *   FreeType sbits manager (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,18 +16,17 @@
  */
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcsbits.h"
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_ERRORS_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/fterrors.h>
 
 #include "ftccback.h"
 #include "ftcerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cache
+#define FT_COMPONENT  cache
 
 
   /*************************************************************************/
@@ -53,10 +52,8 @@
       pitch = -pitch;
 
     size = (FT_ULong)pitch * bitmap->rows;
-    if ( !size )
-      return FT_Err_Ok;
 
-    if ( !FT_ALLOC( sbit->buffer, size ) )
+    if ( !FT_QALLOC( sbit->buffer, size ) )
       FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );
 
     return error;
@@ -109,13 +106,12 @@
     FT_Error          error;
     FTC_GNode         gnode  = FTC_GNODE( snode );
     FTC_Family        family = gnode->family;
-    FT_Memory         memory = manager->memory;
     FT_Face           face;
     FTC_SBit          sbit;
     FTC_SFamilyClass  clazz;
 
 
-    if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count )
+    if ( gindex - gnode->gindex >= snode->count )
     {
       FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
       return FT_THROW( Invalid_Argument );
@@ -124,8 +120,6 @@
     sbit  = snode->sbits + ( gindex - gnode->gindex );
     clazz = (FTC_SFamilyClass)family->clazz;
 
-    sbit->buffer = 0;
-
     error = clazz->family_load_glyph( family, gindex, manager, &face );
     if ( error )
       goto BadGlyph;
@@ -144,12 +138,13 @@
         goto BadGlyph;
       }
 
-      /* Check whether our values fit into 8-bit containers!    */
+      /* Check whether our values fit into 8/16-bit containers! */
       /* If this is not the case, our bitmap is too large       */
       /* and we will leave it as `missing' with sbit.buffer = 0 */
 
 #define CHECK_CHAR( d )  ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d )
 #define CHECK_BYTE( d )  ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d )
+#define CHECK_SHRT( d )  ( temp = (FT_Short)d, (FT_Int)temp == (FT_Int) d )
 
       /* horizontal advance in pixels */
       xadvance = ( slot->advance.x + 32 ) >> 6;
@@ -157,7 +152,7 @@
 
       if ( !CHECK_BYTE( bitmap->rows  )     ||
            !CHECK_BYTE( bitmap->width )     ||
-           !CHECK_CHAR( bitmap->pitch )     ||
+           !CHECK_SHRT( bitmap->pitch )     ||
            !CHECK_CHAR( slot->bitmap_left ) ||
            !CHECK_CHAR( slot->bitmap_top  ) ||
            !CHECK_CHAR( xadvance )          ||
@@ -170,16 +165,25 @@
 
       sbit->width     = (FT_Byte)bitmap->width;
       sbit->height    = (FT_Byte)bitmap->rows;
-      sbit->pitch     = (FT_Char)bitmap->pitch;
+      sbit->pitch     = (FT_Short)bitmap->pitch;
       sbit->left      = (FT_Char)slot->bitmap_left;
       sbit->top       = (FT_Char)slot->bitmap_top;
       sbit->xadvance  = (FT_Char)xadvance;
       sbit->yadvance  = (FT_Char)yadvance;
       sbit->format    = (FT_Byte)bitmap->pixel_mode;
-      sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1);
+      sbit->max_grays = (FT_Byte)( bitmap->num_grays - 1 );
 
-      /* copy the bitmap into a new buffer -- ignore error */
-      error = ftc_sbit_copy_bitmap( sbit, bitmap, memory );
+      if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+      {
+        /* take the bitmap ownership */
+        sbit->buffer = bitmap->buffer;
+        slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+      }
+      else
+      {
+        /* copy the bitmap into a new buffer -- ignore error */
+        error = ftc_sbit_copy_bitmap( sbit, bitmap, manager->memory );
+      }
 
       /* now, compute size */
       if ( asize )
@@ -229,7 +233,7 @@
       goto Exit;
     }
 
-    if ( !FT_NEW( snode ) )
+    if ( !FT_QNEW( snode ) )
     {
       FT_UInt  count, start;
 
@@ -244,7 +248,9 @@
       snode->count = count;
       for ( node_count = 0; node_count < count; node_count++ )
       {
-        snode->sbits[node_count].width = 255;
+        snode->sbits[node_count].width  = 255;
+        snode->sbits[node_count].height = 0;
+        snode->sbits[node_count].buffer = NULL;
       }
 
       error = ftc_snode_load( snode,
@@ -338,8 +344,8 @@
 
     if (list_changed)
       *list_changed = FALSE;
-    result = FT_BOOL( gnode->family == gquery->family                    &&
-                      (FT_UInt)( gindex - gnode->gindex ) < snode->count );
+    result = FT_BOOL( gnode->family == gquery->family       &&
+                      gindex - gnode->gindex < snode->count );
     if ( result )
     {
       /* check if we need to load the glyph bitmap now */
@@ -391,7 +397,7 @@
         {
           error = ftc_snode_load( snode, cache->manager, gindex, &size );
         }
-        FTC_CACHE_TRYLOOP_END( list_changed );
+        FTC_CACHE_TRYLOOP_END( list_changed )
 
         ftcsnode->ref_count--;  /* unlock the node */
 
diff --git a/src/cache/ftcsbits.h b/src/cache/ftcsbits.h
index e698e35..3473923 100644
--- a/src/cache/ftcsbits.h
+++ b/src/cache/ftcsbits.h
@@ -4,7 +4,7 @@
  *
  *   A small-bitmap cache (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTCSBITS_H_
 
 
-#include <ft2build.h>
-#include FT_CACHE_H
+#include <freetype/ftcache.h>
 #include "ftcglyph.h"
 
 
@@ -62,7 +61,7 @@
 
   typedef const FTC_SFamilyClassRec*  FTC_SFamilyClass;
 
-#define FTC_SFAMILY_CLASS( x )  ((FTC_SFamilyClass)(x))
+#define FTC_SFAMILY_CLASS( x )  ( (FTC_SFamilyClass)(x) )
 
 #define FTC_CACHE_SFAMILY_CLASS( x )  \
           FTC_SFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class )
diff --git a/src/cache/rules.mk b/src/cache/rules.mk
index 5589359..82b39aa 100644
--- a/src/cache/rules.mk
+++ b/src/cache/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2000-2018 by
+# Copyright (C) 2000-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -15,7 +15,7 @@
 
 # Cache driver directory
 #
-CACHE_DIR   := $(SRC_DIR)/cache
+CACHE_DIR := $(SRC_DIR)/cache
 
 
 # compilation flags for the driver
diff --git a/src/cff/Jamfile b/src/cff/Jamfile
deleted file mode 100644
index 53c904f..0000000
--- a/src/cff/Jamfile
+++ /dev/null
@@ -1,36 +0,0 @@
-# FreeType 2 src/cff Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) cff ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = cffcmap
-               cffdrivr
-               cffgload
-               cffload
-               cffobjs
-               cffparse
-               cffpic
-               ;
-  }
-  else
-  {
-    _sources = cff ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/cff Jamfile
diff --git a/src/cff/cff.c b/src/cff/cff.c
index 6c7e2c9..b486c38 100644
--- a/src/cff/cff.c
+++ b/src/cff/cff.c
@@ -4,7 +4,7 @@
  *
  *   FreeType OpenType driver component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "cffcmap.c"
 #include "cffdrivr.c"
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index f7316e1..6ed3143 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
  *
  *   CFF character mapping table (cmap) support (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,8 +16,7 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 #include "cffcmap.h"
 #include "cffload.h"
 
@@ -82,7 +81,7 @@
 
     if ( char_code < 255 )
     {
-      FT_UInt  code = (FT_UInt)(char_code + 1);
+      FT_UInt  code = (FT_UInt)( char_code + 1 );
 
 
       for (;;)
@@ -161,6 +160,9 @@
     if ( !charset->sids )
       return FT_THROW( No_Unicode_Glyph_Name );
 
+    if ( !psnames->unicodes_init )
+      return FT_THROW( Unimplemented_Feature );
+
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    cff->num_glyphs,
diff --git a/src/cff/cffcmap.h b/src/cff/cffcmap.h
index 5cf86ac..b2afc2f 100644
--- a/src/cff/cffcmap.h
+++ b/src/cff/cffcmap.h
@@ -4,7 +4,7 @@
  *
  *   CFF character mapping table (cmap) support (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,7 @@
 #ifndef CFFCMAP_H_
 #define CFFCMAP_H_
 
-#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+#include <freetype/internal/cffotypes.h>
 
 FT_BEGIN_HEADER
 
@@ -43,7 +43,7 @@
   } CFF_CMapStdRec;
 
 
-  FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec)
+  FT_DECLARE_CMAP_CLASS( cff_cmap_encoding_class_rec )
 
 
   /*************************************************************************/
@@ -56,7 +56,7 @@
 
   /* unicode (synthetic) cmaps */
 
-  FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec)
+  FT_DECLARE_CMAP_CLASS( cff_cmap_unicode_class_rec )
 
 
 FT_END_HEADER
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 997a734..4e2e0e0 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -4,8 +4,8 @@
  *
  *   OpenType font driver implementation (body).
  *
- * Copyright 1996-2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
+ * Copyright (C) 1996-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
  *
  * This file is part of the FreeType project, and may only be used,
  * modified, and distributed under the terms of the FreeType project
@@ -16,18 +16,17 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_POSTSCRIPT_PROPS_H
-#include FT_SERVICE_CID_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
-#include FT_SERVICE_POSTSCRIPT_NAME_H
-#include FT_SERVICE_TT_CMAP_H
-#include FT_SERVICE_CFF_TABLE_LOAD_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/ftpsprop.h>
+#include <freetype/internal/services/svcid.h>
+#include <freetype/internal/services/svpsinfo.h>
+#include <freetype/internal/services/svpostnm.h>
+#include <freetype/internal/services/svttcmap.h>
+#include <freetype/internal/services/svcfftl.h>
 
 #include "cffdrivr.h"
 #include "cffgload.h"
@@ -37,16 +36,16 @@
 #include "cffobjs.h"
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_SERVICE_MULTIPLE_MASTERS_H
-#include FT_SERVICE_METRICS_VARIATIONS_H
+#include <freetype/internal/services/svmm.h>
+#include <freetype/internal/services/svmetric.h>
 #endif
 
 #include "cfferrs.h"
 
-#include FT_SERVICE_FONT_FORMAT_H
-#include FT_SERVICE_GLYPH_DICT_H
-#include FT_SERVICE_PROPERTIES_H
-#include FT_DRIVER_H
+#include <freetype/internal/services/svfntfmt.h>
+#include <freetype/internal/services/svgldict.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/ftdriver.h>
 
 
   /**************************************************************************
@@ -56,7 +55,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffdriver
+#define FT_COMPONENT  cffdriver
 
 
   /*************************************************************************/
@@ -346,9 +345,9 @@
       else
       {
         FT_ERROR(( "cff_get_glyph_name:"
-                   " cannot get glyph name from a CFF2 font\n"
-                   "                   "
-                   " without the `PSNames' module\n" ));
+                   " cannot get glyph name from a CFF2 font\n" ));
+        FT_ERROR(( "                   "
+                   " without the `psnames' module\n" ));
         error = FT_THROW( Missing_Module );
         goto Exit;
       }
@@ -357,9 +356,9 @@
     if ( !font->psnames )
     {
       FT_ERROR(( "cff_get_glyph_name:"
-                 " cannot get glyph name from CFF & CEF fonts\n"
-                 "                   "
-                 " without the `PSNames' module\n" ));
+                 " cannot get glyph name from CFF & CEF fonts\n" ));
+      FT_ERROR(( "                   "
+                 " without the `psnames' module\n" ));
       error = FT_THROW( Missing_Module );
       goto Exit;
     }
@@ -381,8 +380,8 @@
 
 
   static FT_UInt
-  cff_get_name_index( CFF_Face    face,
-                      FT_String*  glyph_name )
+  cff_get_name_index( CFF_Face          face,
+                      const FT_String*  glyph_name )
   {
     CFF_Font            cff;
     CFF_Charset         charset;
@@ -413,9 +412,9 @@
       else
       {
         FT_ERROR(( "cff_get_name_index:"
-                   " cannot get glyph index from a CFF2 font\n"
-                   "                   "
-                   " without the `PSNames' module\n" ));
+                   " cannot get glyph index from a CFF2 font\n" ));
+        FT_ERROR(( "                   "
+                   " without the `psnames' module\n" ));
         return 0;
       }
     }
@@ -475,11 +474,11 @@
     if ( cff && !cff->font_info )
     {
       CFF_FontRecDict  dict      = &cff->top_font.font_dict;
-      PS_FontInfoRec  *font_info = NULL;
       FT_Memory        memory    = face->root.memory;
+      PS_FontInfoRec*  font_info = NULL;
 
 
-      if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
+      if ( FT_QNEW( font_info ) )
         goto Fail;
 
       font_info->version     = cff_index_get_sid_string( cff,
@@ -516,15 +515,15 @@
     FT_Error  error = FT_Err_Ok;
 
 
-    if ( cff && cff->font_extra == NULL )
+    if ( cff && !cff->font_extra )
     {
       CFF_FontRecDict   dict       = &cff->top_font.font_dict;
-      PS_FontExtraRec*  font_extra = NULL;
       FT_Memory         memory     = face->root.memory;
+      PS_FontExtraRec*  font_extra = NULL;
       FT_String*        embedded_postscript;
 
 
-      if ( FT_ALLOC( font_extra, sizeof ( *font_extra ) ) )
+      if ( FT_QNEW( font_extra ) )
         goto Fail;
 
       font_extra->fs_type = 0U;
@@ -738,7 +737,7 @@
       {
         if ( dict->cid_supplement < FT_INT_MIN ||
              dict->cid_supplement > FT_INT_MAX )
-          FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
+          FT_TRACE1(( "cff_get_ros: too large supplement %ld is truncated\n",
                       dict->cid_supplement ));
         *supplement = (FT_Int)dict->cid_supplement;
       }
@@ -868,6 +867,30 @@
 
 
   static FT_Error
+  cff_set_mm_weightvector( CFF_Face   face,
+                           FT_UInt    len,
+                           FT_Fixed*  weightvector )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->set_mm_weightvector( FT_FACE( face ), len, weightvector );
+  }
+
+
+  static FT_Error
+  cff_get_mm_weightvector( CFF_Face   face,
+                           FT_UInt*   len,
+                           FT_Fixed*  weightvector )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->get_mm_weightvector( FT_FACE( face ), len, weightvector );
+  }
+
+
+  static FT_Error
   cff_get_mm_var( CFF_Face     face,
                   FT_MM_Var*  *master )
   {
@@ -913,20 +936,103 @@
   }
 
 
+  static FT_Error
+  cff_load_item_variation_store( CFF_Face         face,
+                                 FT_ULong         offset,
+                                 GX_ItemVarStore  itemStore )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->load_item_var_store( FT_FACE(face), offset, itemStore );
+  }
+
+
+  static FT_Error
+  cff_load_delta_set_index_mapping( CFF_Face           face,
+                                    FT_ULong           offset,
+                                    GX_DeltaSetIdxMap  map,
+                                    GX_ItemVarStore    itemStore,
+                                    FT_ULong           table_len )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->load_delta_set_idx_map( FT_FACE( face ), offset, map,
+                                       itemStore, table_len );
+  }
+
+
+  static FT_Int
+  cff_get_item_delta( CFF_Face         face,
+                      GX_ItemVarStore  itemStore,
+                      FT_UInt          outerIndex,
+                      FT_UInt          innerIndex )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->get_item_delta( FT_FACE( face ), itemStore,
+                               outerIndex, innerIndex );
+  }
+
+
+  static void
+  cff_done_item_variation_store( CFF_Face          face,
+                                 GX_ItemVarStore  itemStore )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    mm->done_item_var_store( FT_FACE( face ), itemStore );
+  }
+
+
+  static void
+  cff_done_delta_set_index_map( CFF_Face           face,
+                                GX_DeltaSetIdxMap  deltaSetIdxMap )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    mm->done_delta_set_idx_map( FT_FACE ( face ), deltaSetIdxMap );
+  }
+
+
+
   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_Get_Var_Blend_Func) cff_get_var_blend,      /* get_var_blend  */
-    (FT_Done_Blend_Func)    cff_done_blend          /* done_blend     */
+    (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                */
   )
 
 
@@ -1002,8 +1108,7 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \
-     defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#if defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
   FT_DEFINE_SERVICEDESCREC10(
     cff_services,
 
@@ -1018,7 +1123,7 @@
     FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
     FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
   )
-#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES
+#else
   FT_DEFINE_SERVICEDESCREC8(
     cff_services,
 
@@ -1031,32 +1136,6 @@
     FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
     FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
   )
-#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
-  FT_DEFINE_SERVICEDESCREC9(
-    cff_services,
-
-    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
-    FT_SERVICE_ID_MULTI_MASTERS,        &cff_service_multi_masters,
-    FT_SERVICE_ID_METRICS_VARIATIONS,   &cff_service_metrics_var,
-    FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info,
-    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name,
-    FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
-    FT_SERVICE_ID_CID,                  &cff_service_cid_info,
-    FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
-    FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
-  )
-#else
-  FT_DEFINE_SERVICEDESCREC7(
-    cff_services,
-
-    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
-    FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info,
-    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name,
-    FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
-    FT_SERVICE_ID_CID,                  &cff_service_cid_info,
-    FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
-    FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
-  )
 #endif
 
 
diff --git a/src/cff/cffdrivr.h b/src/cff/cffdrivr.h
index 30d3e13..ab1f147 100644
--- a/src/cff/cffdrivr.h
+++ b/src/cff/cffdrivr.h
@@ -4,7 +4,7 @@
  *
  *   High-level OpenType driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define CFFDRIVER_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/cff/cfferrs.h b/src/cff/cfferrs.h
index b5ccc67..bc9a304 100644
--- a/src/cff/cfferrs.h
+++ b/src/cff/cfferrs.h
@@ -4,7 +4,7 @@
  *
  *   CFF error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef CFFERRS_H_
 #define CFFERRS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_BASE    FT_Mod_Err_CFF
 
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* CFFERRS_H_ */
 
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 88f5689..cfa0aaf 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -4,7 +4,7 @@
  *
  *   OpenType Glyph Loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,20 +16,27 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_OUTLINE_H
-#include FT_DRIVER_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/ftoutln.h>
+#include <freetype/ftdriver.h>
 
 #include "cffload.h"
 #include "cffgload.h"
 
 #include "cfferrs.h"
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#define IS_DEFAULT_INSTANCE( _face )             \
+          ( !( FT_IS_NAMED_INSTANCE( _face ) ||  \
+               FT_IS_VARIATION( _face )      ) )
+#else
+#define IS_DEFAULT_INSTANCE( _face )  1
+#endif
+
 
   /**************************************************************************
    *
@@ -38,7 +45,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffgload
+#define FT_COMPONENT  cffgload
 
 
   FT_LOCAL_DEF( FT_Error )
@@ -60,7 +67,7 @@
 
 
       *pointer = (FT_Byte*)data.pointer;
-      *length  = (FT_ULong)data.length;
+      *length  = data.length;
 
       return error;
     }
@@ -68,7 +75,7 @@
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
     {
-      CFF_Font  cff = (CFF_Font)(face->extra.data);
+      CFF_Font  cff = (CFF_Font)( face->extra.data );
 
 
       return cff_index_access_element( &cff->charstrings_index, glyph_index,
@@ -95,7 +102,7 @@
 
 
       data.pointer = *pointer;
-      data.length  = (FT_Int)length;
+      data.length  = (FT_UInt)length;
 
       face->root.internal->incremental_interface->funcs->free_glyph_data(
         face->root.internal->incremental_interface->object, &data );
@@ -104,7 +111,7 @@
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
     {
-      CFF_Font  cff = (CFF_Font)(face->extra.data);
+      CFF_Font  cff = (CFF_Font)( face->extra.data );
 
 
       cff_index_forget_element( &cff->charstrings_index, pointer );
@@ -207,8 +214,8 @@
     PSAux_Service            psaux         = (PSAux_Service)face->psaux;
     const CFF_Decoder_Funcs  decoder_funcs = psaux->cff_decoder_funcs;
 
-    FT_Matrix    font_matrix;
-    FT_Vector    font_offset;
+    FT_Matrix  font_matrix;
+    FT_Vector  font_offset;
 
 
     force_scaling = FALSE;
@@ -256,8 +263,8 @@
 
 
       if ( size->strike_index != 0xFFFFFFFFUL      &&
-           sfnt->load_eblc                         &&
-           ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
+           ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
+           IS_DEFAULT_INSTANCE( size->root.face )  )
       {
         TT_SBit_MetricsRec  metrics;
 
@@ -347,6 +354,73 @@
     if ( load_flags & FT_LOAD_SBITS_ONLY )
       return FT_THROW( Invalid_Argument );
 
+#ifdef FT_CONFIG_OPTION_SVG
+    /* check for OT-SVG */
+    if ( ( 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;
+
+
+      if ( size && (size->root.metrics.x_ppem < 1 ||
+                    size->root.metrics.y_ppem < 1 ) )
+      {
+        error = FT_THROW( Invalid_Size_Handle );
+        return error;
+      }
+
+      FT_TRACE3(( "Trying to load SVG glyph\n" ));
+
+      error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
+      if ( !error )
+      {
+        FT_Fixed  x_scale = size->root.metrics.x_scale;
+        FT_Fixed  y_scale = size->root.metrics.y_scale;
+
+        FT_Short   dummy;
+        FT_UShort  advanceX;
+        FT_UShort  advanceY;
+
+
+        FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
+
+        glyph->root.format = FT_GLYPH_FORMAT_SVG;
+
+        /*
+         * If horizontal or vertical advances are not present in the table,
+         * this is a problem with the font since the standard requires them.
+         * However, we are graceful and calculate the values by ourselves
+         * for the vertical case.
+         */
+        sfnt->get_metrics( face,
+                           FALSE,
+                           glyph_index,
+                           &dummy,
+                           &advanceX );
+        sfnt->get_metrics( face,
+                           TRUE,
+                           glyph_index,
+                           &dummy,
+                           &advanceY );
+
+        glyph->root.linearHoriAdvance = advanceX;
+        glyph->root.linearVertAdvance = advanceY;
+
+        glyph->root.metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
+        glyph->root.metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
+
+        return error;
+      }
+
+      FT_TRACE3(( "Failed to load SVG glyph\n" ));
+    }
+
+#endif /* FT_CONFIG_OPTION_SVG */
+
     /* if we have a CID subfont, use its matrix (which has already */
     /* been multiplied with the root matrix)                       */
 
@@ -364,7 +438,6 @@
       top_upm = (FT_Long)cff->top_font.font_dict.units_per_em;
       sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em;
 
-
       font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
       font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
 
@@ -399,7 +472,6 @@
       PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
 #endif
 
-
       FT_Byte*  charstring;
       FT_ULong  charstring_len;
 
@@ -414,7 +486,12 @@
         decoder.width_only = TRUE;
 
       decoder.builder.no_recurse =
-        (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
+        FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
+
+      /* this function also checks for a valid subfont index */
+      error = decoder_funcs->prepare( &decoder, size, glyph_index );
+      if ( error )
+        goto Glyph_Build_Finished;
 
       /* now load the unscaled outline */
       error = cff_get_glyph_data( face, glyph_index,
@@ -422,10 +499,6 @@
       if ( error )
         goto Glyph_Build_Finished;
 
-      error = decoder_funcs->prepare( &decoder, size, glyph_index );
-      if ( error )
-        goto Glyph_Build_Finished;
-
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
       /* choose which CFF renderer to use */
       if ( driver->hinting_engine == FT_HINTING_FREETYPE )
@@ -665,8 +738,12 @@
         metrics->horiBearingY = cbox.yMax;
 
         if ( has_vertical_info )
+        {
           metrics->vertBearingX = metrics->horiBearingX -
                                     metrics->horiAdvance / 2;
+          metrics->vertBearingY = FT_MulFix( metrics->vertBearingY,
+                                             glyph->y_scale );
+        }
         else
         {
           if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index 5a486cd..3b8cf23 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -4,7 +4,7 @@
  *
  *   OpenType Glyph Loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define CFFGLOAD_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+#include <freetype/freetype.h>
+#include <freetype/internal/cffotypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 015b2c8..4b8c6e1 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
  *
  *   OpenType and CFF data/program tables loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,17 +16,16 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_TYPE1_TABLES_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
+#include <freetype/t1tables.h>
+#include <freetype/internal/psaux.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/services/svmm.h>
 #endif
 
 #include "cffload.h"
@@ -203,7 +202,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffload
+#define FT_COMPONENT  cffload
 
 
   /* read an offset from the index's stream current position */
@@ -357,9 +356,9 @@
 
       data_size = (FT_ULong)( idx->count + 1 ) * offsize;
 
-      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
-           FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
-           FT_FRAME_ENTER( data_size )                  )
+      if ( FT_QNEW_ARRAY( idx->offsets, idx->count + 1 ) ||
+           FT_STREAM_SEEK( idx->start + idx->hdr_size )  ||
+           FT_FRAME_ENTER( data_size )                   )
         goto Exit;
 
       poff   = idx->offsets;
@@ -401,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 (this is, null-terminated).       */
   static FT_Error
   cff_index_get_pointers( CFF_Index   idx,
                           FT_Byte***  table,
@@ -411,7 +410,7 @@
     FT_Error   error     = FT_Err_Ok;
     FT_Memory  memory    = idx->stream->memory;
 
-    FT_Byte**  t         = NULL;
+    FT_Byte**  tbl       = NULL;
     FT_Byte*   new_bytes = NULL;
     FT_ULong   new_size;
 
@@ -428,11 +427,11 @@
     new_size = idx->data_size + idx->count;
 
     if ( idx->count > 0                                &&
-         !FT_NEW_ARRAY( t, idx->count + 1 )            &&
+         !FT_QNEW_ARRAY( tbl, idx->count + 1 )         &&
          ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
     {
       FT_ULong  n, cur_offset;
-      FT_ULong  extra = 0;
+      FT_ULong  extra     = 0;
       FT_Byte*  org_bytes = idx->bytes;
 
 
@@ -443,15 +442,15 @@
       if ( cur_offset != 0 )
       {
         FT_TRACE0(( "cff_index_get_pointers:"
-                    " invalid first offset value %d set to zero\n",
+                    " invalid first offset value %ld set to zero\n",
                     cur_offset ));
         cur_offset = 0;
       }
 
       if ( !pool )
-        t[0] = org_bytes + cur_offset;
+        tbl[0] = org_bytes + cur_offset;
       else
-        t[0] = new_bytes + cur_offset;
+        tbl[0] = new_bytes + cur_offset;
 
       for ( n = 1; n <= idx->count; n++ )
       {
@@ -465,23 +464,25 @@
           next_offset = idx->data_size;
 
         if ( !pool )
-          t[n] = org_bytes + next_offset;
+          tbl[n] = org_bytes + next_offset;
         else
         {
-          t[n] = new_bytes + next_offset + extra;
+          tbl[n] = new_bytes + next_offset + extra;
 
           if ( next_offset != cur_offset )
           {
-            FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
-            t[n][0] = '\0';
-            t[n]   += 1;
+            FT_MEM_COPY( tbl[n - 1],
+                         org_bytes + cur_offset,
+                         tbl[n] - tbl[n - 1] );
+            tbl[n][0] = '\0';
+            tbl[n]   += 1;
             extra++;
           }
         }
 
         cur_offset = next_offset;
       }
-      *table = t;
+      *table = tbl;
 
       if ( pool )
         *pool = new_bytes;
@@ -490,6 +491,11 @@
     }
 
   Exit:
+    if ( error && new_bytes )
+      FT_FREE( new_bytes );
+    if ( error && tbl )
+      FT_FREE( tbl );
+
     return error;
   }
 
@@ -553,8 +559,8 @@
            idx->data_offset > stream->size - off2 + 1 )
       {
         FT_ERROR(( "cff_index_access_element:"
-                   " offset to next entry (%d)"
-                   " exceeds the end of stream (%d)\n",
+                   " offset to next entry (%ld)"
+                   " exceeds the end of stream (%ld)\n",
                    off2, stream->size - idx->data_offset + 1 ));
         off2 = stream->size - idx->data_offset + 1;
       }
@@ -616,7 +622,7 @@
     FT_Byte*    bytes;
     FT_ULong    byte_len;
     FT_Error    error;
-    FT_String*  name = 0;
+    FT_String*  name = NULL;
 
 
     if ( !idx->stream )  /* CFF2 does not include a name index */
@@ -628,10 +634,9 @@
     if ( error )
       goto Exit;
 
-    if ( !FT_ALLOC( name, byte_len + 1 ) )
+    if ( !FT_QALLOC( name, byte_len + 1 ) )
     {
-      if ( byte_len )
-        FT_MEM_COPY( name, bytes, byte_len );
+      FT_MEM_COPY( name, bytes, byte_len );
       name[byte_len] = 0;
     }
     cff_index_forget_element( idx, &bytes );
@@ -766,8 +771,7 @@
 
     case 3:
       /* first, compare to the cache */
-      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
-                        fdselect->cache_count )
+      if ( glyph_index - fdselect->cache_first < fdselect->cache_count )
       {
         fd = fdselect->cache_fd;
         break;
@@ -830,7 +834,6 @@
   {
     FT_Error   error   = FT_Err_Ok;
     FT_UInt    i;
-    FT_Long    j;
     FT_UShort  max_cid = 0;
 
 
@@ -848,9 +851,10 @@
 
     /* When multiple GIDs map to the same CID, we choose the lowest */
     /* GID.  This is not described in any spec, but it matches the  */
-    /* behaviour of recent Acroread versions.                       */
-    for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
-      charset->cids[charset->sids[j]] = (FT_UShort)j;
+    /* behaviour of recent Acroread versions.  The loop stops when  */
+    /* the unsigned index wraps around after reaching zero.         */
+    for ( i = num_glyphs - 1; i < num_glyphs; i-- )
+      charset->cids[charset->sids[i]] = (FT_UShort)i;
 
     charset->max_cid    = max_cid;
     charset->num_glyphs = num_glyphs;
@@ -926,7 +930,7 @@
         goto Exit;
 
       /* Allocate memory for sids. */
-      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
+      if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
         goto Exit;
 
       /* assign the .notdef glyph */
@@ -978,7 +982,7 @@
             if ( glyph_sid > 0xFFFFL - nleft )
             {
               FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
-                         " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
+                         " nleft=%d -> %ld\n", nleft, 0xFFFFL - glyph_sid ));
               nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
             }
 
@@ -1012,14 +1016,14 @@
       case 0:
         if ( num_glyphs > 229 )
         {
-          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
-                     "predefined charset (Adobe ISO-Latin)\n" ));
+          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
+          FT_ERROR(( "predefined charset (Adobe ISO-Latin)\n" ));
           error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
         /* Allocate memory for sids. */
-        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
+        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
           goto Exit;
 
         /* Copy the predefined charset into the allocated memory. */
@@ -1030,14 +1034,14 @@
       case 1:
         if ( num_glyphs > 166 )
         {
-          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
-                     "predefined charset (Adobe Expert)\n" ));
+          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
+          FT_ERROR(( "predefined charset (Adobe Expert)\n" ));
           error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
         /* Allocate memory for sids. */
-        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
+        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
           goto Exit;
 
         /* Copy the predefined charset into the allocated memory.     */
@@ -1048,14 +1052,14 @@
       case 2:
         if ( num_glyphs > 87 )
         {
-          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
-                     "predefined charset (Adobe Expert Subset)\n" ));
+          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
+          FT_ERROR(( "predefined charset (Adobe Expert Subset)\n" ));
           error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
         /* Allocate memory for sids. */
-        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
+        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
           goto Exit;
 
         /* Copy the predefined charset into the allocated memory.     */
@@ -1081,7 +1085,6 @@
       FT_FREE( charset->cids );
       charset->format = 0;
       charset->offset = 0;
-      charset->sids   = 0;
     }
 
     return error;
@@ -1135,6 +1138,8 @@
     {
       FT_UInt   vsOffset;
       FT_UInt   format;
+      FT_UInt   dataCount;
+      FT_UInt   regionCount;
       FT_ULong  regionListOffset;
 
 
@@ -1157,16 +1162,16 @@
       }
 
       /* read top level fields */
-      if ( FT_READ_ULONG( regionListOffset )   ||
-           FT_READ_USHORT( vstore->dataCount ) )
+      if ( FT_READ_ULONG( regionListOffset ) ||
+           FT_READ_USHORT( dataCount )       )
         goto Exit;
 
       /* make temporary copy of item variation data offsets; */
       /* we'll parse region list first, then come back       */
-      if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) )
+      if ( FT_QNEW_ARRAY( dataOffsetArray, dataCount ) )
         goto Exit;
 
-      for ( i = 0; i < vstore->dataCount; i++ )
+      for ( i = 0; i < dataCount; i++ )
       {
         if ( FT_READ_ULONG( dataOffsetArray[i] ) )
           goto Exit;
@@ -1175,20 +1180,24 @@
       /* parse regionList and axisLists */
       if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
            FT_READ_USHORT( vstore->axisCount )           ||
-           FT_READ_USHORT( vstore->regionCount )         )
+           FT_READ_USHORT( regionCount )                 )
         goto Exit;
 
-      if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) )
+      vstore->regionCount = 0;
+      if ( FT_QNEW_ARRAY( vstore->varRegionList, regionCount ) )
         goto Exit;
 
-      for ( i = 0; i < vstore->regionCount; i++ )
+      for ( i = 0; i < regionCount; i++ )
       {
         CFF_VarRegion*  region = &vstore->varRegionList[i];
 
 
-        if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) )
+        if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) )
           goto Exit;
 
+        /* keep track of how many axisList to deallocate on error */
+        vstore->regionCount++;
+
         for ( j = 0; j < vstore->axisCount; j++ )
         {
           CFF_AxisCoords*  axis = &region->axisList[j];
@@ -1208,10 +1217,11 @@
       }
 
       /* use dataOffsetArray now to parse varData items */
-      if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) )
+      vstore->dataCount = 0;
+      if ( FT_QNEW_ARRAY( vstore->varData, dataCount ) )
         goto Exit;
 
-      for ( i = 0; i < vstore->dataCount; i++ )
+      for ( i = 0; i < dataCount; i++ )
       {
         CFF_VarData*  data = &vstore->varData[i];
 
@@ -1230,9 +1240,12 @@
         if ( FT_READ_USHORT( data->regionIdxCount ) )
           goto Exit;
 
-        if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
+        if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
           goto Exit;
 
+        /* keep track of how many regionIndices to deallocate on error */
+        vstore->dataCount++;
+
         for ( j = 0; j < data->regionIdxCount; j++ )
         {
           if ( FT_READ_USHORT( data->regionIndices[j] ) )
@@ -1275,7 +1288,7 @@
   /* Blended values are written to a different buffer,     */
   /* using reserved operator 255.                          */
   /*                                                       */
-  /* Blend calculation is done in 16.16 fixed point.       */
+  /* Blend calculation is done in 16.16 fixed-point.       */
   FT_LOCAL_DEF( FT_Error )
   cff_blend_doBlend( CFF_SubFont  subFont,
                      CFF_Parser   parser,
@@ -1316,9 +1329,9 @@
 
       /* increase or allocate `blend_stack' and reset `blend_top'; */
       /* prepare to append `numBlends' values to the buffer        */
-      if ( FT_REALLOC( subFont->blend_stack,
-                       subFont->blend_alloc,
-                       subFont->blend_alloc + size ) )
+      if ( FT_QREALLOC( subFont->blend_stack,
+                        subFont->blend_alloc,
+                        subFont->blend_alloc + size ) )
         goto Exit;
 
       subFont->blend_top    = subFont->blend_stack + subFont->blend_used;
@@ -1351,7 +1364,7 @@
       FT_UInt32        sum;
 
 
-      /* convert inputs to 16.16 fixed point */
+      /* convert inputs to 16.16 fixed-point */
       sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
 
       for ( j = 1; j < blend->lenBV; j++ )
@@ -1360,7 +1373,7 @@
       /* point parser stack to new value on blend_stack */
       parser->stack[i + base] = subFont->blend_top;
 
-      /* Push blended result as Type 2 5-byte fixed point number.  This */
+      /* Push blended result as Type 2 5-byte fixed-point number.  This */
       /* will not conflict with actual DICTs because 255 is a reserved  */
       /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
       /* decode of this, which rounds to an integer.                    */
@@ -1431,9 +1444,7 @@
 
     /* prepare buffer for the blend vector */
     len = varData->regionIdxCount + 1;    /* add 1 for default component */
-    if ( FT_REALLOC( blend->BV,
-                     blend->lenBV * sizeof( *blend->BV ),
-                     len * sizeof( *blend->BV ) ) )
+    if ( FT_QRENEW_ARRAY( blend->BV, blend->lenBV, len ) )
       goto Exit;
 
     blend->lenBV = len;
@@ -1450,10 +1461,8 @@
       if ( master == 0 )
       {
         blend->BV[master] = FT_FIXED_ONE;
-        FT_TRACE4(( "   build blend vector len %d\n"
-                    "   [ %f ",
-                    len,
-                    blend->BV[master] / 65536.0 ));
+        FT_TRACE4(( "   build blend vector len %d\n", len ));
+        FT_TRACE4(( "   [ %f ", blend->BV[master] / 65536.0 ));
         continue;
       }
 
@@ -1537,9 +1546,7 @@
     if ( lenNDV != 0 )
     {
       /* user has set a normalized vector */
-      if ( FT_REALLOC( blend->lastNDV,
-                       blend->lenNDV * sizeof ( *NDV ),
-                       lenNDV * sizeof ( *NDV ) ) )
+      if ( FT_QRENEW_ARRAY( blend->lastNDV, blend->lenNDV, lenNDV ) )
         goto Exit;
 
       FT_MEM_COPY( blend->lastNDV,
@@ -1821,7 +1828,8 @@
         /* Construct code to GID mapping from code to SID mapping */
         /* and charset.                                           */
 
-        encoding->count = 0;
+        encoding->offset = offset; /* used in cff_face_init */
+        encoding->count  = 0;
 
         error = cff_charset_compute_cids( charset, num_glyphs,
                                           stream->memory );
@@ -1945,7 +1953,7 @@
     if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
     {
       FT_TRACE2(( "cff_load_private_dict:"
-                  " setting unlikely BlueShift value %d to default (7)\n",
+                  " setting unlikely BlueShift value %ld to default (7)\n",
                   priv->blue_shift ));
       priv->blue_shift = 7;
     }
@@ -1953,7 +1961,7 @@
     if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
     {
       FT_TRACE2(( "cff_load_private_dict:"
-                  " setting unlikely BlueFuzz value %d to default (1)\n",
+                  " setting unlikely BlueFuzz value %ld to default (1)\n",
                   priv->blue_fuzz ));
       priv->blue_fuzz = 1;
     }
@@ -2057,7 +2065,7 @@
     if ( !error )
     {
       FT_TRACE4(( " top dictionary:\n" ));
-      error = cff_parser_run( &parser, dict, dict + dict_len );
+      error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
     }
 
     /* clean up regardless of error */
@@ -2357,8 +2365,8 @@
       if ( font->name_index.count > 1 )
       {
         FT_ERROR(( "cff_font_load:"
-                   " invalid CFF font with multiple subfonts\n"
-                   "              "
+                   " invalid CFF font with multiple subfonts\n" ));
+        FT_ERROR(( "              "
                    " in SFNT wrapper\n" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
diff --git a/src/cff/cffload.h b/src/cff/cffload.h
index 7ba9e45..5a41cde 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -4,7 +4,7 @@
  *
  *   OpenType & CFF data/program tables loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,10 +20,9 @@
 #define CFFLOAD_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_CFF_TYPES_H
+#include <freetype/internal/cfftypes.h>
 #include "cffparse.h"
-#include FT_INTERNAL_CFF_OBJECTS_TYPES_H  /* for CFF_Face */
+#include <freetype/internal/cffotypes.h>  /* for CFF_Face */
 
 
 FT_BEGIN_HEADER
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index b3f0f99..40cd9bf 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
  *
  *   OpenType objects manager (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,32 +16,31 @@
  */
 
 
-#include <ft2build.h>
 
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_STREAM_H
-#include FT_ERRORS_H
-#include FT_TRUETYPE_IDS_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_INTERNAL_SFNT_H
-#include FT_DRIVER_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/fterrors.h>
+#include <freetype/ttnameid.h>
+#include <freetype/tttags.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/ftdriver.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SERVICE_MULTIPLE_MASTERS_H
-#include FT_SERVICE_METRICS_VARIATIONS_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/services/svmm.h>
+#include <freetype/internal/services/svmetric.h>
 #endif
 
-#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+#include <freetype/internal/cffotypes.h>
 #include "cffobjs.h"
 #include "cffload.h"
 #include "cffcmap.h"
 
 #include "cfferrs.h"
 
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_SERVICE_CFF_TABLE_LOAD_H
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/services/svcfftl.h>
 
 
   /**************************************************************************
@@ -51,7 +50,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffobjs
+#define FT_COMPONENT  cffobjs
 
 
   /**************************************************************************
@@ -167,46 +166,56 @@
     FT_Error           error = FT_Err_Ok;
     PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
 
+    FT_Memory     memory   = cffsize->face->memory;
+    CFF_Internal  internal = NULL;
+    CFF_Face      face     = (CFF_Face)cffsize->face;
+    CFF_Font      font     = (CFF_Font)face->extra.data;
 
-    if ( funcs )
-    {
-      CFF_Face      face     = (CFF_Face)cffsize->face;
-      CFF_Font      font     = (CFF_Font)face->extra.data;
-      CFF_Internal  internal = NULL;
+    PS_PrivateRec priv;
 
-      PS_PrivateRec  priv;
-      FT_Memory      memory = cffsize->face->memory;
+    FT_UInt       i;
 
-      FT_UInt  i;
+    if ( !funcs )
+      goto Exit;
 
+    if ( FT_NEW( internal ) )
+      goto Exit;
 
-      if ( FT_NEW( internal ) )
-        goto Exit;
-
-      cff_make_private_dict( &font->top_font, &priv );
-      error = funcs->create( cffsize->face->memory, &priv,
+    cff_make_private_dict( &font->top_font, &priv );
+    error = funcs->create( cffsize->face->memory, &priv,
                              &internal->topfont );
+    if ( error )
+      goto Exit;
+
+    for ( i = font->num_subfonts; i > 0; i-- )
+    {
+      CFF_SubFont  sub = font->subfonts[i - 1];
+
+
+      cff_make_private_dict( sub, &priv );
+      error = funcs->create( cffsize->face->memory, &priv,
+                               &internal->subfonts[i - 1] );
       if ( error )
         goto Exit;
-
-      for ( i = font->num_subfonts; i > 0; i-- )
-      {
-        CFF_SubFont  sub = font->subfonts[i - 1];
-
-
-        cff_make_private_dict( sub, &priv );
-        error = funcs->create( cffsize->face->memory, &priv,
-                               &internal->subfonts[i - 1] );
-        if ( error )
-          goto Exit;
-      }
-
-      cffsize->internal->module_data = internal;
     }
 
+    cffsize->internal->module_data = internal;
+
     size->strike_index = 0xFFFFFFFFUL;
 
   Exit:
+    if ( error )
+    {
+      if ( internal )
+      {
+        for ( i = font->num_subfonts; i > 0; i-- )
+          FT_FREE( internal->subfonts[i - 1] );
+        FT_FREE( internal->topfont );
+      }
+
+      FT_FREE( internal );
+    }
+
     return error;
   }
 
@@ -274,6 +283,8 @@
   cff_size_request( FT_Size          size,
                     FT_Size_Request  req )
   {
+    FT_Error  error;
+
     CFF_Size           cffsize = (CFF_Size)size;
     PSH_Globals_Funcs  funcs;
 
@@ -295,7 +306,9 @@
 
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
-    FT_Request_Metrics( size->face, req );
+    error = FT_Request_Metrics( size->face, req );
+    if ( error )
+      goto Exit;
 
     funcs = cff_size_get_globals_funcs( cffsize );
 
@@ -336,7 +349,8 @@
       }
     }
 
-    return FT_Err_Ok;
+  Exit:
+    return error;
   }
 
 
@@ -349,7 +363,8 @@
   FT_LOCAL_DEF( void )
   cff_slot_done( FT_GlyphSlot  slot )
   {
-    slot->internal->glyph_hints = NULL;
+    if ( slot->internal )
+      slot->internal->glyph_hints = NULL;
   }
 
 
@@ -396,9 +411,7 @@
     FT_String*  result;
 
 
-    (void)FT_STRDUP( result, source );
-
-    FT_UNUSED( error );
+    FT_MEM_STRDUP( result, source );
 
     return result;
   }
@@ -644,14 +657,14 @@
 
       dict = &cff->top_font.font_dict;
 
-      /* we need the `PSNames' module for CFF and CEF formats */
+      /* we need the `psnames' module for CFF and CEF formats */
       /* which aren't CID-keyed                               */
       if ( dict->cid_registry == 0xFFFFU && !psnames )
       {
         FT_ERROR(( "cff_face_init:"
-                   " cannot open CFF & CEF fonts\n"
-                   "              "
-                   " without the `PSNames' module\n" ));
+                   " cannot open CFF & CEF fonts\n" ));
+        FT_ERROR(( "              "
+                   " without the `psnames' module\n" ));
         error = FT_THROW( Missing_Module );
         goto Exit;
       }
@@ -674,13 +687,13 @@
 
         /* In Multiple Master CFFs, two SIDs hold the Normalize Design  */
         /* Vector (NDV) and Convert Design Vector (CDV) charstrings,    */
-        /* which may contain NULL bytes in the middle of the data, too. */
+        /* which may contain null bytes in the middle of the data, too. */
         /* We thus access `cff->strings' directly.                      */
         for ( idx = 1; idx < cff->num_strings; idx++ )
         {
           FT_Byte*    s1    = cff->strings[idx - 1];
           FT_Byte*    s2    = cff->strings[idx];
-          FT_PtrDist  s1len = s2 - s1 - 1; /* without the final NULL byte */
+          FT_PtrDist  s1len = s2 - s1 - 1; /* without the final null byte */
           FT_PtrDist  l;
 
 
@@ -940,7 +953,8 @@
                 style_name = cff_strcpy( memory, fullp );
 
                 /* remove the style part from the family name (if present) */
-                remove_style( cffface->family_name, style_name );
+                if ( style_name )
+                  remove_style( cffface->family_name, style_name );
               }
               break;
             }
@@ -962,7 +976,7 @@
           cffface->style_name = style_name;
         else
           /* assume "Regular" style if we don't know better */
-          cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
+          cffface->style_name = cff_strcpy( memory, "Regular" );
 
         /********************************************************************
          *
@@ -1017,12 +1031,10 @@
         cffface->style_flags = flags;
       }
 
-#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
-      /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
-      /* has unset this flag because of the 3.0 `post' table.          */
-      if ( dict->cid_registry == 0xFFFFU )
+      /* CID-keyed CFF or CFF2 fonts don't have glyph names -- the SFNT */
+      /* loader has unset this flag because of the 3.0 `post' table.    */
+      if ( dict->cid_registry == 0xFFFFU && !cff2 )
         cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
-#endif
 
       if ( dict->cid_registry != 0xFFFFU && pure_cff )
         cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
@@ -1038,11 +1050,11 @@
       {
         FT_CharMapRec  cmaprec;
         FT_CharMap     cmap;
-        FT_UInt        nn;
+        FT_Int         nn;
         CFF_Encoding   encoding = &cff->encoding;
 
 
-        for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
+        for ( nn = 0; nn < cffface->num_charmaps; nn++ )
         {
           cmap = cffface->charmaps[nn];
 
@@ -1067,17 +1079,18 @@
         cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
         cmaprec.encoding    = FT_ENCODING_UNICODE;
 
-        nn = (FT_UInt)cffface->num_charmaps;
+        nn = cffface->num_charmaps;
 
         error = FT_CMap_New( &cff_cmap_unicode_class_rec, NULL,
                              &cmaprec, NULL );
         if ( error                                      &&
-             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
+             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
+             FT_ERR_NEQ( error, Unimplemented_Feature ) )
           goto Exit;
         error = FT_Err_Ok;
 
         /* if no Unicode charmap was previously selected, select this one */
-        if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps )
+        if ( !cffface->charmap && nn != cffface->num_charmaps )
           cffface->charmap = cffface->charmaps[nn];
 
       Skip_Unicode:
@@ -1162,11 +1175,7 @@
 
 
     /* set default property values, cf. `ftcffdrv.h' */
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-    driver->hinting_engine = FT_HINTING_FREETYPE;
-#else
     driver->hinting_engine = FT_HINTING_ADOBE;
-#endif
 
     driver->no_stem_darkening = TRUE;
 
diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
index 2beb11b..8f05f61 100644
--- a/src/cff/cffobjs.h
+++ b/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
  *
  *   OpenType objects manager (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define CFFOBJS_H_
 
 
-#include <ft2build.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index b6f5dae..e16206f 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
  *
  *   CFF token stream parser (body)
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,12 @@
  */
 
 
-#include <ft2build.h>
 #include "cffparse.h"
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/ftlist.h>
 
 #include "cfferrs.h"
 #include "cffload.h"
@@ -34,7 +34,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffparse
+#define FT_COMPONENT  cffparse
 
 
   FT_LOCAL_DEF( FT_Error )
@@ -62,7 +62,7 @@
     parser->num_axes    = num_axes;
 
     /* allocate the stack buffer */
-    if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
+    if ( FT_QNEW_ARRAY( parser->stack, stackSize ) )
     {
       FT_FREE( parser->stack );
       goto Exit;
@@ -76,6 +76,23 @@
   }
 
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+  static void
+  finalize_t2_strings( FT_Memory  memory,
+                       void*      data,
+                       void*      user )
+  {
+    CFF_T2_String  t2 = (CFF_T2_String)data;
+
+
+    FT_UNUSED( user );
+
+    memory->free( memory, t2->start );
+    memory->free( memory, data );
+  }
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
   FT_LOCAL_DEF( void )
   cff_parser_done( CFF_Parser  parser )
   {
@@ -83,13 +100,65 @@
 
 
     FT_FREE( parser->stack );
+
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+    FT_List_Finalize( &parser->t2_strings,
+                      finalize_t2_strings,
+                      memory,
+                      NULL );
+#endif
+  }
+
+
+  /* Assuming `first >= last'. */
+
+  static FT_Error
+  cff_parser_within_limits( CFF_Parser  parser,
+                            FT_Byte*    first,
+                            FT_Byte*    last )
+  {
+#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
+
+    /* Fast path for regular FreeType builds with the "new" engine; */
+    /*   `first >= parser->start' can be assumed.                   */
+
+    FT_UNUSED( first );
+
+    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
+
+#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
+    FT_ListNode  node;
+
+
+    if ( first >= parser->start &&
+         last  <  parser->limit )
+      return FT_Err_Ok;
+
+    node = parser->t2_strings.head;
+
+    while ( node )
+    {
+      CFF_T2_String  t2 = (CFF_T2_String)node->data;
+
+
+      if ( first >= t2->start &&
+           last  <  t2->limit )
+        return FT_Err_Ok;
+
+      node = node->next;
+    }
+
+    return FT_THROW( Invalid_Argument );
+
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
   }
 
 
   /* read an integer */
   static FT_Long
-  cff_parse_integer( FT_Byte*  start,
-                     FT_Byte*  limit )
+  cff_parse_integer( CFF_Parser  parser,
+                     FT_Byte*    start )
   {
     FT_Byte*  p   = start;
     FT_Int    v   = *p++;
@@ -98,14 +167,14 @@
 
     if ( v == 28 )
     {
-      if ( p + 2 > limit )
+      if ( cff_parser_within_limits( parser, p, p + 1 ) )
         goto Bad;
 
       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
     }
     else if ( v == 29 )
     {
-      if ( p + 4 > limit )
+      if ( cff_parser_within_limits( parser, p, p + 3 ) )
         goto Bad;
 
       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
@@ -119,14 +188,14 @@
     }
     else if ( v < 251 )
     {
-      if ( p + 1 > limit )
+      if ( cff_parser_within_limits( parser, p, p ) )
         goto Bad;
 
       val = ( v - 247 ) * 256 + p[0] + 108;
     }
     else
     {
-      if ( p + 1 > limit )
+      if ( cff_parser_within_limits( parser, p, p ) )
         goto Bad;
 
       val = -( v - 251 ) * 256 - p[0] - 108;
@@ -175,10 +244,10 @@
 
   /* read a real */
   static FT_Fixed
-  cff_parse_real( FT_Byte*  start,
-                  FT_Byte*  limit,
-                  FT_Long   power_ten,
-                  FT_Long*  scaling )
+  cff_parse_real( CFF_Parser  parser,
+                  FT_Byte*    start,
+                  FT_Long     power_ten,
+                  FT_Long*    scaling )
   {
     FT_Byte*  p = start;
     FT_Int    nib;
@@ -213,7 +282,7 @@
         p++;
 
         /* Make sure we don't read past the end. */
-        if ( p >= limit )
+        if ( cff_parser_within_limits( parser, p, p ) )
           goto Bad;
       }
 
@@ -250,7 +319,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( p >= limit )
+          if ( cff_parser_within_limits( parser, p, p ) )
             goto Bad;
         }
 
@@ -289,7 +358,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( p >= limit )
+          if ( cff_parser_within_limits( parser, p, p ) )
             goto Bad;
         }
 
@@ -456,12 +525,12 @@
     if ( **d == 30 )
     {
       /* binary-coded decimal is truncated to integer */
-      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
+      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
     }
 
     else if ( **d == 255 )
     {
-      /* 16.16 fixed point is used internally for CFF2 blend results. */
+      /* 16.16 fixed-point is used internally for CFF2 blend results. */
       /* Since these are trusted values, a limit check is not needed. */
 
       /* After the 255, 4 bytes give the number.                 */
@@ -482,7 +551,7 @@
     }
 
     else
-      return cff_parse_integer( *d, parser->limit );
+      return cff_parse_integer( parser, *d );
   }
 
 
@@ -493,10 +562,10 @@
             FT_Long     scaling )
   {
     if ( **d == 30 )
-      return cff_parse_real( *d, parser->limit, scaling, NULL );
+      return cff_parse_real( parser, *d, scaling, NULL );
     else
     {
-      FT_Long  val = cff_parse_integer( *d, parser->limit );
+      FT_Long  val = cff_parse_integer( parser, *d );
 
 
       if ( scaling )
@@ -561,14 +630,14 @@
     FT_ASSERT( scaling );
 
     if ( **d == 30 )
-      return cff_parse_real( *d, parser->limit, 0, scaling );
+      return cff_parse_real( parser, *d, 0, scaling );
     else
     {
       FT_Long  number;
       FT_Int   integer_length;
 
 
-      number = cff_parse_integer( d[0], d[1] );
+      number = cff_parse_integer( parser, d[0] );
 
       if ( number > 0x7FFFL )
       {
@@ -644,9 +713,10 @@
            ( max_scaling - min_scaling ) > 9 )
       {
         FT_TRACE1(( "cff_parse_font_matrix:"
-                    " strange scaling values (minimum %d, maximum %d),\n"
-                    "                      "
-                    " using default matrix\n", min_scaling, max_scaling ));
+                    " strange scaling values (minimum %ld, maximum %ld),\n",
+                    min_scaling, max_scaling ));
+        FT_TRACE1(( "                      "
+                    " using default matrix\n" ));
         goto Unlikely;
       }
 
@@ -688,12 +758,12 @@
       *upm = (FT_ULong)power_tens[-max_scaling];
 
       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
-                  (double)matrix->xx / *upm / 65536,
-                  (double)matrix->xy / *upm / 65536,
-                  (double)matrix->yx / *upm / 65536,
-                  (double)matrix->yy / *upm / 65536,
-                  (double)offset->x  / *upm / 65536,
-                  (double)offset->y  / *upm / 65536 ));
+                  (double)matrix->xx / (double)*upm / 65536,
+                  (double)matrix->xy / (double)*upm / 65536,
+                  (double)matrix->yx / (double)*upm / 65536,
+                  (double)matrix->yy / (double)*upm / 65536,
+                  (double)offset->x  / (double)*upm / 65536,
+                  (double)offset->y  / (double)*upm / 65536 ));
 
       if ( !FT_Matrix_Check( matrix ) )
       {
@@ -741,7 +811,7 @@
       bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data   ) );
       error = FT_Err_Ok;
 
-      FT_TRACE4(( " [%d %d %d %d]\n",
+      FT_TRACE4(( " [%ld %ld %ld %ld]\n",
                   bbox->xMin / 65536,
                   bbox->yMin / 65536,
                   bbox->xMax / 65536,
@@ -808,7 +878,7 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     /* beautify tracing message */
-    if ( ft_trace_levels[FT_COMPONENT] < 4 )
+    if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] < 4 )
       FT_TRACE1(( "Multiple Master CFFs not supported yet,"
                   " handling first master design only\n" ));
     else
@@ -864,11 +934,11 @@
         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
       dict->cid_supplement = cff_parse_num( parser, data );
       if ( dict->cid_supplement < 0 )
-        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
+        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %ld is found\n",
                    dict->cid_supplement ));
       error = FT_Err_Ok;
 
-      FT_TRACE4(( " %d %d %d\n",
+      FT_TRACE4(( " %d %d %ld\n",
                   dict->cid_registry,
                   dict->cid_ordering,
                   dict->cid_supplement ));
@@ -1126,16 +1196,15 @@
                   FT_Byte*    start,
                   FT_Byte*    limit )
   {
+    FT_Byte*  p     = start;
+    FT_Error  error = FT_Err_Ok;
+
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
     PSAux_Service  psaux;
-#endif
 
-    FT_Byte*    p       = start;
-    FT_Error    error   = FT_Err_Ok;
     FT_Library  library = parser->library;
-
-    FT_UNUSED( library );
-
+    FT_Memory   memory  = library->memory;
+#endif
 
     parser->top    = parser->stack;
     parser->start  = start;
@@ -1195,8 +1264,11 @@
         FT_Byte*     charstring_base;
         FT_ULong     charstring_len;
 
-        FT_Fixed*  stack;
-        FT_Byte*   q;
+        FT_Fixed*      stack;
+        FT_ListNode    node;
+        CFF_T2_String  t2;
+        FT_Fixed       t2_size;
+        FT_Byte*       q;
 
 
         charstring_base = ++p;
@@ -1231,17 +1303,39 @@
 
         error = psaux->cff_decoder_funcs->parse_charstrings_old(
                   &decoder, charstring_base, charstring_len, 1 );
+        if ( error )
+          goto Exit;
 
         /* Now copy the stack data in the temporary decoder object,    */
         /* converting it back to charstring number representations     */
         /* (this is ugly, I know).                                     */
-        /*                                                             */
-        /* We overwrite the original top DICT charstring under the     */
-        /* assumption that the charstring representation of the result */
-        /* of `cff_decoder_parse_charstrings' is shorter, which should */
-        /* be always true.                                             */
 
-        q     = charstring_base - 1;
+        node = (FT_ListNode)memory->alloc( memory,
+                                           sizeof ( FT_ListNodeRec ) );
+        if ( !node )
+          goto Out_Of_Memory_Error;
+
+        FT_List_Add( &parser->t2_strings, node );
+
+        t2 = (CFF_T2_String)memory->alloc( memory,
+                                           sizeof ( CFF_T2_StringRec ) );
+        if ( !t2 )
+          goto Out_Of_Memory_Error;
+
+        node->data = t2;
+
+        /* `5' is the conservative upper bound of required bytes per stack */
+        /* element.                                                        */
+
+        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 )
@@ -1257,7 +1351,7 @@
 
           if ( *stack < 0 )
           {
-            num = (FT_ULong)-*stack;
+            num = (FT_ULong)NEG_LONG( *stack );
             neg = 1;
           }
           else
@@ -1422,6 +1516,7 @@
 
               case cff_kind_fixed_thousand:
                 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
+                break;
 
               default:
                 ; /* never reached */
@@ -1498,11 +1593,17 @@
           parser->top = parser->stack;
       }
       p++;
-    }
+    } /* while ( p < limit ) */
 
   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 9cefab7..58d59fa 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -4,7 +4,7 @@
  *
  *   CFF token stream parser (specification)
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define CFFPARSE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_CFF_TYPES_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/cfftypes.h>
+#include <freetype/internal/ftobjs.h>
 
 
 FT_BEGIN_HEADER
@@ -60,6 +59,10 @@
     FT_Byte**   top;
     FT_UInt     stackSize;  /* allocated size */
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+    FT_ListRec  t2_strings;
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
     FT_UInt     object_code;
     void*       object;
 
@@ -130,6 +133,15 @@
 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/cff/cfftoken.h b/src/cff/cfftoken.h
index a7ccea8..b61cb0e 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -4,7 +4,7 @@
  *
  *   CFF token definitions (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/cff/module.mk b/src/cff/module.mk
index 8013d5d..b881d04 100644
--- a/src/cff/module.mk
+++ b/src/cff/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/cff/rules.mk b/src/cff/rules.mk
index 0157a99..629424a 100644
--- a/src/cff/rules.mk
+++ b/src/cff/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/cid/Jamfile b/src/cid/Jamfile
deleted file mode 100644
index 1c232fd..0000000
--- a/src/cid/Jamfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# FreeType 2 src/cid Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) cid ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = cidgload
-               cidload
-               cidobjs
-               cidparse
-               cidriver
-               ;
-  }
-  else
-  {
-    _sources = type1cid ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/cid Jamfile
diff --git a/src/cid/ciderrs.h b/src/cid/ciderrs.h
index 673b099..40a1097 100644
--- a/src/cid/ciderrs.h
+++ b/src/cid/ciderrs.h
@@ -4,7 +4,7 @@
  *
  *   CID error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef CIDERRS_H_
 #define CIDERRS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  CID_Err_
 #define FT_ERR_BASE    FT_Mod_Err_CID
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* CIDERRS_H_ */
 
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index e47cd99..ba4b756 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -4,7 +4,7 @@
  *
  *   CID-keyed Type1 Glyph Loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,17 +16,16 @@
  */
 
 
-#include <ft2build.h>
 #include "cidload.h"
 #include "cidgload.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_OUTLINE_H
-#include FT_INTERNAL_CALC_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/ftoutln.h>
+#include <freetype/internal/ftcalc.h>
 
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_CFF_TYPES_H
-#include FT_DRIVER_H
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/cfftypes.h>
+#include <freetype/ftdriver.h>
 
 #include "ciderrs.h"
 
@@ -38,7 +37,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cidgload
+#define FT_COMPONENT  cidgload
 
 
   FT_CALLBACK_DEF( FT_Error )
@@ -64,7 +63,7 @@
 #endif
 
 
-    FT_TRACE1(( "cid_load_glyph: glyph index %d\n", glyph_index ));
+    FT_TRACE1(( "cid_load_glyph: glyph index %u\n", glyph_index ));
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 
@@ -77,20 +76,17 @@
 
       error = inc->funcs->get_glyph_data( inc->object,
                                           glyph_index, &glyph_data );
-      if ( error )
+      if ( error || glyph_data.length < cid->fd_bytes )
         goto Exit;
 
       p         = (FT_Byte*)glyph_data.pointer;
-      fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
+      fd_select = cid_get_offset( &p, cid->fd_bytes );
 
-      if ( glyph_data.length != 0 )
-      {
-        glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes );
-        (void)FT_ALLOC( charstring, glyph_length );
-        if ( !error )
-          ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes,
+      glyph_length = glyph_data.length - cid->fd_bytes;
+
+      if ( !FT_QALLOC( charstring, glyph_length ) )
+        FT_MEM_COPY( charstring, glyph_data.pointer + cid->fd_bytes,
                      glyph_length );
-      }
 
       inc->funcs->free_glyph_data( inc->object, &glyph_data );
 
@@ -105,7 +101,7 @@
     /* For ordinary fonts read the CID font dictionary index */
     /* and charstring offset from the CIDMap.                */
     {
-      FT_UInt   entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes );
+      FT_UInt   entry_len = cid->fd_bytes + cid->gd_bytes;
       FT_ULong  off1, off2;
 
 
@@ -115,15 +111,15 @@
         goto Exit;
 
       p         = (FT_Byte*)stream->cursor;
-      fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
-      off1      = cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
+      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, (FT_Byte)cid->gd_bytes );
+      off2      = cid_get_offset( &p, cid->gd_bytes );
       FT_FRAME_EXIT();
 
-      if ( fd_select >= (FT_ULong)cid->num_dicts ||
-           off2 > stream->size                   ||
-           off1 > off2                           )
+      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 );
@@ -131,11 +127,10 @@
       }
 
       glyph_length = off2 - off1;
-      if ( glyph_length == 0 )
-        goto Exit;
-      if ( FT_ALLOC( charstring, glyph_length ) )
-        goto Exit;
-      if ( FT_STREAM_READ_AT( cid->data_offset + off1,
+
+      if ( glyph_length == 0                             ||
+           FT_QALLOC( charstring, glyph_length )         ||
+           FT_STREAM_READ_AT( cid->data_offset + off1,
                               charstring, glyph_length ) )
         goto Exit;
     }
@@ -393,8 +388,7 @@
     must_finish_decoder = TRUE;
 
     /* set up the decoder */
-    decoder.builder.no_recurse = FT_BOOL(
-      ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
+    decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
 
     error = cid_load_glyph( &decoder, glyph_index );
     if ( error )
diff --git a/src/cid/cidgload.h b/src/cid/cidgload.h
index 21c5e16..97954d4 100644
--- a/src/cid/cidgload.h
+++ b/src/cid/cidgload.h
@@ -4,7 +4,7 @@
  *
  *   OpenType Glyph Loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define CIDGLOAD_H_
 
 
-#include <ft2build.h>
 #include "cidobjs.h"
 
 
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index 1546926..26daa5d 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -4,7 +4,7 @@
  *
  *   CID-keyed Type1 font loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,11 +17,11 @@
 
 
 #include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_MULTIPLE_MASTERS_H
-#include FT_INTERNAL_TYPE1_TYPES_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/psaux.h>
 
 #include "cidload.h"
 
@@ -35,13 +35,13 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cidload
+#define FT_COMPONENT  cidload
 
 
   /* read a single offset */
   FT_LOCAL_DEF( FT_ULong )
   cid_get_offset( FT_Byte*  *start,
-                  FT_Byte    offsize )
+                  FT_UInt    offsize )
   {
     FT_ULong  result;
     FT_Byte*  p = *start;
@@ -113,7 +113,7 @@
         CID_FaceDict  dict;
 
 
-        if ( parser->num_dict < 0 || parser->num_dict >= cid->num_dicts )
+        if ( parser->num_dict >= cid->num_dicts )
         {
           FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n",
                      keyword->ident ));
@@ -154,7 +154,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_Error )
+  FT_CALLBACK_DEF( void )
   cid_parse_font_matrix( CID_Face     face,
                          CID_Parser*  parser )
   {
@@ -164,7 +164,7 @@
     FT_Fixed      temp_scale;
 
 
-    if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < face->cid.num_dicts )
     {
       FT_Matrix*  matrix;
       FT_Vector*  offset;
@@ -179,7 +179,10 @@
       result = cid_parser_to_fixed_array( parser, 6, temp, 3 );
 
       if ( result < 6 )
-        return FT_THROW( Invalid_File_Format );
+      {
+        FT_ERROR(( "cid_parse_font_matrix: not enough matrix elements\n" ));
+        goto Exit;
+      }
 
       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
                   (double)temp[0] / 65536 / 1000,
@@ -194,7 +197,7 @@
       if ( temp_scale == 0 )
       {
         FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" ));
-        return FT_THROW( Invalid_File_Format );
+        goto Exit;
       }
 
       /* atypical case */
@@ -220,7 +223,7 @@
       {
         FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
         parser->root.error = FT_THROW( Invalid_File_Format );
-        return FT_THROW( Invalid_File_Format );
+        goto Exit;
       }
 
       /* note that the font offsets are expressed in integer font units */
@@ -228,11 +231,12 @@
       offset->y  = temp[5] >> 16;
     }
 
-    return FT_Err_Ok;
+  Exit:
+    return;
   }
 
 
-  FT_CALLBACK_DEF( FT_Error )
+  FT_CALLBACK_DEF( void )
   parse_fd_array( CID_Face     face,
                   CID_Parser*  parser )
   {
@@ -240,18 +244,17 @@
     FT_Memory     memory = face->root.memory;
     FT_Stream     stream = parser->stream;
     FT_Error      error  = FT_Err_Ok;
-    FT_Long       num_dicts;
+    FT_Long       num_dicts, max_dicts;
 
 
     num_dicts = cid_parser_to_int( parser );
-    if ( num_dicts < 0 )
+    if ( num_dicts < 0 || num_dicts > FT_INT_MAX )
     {
       FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" ));
-      error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    FT_TRACE4(( " %d\n", num_dicts ));
+    FT_TRACE4(( " %ld\n", num_dicts ));
 
     /*
      * A single entry in the FDArray must (at least) contain the following
@@ -269,18 +272,18 @@
      * need a `dup X' at the very beginning and a `put' at the end, so a
      * rough guess using 100 bytes as the minimum is justified.
      */
-    if ( (FT_ULong)num_dicts > stream->size / 100 )
+    max_dicts = (FT_Long)( stream->size / 100 );
+    if ( num_dicts > max_dicts )
     {
       FT_TRACE0(( "parse_fd_array: adjusting FDArray size"
-                  " (from %d to %d)\n",
-                  num_dicts,
-                  stream->size / 100 ));
-      num_dicts = (FT_Long)( stream->size / 100 );
+                  " (from %ld to %ld)\n",
+                  num_dicts, max_dicts ));
+      num_dicts = max_dicts;
     }
 
     if ( !cid->font_dicts )
     {
-      FT_Int  n;
+      FT_UInt  n;
 
 
       if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) )
@@ -304,7 +307,7 @@
     }
 
   Exit:
-    return error;
+    return;
   }
 
 
@@ -312,24 +315,24 @@
   /* and CID_FaceDictRec (both are public header files and can't  */
   /* changed).  We simply copy the value.                         */
 
-  FT_CALLBACK_DEF( FT_Error )
+  FT_CALLBACK_DEF( void )
   parse_expansion_factor( CID_Face     face,
                           CID_Parser*  parser )
   {
     CID_FaceDict  dict;
 
 
-    if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < face->cid.num_dicts )
     {
       dict = face->cid.font_dicts + parser->num_dict;
 
       dict->expansion_factor              = cid_parser_to_fixed( parser, 0 );
       dict->private_dict.expansion_factor = dict->expansion_factor;
 
-      FT_TRACE4(( "%d\n", dict->expansion_factor ));
+      FT_TRACE4(( "%ld\n", dict->expansion_factor ));
     }
 
-    return FT_Err_Ok;
+    return;
   }
 
 
@@ -337,12 +340,12 @@
   /* `FontName' keyword.  FreeType doesn't need it, but it is nice */
   /* to catch it for producing better trace output.                */
 
-  FT_CALLBACK_DEF( FT_Error )
+  FT_CALLBACK_DEF( void )
   parse_font_name( CID_Face     face,
                    CID_Parser*  parser )
   {
 #ifdef FT_DEBUG_LEVEL_TRACE
-    if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < face->cid.num_dicts )
     {
       T1_TokenRec  token;
       FT_UInt      len;
@@ -361,7 +364,7 @@
     FT_UNUSED( parser );
 #endif
 
-    return FT_Err_Ok;
+    return;
   }
 
 
@@ -424,7 +427,7 @@
               parser->num_dict++;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
-              FT_TRACE4(( " FontDict %d", parser->num_dict ));
+              FT_TRACE4(( " FontDict %u", parser->num_dict ));
               if ( parser->num_dict > face->cid.num_dicts )
                 FT_TRACE4(( " (ignored)" ));
               FT_TRACE4(( "\n" ));
@@ -514,7 +517,7 @@
     FT_Memory      memory = face->root.memory;
     FT_Stream      stream = face->cid_stream;
     FT_Error       error;
-    FT_Int         n;
+    FT_UInt        n;
     CID_Subrs      subr;
     FT_UInt        max_offsets = 0;
     FT_ULong*      offsets = NULL;
@@ -549,20 +552,20 @@
           goto Fail;
         }
 
-        if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) )
+        if ( FT_QRENEW_ARRAY( offsets, max_offsets, new_max ) )
           goto Fail;
 
         max_offsets = new_max;
       }
 
       /* read the subrmap's offsets */
-      if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset )     ||
-           FT_FRAME_ENTER( ( num_subrs + 1 ) * (FT_UInt)dict->sd_bytes ) )
+      if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) ||
+           FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes )      )
         goto Fail;
 
       p = (FT_Byte*)stream->cursor;
       for ( count = 0; count <= num_subrs; count++ )
-        offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes );
+        offsets[count] = cid_get_offset( &p, dict->sd_bytes );
 
       FT_FRAME_EXIT();
 
@@ -586,12 +589,12 @@
       /* allocate, and read them                     */
       data_len = offsets[num_subrs] - offsets[0];
 
-      if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) ||
-           FT_ALLOC( subr->code[0], data_len )       )
+      if ( FT_QNEW_ARRAY( subr->code, num_subrs + 1 ) ||
+           FT_QALLOC( subr->code[0], data_len )       )
         goto Fail;
 
       if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) ||
-           FT_STREAM_READ( subr->code[0], data_len )  )
+           FT_STREAM_READ( subr->code[0], data_len )       )
         goto Fail;
 
       /* set up pointers */
@@ -662,17 +665,18 @@
 
 
   static FT_Error
-  cid_hex_to_binary( FT_Byte*  data,
-                     FT_ULong  data_len,
-                     FT_ULong  offset,
-                     CID_Face  face )
+  cid_hex_to_binary( FT_Byte*   data,
+                     FT_ULong   data_len,
+                     FT_ULong   offset,
+                     CID_Face   face,
+                     FT_ULong*  data_written )
   {
     FT_Stream  stream = face->root.stream;
     FT_Error   error;
 
     FT_Byte    buffer[256];
     FT_Byte   *p, *plimit;
-    FT_Byte   *d, *dlimit;
+    FT_Byte   *d = data, *dlimit;
     FT_Byte    val;
 
     FT_Bool    upper_nibble, done;
@@ -681,7 +685,6 @@
     if ( FT_STREAM_SEEK( offset ) )
       goto Exit;
 
-    d      = data;
     dlimit = d + data_len;
     p      = buffer;
     plimit = p;
@@ -712,7 +715,7 @@
       if ( ft_isdigit( *p ) )
         val = (FT_Byte)( *p - '0' );
       else if ( *p >= 'a' && *p <= 'f' )
-        val = (FT_Byte)( *p - 'a' );
+        val = (FT_Byte)( *p - 'a' + 10 );
       else if ( *p >= 'A' && *p <= 'F' )
         val = (FT_Byte)( *p - 'A' + 10 );
       else if ( *p == ' '  ||
@@ -755,6 +758,7 @@
     error = FT_Err_Ok;
 
   Exit:
+    *data_written = (FT_ULong)( d - data );
     return error;
   }
 
@@ -767,12 +771,11 @@
     CID_Parser*  parser;
     FT_Memory    memory = face->root.memory;
     FT_Error     error;
-    FT_Int       n;
+    FT_UInt      n;
 
     CID_FaceInfo  cid = &face->cid;
 
     FT_ULong  binary_length;
-    FT_ULong  entry_len;
 
 
     cid_init_loader( &loader, face );
@@ -800,8 +803,8 @@
       if ( parser->binary_length >
              face->root.stream->size - parser->data_offset )
       {
-        FT_TRACE0(( "cid_face_open: adjusting length of binary data\n"
-                    "               (from %d to %d bytes)\n",
+        FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" ));
+        FT_TRACE0(( "               (from %lu to %lu bytes)\n",
                     parser->binary_length,
                     face->root.stream->size - parser->data_offset ));
         parser->binary_length = face->root.stream->size -
@@ -809,15 +812,16 @@
       }
 
       /* we must convert the data section from hexadecimal to binary */
-      if ( FT_ALLOC( face->binary_data, parser->binary_length )    ||
+      if ( FT_QALLOC( face->binary_data, parser->binary_length )   ||
            FT_SET_ERROR( cid_hex_to_binary( face->binary_data,
                                             parser->binary_length,
                                             parser->data_offset,
-                                            face ) )               )
+                                            face,
+                                            &binary_length ) )     )
         goto Exit;
 
       FT_Stream_OpenMemory( face->cid_stream,
-                            face->binary_data, parser->binary_length );
+                            face->binary_data, binary_length );
       cid->data_offset = 0;
     }
     else
@@ -828,10 +832,10 @@
 
     /* sanity tests */
 
-    if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 )
+    if ( cid->gd_bytes == 0 )
     {
       FT_ERROR(( "cid_face_open:"
-                 " Invalid `FDBytes' or `GDBytes' value\n" ));
+                 " Invalid `GDBytes' value\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
@@ -840,15 +844,32 @@
     if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 )
     {
       FT_ERROR(( "cid_face_open:"
-                 " Values of `FDBytes' or `GDBytes' larger than 4\n"
-                 "               "
+                 " Values of `FDBytes' or `GDBytes' larger than 4\n" ));
+      FT_ERROR(( "               "
                  " are not supported\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
     binary_length = face->cid_stream->size - cid->data_offset;
-    entry_len     = (FT_ULong)( cid->fd_bytes + cid->gd_bytes );
+
+    if ( cid->cidmap_offset > binary_length )
+    {
+      FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    /* the initial pre-check prevents the multiplication overflow */
+    if ( cid->cid_count > FT_ULONG_MAX / 8                    ||
+         cid->cid_count * ( cid->fd_bytes + cid->gd_bytes ) >
+           binary_length - cid->cidmap_offset                 )
+    {
+      FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
 
     for ( n = 0; n < cid->num_dicts; n++ )
     {
@@ -874,8 +895,7 @@
         dict->private_dict.blue_fuzz = 1;
       }
 
-      if ( dict->sd_bytes < 0                        ||
-           ( dict->num_subrs && dict->sd_bytes < 1 ) )
+      if ( dict->num_subrs && dict->sd_bytes == 0 )
       {
         FT_ERROR(( "cid_face_open: Invalid `SDBytes' value\n" ));
         error = FT_THROW( Invalid_File_Format );
@@ -898,11 +918,10 @@
         goto Exit;
       }
 
-      /* `num_subrs' is scanned as a signed integer */
-      if ( (FT_Int)dict->num_subrs < 0                                     ||
-           ( dict->sd_bytes                                              &&
-             dict->num_subrs > ( binary_length - dict->subrmap_offset ) /
-                                 (FT_UInt)dict->sd_bytes                 ) )
+      /* the initial pre-check prevents the multiplication overflow */
+      if ( dict->num_subrs > FT_UINT_MAX / 4      ||
+           dict->num_subrs * dict->sd_bytes >
+             binary_length - dict->subrmap_offset )
       {
         FT_ERROR(( "cid_face_open: Invalid `SubrCount' value\n" ));
         error = FT_THROW( Invalid_File_Format );
@@ -910,22 +929,6 @@
       }
     }
 
-    if ( cid->cidmap_offset > binary_length )
-    {
-      FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" ));
-      error = FT_THROW( Invalid_File_Format );
-      goto Exit;
-    }
-
-    if ( entry_len                                            &&
-         cid->cid_count >
-           ( binary_length - cid->cidmap_offset ) / entry_len )
-    {
-      FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" ));
-      error = FT_THROW( Invalid_File_Format );
-      goto Exit;
-    }
-
     /* we can now safely proceed */
     error = cid_read_subrs( face );
 
diff --git a/src/cid/cidload.h b/src/cid/cidload.h
index a3e6e28..d12d296 100644
--- a/src/cid/cidload.h
+++ b/src/cid/cidload.h
@@ -4,7 +4,7 @@
  *
  *   CID-keyed Type1 font loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define CIDLOAD_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftstream.h>
 #include "cidparse.h"
 
 
@@ -38,7 +37,7 @@
 
   FT_LOCAL( FT_ULong )
   cid_get_offset( FT_Byte**  start,
-                  FT_Byte    offsize );
+                  FT_UInt    offsize );
 
   FT_LOCAL( FT_Error )
   cid_face_open( CID_Face  face,
diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c
index 91c4ed9..06b2139 100644
--- a/src/cid/cidobjs.c
+++ b/src/cid/cidobjs.c
@@ -4,7 +4,7 @@
  *
  *   CID objects manager (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,17 +16,16 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
 
 #include "cidgload.h"
 #include "cidload.h"
 
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
-#include FT_DRIVER_H
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/pshints.h>
+#include <freetype/ftdriver.h>
 
 #include "ciderrs.h"
 
@@ -38,7 +37,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cidobjs
+#define FT_COMPONENT  cidobjs
 
 
   /**************************************************************************
@@ -50,7 +49,8 @@
   FT_LOCAL_DEF( void )
   cid_slot_done( FT_GlyphSlot  slot )
   {
-    slot->internal->glyph_hints = NULL;
+    if ( slot->internal )
+      slot->internal->glyph_hints = NULL;
   }
 
 
@@ -153,14 +153,18 @@
   }
 
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL_DEF( FT_Error )
   cid_size_request( FT_Size          size,
                     FT_Size_Request  req )
   {
+    FT_Error  error;
+
     PSH_Globals_Funcs  funcs;
 
 
-    FT_Request_Metrics( size->face, req );
+    error = FT_Request_Metrics( size->face, req );
+    if ( error )
+      goto Exit;
 
     funcs = cid_size_get_globals_funcs( (CID_Size)size );
 
@@ -170,7 +174,8 @@
                         size->metrics.y_scale,
                         0, 0 );
 
-    return FT_Err_Ok;
+  Exit:
+    return error;
   }
 
 
@@ -211,7 +216,7 @@
     /* release subrs */
     if ( face->subrs )
     {
-      FT_Int  n;
+      FT_UInt  n;
 
 
       for ( n = 0; n < cid->num_dicts; n++ )
@@ -479,11 +484,7 @@
 
 
     /* set default property values, cf. `ftt1drv.h' */
-#ifdef T1_CONFIG_OPTION_OLD_ENGINE
-    driver->hinting_engine = FT_HINTING_FREETYPE;
-#else
     driver->hinting_engine = FT_HINTING_ADOBE;
-#endif
 
     driver->no_stem_darkening = TRUE;
 
diff --git a/src/cid/cidobjs.h b/src/cid/cidobjs.h
index 33a2e7a..83c0c61 100644
--- a/src/cid/cidobjs.h
+++ b/src/cid/cidobjs.h
@@ -4,7 +4,7 @@
  *
  *   CID objects manager (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,9 +21,9 @@
 
 
 #include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/internal/t1types.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/cid/cidparse.c b/src/cid/cidparse.c
index 861c157..16889db 100644
--- a/src/cid/cidparse.c
+++ b/src/cid/cidparse.c
@@ -4,7 +4,7 @@
  *
  *   CID-keyed Type1 parser (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftstream.h>
 
 #include "cidparse.h"
 
@@ -33,7 +32,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cidparse
+#define FT_COMPONENT  cidparse
 
 
   /*************************************************************************/
@@ -74,7 +73,11 @@
 
     /* first of all, check the font format in the header */
     if ( FT_FRAME_ENTER( 31 ) )
+    {
+      FT_TRACE2(( "  not a CID-keyed font\n" ));
+      error = FT_THROW( Unknown_File_Format );
       goto Exit;
+    }
 
     if ( ft_strncmp( (char *)stream->cursor,
                      "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
@@ -182,7 +185,7 @@
     parser->root.base      = parser->postscript;
     parser->root.cursor    = parser->postscript;
     parser->root.limit     = parser->root.cursor + ps_len;
-    parser->num_dict       = -1;
+    parser->num_dict       = FT_UINT_MAX;
 
     /* Finally, we check whether `StartData' or `/sfnts' was real --  */
     /* it could be in a comment or string.  We also get the arguments */
diff --git a/src/cid/cidparse.h b/src/cid/cidparse.h
index 029c6ae..2fd4e7a 100644
--- a/src/cid/cidparse.h
+++ b/src/cid/cidparse.h
@@ -4,7 +4,7 @@
  *
  *   CID-keyed Type1 parser (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,10 +20,9 @@
 #define CIDPARSE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_TYPE1_TYPES_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psaux.h>
 
 
 FT_BEGIN_HEADER
@@ -79,7 +78,7 @@
     FT_ULong      binary_length;
 
     CID_FaceInfo  cid;
-    FT_Int        num_dict;
+    FT_UInt       num_dict;
 
   } CID_Parser;
 
diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c
index 935c112..f749923 100644
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -4,7 +4,7 @@
  *
  *   CID driver interface (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,22 +16,21 @@
  */
 
 
-#include <ft2build.h>
 #include "cidriver.h"
 #include "cidgload.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_POSTSCRIPT_PROPS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftpsprop.h>
 
 #include "ciderrs.h"
 
-#include FT_SERVICE_POSTSCRIPT_NAME_H
-#include FT_SERVICE_FONT_FORMAT_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
-#include FT_SERVICE_CID_H
-#include FT_SERVICE_PROPERTIES_H
-#include FT_DRIVER_H
+#include <freetype/internal/services/svpostnm.h>
+#include <freetype/internal/services/svfntfmt.h>
+#include <freetype/internal/services/svpsinfo.h>
+#include <freetype/internal/services/svcid.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/ftdriver.h>
 
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/psaux.h>
 
 
   /**************************************************************************
@@ -41,7 +40,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ciddriver
+#define FT_COMPONENT  ciddriver
 
 
   /*
diff --git a/src/cid/cidriver.h b/src/cid/cidriver.h
index 2933808..a624938 100644
--- a/src/cid/cidriver.h
+++ b/src/cid/cidriver.h
@@ -4,7 +4,7 @@
  *
  *   High-level CID driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define CIDRIVER_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/cid/cidtoken.h b/src/cid/cidtoken.h
index d957e5a..925951a 100644
--- a/src/cid/cidtoken.h
+++ b/src/cid/cidtoken.h
@@ -4,7 +4,7 @@
  *
  *   CID token definitions (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/cid/module.mk b/src/cid/module.mk
index 9010e33..563cb34 100644
--- a/src/cid/module.mk
+++ b/src/cid/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/cid/rules.mk b/src/cid/rules.mk
index 94333bd..c526ad3 100644
--- a/src/cid/rules.mk
+++ b/src/cid/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/cid/type1cid.c b/src/cid/type1cid.c
index 02d9400..905c896 100644
--- a/src/cid/type1cid.c
+++ b/src/cid/type1cid.c
@@ -4,7 +4,7 @@
  *
  *   FreeType OpenType driver component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "cidgload.c"
 #include "cidload.c"
diff --git a/src/dlg/dlgwrap.c b/src/dlg/dlgwrap.c
new file mode 100644
index 0000000..271241f
--- /dev/null
+++ b/src/dlg/dlgwrap.c
@@ -0,0 +1,32 @@
+/****************************************************************************
+ *
+ * dlgwrap.c
+ *
+ *   Wrapper file for the 'dlg' library (body only)
+ *
+ * Copyright (C) 2020-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 <ft2build.h>
+#include FT_CONFIG_OPTIONS_H
+
+
+#ifdef FT_DEBUG_LOGGING
+#define DLG_STATIC
+#include "dlg.c"
+#else
+  /* ANSI C doesn't like empty source files */
+  typedef int  _dlg_dummy;
+#endif
+
+
+/* END */
diff --git a/src/dlg/rules.mk b/src/dlg/rules.mk
new file mode 100644
index 0000000..7f506fd
--- /dev/null
+++ b/src/dlg/rules.mk
@@ -0,0 +1,70 @@
+#
+# FreeType 2 dlg logging library configuration rules
+#
+
+
+# Copyright (C) 2020-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.
+
+
+# dlg logging library directory
+#
+DLG_DIR := $(SRC_DIR)/dlg
+
+
+# compilation flags for the library
+#
+DLG_COMPILE := $(CC) $(ANSIFLAGS)                            \
+                     $I$(subst /,$(COMPILER_SEP),$(DLG_DIR)) \
+                     $(INCLUDE_FLAGS)                        \
+                     $(FT_CFLAGS)
+
+
+# dlg logging library sources (i.e., C files)
+#
+DLG_SRC := $(DLG_DIR)/dlgwrap.c
+
+# dlg logging library headers
+#
+DLG_H := $(TOP_DIR)/include/dlg/dlg.h \
+         $(TOP_DIR)/include/dlg/output.h
+
+
+# dlg logging library object(s)
+#
+#   DLG_OBJ_M is used during `multi' builds
+#   DLG_OBJ_S is used during `single' builds
+#
+DLG_OBJ_M := $(DLG_SRC:$(DLG_DIR)/%.c=$(OBJ_DIR)/%.$O)
+DLG_OBJ_S := $(OBJ_DIR)/dlg.$O
+
+# dlg logging library source file for single build
+#
+DLG_SRC_S := $(DLG_DIR)/dlgwrap.c
+
+
+# dlg logging library - single object
+#
+$(DLG_OBJ_S): $(DLG_SRC_S) $(DLG_SRC) $(FREETYPE_H) $(DLG_H)
+	$(DLG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(DLG_SRC_S))
+
+
+# dlg logging library - multiple objects
+#
+$(OBJ_DIR)/%.$O: $(DLG_DIR)/%.c $(FREETYPE_H) $(DLG_H)
+	$(DLG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+
+
+# update main object lists
+#
+DLG_OBJS_S += $(DLG_OBJ_S)
+DLG_OBJS_M += $(DLG_OBJ_M)
+
+
+# EOF
diff --git a/src/gxvalid/Jamfile b/src/gxvalid/Jamfile
deleted file mode 100644
index 74f3c51..0000000
--- a/src/gxvalid/Jamfile
+++ /dev/null
@@ -1,52 +0,0 @@
-# FreeType 2 src/gxvalid Jamfile
-#
-# Copyright 2005-2018 by
-# suzuki toshiya, Masatake YAMATO and Red Hat K.K.
-#
-# 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) gxvalid ;
-
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = gxvbsln
-               gxvcommn
-               gxvfeat
-               gxvjust
-               gxvkern
-               gxvlcar
-               gxvmod
-               gxvmort
-               gxvmort0
-               gxvmort1
-               gxvmort2
-               gxvmort4
-               gxvmort5
-               gxvmorx
-               gxvmorx0
-               gxvmorx1
-               gxvmorx2
-               gxvmorx4
-               gxvmorx5
-               gxvopbd
-               gxvprop
-               gxvtrak
-               ;
-  }
-  else
-  {
-    _sources = gxvalid ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/gxvalid Jamfile
diff --git a/src/gxvalid/README b/src/gxvalid/README
index af8128e..0e3db32 100644
--- a/src/gxvalid/README
+++ b/src/gxvalid/README
@@ -518,7 +518,7 @@
 
 ------------------------------------------------------------------------
 
-Copyright 2004-2018 by
+Copyright (C) 2004-2023 by
 suzuki toshiya, Masatake YAMATO, Red hat K.K.,
 David Turner, Robert Wilhelm, and Werner Lemberg.
 
diff --git a/src/gxvalid/gxvalid.c b/src/gxvalid/gxvalid.c
index f49e8b7..e0359f4 100644
--- a/src/gxvalid/gxvalid.c
+++ b/src/gxvalid/gxvalid.c
@@ -4,7 +4,7 @@
  *
  *   FreeType validator for TrueTypeGX/AAT tables (body only).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -18,7 +18,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "gxvbsln.c"
 #include "gxvcommn.c"
diff --git a/src/gxvalid/gxvalid.h b/src/gxvalid/gxvalid.h
index cf02fcb..a83408b 100644
--- a/src/gxvalid/gxvalid.h
+++ b/src/gxvalid/gxvalid.h
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT table validation (specification only).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -28,13 +28,12 @@
 #ifndef GXVALID_H_
 #define GXVALID_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
-#include "gxverror.h"          /* must come before FT_INTERNAL_VALIDATE_H */
+#include "gxverror.h"                     /* must come before `ftvalid.h' */
 
-#include FT_INTERNAL_VALIDATE_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftvalid.h>
+#include <freetype/internal/ftstream.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/gxvalid/gxvbsln.c b/src/gxvalid/gxvbsln.c
index 8b554fd..030a64e 100644
--- a/src/gxvalid/gxvbsln.c
+++ b/src/gxvalid/gxvbsln.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT bsln table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvbsln
+#define FT_COMPONENT  gxvbsln
 
 
   /*************************************************************************/
diff --git a/src/gxvalid/gxvcommn.c b/src/gxvalid/gxvcommn.c
index 4d8a4a2..7f90874 100644
--- a/src/gxvalid/gxvcommn.c
+++ b/src/gxvalid/gxvcommn.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT common tables validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -35,7 +35,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvcommon
+#define FT_COMPONENT  gxvcommon
 
 
   /*************************************************************************/
@@ -46,16 +46,11 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  static int
-  gxv_compare_ushort_offset( FT_UShort*  a,
-                             FT_UShort*  b )
+  FT_COMPARE_DEF( int )
+  gxv_compare_ushort_offset( const void*  a,
+                             const void*  b )
   {
-    if ( *a < *b )
-      return -1;
-    else if ( *a > *b )
-      return 1;
-    else
-      return 0;
+    return  *(FT_UShort*)a - *(FT_UShort*)b;
   }
 
 
@@ -78,7 +73,7 @@
     buff[nmemb] = limit;
 
     ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ),
-              ( int(*)(const void*, const void*) )gxv_compare_ushort_offset );
+              gxv_compare_ushort_offset );
 
     if ( buff[nmemb] > limit )
       FT_INVALID_OFFSET;
@@ -111,13 +106,17 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  static int
-  gxv_compare_ulong_offset( FT_ULong*  a,
-                            FT_ULong*  b )
+  FT_COMPARE_DEF( int )
+  gxv_compare_ulong_offset( const void*  a,
+                            const void*  b )
   {
-    if ( *a < *b )
+    FT_ULong  a_ = *(FT_ULong*)a;
+    FT_ULong  b_ = *(FT_ULong*)b;
+
+
+    if ( a_ < b_ )
       return -1;
-    else if ( *a > *b )
+    else if ( a_ > b_ )
       return 1;
     else
       return 0;
@@ -143,7 +142,7 @@
     buff[nmemb] = limit;
 
     ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ),
-              ( int(*)(const void*, const void*) )gxv_compare_ulong_offset );
+              gxv_compare_ulong_offset );
 
     if ( buff[nmemb] > limit )
       FT_INVALID_OFFSET;
@@ -439,7 +438,7 @@
       GXV_LIMIT_CHECK( 2 );
       if ( p + 2 >= limit )     /* some fonts have too-short fmt0 array */
       {
-        GXV_TRACE(( "too short, glyphs %d - %d are missing\n",
+        GXV_TRACE(( "too short, glyphs %d - %ld are missing\n",
                     i, gxvalid->face->num_glyphs ));
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
         break;
@@ -534,7 +533,7 @@
 
       if ( lastGlyph < firstGlyph )
       {
-        GXV_TRACE(( "reverse ordered range specification at unit %d:",
+        GXV_TRACE(( "reverse ordered range specification at unit %d:"
                     " lastGlyph %d < firstGlyph %d ",
                     unit, lastGlyph, firstGlyph ));
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
@@ -605,7 +604,7 @@
 
       if ( lastGlyph < firstGlyph )
       {
-        GXV_TRACE(( "reverse ordered range specification at unit %d:",
+        GXV_TRACE(( "reverse ordered range specification at unit %d:"
                     " lastGlyph %d < firstGlyph %d ",
                     unit, lastGlyph, firstGlyph ));
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
@@ -825,7 +824,7 @@
     face = gxvalid->face;
     if ( face->num_glyphs < gid )
     {
-      GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n",
+      GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %ld < %d\n",
                   face->num_glyphs, gid ));
       GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
     }
@@ -1034,7 +1033,7 @@
     GXV_NAME_ENTER( "StateArray" );
 
     GXV_TRACE(( "parse %d bytes by stateSize=%d maxClassID=%d\n",
-                (int)(*length_p), stateSize, (int)(maxClassID) ));
+                (int)( *length_p ), stateSize, (int)maxClassID ));
 
     /*
      * 2 states are predefined and must be described in StateArray:
@@ -1419,7 +1418,7 @@
     GXV_NAME_ENTER( "XStateArray" );
 
     GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n",
-                (int)(*length_p), stateSize, (int)(maxClassID) ));
+                (int)( *length_p ), (int)stateSize, (int)maxClassID ));
 
     /*
      * 2 states are predefined and must be described:
@@ -1493,9 +1492,11 @@
       state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) );
       if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) )
       {
-        FT_TRACE4(( "-> new state = %d (supposed)\n"
-                    "but newState index 0x%04x is not aligned to %d-classes\n",
-                    state, newState_idx,  1 + maxClassID ));
+        FT_TRACE4(( "-> new state = %d (supposed)\n",
+                    state ));
+        FT_TRACE4(( "but newState index 0x%04x"
+                    " is not aligned to %d-classes\n",
+                    newState_idx, 1 + maxClassID ));
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
       }
 
@@ -1581,10 +1582,10 @@
     stateArray = FT_NEXT_ULONG( p );
     entryTable = FT_NEXT_ULONG( p );
 
-    GXV_TRACE(( "nClasses =0x%08x\n", gxvalid->xstatetable.nClasses ));
-    GXV_TRACE(( "offset to classTable=0x%08x\n", classTable ));
-    GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray ));
-    GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable ));
+    GXV_TRACE(( "nClasses =0x%08lx\n", gxvalid->xstatetable.nClasses ));
+    GXV_TRACE(( "offset to classTable=0x%08lx\n", classTable ));
+    GXV_TRACE(( "offset to stateArray=0x%08lx\n", stateArray ));
+    GXV_TRACE(( "offset to entryTable=0x%08lx\n", entryTable ));
 
     if ( gxvalid->xstatetable.nClasses > 0xFFFFU )
       FT_INVALID_DATA;
diff --git a/src/gxvalid/gxvcommn.h b/src/gxvalid/gxvcommn.h
index 9834c57..f88d23a 100644
--- a/src/gxvalid/gxvcommn.h
+++ b/src/gxvalid/gxvcommn.h
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT common tables validation (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -43,10 +43,9 @@
 #define GXVCOMMN_H_
 
 
-#include <ft2build.h>
 #include "gxvalid.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_SFNT_NAMES_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftsnames.h>
 
 
 FT_BEGIN_HEADER
@@ -62,8 +61,11 @@
 
 #undef GXV_LOAD_UNUSED_VARS /* debug purpose */
 
-#define IS_PARANOID_VALIDATION          ( gxvalid->root->level >= FT_VALIDATE_PARANOID )
-#define GXV_SET_ERR_IF_PARANOID( err )  { if ( IS_PARANOID_VALIDATION ) ( err ); }
+#define IS_PARANOID_VALIDATION                             \
+          ( gxvalid->root->level >= FT_VALIDATE_PARANOID )
+#define GXV_SET_ERR_IF_PARANOID( err )                              \
+          do { if ( IS_PARANOID_VALIDATION ) ( err ); } while ( 0 )
+
 
   /*************************************************************************/
   /*************************************************************************/
@@ -262,17 +264,17 @@
   } GXV_ValidatorRec;
 
 
-#define GXV_TABLE_DATA( tag, field )                           \
+#define GXV_TABLE_DATA( tag, field )                             \
         ( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field )
 
 #undef  FT_INVALID_
-#define FT_INVALID_( _error ) \
+#define FT_INVALID_( _error )                                     \
           ft_validator_error( gxvalid->root, FT_THROW( _error ) )
 
-#define GXV_LIMIT_CHECK( _count )                                     \
-          FT_BEGIN_STMNT                                              \
+#define GXV_LIMIT_CHECK( _count )                                       \
+          FT_BEGIN_STMNT                                                \
             if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \
-              FT_INVALID_TOO_SHORT;                                   \
+              FT_INVALID_TOO_SHORT;                                     \
           FT_END_STMNT
 
 
@@ -280,19 +282,19 @@
 
 #define GXV_INIT  gxvalid->debug_indent = 0
 
-#define GXV_NAME_ENTER( name )                             \
-          FT_BEGIN_STMNT                                   \
-            gxvalid->debug_indent += 2;                      \
-            FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \
-            FT_TRACE4(( "%s table\n", name ));             \
+#define GXV_NAME_ENTER( name )                                \
+          FT_BEGIN_STMNT                                      \
+            gxvalid->debug_indent += 2;                       \
+            FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \
+            FT_TRACE4(( "%s table\n", name ));                \
           FT_END_STMNT
 
 #define GXV_EXIT  gxvalid->debug_indent -= 2
 
-#define GXV_TRACE( s )                                     \
-          FT_BEGIN_STMNT                                   \
-            FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \
-            FT_TRACE4( s );                                \
+#define GXV_TRACE( s )                                        \
+          FT_BEGIN_STMNT                                      \
+            FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \
+            FT_TRACE4( s );                                   \
           FT_END_STMNT
 
 #else /* !FT_DEBUG_LEVEL_TRACE */
diff --git a/src/gxvalid/gxverror.h b/src/gxvalid/gxverror.h
index e36b076..09311ed 100644
--- a/src/gxvalid/gxverror.h
+++ b/src/gxvalid/gxverror.h
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT validation module error codes (specification only).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -35,7 +35,7 @@
 #ifndef GXVERROR_H_
 #define GXVERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -43,7 +43,7 @@
 #define FT_ERR_PREFIX  GXV_Err_
 #define FT_ERR_BASE    FT_Mod_Err_GXvalid
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* GXVERROR_H_ */
 
diff --git a/src/gxvalid/gxvfeat.c b/src/gxvalid/gxvfeat.c
index 91500bd..6cf1821 100644
--- a/src/gxvalid/gxvfeat.c
+++ b/src/gxvalid/gxvfeat.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT feat table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -37,7 +37,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvfeat
+#define FT_COMPONENT  gxvfeat
 
 
   /*************************************************************************/
@@ -90,7 +90,7 @@
 
     if ( feature >= gxv_feat_registry_length )
     {
-      GXV_TRACE(( "feature number %d is out of range %d\n",
+      GXV_TRACE(( "feature number %d is out of range %lu\n",
                   feature, gxv_feat_registry_length ));
       GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
       goto Exit;
diff --git a/src/gxvalid/gxvfeat.h b/src/gxvalid/gxvfeat.h
index 715791d..b33c1bc 100644
--- a/src/gxvalid/gxvfeat.h
+++ b/src/gxvalid/gxvfeat.h
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT feat table validation (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
diff --git a/src/gxvalid/gxvfgen.c b/src/gxvalid/gxvfgen.c
index c95aebd..1153542 100644
--- a/src/gxvalid/gxvfgen.c
+++ b/src/gxvalid/gxvfgen.c
@@ -5,7 +5,7 @@
  *   Generate feature registry data for gxv `feat' validator.
  *   This program is derived from gxfeatreg.c in gxlayout.
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Masatake YAMATO and Redhat K.K.
  *
  * This file may only be used,
diff --git a/src/gxvalid/gxvjust.c b/src/gxvalid/gxvjust.c
index c8a9ab6..5cca94d 100644
--- a/src/gxvalid/gxvjust.c
+++ b/src/gxvalid/gxvjust.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT just table validation (body).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -28,7 +28,7 @@
 #include "gxvalid.h"
 #include "gxvcommn.h"
 
-#include FT_SFNT_NAMES_H
+#include <freetype/ftsnames.h>
 
 
   /**************************************************************************
@@ -38,7 +38,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvjust
+#define FT_COMPONENT  gxvjust
 
   /*
    * referred `just' table format specification:
@@ -72,11 +72,13 @@
                           const FT_String*  msg_tag,
                           GXV_Validator     gxvalid )
   {
+    FT_UNUSED( msg_tag );
+
     if ( gid < gxvalid->face->num_glyphs )
       return;
 
     GXV_TRACE(( "just table includes too large %s"
-                " GID=%d > %d (in maxp)\n",
+                " GID=%d > %ld (in maxp)\n",
                 msg_tag, gid, gxvalid->face->num_glyphs ));
     GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
   }
@@ -138,7 +140,7 @@
     count = FT_NEXT_ULONG( p );
     for ( i = 0; i < count; i++ )
     {
-      GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count ));
+      GXV_TRACE(( "validating wdc pair %lu/%lu\n", i + 1, count ));
       gxv_just_wdp_entry_validate( p, limit, gxvalid );
       p += gxvalid->subtable_length;
     }
@@ -154,7 +156,6 @@
   {
     FT_Bytes  p         = table;
     FT_Bytes  wdc_end   = table + GXV_JUST_DATA( wdc_offset_max );
-    FT_UInt   i;
 
 
     GXV_NAME_ENTER( "just justDeltaClusters" );
@@ -162,7 +163,7 @@
     if ( limit <= wdc_end )
       FT_INVALID_OFFSET;
 
-    for ( i = 0; p <= wdc_end; i++ )
+    while ( p <= wdc_end )
     {
       gxv_just_wdc_entry_validate( p, limit, gxvalid );
       p += gxvalid->subtable_length;
@@ -204,7 +205,8 @@
     if ( lowerLimit >= upperLimit )
     {
       GXV_TRACE(( "just table includes invalid range spec:"
-                  " lowerLimit(%d) > upperLimit(%d)\n"     ));
+                  " lowerLimit(%ld) > upperLimit(%ld)\n",
+                  lowerLimit, upperLimit ));
       GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
     }
 
@@ -292,14 +294,14 @@
     gxvalid->subtable_length = (FT_ULong)( p - table );
 
     if ( variantsAxis != 0x64756374L ) /* 'duct' */
-      GXV_TRACE(( "variantsAxis 0x%08x is non default value",
+      GXV_TRACE(( "variantsAxis 0x%08lx is non default value",
                    variantsAxis ));
 
     if ( minimumLimit > noStretchValue )
-      GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n",
+      GXV_TRACE(( "type4:minimumLimit 0x%08lx > noStretchValue 0x%08lx\n",
                   minimumLimit, noStretchValue ));
     else if ( noStretchValue > maximumLimit )
-      GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n",
+      GXV_TRACE(( "type4:noStretchValue 0x%08lx > maximumLimit 0x%08lx\n",
                   noStretchValue, maximumLimit ));
     else if ( !IS_PARANOID_VALIDATION )
       return;
@@ -387,7 +389,7 @@
 
     GXV_LIMIT_CHECK( 4 );
     actionCount = FT_NEXT_ULONG( p );
-    GXV_TRACE(( "actionCount = %d\n", actionCount ));
+    GXV_TRACE(( "actionCount = %lu\n", actionCount ));
 
     for ( i = 0; i < actionCount; i++ )
     {
@@ -512,14 +514,14 @@
     coverage        = FT_NEXT_USHORT( p );
     subFeatureFlags = FT_NEXT_ULONG( p );
 
-    GXV_TRACE(( "  justClassTable: coverage = 0x%04x (%s) ", coverage ));
+    GXV_TRACE(( "  justClassTable: coverage = 0x%04x ", coverage ));
     if ( ( coverage & 0x4000 ) == 0  )
       GXV_TRACE(( "ascending\n" ));
     else
       GXV_TRACE(( "descending\n" ));
 
     if ( subFeatureFlags )
-      GXV_TRACE(( "  justClassTable: nonzero value (0x%08x)"
+      GXV_TRACE(( "  justClassTable: nonzero value (0x%08lx)"
                   " in unused subFeatureFlags\n", subFeatureFlags ));
 
     gxvalid->statetable.optdata               = NULL;
@@ -682,7 +684,7 @@
 
 
     /* Version 1.0 (always:2000) */
-    GXV_TRACE(( " (version = 0x%08x)\n", version ));
+    GXV_TRACE(( " (version = 0x%08lx)\n", version ));
     if ( version != 0x00010000UL )
       FT_INVALID_FORMAT;
 
diff --git a/src/gxvalid/gxvkern.c b/src/gxvalid/gxvkern.c
index df9f10e..21fc245 100644
--- a/src/gxvalid/gxvkern.c
+++ b/src/gxvalid/gxvkern.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT kern table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -28,8 +28,8 @@
 #include "gxvalid.h"
 #include "gxvcommn.h"
 
-#include FT_SFNT_NAMES_H
-#include FT_SERVICE_GX_VALIDATE_H
+#include <freetype/ftsnames.h>
+#include <freetype/internal/services/svgxval.h>
 
 
   /**************************************************************************
@@ -39,7 +39,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvkern
+#define FT_COMPONENT  gxvkern
 
 
   /*************************************************************************/
@@ -487,7 +487,7 @@
 
     if ( gxvalid->face->num_glyphs != glyphCount )
     {
-      GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n",
+      GXV_TRACE(( "maxGID=%ld, but glyphCount=%d\n",
                   gxvalid->face->num_glyphs, glyphCount ));
       GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
     }
@@ -745,7 +745,7 @@
 #ifdef GXV_LOAD_TRACE_VARS
     FT_UShort  version = 0;    /* MS only: subtable version, unused */
 #endif
-    FT_ULong   length;         /* MS: 16bit, Apple: 32bit*/
+    FT_ULong   length;         /* MS: 16bit, Apple: 32bit */
     FT_UShort  coverage;
 #ifdef GXV_LOAD_TRACE_VARS
     FT_UShort  tupleIndex = 0; /* Apple only */
@@ -772,7 +772,7 @@
       tupleIndex = 0;
 #endif
       GXV_TRACE(( "Subtable version = %d\n", version ));
-      GXV_TRACE(( "Subtable length = %d\n", length ));
+      GXV_TRACE(( "Subtable length = %lu\n", length ));
       break;
 
     case KERN_DIALECT_APPLE:
@@ -783,7 +783,7 @@
 #ifdef GXV_LOAD_TRACE_VARS
       tupleIndex = 0;
 #endif
-      GXV_TRACE(( "Subtable length = %d\n", length ));
+      GXV_TRACE(( "Subtable length = %lu\n", length ));
 
       if ( KERN_IS_NEW( gxvalid ) )
       {
@@ -800,7 +800,7 @@
     default:
       length = u16[1];
       GXV_TRACE(( "cannot detect subtable dialect, "
-                  "just skip %d byte\n", length ));
+                  "just skip %lu byte\n", length ));
       goto Exit;
     }
 
@@ -884,7 +884,7 @@
 
     for ( i = 0; i < nTables; i++ )
     {
-      GXV_TRACE(( "validating subtable %d/%d\n", i, nTables ));
+      GXV_TRACE(( "validating subtable %d/%lu\n", i, nTables ));
       /* p should be 32bit-aligned? */
       gxv_kern_subtable_validate( p, 0, gxvalid );
       p += gxvalid->subtable_length;
diff --git a/src/gxvalid/gxvlcar.c b/src/gxvalid/gxvlcar.c
index fd167f6..5f3bf89 100644
--- a/src/gxvalid/gxvlcar.c
+++ b/src/gxvalid/gxvlcar.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT lcar table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvlcar
+#define FT_COMPONENT  gxvlcar
 
 
   /*************************************************************************/
diff --git a/src/gxvalid/gxvmod.c b/src/gxvalid/gxvmod.c
index 847e0f1..0b4115b 100644
--- a/src/gxvalid/gxvmod.c
+++ b/src/gxvalid/gxvmod.c
@@ -4,7 +4,7 @@
  *
  *   FreeType's TrueTypeGX/AAT validation module implementation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -25,12 +25,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_GX_VALIDATE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_GX_VALIDATE_H
+#include <freetype/tttables.h>
+#include <freetype/tttags.h>
+#include <freetype/ftgxval.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svgxval.h>
 
 #include "gxvmod.h"
 #include "gxvalid.h"
@@ -44,7 +43,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmodule
+#define FT_COMPONENT  gxvmodule
 
 
   static FT_Error
@@ -63,7 +62,7 @@
     if ( error )
       goto Exit;
 
-    if ( FT_ALLOC( *table, *table_len ) )
+    if ( FT_QALLOC( *table, *table_len ) )
       goto Exit;
 
     error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
@@ -77,27 +76,31 @@
           FT_Byte* volatile  _sfnt          = NULL; \
           FT_ULong            len_ ## _sfnt = 0
 
-#define GXV_TABLE_LOAD( _sfnt )                                     \
-          if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \
-               ( gx_flags & FT_VALIDATE_ ## _sfnt )            )    \
-          {                                                         \
-            error = gxv_load_table( face, TTAG_ ## _sfnt,           \
-                                    &_sfnt, &len_ ## _sfnt );       \
-            if ( error )                                            \
-              goto Exit;                                            \
-          }
+#define GXV_TABLE_LOAD( _sfnt )                                       \
+          FT_BEGIN_STMNT                                              \
+            if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \
+                 ( gx_flags & FT_VALIDATE_ ## _sfnt )            )    \
+            {                                                         \
+              error = gxv_load_table( face, TTAG_ ## _sfnt,           \
+                                      &_sfnt, &len_ ## _sfnt );       \
+              if ( error )                                            \
+                goto Exit;                                            \
+            }                                                         \
+          FT_END_STMNT
 
-#define GXV_TABLE_VALIDATE( _sfnt )                                  \
-          if ( _sfnt )                                               \
-          {                                                          \
-            ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
-                               FT_VALIDATE_DEFAULT );                \
-            if ( ft_setjmp( valid.jump_buffer ) == 0 )               \
-              gxv_ ## _sfnt ## _validate( _sfnt, face, &valid );     \
-            error = valid.error;                                     \
-            if ( error )                                             \
-              goto Exit;                                             \
-          }
+#define GXV_TABLE_VALIDATE( _sfnt )                                    \
+          FT_BEGIN_STMNT                                               \
+            if ( _sfnt )                                               \
+            {                                                          \
+              ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
+                                 FT_VALIDATE_DEFAULT );                \
+              if ( ft_setjmp( valid.jump_buffer ) == 0 )               \
+                gxv_ ## _sfnt ## _validate( _sfnt, face, &valid );     \
+              error = valid.error;                                     \
+              if ( error )                                             \
+                goto Exit;                                             \
+            }                                                          \
+          FT_END_STMNT
 
 #define GXV_TABLE_SET( _sfnt )                                        \
           if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count )        \
diff --git a/src/gxvalid/gxvmod.h b/src/gxvalid/gxvmod.h
index f6a2502..db3d1d9 100644
--- a/src/gxvalid/gxvmod.h
+++ b/src/gxvalid/gxvmod.h
@@ -5,7 +5,7 @@
  *   FreeType's TrueTypeGX/AAT validation module implementation
  *   (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -29,8 +29,7 @@
 #ifndef GXVMOD_H_
 #define GXVMOD_H_
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/gxvalid/gxvmort.c b/src/gxvalid/gxvmort.c
index 1dfa5a3..7032d63 100644
--- a/src/gxvalid/gxvmort.c
+++ b/src/gxvalid/gxvmort.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT mort table validation (body).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmort
+#define FT_COMPONENT  gxvmort
 
 
   static void
@@ -123,6 +123,7 @@
                               GXV_Validator  gxvalid )
   {
     FT_UNUSED( gxvalid );
+    FT_UNUSED( coverage );
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( coverage & 0x8000U )
@@ -287,7 +288,7 @@
 
     for ( i = 0; i < nChains; i++ )
     {
-      GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains ));
+      GXV_TRACE(( "validating chain %lu/%lu\n", i + 1, nChains ));
       GXV_32BIT_ALIGNMENT_VALIDATE( p - table );
       gxv_mort_chain_validate( p, limit, gxvalid );
       p += gxvalid->subtable_length;
diff --git a/src/gxvalid/gxvmort.h b/src/gxvalid/gxvmort.h
index c2dc657..5c819bd 100644
--- a/src/gxvalid/gxvmort.h
+++ b/src/gxvalid/gxvmort.h
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT common definition for mort table (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -31,7 +31,10 @@
 #include "gxvalid.h"
 #include "gxvcommn.h"
 
-#include FT_SFNT_NAMES_H
+#include <freetype/ftsnames.h>
+
+
+FT_BEGIN_HEADER
 
 
   typedef struct  GXV_mort_featureRec_
@@ -88,6 +91,8 @@
                                     GXV_Validator  gxvalid );
 
 
+FT_END_HEADER
+
 #endif /* GXVMORT_H_ */
 
 
diff --git a/src/gxvalid/gxvmort0.c b/src/gxvalid/gxvmort0.c
index c7901cb..24e70a0 100644
--- a/src/gxvalid/gxvmort0.c
+++ b/src/gxvalid/gxvmort0.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT mort table validation
  *   body for type0 (Indic Script Rearrangement) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmort
+#define FT_COMPONENT  gxvmort
 
 
   static const char* GXV_Mort_IndicScript_Msg[] =
diff --git a/src/gxvalid/gxvmort1.c b/src/gxvalid/gxvmort1.c
index f2f4f57..ea5591f 100644
--- a/src/gxvalid/gxvmort1.c
+++ b/src/gxvalid/gxvmort1.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT mort table validation
  *   body for type1 (Contextual Substitution) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmort
+#define FT_COMPONENT  gxvmort
 
 
   typedef struct  GXV_mort_subtable_type1_StateOptRec_
diff --git a/src/gxvalid/gxvmort2.c b/src/gxvalid/gxvmort2.c
index 33fea0f..50644f0 100644
--- a/src/gxvalid/gxvmort2.c
+++ b/src/gxvalid/gxvmort2.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT mort table validation
  *   body for type2 (Ligature Substitution) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmort
+#define FT_COMPONENT  gxvmort
 
 
   typedef struct  GXV_mort_subtable_type2_StateOptRec_
@@ -152,7 +152,7 @@
     GXV_32BIT_ALIGNMENT_VALIDATE( ligActionOffset );
     if ( p < lat_base )
     {
-      GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n",
+      GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%ld byte rewind)\n",
                   ligActionOffset, lat_base - p ));
 
       /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
@@ -160,7 +160,7 @@
     }
     else if ( lat_limit < p )
     {
-      GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n",
+      GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%ld byte overrun)\n",
                   ligActionOffset, p - lat_limit ));
 
       /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
@@ -187,17 +187,17 @@
       offset = lig_action & 0x3FFFFFFFUL;
       if ( offset * 2 < optdata->ligatureTable )
       {
-        GXV_TRACE(( "too short offset 0x%08x:"
-                    " 2 x offset < ligatureTable (%d byte rewind)\n",
+        GXV_TRACE(( "too short offset 0x%08lx:"
+                    " 2 x offset < ligatureTable (%lu byte rewind)\n",
                      offset, optdata->ligatureTable - offset * 2 ));
 
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
       } else if ( offset * 2 >
                   optdata->ligatureTable + optdata->ligatureTable_length )
       {
-        GXV_TRACE(( "too long offset 0x%08x:"
+        GXV_TRACE(( "too long offset 0x%08lx:"
                     " 2 x offset > ligatureTable + ligatureTable_length"
-                    " (%d byte overrun)\n",
+                    " (%lu byte overrun)\n",
                      offset,
                      optdata->ligatureTable + optdata->ligatureTable_length
                      - offset * 2 ));
diff --git a/src/gxvalid/gxvmort4.c b/src/gxvalid/gxvmort4.c
index 6cf1e80..0641b11 100644
--- a/src/gxvalid/gxvmort4.c
+++ b/src/gxvalid/gxvmort4.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT mort table validation
  *   body for type4 (Non-Contextual Glyph Substitution) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmort
+#define FT_COMPONENT  gxvmort
 
 
   static void
diff --git a/src/gxvalid/gxvmort5.c b/src/gxvalid/gxvmort5.c
index ae94e22..9225bb0 100644
--- a/src/gxvalid/gxvmort5.c
+++ b/src/gxvalid/gxvmort5.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT mort table validation
  *   body for type5 (Contextual Glyph Insertion) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmort
+#define FT_COMPONENT  gxvmort
 
 
   /*
@@ -63,7 +63,7 @@
     *GXV_mort_subtable_type5_StateOptRecData;
 
 
-  FT_LOCAL_DEF( void )
+  static void
   gxv_mort_subtable_type5_subtable_setup( FT_UShort      table_size,
                                           FT_UShort      classTable,
                                           FT_UShort      stateArray,
diff --git a/src/gxvalid/gxvmorx.c b/src/gxvalid/gxvmorx.c
index f02ff54..931bf00 100644
--- a/src/gxvalid/gxvmorx.c
+++ b/src/gxvalid/gxvmorx.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT morx table validation (body).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -35,7 +35,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmorx
+#define FT_COMPONENT  gxvmorx
 
 
   static void
@@ -84,7 +84,7 @@
       p += 4;
 #endif
 
-      GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
+      GXV_TRACE(( "validating chain subtable %d/%d (%lu bytes)\n",
                   i + 1, nSubtables, length ));
 
       type = coverage & 0x0007;
@@ -99,7 +99,7 @@
 
       func = fmt_funcs_table[type];
       if ( !func )
-        GXV_TRACE(( "morx type %d is reserved\n", type ));
+        GXV_TRACE(( "morx type %lu is reserved\n", type ));
 
       func( p, p + rest, gxvalid );
 
@@ -186,7 +186,7 @@
 
     for ( i = 0; i < nChains; i++ )
     {
-      GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains ));
+      GXV_TRACE(( "validating chain %lu/%lu\n", i + 1, nChains ));
       GXV_32BIT_ALIGNMENT_VALIDATE( p - table );
       gxv_morx_chain_validate( p, limit, gxvalid );
       p += gxvalid->subtable_length;
diff --git a/src/gxvalid/gxvmorx.h b/src/gxvalid/gxvmorx.h
index 1ded623..2757255 100644
--- a/src/gxvalid/gxvmorx.h
+++ b/src/gxvalid/gxvmorx.h
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT common definition for morx table (specification).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -33,7 +33,10 @@
 #include "gxvcommn.h"
 #include "gxvmort.h"
 
-#include FT_SFNT_NAMES_H
+#include <freetype/ftsnames.h>
+
+
+FT_BEGIN_HEADER
 
 
   FT_LOCAL( void )
@@ -62,6 +65,8 @@
                                     GXV_Validator  gxvalid );
 
 
+FT_END_HEADER
+
 #endif /* GXVMORX_H_ */
 
 
diff --git a/src/gxvalid/gxvmorx0.c b/src/gxvalid/gxvmorx0.c
index d65ced5..73523f3 100644
--- a/src/gxvalid/gxvmorx0.c
+++ b/src/gxvalid/gxvmorx0.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT morx table validation
  *   body for type0 (Indic Script Rearrangement) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmorx
+#define FT_COMPONENT  gxvmorx
 
 
   static void
diff --git a/src/gxvalid/gxvmorx1.c b/src/gxvalid/gxvmorx1.c
index 1c8da1b..71a2018 100644
--- a/src/gxvalid/gxvmorx1.c
+++ b/src/gxvalid/gxvmorx1.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT morx table validation
  *   body for type1 (Contextual Substitution) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmorx
+#define FT_COMPONENT  gxvmorx
 
 
   typedef struct  GXV_morx_subtable_type1_StateOptRec_
diff --git a/src/gxvalid/gxvmorx2.c b/src/gxvalid/gxvmorx2.c
index d20fc57..858c811 100644
--- a/src/gxvalid/gxvmorx2.c
+++ b/src/gxvalid/gxvmorx2.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT morx table validation
  *   body for type2 (Ligature Substitution) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmorx
+#define FT_COMPONENT  gxvmorx
 
 
   typedef struct  GXV_morx_subtable_type2_StateOptRec_
@@ -72,11 +72,11 @@
     optdata->componentTable = FT_NEXT_ULONG( p );
     optdata->ligatureTable  = FT_NEXT_ULONG( p );
 
-    GXV_TRACE(( "offset to ligActionTable=0x%08x\n",
+    GXV_TRACE(( "offset to ligActionTable=0x%08lx\n",
                 optdata->ligActionTable ));
-    GXV_TRACE(( "offset to componentTable=0x%08x\n",
+    GXV_TRACE(( "offset to componentTable=0x%08lx\n",
                 optdata->componentTable ));
-    GXV_TRACE(( "offset to ligatureTable=0x%08x\n",
+    GXV_TRACE(( "offset to ligatureTable=0x%08lx\n",
                 optdata->ligatureTable ));
   }
 
@@ -116,19 +116,19 @@
 
     gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, gxvalid );
 
-    GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n",
+    GXV_TRACE(( "classTable: offset=0x%08lx length=0x%08lx\n",
                 classTable, *classTable_length_p ));
-    GXV_TRACE(( "stateArray: offset=0x%08x length=0x%08x\n",
+    GXV_TRACE(( "stateArray: offset=0x%08lx length=0x%08lx\n",
                 stateArray, *stateArray_length_p ));
-    GXV_TRACE(( "entryTable: offset=0x%08x length=0x%08x\n",
+    GXV_TRACE(( "entryTable: offset=0x%08lx length=0x%08lx\n",
                 entryTable, *entryTable_length_p ));
-    GXV_TRACE(( "ligActionTable: offset=0x%08x length=0x%08x\n",
+    GXV_TRACE(( "ligActionTable: offset=0x%08lx length=0x%08lx\n",
                 optdata->ligActionTable,
                 optdata->ligActionTable_length ));
-    GXV_TRACE(( "componentTable: offset=0x%08x length=0x%08x\n",
+    GXV_TRACE(( "componentTable: offset=0x%08lx length=0x%08lx\n",
                 optdata->componentTable,
                 optdata->componentTable_length ));
-    GXV_TRACE(( "ligatureTable:  offset=0x%08x length=0x%08x\n",
+    GXV_TRACE(( "ligatureTable:  offset=0x%08lx length=0x%08lx\n",
                 optdata->ligatureTable,
                 optdata->ligatureTable_length ));
 
@@ -157,12 +157,12 @@
 
     if ( p < lat_base )
     {
-      GXV_TRACE(( "p < lat_base (%d byte rewind)\n", lat_base - p ));
+      GXV_TRACE(( "p < lat_base (%ld byte rewind)\n", lat_base - p ));
       FT_INVALID_OFFSET;
     }
     else if ( lat_limit < p )
     {
-      GXV_TRACE(( "lat_limit < p (%d byte overrun)\n", p - lat_limit ));
+      GXV_TRACE(( "lat_limit < p (%ld byte overrun)\n", p - lat_limit ));
       FT_INVALID_OFFSET;
     }
 
@@ -196,7 +196,7 @@
 
         GXV_TRACE(( "ligature action table includes"
                     " too negative offset moving all GID"
-                    " below defined range: 0x%04x\n",
+                    " below defined range: 0x%04lx\n",
                     offset & 0xFFFFU ));
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
       }
@@ -207,14 +207,14 @@
 
         GXV_TRACE(( "ligature action table includes"
                     " too large offset moving all GID"
-                    " over defined range: 0x%04x\n",
+                    " over defined range: 0x%04lx\n",
                     offset & 0xFFFFU ));
         GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
       }
 
       GXV_TRACE(( "ligature action table includes"
                   " invalid offset to add to 16-bit GID:"
-                  " 0x%08x\n", offset ));
+                  " 0x%08lx\n", offset ));
       GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
     }
   }
diff --git a/src/gxvalid/gxvmorx4.c b/src/gxvalid/gxvmorx4.c
index fce219c..c9ad199 100644
--- a/src/gxvalid/gxvmorx4.c
+++ b/src/gxvalid/gxvmorx4.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT morx table validation
  *   body for "morx" type4 (Non-Contextual Glyph Substitution) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmorx
+#define FT_COMPONENT  gxvmorx
 
 
   FT_LOCAL_DEF( void )
diff --git a/src/gxvalid/gxvmorx5.c b/src/gxvalid/gxvmorx5.c
index 8826954..95fa4e2 100644
--- a/src/gxvalid/gxvmorx5.c
+++ b/src/gxvalid/gxvmorx5.c
@@ -5,7 +5,7 @@
  *   TrueTypeGX/AAT morx table validation
  *   body for type5 (Contextual Glyph Insertion) subtable.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvmorx
+#define FT_COMPONENT  gxvmorx
 
 
   /*
diff --git a/src/gxvalid/gxvopbd.c b/src/gxvalid/gxvopbd.c
index 76b6961..5e9a966 100644
--- a/src/gxvalid/gxvopbd.c
+++ b/src/gxvalid/gxvopbd.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT opbd table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvopbd
+#define FT_COMPONENT  gxvopbd
 
 
   /*************************************************************************/
@@ -188,7 +188,7 @@
 
 
     /* only 0x00010000 is defined (1996) */
-    GXV_TRACE(( "(version=0x%08x)\n", version ));
+    GXV_TRACE(( "(version=0x%08lx)\n", version ));
     if ( 0x00010000UL != version )
       FT_INVALID_FORMAT;
 
diff --git a/src/gxvalid/gxvprop.c b/src/gxvalid/gxvprop.c
index 856dd10..63a052a 100644
--- a/src/gxvalid/gxvprop.c
+++ b/src/gxvalid/gxvprop.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT prop table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvprop
+#define FT_COMPONENT  gxvprop
 
 
   /*************************************************************************/
@@ -283,7 +283,7 @@
     format      = FT_NEXT_USHORT( p );
     defaultProp = FT_NEXT_USHORT( p );
 
-    GXV_TRACE(( "  version 0x%08x\n", version ));
+    GXV_TRACE(( "  version 0x%08lx\n", version ));
     GXV_TRACE(( "  format  0x%04x\n", format ));
     GXV_TRACE(( "  defaultProp  0x%04x\n", defaultProp ));
 
@@ -309,7 +309,7 @@
     if ( format == 0 )
     {
       FT_TRACE3(( "(format 0, no per-glyph properties, "
-                  "remaining %d bytes are skipped)", limit - p ));
+                  "remaining %ld bytes are skipped)", limit - p ));
       goto Exit;
     }
 
diff --git a/src/gxvalid/gxvtrak.c b/src/gxvalid/gxvtrak.c
index d2ceb66..f3fb51c 100644
--- a/src/gxvalid/gxvtrak.c
+++ b/src/gxvalid/gxvtrak.c
@@ -4,7 +4,7 @@
  *
  *   TrueTypeGX/AAT trak table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
@@ -36,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gxvtrak
+#define FT_COMPONENT  gxvtrak
 
 
   /*************************************************************************/
@@ -130,7 +130,7 @@
          p = table + j * ( 4 + 2 + 2 );
          t = FT_NEXT_LONG( p );
          if ( t == track )
-           GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
+           GXV_TRACE(( "duplicated entries found for track value 0x%lx\n",
                         track ));
       }
     }
@@ -243,7 +243,7 @@
     vertOffset  = FT_NEXT_USHORT( p );
     reserved    = FT_NEXT_USHORT( p );
 
-    GXV_TRACE(( " (version = 0x%08x)\n", version ));
+    GXV_TRACE(( " (version = 0x%08lx)\n", version ));
     GXV_TRACE(( " (format = 0x%04x)\n", format ));
     GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
     GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
diff --git a/src/gxvalid/module.mk b/src/gxvalid/module.mk
index b64879d..4949134 100644
--- a/src/gxvalid/module.mk
+++ b/src/gxvalid/module.mk
@@ -2,7 +2,7 @@
 # FreeType 2 gxvalid module definition
 #
 
-# Copyright 2004-2018 by
+# Copyright (C) 2004-2023 by
 # suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
diff --git a/src/gxvalid/rules.mk b/src/gxvalid/rules.mk
index 3a17c03..95ae633 100644
--- a/src/gxvalid/rules.mk
+++ b/src/gxvalid/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2004-2018 by
+# Copyright (C) 2004-2023 by
 # suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
diff --git a/src/gzip/Jamfile b/src/gzip/Jamfile
deleted file mode 100644
index a7b4c8c..0000000
--- a/src/gzip/Jamfile
+++ /dev/null
@@ -1,16 +0,0 @@
-# FreeType 2 src/gzip Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) gzip ;
-
-Library  $(FT2_LIB) : ftgzip.c ;
-
-# end of src/pcf Jamfile
diff --git a/src/gzip/LICENSE_ZLIB.TXT b/src/gzip/LICENSE_ZLIB.TXT
new file mode 100644
index 0000000..4c82b60
--- /dev/null
+++ b/src/gzip/LICENSE_ZLIB.TXT
@@ -0,0 +1,18 @@
+zlib License
+This software is provided 'as-is', without any express or implied warranty. In
+no event will the authors be held liable for any damages arising from the use of
+this software.
+
+Permission is granted to anyone to use this software for any purpose, including
+commercial applications, and to alter it and redistribute it freely, subject to
+the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim
+   that you wrote the original software. If you use this software in a product,
+   an acknowledgment in the product documentation would be appreciated but is
+   not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution.
diff --git a/src/gzip/README.freetype b/src/gzip/README.freetype
new file mode 100644
index 0000000..e0c8ced
--- /dev/null
+++ b/src/gzip/README.freetype
@@ -0,0 +1,23 @@
+Name: zlib
+Short Name: zlib
+URL: http://zlib.net/
+Version: 1.2.12
+License: see `zlib.h`
+
+Description:
+"A massively spiffy yet delicately unobtrusive compression library."
+
+'zlib' is a free, general-purpose, legally unencumbered lossless
+data-compression library.  'zlib' implements the "deflate" compression
+algorithm described by RFC 1951, which combines the LZ77 (Lempel-Ziv)
+algorithm with Huffman coding.  zlib also implements the zlib (RFC 1950) and
+gzip (RFC 1952) wrapper formats.
+
+Local Modifications:
+The files in this directory have been prepared as follows.
+
+ - Take the unmodified source code files from the zlib distribution that are
+   included by `ftgzip.c`.
+ - Copy `zconf.h` to `ftzconf.h` (which stays unmodified otherwise).
+ - Run zlib's `zlib2ansi` script on all `.c` files.
+ - Apply the diff file(s) in the `patches` folder.
diff --git a/src/gzip/adler32.c b/src/gzip/adler32.c
index c53f9dd..aa032e1 100644
--- a/src/gzip/adler32.c
+++ b/src/gzip/adler32.c
@@ -1,48 +1,192 @@
 /* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2002 Mark Adler
+ * Copyright (C) 1995-2011, 2016 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
-#include "zlib.h"
+#include "zutil.h"
 
-#define BASE 65521L /* largest prime smaller than 65536 */
+#ifndef Z_FREETYPE
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+#endif
+
+#define BASE 65521U     /* largest prime smaller than 65536 */
 #define NMAX 5552
 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
 
-#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
 
+/* use NO_DIVIDE if your processor does not do division in hardware --
+   try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+   (thank you to John Reiser for pointing this out) */
+#  define CHOP(a) \
+    do { \
+        unsigned long tmp = a >> 16; \
+        a &= 0xffffUL; \
+        a += (tmp << 4) - tmp; \
+    } while (0)
+#  define MOD28(a) \
+    do { \
+        CHOP(a); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD(a) \
+    do { \
+        CHOP(a); \
+        MOD28(a); \
+    } while (0)
+#  define MOD63(a) \
+    do { /* this assumes a is not negative */ \
+        z_off64_t tmp = a >> 32; \
+        a &= 0xffffffffL; \
+        a += (tmp << 8) - (tmp << 5) + tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD28(a) a %= BASE
+#  define MOD63(a) a %= BASE
+#endif
+
 /* ========================================================================= */
-ZEXPORT(uLong) adler32( /* adler, buf, len) */
+uLong ZEXPORT adler32_z(
     uLong adler,
     const Bytef *buf,
-    uInt len )
+    z_size_t len)
 {
-    unsigned long s1 = adler & 0xffff;
-    unsigned long s2 = (adler >> 16) & 0xffff;
-    int k;
+    unsigned long sum2;
+    unsigned n;
 
-    if (buf == Z_NULL) return 1L;
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
 
-    while (len > 0) {
-        k = len < NMAX ? len : NMAX;
-        len -= k;
-        while (k >= 16) {
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD28(sum2);            /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
             DO16(buf);
             buf += 16;
-            k -= 16;
         }
-        if (k != 0) do {
-            s1 += *buf++;
-            s2 += s1;
-        } while (--k);
-        s1 %= BASE;
-        s2 %= BASE;
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
     }
-    return (s2 << 16) | s1;
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
 }
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(
+    uLong adler,
+    const Bytef *buf,
+    uInt len)
+{
+    return adler32_z(adler, buf, len);
+}
+
+#ifndef Z_FREETYPE
+
+/* ========================================================================= */
+local uLong adler32_combine_(
+    uLong adler1,
+    uLong adler2,
+    z_off64_t len2)
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* for negative len, return invalid adler32 as a clue for debugging */
+    if (len2 < 0)
+        return 0xffffffffUL;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    MOD63(len2);                /* assumes len2 >= 0 */
+    rem = (unsigned)len2;
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(
+    uLong adler1,
+    uLong adler2,
+    z_off_t len2)
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(
+    uLong adler1,
+    uLong adler2,
+    z_off64_t len2)
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+#endif  /* !Z_FREETYPE */
diff --git a/src/gzip/crc32.c b/src/gzip/crc32.c
new file mode 100644
index 0000000..6cd1b09
--- /dev/null
+++ b/src/gzip/crc32.c
@@ -0,0 +1,1135 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2022 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * This interleaved implementation of a CRC makes use of pipelined multiple
+ * arithmetic-logic units, commonly found in modern CPU cores. It is due to
+ * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+
+  MAKECRCH can be #defined to write out crc32.h. A main() routine is also
+  produced, so that this one source file can be compiled to an executable.
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
+
+ /*
+  A CRC of a message is computed on N braids of words in the message, where
+  each word consists of W bytes (4 or 8). If N is 3, for example, then three
+  running sparse CRCs are calculated respectively on each braid, at these
+  indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ...
+  This is done starting at a word boundary, and continues until as many blocks
+  of N * W bytes as are available have been processed. The results are combined
+  into a single CRC at the end. For this code, N must be in the range 1..6 and
+  W must be 4 or 8. The upper limit on N can be increased if desired by adding
+  more #if blocks, extending the patterns apparent in the code. In addition,
+  crc32.h would need to be regenerated, if the maximum N value is increased.
+
+  N and W are chosen empirically by benchmarking the execution time on a given
+  processor. The choices for N and W below were based on testing on Intel Kaby
+  Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64
+  Octeon II processors. The Intel, AMD, and ARM processors were all fastest
+  with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4.
+  They were all tested with either gcc or clang, all using the -O3 optimization
+  level. Your mileage may vary.
+ */
+
+/* Define N */
+#ifdef Z_TESTN
+#  define N Z_TESTN
+#else
+#  define N 5
+#endif
+#if N < 1 || N > 6
+#  error N must be in 1..6
+#endif
+
+/*
+  z_crc_t must be at least 32 bits. z_word_t must be at least as long as
+  z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and
+  that bytes are eight bits.
+ */
+
+/*
+  Define W and the associated z_word_t type. If W is not defined, then a
+  braided calculation is not used, and the associated tables and code are not
+  compiled.
+ */
+#ifdef Z_TESTW
+#  if Z_TESTW-1 != -1
+#    define W Z_TESTW
+#  endif
+#else
+#  ifdef MAKECRCH
+#    define W 8         /* required for MAKECRCH */
+#  else
+#    if defined(__x86_64__) || defined(__aarch64__)
+#      define W 8
+#    else
+#      define W 4
+#    endif
+#  endif
+#endif
+#ifdef W
+#  if W == 8 && defined(Z_U8)
+     typedef Z_U8 z_word_t;
+#  elif defined(Z_U4)
+#    undef W
+#    define W 4
+     typedef Z_U4 z_word_t;
+#  else
+#    undef W
+#  endif
+#endif
+
+/* If available, use the ARM processor CRC32 instruction. */
+#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
+#  define ARMCRC32
+#endif
+
+#ifndef Z_FREETYPE
+/* Local functions. */
+local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
+local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
+#endif  /* Z_FREETYPE */
+
+#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
+    local z_word_t byte_swap OF((z_word_t word));
+#endif
+
+#if defined(W) && !defined(ARMCRC32)
+    local z_crc_t crc_word OF((z_word_t data));
+    local z_word_t crc_word_big OF((z_word_t data));
+#endif
+
+#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
+/*
+  Swap the bytes in a z_word_t to convert between little and big endian. Any
+  self-respecting compiler will optimize this to a single machine byte-swap
+  instruction, if one is available. This assumes that word_t is either 32 bits
+  or 64 bits.
+ */
+local z_word_t byte_swap(
+    z_word_t word)
+{
+#  if W == 8
+    return
+        (word & 0xff00000000000000) >> 56 |
+        (word & 0xff000000000000) >> 40 |
+        (word & 0xff0000000000) >> 24 |
+        (word & 0xff00000000) >> 8 |
+        (word & 0xff000000) << 8 |
+        (word & 0xff0000) << 24 |
+        (word & 0xff00) << 40 |
+        (word & 0xff) << 56;
+#  else   /* W == 4 */
+    return
+        (word & 0xff000000) >> 24 |
+        (word & 0xff0000) >> 8 |
+        (word & 0xff00) << 8 |
+        (word & 0xff) << 24;
+#  endif
+}
+#endif
+
+/* CRC polynomial. */
+#define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local z_crc_t FAR crc_table[256];
+local z_crc_t FAR x2n_table[32];
+local void make_crc_table OF((void));
+#ifdef W
+   local z_word_t FAR crc_big_table[256];
+   local z_crc_t FAR crc_braid_table[W][256];
+   local z_word_t FAR crc_braid_big_table[W][256];
+   local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
+#endif
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const z_crc_t FAR *, int));
+   local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
+   local void write_table64 OF((FILE *, const z_word_t FAR *, int));
+#endif /* MAKECRCH */
+
+/*
+  Define a once() function depending on the availability of atomics. If this is
+  compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
+  multiple threads, and if atomics are not available, then get_crc_table() must
+  be called to initialize the tables and must return before any threads are
+  allowed to compute or combine CRCs.
+ */
+
+/* Definition of once functionality. */
+typedef struct once_s once_t;
+local void once OF((once_t *, void (*)(void)));
+
+/* Check for the availability of atomics. */
+#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
+    !defined(__STDC_NO_ATOMICS__)
+
+#include <stdatomic.h>
+
+/* Structure for once(), which must be initialized with ONCE_INIT. */
+struct once_s {
+    atomic_flag begun;
+    atomic_int done;
+};
+#define ONCE_INIT {ATOMIC_FLAG_INIT, 0}
+
+/*
+  Run the provided init() function exactly once, even if multiple threads
+  invoke once() at the same time. The state must be a once_t initialized with
+  ONCE_INIT.
+ */
+local void once(state, init)
+    once_t *state;
+    void (*init)(void);
+{
+    if (!atomic_load(&state->done)) {
+        if (atomic_flag_test_and_set(&state->begun))
+            while (!atomic_load(&state->done))
+                ;
+        else {
+            init();
+            atomic_store(&state->done, 1);
+        }
+    }
+}
+
+#else   /* no atomics */
+
+/* Structure for once(), which must be initialized with ONCE_INIT. */
+struct once_s {
+    volatile int begun;
+    volatile int done;
+};
+#define ONCE_INIT {0, 0}
+
+/* Test and set. Alas, not atomic, but tries to minimize the period of
+   vulnerability. */
+local int test_and_set OF((int volatile *));
+local int test_and_set(
+    int volatile *flag)
+{
+    int was;
+
+    was = *flag;
+    *flag = 1;
+    return was;
+}
+
+/* Run the provided init() function once. This is not thread-safe. */
+local void once(state, init)
+    once_t *state;
+    void (*init)(void);
+{
+    if (!state->done) {
+        if (test_and_set(&state->begun))
+            while (!state->done)
+                ;
+        else {
+            init();
+            state->done = 1;
+        }
+    }
+}
+
+#endif
+
+/* State for once(). */
+local once_t made = ONCE_INIT;
+
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit. Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one. If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder. The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x
+  (which is shifting right by one and adding x^32 mod p if the bit shifted out
+  is a one). We start with the highest power (least significant bit) of q and
+  repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values. This is all the
+  information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+ */
+
+local void make_crc_table()
+{
+    unsigned i, j, n;
+    z_crc_t p;
+
+    /* initialize the CRC of bytes tables */
+    for (i = 0; i < 256; i++) {
+        p = i;
+        for (j = 0; j < 8; j++)
+            p = p & 1 ? (p >> 1) ^ POLY : p >> 1;
+        crc_table[i] = p;
+#ifdef W
+        crc_big_table[i] = byte_swap(p);
+#endif
+    }
+
+    /* initialize the x^2^n mod p(x) table */
+    p = (z_crc_t)1 << 30;         /* x^1 */
+    x2n_table[0] = p;
+    for (n = 1; n < 32; n++)
+        x2n_table[n] = p = multmodp(p, p);
+
+#ifdef W
+    /* initialize the braiding tables -- needs x2n_table[] */
+    braid(crc_braid_table, crc_braid_big_table, N, W);
+#endif
+
+#ifdef MAKECRCH
+    {
+        /*
+          The crc32.h header file contains tables for both 32-bit and 64-bit
+          z_word_t's, and so requires a 64-bit type be available. In that case,
+          z_word_t must be defined to be 64-bits. This code then also generates
+          and writes out the tables for the case that z_word_t is 32 bits.
+         */
+#if !defined(W) || W != 8
+#  error Need a 64-bit integer type in order to generate crc32.h.
+#endif
+        FILE *out;
+        int k, n;
+        z_crc_t ltl[8][256];
+        z_word_t big[8][256];
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+
+        /* write out little-endian CRC table to crc32.h */
+        fprintf(out,
+            "/* crc32.h -- tables for rapid CRC calculation\n"
+            " * Generated automatically by crc32.c\n */\n"
+            "\n"
+            "local const z_crc_t FAR crc_table[] = {\n"
+            "    ");
+        write_table(out, crc_table, 256);
+        fprintf(out,
+            "};\n");
+
+        /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */
+        fprintf(out,
+            "\n"
+            "#ifdef W\n"
+            "\n"
+            "#if W == 8\n"
+            "\n"
+            "local const z_word_t FAR crc_big_table[] = {\n"
+            "    ");
+        write_table64(out, crc_big_table, 256);
+        fprintf(out,
+            "};\n");
+
+        /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */
+        fprintf(out,
+            "\n"
+            "#else /* W == 4 */\n"
+            "\n"
+            "local const z_word_t FAR crc_big_table[] = {\n"
+            "    ");
+        write_table32hi(out, crc_big_table, 256);
+        fprintf(out,
+            "};\n"
+            "\n"
+            "#endif\n");
+
+        /* write out braid tables for each value of N */
+        for (n = 1; n <= 6; n++) {
+            fprintf(out,
+            "\n"
+            "#if N == %d\n", n);
+
+            /* compute braid tables for this N and 64-bit word_t */
+            braid(ltl, big, n, 8);
+
+            /* write out braid tables for 64-bit z_word_t to crc32.h */
+            fprintf(out,
+            "\n"
+            "#if W == 8\n"
+            "\n"
+            "local const z_crc_t FAR crc_braid_table[][256] = {\n");
+            for (k = 0; k < 8; k++) {
+                fprintf(out, "   {");
+                write_table(out, ltl[k], 256);
+                fprintf(out, "}%s", k < 7 ? ",\n" : "");
+            }
+            fprintf(out,
+            "};\n"
+            "\n"
+            "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
+            for (k = 0; k < 8; k++) {
+                fprintf(out, "   {");
+                write_table64(out, big[k], 256);
+                fprintf(out, "}%s", k < 7 ? ",\n" : "");
+            }
+            fprintf(out,
+            "};\n");
+
+            /* compute braid tables for this N and 32-bit word_t */
+            braid(ltl, big, n, 4);
+
+            /* write out braid tables for 32-bit z_word_t to crc32.h */
+            fprintf(out,
+            "\n"
+            "#else /* W == 4 */\n"
+            "\n"
+            "local const z_crc_t FAR crc_braid_table[][256] = {\n");
+            for (k = 0; k < 4; k++) {
+                fprintf(out, "   {");
+                write_table(out, ltl[k], 256);
+                fprintf(out, "}%s", k < 3 ? ",\n" : "");
+            }
+            fprintf(out,
+            "};\n"
+            "\n"
+            "local const z_word_t FAR crc_braid_big_table[][256] = {\n");
+            for (k = 0; k < 4; k++) {
+                fprintf(out, "   {");
+                write_table32hi(out, big[k], 256);
+                fprintf(out, "}%s", k < 3 ? ",\n" : "");
+            }
+            fprintf(out,
+            "};\n"
+            "\n"
+            "#endif\n"
+            "\n"
+            "#endif\n");
+        }
+        fprintf(out,
+            "\n"
+            "#endif\n");
+
+        /* write out zeros operator table to crc32.h */
+        fprintf(out,
+            "\n"
+            "local const z_crc_t FAR x2n_table[] = {\n"
+            "    ");
+        write_table(out, x2n_table, 32);
+        fprintf(out,
+            "};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+
+/*
+   Write the 32-bit values in table[0..k-1] to out, five per line in
+   hexadecimal separated by commas.
+ */
+local void write_table(
+    FILE *out,
+    const z_crc_t FAR *table,
+    int k)
+{
+    int n;
+
+    for (n = 0; n < k; n++)
+        fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
+                (unsigned long)(table[n]),
+                n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
+}
+
+/*
+   Write the high 32-bits of each value in table[0..k-1] to out, five per line
+   in hexadecimal separated by commas.
+ */
+local void write_table32hi(
+    FILE *out,
+    const z_word_t FAR *table,
+    int k)
+{
+    int n;
+
+    for (n = 0; n < k; n++)
+        fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
+                (unsigned long)(table[n] >> 32),
+                n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", "));
+}
+
+/*
+  Write the 64-bit values in table[0..k-1] to out, three per line in
+  hexadecimal separated by commas. This assumes that if there is a 64-bit
+  type, then there is also a long long integer type, and it is at least 64
+  bits. If not, then the type cast and format string can be adjusted
+  accordingly.
+ */
+local void write_table64(
+    FILE *out,
+    const z_word_t FAR *table,
+    int k)
+{
+    int n;
+
+    for (n = 0; n < k; n++)
+        fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : "    ",
+                (unsigned long long)(table[n]),
+                n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
+}
+
+/* Actually do the deed. */
+int main()
+{
+    make_crc_table();
+    return 0;
+}
+
+#endif /* MAKECRCH */
+
+#ifdef W
+/*
+  Generate the little and big-endian braid tables for the given n and z_word_t
+  size w. Each array must have room for w blocks of 256 elements.
+ */
+local void braid(ltl, big, n, w)
+    z_crc_t ltl[][256];
+    z_word_t big[][256];
+    int n;
+    int w;
+{
+    int k;
+    z_crc_t i, p, q;
+    for (k = 0; k < w; k++) {
+        p = x2nmodp((n * w + 3 - k) << 3, 0);
+        ltl[k][0] = 0;
+        big[w - 1 - k][0] = 0;
+        for (i = 1; i < 256; i++) {
+            ltl[k][i] = q = multmodp(i << 24, p);
+            big[w - 1 - k][i] = byte_swap(q);
+        }
+    }
+}
+#endif
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
+ * of x for combining CRC-32s, all made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* ========================================================================
+ * Routines used for CRC calculation. Some are also required for the table
+ * generation above.
+ */
+
+#ifndef Z_FREETYPE
+
+/*
+  Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
+  reflected. For speed, this requires that a not be zero.
+ */
+local z_crc_t multmodp(
+    z_crc_t a,
+    z_crc_t b)
+{
+    z_crc_t m, p;
+
+    m = (z_crc_t)1 << 31;
+    p = 0;
+    for (;;) {
+        if (a & m) {
+            p ^= b;
+            if ((a & (m - 1)) == 0)
+                break;
+        }
+        m >>= 1;
+        b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
+    }
+    return p;
+}
+
+/*
+  Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
+  initialized.
+ */
+local z_crc_t x2nmodp(
+    z_off64_t n,
+    unsigned k)
+{
+    z_crc_t p;
+
+    p = (z_crc_t)1 << 31;           /* x^0 == 1 */
+    while (n) {
+        if (n & 1)
+            p = multmodp(x2n_table[k & 31], p);
+        n >>= 1;
+        k++;
+    }
+    return p;
+}
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32(), and to force the
+ * generation of the CRC tables in a threaded application.
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const z_crc_t FAR *)crc_table;
+}
+
+#endif  /* Z_FREETYPE */
+
+/* =========================================================================
+ * Use ARM machine instructions if available. This will compute the CRC about
+ * ten times faster than the braided calculation. This code does not check for
+ * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will
+ * only be defined if the compilation specifies an ARM processor architecture
+ * that has the instructions. For example, compiling with -march=armv8.1-a or
+ * -march=armv8-a+crc, or -march=native if the compile machine has the crc32
+ * instructions.
+ */
+#ifdef ARMCRC32
+
+/*
+   Constants empirically determined to maximize speed. These values are from
+   measurements on a Cortex-A57. Your mileage may vary.
+ */
+#define Z_BATCH 3990                /* number of words in a batch */
+#define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
+#define Z_BATCH_MIN 800             /* fewest words in a final batch */
+
+unsigned long ZEXPORT crc32_z(
+    unsigned long crc,
+    const unsigned char FAR *buf,
+    z_size_t len)
+{
+    z_crc_t val;
+    z_word_t crc1, crc2;
+    const z_word_t *word;
+    z_word_t val0, val1, val2;
+    z_size_t last, last2, i;
+    z_size_t num;
+
+    /* Return initial CRC, if requested. */
+    if (buf == Z_NULL) return 0;
+
+#ifdef DYNAMIC_CRC_TABLE
+    once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+
+    /* Pre-condition the CRC */
+    crc = (~crc) & 0xffffffff;
+
+    /* Compute the CRC up to a word boundary. */
+    while (len && ((z_size_t)buf & 7) != 0) {
+        len--;
+        val = *buf++;
+        __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
+    }
+
+    /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */
+    word = (z_word_t const *)buf;
+    num = len >> 3;
+    len &= 7;
+
+    /* Do three interleaved CRCs to realize the throughput of one crc32x
+       instruction per cycle. Each CRC is calculated on Z_BATCH words. The
+       three CRCs are combined into a single CRC after each set of batches. */
+    while (num >= 3 * Z_BATCH) {
+        crc1 = 0;
+        crc2 = 0;
+        for (i = 0; i < Z_BATCH; i++) {
+            val0 = word[i];
+            val1 = word[i + Z_BATCH];
+            val2 = word[i + 2 * Z_BATCH];
+            __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
+            __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
+            __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
+        }
+        word += 3 * Z_BATCH;
+        num -= 3 * Z_BATCH;
+        crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1;
+        crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2;
+    }
+
+    /* Do one last smaller batch with the remaining words, if there are enough
+       to pay for the combination of CRCs. */
+    last = num / 3;
+    if (last >= Z_BATCH_MIN) {
+        last2 = last << 1;
+        crc1 = 0;
+        crc2 = 0;
+        for (i = 0; i < last; i++) {
+            val0 = word[i];
+            val1 = word[i + last];
+            val2 = word[i + last2];
+            __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
+            __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1));
+            __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2));
+        }
+        word += 3 * last;
+        num -= 3 * last;
+        val = x2nmodp(last, 6);
+        crc = multmodp(val, crc) ^ crc1;
+        crc = multmodp(val, crc) ^ crc2;
+    }
+
+    /* Compute the CRC on any remaining words. */
+    for (i = 0; i < num; i++) {
+        val0 = word[i];
+        __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0));
+    }
+    word += num;
+
+    /* Complete the CRC on any remaining bytes. */
+    buf = (const unsigned char FAR *)word;
+    while (len) {
+        len--;
+        val = *buf++;
+        __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val));
+    }
+
+    /* Return the CRC, post-conditioned. */
+    return crc ^ 0xffffffff;
+}
+
+#else
+
+#ifdef W
+
+/*
+  Return the CRC of the W bytes in the word_t data, taking the
+  least-significant byte of the word as the first byte of data, without any pre
+  or post conditioning. This is used to combine the CRCs of each braid.
+ */
+local z_crc_t crc_word(
+    z_word_t data)
+{
+    int k;
+    for (k = 0; k < W; k++)
+        data = (data >> 8) ^ crc_table[data & 0xff];
+    return (z_crc_t)data;
+}
+
+local z_word_t crc_word_big(
+    z_word_t data)
+{
+    int k;
+    for (k = 0; k < W; k++)
+        data = (data << 8) ^
+            crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
+    return data;
+}
+
+#endif
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32_z(
+    unsigned long crc,
+    const unsigned char FAR *buf,
+    z_size_t len)
+{
+    /* Return initial CRC, if requested. */
+    if (buf == Z_NULL) return 0;
+
+#ifdef DYNAMIC_CRC_TABLE
+    once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+
+    /* Pre-condition the CRC */
+    crc = (~crc) & 0xffffffff;
+
+#ifdef W
+
+    /* If provided enough bytes, do a braided CRC calculation. */
+    if (len >= N * W + W - 1) {
+        z_size_t blks;
+        z_word_t const *words;
+        unsigned endian;
+        int k;
+
+        /* Compute the CRC up to a z_word_t boundary. */
+        while (len && ((z_size_t)buf & (W - 1)) != 0) {
+            len--;
+            crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        }
+
+        /* Compute the CRC on as many N z_word_t blocks as are available. */
+        blks = len / (N * W);
+        len -= blks * N * W;
+        words = (z_word_t const *)buf;
+
+        /* Do endian check at execution time instead of compile time, since ARM
+           processors can change the endianess at execution time. If the
+           compiler knows what the endianess will be, it can optimize out the
+           check and the unused branch. */
+        endian = 1;
+        if (*(unsigned char *)&endian) {
+            /* Little endian. */
+
+            z_crc_t crc0;
+            z_word_t word0;
+#if N > 1
+            z_crc_t crc1;
+            z_word_t word1;
+#if N > 2
+            z_crc_t crc2;
+            z_word_t word2;
+#if N > 3
+            z_crc_t crc3;
+            z_word_t word3;
+#if N > 4
+            z_crc_t crc4;
+            z_word_t word4;
+#if N > 5
+            z_crc_t crc5;
+            z_word_t word5;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+            /* Initialize the CRC for each braid. */
+            crc0 = crc;
+#if N > 1
+            crc1 = 0;
+#if N > 2
+            crc2 = 0;
+#if N > 3
+            crc3 = 0;
+#if N > 4
+            crc4 = 0;
+#if N > 5
+            crc5 = 0;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+            /*
+              Process the first blks-1 blocks, computing the CRCs on each braid
+              independently.
+             */
+            while (--blks) {
+                /* Load the word for each braid into registers. */
+                word0 = crc0 ^ words[0];
+#if N > 1
+                word1 = crc1 ^ words[1];
+#if N > 2
+                word2 = crc2 ^ words[2];
+#if N > 3
+                word3 = crc3 ^ words[3];
+#if N > 4
+                word4 = crc4 ^ words[4];
+#if N > 5
+                word5 = crc5 ^ words[5];
+#endif
+#endif
+#endif
+#endif
+#endif
+                words += N;
+
+                /* Compute and update the CRC for each word. The loop should
+                   get unrolled. */
+                crc0 = crc_braid_table[0][word0 & 0xff];
+#if N > 1
+                crc1 = crc_braid_table[0][word1 & 0xff];
+#if N > 2
+                crc2 = crc_braid_table[0][word2 & 0xff];
+#if N > 3
+                crc3 = crc_braid_table[0][word3 & 0xff];
+#if N > 4
+                crc4 = crc_braid_table[0][word4 & 0xff];
+#if N > 5
+                crc5 = crc_braid_table[0][word5 & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+                for (k = 1; k < W; k++) {
+                    crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff];
+#if N > 1
+                    crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff];
+#if N > 2
+                    crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff];
+#if N > 3
+                    crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff];
+#if N > 4
+                    crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff];
+#if N > 5
+                    crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+                }
+            }
+
+            /*
+              Process the last block, combining the CRCs of the N braids at the
+              same time.
+             */
+            crc = crc_word(crc0 ^ words[0]);
+#if N > 1
+            crc = crc_word(crc1 ^ words[1] ^ crc);
+#if N > 2
+            crc = crc_word(crc2 ^ words[2] ^ crc);
+#if N > 3
+            crc = crc_word(crc3 ^ words[3] ^ crc);
+#if N > 4
+            crc = crc_word(crc4 ^ words[4] ^ crc);
+#if N > 5
+            crc = crc_word(crc5 ^ words[5] ^ crc);
+#endif
+#endif
+#endif
+#endif
+#endif
+            words += N;
+        }
+        else {
+            /* Big endian. */
+
+            z_word_t crc0, word0, comb;
+#if N > 1
+            z_word_t crc1, word1;
+#if N > 2
+            z_word_t crc2, word2;
+#if N > 3
+            z_word_t crc3, word3;
+#if N > 4
+            z_word_t crc4, word4;
+#if N > 5
+            z_word_t crc5, word5;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+            /* Initialize the CRC for each braid. */
+            crc0 = byte_swap(crc);
+#if N > 1
+            crc1 = 0;
+#if N > 2
+            crc2 = 0;
+#if N > 3
+            crc3 = 0;
+#if N > 4
+            crc4 = 0;
+#if N > 5
+            crc5 = 0;
+#endif
+#endif
+#endif
+#endif
+#endif
+
+            /*
+              Process the first blks-1 blocks, computing the CRCs on each braid
+              independently.
+             */
+            while (--blks) {
+                /* Load the word for each braid into registers. */
+                word0 = crc0 ^ words[0];
+#if N > 1
+                word1 = crc1 ^ words[1];
+#if N > 2
+                word2 = crc2 ^ words[2];
+#if N > 3
+                word3 = crc3 ^ words[3];
+#if N > 4
+                word4 = crc4 ^ words[4];
+#if N > 5
+                word5 = crc5 ^ words[5];
+#endif
+#endif
+#endif
+#endif
+#endif
+                words += N;
+
+                /* Compute and update the CRC for each word. The loop should
+                   get unrolled. */
+                crc0 = crc_braid_big_table[0][word0 & 0xff];
+#if N > 1
+                crc1 = crc_braid_big_table[0][word1 & 0xff];
+#if N > 2
+                crc2 = crc_braid_big_table[0][word2 & 0xff];
+#if N > 3
+                crc3 = crc_braid_big_table[0][word3 & 0xff];
+#if N > 4
+                crc4 = crc_braid_big_table[0][word4 & 0xff];
+#if N > 5
+                crc5 = crc_braid_big_table[0][word5 & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+                for (k = 1; k < W; k++) {
+                    crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff];
+#if N > 1
+                    crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff];
+#if N > 2
+                    crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff];
+#if N > 3
+                    crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff];
+#if N > 4
+                    crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff];
+#if N > 5
+                    crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff];
+#endif
+#endif
+#endif
+#endif
+#endif
+                }
+            }
+
+            /*
+              Process the last block, combining the CRCs of the N braids at the
+              same time.
+             */
+            comb = crc_word_big(crc0 ^ words[0]);
+#if N > 1
+            comb = crc_word_big(crc1 ^ words[1] ^ comb);
+#if N > 2
+            comb = crc_word_big(crc2 ^ words[2] ^ comb);
+#if N > 3
+            comb = crc_word_big(crc3 ^ words[3] ^ comb);
+#if N > 4
+            comb = crc_word_big(crc4 ^ words[4] ^ comb);
+#if N > 5
+            comb = crc_word_big(crc5 ^ words[5] ^ comb);
+#endif
+#endif
+#endif
+#endif
+#endif
+            words += N;
+            crc = byte_swap(comb);
+        }
+
+        /*
+          Update the pointer to the remaining bytes to process.
+         */
+        buf = (unsigned char const *)words;
+    }
+
+#endif /* W */
+
+    /* Complete the computation of the CRC on any remaining bytes. */
+    while (len >= 8) {
+        len -= 8;
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+    }
+    while (len) {
+        len--;
+        crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
+    }
+
+    /* Return the CRC, post-conditioned. */
+    return crc ^ 0xffffffff;
+}
+
+#endif
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(
+    unsigned long crc,
+    const unsigned char FAR *buf,
+    uInt len)
+{
+    return crc32_z(crc, buf, len);
+}
+
+#ifndef Z_FREETYPE
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine64(
+    uLong crc1,
+    uLong crc2,
+    z_off64_t len2)
+{
+#ifdef DYNAMIC_CRC_TABLE
+    once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+    return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(
+    uLong crc1,
+    uLong crc2,
+    z_off_t len2)
+{
+    return crc32_combine64(crc1, crc2, (z_off64_t)len2);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine_gen64(
+    z_off64_t len2)
+{
+#ifdef DYNAMIC_CRC_TABLE
+    once(&made, make_crc_table);
+#endif /* DYNAMIC_CRC_TABLE */
+    return x2nmodp(len2, 3);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine_gen(
+    z_off_t len2)
+{
+    return crc32_combine_gen64((z_off64_t)len2);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine_op(
+    uLong crc1,
+    uLong crc2,
+    uLong op)
+{
+    return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
+}
+
+#endif  /* Z_FREETYPE */
diff --git a/src/gzip/crc32.h b/src/gzip/crc32.h
new file mode 100644
index 0000000..137df68
--- /dev/null
+++ b/src/gzip/crc32.h
@@ -0,0 +1,9446 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[] = {
+    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};
+
+#ifdef W
+
+#if W == 8
+
+local const z_word_t FAR crc_big_table[] = {
+    0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000,
+    0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000,
+    0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000,
+    0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000,
+    0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000,
+    0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000,
+    0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000,
+    0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000,
+    0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000,
+    0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000,
+    0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000,
+    0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000,
+    0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000,
+    0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000,
+    0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000,
+    0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000,
+    0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000,
+    0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000,
+    0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000,
+    0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000,
+    0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000,
+    0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000,
+    0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000,
+    0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000,
+    0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000,
+    0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000,
+    0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000,
+    0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000,
+    0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000,
+    0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000,
+    0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000,
+    0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000,
+    0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000,
+    0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000,
+    0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000,
+    0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000,
+    0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000,
+    0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000,
+    0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000,
+    0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000,
+    0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000,
+    0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000,
+    0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000,
+    0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000,
+    0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000,
+    0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000,
+    0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000,
+    0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000,
+    0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000,
+    0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000,
+    0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000,
+    0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000,
+    0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000,
+    0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000,
+    0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000,
+    0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000,
+    0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000,
+    0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000,
+    0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000,
+    0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000,
+    0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000,
+    0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000,
+    0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000,
+    0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000,
+    0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000,
+    0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000,
+    0x8567077200000000, 0x1357000500000000, 0x824abf9500000000,
+    0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000,
+    0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000,
+    0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000,
+    0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000,
+    0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000,
+    0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000,
+    0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000,
+    0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000,
+    0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000,
+    0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000,
+    0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000,
+    0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000,
+    0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000,
+    0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000,
+    0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000,
+    0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000,
+    0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000,
+    0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000,
+    0x8def022d00000000};
+
+#else /* W == 4 */
+
+local const z_word_t FAR crc_big_table[] = {
+    0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07,
+    0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79,
+    0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7,
+    0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84,
+    0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13,
+    0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663,
+    0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5,
+    0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5,
+    0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832,
+    0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51,
+    0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf,
+    0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1,
+    0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76,
+    0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606,
+    0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996,
+    0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6,
+    0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c,
+    0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712,
+    0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c,
+    0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4,
+    0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943,
+    0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333,
+    0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe,
+    0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce,
+    0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359,
+    0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a,
+    0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04,
+    0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a,
+    0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0,
+    0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580,
+    0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10,
+    0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060,
+    0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1,
+    0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf,
+    0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31,
+    0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852,
+    0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5,
+    0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5,
+    0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75,
+    0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005,
+    0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292,
+    0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1,
+    0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f,
+    0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111,
+    0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0,
+    0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0,
+    0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40,
+    0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530,
+    0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba,
+    0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4,
+    0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a,
+    0x8def022d};
+
+#endif
+
+#if N == 1
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,
+    0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,
+    0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,
+    0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,
+    0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,
+    0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,
+    0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,
+    0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,
+    0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,
+    0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,
+    0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,
+    0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,
+    0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,
+    0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,
+    0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,
+    0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
+    0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,
+    0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,
+    0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,
+    0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,
+    0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,
+    0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,
+    0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,
+    0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,
+    0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,
+    0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,
+    0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,
+    0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,
+    0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,
+    0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,
+    0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,
+    0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
+    0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,
+    0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,
+    0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,
+    0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,
+    0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,
+    0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,
+    0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,
+    0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,
+    0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,
+    0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,
+    0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,
+    0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,
+    0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,
+    0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,
+    0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,
+    0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
+    0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,
+    0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,
+    0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,
+    0x264b06e6},
+   {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,
+    0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,
+    0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,
+    0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,
+    0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,
+    0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,
+    0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,
+    0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,
+    0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,
+    0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,
+    0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,
+    0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,
+    0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,
+    0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,
+    0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,
+    0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
+    0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,
+    0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,
+    0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,
+    0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,
+    0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,
+    0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,
+    0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,
+    0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,
+    0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,
+    0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,
+    0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,
+    0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,
+    0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,
+    0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,
+    0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,
+    0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
+    0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,
+    0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,
+    0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,
+    0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,
+    0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,
+    0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,
+    0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,
+    0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,
+    0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,
+    0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,
+    0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,
+    0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,
+    0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,
+    0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,
+    0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,
+    0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
+    0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,
+    0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,
+    0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,
+    0x92364a30},
+   {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,
+    0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,
+    0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,
+    0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,
+    0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,
+    0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,
+    0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,
+    0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,
+    0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,
+    0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,
+    0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,
+    0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,
+    0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,
+    0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,
+    0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,
+    0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
+    0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,
+    0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,
+    0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,
+    0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,
+    0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,
+    0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,
+    0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,
+    0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,
+    0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,
+    0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,
+    0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,
+    0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,
+    0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,
+    0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,
+    0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,
+    0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
+    0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,
+    0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,
+    0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,
+    0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,
+    0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,
+    0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,
+    0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,
+    0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,
+    0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,
+    0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,
+    0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,
+    0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,
+    0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,
+    0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,
+    0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,
+    0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
+    0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,
+    0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,
+    0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,
+    0xe4c4abcc},
+   {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,
+    0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,
+    0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,
+    0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,
+    0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,
+    0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,
+    0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,
+    0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,
+    0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,
+    0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,
+    0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,
+    0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,
+    0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,
+    0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,
+    0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,
+    0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
+    0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,
+    0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,
+    0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,
+    0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,
+    0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,
+    0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,
+    0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,
+    0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,
+    0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,
+    0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,
+    0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,
+    0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,
+    0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,
+    0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,
+    0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,
+    0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
+    0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,
+    0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,
+    0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,
+    0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,
+    0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,
+    0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,
+    0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,
+    0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,
+    0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,
+    0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,
+    0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,
+    0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,
+    0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,
+    0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,
+    0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,
+    0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
+    0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,
+    0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,
+    0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,
+    0xca64c78c},
+   {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,
+    0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,
+    0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,
+    0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
+    0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,
+    0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,
+    0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,
+    0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
+    0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,
+    0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,
+    0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,
+    0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
+    0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,
+    0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,
+    0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,
+    0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
+    0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,
+    0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,
+    0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,
+    0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
+    0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,
+    0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,
+    0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,
+    0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
+    0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,
+    0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,
+    0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,
+    0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
+    0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,
+    0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,
+    0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,
+    0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
+    0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,
+    0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,
+    0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,
+    0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
+    0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,
+    0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,
+    0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,
+    0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
+    0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,
+    0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,
+    0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,
+    0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
+    0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,
+    0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,
+    0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,
+    0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
+    0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,
+    0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,
+    0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,
+    0xde0506f1},
+   {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,
+    0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,
+    0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,
+    0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
+    0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,
+    0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,
+    0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,
+    0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
+    0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,
+    0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,
+    0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,
+    0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
+    0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,
+    0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,
+    0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,
+    0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
+    0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,
+    0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,
+    0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,
+    0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
+    0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,
+    0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,
+    0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,
+    0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
+    0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,
+    0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,
+    0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,
+    0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
+    0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,
+    0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,
+    0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,
+    0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
+    0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,
+    0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,
+    0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,
+    0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
+    0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,
+    0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,
+    0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,
+    0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
+    0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,
+    0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,
+    0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,
+    0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
+    0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,
+    0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,
+    0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,
+    0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
+    0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,
+    0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,
+    0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,
+    0xbe9834ed},
+   {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,
+    0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,
+    0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,
+    0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
+    0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,
+    0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,
+    0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,
+    0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
+    0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,
+    0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,
+    0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,
+    0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
+    0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,
+    0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,
+    0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,
+    0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
+    0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,
+    0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,
+    0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,
+    0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
+    0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,
+    0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,
+    0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,
+    0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
+    0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,
+    0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,
+    0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,
+    0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
+    0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,
+    0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,
+    0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,
+    0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
+    0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,
+    0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,
+    0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,
+    0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
+    0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,
+    0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,
+    0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,
+    0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
+    0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,
+    0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,
+    0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,
+    0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
+    0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,
+    0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,
+    0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,
+    0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
+    0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,
+    0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,
+    0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,
+    0x9324fd72},
+   {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}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000,
+    0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000,
+    0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000,
+    0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000,
+    0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000,
+    0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000,
+    0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000,
+    0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000,
+    0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000,
+    0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000,
+    0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000,
+    0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000,
+    0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000,
+    0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000,
+    0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000,
+    0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000,
+    0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000,
+    0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000,
+    0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000,
+    0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000,
+    0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000,
+    0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000,
+    0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000,
+    0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000,
+    0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000,
+    0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000,
+    0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000,
+    0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000,
+    0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000,
+    0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000,
+    0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000,
+    0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000,
+    0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000,
+    0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000,
+    0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000,
+    0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000,
+    0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000,
+    0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000,
+    0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000,
+    0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000,
+    0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000,
+    0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000,
+    0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000,
+    0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000,
+    0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000,
+    0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000,
+    0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000,
+    0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000,
+    0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000,
+    0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000,
+    0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000,
+    0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000,
+    0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000,
+    0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000,
+    0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000,
+    0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000,
+    0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000,
+    0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000,
+    0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000,
+    0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000,
+    0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000,
+    0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000,
+    0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000,
+    0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000,
+    0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000,
+    0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000,
+    0x8567077200000000, 0x1357000500000000, 0x824abf9500000000,
+    0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000,
+    0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000,
+    0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000,
+    0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000,
+    0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000,
+    0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000,
+    0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000,
+    0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000,
+    0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000,
+    0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000,
+    0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000,
+    0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000,
+    0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000,
+    0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000,
+    0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000,
+    0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000,
+    0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000,
+    0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000,
+    0x8def022d00000000},
+   {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000,
+    0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000,
+    0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000,
+    0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000,
+    0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000,
+    0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000,
+    0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000,
+    0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000,
+    0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000,
+    0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000,
+    0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000,
+    0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000,
+    0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000,
+    0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000,
+    0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000,
+    0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000,
+    0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000,
+    0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000,
+    0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000,
+    0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000,
+    0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000,
+    0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000,
+    0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000,
+    0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000,
+    0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000,
+    0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000,
+    0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000,
+    0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000,
+    0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000,
+    0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000,
+    0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000,
+    0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000,
+    0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000,
+    0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000,
+    0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000,
+    0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000,
+    0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000,
+    0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000,
+    0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000,
+    0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000,
+    0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000,
+    0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000,
+    0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000,
+    0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000,
+    0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000,
+    0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000,
+    0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000,
+    0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000,
+    0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000,
+    0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000,
+    0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000,
+    0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000,
+    0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000,
+    0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000,
+    0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000,
+    0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000,
+    0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000,
+    0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000,
+    0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000,
+    0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000,
+    0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000,
+    0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000,
+    0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000,
+    0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000,
+    0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000,
+    0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000,
+    0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000,
+    0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000,
+    0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000,
+    0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000,
+    0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000,
+    0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000,
+    0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000,
+    0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000,
+    0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000,
+    0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000,
+    0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000,
+    0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000,
+    0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000,
+    0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000,
+    0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000,
+    0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000,
+    0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000,
+    0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000,
+    0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000,
+    0x72fd249300000000},
+   {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000,
+    0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000,
+    0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000,
+    0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000,
+    0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000,
+    0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000,
+    0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000,
+    0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000,
+    0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000,
+    0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000,
+    0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000,
+    0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000,
+    0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000,
+    0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000,
+    0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000,
+    0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000,
+    0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000,
+    0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000,
+    0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000,
+    0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000,
+    0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000,
+    0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000,
+    0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000,
+    0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000,
+    0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000,
+    0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000,
+    0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000,
+    0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000,
+    0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000,
+    0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000,
+    0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000,
+    0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000,
+    0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000,
+    0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000,
+    0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000,
+    0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000,
+    0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000,
+    0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000,
+    0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000,
+    0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000,
+    0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000,
+    0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000,
+    0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000,
+    0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000,
+    0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000,
+    0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000,
+    0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000,
+    0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000,
+    0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000,
+    0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000,
+    0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000,
+    0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000,
+    0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000,
+    0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000,
+    0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000,
+    0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000,
+    0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000,
+    0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000,
+    0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000,
+    0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000,
+    0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000,
+    0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000,
+    0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000,
+    0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000,
+    0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000,
+    0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000,
+    0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000,
+    0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000,
+    0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000,
+    0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000,
+    0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000,
+    0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000,
+    0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000,
+    0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000,
+    0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000,
+    0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000,
+    0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000,
+    0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000,
+    0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000,
+    0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000,
+    0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000,
+    0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000,
+    0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000,
+    0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000,
+    0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000,
+    0xed3498be00000000},
+   {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000,
+    0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000,
+    0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000,
+    0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000,
+    0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000,
+    0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000,
+    0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000,
+    0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000,
+    0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000,
+    0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000,
+    0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000,
+    0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000,
+    0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000,
+    0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000,
+    0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000,
+    0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000,
+    0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000,
+    0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000,
+    0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000,
+    0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000,
+    0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000,
+    0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000,
+    0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000,
+    0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000,
+    0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000,
+    0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000,
+    0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000,
+    0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000,
+    0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000,
+    0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000,
+    0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000,
+    0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000,
+    0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000,
+    0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000,
+    0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000,
+    0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000,
+    0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000,
+    0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000,
+    0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000,
+    0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000,
+    0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000,
+    0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000,
+    0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000,
+    0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000,
+    0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000,
+    0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000,
+    0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000,
+    0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000,
+    0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000,
+    0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000,
+    0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000,
+    0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000,
+    0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000,
+    0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000,
+    0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000,
+    0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000,
+    0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000,
+    0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000,
+    0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000,
+    0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000,
+    0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000,
+    0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000,
+    0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000,
+    0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000,
+    0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000,
+    0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000,
+    0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000,
+    0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000,
+    0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000,
+    0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000,
+    0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000,
+    0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000,
+    0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000,
+    0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000,
+    0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000,
+    0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000,
+    0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000,
+    0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000,
+    0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000,
+    0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000,
+    0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000,
+    0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000,
+    0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000,
+    0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000,
+    0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000,
+    0xf10605de00000000},
+   {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000,
+    0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000,
+    0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000,
+    0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000,
+    0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000,
+    0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000,
+    0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000,
+    0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000,
+    0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000,
+    0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000,
+    0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000,
+    0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000,
+    0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000,
+    0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000,
+    0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000,
+    0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000,
+    0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000,
+    0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000,
+    0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000,
+    0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000,
+    0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000,
+    0x572f712300000000, 0x4958f35800000000, 0xf971936500000000,
+    0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000,
+    0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000,
+    0x8813836800000000, 0x383ae35500000000, 0xe840431200000000,
+    0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000,
+    0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000,
+    0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000,
+    0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000,
+    0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000,
+    0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000,
+    0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000,
+    0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000,
+    0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000,
+    0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000,
+    0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000,
+    0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000,
+    0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000,
+    0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000,
+    0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000,
+    0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000,
+    0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000,
+    0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000,
+    0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000,
+    0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000,
+    0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000,
+    0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000,
+    0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000,
+    0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000,
+    0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000,
+    0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000,
+    0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000,
+    0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000,
+    0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000,
+    0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000,
+    0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000,
+    0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000,
+    0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000,
+    0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000,
+    0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000,
+    0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000,
+    0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000,
+    0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000,
+    0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000,
+    0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000,
+    0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000,
+    0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000,
+    0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000,
+    0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000,
+    0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000,
+    0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000,
+    0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000,
+    0x983485b900000000, 0x281de58400000000, 0xf86745c300000000,
+    0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000,
+    0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000,
+    0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000,
+    0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000,
+    0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000,
+    0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000,
+    0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000,
+    0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000,
+    0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000,
+    0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000,
+    0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000,
+    0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000,
+    0x8cc764ca00000000},
+   {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000,
+    0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000,
+    0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000,
+    0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000,
+    0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000,
+    0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000,
+    0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000,
+    0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000,
+    0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000,
+    0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000,
+    0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000,
+    0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000,
+    0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000,
+    0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000,
+    0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000,
+    0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000,
+    0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000,
+    0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000,
+    0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000,
+    0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000,
+    0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000,
+    0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000,
+    0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000,
+    0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000,
+    0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000,
+    0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000,
+    0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000,
+    0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000,
+    0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000,
+    0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000,
+    0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000,
+    0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000,
+    0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000,
+    0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000,
+    0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000,
+    0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000,
+    0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000,
+    0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000,
+    0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000,
+    0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000,
+    0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000,
+    0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000,
+    0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000,
+    0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000,
+    0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000,
+    0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000,
+    0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000,
+    0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000,
+    0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000,
+    0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000,
+    0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000,
+    0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000,
+    0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000,
+    0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000,
+    0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000,
+    0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000,
+    0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000,
+    0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000,
+    0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000,
+    0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000,
+    0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000,
+    0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000,
+    0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000,
+    0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000,
+    0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000,
+    0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000,
+    0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000,
+    0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000,
+    0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000,
+    0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000,
+    0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000,
+    0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000,
+    0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000,
+    0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000,
+    0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000,
+    0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000,
+    0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000,
+    0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000,
+    0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000,
+    0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000,
+    0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000,
+    0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000,
+    0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000,
+    0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000,
+    0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000,
+    0xccabc4e400000000},
+   {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000,
+    0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000,
+    0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000,
+    0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000,
+    0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000,
+    0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000,
+    0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000,
+    0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000,
+    0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000,
+    0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000,
+    0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000,
+    0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000,
+    0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000,
+    0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000,
+    0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000,
+    0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000,
+    0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000,
+    0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000,
+    0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000,
+    0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000,
+    0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000,
+    0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000,
+    0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000,
+    0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000,
+    0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000,
+    0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000,
+    0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000,
+    0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000,
+    0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000,
+    0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000,
+    0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000,
+    0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000,
+    0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000,
+    0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000,
+    0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000,
+    0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000,
+    0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000,
+    0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000,
+    0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000,
+    0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000,
+    0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000,
+    0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000,
+    0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000,
+    0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000,
+    0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000,
+    0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000,
+    0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000,
+    0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000,
+    0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000,
+    0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000,
+    0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000,
+    0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000,
+    0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000,
+    0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000,
+    0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000,
+    0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000,
+    0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000,
+    0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000,
+    0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000,
+    0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000,
+    0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000,
+    0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000,
+    0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000,
+    0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000,
+    0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000,
+    0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000,
+    0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000,
+    0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000,
+    0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000,
+    0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000,
+    0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000,
+    0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000,
+    0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000,
+    0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000,
+    0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000,
+    0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000,
+    0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000,
+    0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000,
+    0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000,
+    0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000,
+    0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000,
+    0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000,
+    0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000,
+    0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000,
+    0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000,
+    0x304a369200000000},
+   {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000,
+    0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000,
+    0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000,
+    0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000,
+    0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000,
+    0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000,
+    0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000,
+    0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000,
+    0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000,
+    0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000,
+    0x1923316900000000, 0x87239ba500000000, 0x566276f900000000,
+    0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000,
+    0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000,
+    0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000,
+    0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000,
+    0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000,
+    0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000,
+    0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000,
+    0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000,
+    0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000,
+    0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000,
+    0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000,
+    0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000,
+    0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000,
+    0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000,
+    0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000,
+    0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000,
+    0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000,
+    0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000,
+    0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000,
+    0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000,
+    0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000,
+    0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000,
+    0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000,
+    0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000,
+    0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000,
+    0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000,
+    0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000,
+    0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000,
+    0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000,
+    0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000,
+    0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000,
+    0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000,
+    0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000,
+    0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000,
+    0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000,
+    0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000,
+    0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000,
+    0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000,
+    0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000,
+    0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000,
+    0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000,
+    0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000,
+    0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000,
+    0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000,
+    0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000,
+    0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000,
+    0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000,
+    0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000,
+    0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000,
+    0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000,
+    0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000,
+    0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000,
+    0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000,
+    0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000,
+    0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000,
+    0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000,
+    0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000,
+    0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000,
+    0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000,
+    0x6171384400000000, 0xff71928800000000, 0xe678578200000000,
+    0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000,
+    0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000,
+    0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000,
+    0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000,
+    0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000,
+    0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000,
+    0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000,
+    0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000,
+    0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000,
+    0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000,
+    0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000,
+    0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000,
+    0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000,
+    0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000,
+    0xe6064b2600000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757,
+    0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a,
+    0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733,
+    0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
+    0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,
+    0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42,
+    0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5,
+    0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
+    0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086,
+    0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4,
+    0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,
+    0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
+    0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d,
+    0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f,
+    0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859,
+    0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
+    0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,
+    0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028,
+    0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891,
+    0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
+    0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec,
+    0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde,
+    0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,
+    0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
+    0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24,
+    0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e,
+    0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7,
+    0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
+    0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,
+    0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196,
+    0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0,
+    0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
+    0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52,
+    0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f,
+    0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,
+    0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
+    0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675,
+    0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647,
+    0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d,
+    0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
+    0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,
+    0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc,
+    0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645,
+    0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
+    0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138,
+    0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a,
+    0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,
+    0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
+    0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0,
+    0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d,
+    0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194,
+    0xde0506f1},
+   {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc,
+    0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f,
+    0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a,
+    0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
+    0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,
+    0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023,
+    0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e,
+    0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
+    0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84,
+    0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7,
+    0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,
+    0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
+    0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0,
+    0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b,
+    0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816,
+    0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
+    0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,
+    0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f,
+    0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba,
+    0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
+    0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98,
+    0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873,
+    0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,
+    0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
+    0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134,
+    0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7,
+    0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732,
+    0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
+    0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,
+    0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b,
+    0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26,
+    0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
+    0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc,
+    0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef,
+    0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,
+    0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
+    0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8,
+    0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43,
+    0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e,
+    0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
+    0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,
+    0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07,
+    0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982,
+    0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
+    0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0,
+    0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b,
+    0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,
+    0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
+    0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c,
+    0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f,
+    0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda,
+    0xbe9834ed},
+   {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504,
+    0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49,
+    0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e,
+    0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
+    0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,
+    0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c,
+    0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620,
+    0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
+    0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae,
+    0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2,
+    0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,
+    0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
+    0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05,
+    0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40,
+    0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f,
+    0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
+    0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,
+    0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d,
+    0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da,
+    0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
+    0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af,
+    0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea,
+    0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,
+    0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
+    0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa,
+    0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a,
+    0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd,
+    0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
+    0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,
+    0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f,
+    0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290,
+    0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
+    0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed,
+    0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0,
+    0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,
+    0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
+    0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0,
+    0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5,
+    0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc,
+    0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
+    0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,
+    0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e,
+    0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299,
+    0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
+    0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec,
+    0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9,
+    0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,
+    0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
+    0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9,
+    0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4,
+    0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33,
+    0x9324fd72},
+   {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}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07,
+    0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79,
+    0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7,
+    0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84,
+    0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13,
+    0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663,
+    0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5,
+    0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5,
+    0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832,
+    0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51,
+    0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf,
+    0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1,
+    0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76,
+    0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606,
+    0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996,
+    0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6,
+    0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c,
+    0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712,
+    0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c,
+    0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4,
+    0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943,
+    0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333,
+    0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe,
+    0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce,
+    0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359,
+    0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a,
+    0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04,
+    0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a,
+    0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0,
+    0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580,
+    0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10,
+    0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060,
+    0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1,
+    0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf,
+    0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31,
+    0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852,
+    0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5,
+    0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5,
+    0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75,
+    0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005,
+    0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292,
+    0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1,
+    0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f,
+    0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111,
+    0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0,
+    0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0,
+    0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40,
+    0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530,
+    0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba,
+    0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4,
+    0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a,
+    0x8def022d},
+   {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64,
+    0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1,
+    0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e,
+    0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61,
+    0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82,
+    0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff,
+    0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7,
+    0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da,
+    0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139,
+    0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6,
+    0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89,
+    0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c,
+    0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0,
+    0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d,
+    0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a,
+    0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177,
+    0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de,
+    0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b,
+    0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824,
+    0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e,
+    0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad,
+    0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0,
+    0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d,
+    0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60,
+    0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83,
+    0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822,
+    0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d,
+    0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8,
+    0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171,
+    0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c,
+    0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b,
+    0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6,
+    0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca,
+    0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f,
+    0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430,
+    0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf,
+    0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c,
+    0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51,
+    0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9,
+    0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84,
+    0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67,
+    0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398,
+    0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7,
+    0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62,
+    0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e,
+    0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923,
+    0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4,
+    0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9,
+    0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070,
+    0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5,
+    0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a,
+    0x72fd2493},
+   {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907,
+    0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f,
+    0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a,
+    0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e,
+    0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512,
+    0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14,
+    0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b,
+    0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d,
+    0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731,
+    0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925,
+    0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620,
+    0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28,
+    0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70,
+    0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176,
+    0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d,
+    0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b,
+    0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b,
+    0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63,
+    0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266,
+    0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a,
+    0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446,
+    0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40,
+    0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557,
+    0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51,
+    0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d,
+    0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0,
+    0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5,
+    0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed,
+    0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd,
+    0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb,
+    0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0,
+    0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6,
+    0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de,
+    0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6,
+    0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3,
+    0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7,
+    0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb,
+    0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd,
+    0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92,
+    0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094,
+    0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598,
+    0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c,
+    0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489,
+    0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81,
+    0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9,
+    0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af,
+    0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4,
+    0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2,
+    0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2,
+    0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba,
+    0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf,
+    0xed3498be},
+   {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f,
+    0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d,
+    0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0,
+    0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42,
+    0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95,
+    0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2,
+    0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a,
+    0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d,
+    0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea,
+    0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748,
+    0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5,
+    0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27,
+    0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b,
+    0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac,
+    0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4,
+    0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3,
+    0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44,
+    0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6,
+    0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b,
+    0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329,
+    0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe,
+    0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9,
+    0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1,
+    0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6,
+    0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921,
+    0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555,
+    0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8,
+    0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a,
+    0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd,
+    0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a,
+    0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2,
+    0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5,
+    0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2,
+    0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330,
+    0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad,
+    0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f,
+    0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8,
+    0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef,
+    0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc,
+    0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb,
+    0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c,
+    0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e,
+    0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03,
+    0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1,
+    0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6,
+    0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1,
+    0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9,
+    0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e,
+    0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409,
+    0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb,
+    0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966,
+    0xf10605de}};
+
+#endif
+
+#endif
+
+#if N == 2
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87,
+    0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede,
+    0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab,
+    0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c,
+    0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1,
+    0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7,
+    0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e,
+    0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308,
+    0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5,
+    0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472,
+    0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07,
+    0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e,
+    0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa,
+    0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec,
+    0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6,
+    0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0,
+    0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3,
+    0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba,
+    0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf,
+    0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975,
+    0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8,
+    0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde,
+    0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a,
+    0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c,
+    0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1,
+    0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65,
+    0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410,
+    0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649,
+    0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a,
+    0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c,
+    0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946,
+    0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450,
+    0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e,
+    0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857,
+    0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022,
+    0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5,
+    0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758,
+    0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e,
+    0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d,
+    0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b,
+    0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6,
+    0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401,
+    0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74,
+    0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d,
+    0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073,
+    0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65,
+    0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f,
+    0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749,
+    0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a,
+    0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033,
+    0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846,
+    0x0d7139d7},
+   {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563,
+    0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f,
+    0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875,
+    0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536,
+    0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8,
+    0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43,
+    0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f,
+    0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184,
+    0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a,
+    0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39,
+    0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523,
+    0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f,
+    0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d,
+    0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6,
+    0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b,
+    0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0,
+    0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151,
+    0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d,
+    0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47,
+    0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a,
+    0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964,
+    0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef,
+    0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d,
+    0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6,
+    0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348,
+    0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53,
+    0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449,
+    0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645,
+    0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4,
+    0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f,
+    0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2,
+    0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69,
+    0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46,
+    0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a,
+    0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650,
+    0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13,
+    0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded,
+    0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366,
+    0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57,
+    0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc,
+    0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222,
+    0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61,
+    0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b,
+    0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277,
+    0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558,
+    0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3,
+    0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e,
+    0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5,
+    0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74,
+    0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78,
+    0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262,
+    0x1c53e98a},
+   {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b,
+    0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40,
+    0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580,
+    0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7,
+    0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a,
+    0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37,
+    0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75,
+    0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218,
+    0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5,
+    0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2,
+    0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02,
+    0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59,
+    0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1,
+    0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c,
+    0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a,
+    0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307,
+    0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486,
+    0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd,
+    0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d,
+    0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2,
+    0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f,
+    0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72,
+    0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8,
+    0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985,
+    0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268,
+    0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94,
+    0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454,
+    0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f,
+    0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e,
+    0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3,
+    0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915,
+    0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778,
+    0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821,
+    0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a,
+    0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba,
+    0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d,
+    0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560,
+    0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d,
+    0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe,
+    0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3,
+    0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e,
+    0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509,
+    0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9,
+    0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92,
+    0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb,
+    0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6,
+    0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50,
+    0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d,
+    0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc,
+    0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7,
+    0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927,
+    0x3f88e851},
+   {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96,
+    0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8,
+    0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0,
+    0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14,
+    0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7,
+    0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4,
+    0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe,
+    0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad,
+    0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e,
+    0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa,
+    0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2,
+    0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c,
+    0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab,
+    0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8,
+    0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d,
+    0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e,
+    0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7,
+    0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99,
+    0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1,
+    0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690,
+    0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933,
+    0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20,
+    0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf,
+    0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc,
+    0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f,
+    0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92,
+    0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca,
+    0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4,
+    0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd,
+    0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de,
+    0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb,
+    0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8,
+    0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474,
+    0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a,
+    0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252,
+    0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6,
+    0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55,
+    0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846,
+    0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7,
+    0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4,
+    0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47,
+    0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3,
+    0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb,
+    0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5,
+    0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49,
+    0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a,
+    0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f,
+    0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c,
+    0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305,
+    0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b,
+    0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523,
+    0x3dee8ca6},
+   {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f,
+    0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91,
+    0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e,
+    0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c,
+    0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02,
+    0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12,
+    0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567,
+    0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277,
+    0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679,
+    0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b,
+    0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4,
+    0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a,
+    0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0,
+    0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0,
+    0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91,
+    0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881,
+    0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173,
+    0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d,
+    0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912,
+    0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8,
+    0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6,
+    0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6,
+    0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b,
+    0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b,
+    0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75,
+    0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f,
+    0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00,
+    0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee,
+    0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c,
+    0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c,
+    0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d,
+    0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d,
+    0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67,
+    0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89,
+    0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706,
+    0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14,
+    0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a,
+    0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a,
+    0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f,
+    0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f,
+    0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591,
+    0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983,
+    0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c,
+    0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2,
+    0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8,
+    0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8,
+    0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89,
+    0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99,
+    0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b,
+    0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485,
+    0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a,
+    0x36197165},
+   {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382,
+    0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85,
+    0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06,
+    0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca,
+    0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e,
+    0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc,
+    0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616,
+    0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54,
+    0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10,
+    0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc,
+    0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f,
+    0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58,
+    0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef,
+    0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad,
+    0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b,
+    0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29,
+    0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6,
+    0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1,
+    0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622,
+    0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039,
+    0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d,
+    0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f,
+    0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32,
+    0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770,
+    0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034,
+    0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f,
+    0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc,
+    0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db,
+    0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154,
+    0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16,
+    0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0,
+    0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592,
+    0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca,
+    0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd,
+    0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e,
+    0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882,
+    0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6,
+    0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384,
+    0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1,
+    0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3,
+    0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7,
+    0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b,
+    0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8,
+    0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff,
+    0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7,
+    0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5,
+    0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23,
+    0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761,
+    0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee,
+    0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9,
+    0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a,
+    0x1a3b93aa},
+   {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a,
+    0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca,
+    0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3,
+    0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb,
+    0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c,
+    0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58,
+    0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed,
+    0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9,
+    0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e,
+    0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906,
+    0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f,
+    0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf,
+    0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0,
+    0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4,
+    0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769,
+    0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d,
+    0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632,
+    0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82,
+    0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb,
+    0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73,
+    0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484,
+    0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0,
+    0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5,
+    0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1,
+    0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516,
+    0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f,
+    0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946,
+    0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6,
+    0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9,
+    0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad,
+    0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820,
+    0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364,
+    0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab,
+    0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b,
+    0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62,
+    0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a,
+    0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd,
+    0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089,
+    0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c,
+    0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8,
+    0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f,
+    0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477,
+    0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e,
+    0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be,
+    0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71,
+    0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635,
+    0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8,
+    0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc,
+    0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3,
+    0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753,
+    0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a,
+    0xe147d714},
+   {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c,
+    0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b,
+    0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92,
+    0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4,
+    0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069,
+    0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526,
+    0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25,
+    0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a,
+    0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7,
+    0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491,
+    0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958,
+    0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f,
+    0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307,
+    0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648,
+    0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999,
+    0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6,
+    0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a,
+    0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d,
+    0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4,
+    0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61,
+    0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc,
+    0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3,
+    0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53,
+    0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c,
+    0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1,
+    0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c,
+    0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5,
+    0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92,
+    0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e,
+    0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771,
+    0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0,
+    0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def,
+    0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0,
+    0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7,
+    0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e,
+    0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58,
+    0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285,
+    0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca,
+    0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce,
+    0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81,
+    0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c,
+    0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a,
+    0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3,
+    0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4,
+    0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb,
+    0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4,
+    0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75,
+    0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a,
+    0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296,
+    0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1,
+    0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808,
+    0x494f0c4b}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000,
+    0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000,
+    0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000,
+    0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000,
+    0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000,
+    0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000,
+    0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000,
+    0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000,
+    0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000,
+    0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000,
+    0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000,
+    0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000,
+    0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000,
+    0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000,
+    0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000,
+    0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000,
+    0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000,
+    0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000,
+    0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000,
+    0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000,
+    0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000,
+    0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000,
+    0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000,
+    0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000,
+    0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000,
+    0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000,
+    0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000,
+    0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000,
+    0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000,
+    0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000,
+    0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000,
+    0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000,
+    0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000,
+    0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000,
+    0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000,
+    0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000,
+    0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000,
+    0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000,
+    0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000,
+    0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000,
+    0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000,
+    0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000,
+    0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000,
+    0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000,
+    0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000,
+    0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000,
+    0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000,
+    0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000,
+    0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000,
+    0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000,
+    0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000,
+    0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000,
+    0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000,
+    0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000,
+    0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000,
+    0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000,
+    0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000,
+    0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000,
+    0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000,
+    0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000,
+    0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000,
+    0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000,
+    0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000,
+    0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000,
+    0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000,
+    0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000,
+    0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000,
+    0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000,
+    0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000,
+    0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000,
+    0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000,
+    0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000,
+    0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000,
+    0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000,
+    0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000,
+    0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000,
+    0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000,
+    0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000,
+    0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000,
+    0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000,
+    0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000,
+    0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000,
+    0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000,
+    0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000,
+    0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000,
+    0x4b0c4f4900000000},
+   {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000,
+    0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000,
+    0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000,
+    0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000,
+    0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000,
+    0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000,
+    0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000,
+    0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000,
+    0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000,
+    0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000,
+    0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000,
+    0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000,
+    0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000,
+    0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000,
+    0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000,
+    0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000,
+    0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000,
+    0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000,
+    0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000,
+    0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000,
+    0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000,
+    0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000,
+    0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000,
+    0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000,
+    0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000,
+    0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000,
+    0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000,
+    0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000,
+    0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000,
+    0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000,
+    0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000,
+    0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000,
+    0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000,
+    0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000,
+    0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000,
+    0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000,
+    0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000,
+    0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000,
+    0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000,
+    0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000,
+    0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000,
+    0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000,
+    0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000,
+    0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000,
+    0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000,
+    0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000,
+    0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000,
+    0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000,
+    0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000,
+    0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000,
+    0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000,
+    0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000,
+    0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000,
+    0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000,
+    0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000,
+    0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000,
+    0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000,
+    0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000,
+    0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000,
+    0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000,
+    0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000,
+    0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000,
+    0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000,
+    0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000,
+    0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000,
+    0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000,
+    0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000,
+    0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000,
+    0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000,
+    0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000,
+    0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000,
+    0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000,
+    0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000,
+    0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000,
+    0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000,
+    0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000,
+    0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000,
+    0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000,
+    0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000,
+    0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000,
+    0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000,
+    0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000,
+    0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000,
+    0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000,
+    0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000,
+    0x14d747e100000000},
+   {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000,
+    0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000,
+    0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000,
+    0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000,
+    0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000,
+    0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000,
+    0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000,
+    0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000,
+    0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000,
+    0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000,
+    0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000,
+    0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000,
+    0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000,
+    0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000,
+    0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000,
+    0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000,
+    0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000,
+    0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000,
+    0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000,
+    0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000,
+    0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000,
+    0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000,
+    0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000,
+    0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000,
+    0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000,
+    0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000,
+    0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000,
+    0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000,
+    0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000,
+    0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000,
+    0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000,
+    0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000,
+    0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000,
+    0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000,
+    0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000,
+    0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000,
+    0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000,
+    0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000,
+    0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000,
+    0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000,
+    0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000,
+    0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000,
+    0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000,
+    0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000,
+    0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000,
+    0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000,
+    0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000,
+    0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000,
+    0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000,
+    0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000,
+    0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000,
+    0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000,
+    0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000,
+    0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000,
+    0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000,
+    0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000,
+    0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000,
+    0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000,
+    0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000,
+    0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000,
+    0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000,
+    0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000,
+    0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000,
+    0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000,
+    0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000,
+    0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000,
+    0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000,
+    0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000,
+    0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000,
+    0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000,
+    0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000,
+    0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000,
+    0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000,
+    0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000,
+    0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000,
+    0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000,
+    0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000,
+    0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000,
+    0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000,
+    0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000,
+    0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000,
+    0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000,
+    0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000,
+    0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000,
+    0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000,
+    0xaa933b1a00000000},
+   {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000,
+    0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000,
+    0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000,
+    0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000,
+    0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000,
+    0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000,
+    0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000,
+    0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000,
+    0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000,
+    0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000,
+    0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000,
+    0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000,
+    0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000,
+    0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000,
+    0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000,
+    0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000,
+    0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000,
+    0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000,
+    0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000,
+    0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000,
+    0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000,
+    0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000,
+    0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000,
+    0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000,
+    0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000,
+    0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000,
+    0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000,
+    0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000,
+    0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000,
+    0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000,
+    0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000,
+    0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000,
+    0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000,
+    0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000,
+    0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000,
+    0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000,
+    0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000,
+    0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000,
+    0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000,
+    0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000,
+    0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000,
+    0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000,
+    0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000,
+    0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000,
+    0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000,
+    0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000,
+    0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000,
+    0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000,
+    0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000,
+    0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000,
+    0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000,
+    0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000,
+    0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000,
+    0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000,
+    0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000,
+    0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000,
+    0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000,
+    0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000,
+    0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000,
+    0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000,
+    0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000,
+    0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000,
+    0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000,
+    0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000,
+    0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000,
+    0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000,
+    0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000,
+    0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000,
+    0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000,
+    0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000,
+    0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000,
+    0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000,
+    0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000,
+    0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000,
+    0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000,
+    0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000,
+    0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000,
+    0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000,
+    0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000,
+    0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000,
+    0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000,
+    0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000,
+    0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000,
+    0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000,
+    0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000,
+    0x6571193600000000},
+   {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000,
+    0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000,
+    0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000,
+    0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000,
+    0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000,
+    0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000,
+    0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000,
+    0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000,
+    0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000,
+    0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000,
+    0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000,
+    0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000,
+    0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000,
+    0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000,
+    0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000,
+    0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000,
+    0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000,
+    0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000,
+    0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000,
+    0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000,
+    0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000,
+    0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000,
+    0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000,
+    0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000,
+    0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000,
+    0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000,
+    0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000,
+    0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000,
+    0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000,
+    0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000,
+    0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000,
+    0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000,
+    0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000,
+    0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000,
+    0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000,
+    0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000,
+    0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000,
+    0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000,
+    0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000,
+    0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000,
+    0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000,
+    0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000,
+    0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000,
+    0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000,
+    0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000,
+    0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000,
+    0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000,
+    0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000,
+    0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000,
+    0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000,
+    0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000,
+    0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000,
+    0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000,
+    0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000,
+    0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000,
+    0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000,
+    0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000,
+    0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000,
+    0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000,
+    0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000,
+    0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000,
+    0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000,
+    0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000,
+    0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000,
+    0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000,
+    0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000,
+    0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000,
+    0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000,
+    0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000,
+    0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000,
+    0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000,
+    0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000,
+    0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000,
+    0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000,
+    0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000,
+    0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000,
+    0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000,
+    0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000,
+    0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000,
+    0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000,
+    0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000,
+    0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000,
+    0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000,
+    0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000,
+    0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000,
+    0xa68cee3d00000000},
+   {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000,
+    0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000,
+    0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000,
+    0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000,
+    0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000,
+    0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000,
+    0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000,
+    0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000,
+    0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000,
+    0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000,
+    0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000,
+    0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000,
+    0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000,
+    0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000,
+    0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000,
+    0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000,
+    0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000,
+    0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000,
+    0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000,
+    0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000,
+    0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000,
+    0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000,
+    0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000,
+    0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000,
+    0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000,
+    0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000,
+    0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000,
+    0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000,
+    0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000,
+    0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000,
+    0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000,
+    0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000,
+    0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000,
+    0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000,
+    0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000,
+    0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000,
+    0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000,
+    0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000,
+    0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000,
+    0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000,
+    0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000,
+    0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000,
+    0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000,
+    0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000,
+    0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000,
+    0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000,
+    0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000,
+    0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000,
+    0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000,
+    0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000,
+    0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000,
+    0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000,
+    0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000,
+    0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000,
+    0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000,
+    0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000,
+    0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000,
+    0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000,
+    0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000,
+    0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000,
+    0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000,
+    0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000,
+    0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000,
+    0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000,
+    0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000,
+    0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000,
+    0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000,
+    0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000,
+    0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000,
+    0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000,
+    0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000,
+    0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000,
+    0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000,
+    0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000,
+    0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000,
+    0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000,
+    0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000,
+    0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000,
+    0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000,
+    0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000,
+    0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000,
+    0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000,
+    0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000,
+    0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000,
+    0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000,
+    0x51e8883f00000000},
+   {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000,
+    0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000,
+    0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000,
+    0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000,
+    0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000,
+    0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000,
+    0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000,
+    0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000,
+    0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000,
+    0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000,
+    0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000,
+    0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000,
+    0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000,
+    0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000,
+    0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000,
+    0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000,
+    0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000,
+    0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000,
+    0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000,
+    0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000,
+    0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000,
+    0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000,
+    0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000,
+    0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000,
+    0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000,
+    0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000,
+    0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000,
+    0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000,
+    0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000,
+    0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000,
+    0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000,
+    0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000,
+    0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000,
+    0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000,
+    0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000,
+    0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000,
+    0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000,
+    0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000,
+    0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000,
+    0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000,
+    0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000,
+    0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000,
+    0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000,
+    0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000,
+    0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000,
+    0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000,
+    0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000,
+    0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000,
+    0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000,
+    0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000,
+    0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000,
+    0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000,
+    0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000,
+    0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000,
+    0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000,
+    0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000,
+    0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000,
+    0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000,
+    0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000,
+    0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000,
+    0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000,
+    0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000,
+    0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000,
+    0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000,
+    0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000,
+    0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000,
+    0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000,
+    0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000,
+    0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000,
+    0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000,
+    0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000,
+    0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000,
+    0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000,
+    0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000,
+    0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000,
+    0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000,
+    0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000,
+    0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000,
+    0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000,
+    0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000,
+    0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000,
+    0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000,
+    0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000,
+    0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000,
+    0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000,
+    0x8ae9531c00000000},
+   {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000,
+    0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000,
+    0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000,
+    0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000,
+    0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000,
+    0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000,
+    0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000,
+    0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000,
+    0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000,
+    0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000,
+    0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000,
+    0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000,
+    0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000,
+    0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000,
+    0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000,
+    0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000,
+    0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000,
+    0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000,
+    0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000,
+    0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000,
+    0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000,
+    0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000,
+    0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000,
+    0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000,
+    0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000,
+    0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000,
+    0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000,
+    0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000,
+    0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000,
+    0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000,
+    0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000,
+    0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000,
+    0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000,
+    0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000,
+    0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000,
+    0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000,
+    0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000,
+    0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000,
+    0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000,
+    0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000,
+    0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000,
+    0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000,
+    0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000,
+    0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000,
+    0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000,
+    0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000,
+    0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000,
+    0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000,
+    0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000,
+    0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000,
+    0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000,
+    0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000,
+    0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000,
+    0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000,
+    0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000,
+    0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000,
+    0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000,
+    0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000,
+    0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000,
+    0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000,
+    0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000,
+    0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000,
+    0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000,
+    0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000,
+    0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000,
+    0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000,
+    0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000,
+    0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000,
+    0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000,
+    0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000,
+    0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000,
+    0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000,
+    0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000,
+    0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000,
+    0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000,
+    0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000,
+    0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000,
+    0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000,
+    0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000,
+    0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000,
+    0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000,
+    0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000,
+    0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000,
+    0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000,
+    0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000,
+    0xd739710d00000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa,
+    0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b,
+    0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232,
+    0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8,
+    0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,
+    0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa,
+    0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b,
+    0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,
+    0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719,
+    0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3,
+    0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,
+    0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b,
+    0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed,
+    0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89,
+    0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25,
+    0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
+    0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,
+    0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed,
+    0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4,
+    0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758,
+    0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e,
+    0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a,
+    0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,
+    0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,
+    0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df,
+    0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544,
+    0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d,
+    0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c,
+    0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,
+    0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95,
+    0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839,
+    0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
+    0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976,
+    0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7,
+    0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,
+    0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144,
+    0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12,
+    0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376,
+    0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a,
+    0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,
+    0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,
+    0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682,
+    0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b,
+    0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a,
+    0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561,
+    0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05,
+    0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,
+    0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
+    0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0,
+    0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61,
+    0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678,
+    0x264b06e6},
+   {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413,
+    0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3,
+    0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d,
+    0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653,
+    0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,
+    0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e,
+    0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5,
+    0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,
+    0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8,
+    0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6,
+    0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,
+    0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8,
+    0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579,
+    0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade,
+    0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37,
+    0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
+    0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,
+    0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64,
+    0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea,
+    0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678,
+    0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282,
+    0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25,
+    0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,
+    0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,
+    0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f,
+    0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146,
+    0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8,
+    0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08,
+    0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,
+    0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b,
+    0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972,
+    0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
+    0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d,
+    0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd,
+    0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,
+    0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d,
+    0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7,
+    0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60,
+    0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2,
+    0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,
+    0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,
+    0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1,
+    0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f,
+    0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf,
+    0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617,
+    0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0,
+    0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,
+    0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
+    0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca,
+    0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a,
+    0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184,
+    0x92364a30},
+   {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216,
+    0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8,
+    0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170,
+    0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035,
+    0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,
+    0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145,
+    0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d,
+    0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,
+    0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d,
+    0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408,
+    0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,
+    0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e,
+    0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c,
+    0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf,
+    0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a,
+    0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
+    0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,
+    0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f,
+    0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987,
+    0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4,
+    0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37,
+    0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84,
+    0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,
+    0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,
+    0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba,
+    0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d,
+    0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5,
+    0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b,
+    0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,
+    0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0,
+    0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525,
+    0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
+    0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8,
+    0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026,
+    0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,
+    0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db,
+    0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118,
+    0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab,
+    0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf,
+    0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,
+    0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,
+    0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a,
+    0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32,
+    0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec,
+    0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82,
+    0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31,
+    0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,
+    0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
+    0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f,
+    0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1,
+    0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869,
+    0xe4c4abcc},
+   {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0,
+    0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271,
+    0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61,
+    0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52,
+    0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,
+    0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333,
+    0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64,
+    0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,
+    0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205,
+    0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136,
+    0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,
+    0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997,
+    0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849,
+    0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739,
+    0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8,
+    0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
+    0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,
+    0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba,
+    0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa,
+    0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d,
+    0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c,
+    0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc,
+    0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,
+    0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,
+    0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce,
+    0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922,
+    0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532,
+    0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183,
+    0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,
+    0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860,
+    0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1,
+    0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
+    0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956,
+    0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7,
+    0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,
+    0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4,
+    0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5,
+    0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5,
+    0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb,
+    0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,
+    0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,
+    0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9,
+    0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9,
+    0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48,
+    0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df,
+    0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af,
+    0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,
+    0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
+    0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d,
+    0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c,
+    0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c,
+    0xca64c78c}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5,
+    0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d,
+    0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf,
+    0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027,
+    0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050,
+    0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098,
+    0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb,
+    0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173,
+    0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104,
+    0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c,
+    0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e,
+    0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6,
+    0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358,
+    0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390,
+    0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312,
+    0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da,
+    0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd,
+    0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335,
+    0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387,
+    0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de,
+    0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9,
+    0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261,
+    0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283,
+    0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b,
+    0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c,
+    0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c,
+    0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e,
+    0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6,
+    0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1,
+    0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619,
+    0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b,
+    0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653,
+    0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785,
+    0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d,
+    0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf,
+    0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757,
+    0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720,
+    0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8,
+    0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593,
+    0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b,
+    0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c,
+    0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4,
+    0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506,
+    0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe,
+    0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428,
+    0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0,
+    0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462,
+    0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa,
+    0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd,
+    0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445,
+    0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7,
+    0x8cc764ca},
+   {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b,
+    0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27,
+    0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a,
+    0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285,
+    0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef,
+    0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf,
+    0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a,
+    0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a,
+    0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70,
+    0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf,
+    0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2,
+    0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e,
+    0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f,
+    0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f,
+    0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae,
+    0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe,
+    0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97,
+    0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b,
+    0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436,
+    0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e,
+    0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4,
+    0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4,
+    0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46,
+    0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716,
+    0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c,
+    0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5,
+    0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8,
+    0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774,
+    0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d,
+    0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d,
+    0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc,
+    0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec,
+    0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82,
+    0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e,
+    0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623,
+    0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c,
+    0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6,
+    0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6,
+    0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c,
+    0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c,
+    0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66,
+    0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9,
+    0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4,
+    0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978,
+    0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416,
+    0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946,
+    0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7,
+    0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7,
+    0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e,
+    0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32,
+    0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f,
+    0xccabc4e4},
+   {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4,
+    0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895,
+    0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50,
+    0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656,
+    0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154,
+    0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906,
+    0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258,
+    0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a,
+    0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08,
+    0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e,
+    0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb,
+    0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa,
+    0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44,
+    0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316,
+    0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0,
+    0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2,
+    0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7,
+    0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6,
+    0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73,
+    0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba,
+    0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8,
+    0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea,
+    0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b,
+    0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29,
+    0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b,
+    0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e,
+    0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb,
+    0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a,
+    0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef,
+    0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd,
+    0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b,
+    0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019,
+    0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3,
+    0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2,
+    0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417,
+    0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11,
+    0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13,
+    0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241,
+    0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b,
+    0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09,
+    0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b,
+    0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d,
+    0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8,
+    0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9,
+    0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003,
+    0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851,
+    0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7,
+    0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5,
+    0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190,
+    0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1,
+    0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134,
+    0x304a3692},
+   {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84,
+    0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f,
+    0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15,
+    0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2,
+    0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf,
+    0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7,
+    0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb,
+    0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3,
+    0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae,
+    0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749,
+    0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243,
+    0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8,
+    0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29,
+    0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61,
+    0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8,
+    0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0,
+    0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1,
+    0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a,
+    0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40,
+    0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e,
+    0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03,
+    0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b,
+    0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee,
+    0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6,
+    0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb,
+    0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f,
+    0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495,
+    0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e,
+    0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f,
+    0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067,
+    0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be,
+    0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6,
+    0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e,
+    0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5,
+    0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf,
+    0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958,
+    0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305,
+    0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d,
+    0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338,
+    0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370,
+    0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d,
+    0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca,
+    0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0,
+    0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b,
+    0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083,
+    0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb,
+    0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012,
+    0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a,
+    0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b,
+    0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0,
+    0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea,
+    0xe6064b26}};
+
+#endif
+
+#endif
+
+#if N == 3
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f,
+    0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999,
+    0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee,
+    0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615,
+    0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383,
+    0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb,
+    0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275,
+    0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d,
+    0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b,
+    0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460,
+    0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317,
+    0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1,
+    0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5,
+    0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd,
+    0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04,
+    0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c,
+    0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7,
+    0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11,
+    0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66,
+    0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7,
+    0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871,
+    0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309,
+    0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd,
+    0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85,
+    0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913,
+    0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d,
+    0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a,
+    0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc,
+    0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57,
+    0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f,
+    0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6,
+    0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e,
+    0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f,
+    0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289,
+    0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe,
+    0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05,
+    0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893,
+    0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb,
+    0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0,
+    0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8,
+    0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e,
+    0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5,
+    0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2,
+    0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574,
+    0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5,
+    0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add,
+    0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114,
+    0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c,
+    0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7,
+    0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701,
+    0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076,
+    0x09cd8551},
+   {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193,
+    0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2,
+    0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c,
+    0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71,
+    0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a,
+    0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d,
+    0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71,
+    0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436,
+    0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d,
+    0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000,
+    0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae,
+    0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf,
+    0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930,
+    0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277,
+    0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff,
+    0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8,
+    0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef,
+    0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e,
+    0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20,
+    0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95,
+    0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e,
+    0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9,
+    0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d,
+    0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a,
+    0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151,
+    0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4,
+    0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a,
+    0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b,
+    0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c,
+    0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b,
+    0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3,
+    0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4,
+    0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b,
+    0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a,
+    0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4,
+    0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189,
+    0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92,
+    0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5,
+    0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9,
+    0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe,
+    0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5,
+    0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8,
+    0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66,
+    0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707,
+    0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8,
+    0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f,
+    0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707,
+    0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40,
+    0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017,
+    0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876,
+    0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8,
+    0x7bc97a0c},
+   {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300,
+    0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0,
+    0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80,
+    0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701,
+    0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41,
+    0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81,
+    0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43,
+    0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83,
+    0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3,
+    0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42,
+    0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202,
+    0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2,
+    0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7,
+    0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407,
+    0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47,
+    0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87,
+    0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86,
+    0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46,
+    0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506,
+    0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44,
+    0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704,
+    0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4,
+    0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5,
+    0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505,
+    0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45,
+    0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f,
+    0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f,
+    0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f,
+    0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e,
+    0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e,
+    0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e,
+    0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce,
+    0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c,
+    0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc,
+    0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c,
+    0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d,
+    0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d,
+    0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d,
+    0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88,
+    0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48,
+    0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708,
+    0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89,
+    0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9,
+    0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309,
+    0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb,
+    0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b,
+    0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b,
+    0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b,
+    0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a,
+    0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a,
+    0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a,
+    0x7851a2ca},
+   {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb,
+    0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8,
+    0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0,
+    0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f,
+    0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a,
+    0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf,
+    0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5,
+    0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380,
+    0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815,
+    0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa,
+    0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2,
+    0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1,
+    0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1,
+    0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4,
+    0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa,
+    0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df,
+    0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6,
+    0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5,
+    0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad,
+    0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca,
+    0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f,
+    0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a,
+    0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8,
+    0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d,
+    0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708,
+    0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d,
+    0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865,
+    0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636,
+    0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f,
+    0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a,
+    0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744,
+    0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061,
+    0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0,
+    0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293,
+    0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb,
+    0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874,
+    0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1,
+    0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4,
+    0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f,
+    0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a,
+    0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f,
+    0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120,
+    0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778,
+    0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b,
+    0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a,
+    0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af,
+    0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81,
+    0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4,
+    0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd,
+    0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e,
+    0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6,
+    0x566b6848},
+   {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59,
+    0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4,
+    0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67,
+    0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef,
+    0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97,
+    0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88,
+    0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687,
+    0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698,
+    0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0,
+    0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068,
+    0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb,
+    0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056,
+    0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016,
+    0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009,
+    0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028,
+    0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037,
+    0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a,
+    0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7,
+    0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054,
+    0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7,
+    0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af,
+    0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0,
+    0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4,
+    0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab,
+    0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3,
+    0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a,
+    0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9,
+    0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54,
+    0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09,
+    0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16,
+    0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37,
+    0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28,
+    0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e,
+    0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3,
+    0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40,
+    0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8,
+    0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0,
+    0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf,
+    0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6,
+    0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9,
+    0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1,
+    0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059,
+    0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca,
+    0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067,
+    0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031,
+    0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e,
+    0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f,
+    0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010,
+    0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d,
+    0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0,
+    0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073,
+    0xd8ac6b35},
+   {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2,
+    0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd,
+    0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696,
+    0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3,
+    0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f,
+    0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35,
+    0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5,
+    0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f,
+    0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673,
+    0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46,
+    0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d,
+    0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632,
+    0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28,
+    0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192,
+    0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c,
+    0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6,
+    0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0,
+    0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff,
+    0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4,
+    0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95,
+    0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9,
+    0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03,
+    0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7,
+    0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d,
+    0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151,
+    0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808,
+    0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343,
+    0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c,
+    0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a,
+    0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0,
+    0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e,
+    0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594,
+    0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6,
+    0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399,
+    0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2,
+    0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7,
+    0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb,
+    0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571,
+    0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289,
+    0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33,
+    0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f,
+    0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a,
+    0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461,
+    0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e,
+    0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c,
+    0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6,
+    0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918,
+    0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2,
+    0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484,
+    0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb,
+    0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0,
+    0xa140efa8},
+   {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706,
+    0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed,
+    0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289,
+    0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a,
+    0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214,
+    0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3,
+    0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3,
+    0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254,
+    0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a,
+    0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9,
+    0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad,
+    0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746,
+    0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060,
+    0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187,
+    0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef,
+    0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408,
+    0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e,
+    0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495,
+    0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1,
+    0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532,
+    0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c,
+    0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb,
+    0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb,
+    0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c,
+    0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42,
+    0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060,
+    0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04,
+    0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef,
+    0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99,
+    0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e,
+    0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16,
+    0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1,
+    0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7,
+    0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c,
+    0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38,
+    0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb,
+    0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5,
+    0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42,
+    0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62,
+    0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85,
+    0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb,
+    0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18,
+    0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c,
+    0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997,
+    0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1,
+    0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36,
+    0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e,
+    0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9,
+    0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf,
+    0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24,
+    0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040,
+    0x917cd6a1},
+   {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf,
+    0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd,
+    0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896,
+    0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9,
+    0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3,
+    0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f,
+    0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d,
+    0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1,
+    0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab,
+    0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4,
+    0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f,
+    0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d,
+    0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4,
+    0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978,
+    0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad,
+    0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621,
+    0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46,
+    0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854,
+    0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f,
+    0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a,
+    0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890,
+    0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c,
+    0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4,
+    0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238,
+    0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622,
+    0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab,
+    0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0,
+    0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2,
+    0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295,
+    0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19,
+    0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc,
+    0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140,
+    0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd,
+    0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf,
+    0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184,
+    0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb,
+    0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1,
+    0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d,
+    0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb,
+    0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257,
+    0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d,
+    0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22,
+    0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069,
+    0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b,
+    0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6,
+    0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a,
+    0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf,
+    0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33,
+    0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254,
+    0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146,
+    0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d,
+    0x18ba364e}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000,
+    0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000,
+    0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000,
+    0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000,
+    0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000,
+    0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000,
+    0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000,
+    0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000,
+    0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000,
+    0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000,
+    0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000,
+    0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000,
+    0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000,
+    0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000,
+    0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000,
+    0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000,
+    0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000,
+    0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000,
+    0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000,
+    0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000,
+    0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000,
+    0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000,
+    0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000,
+    0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000,
+    0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000,
+    0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000,
+    0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000,
+    0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000,
+    0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000,
+    0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000,
+    0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000,
+    0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000,
+    0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000,
+    0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000,
+    0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000,
+    0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000,
+    0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000,
+    0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000,
+    0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000,
+    0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000,
+    0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000,
+    0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000,
+    0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000,
+    0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000,
+    0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000,
+    0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000,
+    0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000,
+    0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000,
+    0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000,
+    0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000,
+    0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000,
+    0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000,
+    0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000,
+    0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000,
+    0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000,
+    0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000,
+    0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000,
+    0x08eda52100000000, 0x4391370100000000, 0x005a918600000000,
+    0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000,
+    0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000,
+    0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000,
+    0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000,
+    0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000,
+    0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000,
+    0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000,
+    0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000,
+    0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000,
+    0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000,
+    0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000,
+    0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000,
+    0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000,
+    0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000,
+    0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000,
+    0x7b23114500000000, 0x305f836500000000, 0x739425e200000000,
+    0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000,
+    0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000,
+    0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000,
+    0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000,
+    0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000,
+    0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000,
+    0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000,
+    0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000,
+    0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000,
+    0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000,
+    0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000,
+    0x4e36ba1800000000},
+   {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000,
+    0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000,
+    0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000,
+    0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000,
+    0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000,
+    0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000,
+    0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000,
+    0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000,
+    0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000,
+    0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000,
+    0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000,
+    0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000,
+    0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000,
+    0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000,
+    0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000,
+    0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000,
+    0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000,
+    0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000,
+    0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000,
+    0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000,
+    0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000,
+    0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000,
+    0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000,
+    0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000,
+    0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000,
+    0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000,
+    0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000,
+    0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000,
+    0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000,
+    0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000,
+    0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000,
+    0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000,
+    0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000,
+    0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000,
+    0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000,
+    0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000,
+    0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000,
+    0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000,
+    0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000,
+    0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000,
+    0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000,
+    0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000,
+    0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000,
+    0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000,
+    0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000,
+    0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000,
+    0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000,
+    0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000,
+    0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000,
+    0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000,
+    0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000,
+    0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000,
+    0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000,
+    0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000,
+    0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000,
+    0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000,
+    0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000,
+    0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000,
+    0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000,
+    0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000,
+    0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000,
+    0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000,
+    0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000,
+    0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000,
+    0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000,
+    0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000,
+    0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000,
+    0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000,
+    0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000,
+    0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000,
+    0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000,
+    0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000,
+    0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000,
+    0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000,
+    0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000,
+    0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000,
+    0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000,
+    0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000,
+    0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000,
+    0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000,
+    0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000,
+    0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000,
+    0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000,
+    0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000,
+    0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000,
+    0xa1d67c9100000000},
+   {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000,
+    0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000,
+    0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000,
+    0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000,
+    0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000,
+    0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000,
+    0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000,
+    0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000,
+    0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000,
+    0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000,
+    0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000,
+    0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000,
+    0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000,
+    0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000,
+    0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000,
+    0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000,
+    0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000,
+    0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000,
+    0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000,
+    0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000,
+    0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000,
+    0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000,
+    0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000,
+    0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000,
+    0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000,
+    0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000,
+    0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000,
+    0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000,
+    0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000,
+    0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000,
+    0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000,
+    0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000,
+    0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000,
+    0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000,
+    0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000,
+    0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000,
+    0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000,
+    0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000,
+    0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000,
+    0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000,
+    0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000,
+    0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000,
+    0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000,
+    0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000,
+    0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000,
+    0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000,
+    0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000,
+    0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000,
+    0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000,
+    0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000,
+    0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000,
+    0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000,
+    0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000,
+    0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000,
+    0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000,
+    0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000,
+    0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000,
+    0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000,
+    0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000,
+    0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000,
+    0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000,
+    0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000,
+    0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000,
+    0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000,
+    0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000,
+    0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000,
+    0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000,
+    0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000,
+    0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000,
+    0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000,
+    0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000,
+    0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000,
+    0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000,
+    0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000,
+    0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000,
+    0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000,
+    0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000,
+    0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000,
+    0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000,
+    0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000,
+    0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000,
+    0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000,
+    0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000,
+    0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000,
+    0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000,
+    0xa8ef40a100000000},
+   {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000,
+    0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000,
+    0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000,
+    0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000,
+    0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000,
+    0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000,
+    0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000,
+    0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000,
+    0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000,
+    0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000,
+    0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000,
+    0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000,
+    0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000,
+    0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000,
+    0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000,
+    0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000,
+    0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000,
+    0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000,
+    0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000,
+    0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000,
+    0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000,
+    0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000,
+    0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000,
+    0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000,
+    0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000,
+    0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000,
+    0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000,
+    0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000,
+    0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000,
+    0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000,
+    0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000,
+    0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000,
+    0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000,
+    0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000,
+    0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000,
+    0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000,
+    0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000,
+    0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000,
+    0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000,
+    0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000,
+    0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000,
+    0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000,
+    0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000,
+    0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000,
+    0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000,
+    0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000,
+    0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000,
+    0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000,
+    0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000,
+    0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000,
+    0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000,
+    0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000,
+    0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000,
+    0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000,
+    0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000,
+    0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000,
+    0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000,
+    0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000,
+    0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000,
+    0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000,
+    0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000,
+    0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000,
+    0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000,
+    0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000,
+    0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000,
+    0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000,
+    0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000,
+    0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000,
+    0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000,
+    0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000,
+    0x933d017400000000, 0xd506661100000000, 0x46a022f000000000,
+    0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000,
+    0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000,
+    0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000,
+    0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000,
+    0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000,
+    0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000,
+    0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000,
+    0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000,
+    0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000,
+    0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000,
+    0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000,
+    0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000,
+    0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000,
+    0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000,
+    0x356bacd800000000},
+   {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000,
+    0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000,
+    0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000,
+    0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000,
+    0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000,
+    0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000,
+    0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000,
+    0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000,
+    0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000,
+    0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000,
+    0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000,
+    0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000,
+    0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000,
+    0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000,
+    0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000,
+    0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000,
+    0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000,
+    0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000,
+    0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000,
+    0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000,
+    0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000,
+    0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000,
+    0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000,
+    0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000,
+    0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000,
+    0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000,
+    0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000,
+    0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000,
+    0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000,
+    0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000,
+    0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000,
+    0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000,
+    0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000,
+    0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000,
+    0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000,
+    0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000,
+    0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000,
+    0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000,
+    0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000,
+    0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000,
+    0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000,
+    0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000,
+    0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000,
+    0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000,
+    0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000,
+    0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000,
+    0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000,
+    0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000,
+    0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000,
+    0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000,
+    0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000,
+    0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000,
+    0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000,
+    0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000,
+    0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000,
+    0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000,
+    0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000,
+    0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000,
+    0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000,
+    0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000,
+    0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000,
+    0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000,
+    0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000,
+    0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000,
+    0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000,
+    0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000,
+    0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000,
+    0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000,
+    0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000,
+    0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000,
+    0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000,
+    0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000,
+    0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000,
+    0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000,
+    0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000,
+    0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000,
+    0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000,
+    0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000,
+    0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000,
+    0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000,
+    0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000,
+    0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000,
+    0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000,
+    0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000,
+    0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000,
+    0x48686b5600000000},
+   {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000,
+    0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000,
+    0x805af17200000000, 0x403ed96500000000, 0x002643b900000000,
+    0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000,
+    0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000,
+    0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000,
+    0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000,
+    0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000,
+    0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000,
+    0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000,
+    0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000,
+    0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000,
+    0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000,
+    0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000,
+    0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000,
+    0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000,
+    0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000,
+    0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000,
+    0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000,
+    0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000,
+    0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000,
+    0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000,
+    0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000,
+    0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000,
+    0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000,
+    0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000,
+    0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000,
+    0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000,
+    0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000,
+    0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000,
+    0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000,
+    0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000,
+    0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000,
+    0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000,
+    0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000,
+    0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000,
+    0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000,
+    0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000,
+    0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000,
+    0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000,
+    0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000,
+    0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000,
+    0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000,
+    0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000,
+    0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000,
+    0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000,
+    0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000,
+    0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000,
+    0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000,
+    0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000,
+    0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000,
+    0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000,
+    0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000,
+    0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000,
+    0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000,
+    0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000,
+    0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000,
+    0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000,
+    0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000,
+    0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000,
+    0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000,
+    0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000,
+    0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000,
+    0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000,
+    0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000,
+    0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000,
+    0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000,
+    0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000,
+    0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000,
+    0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000,
+    0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000,
+    0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000,
+    0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000,
+    0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000,
+    0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000,
+    0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000,
+    0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000,
+    0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000,
+    0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000,
+    0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000,
+    0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000,
+    0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000,
+    0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000,
+    0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000,
+    0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000,
+    0xcaa2517800000000},
+   {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000,
+    0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000,
+    0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000,
+    0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000,
+    0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000,
+    0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000,
+    0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000,
+    0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000,
+    0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000,
+    0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000,
+    0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000,
+    0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000,
+    0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000,
+    0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000,
+    0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000,
+    0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000,
+    0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000,
+    0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000,
+    0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000,
+    0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000,
+    0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000,
+    0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000,
+    0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000,
+    0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000,
+    0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000,
+    0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000,
+    0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000,
+    0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000,
+    0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000,
+    0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000,
+    0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000,
+    0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000,
+    0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000,
+    0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000,
+    0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000,
+    0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000,
+    0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000,
+    0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000,
+    0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000,
+    0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000,
+    0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000,
+    0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000,
+    0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000,
+    0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000,
+    0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000,
+    0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000,
+    0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000,
+    0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000,
+    0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000,
+    0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000,
+    0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000,
+    0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000,
+    0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000,
+    0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000,
+    0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000,
+    0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000,
+    0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000,
+    0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000,
+    0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000,
+    0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000,
+    0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000,
+    0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000,
+    0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000,
+    0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000,
+    0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000,
+    0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000,
+    0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000,
+    0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000,
+    0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000,
+    0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000,
+    0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000,
+    0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000,
+    0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000,
+    0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000,
+    0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000,
+    0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000,
+    0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000,
+    0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000,
+    0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000,
+    0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000,
+    0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000,
+    0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000,
+    0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000,
+    0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000,
+    0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000,
+    0x0c7ac97b00000000},
+   {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000,
+    0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000,
+    0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000,
+    0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000,
+    0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000,
+    0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000,
+    0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000,
+    0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000,
+    0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000,
+    0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000,
+    0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000,
+    0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000,
+    0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000,
+    0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000,
+    0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000,
+    0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000,
+    0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000,
+    0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000,
+    0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000,
+    0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000,
+    0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000,
+    0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000,
+    0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000,
+    0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000,
+    0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000,
+    0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000,
+    0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000,
+    0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000,
+    0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000,
+    0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000,
+    0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000,
+    0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000,
+    0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000,
+    0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000,
+    0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000,
+    0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000,
+    0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000,
+    0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000,
+    0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000,
+    0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000,
+    0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000,
+    0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000,
+    0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000,
+    0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000,
+    0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000,
+    0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000,
+    0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000,
+    0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000,
+    0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000,
+    0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000,
+    0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000,
+    0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000,
+    0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000,
+    0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000,
+    0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000,
+    0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000,
+    0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000,
+    0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000,
+    0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000,
+    0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000,
+    0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000,
+    0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000,
+    0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000,
+    0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000,
+    0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000,
+    0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000,
+    0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000,
+    0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000,
+    0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000,
+    0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000,
+    0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000,
+    0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000,
+    0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000,
+    0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000,
+    0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000,
+    0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000,
+    0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000,
+    0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000,
+    0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000,
+    0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000,
+    0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000,
+    0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000,
+    0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000,
+    0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000,
+    0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000,
+    0x5185cd0900000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f,
+    0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91,
+    0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e,
+    0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c,
+    0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02,
+    0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12,
+    0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567,
+    0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277,
+    0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679,
+    0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b,
+    0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4,
+    0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a,
+    0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0,
+    0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0,
+    0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91,
+    0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881,
+    0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173,
+    0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d,
+    0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912,
+    0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8,
+    0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6,
+    0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6,
+    0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b,
+    0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b,
+    0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75,
+    0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f,
+    0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00,
+    0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee,
+    0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c,
+    0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c,
+    0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d,
+    0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d,
+    0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67,
+    0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89,
+    0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706,
+    0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14,
+    0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a,
+    0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a,
+    0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f,
+    0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f,
+    0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591,
+    0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983,
+    0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c,
+    0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2,
+    0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8,
+    0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8,
+    0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89,
+    0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99,
+    0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b,
+    0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485,
+    0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a,
+    0x36197165},
+   {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382,
+    0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85,
+    0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06,
+    0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca,
+    0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e,
+    0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc,
+    0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616,
+    0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54,
+    0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10,
+    0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc,
+    0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f,
+    0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58,
+    0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef,
+    0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad,
+    0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b,
+    0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29,
+    0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6,
+    0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1,
+    0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622,
+    0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039,
+    0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d,
+    0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f,
+    0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32,
+    0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770,
+    0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034,
+    0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f,
+    0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc,
+    0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db,
+    0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154,
+    0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16,
+    0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0,
+    0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592,
+    0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca,
+    0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd,
+    0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e,
+    0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882,
+    0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6,
+    0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384,
+    0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1,
+    0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3,
+    0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7,
+    0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b,
+    0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8,
+    0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff,
+    0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7,
+    0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5,
+    0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23,
+    0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761,
+    0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee,
+    0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9,
+    0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a,
+    0x1a3b93aa},
+   {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a,
+    0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca,
+    0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3,
+    0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb,
+    0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c,
+    0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58,
+    0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed,
+    0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9,
+    0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e,
+    0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906,
+    0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f,
+    0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf,
+    0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0,
+    0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4,
+    0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769,
+    0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d,
+    0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632,
+    0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82,
+    0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb,
+    0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73,
+    0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484,
+    0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0,
+    0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5,
+    0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1,
+    0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516,
+    0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f,
+    0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946,
+    0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6,
+    0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9,
+    0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad,
+    0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820,
+    0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364,
+    0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab,
+    0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b,
+    0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62,
+    0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a,
+    0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd,
+    0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089,
+    0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c,
+    0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8,
+    0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f,
+    0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477,
+    0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e,
+    0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be,
+    0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71,
+    0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635,
+    0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8,
+    0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc,
+    0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3,
+    0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753,
+    0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a,
+    0xe147d714},
+   {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c,
+    0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b,
+    0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92,
+    0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4,
+    0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069,
+    0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526,
+    0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25,
+    0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a,
+    0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7,
+    0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491,
+    0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958,
+    0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f,
+    0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307,
+    0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648,
+    0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999,
+    0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6,
+    0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a,
+    0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d,
+    0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4,
+    0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61,
+    0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc,
+    0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3,
+    0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53,
+    0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c,
+    0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1,
+    0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c,
+    0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5,
+    0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92,
+    0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e,
+    0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771,
+    0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0,
+    0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def,
+    0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0,
+    0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7,
+    0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e,
+    0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58,
+    0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285,
+    0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca,
+    0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce,
+    0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81,
+    0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c,
+    0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a,
+    0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3,
+    0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4,
+    0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb,
+    0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4,
+    0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75,
+    0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a,
+    0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296,
+    0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1,
+    0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808,
+    0x494f0c4b}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d,
+    0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac,
+    0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8,
+    0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95,
+    0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817,
+    0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d,
+    0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac,
+    0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6,
+    0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564,
+    0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39,
+    0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d,
+    0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac,
+    0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de,
+    0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594,
+    0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b,
+    0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01,
+    0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f,
+    0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de,
+    0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba,
+    0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65,
+    0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7,
+    0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad,
+    0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de,
+    0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294,
+    0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716,
+    0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71,
+    0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15,
+    0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4,
+    0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca,
+    0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280,
+    0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f,
+    0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15,
+    0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9,
+    0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748,
+    0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c,
+    0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971,
+    0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3,
+    0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9,
+    0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196,
+    0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc,
+    0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e,
+    0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03,
+    0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67,
+    0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296,
+    0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a,
+    0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170,
+    0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af,
+    0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5,
+    0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb,
+    0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a,
+    0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e,
+    0x4b0c4f49},
+   {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09,
+    0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc,
+    0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e,
+    0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc,
+    0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934,
+    0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2,
+    0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b,
+    0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad,
+    0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155,
+    0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187,
+    0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65,
+    0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390,
+    0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e,
+    0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378,
+    0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889,
+    0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f,
+    0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0,
+    0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145,
+    0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7,
+    0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a,
+    0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2,
+    0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924,
+    0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2,
+    0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514,
+    0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec,
+    0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709,
+    0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb,
+    0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e,
+    0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1,
+    0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227,
+    0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6,
+    0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030,
+    0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0,
+    0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55,
+    0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7,
+    0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165,
+    0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d,
+    0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b,
+    0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c,
+    0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a,
+    0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362,
+    0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0,
+    0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52,
+    0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7,
+    0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237,
+    0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1,
+    0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020,
+    0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6,
+    0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719,
+    0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec,
+    0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e,
+    0x14d747e1},
+   {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0,
+    0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b,
+    0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652,
+    0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437,
+    0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514,
+    0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265,
+    0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de,
+    0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af,
+    0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c,
+    0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9,
+    0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0,
+    0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b,
+    0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6,
+    0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7,
+    0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734,
+    0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045,
+    0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8,
+    0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303,
+    0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a,
+    0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9,
+    0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea,
+    0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b,
+    0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6,
+    0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7,
+    0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4,
+    0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6,
+    0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f,
+    0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054,
+    0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9,
+    0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8,
+    0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b,
+    0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a,
+    0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441,
+    0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a,
+    0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3,
+    0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6,
+    0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5,
+    0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94,
+    0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9,
+    0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288,
+    0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab,
+    0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce,
+    0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7,
+    0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c,
+    0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527,
+    0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256,
+    0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5,
+    0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4,
+    0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39,
+    0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2,
+    0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db,
+    0xaa933b1a},
+   {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603,
+    0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d,
+    0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9,
+    0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b,
+    0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a,
+    0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792,
+    0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4,
+    0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c,
+    0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d,
+    0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f,
+    0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb,
+    0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65,
+    0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330,
+    0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8,
+    0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da,
+    0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742,
+    0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f,
+    0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1,
+    0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5,
+    0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f,
+    0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e,
+    0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6,
+    0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8,
+    0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250,
+    0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021,
+    0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb,
+    0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f,
+    0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511,
+    0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c,
+    0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4,
+    0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886,
+    0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e,
+    0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b,
+    0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5,
+    0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791,
+    0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003,
+    0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272,
+    0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea,
+    0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc,
+    0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24,
+    0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55,
+    0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7,
+    0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3,
+    0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d,
+    0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548,
+    0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0,
+    0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2,
+    0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a,
+    0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47,
+    0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9,
+    0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad,
+    0x65711936}};
+
+#endif
+
+#endif
+
+#if N == 4
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a,
+    0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe,
+    0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b,
+    0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656,
+    0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd,
+    0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d,
+    0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7,
+    0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47,
+    0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac,
+    0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691,
+    0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404,
+    0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0,
+    0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4,
+    0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424,
+    0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5,
+    0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65,
+    0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67,
+    0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3,
+    0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626,
+    0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9,
+    0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222,
+    0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2,
+    0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a,
+    0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a,
+    0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1,
+    0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2,
+    0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077,
+    0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3,
+    0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1,
+    0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621,
+    0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0,
+    0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60,
+    0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0,
+    0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64,
+    0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1,
+    0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc,
+    0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027,
+    0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7,
+    0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9,
+    0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79,
+    0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292,
+    0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af,
+    0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a,
+    0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee,
+    0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e,
+    0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe,
+    0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f,
+    0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff,
+    0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd,
+    0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29,
+    0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc,
+    0xe3c45916},
+   {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344,
+    0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59,
+    0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e,
+    0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463,
+    0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98,
+    0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d,
+    0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3,
+    0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656,
+    0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad,
+    0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0,
+    0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397,
+    0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a,
+    0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2,
+    0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357,
+    0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8,
+    0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d,
+    0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696,
+    0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b,
+    0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc,
+    0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0,
+    0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b,
+    0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be,
+    0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811,
+    0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384,
+    0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f,
+    0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955,
+    0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362,
+    0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f,
+    0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94,
+    0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701,
+    0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe,
+    0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b,
+    0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1,
+    0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc,
+    0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b,
+    0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986,
+    0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d,
+    0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8,
+    0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4,
+    0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371,
+    0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a,
+    0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87,
+    0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0,
+    0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad,
+    0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527,
+    0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2,
+    0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d,
+    0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998,
+    0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73,
+    0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e,
+    0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59,
+    0xa7520488},
+   {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20,
+    0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09,
+    0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431,
+    0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a,
+    0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203,
+    0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b,
+    0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14,
+    0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c,
+    0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25,
+    0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e,
+    0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36,
+    0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f,
+    0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649,
+    0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961,
+    0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58,
+    0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170,
+    0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b,
+    0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742,
+    0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a,
+    0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55,
+    0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c,
+    0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64,
+    0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f,
+    0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77,
+    0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e,
+    0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a,
+    0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2,
+    0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b,
+    0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090,
+    0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8,
+    0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881,
+    0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9,
+    0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6,
+    0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f,
+    0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7,
+    0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c,
+    0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695,
+    0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd,
+    0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb,
+    0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3,
+    0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa,
+    0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1,
+    0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9,
+    0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0,
+    0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df,
+    0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7,
+    0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace,
+    0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6,
+    0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd,
+    0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4,
+    0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec,
+    0x3522e9e4},
+   {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1,
+    0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86,
+    0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b,
+    0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669,
+    0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7,
+    0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352,
+    0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03,
+    0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6,
+    0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38,
+    0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a,
+    0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7,
+    0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80,
+    0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7,
+    0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522,
+    0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d,
+    0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8,
+    0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103,
+    0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54,
+    0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9,
+    0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0,
+    0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e,
+    0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb,
+    0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1,
+    0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624,
+    0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea,
+    0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a,
+    0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37,
+    0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360,
+    0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab,
+    0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e,
+    0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741,
+    0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4,
+    0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334,
+    0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63,
+    0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de,
+    0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c,
+    0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942,
+    0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7,
+    0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131,
+    0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4,
+    0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a,
+    0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758,
+    0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5,
+    0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2,
+    0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32,
+    0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7,
+    0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8,
+    0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d,
+    0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6,
+    0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1,
+    0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c,
+    0x97411e28},
+   {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474,
+    0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5,
+    0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6,
+    0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7,
+    0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938,
+    0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051,
+    0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a,
+    0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3,
+    0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c,
+    0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d,
+    0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e,
+    0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf,
+    0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740,
+    0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29,
+    0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592,
+    0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb,
+    0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4,
+    0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365,
+    0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036,
+    0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7,
+    0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08,
+    0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561,
+    0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a,
+    0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663,
+    0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac,
+    0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d,
+    0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce,
+    0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f,
+    0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50,
+    0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639,
+    0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82,
+    0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb,
+    0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954,
+    0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5,
+    0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86,
+    0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7,
+    0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418,
+    0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71,
+    0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa,
+    0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93,
+    0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c,
+    0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d,
+    0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e,
+    0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df,
+    0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60,
+    0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309,
+    0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2,
+    0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db,
+    0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4,
+    0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45,
+    0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16,
+    0x93c7a00b},
+   {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45,
+    0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb,
+    0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d,
+    0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696,
+    0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf,
+    0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb,
+    0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028,
+    0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c,
+    0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65,
+    0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be,
+    0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038,
+    0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6,
+    0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15,
+    0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11,
+    0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d,
+    0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19,
+    0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05,
+    0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b,
+    0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d,
+    0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c,
+    0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35,
+    0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31,
+    0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068,
+    0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c,
+    0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25,
+    0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a,
+    0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac,
+    0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22,
+    0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e,
+    0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a,
+    0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36,
+    0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32,
+    0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84,
+    0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a,
+    0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c,
+    0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057,
+    0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e,
+    0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a,
+    0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc,
+    0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8,
+    0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1,
+    0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a,
+    0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec,
+    0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62,
+    0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4,
+    0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0,
+    0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc,
+    0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8,
+    0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4,
+    0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a,
+    0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc,
+    0xce5f968d},
+   {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de,
+    0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b,
+    0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d,
+    0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680,
+    0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4,
+    0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d,
+    0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde,
+    0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97,
+    0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3,
+    0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e,
+    0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678,
+    0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d,
+    0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723,
+    0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a,
+    0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0,
+    0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9,
+    0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85,
+    0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770,
+    0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56,
+    0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a,
+    0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e,
+    0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67,
+    0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785,
+    0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc,
+    0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788,
+    0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90,
+    0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6,
+    0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843,
+    0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f,
+    0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336,
+    0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac,
+    0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5,
+    0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68,
+    0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d,
+    0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb,
+    0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36,
+    0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72,
+    0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b,
+    0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b,
+    0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402,
+    0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446,
+    0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb,
+    0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed,
+    0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418,
+    0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95,
+    0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc,
+    0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946,
+    0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f,
+    0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233,
+    0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6,
+    0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0,
+    0x3e721277},
+   {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb,
+    0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9,
+    0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11,
+    0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d,
+    0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9,
+    0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c,
+    0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881,
+    0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274,
+    0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790,
+    0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc,
+    0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514,
+    0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56,
+    0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9,
+    0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c,
+    0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13,
+    0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6,
+    0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c,
+    0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e,
+    0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386,
+    0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376,
+    0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692,
+    0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67,
+    0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416,
+    0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3,
+    0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07,
+    0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd,
+    0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15,
+    0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457,
+    0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd,
+    0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28,
+    0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337,
+    0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2,
+    0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594,
+    0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6,
+    0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e,
+    0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52,
+    0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6,
+    0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143,
+    0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17,
+    0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2,
+    0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306,
+    0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a,
+    0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182,
+    0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0,
+    0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496,
+    0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63,
+    0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c,
+    0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89,
+    0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903,
+    0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041,
+    0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9,
+    0x1c65ace7}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000,
+    0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000,
+    0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000,
+    0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000,
+    0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000,
+    0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000,
+    0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000,
+    0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000,
+    0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000,
+    0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000,
+    0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000,
+    0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000,
+    0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000,
+    0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000,
+    0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000,
+    0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000,
+    0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000,
+    0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000,
+    0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000,
+    0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000,
+    0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000,
+    0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000,
+    0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000,
+    0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000,
+    0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000,
+    0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000,
+    0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000,
+    0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000,
+    0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000,
+    0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000,
+    0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000,
+    0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000,
+    0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000,
+    0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000,
+    0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000,
+    0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000,
+    0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000,
+    0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000,
+    0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000,
+    0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000,
+    0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000,
+    0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000,
+    0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000,
+    0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000,
+    0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000,
+    0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000,
+    0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000,
+    0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000,
+    0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000,
+    0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000,
+    0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000,
+    0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000,
+    0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000,
+    0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000,
+    0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000,
+    0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000,
+    0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000,
+    0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000,
+    0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000,
+    0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000,
+    0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000,
+    0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000,
+    0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000,
+    0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000,
+    0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000,
+    0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000,
+    0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000,
+    0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000,
+    0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000,
+    0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000,
+    0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000,
+    0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000,
+    0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000,
+    0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000,
+    0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000,
+    0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000,
+    0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000,
+    0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000,
+    0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000,
+    0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000,
+    0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000,
+    0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000,
+    0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000,
+    0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000,
+    0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000,
+    0xe7ac651c00000000},
+   {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000,
+    0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000,
+    0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000,
+    0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000,
+    0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000,
+    0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000,
+    0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000,
+    0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000,
+    0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000,
+    0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000,
+    0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000,
+    0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000,
+    0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000,
+    0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000,
+    0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000,
+    0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000,
+    0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000,
+    0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000,
+    0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000,
+    0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000,
+    0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000,
+    0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000,
+    0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000,
+    0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000,
+    0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000,
+    0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000,
+    0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000,
+    0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000,
+    0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000,
+    0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000,
+    0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000,
+    0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000,
+    0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000,
+    0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000,
+    0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000,
+    0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000,
+    0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000,
+    0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000,
+    0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000,
+    0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000,
+    0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000,
+    0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000,
+    0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000,
+    0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000,
+    0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000,
+    0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000,
+    0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000,
+    0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000,
+    0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000,
+    0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000,
+    0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000,
+    0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000,
+    0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000,
+    0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000,
+    0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000,
+    0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000,
+    0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000,
+    0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000,
+    0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000,
+    0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000,
+    0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000,
+    0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000,
+    0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000,
+    0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000,
+    0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000,
+    0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000,
+    0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000,
+    0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000,
+    0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000,
+    0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000,
+    0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000,
+    0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000,
+    0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000,
+    0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000,
+    0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000,
+    0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000,
+    0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000,
+    0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000,
+    0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000,
+    0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000,
+    0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000,
+    0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000,
+    0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000,
+    0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000,
+    0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000,
+    0x7712723e00000000},
+   {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000,
+    0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000,
+    0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000,
+    0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000,
+    0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000,
+    0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000,
+    0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000,
+    0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000,
+    0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000,
+    0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000,
+    0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000,
+    0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000,
+    0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000,
+    0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000,
+    0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000,
+    0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000,
+    0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000,
+    0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000,
+    0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000,
+    0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000,
+    0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000,
+    0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000,
+    0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000,
+    0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000,
+    0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000,
+    0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000,
+    0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000,
+    0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000,
+    0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000,
+    0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000,
+    0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000,
+    0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000,
+    0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000,
+    0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000,
+    0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000,
+    0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000,
+    0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000,
+    0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000,
+    0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000,
+    0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000,
+    0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000,
+    0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000,
+    0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000,
+    0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000,
+    0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000,
+    0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000,
+    0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000,
+    0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000,
+    0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000,
+    0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000,
+    0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000,
+    0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000,
+    0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000,
+    0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000,
+    0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000,
+    0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000,
+    0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000,
+    0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000,
+    0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000,
+    0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000,
+    0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000,
+    0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000,
+    0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000,
+    0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000,
+    0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000,
+    0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000,
+    0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000,
+    0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000,
+    0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000,
+    0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000,
+    0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000,
+    0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000,
+    0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000,
+    0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000,
+    0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000,
+    0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000,
+    0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000,
+    0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000,
+    0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000,
+    0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000,
+    0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000,
+    0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000,
+    0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000,
+    0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000,
+    0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000,
+    0x8d965fce00000000},
+   {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000,
+    0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000,
+    0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000,
+    0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000,
+    0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000,
+    0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000,
+    0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000,
+    0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000,
+    0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000,
+    0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000,
+    0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000,
+    0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000,
+    0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000,
+    0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000,
+    0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000,
+    0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000,
+    0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000,
+    0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000,
+    0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000,
+    0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000,
+    0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000,
+    0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000,
+    0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000,
+    0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000,
+    0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000,
+    0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000,
+    0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000,
+    0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000,
+    0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000,
+    0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000,
+    0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000,
+    0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000,
+    0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000,
+    0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000,
+    0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000,
+    0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000,
+    0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000,
+    0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000,
+    0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000,
+    0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000,
+    0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000,
+    0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000,
+    0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000,
+    0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000,
+    0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000,
+    0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000,
+    0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000,
+    0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000,
+    0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000,
+    0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000,
+    0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000,
+    0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000,
+    0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000,
+    0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000,
+    0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000,
+    0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000,
+    0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000,
+    0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000,
+    0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000,
+    0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000,
+    0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000,
+    0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000,
+    0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000,
+    0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000,
+    0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000,
+    0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000,
+    0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000,
+    0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000,
+    0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000,
+    0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000,
+    0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000,
+    0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000,
+    0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000,
+    0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000,
+    0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000,
+    0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000,
+    0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000,
+    0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000,
+    0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000,
+    0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000,
+    0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000,
+    0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000,
+    0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000,
+    0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000,
+    0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000,
+    0x0ba0c79300000000},
+   {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000,
+    0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000,
+    0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000,
+    0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000,
+    0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000,
+    0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000,
+    0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000,
+    0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000,
+    0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000,
+    0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000,
+    0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000,
+    0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000,
+    0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000,
+    0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000,
+    0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000,
+    0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000,
+    0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000,
+    0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000,
+    0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000,
+    0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000,
+    0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000,
+    0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000,
+    0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000,
+    0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000,
+    0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000,
+    0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000,
+    0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000,
+    0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000,
+    0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000,
+    0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000,
+    0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000,
+    0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000,
+    0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000,
+    0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000,
+    0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000,
+    0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000,
+    0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000,
+    0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000,
+    0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000,
+    0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000,
+    0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000,
+    0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000,
+    0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000,
+    0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000,
+    0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000,
+    0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000,
+    0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000,
+    0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000,
+    0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000,
+    0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000,
+    0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000,
+    0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000,
+    0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000,
+    0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000,
+    0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000,
+    0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000,
+    0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000,
+    0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000,
+    0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000,
+    0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000,
+    0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000,
+    0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000,
+    0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000,
+    0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000,
+    0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000,
+    0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000,
+    0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000,
+    0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000,
+    0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000,
+    0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000,
+    0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000,
+    0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000,
+    0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000,
+    0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000,
+    0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000,
+    0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000,
+    0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000,
+    0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000,
+    0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000,
+    0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000,
+    0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000,
+    0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000,
+    0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000,
+    0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000,
+    0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000,
+    0x281e419700000000},
+   {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000,
+    0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000,
+    0x304a428900000000, 0x38a922b500000000, 0x011e763800000000,
+    0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000,
+    0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000,
+    0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000,
+    0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000,
+    0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000,
+    0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000,
+    0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000,
+    0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000,
+    0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000,
+    0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000,
+    0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000,
+    0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000,
+    0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000,
+    0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000,
+    0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000,
+    0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000,
+    0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000,
+    0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000,
+    0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000,
+    0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000,
+    0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000,
+    0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000,
+    0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000,
+    0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000,
+    0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000,
+    0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000,
+    0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000,
+    0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000,
+    0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000,
+    0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000,
+    0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000,
+    0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000,
+    0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000,
+    0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000,
+    0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000,
+    0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000,
+    0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000,
+    0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000,
+    0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000,
+    0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000,
+    0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000,
+    0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000,
+    0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000,
+    0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000,
+    0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000,
+    0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000,
+    0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000,
+    0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000,
+    0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000,
+    0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000,
+    0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000,
+    0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000,
+    0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000,
+    0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000,
+    0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000,
+    0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000,
+    0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000,
+    0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000,
+    0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000,
+    0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000,
+    0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000,
+    0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000,
+    0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000,
+    0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000,
+    0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000,
+    0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000,
+    0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000,
+    0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000,
+    0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000,
+    0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000,
+    0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000,
+    0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000,
+    0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000,
+    0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000,
+    0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000,
+    0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000,
+    0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000,
+    0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000,
+    0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000,
+    0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000,
+    0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000,
+    0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000,
+    0xe4e9223500000000},
+   {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000,
+    0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000,
+    0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000,
+    0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000,
+    0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000,
+    0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000,
+    0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000,
+    0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000,
+    0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000,
+    0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000,
+    0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000,
+    0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000,
+    0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000,
+    0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000,
+    0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000,
+    0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000,
+    0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000,
+    0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000,
+    0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000,
+    0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000,
+    0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000,
+    0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000,
+    0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000,
+    0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000,
+    0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000,
+    0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000,
+    0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000,
+    0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000,
+    0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000,
+    0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000,
+    0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000,
+    0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000,
+    0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000,
+    0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000,
+    0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000,
+    0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000,
+    0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000,
+    0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000,
+    0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000,
+    0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000,
+    0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000,
+    0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000,
+    0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000,
+    0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000,
+    0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000,
+    0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000,
+    0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000,
+    0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000,
+    0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000,
+    0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000,
+    0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000,
+    0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000,
+    0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000,
+    0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000,
+    0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000,
+    0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000,
+    0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000,
+    0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000,
+    0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000,
+    0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000,
+    0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000,
+    0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000,
+    0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000,
+    0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000,
+    0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000,
+    0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000,
+    0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000,
+    0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000,
+    0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000,
+    0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000,
+    0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000,
+    0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000,
+    0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000,
+    0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000,
+    0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000,
+    0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000,
+    0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000,
+    0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000,
+    0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000,
+    0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000,
+    0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000,
+    0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000,
+    0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000,
+    0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000,
+    0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000,
+    0x880452a700000000},
+   {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000,
+    0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000,
+    0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000,
+    0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000,
+    0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000,
+    0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000,
+    0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000,
+    0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000,
+    0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000,
+    0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000,
+    0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000,
+    0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000,
+    0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000,
+    0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000,
+    0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000,
+    0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000,
+    0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000,
+    0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000,
+    0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000,
+    0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000,
+    0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000,
+    0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000,
+    0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000,
+    0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000,
+    0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000,
+    0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000,
+    0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000,
+    0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000,
+    0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000,
+    0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000,
+    0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000,
+    0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000,
+    0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000,
+    0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000,
+    0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000,
+    0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000,
+    0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000,
+    0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000,
+    0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000,
+    0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000,
+    0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000,
+    0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000,
+    0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000,
+    0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000,
+    0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000,
+    0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000,
+    0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000,
+    0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000,
+    0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000,
+    0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000,
+    0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000,
+    0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000,
+    0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000,
+    0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000,
+    0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000,
+    0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000,
+    0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000,
+    0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000,
+    0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000,
+    0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000,
+    0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000,
+    0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000,
+    0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000,
+    0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000,
+    0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000,
+    0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000,
+    0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000,
+    0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000,
+    0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000,
+    0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000,
+    0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000,
+    0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000,
+    0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000,
+    0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000,
+    0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000,
+    0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000,
+    0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000,
+    0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000,
+    0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000,
+    0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000,
+    0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000,
+    0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000,
+    0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000,
+    0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000,
+    0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000,
+    0x1659c4e300000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87,
+    0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede,
+    0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab,
+    0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c,
+    0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1,
+    0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7,
+    0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e,
+    0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308,
+    0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5,
+    0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472,
+    0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07,
+    0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e,
+    0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa,
+    0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec,
+    0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6,
+    0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0,
+    0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3,
+    0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba,
+    0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf,
+    0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975,
+    0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8,
+    0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde,
+    0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a,
+    0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c,
+    0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1,
+    0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65,
+    0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410,
+    0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649,
+    0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a,
+    0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c,
+    0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946,
+    0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450,
+    0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e,
+    0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857,
+    0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022,
+    0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5,
+    0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758,
+    0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e,
+    0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d,
+    0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b,
+    0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6,
+    0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401,
+    0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74,
+    0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d,
+    0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073,
+    0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65,
+    0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f,
+    0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749,
+    0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a,
+    0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033,
+    0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846,
+    0x0d7139d7},
+   {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563,
+    0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f,
+    0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875,
+    0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536,
+    0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8,
+    0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43,
+    0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f,
+    0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184,
+    0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a,
+    0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39,
+    0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523,
+    0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f,
+    0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d,
+    0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6,
+    0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b,
+    0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0,
+    0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151,
+    0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d,
+    0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47,
+    0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a,
+    0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964,
+    0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef,
+    0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d,
+    0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6,
+    0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348,
+    0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53,
+    0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449,
+    0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645,
+    0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4,
+    0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f,
+    0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2,
+    0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69,
+    0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46,
+    0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a,
+    0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650,
+    0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13,
+    0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded,
+    0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366,
+    0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57,
+    0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc,
+    0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222,
+    0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61,
+    0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b,
+    0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277,
+    0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558,
+    0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3,
+    0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e,
+    0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5,
+    0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74,
+    0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78,
+    0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262,
+    0x1c53e98a},
+   {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b,
+    0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40,
+    0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580,
+    0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7,
+    0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a,
+    0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37,
+    0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75,
+    0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218,
+    0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5,
+    0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2,
+    0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02,
+    0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59,
+    0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1,
+    0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c,
+    0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a,
+    0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307,
+    0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486,
+    0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd,
+    0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d,
+    0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2,
+    0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f,
+    0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72,
+    0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8,
+    0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985,
+    0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268,
+    0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94,
+    0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454,
+    0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f,
+    0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e,
+    0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3,
+    0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915,
+    0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778,
+    0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821,
+    0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a,
+    0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba,
+    0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d,
+    0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560,
+    0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d,
+    0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe,
+    0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3,
+    0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e,
+    0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509,
+    0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9,
+    0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92,
+    0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb,
+    0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6,
+    0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50,
+    0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d,
+    0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc,
+    0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7,
+    0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927,
+    0x3f88e851},
+   {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96,
+    0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8,
+    0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0,
+    0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14,
+    0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7,
+    0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4,
+    0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe,
+    0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad,
+    0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e,
+    0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa,
+    0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2,
+    0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c,
+    0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab,
+    0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8,
+    0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d,
+    0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e,
+    0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7,
+    0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99,
+    0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1,
+    0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690,
+    0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933,
+    0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20,
+    0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf,
+    0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc,
+    0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f,
+    0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92,
+    0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca,
+    0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4,
+    0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd,
+    0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de,
+    0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb,
+    0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8,
+    0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474,
+    0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a,
+    0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252,
+    0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6,
+    0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55,
+    0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846,
+    0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7,
+    0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4,
+    0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47,
+    0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3,
+    0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb,
+    0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5,
+    0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49,
+    0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a,
+    0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f,
+    0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c,
+    0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305,
+    0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b,
+    0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523,
+    0x3dee8ca6}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0,
+    0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587,
+    0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa,
+    0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09,
+    0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee,
+    0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3,
+    0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3,
+    0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce,
+    0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429,
+    0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda,
+    0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7,
+    0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0,
+    0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd,
+    0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0,
+    0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287,
+    0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a,
+    0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9,
+    0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e,
+    0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3,
+    0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3,
+    0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054,
+    0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49,
+    0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da,
+    0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7,
+    0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20,
+    0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d,
+    0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00,
+    0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347,
+    0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14,
+    0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209,
+    0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e,
+    0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33,
+    0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3,
+    0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194,
+    0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9,
+    0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a,
+    0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd,
+    0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0,
+    0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d,
+    0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460,
+    0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87,
+    0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674,
+    0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509,
+    0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e,
+    0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae,
+    0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3,
+    0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694,
+    0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989,
+    0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da,
+    0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d,
+    0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0,
+    0xa68cee3d},
+   {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19,
+    0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae,
+    0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb,
+    0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a,
+    0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55,
+    0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1,
+    0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c,
+    0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8,
+    0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7,
+    0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936,
+    0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453,
+    0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4,
+    0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941,
+    0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5,
+    0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93,
+    0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17,
+    0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e,
+    0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89,
+    0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec,
+    0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0,
+    0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf,
+    0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b,
+    0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b,
+    0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f,
+    0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0,
+    0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e,
+    0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b,
+    0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc,
+    0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5,
+    0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261,
+    0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637,
+    0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3,
+    0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57,
+    0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0,
+    0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85,
+    0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454,
+    0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b,
+    0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f,
+    0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423,
+    0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7,
+    0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8,
+    0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739,
+    0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c,
+    0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb,
+    0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f,
+    0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b,
+    0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd,
+    0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59,
+    0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070,
+    0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7,
+    0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2,
+    0x51e8883f},
+   {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a,
+    0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276,
+    0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed,
+    0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55,
+    0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b,
+    0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8,
+    0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320,
+    0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413,
+    0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd,
+    0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75,
+    0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee,
+    0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312,
+    0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca,
+    0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9,
+    0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad,
+    0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e,
+    0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504,
+    0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8,
+    0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63,
+    0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353,
+    0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d,
+    0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be,
+    0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae,
+    0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d,
+    0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943,
+    0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7,
+    0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c,
+    0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390,
+    0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a,
+    0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239,
+    0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d,
+    0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e,
+    0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c,
+    0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0,
+    0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b,
+    0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93,
+    0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d,
+    0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e,
+    0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c,
+    0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f,
+    0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1,
+    0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579,
+    0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2,
+    0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e,
+    0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c,
+    0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f,
+    0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b,
+    0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158,
+    0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2,
+    0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e,
+    0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5,
+    0x8ae9531c},
+   {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4,
+    0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd,
+    0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220,
+    0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf,
+    0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495,
+    0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def,
+    0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90,
+    0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea,
+    0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0,
+    0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f,
+    0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2,
+    0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab,
+    0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e,
+    0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754,
+    0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda,
+    0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0,
+    0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c,
+    0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215,
+    0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8,
+    0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910,
+    0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a,
+    0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30,
+    0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658,
+    0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22,
+    0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478,
+    0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2,
+    0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f,
+    0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606,
+    0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba,
+    0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0,
+    0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e,
+    0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034,
+    0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f,
+    0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996,
+    0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b,
+    0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84,
+    0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de,
+    0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4,
+    0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5,
+    0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f,
+    0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5,
+    0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a,
+    0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7,
+    0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce,
+    0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65,
+    0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f,
+    0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91,
+    0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb,
+    0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57,
+    0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e,
+    0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3,
+    0xd739710d}};
+
+#endif
+
+#endif
+
+#if N == 5
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df,
+    0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8,
+    0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef,
+    0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376,
+    0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201,
+    0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399,
+    0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372,
+    0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea,
+    0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d,
+    0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004,
+    0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353,
+    0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334,
+    0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a,
+    0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2,
+    0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a,
+    0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2,
+    0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b,
+    0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c,
+    0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b,
+    0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f,
+    0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338,
+    0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0,
+    0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6,
+    0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e,
+    0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319,
+    0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3,
+    0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4,
+    0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783,
+    0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a,
+    0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492,
+    0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a,
+    0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2,
+    0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496,
+    0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1,
+    0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6,
+    0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f,
+    0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548,
+    0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0,
+    0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741,
+    0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9,
+    0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae,
+    0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437,
+    0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760,
+    0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707,
+    0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433,
+    0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab,
+    0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703,
+    0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b,
+    0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412,
+    0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475,
+    0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722,
+    0xe9947565},
+   {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5,
+    0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22,
+    0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c,
+    0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed,
+    0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d,
+    0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1,
+    0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e,
+    0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32,
+    0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142,
+    0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93,
+    0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d,
+    0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a,
+    0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58,
+    0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14,
+    0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81,
+    0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd,
+    0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab,
+    0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c,
+    0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72,
+    0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f,
+    0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff,
+    0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3,
+    0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30,
+    0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c,
+    0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c,
+    0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558,
+    0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146,
+    0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581,
+    0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7,
+    0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab,
+    0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e,
+    0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272,
+    0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838,
+    0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff,
+    0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1,
+    0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330,
+    0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840,
+    0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c,
+    0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb,
+    0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7,
+    0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7,
+    0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616,
+    0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208,
+    0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf,
+    0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85,
+    0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9,
+    0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c,
+    0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10,
+    0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76,
+    0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1,
+    0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf,
+    0xf7d05006},
+   {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b,
+    0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774,
+    0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58,
+    0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a,
+    0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb,
+    0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952,
+    0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e,
+    0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7,
+    0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746,
+    0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14,
+    0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338,
+    0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907,
+    0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777,
+    0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de,
+    0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064,
+    0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd,
+    0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951,
+    0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e,
+    0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42,
+    0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b,
+    0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a,
+    0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3,
+    0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904,
+    0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad,
+    0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c,
+    0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d,
+    0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861,
+    0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e,
+    0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2,
+    0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b,
+    0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1,
+    0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78,
+    0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f,
+    0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40,
+    0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c,
+    0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e,
+    0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf,
+    0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166,
+    0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d,
+    0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4,
+    0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805,
+    0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157,
+    0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b,
+    0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644,
+    0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43,
+    0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea,
+    0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850,
+    0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9,
+    0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165,
+    0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a,
+    0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676,
+    0xb2075b94},
+   {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf,
+    0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61,
+    0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be,
+    0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd,
+    0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3,
+    0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063,
+    0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105,
+    0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5,
+    0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb,
+    0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8,
+    0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07,
+    0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9,
+    0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5,
+    0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515,
+    0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4,
+    0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014,
+    0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7,
+    0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269,
+    0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6,
+    0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af,
+    0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1,
+    0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111,
+    0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d,
+    0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad,
+    0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3,
+    0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75,
+    0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa,
+    0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74,
+    0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7,
+    0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477,
+    0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6,
+    0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176,
+    0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af,
+    0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71,
+    0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae,
+    0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd,
+    0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3,
+    0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073,
+    0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0,
+    0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400,
+    0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e,
+    0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d,
+    0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2,
+    0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c,
+    0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5,
+    0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505,
+    0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4,
+    0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004,
+    0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7,
+    0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279,
+    0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6,
+    0xba50bcb9},
+   {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897,
+    0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb,
+    0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2,
+    0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2,
+    0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372,
+    0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70,
+    0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92,
+    0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190,
+    0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40,
+    0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430,
+    0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759,
+    0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75,
+    0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2,
+    0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0,
+    0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7,
+    0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5,
+    0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39,
+    0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215,
+    0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c,
+    0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5,
+    0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625,
+    0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27,
+    0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c,
+    0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e,
+    0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee,
+    0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71,
+    0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18,
+    0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134,
+    0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8,
+    0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba,
+    0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd,
+    0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff,
+    0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a,
+    0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6,
+    0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf,
+    0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf,
+    0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f,
+    0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d,
+    0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d,
+    0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f,
+    0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af,
+    0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df,
+    0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6,
+    0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a,
+    0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef,
+    0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed,
+    0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa,
+    0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8,
+    0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624,
+    0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08,
+    0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861,
+    0x808abcf4},
+   {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2,
+    0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd,
+    0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76,
+    0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52,
+    0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e,
+    0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124,
+    0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147,
+    0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d,
+    0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31,
+    0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15,
+    0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae,
+    0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1,
+    0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d,
+    0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307,
+    0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9,
+    0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3,
+    0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084,
+    0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb,
+    0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850,
+    0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2,
+    0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe,
+    0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94,
+    0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261,
+    0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b,
+    0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917,
+    0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53,
+    0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8,
+    0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787,
+    0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0,
+    0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba,
+    0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404,
+    0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e,
+    0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af,
+    0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0,
+    0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b,
+    0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f,
+    0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543,
+    0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129,
+    0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627,
+    0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d,
+    0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51,
+    0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75,
+    0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce,
+    0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1,
+    0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760,
+    0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a,
+    0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4,
+    0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde,
+    0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089,
+    0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6,
+    0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d,
+    0xefdb3f95},
+   {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8,
+    0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7,
+    0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945,
+    0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9,
+    0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652,
+    0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc,
+    0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a,
+    0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4,
+    0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f,
+    0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3,
+    0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51,
+    0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e,
+    0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c,
+    0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362,
+    0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11,
+    0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff,
+    0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7,
+    0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8,
+    0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a,
+    0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690,
+    0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b,
+    0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5,
+    0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05,
+    0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb,
+    0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740,
+    0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f,
+    0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded,
+    0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2,
+    0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa,
+    0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714,
+    0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67,
+    0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89,
+    0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7,
+    0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8,
+    0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a,
+    0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6,
+    0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d,
+    0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3,
+    0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9,
+    0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57,
+    0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc,
+    0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540,
+    0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2,
+    0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd,
+    0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93,
+    0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d,
+    0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e,
+    0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0,
+    0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8,
+    0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7,
+    0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75,
+    0x0e2fbf43},
+   {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc,
+    0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a,
+    0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3,
+    0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7,
+    0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b,
+    0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154,
+    0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3,
+    0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc,
+    0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330,
+    0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264,
+    0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd,
+    0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b,
+    0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a,
+    0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175,
+    0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275,
+    0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a,
+    0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234,
+    0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2,
+    0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b,
+    0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a,
+    0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6,
+    0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189,
+    0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b,
+    0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204,
+    0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8,
+    0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226,
+    0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff,
+    0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219,
+    0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167,
+    0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258,
+    0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158,
+    0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267,
+    0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c,
+    0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da,
+    0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003,
+    0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157,
+    0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b,
+    0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4,
+    0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179,
+    0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246,
+    0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a,
+    0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de,
+    0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107,
+    0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1,
+    0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba,
+    0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285,
+    0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185,
+    0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba,
+    0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4,
+    0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322,
+    0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb,
+    0xf4377108}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000,
+    0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000,
+    0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000,
+    0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000,
+    0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000,
+    0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000,
+    0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000,
+    0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000,
+    0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000,
+    0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000,
+    0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000,
+    0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000,
+    0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000,
+    0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000,
+    0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000,
+    0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000,
+    0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000,
+    0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000,
+    0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000,
+    0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000,
+    0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000,
+    0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000,
+    0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000,
+    0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000,
+    0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000,
+    0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000,
+    0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000,
+    0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000,
+    0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000,
+    0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000,
+    0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000,
+    0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000,
+    0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000,
+    0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000,
+    0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000,
+    0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000,
+    0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000,
+    0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000,
+    0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000,
+    0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000,
+    0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000,
+    0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000,
+    0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000,
+    0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000,
+    0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000,
+    0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000,
+    0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000,
+    0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000,
+    0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000,
+    0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000,
+    0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000,
+    0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000,
+    0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000,
+    0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000,
+    0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000,
+    0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000,
+    0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000,
+    0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000,
+    0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000,
+    0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000,
+    0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000,
+    0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000,
+    0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000,
+    0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000,
+    0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000,
+    0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000,
+    0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000,
+    0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000,
+    0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000,
+    0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000,
+    0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000,
+    0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000,
+    0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000,
+    0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000,
+    0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000,
+    0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000,
+    0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000,
+    0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000,
+    0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000,
+    0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000,
+    0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000,
+    0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000,
+    0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000,
+    0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000,
+    0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000,
+    0x087137f400000000},
+   {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000,
+    0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000,
+    0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000,
+    0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000,
+    0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000,
+    0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000,
+    0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000,
+    0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000,
+    0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000,
+    0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000,
+    0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000,
+    0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000,
+    0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000,
+    0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000,
+    0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000,
+    0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000,
+    0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000,
+    0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000,
+    0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000,
+    0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000,
+    0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000,
+    0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000,
+    0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000,
+    0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000,
+    0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000,
+    0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000,
+    0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000,
+    0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000,
+    0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000,
+    0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000,
+    0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000,
+    0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000,
+    0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000,
+    0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000,
+    0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000,
+    0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000,
+    0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000,
+    0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000,
+    0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000,
+    0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000,
+    0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000,
+    0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000,
+    0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000,
+    0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000,
+    0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000,
+    0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000,
+    0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000,
+    0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000,
+    0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000,
+    0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000,
+    0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000,
+    0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000,
+    0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000,
+    0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000,
+    0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000,
+    0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000,
+    0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000,
+    0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000,
+    0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000,
+    0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000,
+    0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000,
+    0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000,
+    0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000,
+    0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000,
+    0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000,
+    0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000,
+    0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000,
+    0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000,
+    0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000,
+    0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000,
+    0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000,
+    0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000,
+    0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000,
+    0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000,
+    0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000,
+    0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000,
+    0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000,
+    0x1129fad400000000, 0x621116d400000000, 0x544094f000000000,
+    0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000,
+    0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000,
+    0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000,
+    0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000,
+    0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000,
+    0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000,
+    0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000,
+    0x43bf2f0e00000000},
+   {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000,
+    0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000,
+    0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000,
+    0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000,
+    0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000,
+    0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000,
+    0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000,
+    0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000,
+    0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000,
+    0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000,
+    0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000,
+    0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000,
+    0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000,
+    0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000,
+    0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000,
+    0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000,
+    0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000,
+    0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000,
+    0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000,
+    0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000,
+    0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000,
+    0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000,
+    0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000,
+    0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000,
+    0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000,
+    0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000,
+    0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000,
+    0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000,
+    0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000,
+    0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000,
+    0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000,
+    0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000,
+    0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000,
+    0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000,
+    0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000,
+    0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000,
+    0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000,
+    0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000,
+    0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000,
+    0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000,
+    0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000,
+    0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000,
+    0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000,
+    0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000,
+    0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000,
+    0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000,
+    0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000,
+    0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000,
+    0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000,
+    0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000,
+    0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000,
+    0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000,
+    0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000,
+    0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000,
+    0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000,
+    0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000,
+    0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000,
+    0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000,
+    0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000,
+    0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000,
+    0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000,
+    0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000,
+    0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000,
+    0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000,
+    0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000,
+    0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000,
+    0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000,
+    0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000,
+    0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000,
+    0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000,
+    0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000,
+    0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000,
+    0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000,
+    0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000,
+    0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000,
+    0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000,
+    0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000,
+    0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000,
+    0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000,
+    0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000,
+    0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000,
+    0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000,
+    0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000,
+    0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000,
+    0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000,
+    0x953fdbef00000000},
+   {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000,
+    0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000,
+    0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000,
+    0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000,
+    0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000,
+    0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000,
+    0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000,
+    0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000,
+    0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000,
+    0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000,
+    0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000,
+    0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000,
+    0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000,
+    0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000,
+    0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000,
+    0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000,
+    0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000,
+    0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000,
+    0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000,
+    0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000,
+    0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000,
+    0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000,
+    0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000,
+    0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000,
+    0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000,
+    0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000,
+    0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000,
+    0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000,
+    0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000,
+    0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000,
+    0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000,
+    0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000,
+    0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000,
+    0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000,
+    0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000,
+    0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000,
+    0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000,
+    0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000,
+    0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000,
+    0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000,
+    0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000,
+    0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000,
+    0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000,
+    0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000,
+    0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000,
+    0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000,
+    0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000,
+    0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000,
+    0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000,
+    0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000,
+    0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000,
+    0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000,
+    0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000,
+    0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000,
+    0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000,
+    0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000,
+    0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000,
+    0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000,
+    0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000,
+    0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000,
+    0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000,
+    0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000,
+    0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000,
+    0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000,
+    0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000,
+    0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000,
+    0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000,
+    0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000,
+    0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000,
+    0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000,
+    0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000,
+    0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000,
+    0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000,
+    0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000,
+    0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000,
+    0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000,
+    0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000,
+    0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000,
+    0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000,
+    0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000,
+    0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000,
+    0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000,
+    0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000,
+    0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000,
+    0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000,
+    0xf4bc8a8000000000},
+   {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000,
+    0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000,
+    0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000,
+    0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000,
+    0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000,
+    0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000,
+    0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000,
+    0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000,
+    0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000,
+    0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000,
+    0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000,
+    0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000,
+    0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000,
+    0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000,
+    0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000,
+    0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000,
+    0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000,
+    0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000,
+    0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000,
+    0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000,
+    0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000,
+    0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000,
+    0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000,
+    0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000,
+    0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000,
+    0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000,
+    0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000,
+    0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000,
+    0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000,
+    0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000,
+    0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000,
+    0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000,
+    0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000,
+    0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000,
+    0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000,
+    0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000,
+    0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000,
+    0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000,
+    0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000,
+    0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000,
+    0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000,
+    0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000,
+    0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000,
+    0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000,
+    0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000,
+    0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000,
+    0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000,
+    0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000,
+    0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000,
+    0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000,
+    0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000,
+    0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000,
+    0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000,
+    0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000,
+    0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000,
+    0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000,
+    0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000,
+    0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000,
+    0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000,
+    0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000,
+    0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000,
+    0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000,
+    0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000,
+    0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000,
+    0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000,
+    0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000,
+    0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000,
+    0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000,
+    0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000,
+    0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000,
+    0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000,
+    0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000,
+    0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000,
+    0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000,
+    0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000,
+    0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000,
+    0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000,
+    0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000,
+    0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000,
+    0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000,
+    0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000,
+    0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000,
+    0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000,
+    0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000,
+    0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000,
+    0xb9bc50ba00000000},
+   {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000,
+    0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000,
+    0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000,
+    0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000,
+    0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000,
+    0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000,
+    0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000,
+    0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000,
+    0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000,
+    0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000,
+    0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000,
+    0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000,
+    0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000,
+    0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000,
+    0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000,
+    0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000,
+    0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000,
+    0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000,
+    0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000,
+    0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000,
+    0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000,
+    0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000,
+    0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000,
+    0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000,
+    0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000,
+    0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000,
+    0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000,
+    0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000,
+    0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000,
+    0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000,
+    0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000,
+    0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000,
+    0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000,
+    0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000,
+    0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000,
+    0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000,
+    0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000,
+    0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000,
+    0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000,
+    0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000,
+    0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000,
+    0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000,
+    0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000,
+    0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000,
+    0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000,
+    0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000,
+    0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000,
+    0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000,
+    0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000,
+    0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000,
+    0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000,
+    0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000,
+    0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000,
+    0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000,
+    0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000,
+    0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000,
+    0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000,
+    0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000,
+    0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000,
+    0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000,
+    0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000,
+    0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000,
+    0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000,
+    0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000,
+    0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000,
+    0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000,
+    0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000,
+    0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000,
+    0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000,
+    0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000,
+    0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000,
+    0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000,
+    0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000,
+    0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000,
+    0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000,
+    0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000,
+    0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000,
+    0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000,
+    0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000,
+    0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000,
+    0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000,
+    0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000,
+    0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000,
+    0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000,
+    0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000,
+    0x945b07b200000000},
+   {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000,
+    0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000,
+    0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000,
+    0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000,
+    0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000,
+    0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000,
+    0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000,
+    0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000,
+    0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000,
+    0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000,
+    0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000,
+    0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000,
+    0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000,
+    0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000,
+    0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000,
+    0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000,
+    0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000,
+    0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000,
+    0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000,
+    0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000,
+    0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000,
+    0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000,
+    0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000,
+    0x149f066100000000, 0xef839db200000000, 0x468814fc00000000,
+    0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000,
+    0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000,
+    0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000,
+    0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000,
+    0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000,
+    0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000,
+    0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000,
+    0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000,
+    0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000,
+    0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000,
+    0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000,
+    0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000,
+    0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000,
+    0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000,
+    0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000,
+    0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000,
+    0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000,
+    0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000,
+    0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000,
+    0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000,
+    0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000,
+    0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000,
+    0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000,
+    0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000,
+    0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000,
+    0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000,
+    0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000,
+    0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000,
+    0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000,
+    0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000,
+    0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000,
+    0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000,
+    0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000,
+    0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000,
+    0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000,
+    0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000,
+    0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000,
+    0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000,
+    0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000,
+    0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000,
+    0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000,
+    0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000,
+    0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000,
+    0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000,
+    0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000,
+    0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000,
+    0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000,
+    0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000,
+    0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000,
+    0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000,
+    0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000,
+    0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000,
+    0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000,
+    0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000,
+    0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000,
+    0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000,
+    0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000,
+    0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000,
+    0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000,
+    0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000,
+    0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000,
+    0x0650d0f700000000},
+   {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000,
+    0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000,
+    0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000,
+    0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000,
+    0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000,
+    0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000,
+    0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000,
+    0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000,
+    0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000,
+    0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000,
+    0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000,
+    0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000,
+    0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000,
+    0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000,
+    0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000,
+    0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000,
+    0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000,
+    0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000,
+    0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000,
+    0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000,
+    0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000,
+    0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000,
+    0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000,
+    0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000,
+    0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000,
+    0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000,
+    0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000,
+    0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000,
+    0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000,
+    0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000,
+    0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000,
+    0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000,
+    0xc702c15700000000, 0x809085f800000000, 0x082039d200000000,
+    0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000,
+    0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000,
+    0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000,
+    0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000,
+    0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000,
+    0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000,
+    0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000,
+    0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000,
+    0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000,
+    0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000,
+    0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000,
+    0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000,
+    0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000,
+    0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000,
+    0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000,
+    0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000,
+    0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000,
+    0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000,
+    0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000,
+    0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000,
+    0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000,
+    0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000,
+    0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000,
+    0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000,
+    0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000,
+    0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000,
+    0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000,
+    0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000,
+    0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000,
+    0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000,
+    0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000,
+    0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000,
+    0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000,
+    0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000,
+    0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000,
+    0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000,
+    0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000,
+    0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000,
+    0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000,
+    0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000,
+    0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000,
+    0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000,
+    0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000,
+    0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000,
+    0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000,
+    0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000,
+    0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000,
+    0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000,
+    0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000,
+    0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000,
+    0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000,
+    0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000,
+    0x657594e900000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59,
+    0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4,
+    0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67,
+    0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef,
+    0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97,
+    0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88,
+    0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687,
+    0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698,
+    0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0,
+    0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068,
+    0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb,
+    0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056,
+    0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016,
+    0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009,
+    0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028,
+    0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037,
+    0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a,
+    0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7,
+    0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054,
+    0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7,
+    0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af,
+    0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0,
+    0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4,
+    0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab,
+    0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3,
+    0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a,
+    0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9,
+    0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54,
+    0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09,
+    0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16,
+    0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37,
+    0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28,
+    0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e,
+    0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3,
+    0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40,
+    0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8,
+    0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0,
+    0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf,
+    0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6,
+    0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9,
+    0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1,
+    0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059,
+    0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca,
+    0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067,
+    0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031,
+    0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e,
+    0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f,
+    0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010,
+    0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d,
+    0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0,
+    0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073,
+    0xd8ac6b35},
+   {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2,
+    0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd,
+    0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696,
+    0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3,
+    0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f,
+    0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35,
+    0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5,
+    0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f,
+    0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673,
+    0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46,
+    0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d,
+    0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632,
+    0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28,
+    0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192,
+    0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c,
+    0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6,
+    0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0,
+    0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff,
+    0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4,
+    0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95,
+    0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9,
+    0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03,
+    0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7,
+    0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d,
+    0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151,
+    0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808,
+    0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343,
+    0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c,
+    0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a,
+    0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0,
+    0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e,
+    0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594,
+    0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6,
+    0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399,
+    0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2,
+    0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7,
+    0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb,
+    0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571,
+    0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289,
+    0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33,
+    0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f,
+    0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a,
+    0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461,
+    0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e,
+    0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c,
+    0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6,
+    0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918,
+    0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2,
+    0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484,
+    0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb,
+    0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0,
+    0xa140efa8},
+   {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706,
+    0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed,
+    0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289,
+    0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a,
+    0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214,
+    0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3,
+    0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3,
+    0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254,
+    0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a,
+    0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9,
+    0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad,
+    0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746,
+    0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060,
+    0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187,
+    0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef,
+    0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408,
+    0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e,
+    0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495,
+    0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1,
+    0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532,
+    0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c,
+    0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb,
+    0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb,
+    0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c,
+    0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42,
+    0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060,
+    0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04,
+    0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef,
+    0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99,
+    0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e,
+    0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16,
+    0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1,
+    0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7,
+    0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c,
+    0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38,
+    0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb,
+    0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5,
+    0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42,
+    0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62,
+    0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85,
+    0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb,
+    0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18,
+    0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c,
+    0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997,
+    0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1,
+    0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36,
+    0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e,
+    0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9,
+    0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf,
+    0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24,
+    0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040,
+    0x917cd6a1},
+   {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf,
+    0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd,
+    0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896,
+    0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9,
+    0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3,
+    0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f,
+    0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d,
+    0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1,
+    0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab,
+    0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4,
+    0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f,
+    0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d,
+    0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4,
+    0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978,
+    0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad,
+    0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621,
+    0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46,
+    0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854,
+    0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f,
+    0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a,
+    0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890,
+    0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c,
+    0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4,
+    0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238,
+    0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622,
+    0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab,
+    0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0,
+    0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2,
+    0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295,
+    0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19,
+    0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc,
+    0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140,
+    0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd,
+    0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf,
+    0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184,
+    0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb,
+    0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1,
+    0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d,
+    0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb,
+    0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257,
+    0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d,
+    0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22,
+    0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069,
+    0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b,
+    0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6,
+    0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a,
+    0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf,
+    0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33,
+    0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254,
+    0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146,
+    0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d,
+    0x18ba364e}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873,
+    0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661,
+    0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441,
+    0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44,
+    0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1,
+    0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05,
+    0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa,
+    0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e,
+    0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb,
+    0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be,
+    0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e,
+    0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c,
+    0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d,
+    0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9,
+    0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f,
+    0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b,
+    0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39,
+    0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b,
+    0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b,
+    0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20,
+    0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595,
+    0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61,
+    0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0,
+    0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644,
+    0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1,
+    0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d,
+    0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d,
+    0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f,
+    0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad,
+    0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359,
+    0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f,
+    0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b,
+    0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7,
+    0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5,
+    0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5,
+    0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0,
+    0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65,
+    0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091,
+    0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633,
+    0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7,
+    0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272,
+    0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77,
+    0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57,
+    0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145,
+    0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9,
+    0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d,
+    0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb,
+    0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f,
+    0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad,
+    0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf,
+    0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f,
+    0x4e36ba18},
+   {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b,
+    0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8,
+    0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19,
+    0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4,
+    0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239,
+    0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd,
+    0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258,
+    0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc,
+    0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41,
+    0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c,
+    0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d,
+    0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e,
+    0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba,
+    0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e,
+    0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8,
+    0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c,
+    0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f,
+    0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c,
+    0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d,
+    0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d,
+    0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0,
+    0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014,
+    0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc,
+    0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628,
+    0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5,
+    0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941,
+    0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0,
+    0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53,
+    0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880,
+    0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264,
+    0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92,
+    0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776,
+    0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8,
+    0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b,
+    0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea,
+    0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837,
+    0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca,
+    0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e,
+    0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211,
+    0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5,
+    0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08,
+    0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5,
+    0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934,
+    0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7,
+    0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049,
+    0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad,
+    0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b,
+    0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf,
+    0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c,
+    0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f,
+    0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e,
+    0xa1d67c91},
+   {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9,
+    0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de,
+    0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94,
+    0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0,
+    0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a,
+    0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924,
+    0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052,
+    0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c,
+    0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6,
+    0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2,
+    0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8,
+    0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f,
+    0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d,
+    0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273,
+    0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30,
+    0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e,
+    0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7,
+    0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980,
+    0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca,
+    0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8,
+    0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62,
+    0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c,
+    0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c,
+    0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032,
+    0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798,
+    0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d,
+    0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07,
+    0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630,
+    0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389,
+    0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7,
+    0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4,
+    0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca,
+    0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55,
+    0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662,
+    0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828,
+    0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c,
+    0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6,
+    0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98,
+    0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3,
+    0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d,
+    0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037,
+    0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913,
+    0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759,
+    0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e,
+    0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1,
+    0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf,
+    0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c,
+    0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2,
+    0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b,
+    0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c,
+    0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276,
+    0xa8ef40a1},
+   {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e,
+    0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8,
+    0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819,
+    0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f,
+    0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d,
+    0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756,
+    0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0,
+    0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb,
+    0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9,
+    0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f,
+    0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e,
+    0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8,
+    0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835,
+    0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e,
+    0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62,
+    0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749,
+    0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b,
+    0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d,
+    0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc,
+    0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80,
+    0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2,
+    0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599,
+    0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05,
+    0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e,
+    0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c,
+    0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e,
+    0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef,
+    0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359,
+    0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b,
+    0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0,
+    0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc,
+    0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7,
+    0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f,
+    0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189,
+    0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568,
+    0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e,
+    0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c,
+    0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27,
+    0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794,
+    0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf,
+    0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d,
+    0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db,
+    0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a,
+    0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c,
+    0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544,
+    0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f,
+    0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013,
+    0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38,
+    0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea,
+    0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c,
+    0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd,
+    0x356bacd8}};
+
+#endif
+
+#endif
+
+#if N == 6
+
+#if W == 8
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370,
+    0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d,
+    0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69,
+    0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426,
+    0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3,
+    0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f,
+    0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c,
+    0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490,
+    0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155,
+    0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a,
+    0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e,
+    0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603,
+    0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349,
+    0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5,
+    0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50,
+    0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc,
+    0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b,
+    0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76,
+    0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862,
+    0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9,
+    0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c,
+    0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0,
+    0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937,
+    0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b,
+    0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e,
+    0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e,
+    0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a,
+    0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357,
+    0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0,
+    0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c,
+    0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9,
+    0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165,
+    0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766,
+    0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b,
+    0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f,
+    0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030,
+    0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5,
+    0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59,
+    0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63,
+    0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf,
+    0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a,
+    0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845,
+    0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51,
+    0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c,
+    0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f,
+    0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3,
+    0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46,
+    0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea,
+    0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d,
+    0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60,
+    0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74,
+    0x8568a0a8},
+   {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5,
+    0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf,
+    0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5,
+    0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba,
+    0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf,
+    0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f,
+    0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0,
+    0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450,
+    0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55,
+    0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a,
+    0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620,
+    0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a,
+    0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454,
+    0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4,
+    0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534,
+    0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584,
+    0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694,
+    0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e,
+    0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4,
+    0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1,
+    0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4,
+    0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164,
+    0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1,
+    0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911,
+    0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314,
+    0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c,
+    0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6,
+    0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec,
+    0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc,
+    0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c,
+    0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c,
+    0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c,
+    0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716,
+    0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c,
+    0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676,
+    0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879,
+    0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c,
+    0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc,
+    0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77,
+    0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7,
+    0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2,
+    0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd,
+    0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7,
+    0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad,
+    0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897,
+    0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827,
+    0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7,
+    0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947,
+    0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57,
+    0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d,
+    0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37,
+    0x0d907052},
+   {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d,
+    0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89,
+    0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31,
+    0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81,
+    0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e,
+    0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0,
+    0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f,
+    0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291,
+    0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e,
+    0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e,
+    0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936,
+    0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2,
+    0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13,
+    0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d,
+    0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f,
+    0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1,
+    0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a,
+    0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae,
+    0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516,
+    0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f,
+    0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20,
+    0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe,
+    0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28,
+    0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6,
+    0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419,
+    0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5,
+    0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d,
+    0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889,
+    0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412,
+    0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c,
+    0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e,
+    0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0,
+    0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02,
+    0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986,
+    0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e,
+    0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e,
+    0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221,
+    0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf,
+    0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913,
+    0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d,
+    0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622,
+    0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592,
+    0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a,
+    0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae,
+    0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c,
+    0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82,
+    0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20,
+    0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe,
+    0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025,
+    0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1,
+    0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719,
+    0xfd1a6c8a},
+   {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3,
+    0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb,
+    0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d,
+    0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb,
+    0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9,
+    0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156,
+    0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045,
+    0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa,
+    0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8,
+    0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e,
+    0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8,
+    0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0,
+    0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38,
+    0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87,
+    0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46,
+    0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9,
+    0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585,
+    0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d,
+    0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb,
+    0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531,
+    0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03,
+    0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc,
+    0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33,
+    0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c,
+    0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be,
+    0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d,
+    0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b,
+    0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303,
+    0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f,
+    0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0,
+    0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801,
+    0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe,
+    0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e,
+    0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346,
+    0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620,
+    0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776,
+    0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844,
+    0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb,
+    0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0,
+    0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f,
+    0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d,
+    0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b,
+    0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d,
+    0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75,
+    0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795,
+    0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a,
+    0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb,
+    0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354,
+    0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28,
+    0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30,
+    0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856,
+    0x7895f01a},
+   {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188,
+    0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33,
+    0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d,
+    0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445,
+    0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2,
+    0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058,
+    0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43,
+    0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9,
+    0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e,
+    0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06,
+    0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228,
+    0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93,
+    0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e,
+    0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4,
+    0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b,
+    0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371,
+    0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265,
+    0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede,
+    0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0,
+    0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f,
+    0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8,
+    0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32,
+    0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae,
+    0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544,
+    0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3,
+    0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f,
+    0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911,
+    0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa,
+    0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be,
+    0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54,
+    0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b,
+    0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1,
+    0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652,
+    0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9,
+    0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7,
+    0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f,
+    0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68,
+    0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782,
+    0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797,
+    0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d,
+    0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a,
+    0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2,
+    0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc,
+    0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647,
+    0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4,
+    0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e,
+    0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41,
+    0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab,
+    0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf,
+    0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904,
+    0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a,
+    0x9239b848},
+   {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad,
+    0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0,
+    0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40,
+    0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b,
+    0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d,
+    0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b,
+    0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb,
+    0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d,
+    0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b,
+    0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0,
+    0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840,
+    0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d,
+    0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b,
+    0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d,
+    0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6,
+    0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0,
+    0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580,
+    0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd,
+    0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d,
+    0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b,
+    0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d,
+    0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b,
+    0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6,
+    0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0,
+    0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6,
+    0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c,
+    0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c,
+    0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461,
+    0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841,
+    0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317,
+    0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac,
+    0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa,
+    0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7,
+    0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba,
+    0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a,
+    0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161,
+    0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777,
+    0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21,
+    0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a,
+    0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc,
+    0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da,
+    0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1,
+    0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01,
+    0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c,
+    0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241,
+    0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917,
+    0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac,
+    0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa,
+    0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da,
+    0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397,
+    0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537,
+    0xeb36d3cc},
+   {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b,
+    0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059,
+    0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251,
+    0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d,
+    0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9,
+    0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c,
+    0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41,
+    0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4,
+    0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10,
+    0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c,
+    0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54,
+    0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476,
+    0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8,
+    0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d,
+    0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92,
+    0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307,
+    0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad,
+    0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f,
+    0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87,
+    0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17,
+    0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3,
+    0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46,
+    0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197,
+    0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02,
+    0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6,
+    0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e,
+    0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96,
+    0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4,
+    0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e,
+    0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b,
+    0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934,
+    0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1,
+    0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7,
+    0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5,
+    0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd,
+    0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1,
+    0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475,
+    0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0,
+    0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155,
+    0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0,
+    0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304,
+    0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348,
+    0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140,
+    0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862,
+    0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14,
+    0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181,
+    0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e,
+    0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab,
+    0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01,
+    0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523,
+    0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b,
+    0x38e5f3c5},
+   {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06,
+    0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad,
+    0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509,
+    0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba,
+    0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414,
+    0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3,
+    0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733,
+    0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994,
+    0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a,
+    0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889,
+    0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d,
+    0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386,
+    0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621,
+    0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886,
+    0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e,
+    0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389,
+    0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f,
+    0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294,
+    0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30,
+    0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3,
+    0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d,
+    0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba,
+    0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a,
+    0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad,
+    0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03,
+    0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2,
+    0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306,
+    0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad,
+    0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b,
+    0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc,
+    0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914,
+    0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3,
+    0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435,
+    0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e,
+    0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a,
+    0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589,
+    0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27,
+    0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080,
+    0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21,
+    0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586,
+    0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28,
+    0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b,
+    0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f,
+    0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94,
+    0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12,
+    0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5,
+    0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d,
+    0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba,
+    0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c,
+    0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7,
+    0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103,
+    0x3d3101a2}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000,
+    0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000,
+    0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000,
+    0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000,
+    0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000,
+    0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000,
+    0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000,
+    0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000,
+    0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000,
+    0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000,
+    0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000,
+    0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000,
+    0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000,
+    0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000,
+    0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000,
+    0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000,
+    0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000,
+    0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000,
+    0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000,
+    0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000,
+    0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000,
+    0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000,
+    0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000,
+    0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000,
+    0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000,
+    0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000,
+    0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000,
+    0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000,
+    0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000,
+    0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000,
+    0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000,
+    0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000,
+    0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000,
+    0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000,
+    0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000,
+    0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000,
+    0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000,
+    0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000,
+    0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000,
+    0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000,
+    0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000,
+    0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000,
+    0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000,
+    0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000,
+    0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000,
+    0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000,
+    0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000,
+    0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000,
+    0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000,
+    0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000,
+    0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000,
+    0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000,
+    0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000,
+    0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000,
+    0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000,
+    0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000,
+    0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000,
+    0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000,
+    0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000,
+    0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000,
+    0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000,
+    0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000,
+    0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000,
+    0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000,
+    0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000,
+    0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000,
+    0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000,
+    0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000,
+    0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000,
+    0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000,
+    0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000,
+    0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000,
+    0x3688267d00000000, 0x9718319500000000, 0x35af787600000000,
+    0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000,
+    0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000,
+    0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000,
+    0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000,
+    0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000,
+    0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000,
+    0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000,
+    0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000,
+    0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000,
+    0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000,
+    0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000,
+    0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000,
+    0xa201313d00000000},
+   {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000,
+    0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000,
+    0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000,
+    0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000,
+    0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000,
+    0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000,
+    0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000,
+    0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000,
+    0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000,
+    0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000,
+    0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000,
+    0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000,
+    0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000,
+    0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000,
+    0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000,
+    0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000,
+    0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000,
+    0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000,
+    0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000,
+    0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000,
+    0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000,
+    0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000,
+    0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000,
+    0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000,
+    0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000,
+    0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000,
+    0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000,
+    0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000,
+    0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000,
+    0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000,
+    0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000,
+    0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000,
+    0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000,
+    0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000,
+    0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000,
+    0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000,
+    0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000,
+    0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000,
+    0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000,
+    0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000,
+    0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000,
+    0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000,
+    0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000,
+    0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000,
+    0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000,
+    0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000,
+    0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000,
+    0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000,
+    0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000,
+    0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000,
+    0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000,
+    0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000,
+    0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000,
+    0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000,
+    0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000,
+    0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000,
+    0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000,
+    0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000,
+    0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000,
+    0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000,
+    0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000,
+    0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000,
+    0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000,
+    0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000,
+    0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000,
+    0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000,
+    0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000,
+    0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000,
+    0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000,
+    0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000,
+    0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000,
+    0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000,
+    0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000,
+    0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000,
+    0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000,
+    0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000,
+    0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000,
+    0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000,
+    0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000,
+    0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000,
+    0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000,
+    0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000,
+    0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000,
+    0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000,
+    0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000,
+    0xc5f3e53800000000},
+   {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000,
+    0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000,
+    0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000,
+    0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000,
+    0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000,
+    0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000,
+    0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000,
+    0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000,
+    0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000,
+    0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000,
+    0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000,
+    0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000,
+    0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000,
+    0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000,
+    0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000,
+    0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000,
+    0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000,
+    0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000,
+    0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000,
+    0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000,
+    0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000,
+    0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000,
+    0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000,
+    0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000,
+    0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000,
+    0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000,
+    0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000,
+    0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000,
+    0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000,
+    0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000,
+    0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000,
+    0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000,
+    0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000,
+    0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000,
+    0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000,
+    0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000,
+    0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000,
+    0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000,
+    0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000,
+    0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000,
+    0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000,
+    0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000,
+    0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000,
+    0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000,
+    0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000,
+    0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000,
+    0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000,
+    0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000,
+    0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000,
+    0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000,
+    0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000,
+    0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000,
+    0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000,
+    0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000,
+    0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000,
+    0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000,
+    0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000,
+    0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000,
+    0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000,
+    0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000,
+    0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000,
+    0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000,
+    0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000,
+    0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000,
+    0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000,
+    0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000,
+    0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000,
+    0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000,
+    0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000,
+    0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000,
+    0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000,
+    0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000,
+    0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000,
+    0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000,
+    0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000,
+    0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000,
+    0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000,
+    0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000,
+    0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000,
+    0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000,
+    0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000,
+    0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000,
+    0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000,
+    0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000,
+    0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000,
+    0xccd336eb00000000},
+   {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000,
+    0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000,
+    0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000,
+    0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000,
+    0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000,
+    0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000,
+    0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000,
+    0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000,
+    0xb249204500000000, 0xd071086f00000000, 0x7639701100000000,
+    0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000,
+    0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000,
+    0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000,
+    0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000,
+    0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000,
+    0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000,
+    0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000,
+    0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000,
+    0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000,
+    0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000,
+    0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000,
+    0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000,
+    0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000,
+    0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000,
+    0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000,
+    0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000,
+    0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000,
+    0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000,
+    0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000,
+    0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000,
+    0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000,
+    0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000,
+    0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000,
+    0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000,
+    0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000,
+    0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000,
+    0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000,
+    0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000,
+    0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000,
+    0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000,
+    0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000,
+    0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000,
+    0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000,
+    0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000,
+    0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000,
+    0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000,
+    0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000,
+    0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000,
+    0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000,
+    0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000,
+    0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000,
+    0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000,
+    0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000,
+    0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000,
+    0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000,
+    0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000,
+    0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000,
+    0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000,
+    0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000,
+    0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000,
+    0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000,
+    0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000,
+    0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000,
+    0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000,
+    0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000,
+    0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000,
+    0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000,
+    0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000,
+    0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000,
+    0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000,
+    0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000,
+    0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000,
+    0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000,
+    0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000,
+    0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000,
+    0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000,
+    0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000,
+    0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000,
+    0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000,
+    0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000,
+    0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000,
+    0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000,
+    0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000,
+    0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000,
+    0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000,
+    0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000,
+    0x48b8399200000000},
+   {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000,
+    0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000,
+    0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000,
+    0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000,
+    0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000,
+    0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000,
+    0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000,
+    0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000,
+    0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000,
+    0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000,
+    0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000,
+    0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000,
+    0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000,
+    0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000,
+    0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000,
+    0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000,
+    0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000,
+    0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000,
+    0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000,
+    0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000,
+    0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000,
+    0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000,
+    0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000,
+    0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000,
+    0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000,
+    0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000,
+    0xb521428400000000, 0xf909d42700000000, 0x762efede00000000,
+    0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000,
+    0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000,
+    0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000,
+    0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000,
+    0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000,
+    0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000,
+    0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000,
+    0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000,
+    0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000,
+    0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000,
+    0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000,
+    0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000,
+    0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000,
+    0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000,
+    0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000,
+    0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000,
+    0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000,
+    0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000,
+    0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000,
+    0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000,
+    0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000,
+    0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000,
+    0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000,
+    0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000,
+    0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000,
+    0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000,
+    0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000,
+    0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000,
+    0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000,
+    0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000,
+    0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000,
+    0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000,
+    0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000,
+    0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000,
+    0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000,
+    0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000,
+    0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000,
+    0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000,
+    0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000,
+    0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000,
+    0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000,
+    0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000,
+    0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000,
+    0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000,
+    0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000,
+    0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000,
+    0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000,
+    0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000,
+    0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000,
+    0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000,
+    0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000,
+    0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000,
+    0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000,
+    0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000,
+    0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000,
+    0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000,
+    0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000,
+    0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000,
+    0x1af0957800000000},
+   {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000,
+    0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000,
+    0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000,
+    0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000,
+    0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000,
+    0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000,
+    0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000,
+    0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000,
+    0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000,
+    0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000,
+    0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000,
+    0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000,
+    0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000,
+    0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000,
+    0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000,
+    0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000,
+    0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000,
+    0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000,
+    0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000,
+    0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000,
+    0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000,
+    0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000,
+    0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000,
+    0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000,
+    0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000,
+    0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000,
+    0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000,
+    0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000,
+    0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000,
+    0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000,
+    0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000,
+    0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000,
+    0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000,
+    0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000,
+    0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000,
+    0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000,
+    0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000,
+    0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000,
+    0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000,
+    0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000,
+    0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000,
+    0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000,
+    0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000,
+    0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000,
+    0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000,
+    0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000,
+    0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000,
+    0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000,
+    0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000,
+    0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000,
+    0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000,
+    0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000,
+    0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000,
+    0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000,
+    0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000,
+    0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000,
+    0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000,
+    0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000,
+    0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000,
+    0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000,
+    0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000,
+    0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000,
+    0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000,
+    0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000,
+    0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000,
+    0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000,
+    0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000,
+    0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000,
+    0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000,
+    0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000,
+    0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000,
+    0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000,
+    0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000,
+    0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000,
+    0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000,
+    0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000,
+    0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000,
+    0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000,
+    0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000,
+    0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000,
+    0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000,
+    0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000,
+    0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000,
+    0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000,
+    0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000,
+    0x8a6c1afd00000000},
+   {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000,
+    0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000,
+    0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000,
+    0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000,
+    0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000,
+    0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000,
+    0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000,
+    0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000,
+    0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000,
+    0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000,
+    0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000,
+    0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000,
+    0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000,
+    0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000,
+    0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000,
+    0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000,
+    0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000,
+    0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000,
+    0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000,
+    0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000,
+    0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000,
+    0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000,
+    0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000,
+    0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000,
+    0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000,
+    0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000,
+    0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000,
+    0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000,
+    0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000,
+    0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000,
+    0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000,
+    0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000,
+    0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000,
+    0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000,
+    0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000,
+    0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000,
+    0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000,
+    0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000,
+    0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000,
+    0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000,
+    0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000,
+    0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000,
+    0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000,
+    0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000,
+    0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000,
+    0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000,
+    0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000,
+    0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000,
+    0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000,
+    0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000,
+    0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000,
+    0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000,
+    0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000,
+    0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000,
+    0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000,
+    0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000,
+    0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000,
+    0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000,
+    0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000,
+    0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000,
+    0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000,
+    0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000,
+    0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000,
+    0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000,
+    0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000,
+    0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000,
+    0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000,
+    0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000,
+    0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000,
+    0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000,
+    0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000,
+    0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000,
+    0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000,
+    0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000,
+    0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000,
+    0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000,
+    0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000,
+    0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000,
+    0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000,
+    0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000,
+    0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000,
+    0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000,
+    0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000,
+    0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000,
+    0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000,
+    0x5270900d00000000},
+   {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000,
+    0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000,
+    0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000,
+    0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000,
+    0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000,
+    0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000,
+    0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000,
+    0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000,
+    0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000,
+    0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000,
+    0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000,
+    0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000,
+    0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000,
+    0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000,
+    0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000,
+    0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000,
+    0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000,
+    0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000,
+    0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000,
+    0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000,
+    0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000,
+    0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000,
+    0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000,
+    0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000,
+    0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000,
+    0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000,
+    0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000,
+    0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000,
+    0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000,
+    0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000,
+    0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000,
+    0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000,
+    0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000,
+    0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000,
+    0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000,
+    0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000,
+    0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000,
+    0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000,
+    0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000,
+    0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000,
+    0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000,
+    0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000,
+    0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000,
+    0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000,
+    0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000,
+    0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000,
+    0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000,
+    0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000,
+    0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000,
+    0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000,
+    0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000,
+    0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000,
+    0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000,
+    0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000,
+    0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000,
+    0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000,
+    0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000,
+    0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000,
+    0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000,
+    0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000,
+    0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000,
+    0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000,
+    0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000,
+    0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000,
+    0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000,
+    0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000,
+    0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000,
+    0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000,
+    0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000,
+    0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000,
+    0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000,
+    0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000,
+    0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000,
+    0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000,
+    0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000,
+    0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000,
+    0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000,
+    0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000,
+    0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000,
+    0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000,
+    0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000,
+    0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000,
+    0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000,
+    0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000,
+    0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000,
+    0xa8a0688500000000}};
+
+#else /* W == 4 */
+
+local const z_crc_t FAR crc_braid_table[][256] = {
+   {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f,
+    0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999,
+    0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee,
+    0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615,
+    0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383,
+    0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb,
+    0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275,
+    0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d,
+    0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b,
+    0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460,
+    0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317,
+    0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1,
+    0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5,
+    0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd,
+    0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04,
+    0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c,
+    0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7,
+    0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11,
+    0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66,
+    0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7,
+    0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871,
+    0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309,
+    0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd,
+    0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85,
+    0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913,
+    0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d,
+    0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a,
+    0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc,
+    0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57,
+    0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f,
+    0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6,
+    0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e,
+    0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f,
+    0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289,
+    0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe,
+    0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05,
+    0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893,
+    0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb,
+    0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0,
+    0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8,
+    0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e,
+    0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5,
+    0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2,
+    0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574,
+    0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5,
+    0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add,
+    0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114,
+    0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c,
+    0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7,
+    0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701,
+    0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076,
+    0x09cd8551},
+   {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193,
+    0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2,
+    0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c,
+    0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71,
+    0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a,
+    0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d,
+    0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71,
+    0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436,
+    0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d,
+    0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000,
+    0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae,
+    0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf,
+    0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930,
+    0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277,
+    0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff,
+    0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8,
+    0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef,
+    0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e,
+    0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20,
+    0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95,
+    0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e,
+    0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9,
+    0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d,
+    0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a,
+    0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151,
+    0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4,
+    0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a,
+    0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b,
+    0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c,
+    0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b,
+    0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3,
+    0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4,
+    0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b,
+    0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a,
+    0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4,
+    0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189,
+    0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92,
+    0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5,
+    0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9,
+    0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe,
+    0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5,
+    0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8,
+    0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66,
+    0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707,
+    0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8,
+    0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f,
+    0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707,
+    0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40,
+    0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017,
+    0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876,
+    0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8,
+    0x7bc97a0c},
+   {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300,
+    0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0,
+    0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80,
+    0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701,
+    0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41,
+    0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81,
+    0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43,
+    0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83,
+    0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3,
+    0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42,
+    0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202,
+    0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2,
+    0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7,
+    0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407,
+    0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47,
+    0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87,
+    0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86,
+    0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46,
+    0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506,
+    0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44,
+    0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704,
+    0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4,
+    0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5,
+    0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505,
+    0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45,
+    0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f,
+    0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f,
+    0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f,
+    0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e,
+    0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e,
+    0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e,
+    0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce,
+    0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c,
+    0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc,
+    0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c,
+    0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d,
+    0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d,
+    0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d,
+    0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88,
+    0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48,
+    0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708,
+    0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89,
+    0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9,
+    0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309,
+    0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb,
+    0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b,
+    0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b,
+    0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b,
+    0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a,
+    0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a,
+    0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a,
+    0x7851a2ca},
+   {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb,
+    0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8,
+    0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0,
+    0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f,
+    0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a,
+    0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf,
+    0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5,
+    0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380,
+    0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815,
+    0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa,
+    0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2,
+    0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1,
+    0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1,
+    0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4,
+    0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa,
+    0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df,
+    0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6,
+    0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5,
+    0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad,
+    0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca,
+    0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f,
+    0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a,
+    0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8,
+    0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d,
+    0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708,
+    0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d,
+    0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865,
+    0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636,
+    0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f,
+    0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a,
+    0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744,
+    0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061,
+    0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0,
+    0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293,
+    0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb,
+    0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874,
+    0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1,
+    0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4,
+    0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f,
+    0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a,
+    0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f,
+    0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120,
+    0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778,
+    0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b,
+    0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a,
+    0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af,
+    0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81,
+    0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4,
+    0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd,
+    0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e,
+    0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6,
+    0x566b6848}};
+
+local const z_word_t FAR crc_braid_big_table[][256] = {
+   {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912,
+    0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba,
+    0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3,
+    0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30,
+    0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e,
+    0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3,
+    0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73,
+    0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe,
+    0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0,
+    0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643,
+    0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a,
+    0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082,
+    0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4,
+    0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279,
+    0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735,
+    0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8,
+    0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad,
+    0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05,
+    0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c,
+    0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718,
+    0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46,
+    0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb,
+    0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc,
+    0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41,
+    0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f,
+    0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad,
+    0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4,
+    0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c,
+    0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779,
+    0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4,
+    0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8,
+    0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235,
+    0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7,
+    0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f,
+    0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476,
+    0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195,
+    0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb,
+    0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46,
+    0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622,
+    0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af,
+    0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1,
+    0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12,
+    0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b,
+    0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3,
+    0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51,
+    0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc,
+    0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90,
+    0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d,
+    0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708,
+    0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0,
+    0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9,
+    0x48686b56},
+   {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c,
+    0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae,
+    0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb,
+    0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90,
+    0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410,
+    0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b,
+    0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6,
+    0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed,
+    0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d,
+    0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036,
+    0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953,
+    0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1,
+    0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca,
+    0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781,
+    0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d,
+    0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416,
+    0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f,
+    0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd,
+    0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8,
+    0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b,
+    0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb,
+    0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0,
+    0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5,
+    0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e,
+    0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e,
+    0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558,
+    0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d,
+    0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf,
+    0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6,
+    0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad,
+    0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971,
+    0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a,
+    0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b,
+    0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969,
+    0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c,
+    0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57,
+    0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7,
+    0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c,
+    0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab,
+    0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0,
+    0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160,
+    0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b,
+    0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e,
+    0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac,
+    0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d,
+    0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546,
+    0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a,
+    0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1,
+    0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8,
+    0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a,
+    0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f,
+    0xcaa25178},
+   {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00,
+    0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b,
+    0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed,
+    0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777,
+    0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01,
+    0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a,
+    0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef,
+    0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74,
+    0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002,
+    0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498,
+    0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee,
+    0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75,
+    0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05,
+    0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e,
+    0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8,
+    0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73,
+    0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404,
+    0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f,
+    0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9,
+    0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71,
+    0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607,
+    0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c,
+    0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb,
+    0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470,
+    0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806,
+    0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790,
+    0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6,
+    0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d,
+    0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a,
+    0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991,
+    0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7,
+    0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c,
+    0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09,
+    0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92,
+    0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4,
+    0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e,
+    0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08,
+    0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593,
+    0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3,
+    0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778,
+    0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e,
+    0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94,
+    0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2,
+    0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079,
+    0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c,
+    0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497,
+    0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1,
+    0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a,
+    0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d,
+    0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396,
+    0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0,
+    0x0c7ac97b},
+   {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669,
+    0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853,
+    0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062,
+    0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527,
+    0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad,
+    0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545,
+    0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27,
+    0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf,
+    0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45,
+    0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800,
+    0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031,
+    0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b,
+    0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26,
+    0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce,
+    0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d,
+    0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5,
+    0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130,
+    0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a,
+    0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b,
+    0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480,
+    0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a,
+    0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2,
+    0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e,
+    0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996,
+    0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c,
+    0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc,
+    0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd,
+    0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7,
+    0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232,
+    0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da,
+    0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439,
+    0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1,
+    0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da,
+    0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0,
+    0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1,
+    0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94,
+    0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e,
+    0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6,
+    0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2,
+    0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a,
+    0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0,
+    0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95,
+    0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4,
+    0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e,
+    0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395,
+    0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d,
+    0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e,
+    0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676,
+    0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83,
+    0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9,
+    0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888,
+    0x5185cd09}};
+
+#endif
+
+#endif
+
+#endif
+
+local const z_crc_t FAR x2n_table[] = {
+    0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000,
+    0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467,
+    0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0,
+    0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169,
+    0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37,
+    0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a,
+    0xc40ba6d0, 0xc4e22c3c};
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index 91b343b..48da6ff 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -8,7 +8,7 @@
  * parse compressed PCF fonts, as found with many X11 server
  * distributions.
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,15 +20,14 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_GZIP_H
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftgzip.h>
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -36,7 +35,7 @@
 #define FT_ERR_PREFIX  Gzip_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Gzip
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 
 #ifdef FT_CONFIG_OPTION_USE_ZLIB
@@ -70,10 +69,15 @@
   /*                                                                   */
   /* so that configuration with `FT_CONFIG_OPTION_SYSTEM_ZLIB' might   */
   /* include the wrong `zconf.h' file, leading to errors.              */
-#include "zlib.h"
 
-#undef  SLOW
-#define SLOW  1  /* we can't use asm-optimized sources here! */
+#if defined( __GNUC__ ) ||  defined( __clang__ )
+#define ZEXPORT
+#define ZEXTERN      static
+#endif
+
+#define HAVE_MEMCPY  1
+#define Z_SOLO       1
+#define Z_FREETYPE   1
 
 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++)   */
   /* We disable the warning `conversion from XXX to YYY,     */
@@ -84,24 +88,25 @@
 #pragma warning( disable : 4244 )
 #endif /* _MSC_VER */
 
-  /* Urgh.  `inflate_mask' must not be declared twice -- C++ doesn't like
-     this.  We temporarily disable it and load all necessary header files. */
-#define NO_INFLATE_MASK
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#undef  NO_INFLATE_MASK
+#if defined( __GNUC__ )
+#pragma GCC diagnostic push
+#ifndef __cplusplus
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+#endif
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
 
-  /* infutil.c must be included before infcodes.c */
 #include "zutil.c"
-#include "inftrees.c"
-#include "infutil.c"
-#include "infcodes.c"
-#include "infblock.c"
+#include "inffast.c"
 #include "inflate.c"
+#include "inftrees.c"
 #include "adler32.c"
+#include "crc32.c"
+
+#if defined( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
 
 #if defined( _MSC_VER )
 #pragma warning( pop )
@@ -122,48 +127,32 @@
      'malloc/free' */
 
   static voidpf
-  ft_gzip_alloc( FT_Memory  memory,
-                 uInt       items,
-                 uInt       size )
+  ft_gzip_alloc( voidpf  opaque,
+                 uInt    items,
+                 uInt    size )
   {
-    FT_ULong    sz = (FT_ULong)size * items;
+    FT_Memory   memory = (FT_Memory)opaque;
+    FT_ULong    sz     = (FT_ULong)size * items;
     FT_Error    error;
-    FT_Pointer  p  = NULL;
+    FT_Pointer  p      = NULL;
 
 
-    (void)FT_ALLOC( p, sz );
+    /* allocate and zero out */
+    FT_MEM_ALLOC( p, sz );
     return p;
   }
 
 
   static void
-  ft_gzip_free( FT_Memory  memory,
-                voidpf     address )
+  ft_gzip_free( voidpf  opaque,
+                voidpf  address )
   {
+    FT_Memory  memory = (FT_Memory)opaque;
+
+
     FT_MEM_FREE( address );
   }
 
-
-#if !defined( FT_CONFIG_OPTION_SYSTEM_ZLIB ) && !defined( USE_ZLIB_ZCALLOC )
-
-  local voidpf
-  zcalloc ( voidpf    opaque,
-            unsigned  items,
-            unsigned  size )
-  {
-    return ft_gzip_alloc( (FT_Memory)opaque, items, size );
-  }
-
-  local void
-  zcfree( voidpf  opaque,
-          voidpf  ptr )
-  {
-    ft_gzip_free( (FT_Memory)opaque, ptr );
-  }
-
-#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */
-
-
 /***************************************************************************/
 /***************************************************************************/
 /*****                                                                 *****/
@@ -305,8 +294,8 @@
     }
 
     /* initialize zlib -- there is no zlib header in the compressed stream */
-    zstream->zalloc = (alloc_func)ft_gzip_alloc;
-    zstream->zfree  = (free_func) ft_gzip_free;
+    zstream->zalloc = ft_gzip_alloc;
+    zstream->zfree  = ft_gzip_free;
     zstream->opaque = stream->memory;
 
     zstream->avail_in = 0;
@@ -463,12 +452,13 @@
                             FT_ULong     count )
   {
     FT_Error  error = FT_Err_Ok;
-    FT_ULong  delta;
 
 
     for (;;)
     {
-      delta = (FT_ULong)( zip->limit - zip->cursor );
+      FT_ULong  delta = (FT_ULong)( zip->limit - zip->cursor );
+
+
       if ( delta >= count )
         delta = count;
 
@@ -672,7 +662,7 @@
         FT_Byte*  zip_buff = NULL;
 
 
-        if ( !FT_ALLOC( zip_buff, zip_size ) )
+        if ( !FT_QALLOC( zip_buff, zip_size ) )
         {
           FT_ULong  count;
 
@@ -731,7 +721,7 @@
 
     /* check for `input' delayed to `inflate' */
 
-    if ( !memory || ! output_len || !output )
+    if ( !memory || !output_len || !output )
       return FT_THROW( Invalid_Argument );
 
     /* this function is modeled after zlib's `uncompress' function */
@@ -742,11 +732,12 @@
     stream.next_out  = output;
     stream.avail_out = (uInt)*output_len;
 
-    stream.zalloc = (alloc_func)ft_gzip_alloc;
-    stream.zfree  = (free_func) ft_gzip_free;
+    stream.zalloc = ft_gzip_alloc;
+    stream.zfree  = ft_gzip_free;
     stream.opaque = memory;
 
-    err = inflateInit2( &stream, MAX_WBITS );
+    err = inflateInit2( &stream, MAX_WBITS|32 );
+
     if ( err != Z_OK )
       return FT_THROW( Invalid_Argument );
 
@@ -773,6 +764,9 @@
     if ( err == Z_DATA_ERROR )
       return FT_THROW( Invalid_Table );
 
+    if ( err == Z_NEED_DICT )
+      return FT_THROW( Invalid_Table );
+
     return FT_Err_Ok;
   }
 
diff --git a/src/gzip/ftzconf.h b/src/gzip/ftzconf.h
index 3abf0ba..bf977d3 100644
--- a/src/gzip/ftzconf.h
+++ b/src/gzip/ftzconf.h
@@ -1,109 +1,258 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
-#ifndef _ZCONF_H
-#define _ZCONF_H
+#ifndef ZCONF_H
+#define ZCONF_H
 
 /*
  * If you *really* need a unique prefix for all types and library functions,
  * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
  */
-#ifdef Z_PREFIX
-#  define deflateInit_         z_deflateInit_
-#  define deflate              z_deflate
-#  define deflateEnd           z_deflateEnd
-#  define inflateInit_         z_inflateInit_
-#  define inflate              z_inflate
-#  define inflateEnd           z_inflateEnd
-#  define deflateInit2_        z_deflateInit2_
-#  define deflateSetDictionary z_deflateSetDictionary
-#  define deflateCopy          z_deflateCopy
-#  define deflateReset         z_deflateReset
-#  define deflateParams        z_deflateParams
-#  define inflateInit2_        z_inflateInit2_
-#  define inflateSetDictionary z_inflateSetDictionary
-#  define inflateSync          z_inflateSync
-#  define inflateSyncPoint     z_inflateSyncPoint
-#  define inflateReset         z_inflateReset
-#  define compress             z_compress
-#  define compress2            z_compress2
-#  define uncompress           z_uncompress
-#  define adler32              z_adler32
-#  define crc32                z_crc32
-#  define get_crc_table        z_get_crc_table
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
 
-#  define Byte   z_Byte
-#  define uInt   z_uInt
-#  define uLong  z_uLong
-#  define Bytef  z_Bytef
-#  define charf  z_charf
-#  define intf   z_intf
-#  define uIntf  z_uIntf
-#  define uLongf z_uLongf
-#  define voidpf z_voidpf
-#  define voidp  z_voidp
-#endif
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#  define WIN32
-#endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-#  ifndef __32BIT__
-#    define __32BIT__
+/* all linked symbols and init macros */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define adler32_z             z_adler32_z
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
 #  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define crc32_combine_gen     z_crc32_combine_gen
+#  define crc32_combine_gen64   z_crc32_combine_gen64
+#  define crc32_combine_op      z_crc32_combine_op
+#  define crc32_z               z_crc32_z
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateGetDictionary  z_deflateGetDictionary
+#  define deflateInit           z_deflateInit
+#  define deflateInit2          z_deflateInit2
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzfread               z_gzfread
+#    define gzfwrite              z_gzfwrite
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzvprintf             z_gzvprintf
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit       z_inflateBackInit
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCodesUsed      z_inflateCodesUsed
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit           z_inflateInit
+#  define inflateInit2          z_inflateInit2
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateValidate       z_inflateValidate
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#    define uncompress2           z_uncompress2
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
 #endif
+
 #if defined(__MSDOS__) && !defined(MSDOS)
 #  define MSDOS
 #endif
-
-/* WinCE doesn't have errno.h */
-#ifdef _WIN32_WCE
-#  define NO_ERRNO_H
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
 #endif
-
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
 
 /*
  * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
  * than 64k bytes at a time (needed on systems with 16-bit int).
  */
-#if defined(MSDOS) && !defined(__32BIT__)
+#ifdef SYS16BIT
 #  define MAXSEG_64K
 #endif
 #ifdef MSDOS
 #  define UNALIGNED_OK
 #endif
 
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
-#  define STDC
-#endif
-#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+#ifdef __STDC_VERSION__
 #  ifndef STDC
 #    define STDC
 #  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
 #endif
 
 #ifndef STDC
 #  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-#    define const
+#    define const       /* note: need a more gentle solution here */
 #  endif
 #endif
 
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-#  define NO_DUMMY_DECL
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
 #endif
 
-/* Old Borland C and LCC incorrectly complains about missing returns: */
-#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-#  define NEED_DUMMY_RETURN
-#endif
-
-#if defined(__LCC__)
-#  define  NEED_DUMMY_RETURN
+#ifdef Z_SOLO
+   typedef unsigned long z_size_t;
+#else
+#  define z_longlong long long
+#  if defined(NO_SIZE_T)
+     typedef unsigned NO_SIZE_T z_size_t;
+#  elif defined(STDC)
+#    include <stddef.h>
+     typedef size_t z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
+#  undef z_longlong
 #endif
 
 /* Maximum value for memLevel in deflateInit2 */
@@ -133,7 +282,7 @@
  Of course this will generally degrade compression (there's no free lunch).
 
    The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
  for small objects.
 */
 
@@ -147,75 +296,104 @@
 #  endif
 #endif
 
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
 /* The following definitions for FAR are needed only for MSDOS mixed
  * model programming (small or medium model with some far allocations).
  * This was tested only with MSC; for other MSDOS compilers you may have
  * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
  * just define FAR to be empty.
  */
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-   /* MSC small or medium model */
-#  define SMALL_MEDIUM
-#  ifdef _MSC_VER
-#    define FAR _far
-#  else
-#    define FAR far
-#  endif
-#endif
-#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-#  ifndef __32BIT__
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
 #    define SMALL_MEDIUM
-#    define FAR _far
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
 #  endif
 #endif
 
-/* Compile with -DZLIB_DLL for Windows DLL support */
-#if defined(ZLIB_DLL)
-#  if defined(_WINDOWS) || defined(WINDOWS)
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
 #    ifdef FAR
 #      undef FAR
 #    endif
-#    include <windows.h>
-#    define ZEXPORT(x)  x WINAPI
-#    ifdef WIN32
-#      define ZEXPORTVA(x)  x WINAPIV
-#    else
-#      define ZEXPORTVA(x)  x FAR _cdecl _export
+#    ifndef WIN32_LEAN_AND_MEAN
+#      define WIN32_LEAN_AND_MEAN
 #    endif
-#  endif
-#  if defined (__BORLANDC__)
-#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-#      include <windows.h>
-#      define ZEXPORT(x) x __declspec(dllexport) WINAPI
-#      define ZEXPORTRVA(x)  x __declspec(dllexport) WINAPIV
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
 #    else
-#      if defined (_Windows) && defined (__DLL__)
-#        define ZEXPORT(x) x _export
-#        define ZEXPORTVA(x) x _export
-#      endif
+#      define ZEXPORTVA FAR CDECL
 #    endif
 #  endif
 #endif
 
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
 
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
 #ifndef ZEXPORT
-#  define ZEXPORT(x)   static x
+#  define ZEXPORT
 #endif
 #ifndef ZEXPORTVA
-#  define ZEXPORTVA(x)   static x
-#endif
-#ifndef ZEXTERN
-#  define ZEXTERN(x) static x
-#endif
-#ifndef ZEXTERNDEF
-#  define ZEXTERNDEF(x)  static x
+#  define ZEXPORTVA
 #endif
 
 #ifndef FAR
-#   define FAR
+#  define FAR
 #endif
 
-#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+#if !defined(__MACTYPES__)
 typedef unsigned char  Byte;  /* 8 bits */
 #endif
 typedef unsigned int   uInt;  /* 16 bits or more */
@@ -233,52 +411,137 @@
 typedef uLong FAR uLongf;
 
 #ifdef STDC
-   typedef void FAR *voidpf;
-   typedef void     *voidp;
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
 #else
-   typedef Byte FAR *voidpf;
-   typedef Byte     *voidp;
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
 #endif
 
-#ifdef HAVE_UNISTD_H
-#  include <sys/types.h> /* for off_t */
-#  include <unistd.h>    /* for SEEK_* and off_t */
-#  define z_off_t  off_t
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
 #endif
-#ifndef SEEK_SET
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#ifndef Z_HAVE_UNISTD_H
+#  ifdef __WATCOMC__
+#    define Z_HAVE_UNISTD_H
+#  endif
+#endif
+#ifndef Z_HAVE_UNISTD_H
+#  if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
+#    define Z_HAVE_UNISTD_H
+#  endif
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
 #  define SEEK_SET        0       /* Seek from beginning of file.  */
 #  define SEEK_CUR        1       /* Seek from current position.  */
 #  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
 #endif
+
 #ifndef z_off_t
-#  define  z_off_t long
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
 #endif
 
 /* MVS linker does not support external names larger than 8 bytes */
 #if defined(__MVS__)
-#   pragma map(deflateInit_,"DEIN")
-#   pragma map(deflateInit2_,"DEIN2")
-#   pragma map(deflateEnd,"DEEND")
-#   pragma map(inflateInit_,"ININ")
-#   pragma map(inflateInit2_,"ININ2")
-#   pragma map(inflateEnd,"INEND")
-#   pragma map(inflateSync,"INSY")
-#   pragma map(inflateSetDictionary,"INSEDI")
-#   pragma map(inflate_blocks,"INBL")
-#   pragma map(inflate_blocks_new,"INBLNE")
-#   pragma map(inflate_blocks_free,"INBLFR")
-#   pragma map(inflate_blocks_reset,"INBLRE")
-#   pragma map(inflate_codes_free,"INCOFR")
-#   pragma map(inflate_codes,"INCO")
-#   pragma map(inflate_fast,"INFA")
-#   pragma map(inflate_flush,"INFLU")
-#   pragma map(inflate_mask,"INMA")
-#   pragma map(inflate_set_dictionary,"INSEDI2")
-#   pragma map(inflate_copyright,"INCOPY")
-#   pragma map(inflate_trees_bits,"INTRBI")
-#   pragma map(inflate_trees_dynamic,"INTRDY")
-#   pragma map(inflate_trees_fixed,"INTRFI")
-#   pragma map(inflate_trees_free,"INTRFR")
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
 #endif
 
-#endif /* _ZCONF_H */
+#endif /* ZCONF_H */
diff --git a/src/gzip/gzguts.h b/src/gzip/gzguts.h
new file mode 100644
index 0000000..4f09a52
--- /dev/null
+++ b/src/gzip/gzguts.h
@@ -0,0 +1,219 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004-2019 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+#  ifndef _LARGEFILE_SOURCE
+#    define _LARGEFILE_SOURCE 1
+#  endif
+#  ifdef _FILE_OFFSET_BITS
+#    undef _FILE_OFFSET_BITS
+#  endif
+#endif
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#  include <limits.h>
+#endif
+
+#ifndef _POSIX_SOURCE
+#  define _POSIX_SOURCE
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+#  include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+#  include <io.h>
+#endif
+
+#if defined(_WIN32)
+#  define WIDECHAR
+#endif
+
+#ifdef WINAPI_FAMILY
+#  define open _open
+#  define read _read
+#  define write _write
+#  define close _close
+#endif
+
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+   but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+#         define vsnprintf _vsnprintf
+#      endif
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#  ifdef VMS
+#    define NO_vsnprintf
+#  endif
+#  ifdef __OS400__
+#    define NO_vsnprintf
+#  endif
+#  ifdef __MVS__
+#    define NO_vsnprintf
+#  endif
+#endif
+
+/* unlike snprintf (which is required in C99), _snprintf does not guarantee
+   null termination of the result -- however this is only used in gzlib.c where
+   the result is assured to fit in the space provided */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#  define snprintf _snprintf
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+   define "local" for the non-static meaning of "static", for readability
+   (compile with -Dlocal if your debugger can't find static symbols) */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+  extern voidp  malloc OF((uInt size));
+  extern void   free   OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+#  include <windows.h>
+#  define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+#  ifndef NO_STRERROR
+#    include <errno.h>
+#    define zstrerror() strerror(errno)
+#  else
+#    define zstrerror() "stdio error (consult errno)"
+#  endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+   twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0      /* look for a gzip header */
+#define COPY__ 1    /* copy input directly */
+#define GZIP 2      /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+        /* exposed contents for gzgetc() macro */
+    struct gzFile_s x;      /* "x" for exposed */
+                            /* x.have: number of bytes available at x.next */
+                            /* x.next: next output data to deliver or write */
+                            /* x.pos: current position in uncompressed data */
+        /* used for both reading and writing */
+    int mode;               /* see gzip modes above */
+    int fd;                 /* file descriptor */
+    char *path;             /* path or fd for error messages */
+    unsigned size;          /* buffer size, zero if not allocated yet */
+    unsigned want;          /* requested buffer size, default is GZBUFSIZE */
+    unsigned char *in;      /* input buffer (double-sized when writing) */
+    unsigned char *out;     /* output buffer (double-sized when reading) */
+    int direct;             /* 0 if processing gzip, 1 if transparent */
+        /* just for reading */
+    int how;                /* 0: get header, 1: copy, 2: decompress */
+    z_off64_t start;        /* where the gzip data started, for rewinding */
+    int eof;                /* true if end of input file reached */
+    int past;               /* true if read requested past end */
+        /* just for writing */
+    int level;              /* compression level */
+    int strategy;           /* compression strategy */
+    int reset;              /* true if a reset is pending after a Z_FINISH */
+        /* seek request */
+    z_off64_t skip;         /* amount to skip (already rewound if backwards) */
+    int seek;               /* true if seek request pending */
+        /* error information */
+    int err;                /* error code */
+    char *msg;              /* error message */
+        /* zlib inflate or deflate stream */
+    z_stream strm;          /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+   value -- needed when comparing unsigned to z_off64_t, which is signed
+   (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/src/gzip/infback.c b/src/gzip/infback.c
new file mode 100644
index 0000000..264c14e
--- /dev/null
+++ b/src/gzip/infback.c
@@ -0,0 +1,644 @@
+/* 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/infblock.c b/src/gzip/infblock.c
deleted file mode 100644
index d6e2dc2..0000000
--- a/src/gzip/infblock.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
-   Notes beyond the 1.93a appnote.txt:
-
-   1. Distance pointers never point before the beginning of the output
-      stream.
-   2. Distance pointers can point back across blocks, up to 32k away.
-   3. There is an implied maximum of 7 bits for the bit length table and
-      15 bits for the actual data.
-   4. If only one code exists, then it is encoded using one bit.  (Zero
-      would be more efficient, but perhaps a little confusing.)  If two
-      codes exist, they are coded using one bit each (0 and 1).
-   5. There is no way of sending zero distance codes--a dummy must be
-      sent if there are none.  (History: a pre 2.0 version of PKZIP would
-      store blocks with no distance codes, but this was discovered to be
-      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
-      zero distance codes, which is sent as one code of zero bits in
-      length.
-   6. There are up to 286 literal/length codes.  Code 256 represents the
-      end-of-block.  Note however that the static length tree defines
-      288 codes just to fill out the Huffman codes.  Codes 286 and 287
-      cannot be used though, since there is no length base or extra bits
-      defined for them.  Similarily, there are up to 30 distance codes.
-      However, static trees define 32 codes (all 5 bits) to fill out the
-      Huffman codes, but the last two had better not show up in the data.
-   7. Unzip can check dynamic Huffman blocks for complete code sets.
-      The exception is that a single code would not be complete (see #4).
-   8. The five bits following the block type is really the number of
-      literal codes sent minus 257.
-   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-      (1+6+6).  Therefore, to output three times the length, you output
-      three codes (1+1+1), whereas to output four times the same length,
-      you only need two codes (1+3).  Hmm.
-  10. In the tree reconstruction algorithm, Code = Code + Increment
-      only if BitLength(i) is not zero.  (Pretty obvious.)
-  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
-  12. Note: length code 284 can represent 227-258, but length code 285
-      really is 258.  The last length deserves its own, short code
-      since it gets used a lot in very redundant files.  The length
-      258 is special since 258 - 3 (the min match length) is 255.
-  13. The literal/length and distance code bit lengths are read as a
-      single stream of lengths.  It is possible (and advantageous) for
-      a repeat code (16, 17, or 18) to go across the boundary between
-      the two sets of lengths.
- */
-
-
-local void inflate_blocks_reset( /* s, z, c) */
-inflate_blocks_statef *s,
-z_streamp z,
-uLongf *c )
-{
-  if (c != Z_NULL)
-    *c = s->check;
-  if (s->mode == BTREE || s->mode == DTREE)
-    ZFREE(z, s->sub.trees.blens);
-  if (s->mode == CODES)
-    inflate_codes_free(s->sub.decode.codes, z);
-  s->mode = TYPE;
-  s->bitk = 0;
-  s->bitb = 0;
-  s->read = s->write = s->window;
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
-  Tracev((stderr, "inflate:   blocks reset\n"));
-}
-
-
-local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */
-z_streamp z,
-check_func c,
-uInt w )
-{
-  inflate_blocks_statef *s;
-
-  if ((s = (inflate_blocks_statef *)ZALLOC
-       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-    return s;
-  if ((s->hufts =
-       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
-  {
-    ZFREE(z, s);
-    return Z_NULL;
-  }
-  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-  {
-    ZFREE(z, s->hufts);
-    ZFREE(z, s);
-    return Z_NULL;
-  }
-  s->end = s->window + w;
-  s->checkfn = c;
-  s->mode = TYPE;
-  Tracev((stderr, "inflate:   blocks allocated\n"));
-  inflate_blocks_reset(s, z, Z_NULL);
-  return s;
-}
-
-
-local int inflate_blocks( /* s, z, r) */
-inflate_blocks_statef *s,
-z_streamp z,
-int r )
-{
-  uInt t;               /* temporary storage */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input based on current state */
-  while (1) switch (s->mode)
-  {
-    case TYPE:
-      NEEDBITS(3)
-      t = (uInt)b & 7;
-      s->last = t & 1;
-      switch (t >> 1)
-      {
-        case 0:                         /* stored */
-          Tracev((stderr, "inflate:     stored block%s\n",
-                 s->last ? " (last)" : ""));
-          DUMPBITS(3)
-          t = k & 7;                    /* go to byte boundary */
-          DUMPBITS(t)
-          s->mode = LENS;               /* get length of stored block */
-          break;
-        case 1:                         /* fixed */
-          Tracev((stderr, "inflate:     fixed codes block%s\n",
-                 s->last ? " (last)" : ""));
-          {
-            uInt bl, bd;
-            inflate_huft *tl, *td;
-
-            inflate_trees_fixed(&bl, &bd, (const inflate_huft**)&tl,
-                                          (const inflate_huft**)&td, z);
-            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-            if (s->sub.decode.codes == Z_NULL)
-            {
-              r = Z_MEM_ERROR;
-              LEAVE
-            }
-          }
-          DUMPBITS(3)
-          s->mode = CODES;
-          break;
-        case 2:                         /* dynamic */
-          Tracev((stderr, "inflate:     dynamic codes block%s\n",
-                 s->last ? " (last)" : ""));
-          DUMPBITS(3)
-          s->mode = TABLE;
-          break;
-        case 3:                         /* illegal */
-          DUMPBITS(3)
-          s->mode = BAD;
-          z->msg = (char*)"invalid block type";
-          r = Z_DATA_ERROR;
-          LEAVE
-      }
-      break;
-    case LENS:
-      NEEDBITS(32)
-      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
-      {
-        s->mode = BAD;
-        z->msg = (char*)"invalid stored block lengths";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-      s->sub.left = (uInt)b & 0xffff;
-      b = k = 0;                      /* dump bits */
-      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
-      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
-      break;
-    case STORED:
-      if (n == 0)
-        LEAVE
-      NEEDOUT
-      t = s->sub.left;
-      if (t > n) t = n;
-      if (t > m) t = m;
-      zmemcpy(q, p, t);
-      p += t;  n -= t;
-      q += t;  m -= t;
-      if ((s->sub.left -= t) != 0)
-        break;
-      Tracev((stderr, "inflate:       stored end, %lu total out\n",
-              z->total_out + (q >= s->read ? q - s->read :
-              (s->end - s->read) + (q - s->window))));
-      s->mode = s->last ? DRY : TYPE;
-      break;
-    case TABLE:
-      NEEDBITS(14)
-      s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
-      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-      {
-        s->mode = BAD;
-        z->msg = (char*)"too many length or distance symbols";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-#endif
-      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-      {
-        r = Z_MEM_ERROR;
-        LEAVE
-      }
-      DUMPBITS(14)
-      s->sub.trees.index = 0;
-      Tracev((stderr, "inflate:       table sizes ok\n"));
-      s->mode = BTREE;
-    case BTREE:
-      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-      {
-        NEEDBITS(3)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-        DUMPBITS(3)
-      }
-      while (s->sub.trees.index < 19)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-      s->sub.trees.bb = 7;
-      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-                             &s->sub.trees.tb, s->hufts, z);
-      if (t != Z_OK)
-      {
-        r = t;
-        if (r == Z_DATA_ERROR)
-        {
-          ZFREE(z, s->sub.trees.blens);
-          s->mode = BAD;
-        }
-        LEAVE
-      }
-      s->sub.trees.index = 0;
-      Tracev((stderr, "inflate:       bits tree ok\n"));
-      s->mode = DTREE;
-    case DTREE:
-      while (t = s->sub.trees.table,
-             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-      {
-        inflate_huft *h;
-        uInt i, j, c;
-
-        t = s->sub.trees.bb;
-        NEEDBITS(t)
-        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-        t = h->bits;
-        c = h->base;
-        if (c < 16)
-        {
-          DUMPBITS(t)
-          s->sub.trees.blens[s->sub.trees.index++] = c;
-        }
-        else /* c == 16..18 */
-        {
-          i = c == 18 ? 7 : c - 14;
-          j = c == 18 ? 11 : 3;
-          NEEDBITS(t + i)
-          DUMPBITS(t)
-          j += (uInt)b & inflate_mask[i];
-          DUMPBITS(i)
-          i = s->sub.trees.index;
-          t = s->sub.trees.table;
-          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-              (c == 16 && i < 1))
-          {
-            ZFREE(z, s->sub.trees.blens);
-            s->mode = BAD;
-            z->msg = (char*)"invalid bit length repeat";
-            r = Z_DATA_ERROR;
-            LEAVE
-          }
-          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-          do {
-            s->sub.trees.blens[i++] = c;
-          } while (--j);
-          s->sub.trees.index = i;
-        }
-      }
-      s->sub.trees.tb = Z_NULL;
-      {
-        uInt bl, bd;
-        inflate_huft *tl, *td;
-        inflate_codes_statef *c;
-
-        bl = 9;         /* must be <= 9 for lookahead assumptions */
-        bd = 6;         /* must be <= 9 for lookahead assumptions */
-        t = s->sub.trees.table;
-        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
-                                  s->hufts, z);
-        if (t != Z_OK)
-        {
-          if (t == (uInt)Z_DATA_ERROR)
-          {
-            ZFREE(z, s->sub.trees.blens);
-            s->mode = BAD;
-          }
-          r = t;
-          LEAVE
-        }
-        Tracev((stderr, "inflate:       trees ok\n"));
-        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-        {
-          r = Z_MEM_ERROR;
-          LEAVE
-        }
-        s->sub.decode.codes = c;
-      }
-      ZFREE(z, s->sub.trees.blens);
-      s->mode = CODES;
-    case CODES:
-      UPDATE
-      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-        return inflate_flush(s, z, r);
-      r = Z_OK;
-      inflate_codes_free(s->sub.decode.codes, z);
-      LOAD
-      Tracev((stderr, "inflate:       codes end, %lu total out\n",
-              z->total_out + (q >= s->read ? q - s->read :
-              (s->end - s->read) + (q - s->window))));
-      if (!s->last)
-      {
-        s->mode = TYPE;
-        break;
-      }
-      s->mode = DRY;
-    case DRY:
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      s->mode = DONE;
-    case DONE:
-      r = Z_STREAM_END;
-      LEAVE
-    case BAD:
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-#ifdef NEED_DUMMY_RETURN
-  return 0;
-#endif
-}
-
-
-local int inflate_blocks_free( /* s, z) */
-inflate_blocks_statef *s,
-z_streamp z )
-{
-  inflate_blocks_reset(s, z, Z_NULL);
-  ZFREE(z, s->window);
-  ZFREE(z, s->hufts);
-  ZFREE(z, s);
-  Tracev((stderr, "inflate:   blocks freed\n"));
-  return Z_OK;
-}
-
-
diff --git a/src/gzip/infblock.h b/src/gzip/infblock.h
deleted file mode 100644
index c2535a1..0000000
--- a/src/gzip/infblock.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFBLOCK_H
-#define _INFBLOCK_H
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-local  inflate_blocks_statef * inflate_blocks_new OF((
-    z_streamp z,
-    check_func c,               /* check function */
-    uInt w));                   /* window size */
-
-local  int inflate_blocks OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));                      /* initial return code */
-
-local  void inflate_blocks_reset OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    uLongf *));                  /* check value on output */
-
-local  int inflate_blocks_free OF((
-    inflate_blocks_statef *,
-    z_streamp));
-
-#endif /* _INFBLOCK_H */
diff --git a/src/gzip/infcodes.c b/src/gzip/infcodes.c
deleted file mode 100644
index f7bfd58..0000000
--- a/src/gzip/infcodes.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-      START,    /* x: set up for LEN */
-      LEN,      /* i: get length/literal/eob next */
-      LENEXT,   /* i: getting length extra (have base) */
-      DIST,     /* i: get distance next */
-      DISTEXT,  /* i: getting distance extra */
-      COPY,     /* o: copying bytes in window, waiting for space */
-      LIT,      /* o: got literal, waiting for output space */
-      WASH,     /* o: got eob, possibly still output waiting */
-      END,      /* x: got eob and all data flushed */
-      BADCODE}  /* x: got error */
-inflate_codes_mode;
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
-  /* mode */
-  inflate_codes_mode mode;      /* current inflate_codes mode */
-
-  /* mode dependent information */
-  uInt len;
-  union {
-    struct {
-      inflate_huft *tree;       /* pointer into tree */
-      uInt need;                /* bits needed */
-    } code;             /* if LEN or DIST, where in tree */
-    uInt lit;           /* if LIT, literal */
-    struct {
-      uInt get;                 /* bits to get for extra */
-      uInt dist;                /* distance back to copy from */
-    } copy;             /* if EXT or COPY, where and how much */
-  } sub;                /* submode */
-
-  /* mode independent information */
-  Byte lbits;           /* ltree bits decoded per branch */
-  Byte dbits;           /* dtree bits decoder per branch */
-  inflate_huft *ltree;          /* literal/length/eob tree */
-  inflate_huft *dtree;          /* distance tree */
-
-};
-
-
-local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */
-uInt bl, uInt bd,
-inflate_huft *tl,
-inflate_huft *td, /* need separate declaration for Borland C++ */
-z_streamp z )
-{
-  inflate_codes_statef *c;
-
-  if ((c = (inflate_codes_statef *)
-       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-  {
-    c->mode = START;
-    c->lbits = (Byte)bl;
-    c->dbits = (Byte)bd;
-    c->ltree = tl;
-    c->dtree = td;
-    Tracev((stderr, "inflate:       codes new\n"));
-  }
-  return c;
-}
-
-
-local int inflate_codes( /* s, z, r) */
-inflate_blocks_statef *s,
-z_streamp z,
-int r )
-{
-  uInt j;               /* temporary storage */
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  Bytef *f;             /* pointer to copy strings from */
-  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input and output based on current state */
-  while (1) switch (c->mode)
-  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-    case START:         /* x: set up for LEN */
-#ifndef SLOW
-      if (m >= 258 && n >= 10)
-      {
-        UPDATE
-        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-        LOAD
-        if (r != Z_OK)
-        {
-          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-          break;
-        }
-      }
-#endif /* !SLOW */
-      c->sub.code.need = c->lbits;
-      c->sub.code.tree = c->ltree;
-      c->mode = LEN;
-    case LEN:           /* i: get length/literal/eob next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e == 0)               /* literal */
-      {
-        c->sub.lit = t->base;
-        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                 "inflate:         literal '%c'\n" :
-                 "inflate:         literal 0x%02x\n", t->base));
-        c->mode = LIT;
-        break;
-      }
-      if (e & 16)               /* length */
-      {
-        c->sub.copy.get = e & 15;
-        c->len = t->base;
-        c->mode = LENEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t + t->base;
-        break;
-      }
-      if (e & 32)               /* end of block */
-      {
-        Tracevv((stderr, "inflate:         end of block\n"));
-        c->mode = WASH;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid literal/length code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case LENEXT:        /* i: getting length extra (have base) */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->len += (uInt)b & inflate_mask[j];
-      DUMPBITS(j)
-      c->sub.code.need = c->dbits;
-      c->sub.code.tree = c->dtree;
-      Tracevv((stderr, "inflate:         length %u\n", c->len));
-      c->mode = DIST;
-    case DIST:          /* i: get distance next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e & 16)               /* distance */
-      {
-        c->sub.copy.get = e & 15;
-        c->sub.copy.dist = t->base;
-        c->mode = DISTEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t + t->base;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid distance code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case DISTEXT:       /* i: getting distance extra */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->sub.copy.dist += (uInt)b & inflate_mask[j];
-      DUMPBITS(j)
-      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
-      c->mode = COPY;
-    case COPY:          /* o: copying bytes in window, waiting for space */
-      f = q - c->sub.copy.dist;
-      while (f < s->window)             /* modulo window size-"while" instead */
-        f += s->end - s->window;        /* of "if" handles invalid distances */
-      while (c->len)
-      {
-        NEEDOUT
-        OUTBYTE(*f++)
-        if (f == s->end)
-          f = s->window;
-        c->len--;
-      }
-      c->mode = START;
-      break;
-    case LIT:           /* o: got literal, waiting for output space */
-      NEEDOUT
-      OUTBYTE(c->sub.lit)
-      c->mode = START;
-      break;
-    case WASH:          /* o: got eob, possibly more output */
-      if (k > 7)        /* return unused byte, if any */
-      {
-        Assert(k < 16, "inflate_codes grabbed too many bytes")
-        k -= 8;
-        n++;
-        p--;            /* can always return one */
-      }
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      c->mode = END;
-    case END:
-      r = Z_STREAM_END;
-      LEAVE
-    case BADCODE:       /* x: got error */
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-#ifdef NEED_DUMMY_RETURN
-  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
-#endif
-}
-
-
-local void inflate_codes_free( /* c, z) */
-inflate_codes_statef *c,
-z_streamp z )
-{
-  ZFREE(z, c);
-  Tracev((stderr, "inflate:       codes free\n"));
-}
diff --git a/src/gzip/infcodes.h b/src/gzip/infcodes.h
deleted file mode 100644
index 154d7f8..0000000
--- a/src/gzip/infcodes.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFCODES_H
-#define _INFCODES_H
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-local inflate_codes_statef *inflate_codes_new OF((
-    uInt, uInt,
-    inflate_huft *, inflate_huft *,
-    z_streamp ));
-
-local int inflate_codes OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-local void inflate_codes_free OF((
-    inflate_codes_statef *,
-    z_streamp ));
-
-#endif /* _INFCODES_H */
diff --git a/src/gzip/inffast.c b/src/gzip/inffast.c
new file mode 100644
index 0000000..809737b
--- /dev/null
+++ b/src/gzip/inffast.c
@@ -0,0 +1,323 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef ASMINF
+#  pragma message("Assembler code may have bugs -- use at your own risk")
+#else
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void ZLIB_INTERNAL inflate_fast(
+    z_streamp strm,
+    unsigned start)
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *in;      /* local strm->next_in */
+    z_const unsigned char FAR *last;    /* have enough input while in < last */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code const *here;           /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    wnext = state->wnext;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(*in++) << bits;
+            bits += 8;
+            hold += (unsigned long)(*in++) << bits;
+            bits += 8;
+        }
+        here = lcode + (hold & lmask);
+      dolen:
+        op = (unsigned)(here->bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(here->op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", here->val));
+            *out++ = (unsigned char)(here->val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(here->val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(*in++) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(*in++) << bits;
+                bits += 8;
+                hold += (unsigned long)(*in++) << bits;
+                bits += 8;
+            }
+            here = dcode + (hold & dmask);
+          dodist:
+            op = (unsigned)(here->bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(here->op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(here->val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(*in++) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(*in++) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        if (state->sane) {
+                            strm->msg =
+                                (char *)"invalid distance too far back";
+                            state->mode = BAD;
+                            break;
+                        }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        if (len <= op - whave) {
+                            do {
+                                *out++ = 0;
+                            } while (--len);
+                            continue;
+                        }
+                        len -= op - whave;
+                        do {
+                            *out++ = 0;
+                        } while (--op > whave);
+                        if (op == 0) {
+                            from = out - dist;
+                            do {
+                                *out++ = *from++;
+                            } while (--len);
+                            continue;
+                        }
+#endif
+                    }
+                    from = window;
+                    if (wnext == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                *out++ = *from++;
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (wnext < op) {      /* wrap around window */
+                        from += wsize + wnext - op;
+                        op -= wnext;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                *out++ = *from++;
+                            } while (--op);
+                            from = window;
+                            if (wnext < len) {  /* some from start of window */
+                                op = wnext;
+                                len -= op;
+                                do {
+                                    *out++ = *from++;
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += wnext - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                *out++ = *from++;
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        len -= 3;
+                    }
+                    if (len) {
+                        *out++ = *from++;
+                        if (len > 1)
+                            *out++ = *from++;
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        *out++ = *from++;
+                        if (len > 1)
+                            *out++ = *from++;
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                here = dcode + here->val + (hold & ((1U << op) - 1));
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            here = lcode + here->val + (hold & ((1U << op) - 1));
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in;
+    strm->next_out = out;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and wnext == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/src/gzip/inffast.h b/src/gzip/inffast.h
new file mode 100644
index 0000000..684ae87
--- /dev/null
+++ b/src/gzip/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+static void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/src/gzip/inffixed.h b/src/gzip/inffixed.h
index 4d4760e..d628327 100644
--- a/src/gzip/inffixed.h
+++ b/src/gzip/inffixed.h
@@ -1,151 +1,94 @@
-/* inffixed.h -- table for decoding fixed codes
- * Generated automatically by the maketree.c program
- */
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
 
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
+    /* WARNING: this file should *not* be used by applications.
+       It is part of the implementation of this library and is
+       subject to change. Applications should only use zlib.h.
+     */
 
-local const uInt fixed_bl = 9;
-local const uInt fixed_bd = 5;
-local const inflate_huft fixed_tl[] = {
-    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
-    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
-    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
-    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
-    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
-    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
-    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
-    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
-    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
-    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
-    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
-    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
-    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
-    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
-    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
-    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
-    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
-    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
-    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
-    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
-    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
-    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
-    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
-    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
-    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
-    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
-    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
-    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
-    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
-    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
-    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
-    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
-    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
-    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
-    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
-    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
-    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
-    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
-    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
-    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
-    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
-    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
-    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
-    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
-    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
-    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
-    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
-    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
-    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
-    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
-    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
-    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
-    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
-    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
-    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
-    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
-    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
-    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
-    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
-    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
-    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
-    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
-    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
-    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
-    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
-    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
-    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
-    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
-    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
-    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
-    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
-    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
-    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
-    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
-    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
-    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
-    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
-    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
-    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
-    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
-    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
-    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
-    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
-    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
-    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
-    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
-    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
-    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
-    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
-    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
-    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
-    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
-    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
-    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
-    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
-    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
-    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
-    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
-    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
-    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
-    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
-    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
-    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
-    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
-    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
-    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
-    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
-    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
-    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
-    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
-    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
-    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
-  };
-local const inflate_huft fixed_td[] = {
-    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
-    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
-    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
-    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
-    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
-    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
-    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
-    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
-  };
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
diff --git a/src/gzip/inflate.c b/src/gzip/inflate.c
index 8877fa3..5117e2e 100644
--- a/src/gzip/inflate.c
+++ b/src/gzip/inflate.c
@@ -1,273 +1,1605 @@
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-2002 Mark Adler
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2022 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
 #include "zutil.h"
-#include "infblock.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
 
-#define  DONE  INFLATE_DONE
-#define  BAD   INFLATE_BAD
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
 
-typedef enum {
-      METHOD,   /* waiting for method byte */
-      FLAG,     /* waiting for flag byte */
-      DICT4,    /* four dictionary check bytes to go */
-      DICT3,    /* three dictionary check bytes to go */
-      DICT2,    /* two dictionary check bytes to go */
-      DICT1,    /* one dictionary check byte to go */
-      DICT0,    /* waiting for inflateSetDictionary */
-      BLOCKS,   /* decompressing blocks */
-      CHECK4,   /* four check bytes to go */
-      CHECK3,   /* three check bytes to go */
-      CHECK2,   /* two check bytes to go */
-      CHECK1,   /* one check byte to go */
-      DONE,     /* finished check, done */
-      BAD}      /* got an error--stay here */
-inflate_mode;
+/* function prototypes */
+local int inflateStateCheck OF((z_streamp strm));
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+                           unsigned copy));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+#ifndef Z_FREETYPE
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+                              unsigned len));
+#endif
 
-/* inflate private state */
-struct internal_state {
-
-  /* mode */
-  inflate_mode  mode;   /* current inflate mode */
-
-  /* mode dependent information */
-  union {
-    uInt method;        /* if FLAGS, method byte */
-    struct {
-      uLong was;                /* computed check value */
-      uLong need;               /* stream check value */
-    } check;            /* if CHECK, check values to compare */
-    uInt marker;        /* if BAD, inflateSync's marker bytes count */
-  } sub;        /* submode */
-
-  /* mode independent information */
-  int  nowrap;          /* flag for no wrapper */
-  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
-  inflate_blocks_statef
-    *blocks;            /* current inflate_blocks state */
-
-};
-
-
-ZEXPORT(int) inflateReset( /* z) */
-z_streamp z )
+local int inflateStateCheck(
+    z_streamp strm)
 {
-  if (z == Z_NULL || z->state == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->total_in = z->total_out = 0;
-  z->msg = Z_NULL;
-  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
-  Tracev((stderr, "inflate: reset\n"));
-  return Z_OK;
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+        return 1;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state == Z_NULL || state->strm != strm ||
+        state->mode < HEAD || state->mode > SYNC)
+        return 1;
+    return 0;
 }
 
-
-ZEXPORT(int) inflateEnd( /* z) */
-z_streamp z )
+int ZEXPORT inflateResetKeep(
+    z_streamp strm)
 {
-  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->blocks != Z_NULL)
-    inflate_blocks_free(z->state->blocks, z);
-  ZFREE(z, z->state);
-  z->state = Z_NULL;
-  Tracev((stderr, "inflate: end\n"));
-  return Z_OK;
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    if (state->wrap)        /* to support ill-conceived Java test suite */
+        strm->adler = state->wrap & 1;
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->flags = -1;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    state->sane = 1;
+    state->back = -1;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
 }
 
-
-ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */
-z_streamp z,
-int w,
-const char *version,
-int stream_size )
+int ZEXPORT inflateReset(
+    z_streamp strm)
 {
-  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-      stream_size != sizeof(z_stream))
-      return Z_VERSION_ERROR;
+    struct inflate_state FAR *state;
 
-  /* initialize state */
-  if (z == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->msg = Z_NULL;
-  if (z->zalloc == Z_NULL)
-  {
-    z->zalloc = zcalloc;
-    z->opaque = (voidpf)0;
-  }
-  if (z->zfree == Z_NULL) z->zfree = zcfree;
-  if ((z->state = (struct internal_state FAR *)
-       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-    return Z_MEM_ERROR;
-  z->state->blocks = Z_NULL;
-
-  /* handle undocumented nowrap option (no zlib header or check) */
-  z->state->nowrap = 0;
-  if (w < 0)
-  {
-    w = - w;
-    z->state->nowrap = 1;
-  }
-
-  /* set window size */
-  if (w < 8 || w > 15)
-  {
-    inflateEnd(z);
-    return Z_STREAM_ERROR;
-  }
-  z->state->wbits = (uInt)w;
-
-  /* create inflate_blocks state */
-  if ((z->state->blocks =
-      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
-      == Z_NULL)
-  {
-    inflateEnd(z);
-    return Z_MEM_ERROR;
-  }
-  Tracev((stderr, "inflate: allocated\n"));
-
-  /* reset state */
-  inflateReset(z);
-  return Z_OK;
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->wsize = 0;
+    state->whave = 0;
+    state->wnext = 0;
+    return inflateResetKeep(strm);
 }
 
-
-
-#undef  NEEDBYTE
-#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-
-#undef  NEXTBYTE
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-
-ZEXPORT(int) inflate( /* z, f) */
-z_streamp z,
-int f )
+int ZEXPORT inflateReset2(
+    z_streamp strm,
+    int windowBits)
 {
-  int r;
-  uInt b;
+    int wrap;
+    struct inflate_state FAR *state;
 
-  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
-    return Z_STREAM_ERROR;
-  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
-  r = Z_BUF_ERROR;
-  while (1) switch (z->state->mode)
-  {
-    case METHOD:
-      NEEDBYTE
-      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"unknown compression method";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"invalid window size";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      z->state->mode = FLAG;
-    case FLAG:
-      NEEDBYTE
-      b = NEXTBYTE;
-      if (((z->state->sub.method << 8) + b) % 31)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"incorrect header check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      Tracev((stderr, "inflate: zlib header ok\n"));
-      if (!(b & PRESET_DICT))
-      {
-        z->state->mode = BLOCKS;
-        break;
-      }
-      z->state->mode = DICT4;
-    case DICT4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = DICT3;
-    case DICT3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = DICT2;
-    case DICT2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = DICT1;
-    case DICT1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-      z->adler = z->state->sub.check.need;
-      z->state->mode = DICT0;
-      return Z_NEED_DICT;
-    case DICT0:
-      z->state->mode = BAD;
-      z->msg = (char*)"need dictionary";
-      z->state->sub.marker = 0;       /* can try inflateSync */
-      return Z_STREAM_ERROR;
-    case BLOCKS:
-      r = inflate_blocks(z->state->blocks, z, r);
-      if (r == Z_DATA_ERROR)
-      {
-        z->state->mode = BAD;
-        z->state->sub.marker = 0;       /* can try inflateSync */
-        break;
-      }
-      if (r == Z_OK)
-        r = f;
-      if (r != Z_STREAM_END)
-        return r;
-      r = f;
-      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-      if (z->state->nowrap)
-      {
-        z->state->mode = DONE;
-        break;
-      }
-      z->state->mode = CHECK4;
-    case CHECK4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = CHECK3;
-    case CHECK3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = CHECK2;
-    case CHECK2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = CHECK1;
-    case CHECK1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
+    /* get the state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
 
-      if (z->state->sub.check.was != z->state->sub.check.need)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"incorrect data check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
+    /* extract wrap request from windowBits parameter */
+    if (windowBits < 0) {
+        if (windowBits < -15)
+            return Z_STREAM_ERROR;
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        wrap = (windowBits >> 4) + 5;
+#ifdef GUNZIP
+        if (windowBits < 48)
+            windowBits &= 15;
+#endif
+    }
+
+    /* set number of window bits, free window if different */
+    if (windowBits && (windowBits < 8 || windowBits > 15))
+        return Z_STREAM_ERROR;
+    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+        ZFREE(strm, state->window);
+        state->window = Z_NULL;
+    }
+
+    /* update state and reset the rest of it */
+    state->wrap = wrap;
+    state->wbits = (unsigned)windowBits;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(
+    z_streamp strm,
+    int windowBits,
+    const char *version,
+    int stream_size)
+{
+    int ret;
+    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) 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->strm = strm;
+    state->window = Z_NULL;
+    state->mode = HEAD;     /* to pass state test in inflateReset2() */
+    ret = inflateReset2(strm, windowBits);
+    if (ret != Z_OK) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+    }
+    return ret;
+}
+
+#ifndef Z_FREETYPE
+
+int ZEXPORT inflateInit_(
+    z_streamp strm,
+    const char *version,
+    int stream_size)
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(
+    z_streamp strm,
+    int bits,
+    int value)
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits < 0) {
+        state->hold = 0;
+        state->bits = 0;
+        return Z_OK;
+    }
+    if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += (unsigned)value << state->bits;
+    state->bits += (uInt)bits;
+    return Z_OK;
+}
+
+#endif  /* !Z_FREETYPE */
+
+/*
+   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;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+               state.lencode[low].bits, state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(
+    z_streamp strm,
+    const Bytef *end,
+    unsigned copy)
+{
+    struct inflate_state FAR *state;
+    unsigned dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->wnext = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, end - state->wsize, state->wsize);
+        state->wnext = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->wnext;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->wnext, end - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, end - copy, copy);
+            state->wnext = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->wnext += dist;
+            if (state->wnext == state->wsize) state->wnext = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE_CHECK(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#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)
+
+/* Restore state from registers in inflate() */
+#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)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        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 inflate(). */
+#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)
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
         break;
-      }
-      Tracev((stderr, "inflate: zlib check ok\n"));
-      z->state->mode = DONE;
-    case DONE:
-      return Z_STREAM_END;
-    case BAD:
-      return Z_DATA_ERROR;
-    default:
-      return Z_STREAM_ERROR;
-  }
-#ifdef NEED_DUMMY_RETURN
-  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(
+    z_streamp strm,
+    int flush)
+{
+    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 in, out;           /* save starting available input and output */
+    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 */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    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};
+
+    if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                if (state->wbits == 0)
+                    state->wbits = 15;
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (state->wbits == 0)
+                state->wbits = len;
+            if (len > 15 || len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            state->flags = 0;               /* indicate zlib header */
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if ((state->flags & 0x0200) && (state->wrap & 4))
+                CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+                /* fallthrough */
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if ((state->flags & 0x0200) && (state->wrap & 4))
+                CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+                /* fallthrough */
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if ((state->flags & 0x0200) && (state->wrap & 4))
+                CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+                /* fallthrough */
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if ((state->flags & 0x0200) && (state->wrap & 4))
+                    CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+                /* fallthrough */
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL &&
+                        (len = state->head->extra_len - state->length) <
+                            state->head->extra_max) {
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if ((state->flags & 0x0200) && (state->wrap & 4))
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+                /* fallthrough */
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = (Bytef)len;
+                } while (len && copy < have);
+                if ((state->flags & 0x0200) && (state->wrap & 4))
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+                /* fallthrough */
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = (Bytef)len;
+                } while (len && copy < have);
+                if ((state->flags & 0x0200) && (state->wrap & 4))
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+                /* fallthrough */
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = ZSWAP32(hold);
+            INITBITS();
+            state->mode = DICT;
+                /* fallthrough */
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+                /* fallthrough */
+        case TYPE:
+            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+                /* fallthrough */
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                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 */
+                if (flush == Z_TREES) {
+                    DROPBITS(2);
+                    goto inf_leave;
+                }
+                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:
+            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();
+            state->mode = COPY_;
+            if (flush == Z_TREES) goto inf_leave;
+                /* fallthrough */
+        case COPY_:
+            state->mode = COPY;
+                /* fallthrough */
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            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"));
+            state->have = 0;
+            state->mode = LENLENS;
+                /* fallthrough */
+        case LENLENS:
+            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 = (const code 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"));
+            state->have = 0;
+            state->mode = CODELENS;
+                /* fallthrough */
+        case CODELENS:
+            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 = 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 = (const code 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 = (const code 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_;
+            if (flush == Z_TREES) goto inf_leave;
+                /* fallthrough */
+        case LEN_:
+            state->mode = LEN;
+                /* fallthrough */
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                if (state->mode == TYPE)
+                    state->back = -1;
+                break;
+            }
+            state->back = 0;
+            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);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            state->length = (unsigned)here.val;
+            if ((int)(here.op) == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                state->mode = LIT;
+                break;
+            }
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->back = -1;
+                state->mode = TYPE;
+                break;
+            }
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = LENEXT;
+                /* fallthrough */
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->was = state->length;
+            state->mode = DIST;
+                /* fallthrough */
+        case DIST:
+            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);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = DISTEXT;
+                /* fallthrough */
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+                /* fallthrough */
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->whave) {
+                    if (state->sane) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                    Trace((stderr, "inflate.c too far\n"));
+                    copy -= state->whave;
+                    if (copy > state->length) copy = state->length;
+                    if (copy > left) copy = left;
+                    left -= copy;
+                    state->length -= copy;
+                    do {
+                        *put++ = 0;
+                    } while (--copy);
+                    if (state->length == 0) state->mode = LEN;
+                    break;
+#endif
+                }
+                if (copy > state->wnext) {
+                    copy -= state->wnext;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->wnext - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if ((state->wrap & 4) && out)
+                    strm->adler = state->check =
+                        UPDATE_CHECK(state->check, put - out, out);
+                out = left;
+                if ((state->wrap & 4) && (
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     ZSWAP32(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+                /* fallthrough */
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+                /* fallthrough */
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+                /* fallthrough */
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+            (state->mode < CHECK || flush != Z_FINISH)))
+        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if ((state->wrap & 4) && out)
+        strm->adler = state->check =
+            UPDATE_CHECK(state->check, strm->next_out - out, out);
+    strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0) +
+                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(
+    z_streamp strm)
+{
+    struct inflate_state FAR *state;
+    if (inflateStateCheck(strm))
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+#ifndef Z_FREETYPE
+
+int ZEXPORT inflateGetDictionary(
+    z_streamp strm,
+    Bytef *dictionary,
+    uInt *dictLength)
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* copy dictionary */
+    if (state->whave && dictionary != Z_NULL) {
+        zmemcpy(dictionary, state->window + state->wnext,
+                state->whave - state->wnext);
+        zmemcpy(dictionary + state->whave - state->wnext,
+                state->window, state->wnext);
+    }
+    if (dictLength != Z_NULL)
+        *dictLength = state->whave;
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(
+    z_streamp strm,
+    const Bytef *dictionary,
+    uInt dictLength)
+{
+    struct inflate_state FAR *state;
+    unsigned long dictid;
+    int ret;
+
+    /* check state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary identifier */
+    if (state->mode == DICT) {
+        dictid = adler32(0L, Z_NULL, 0);
+        dictid = adler32(dictid, dictionary, dictLength);
+        if (dictid != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window using updatewindow(), which will amend the
+       existing dictionary if appropriate */
+    ret = updatewindow(strm, dictionary + dictLength, dictLength);
+    if (ret) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(
+    z_streamp strm,
+    gz_headerp head)
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(
+    unsigned FAR *have,
+    const unsigned char FAR *buf,
+    unsigned len)
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(
+    z_streamp strm)
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    int flags;                  /* temporary to save header status */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    if (state->flags == -1)
+        state->wrap = 0;    /* if no header yet, treat as raw */
+    else
+        state->wrap &= ~4;  /* no point in computing a check value now */
+    flags = state->flags;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->flags = flags;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(
+    z_streamp strm)
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(
+    z_streamp dest,
+    z_streamp source)
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (inflateStateCheck(source) || dest == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+    copy->strm = dest;
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(
+    z_streamp strm,
+    int subvert)
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+    state->sane = !subvert;
+    return Z_OK;
+#else
+    (void)subvert;
+    state->sane = 1;
+    return Z_DATA_ERROR;
 #endif
 }
 
+int ZEXPORT inflateValidate(
+    z_streamp strm,
+    int check)
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (check && state->wrap)
+        state->wrap |= 4;
+    else
+        state->wrap &= ~4;
+    return Z_OK;
+}
+
+long ZEXPORT inflateMark(
+    z_streamp strm)
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm))
+        return -(1L << 16);
+    state = (struct inflate_state FAR *)strm->state;
+    return (long)(((unsigned long)((long)state->back)) << 16) +
+        (state->mode == COPY ? state->length :
+            (state->mode == MATCH ? state->was - state->length : 0));
+}
+
+unsigned long ZEXPORT inflateCodesUsed(
+    z_streamp strm)
+{
+    struct inflate_state FAR *state;
+    if (inflateStateCheck(strm)) return (unsigned long)-1;
+    state = (struct inflate_state FAR *)strm->state;
+    return (unsigned long)(state->next - state->codes);
+}
+
+#endif  /* !Z_FREETYPE */
diff --git a/src/gzip/inflate.h b/src/gzip/inflate.h
new file mode 100644
index 0000000..c6f5a52
--- /dev/null
+++ b/src/gzip/inflate.h
@@ -0,0 +1,131 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2019 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef INFLATE_H
+#define INFLATE_H
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD = 16180,   /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY_,      /* i/o: same as COPY below, but only first time in */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN_,       /* i: same as LEN below, but only first time in */
+            LEN,        /* i: waiting for length/lit/eob code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib) or (raw)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+                  HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+        (raw) -> TYPEDO
+    Read deflate blocks:
+            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+            STORED -> COPY_ -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN_
+            LEN_ -> LEN
+    Read deflate codes in fixed or dynamic block:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* State maintained between inflate() calls -- approximately 7K bytes, not
+   including the allocated sliding window, which is up to 32K bytes. */
+struct inflate_state {
+    z_streamp strm;             /* pointer back to this zlib stream */
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip,
+                                   bit 2 true to validate check value */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags, 0 if zlib, or
+                                   -1 if raw or no header yet */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+    int sane;                   /* if false, allow invalid distance too far */
+    int back;                   /* bits back of last unprocessed length/lit */
+    unsigned was;               /* initial length of match */
+};
+
+#endif  /* INFLATE_H */
diff --git a/src/gzip/inftrees.c b/src/gzip/inftrees.c
index 56f52b1..dd4965e 100644
--- a/src/gzip/inftrees.c
+++ b/src/gzip/inftrees.c
@@ -1,20 +1,15 @@
 /* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2002 Mark Adler
+ * Copyright (C) 1995-2022 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 #include "zutil.h"
 #include "inftrees.h"
 
-#if !defined(BUILDFIXED) && !defined(STDC)
-#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
-#endif
+#define MAXBITS 15
 
-
-#if 0
-local const char inflate_copyright[] =
-   " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
-#endif
+static const char inflate_copyright[] =
+   " inflate 1.2.13 Copyright 1995-2022 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -22,447 +17,288 @@
   copyright string in the executable of your product.
  */
 
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
-    uIntf *,            /* code lengths in bits */
-    uInt,               /* number of codes */
-    uInt,               /* number of "simple" codes */
-    const uIntf *,      /* list of base values for non-simple codes */
-    const uIntf *,      /* list of extra bits for non-simple codes */
-    inflate_huft * FAR*,/* result: starting table */
-    uIntf *,            /* maximum lookup bits (returns actual) */
-    inflate_huft *,     /* space for trees */
-    uInt *,             /* hufts used in space */
-    uIntf * ));         /* space for values */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(
+    codetype type,
+    unsigned short FAR *lens,
+    unsigned codes,
+    code FAR * FAR *table,
+    unsigned FAR *bits,
+    unsigned short FAR *work)
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code here;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    unsigned match;             /* use base and extra for symbol >= match */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
         3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-        /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
-        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-        8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
-        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-        12, 12, 13, 13};
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
 
-/*
-   Huffman code decoding is performed using a multi-level table lookup.
-   The fastest way to decode is to simply build a lookup table whose
-   size is determined by the longest code.  However, the time it takes
-   to build this table can also be a factor if the data being decoded
-   is not very long.  The most common codes are necessarily the
-   shortest codes, so those codes dominate the decoding time, and hence
-   the speed.  The idea is you can have a shorter table that decodes the
-   shorter, more probable codes, and then point to subsidiary tables for
-   the longer codes.  The time it costs to decode the longer codes is
-   then traded against the time it takes to make longer tables.
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
 
-   This results of this trade are in the variables lbits and dbits
-   below.  lbits is the number of bits the first level table for literal/
-   length codes can decode in one step, and dbits is the same thing for
-   the distance codes.  Subsequent tables are also less than or equal to
-   those sizes.  These values may be adjusted either when all of the
-   codes are shorter than that, in which case the longest code length in
-   bits is used, or when the shortest code is *longer* than the requested
-   table size, in which case the length of the shortest code in bits is
-   used.
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
 
-   There are two different values for the two tables, since they code a
-   different number of possibilities each.  The literal/length table
-   codes 286 possible values, or in a flat code, a little over eight
-   bits.  The distance table codes 30 possible values, or a little less
-   than five bits, flat.  The optimum values for speed end up being
-   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-   The optimum values may differ though from machine to machine, and
-   possibly even between compilers.  Your mileage may vary.
- */
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
 
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
 
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15         /* maximum bit length of any code */
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
 
-local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */
-uIntf *b,               /* code lengths in bits (all assumed <= BMAX) */
-uInt n,                 /* number of codes (assumed <= 288) */
-uInt s,                 /* number of simple-valued codes (0..s-1) */
-const uIntf *d,         /* list of base values for non-simple codes */
-const uIntf *e,         /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t,  /* result: starting table */
-uIntf *m,               /* maximum lookup bits, returns actual */
-inflate_huft *hp,       /* space for trees */
-uInt *hn,               /* hufts used in space */
-uIntf *v                /* working area: values in order of bit length */
-/* Given a list of code lengths and a maximum table size, make a set of
-   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
-   if the given code set is incomplete (the tables are still built in this
-   case), or Z_DATA_ERROR if the input is invalid. */
-)
-{
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        here.op = (unsigned char)64;    /* invalid code marker */
+        here.bits = (unsigned char)1;
+        here.val = (unsigned short)0;
+        *(*table)++ = here;             /* make a table to force an error */
+        *(*table)++ = here;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min < max; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
 
-  uInt a;                       /* counter for codes of length k */
-  uInt c[BMAX+1];               /* bit length count table */
-  uInt f;                       /* i repeats in table every f entries */
-  int g;                        /* maximum code length */
-  int h;                        /* table level */
-  uInt i;                       /* counter, current code */
-  uInt j;                       /* counter */
-  int k;                        /* number of bits in current code */
-  int l;                        /* bits per table (returned in m) */
-  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
-  uIntf *p;                     /* pointer into c[], b[], or v[] */
-  inflate_huft *q;              /* points to current table */
-  struct inflate_huft_s r;      /* table entry for structure assignment */
-  inflate_huft *u[BMAX];        /* table stack */
-  int w;                        /* bits before this table == (l * h) */
-  uInt x[BMAX+1];               /* bit offsets, then code stack */
-  uIntf *xp;                    /* pointer into x */
-  int y;                        /* number of dummy codes added */
-  uInt z;                       /* number of entries in current table */
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
 
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
 
-  /* Make compiler happy */
-  r.base = 0;
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
 
-  /* Generate counts for each bit length */
-  p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
-  C4                            /* clear c[]--assume BMAX+1 is 16 */
-  p = b;  i = n;
-  do {
-    c[*p++]++;                  /* assume all entries <= BMAX */
-  } while (--i);
-  if (c[0] == n)                /* null input--all zero length codes */
-  {
-    *t = (inflate_huft *)Z_NULL;
-    *m = 0;
-    return Z_OK;
-  }
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
 
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
 
-  /* Find minimum and maximum length, bound *m by those */
-  l = *m;
-  for (j = 1; j <= BMAX; j++)
-    if (c[j])
-      break;
-  k = j;                        /* minimum code length */
-  if ((uInt)l < j)
-    l = j;
-  for (i = BMAX; i; i--)
-    if (c[i])
-      break;
-  g = i;                        /* maximum code length */
-  if ((uInt)l > i)
-    l = i;
-  *m = l;
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
 
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftrees.h
+       for more information.
 
-  /* Adjust last length count to fill out codes, if needed */
-  for (y = 1 << j; j < i; j++, y <<= 1)
-    if ((y -= c[j]) < 0)
-      return Z_DATA_ERROR;
-  if ((y -= c[i]) < 0)
-    return Z_DATA_ERROR;
-  c[i] += y;
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
 
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        match = 20;
+        break;
+    case LENS:
+        base = lbase;
+        extra = lext;
+        match = 257;
+        break;
+    default:    /* DISTS */
+        base = dbase;
+        extra = dext;
+        match = 0;
+    }
 
-  /* Generate starting offsets into the value table for each length */
-  x[1] = j = 0;
-  p = c + 1;  xp = x + 2;
-  while (--i) {                 /* note that i == g from above */
-    *xp++ = (j += *p++);
-  }
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
 
+    /* check available table space */
+    if ((type == LENS && used > ENOUGH_LENS) ||
+        (type == DISTS && used > ENOUGH_DISTS))
+        return 1;
 
-  /* Make a table of values in order of bit lengths */
-  p = b;  i = 0;
-  do {
-    if ((j = *p++) != 0)
-      v[x[j]++] = i;
-  } while (++i < n);
-  n = x[g];                     /* set n to length of v */
-
-
-  /* Generate the Huffman codes and for each, make the table entries */
-  x[0] = i = 0;                 /* first Huffman code is zero */
-  p = v;                        /* grab values in bit order */
-  h = -1;                       /* no tables yet--level -1 */
-  w = -l;                       /* bits decoded == (l * h) */
-  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
-  q = (inflate_huft *)Z_NULL;   /* ditto */
-  z = 0;                        /* ditto */
-
-  /* go through the bit lengths (k already is bits in shortest code) */
-  for (; k <= g; k++)
-  {
-    a = c[k];
-    while (a--)
-    {
-      /* here i is the Huffman code of length k bits for value *p */
-      /* make tables up to required level */
-      while (k > w + l)
-      {
-        h++;
-        w += l;                 /* previous table always l bits */
-
-        /* compute minimum size table less than or equal to l bits */
-        z = g - w;
-        z = z > (uInt)l ? (uInt)l : z;        /* table size upper limit */
-        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
-        {                       /* too few codes for k-w bit table */
-          f -= a + 1;           /* deduct codes from patterns left */
-          xp = c + k;
-          if (j < z)
-            while (++j < z)     /* try smaller tables up to z bits */
-            {
-              if ((f <<= 1) <= *++xp)
-                break;          /* enough codes to use up j bits */
-              f -= *xp;         /* else deduct codes from patterns */
-            }
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        here.bits = (unsigned char)(len - drop);
+        if (work[sym] + 1U < match) {
+            here.op = (unsigned char)0;
+            here.val = work[sym];
         }
-        z = 1 << j;             /* table entries for j-bit table */
+        else if (work[sym] >= match) {
+            here.op = (unsigned char)(extra[work[sym] - match]);
+            here.val = base[work[sym] - match];
+        }
+        else {
+            here.op = (unsigned char)(32 + 64);         /* end of block */
+            here.val = 0;
+        }
 
-        /* allocate new table */
-        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
-          return Z_DATA_ERROR;  /* overflow of MANY */
-        u[h] = q = hp + *hn;
-        *hn += z;
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = here;
+        } while (fill != 0);
 
-        /* connect to last table, if there is one */
-        if (h)
-        {
-          x[h] = i;             /* save pattern for backing up */
-          r.bits = (Byte)l;     /* bits to dump before this table */
-          r.exop = (Byte)j;     /* bits in this table */
-          j = i >> (w - l);
-          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
-          u[h-1][j] = r;        /* connect to last table */
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
         }
         else
-          *t = q;               /* first table is returned result */
-      }
+            huff = 0;
 
-      /* set up table entry in r */
-      r.bits = (Byte)(k - w);
-      if (p >= v + n)
-        r.exop = 128 + 64;      /* out of values--invalid code */
-      else if (*p < s)
-      {
-        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
-        r.base = *p++;          /* simple code is just the value */
-      }
-      else
-      {
-        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
-        r.base = d[*p++ - s];
-      }
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
 
-      /* fill code-like entries with r */
-      f = 1 << (k - w);
-      for (j = i >> w; j < z; j += f)
-        q[j] = r;
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
 
-      /* backwards increment the k-bit code i */
-      for (j = 1 << (k - 1); i & j; j >>= 1)
-        i ^= j;
-      i ^= j;
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
 
-      /* backup over finished tables */
-      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
-      while ((i & mask) != x[h])
-      {
-        h--;                    /* don't need to update q */
-        w -= l;
-        mask = (1 << w) - 1;
-      }
-    }
-  }
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
 
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used > ENOUGH_LENS) ||
+                (type == DISTS && used > ENOUGH_DISTS))
+                return 1;
 
-  /* Return Z_BUF_ERROR if we were given an incomplete table */
-  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-local int inflate_trees_bits( /* c, bb, tb, hp, z) */
-uIntf *c,               /* 19 code lengths */
-uIntf *bb,              /* bits tree desired/actual depth */
-inflate_huft * FAR *tb, /* bits tree result */
-inflate_huft *hp,       /* space for trees */
-z_streamp z             /* for messages */
-)
-{
-  int r;
-  uInt hn = 0;          /* hufts used in space */
-  uIntf *v;             /* work area for huft_build */
-
-  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
-    return Z_MEM_ERROR;
-  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
-                 tb, bb, hp, &hn, v);
-  if (r == Z_DATA_ERROR)
-    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
-  else if (r == Z_BUF_ERROR || *bb == 0)
-  {
-    z->msg = (char*)"incomplete dynamic bit lengths tree";
-    r = Z_DATA_ERROR;
-  }
-  ZFREE(z, v);
-  return r;
-}
-
-
-local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */
-uInt nl,                /* number of literal/length codes */
-uInt nd,                /* number of distance codes */
-uIntf *c,               /* that many (total) code lengths */
-uIntf *bl,              /* literal desired/actual bit depth */
-uIntf *bd,              /* distance desired/actual bit depth */
-inflate_huft * FAR *tl, /* literal/length tree result */
-inflate_huft * FAR *td, /* distance tree result */
-inflate_huft *hp,       /* space for trees */
-z_streamp z             /* for messages */
-)
-{
-  int r;
-  uInt hn = 0;          /* hufts used in space */
-  uIntf *v;             /* work area for huft_build */
-
-  /* allocate work area */
-  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-    return Z_MEM_ERROR;
-
-  /* build literal/length tree */
-  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
-  if (r != Z_OK || *bl == 0)
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed literal/length tree";
-    else if (r != Z_MEM_ERROR)
-    {
-      z->msg = (char*)"incomplete literal/length tree";
-      r = Z_DATA_ERROR;
-    }
-    ZFREE(z, v);
-    return r;
-  }
-
-  /* build distance tree */
-  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
-  if (r != Z_OK || (*bd == 0 && nl > 257))
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed distance tree";
-    else if (r == Z_BUF_ERROR) {
-#if 0
-    {
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
-      r = Z_OK;
-    }
-#else
-      z->msg = (char*)"incomplete distance tree";
-      r = Z_DATA_ERROR;
-    }
-    else if (r != Z_MEM_ERROR)
-    {
-      z->msg = (char*)"empty distance tree with lengths";
-      r = Z_DATA_ERROR;
-    }
-    ZFREE(z, v);
-    return r;
-#endif
-  }
-
-  /* done */
-  ZFREE(z, v);
-  return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-#ifdef BUILDFIXED
-local int fixed_built = 0;
-#define FIXEDH 544      /* number of hufts used by fixed tables */
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-#else
-#include "inffixed.h"
-#endif
-
-
-local int inflate_trees_fixed( /* bl, bd, tl, td, z) */
-uIntf *bl,                      /* literal desired/actual bit depth */
-uIntf *bd,                      /* distance desired/actual bit depth */
-const inflate_huft * FAR *tl,   /* literal/length tree result */
-const inflate_huft * FAR *td,   /* distance tree result */
-z_streamp z                     /* for memory allocation */
-)
-{
-#ifdef BUILDFIXED
-  /* build fixed tables if not already */
-  if (!fixed_built)
-  {
-    int k;              /* temporary variable */
-    uInt f = 0;         /* number of hufts used in fixed_mem */
-    uIntf *c;           /* length list for huft_build */
-    uIntf *v;           /* work area for huft_build */
-
-    /* allocate memory */
-    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-      return Z_MEM_ERROR;
-    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-    {
-      ZFREE(z, c);
-      return Z_MEM_ERROR;
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
     }
 
-    /* literal table */
-    for (k = 0; k < 144; k++)
-      c[k] = 8;
-    for (; k < 256; k++)
-      c[k] = 9;
-    for (; k < 280; k++)
-      c[k] = 7;
-    for (; k < 288; k++)
-      c[k] = 8;
-    fixed_bl = 9;
-    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
-               fixed_mem, &f, v);
+    /* fill in remaining table entry if code is incomplete (guaranteed to have
+       at most one remaining entry, since if the code is incomplete, the
+       maximum code length that was allowed to get this far is one bit) */
+    if (huff != 0) {
+        here.op = (unsigned char)64;            /* invalid code marker */
+        here.bits = (unsigned char)(len - drop);
+        here.val = (unsigned short)0;
+        next[huff] = here;
+    }
 
-    /* distance table */
-    for (k = 0; k < 30; k++)
-      c[k] = 5;
-    fixed_bd = 5;
-    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
-               fixed_mem, &f, v);
-
-    /* done */
-    ZFREE(z, v);
-    ZFREE(z, c);
-    fixed_built = 1;
-  }
-#else
-  FT_UNUSED(z);
-#endif
-  *bl = fixed_bl;
-  *bd = fixed_bd;
-  *tl = fixed_tl;
-  *td = fixed_td;
-  return Z_OK;
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
 }
diff --git a/src/gzip/inftrees.h b/src/gzip/inftrees.h
index 07bf2aa..a2207ef 100644
--- a/src/gzip/inftrees.h
+++ b/src/gzip/inftrees.h
@@ -1,63 +1,67 @@
 /* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2002 Mark Adler
+ * Copyright (C) 1995-2005, 2010 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
+#ifndef INFTREES_H
+#define INFTREES_H
+
 /* WARNING: this file should *not* be used by applications. It is
    part of the implementation of the compression library and is
    subject to change. Applications should only use zlib.h.
  */
 
-/* Huffman code lookup table entry--this entry is four bytes for machines
-   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
 
-#ifndef _INFTREES_H
-#define _INFTREES_H
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
 
-typedef struct inflate_huft_s FAR inflate_huft;
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1444, which is the sum of 852 for literal/length codes and 592 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in inflate.c and infback.c.  If the root table size is
+   changed, then these maximum sizes would be need to be recalculated and
+   updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
 
-struct inflate_huft_s {
-  union {
-    struct {
-      Byte Exop;        /* number of extra bits or operation */
-      Byte Bits;        /* number of bits in this code or subcode */
-    } what;
-    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
-  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
-  uInt base;            /* literal, length base, distance base,
-                           or table offset */
-};
+/* Type of code to build for inflate_table() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
 
-/* Maximum size of dynamic tree.  The maximum found in a long but non-
-   exhaustive search was 1004 huft structures (850 for length/literals
-   and 154 for distances, the latter actually the result of an
-   exhaustive search).  The actual maximum is not known, but the
-   value below is more than safe. */
-#define MANY 1440
+static int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
 
-local  int inflate_trees_bits OF((
-    uIntf *,                    /* 19 code lengths */
-    uIntf *,                    /* bits tree desired/actual depth */
-    inflate_huft * FAR *,       /* bits tree result */
-    inflate_huft *,             /* space for trees */
-    z_streamp));                /* for messages */
-
-local  int inflate_trees_dynamic OF((
-    uInt,                       /* number of literal/length codes */
-    uInt,                       /* number of distance codes */
-    uIntf *,                    /* that many (total) code lengths */
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
-    inflate_huft *,             /* space for trees */
-    z_streamp));                /* for messages */
-
-local  int inflate_trees_fixed OF((
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    const inflate_huft * FAR *, /* literal/length tree result */
-    const inflate_huft * FAR *, /* distance tree result */
-    z_streamp));                /* for memory allocation */
-
-#endif /* _INFTREES_H */
+#endif  /* INFTREES_H_ */
diff --git a/src/gzip/infutil.c b/src/gzip/infutil.c
deleted file mode 100644
index 6087b40..0000000
--- a/src/gzip/infutil.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-
-/* And'ing with mask[n] masks the lower n bits */
-local const uInt inflate_mask[17] = {
-    0x0000,
-    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush( /* s, z, r) */
-inflate_blocks_statef *s,
-z_streamp z,
-int r )
-{
-  uInt n;
-  Bytef *p;
-  Bytef *q;
-
-  /* local copies of source and destination pointers */
-  p = z->next_out;
-  q = s->read;
-
-  /* compute number of bytes to copy as far as end of window */
-  n = (uInt)((q <= s->write ? s->write : s->end) - q);
-  if (n > z->avail_out) n = z->avail_out;
-  if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-  /* update counters */
-  z->avail_out -= n;
-  z->total_out += n;
-
-  /* update check information */
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-  /* copy as far as end of window */
-  zmemcpy(p, q, n);
-  p += n;
-  q += n;
-
-  /* see if more to copy at beginning of window */
-  if (q == s->end)
-  {
-    /* wrap pointers */
-    q = s->window;
-    if (s->write == s->end)
-      s->write = s->window;
-
-    /* compute bytes to copy */
-    n = (uInt)(s->write - q);
-    if (n > z->avail_out) n = z->avail_out;
-    if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-    /* update counters */
-    z->avail_out -= n;
-    z->total_out += n;
-
-    /* update check information */
-    if (s->checkfn != Z_NULL)
-      z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-    /* copy */
-    zmemcpy(p, q, n);
-    p += n;
-    q += n;
-  }
-
-  /* update pointers */
-  z->next_out = p;
-  s->read = q;
-
-  /* done */
-  return r;
-}
diff --git a/src/gzip/infutil.h b/src/gzip/infutil.h
deleted file mode 100644
index 7174b6d..0000000
--- a/src/gzip/infutil.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-typedef enum {
-      TYPE,     /* get type bits (3, including end bit) */
-      LENS,     /* get lengths for stored */
-      STORED,   /* processing stored block */
-      TABLE,    /* get table lengths */
-      BTREE,    /* get bit lengths tree for a dynamic block */
-      DTREE,    /* get length, distance trees for a dynamic block */
-      CODES,    /* processing fixed or dynamic block */
-      DRY,      /* output remaining window bytes */
-      DONE,     /* finished last block, done */
-      BAD}      /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
-  /* mode */
-  inflate_block_mode  mode;     /* current inflate_block mode */
-
-  /* mode dependent information */
-  union {
-    uInt left;          /* if STORED, bytes left to copy */
-    struct {
-      uInt table;               /* table lengths (14 bits) */
-      uInt index;               /* index into blens (or border) */
-      uIntf *blens;             /* bit lengths of codes */
-      uInt bb;                  /* bit length tree depth */
-      inflate_huft *tb;         /* bit length decoding tree */
-    } trees;            /* if DTREE, decoding info for trees */
-    struct {
-      inflate_codes_statef
-         *codes;
-    } decode;           /* if CODES, current state */
-  } sub;                /* submode */
-  uInt last;            /* true if this block is the last block */
-
-  /* mode independent information */
-  uInt bitk;            /* bits in bit buffer */
-  uLong bitb;           /* bit buffer */
-  inflate_huft *hufts;  /* single malloc for tree space */
-  Bytef *window;        /* sliding window */
-  Bytef *end;           /* one byte after sliding window */
-  Bytef *read;          /* window read pointer */
-  Bytef *write;         /* window write pointer */
-  check_func checkfn;   /* check function */
-  uLong check;          /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/*   update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/*   get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/*   output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/*   load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-#ifndef NO_INFLATE_MASK
-local uInt inflate_mask[17];
-#endif
-
-/* copy as much as possible from the sliding window to the output area */
-local int inflate_flush OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-#endif
diff --git a/src/gzip/patches/freetype-zlib.diff b/src/gzip/patches/freetype-zlib.diff
new file mode 100644
index 0000000..6ac76df
--- /dev/null
+++ b/src/gzip/patches/freetype-zlib.diff
@@ -0,0 +1,469 @@
+[zlib] Fix zlib sources for compilation with FreeType
+
+We must ensure that they do not issue compiler errors or warnings when they
+are compiled as part of `src/gzip/ftgzip.c`.
+
+* src/gzip/gzguts.h (COPY): Rename to...
+(COPY__): ... this since `COPY` and `COPY_` conflict with enum values,
+which have the same name in `zlib.h`.
+
+* src/gzip/inflate.c, src/gzip/adler32.c, src/gzip/crc32.c,
+src/gzip/zutil.c: Omit unused function declarations and definitions when
+`Z_FREETYPE` is defined.
+
+* src/gzip/inffast.h (inflate_fast): Declare as static.
+
+* src/gzip/inftrees.c (inflate_copyright): Declare as static.
+
+* src/gzip/zlib.h: Include `ftzconf.h` instead of `zconf.h` to avoid
+conflicts with system-installed headers.
+Omit unused function declarations when `Z_FREETYPE` is defined.
+(inflateInit2)[Z_FREETYPE]: Provide proper declaration.
+
+* src/gzip/zutil.h: Use `ft_memxxx` functions instead of `memxxx`.
+Omit unused function declarations when `Z_FREETYPE` is defined.
+
+* src/gzip/inflate.h, src/gzip/inftrees.h: Add header guard macros to
+prevent compiler errors.
+
+* src/gzip/inftrees.h: Add header guard macros to prevent compiler errors.
+(inflate_table): Declare as static.
+
+diff --git b/src/gzip/adler32.c a/src/gzip/adler32.c
+index be5e8a247..aa032e1dd 100644
+--- b/src/gzip/adler32.c
++++ a/src/gzip/adler32.c
+@@ -7,7 +7,9 @@
+ 
+ #include "zutil.h"
+ 
++#ifndef Z_FREETYPE
+ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
++#endif
+ 
+ #define BASE 65521U     /* largest prime smaller than 65536 */
+ #define NMAX 5552
+@@ -139,6 +141,8 @@ uLong ZEXPORT adler32(
+     return adler32_z(adler, buf, len);
+ }
+ 
++#ifndef Z_FREETYPE
++
+ /* ========================================================================= */
+ local uLong adler32_combine_(
+     uLong adler1,
+@@ -184,3 +188,5 @@ uLong ZEXPORT adler32_combine64(
+ {
+     return adler32_combine_(adler1, adler2, len2);
+ }
++
++#endif  /* !Z_FREETYPE */
+diff --git b/src/gzip/crc32.c a/src/gzip/crc32.c
+index 3a52aa89d..6cd1b09d5 100644
+--- b/src/gzip/crc32.c
++++ a/src/gzip/crc32.c
+@@ -103,9 +103,11 @@
+ #  define ARMCRC32
+ #endif
+ 
++#ifndef Z_FREETYPE
+ /* Local functions. */
+ local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
+ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
++#endif  /* Z_FREETYPE */
+ 
+ #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
+     local z_word_t byte_swap OF((z_word_t word));
+@@ -544,6 +546,8 @@ local void braid(ltl, big, n, w)
+  * generation above.
+  */
+ 
++#ifndef Z_FREETYPE
++
+ /*
+   Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
+   reflected. For speed, this requires that a not be zero.
+@@ -600,6 +604,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table()
+     return (const z_crc_t FAR *)crc_table;
+ }
+ 
++#endif  /* Z_FREETYPE */
++
+ /* =========================================================================
+  * Use ARM machine instructions if available. This will compute the CRC about
+  * ten times faster than the braided calculation. This code does not check for
+@@ -1077,6 +1083,8 @@ unsigned long ZEXPORT crc32(
+     return crc32_z(crc, buf, len);
+ }
+ 
++#ifndef Z_FREETYPE
++
+ /* ========================================================================= */
+ uLong ZEXPORT crc32_combine64(
+     uLong crc1,
+@@ -1123,3 +1131,5 @@ uLong ZEXPORT crc32_combine_op(
+ {
+     return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
+ }
++
++#endif  /* Z_FREETYPE */
+diff --git b/src/gzip/gzguts.h a/src/gzip/gzguts.h
+index 57faf3716..4f09a52a7 100644
+--- b/src/gzip/gzguts.h
++++ a/src/gzip/gzguts.h
+@@ -163,7 +163,7 @@
+ 
+ /* values for gz_state how */
+ #define LOOK 0      /* look for a gzip header */
+-#define COPY 1      /* copy input directly */
++#define COPY__ 1    /* copy input directly */
+ #define GZIP 2      /* decompress a gzip stream */
+ 
+ /* internal gzip file state data structure */
+diff --git b/src/gzip/inffast.h a/src/gzip/inffast.h
+index e5c1aa4ca..684ae878c 100644
+--- b/src/gzip/inffast.h
++++ a/src/gzip/inffast.h
+@@ -8,4 +8,4 @@
+    subject to change. Applications should only use zlib.h.
+  */
+ 
+-void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
++static void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
+diff --git b/src/gzip/inflate.c a/src/gzip/inflate.c
+index c9e566b03..5117e2e26 100644
+--- b/src/gzip/inflate.c
++++ a/src/gzip/inflate.c
+@@ -99,8 +99,10 @@ local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ #ifdef BUILDFIXED
+    void makefixed OF((void));
+ #endif
++#ifndef Z_FREETYPE
+ local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+                               unsigned len));
++#endif
+ 
+ local int inflateStateCheck(
+     z_streamp strm)
+@@ -239,6 +241,8 @@ int ZEXPORT inflateInit2_(
+     return ret;
+ }
+ 
++#ifndef Z_FREETYPE
++
+ int ZEXPORT inflateInit_(
+     z_streamp strm,
+     const char *version,
+@@ -268,6 +272,8 @@ int ZEXPORT inflatePrime(
+     return Z_OK;
+ }
+ 
++#endif  /* !Z_FREETYPE */
++
+ /*
+    Return state with length and distance decoding tables and index sizes set to
+    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+@@ -1315,6 +1321,8 @@ int ZEXPORT inflateEnd(
+     return Z_OK;
+ }
+ 
++#ifndef Z_FREETYPE
++
+ int ZEXPORT inflateGetDictionary(
+     z_streamp strm,
+     Bytef *dictionary,
+@@ -1593,3 +1601,5 @@ unsigned long ZEXPORT inflateCodesUsed(
+     state = (struct inflate_state FAR *)strm->state;
+     return (unsigned long)(state->next - state->codes);
+ }
++
++#endif  /* !Z_FREETYPE */
+diff --git b/src/gzip/inflate.h a/src/gzip/inflate.h
+index f127b6b1f..c6f5a52e1 100644
+--- b/src/gzip/inflate.h
++++ a/src/gzip/inflate.h
+@@ -3,6 +3,9 @@
+  * For conditions of distribution and use, see copyright notice in zlib.h
+  */
+ 
++#ifndef INFLATE_H
++#define INFLATE_H
++
+ /* WARNING: this file should *not* be used by applications. It is
+    part of the implementation of the compression library and is
+    subject to change. Applications should only use zlib.h.
+@@ -124,3 +127,5 @@ struct inflate_state {
+     int back;                   /* bits back of last unprocessed length/lit */
+     unsigned was;               /* initial length of match */
+ };
++
++#endif  /* INFLATE_H */
+diff --git b/src/gzip/inftrees.c a/src/gzip/inftrees.c
+index d8405a24c..dd4965e9a 100644
+--- b/src/gzip/inftrees.c
++++ a/src/gzip/inftrees.c
+@@ -8,7 +8,7 @@
+ 
+ #define MAXBITS 15
+ 
+-const char inflate_copyright[] =
++static const char inflate_copyright[] =
+    " inflate 1.2.13 Copyright 1995-2022 Mark Adler ";
+ /*
+   If you use the zlib library in a product, an acknowledgment is welcome
+diff --git b/src/gzip/inftrees.h a/src/gzip/inftrees.h
+index f53665311..a2207efb1 100644
+--- b/src/gzip/inftrees.h
++++ a/src/gzip/inftrees.h
+@@ -3,6 +3,9 @@
+  * For conditions of distribution and use, see copyright notice in zlib.h
+  */
+ 
++#ifndef INFTREES_H
++#define INFTREES_H
++
+ /* WARNING: this file should *not* be used by applications. It is
+    part of the implementation of the compression library and is
+    subject to change. Applications should only use zlib.h.
+@@ -57,6 +60,8 @@ typedef enum {
+     DISTS
+ } codetype;
+ 
+-int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
++static int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                              unsigned codes, code FAR * FAR *table,
+                              unsigned FAR *bits, unsigned short FAR *work));
++
++#endif  /* INFTREES_H_ */
+diff --git b/src/gzip/zlib.h a/src/gzip/zlib.h
+index 953cb5012..3f2f76e3c 100644
+--- b/src/gzip/zlib.h
++++ a/src/gzip/zlib.h
+@@ -31,7 +31,7 @@
+ #ifndef ZLIB_H
+ #define ZLIB_H
+ 
+-#include "zconf.h"
++#include "ftzconf.h"
+ 
+ #ifdef __cplusplus
+ extern "C" {
+@@ -211,6 +211,8 @@ typedef gz_header FAR *gz_headerp;
+ 
+ #define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+ 
++#ifndef Z_FREETYPE
++
+ #define zlib_version zlibVersion()
+ /* for compatibility with versions < 1.0.2 */
+ 
+@@ -373,6 +375,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+    deallocated).
+ */
+ 
++#endif  /* !Z_FREETYPE */
+ 
+ /*
+ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+@@ -534,6 +537,8 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+     The following functions are needed only in some special applications.
+ */
+ 
++#ifndef Z_FREETYPE
++
+ /*
+ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                      int  level,
+@@ -956,6 +961,8 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+    destination.
+ */
+ 
++#endif  /* !Z_FREETYPE */
++
+ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+ /*
+      This function is equivalent to inflateEnd followed by inflateInit,
+@@ -980,6 +987,8 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+    the windowBits parameter is invalid.
+ */
+ 
++#ifndef Z_FREETYPE
++
+ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                      int bits,
+                                      int value));
+@@ -1069,6 +1078,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+    stream state was inconsistent.
+ */
+ 
++#endif  /* !Z_FREETYPE */
++
+ /*
+ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window));
+@@ -1095,6 +1106,8 @@ typedef unsigned (*in_func) OF((void FAR *,
+                                 z_const unsigned char FAR * FAR *));
+ typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+ 
++#ifndef Z_FREETYPE
++
+ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                     in_func in, void FAR *in_desc,
+                                     out_func out, void FAR *out_desc));
+@@ -1214,6 +1227,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+      27-31: 0 (reserved)
+  */
+ 
++#endif  /* !Z_FREETYPE */
++
+ #ifndef Z_SOLO
+ 
+                         /* utility functions */
+@@ -1765,6 +1780,8 @@ ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
+    crc32_combine_op().
+ */
+ 
++#ifndef Z_FREETYPE
++
+ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
+ /*
+      Give the same result as crc32_combine(), using op in place of len2. op is
+@@ -1822,6 +1839,19 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                            ZLIB_VERSION, (int)sizeof(z_stream))
+ #endif
+ 
++#else  /* Z_FREETYPE */
++
++
++ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
++                                      const char *version, int stream_size));
++
++#  define inflateInit2(strm, windowBits) \
++          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
++                        (int)sizeof(z_stream))
++
++#endif  /* Z_FREETYPE */
++
++
+ #ifndef Z_SOLO
+ 
+ /* gzgetc() macro and its supporting function and exposed data structure.  Note
+@@ -1901,20 +1931,25 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+ 
+ #else /* Z_SOLO */
+ 
++#ifndef Z_FREETYPE
+    ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
++#endif
+ 
+ #endif /* !Z_SOLO */
+ 
+ /* undocumented functions */
++#ifndef Z_FREETYPE
+ ZEXTERN const char   * ZEXPORT zError           OF((int));
+ ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
+ ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ ZEXTERN int            ZEXPORT inflateValidate OF((z_streamp, int));
+ ZEXTERN unsigned long  ZEXPORT inflateCodesUsed OF((z_streamp));
++#endif  /* !Z_FREETYPE */
+ ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
++#ifndef Z_FREETYPE
+ ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+ #if defined(_WIN32) && !defined(Z_SOLO)
+ ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
+@@ -1927,6 +1962,7 @@ ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                   va_list va));
+ #  endif
+ #endif
++#endif  /* !Z_FREETYPE */
+ 
+ #ifdef __cplusplus
+ }
+diff --git b/src/gzip/zutil.c a/src/gzip/zutil.c
+index ef174ca64..542706ca0 100644
+--- b/src/gzip/zutil.c
++++ a/src/gzip/zutil.c
+@@ -10,6 +10,8 @@
+ #  include "gzguts.h"
+ #endif
+ 
++#ifndef Z_FREETYPE
++
+ z_const char * const z_errmsg[10] = {
+     (z_const char *)"need dictionary",     /* Z_NEED_DICT       2  */
+     (z_const char *)"stream end",          /* Z_STREAM_END      1  */
+@@ -138,6 +140,8 @@ const char * ZEXPORT zError(
+     return ERR_MSG(err);
+ }
+ 
++#endif  /* !Z_FREETYPE */
++
+ #if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
+     /* The older Microsoft C Run-Time Library for Windows CE doesn't have
+      * errno.  We define it as a global variable to simplify porting.
+@@ -159,6 +163,8 @@ void ZLIB_INTERNAL zmemcpy(
+     } while (--len != 0);
+ }
+ 
++#ifndef Z_FREETYPE
++
+ int ZLIB_INTERNAL zmemcmp(
+     const Bytef* s1,
+     const Bytef* s2,
+@@ -181,6 +187,7 @@ void ZLIB_INTERNAL zmemzero(
+         *dest++ = 0;  /* ??? to be unrolled */
+     } while (--len != 0);
+ }
++#endif  /* !Z_FREETYPE */
+ #endif
+ 
+ #ifndef Z_SOLO
+diff --git b/src/gzip/zutil.h a/src/gzip/zutil.h
+index 0bc7f4ecd..055ba8b62 100644
+--- b/src/gzip/zutil.h
++++ a/src/gzip/zutil.h
+@@ -53,8 +53,10 @@ typedef unsigned long  ulg;
+ #  endif
+ #endif
+ 
++#ifndef Z_FREETYPE
+ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+ /* (size given to avoid silly warnings with Visual C++) */
++#endif  /* !Z_FREETYPE */
+ 
+ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+ 
+@@ -188,6 +190,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+   #pragma warn -8066
+ #endif
+ 
++#ifndef Z_FREETYPE
++
+ /* provide prototypes for these when building zlib without LFS */
+ #if !defined(_WIN32) && \
+     (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+@@ -196,6 +200,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+     ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
+ #endif
+ 
++#endif  /* !Z_FREETYPE */
++
+         /* common defaults */
+ 
+ #ifndef OS_CODE
+@@ -227,9 +233,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+ #    define zmemcmp _fmemcmp
+ #    define zmemzero(dest, len) _fmemset(dest, 0, len)
+ #  else
+-#    define zmemcpy memcpy
+-#    define zmemcmp memcmp
+-#    define zmemzero(dest, len) memset(dest, 0, len)
++#    define zmemcpy ft_memcpy
++#    define zmemcmp ft_memcmp
++#    define zmemzero(dest, len) ft_memset(dest, 0, len)
+ #  endif
+ #else
+    void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
diff --git a/src/gzip/rules.mk b/src/gzip/rules.mk
index 1a2e48b..6feb6f5 100644
--- a/src/gzip/rules.mk
+++ b/src/gzip/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -40,17 +40,17 @@
 # unconditionally.
 #
 GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c  \
+                 $(GZIP_DIR)/crc32.c    \
+                 $(GZIP_DIR)/crc32.h    \
                  $(GZIP_DIR)/ftzconf.h  \
-                 $(GZIP_DIR)/infblock.c \
-                 $(GZIP_DIR)/infblock.h \
-                 $(GZIP_DIR)/infcodes.c \
-                 $(GZIP_DIR)/infcodes.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)/infutil.c  \
-                 $(GZIP_DIR)/infutil.h  \
                  $(GZIP_DIR)/zlib.h     \
                  $(GZIP_DIR)/zutil.c    \
                  $(GZIP_DIR)/zutil.h
diff --git a/src/gzip/zlib.h b/src/gzip/zlib.h
index a4e82c6..3f2f76e 100644
--- a/src/gzip/zlib.h
+++ b/src/gzip/zlib.h
@@ -1,7 +1,7 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.1.4, March 11th, 2002
+  version 1.2.13, October 13th, 2022
 
-  Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,12 +24,12 @@
 
 
   The data format used by the zlib library is described by RFCs (Request for
-  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
 */
 
-#ifndef _ZLIB_H
-#define _ZLIB_H
+#ifndef ZLIB_H
+#define ZLIB_H
 
 #include "ftzconf.h"
 
@@ -37,27 +37,45 @@
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.1.4"
+#define ZLIB_VERSION "1.2.13"
+#define ZLIB_VERNUM 0x12d0
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 13
+#define ZLIB_VER_SUBREVISION 0
 
 /*
-     The 'zlib' compression library provides in-memory compression and
-  decompression functions, including integrity checks of the uncompressed
-  data.  This version of the library supports only one compression method
-  (deflation) but other algorithms will be added later and will have the same
-  stream interface.
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
 
-     Compression can be done in a single step if the buffers are large
-  enough (for example if an input file is mmap'ed), or can be done by
-  repeated calls of the compression function.  In the latter case, the
-  application must provide more input and/or consume the output
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
   (providing more output space) before each call.
 
-     The library also supports reading and writing files in gzip (.gz) format
-  with an interface similar to that of stdio.
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
 
-     The library does not install any signal handler. The decoder checks
-  the consistency of the compressed data, so the library should never
-  crash even in case of corrupted input.
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip and raw deflate streams in
+  memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in the case of corrupted input.
 */
 
 typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
@@ -66,68 +84,95 @@
 struct internal_state;
 
 typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
+    z_const Bytef *next_in;     /* next input byte */
     uInt     avail_in;  /* number of bytes available at next_in */
-    uLong    total_in;  /* total nb of input bytes read so far */
+    uLong    total_in;  /* total number of input bytes read so far */
 
-    Bytef    *next_out; /* next output byte should be put there */
+    Bytef    *next_out; /* next output byte will go here */
     uInt     avail_out; /* remaining free space at next_out */
-    uLong    total_out; /* total nb of bytes output so far */
+    uLong    total_out; /* total number of bytes output so far */
 
-    char     *msg;      /* last error message, NULL if no error */
+    z_const char *msg;  /* last error message, NULL if no error */
     struct internal_state FAR *state; /* not visible by applications */
 
     alloc_func zalloc;  /* used to allocate the internal state */
     free_func  zfree;   /* used to free the internal state */
     voidpf     opaque;  /* private data object passed to zalloc and zfree */
 
-    int     data_type;  /* best guess about the data type: ascii or binary */
-    uLong   adler;      /* adler32 value of the uncompressed data */
+    int     data_type;  /* best guess about the data type: binary or text
+                           for deflate, or the decoding state for inflate */
+    uLong   adler;      /* Adler-32 or CRC-32 value of the uncompressed data */
     uLong   reserved;   /* reserved for future use */
 } z_stream;
 
 typedef z_stream FAR *z_streamp;
 
 /*
-   The application must update next_in and avail_in when avail_in has
-   dropped to zero. It must update next_out and avail_out when avail_out
-   has dropped to zero. The application must initialize zalloc, zfree and
-   opaque before calling the init function. All other fields are set by the
-   compression library and must not be updated by the application.
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
 
-   The opaque value provided by the application will be passed as the first
-   parameter for calls of zalloc and zfree. This can be useful for custom
-   memory management. The compression library attaches no meaning to the
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
    opaque value.
 
-   zalloc must return Z_NULL if there is not enough memory for the object.
+     zalloc must return Z_NULL if there is not enough memory for the object.
    If zlib is used in a multi-threaded application, zalloc and zfree must be
-   thread safe.
+   thread safe.  In that case, zlib is thread-safe.  When zalloc and zfree are
+   Z_NULL on entry to the initialization function, they are set to internal
+   routines that use the standard library functions malloc() and free().
 
-   On 16-bit systems, the functions zalloc and zfree must be able to allocate
-   exactly 65536 bytes, but will not be required to allocate more than this
-   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-   pointers returned by zalloc for objects of exactly 65536 bytes *must*
-   have their offset normalized to zero. The default allocation function
-   provided by this library ensures this (see zutil.c). To reduce memory
-   requirements and avoid any allocation of 64K objects, at the expense of
-   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
 
-   The fields total_in and total_out can be used for statistics or
-   progress reports. After compression, total_in holds the total size of
-   the uncompressed data and may be saved for use in the decompressor
-   (particularly if the decompressor wants to decompress everything in
-   a single step).
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use by the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
 */
 
                         /* constants */
 
 #define Z_NO_FLUSH      0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_PARTIAL_FLUSH 1
 #define Z_SYNC_FLUSH    2
 #define Z_FULL_FLUSH    3
 #define Z_FINISH        4
-/* Allowed flush values; see deflate() below for details */
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
 
 #define Z_OK            0
 #define Z_STREAM_END    1
@@ -138,8 +183,8 @@
 #define Z_MEM_ERROR    (-4)
 #define Z_BUF_ERROR    (-5)
 #define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
  */
 
 #define Z_NO_COMPRESSION         0
@@ -150,636 +195,1523 @@
 
 #define Z_FILTERED            1
 #define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
 #define Z_DEFAULT_STRATEGY    0
 /* compression strategy; see deflateInit2() below for details */
 
 #define Z_BINARY   0
-#define Z_ASCII    1
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
 #define Z_UNKNOWN  2
-/* Possible values of the data_type field */
+/* Possible values of the data_type field for deflate() */
 
 #define Z_DEFLATED   8
 /* The deflate compression method (the only one supported in this version) */
 
 #define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
 
+#ifndef Z_FREETYPE
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
 
                         /* basic functions */
 
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
 /* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-   If the first character differs, the library code actually used is
-   not compatible with the zlib.h header file used by the application.
-   This check is automatically made by deflateInit and inflateInit.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
  */
 
 /*
-ZEXTERN(int)  deflateInit OF((z_streamp strm, int level));
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
 
-     Initializes the internal stream state for compression. The fields
-   zalloc, zfree and opaque must be initialized before by the caller.
-   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-   use default allocation functions.
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
 
      The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-   1 gives best speed, 9 gives best compression, 0 gives no compression at
-   all (the input data is simply copied a block at a time).
-   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-   compression (currently equivalent to level 6).
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
 
-     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
    Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-   with the version assumed by the caller (ZLIB_VERSION).
-   msg is set to null if there is no error message.  deflateInit does not
-   perform any compression: this will be done by deflate().
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
 */
 
 
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
 /*
     deflate compresses as much data as possible, and stops when the input
-  buffer becomes empty or the output buffer becomes full. It may introduce some
-  output latency (reading input without producing any output) except when
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
   forced to flush.
 
-    The detailed semantics are as follows. deflate performs one or both of the
+    The detailed semantics are as follows.  deflate performs one or both of the
   following actions:
 
   - Compress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
+    accordingly.  If not all input can be processed (because there is not
     enough room in the output buffer), next_in and avail_in are updated and
     processing will resume at this point for the next call of deflate().
 
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly. This action is forced if the parameter flush is non zero.
+  - Generate more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
     Forcing flush frequently degrades the compression ratio, so this parameter
-    should be set only when necessary (in interactive applications).
-    Some output may be provided even if flush is not set.
+    should be set only when necessary.  Some output may be provided even if
+    flush is zero.
 
-  Before the call of deflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating avail_in or avail_out accordingly; avail_out
-  should never be zero before the call. The application can consume the
-  compressed output when it wants, for example when the output buffer is full
-  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-  and with zero avail_out, it must be called again after making room in the
-  output buffer because there might be more output pending.
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending. See deflatePending(),
+  which can be used if desired to determine whether or not there is more output
+  in that case.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
 
     If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
   flushed to the output buffer and the output is aligned on a byte boundary, so
-  that the decompressor can get all input data available so far. (In particular
-  avail_in is zero after the call if enough output space has been provided
-  before the call.)  Flushing may degrade compression for some compression
-  algorithms and so it should be used only when necessary.
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed
+  codes block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
 
     If flush is set to Z_FULL_FLUSH, all output is flushed as with
   Z_SYNC_FLUSH, and the compression state is reset so that decompression can
   restart from this point if previous compressed data has been damaged or if
-  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-  the compression.
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
 
     If deflate returns with avail_out == 0, this function must be called again
   with the same value of the flush parameter and more output space (updated
   avail_out), until the flush is complete (deflate returns with non-zero
-  avail_out).
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
 
     If the parameter flush is set to Z_FINISH, pending input is processed,
-  pending output is flushed and deflate returns with Z_STREAM_END if there
-  was enough output space; if deflate returns with Z_OK, this function must be
-  called again with Z_FINISH and more output space (updated avail_out) but no
-  more input data, until it returns with Z_STREAM_END or an error. After
-  deflate has returned Z_STREAM_END, the only possible operations on the
-  stream are deflateReset or deflateEnd.
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space.  If deflate returns with Z_OK or Z_BUF_ERROR, this
+  function must be called again with Z_FINISH and more output space (updated
+  avail_out) but no more input data, until it returns with Z_STREAM_END or an
+  error.  After deflate has returned Z_STREAM_END, the only possible operations
+  on the stream are deflateReset or deflateEnd.
 
-    Z_FINISH can be used immediately after deflateInit if all the compression
-  is to be done in a single step. In this case, avail_out must be at least
-  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
-  Z_STREAM_END, then it must be called again as described above.
+    Z_FINISH can be used in the first deflate call after deflateInit if all the
+  compression is to be done in a single step.  In order to complete in one
+  call, avail_out must be at least the value returned by deflateBound (see
+  below).  Then deflate is guaranteed to return Z_STREAM_END.  If not enough
+  output space is provided, deflate will not return Z_STREAM_END, and it must
+  be called again as described above.
 
-    deflate() sets strm->adler to the adler32 checksum of all input read
-  so far (that is, total_in bytes).
+    deflate() sets strm->adler to the Adler-32 checksum of all input read
+  so far (that is, total_in bytes).  If a gzip stream is being generated, then
+  strm->adler will be the CRC-32 checksum of the input read so far.  (See
+  deflateInit2 below.)
 
-    deflate() may update data_type if it can make a good guess about
-  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-  binary. This field is only for information purposes and does not affect
-  the compression algorithm in any manner.
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  If in doubt, the data is
+  considered binary.  This field is only for information purposes and does not
+  affect the compression algorithm in any manner.
 
     deflate() returns Z_OK if some progress has been made (more input
   processed or more output produced), Z_STREAM_END if all input has been
   consumed and all output has been produced (only when flush is set to
   Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
-  (for example avail_in or avail_out was zero).
+  if next_in or next_out was Z_NULL or the state was inadvertently written over
+  by the application), or Z_BUF_ERROR if no progress is possible (for example
+  avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not fatal, and
+  deflate() can be called again with more input and more output space to
+  continue compressing.
 */
 
 
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
 /*
      All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
+   This function discards any unprocessed input and does not flush any pending
+   output.
 
      deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
    stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-   prematurely (some input or output was discarded). In the error case,
-   msg may be set but then points to a static string (which must not be
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
    deallocated).
 */
 
+#endif  /* !Z_FREETYPE */
 
 /*
-ZEXTERN(int)  inflateInit OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
 
-     Initializes the internal stream state for decompression. The fields
+     Initializes the internal stream state for decompression.  The fields
    next_in, avail_in, zalloc, zfree and opaque must be initialized before by
-   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
-   value depends on the compression method), inflateInit determines the
-   compression method from the zlib header and allocates all data structures
-   accordingly; otherwise the allocation will be deferred to the first call of
-   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
-   use default allocation functions.
+   the caller.  In the current version of inflate, the provided input is not
+   read or consumed.  The allocation of a sliding window will be deferred to
+   the first call of inflate (if the decompression does not complete on the
+   first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates
+   them to use default allocation functions.
 
      inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
    memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
-   version assumed by the caller.  msg is set to null if there is no error
-   message. inflateInit does not perform any decompression apart from reading
-   the zlib header if present: this will be done by inflate().  (So next_in and
-   avail_in may be modified, but next_out and avail_out are unchanged.)
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression.
+   Actual decompression will be done by inflate().  So next_in, and avail_in,
+   next_out, and avail_out are unused and unchanged.  The current
+   implementation of inflateInit() does not process any header information --
+   that is deferred until inflate() is called.
 */
 
 
-ZEXTERN(int) inflate OF((z_streamp strm, int flush));
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
 /*
     inflate decompresses as much data as possible, and stops when the input
-  buffer becomes empty or the output buffer becomes full. It may some
-  introduce some output latency (reading input without producing any output)
-  except when forced to flush.
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
 
-  The detailed semantics are as follows. inflate performs one or both of the
+  The detailed semantics are as follows.  inflate performs one or both of the
   following actions:
 
   - Decompress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in is updated and processing
-    will resume at this point for the next call of inflate().
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), then next_in and avail_in are updated
+    accordingly, and processing will resume at this point for the next call of
+    inflate().
 
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly.  inflate() provides as much output as possible, until there
-    is no more input data or no more space in the output buffer (see below
-    about the flush parameter).
+  - Generate more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
 
-  Before the call of inflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating the next_* and avail_* values accordingly.
-  The application can consume the uncompressed output when it wants, for
-  example when the output buffer is full (avail_out == 0), or after each
-  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-  must be called again after making room in the output buffer because there
-  might be more output pending.
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  If the
+  caller of inflate() does not provide both available input and available
+  output space, it is possible that there will be no progress made.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
 
-    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
-  output as possible to the output buffer. The flushing behavior of inflate is
-  not specified for values of the flush parameter other than Z_SYNC_FLUSH
-  and Z_FINISH, but the current implementation actually flushes as much output
-  as possible anyway.
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  To assist in this, on return inflate() always sets strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
 
     inflate() should normally be called until it returns Z_STREAM_END or an
-  error. However if all decompression is to be performed in a single step
-  (a single call of inflate), the parameter flush should be set to
-  Z_FINISH. In this case all pending input is processed and all pending
-  output is flushed; avail_out must be large enough to hold all the
-  uncompressed data. (The size of the uncompressed data may have been saved
-  by the compressor for this purpose.) The next operation on this stream must
-  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-  is never required, but can be used to inform inflate that a faster routine
-  may be used for the single inflate() call.
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all of the uncompressed data for the
+  operation to complete.  (The size of the uncompressed data may have been
+  saved by the compressor for this purpose.)  The use of Z_FINISH is not
+  required to perform an inflation in one step.  However it may be used to
+  inform inflate that a faster approach can be used for the single inflate()
+  call.  Z_FINISH also informs inflate to not maintain a sliding window if the
+  stream completes, which reduces inflate's memory footprint.  If the stream
+  does not complete, either because not all of the stream is provided or not
+  enough output space is provided, then a sliding window will be allocated and
+  inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+  been used.
 
-     If a preset dictionary is needed at this point (see inflateSetDictionary
-  below), inflate sets strm-adler to the adler32 checksum of the
-  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
-  it sets strm->adler to the adler32 checksum of all output produced
-  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
-  an error code as described below. At the end of the stream, inflate()
-  checks that its computed adler32 checksum is equal to that saved by the
-  compressor and returns Z_STREAM_END only if the checksum is correct.
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed Adler-32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained unless inflateGetHeader() is used.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  produced so far.  The CRC-32 is checked against the gzip trailer, as is the
+  uncompressed length, modulo 2^32.
 
     inflate() returns Z_OK if some progress has been made (more input processed
   or more output produced), Z_STREAM_END if the end of the compressed data has
   been reached and all uncompressed output has been produced, Z_NEED_DICT if a
   preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
-  corrupted (input stream not conforming to the zlib format or incorrect
-  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
-  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
-  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
-  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
-  case, the application may then call inflateSync to look for a good
-  compression block.
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value, in which case strm->msg points to a string with a more specific
+  error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL, or the state was inadvertently written over
+  by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
+  if no progress was possible or if there was not enough room in the output
+  buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is to be attempted.
 */
 
 
-ZEXTERN(int)  inflateEnd OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
 /*
      All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
+   This function discards any unprocessed input and does not flush any pending
+   output.
 
-     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-   was inconsistent. In the error case, msg may be set but then points to a
-   static string (which must not be deallocated).
+     inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
+   was inconsistent.
 */
 
+
                         /* Advanced functions */
 
 /*
     The following functions are needed only in some special applications.
 */
 
+#ifndef Z_FREETYPE
+
 /*
-ZEXTERN(int)  deflateInit2 OF((z_streamp strm,
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
                                      int  level,
                                      int  method,
                                      int  windowBits,
                                      int  memLevel,
                                      int  strategy));
 
-     This is another version of deflateInit with more compression options. The
-   fields next_in, zalloc, zfree and opaque must be initialized before by
-   the caller.
+     This is another version of deflateInit with more compression options.  The
+   fields zalloc, zfree and opaque must be initialized before by the caller.
 
-     The method parameter is the compression method. It must be Z_DEFLATED in
+     The method parameter is the compression method.  It must be Z_DEFLATED in
    this version of the library.
 
      The windowBits parameter is the base two logarithm of the window size
    (the size of the history buffer).  It should be in the range 8..15 for this
-   version of the library. Larger values of this parameter result in better
-   compression at the expense of memory usage. The default value is 15 if
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
    deflateInit is used instead.
 
+     For the current implementation of deflate(), a windowBits value of 8 (a
+   window size of 256 bytes) is not supported.  As a result, a request for 8
+   will result in 9 (a 512-byte window).  In that case, providing 8 to
+   inflateInit2() will result in an error when the zlib header with 9 is
+   checked against the initialization of inflate().  The remedy is to not use 8
+   with deflateInit2() with this initialization, or at least in that case use 9
+   with inflateInit2().
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute a check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to the appropriate value,
+   if the operating system was determined at compile time.  If a gzip stream is
+   being written, strm->adler is a CRC-32 instead of an Adler-32.
+
+     For raw deflate or gzip encoding, a request for a 256-byte window is
+   rejected as invalid, since only the zlib header provides a means of
+   transmitting the window size to the decompressor.
+
      The memLevel parameter specifies how much memory should be allocated
-   for the internal compression state. memLevel=1 uses minimum memory but
-   is slow and reduces compression ratio; memLevel=9 uses maximum memory
-   for optimal speed. The default value is 8. See zconf.h for total memory
-   usage as a function of windowBits and memLevel.
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
 
-     The strategy parameter is used to tune the compression algorithm. Use the
+     The strategy parameter is used to tune the compression algorithm.  Use the
    value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-   string match).  Filtered data consists mostly of small values with a
-   somewhat random distribution. In this case, the compression algorithm is
-   tuned to compress them better. The effect of Z_FILTERED is to force more
-   Huffman coding and less string matching; it is somewhat intermediate
-   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-   the compression ratio but not the correctness of the compressed output even
-   if it is not set appropriately.
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
 
-      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
-   method). msg is set to null if there is no error message.  deflateInit2 does
-   not perform any compression: this will be done by deflate().
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
 */
 
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
 /*
      Initializes the compression dictionary from the given byte sequence
-   without producing any compressed output. This function must be called
-   immediately after deflateInit, deflateInit2 or deflateReset, before any
-   call of deflate. The compressor and decompressor must use exactly the same
-   dictionary (see inflateSetDictionary).
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
 
      The dictionary should consist of strings (byte sequences) that are likely
    to be encountered later in the data to be compressed, with the most commonly
-   used strings preferably put towards the end of the dictionary. Using a
+   used strings preferably put towards the end of the dictionary.  Using a
    dictionary is most useful when the data to be compressed is short and can be
    predicted with good accuracy; the data can then be compressed better than
    with the default empty dictionary.
 
      Depending on the size of the compression data structures selected by
    deflateInit or deflateInit2, a part of the dictionary may in effect be
-   discarded, for example if the dictionary is larger than the window size in
-   deflate or deflate2. Thus the strings most likely to be useful should be
-   put at the end of the dictionary, not at the front.
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
 
-     Upon return of this function, strm->adler is set to the Adler32 value
+     Upon return of this function, strm->adler is set to the Adler-32 value
    of the dictionary; the decompressor may later use this value to determine
-   which dictionary has been used by the compressor. (The Adler32 value
+   which dictionary has been used by the compressor.  (The Adler-32 value
    applies to the whole dictionary even if only a subset of the dictionary is
-   actually used by the compressor.)
+   actually used by the compressor.) If a raw deflate was requested, then the
+   Adler-32 value is not computed and strm->adler is not set.
 
      deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state is
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
    inconsistent (for example if deflate has already been called for this stream
-   or if the compression method is bsort). deflateSetDictionary does not
-   perform any compression: this will be done by deflate().
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
 */
 
+ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by deflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If deflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similarly, if dictLength is Z_NULL, then it is not set.
+
+     deflateGetDictionary() may return a length less than the window size, even
+   when more than the window size in input has been provided. It may return up
+   to 258 bytes less in that case, due to how zlib's implementation of deflate
+   manages the sliding window and lookahead for matches, where matches can be
+   up to 258 bytes long. If the application needs the last window-size bytes of
+   input, then that would need to be saved by the application outside of zlib.
+
+     deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
 /*
      Sets the destination stream as a complete copy of the source stream.
 
      This function can be useful when several compression strategies will be
    tried, for example when there are several ways of pre-processing the input
-   data with a filter. The streams that will be discarded should then be freed
+   data with a filter.  The streams that will be discarded should then be freed
    by calling deflateEnd.  Note that deflateCopy duplicates the internal
-   compression state which can be quite large, so this strategy is slow and
-   can consume lots of memory.
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
 
      deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
    enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-   (such as zalloc being NULL). msg is left unchanged in both source and
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
    destination.
 */
 
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
 /*
-     This function is equivalent to deflateEnd followed by deflateInit,
-   but does not free and reallocate all the internal compression state.
-   The stream will keep the same compression level and any other attributes
-   that may have been set by deflateInit2.
+     This function is equivalent to deflateEnd followed by deflateInit, but
+   does not free and reallocate the internal compression state.  The stream
+   will leave the compression level and any other attributes that may have been
+   set unchanged.
 
-      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
 */
 
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
 /*
      Dynamically update the compression level and compression strategy.  The
-   interpretation of level and strategy is as in deflateInit2.  This can be
+   interpretation of level and strategy is as in deflateInit2().  This can be
    used to switch between compression and straight copy of the input data, or
-   to switch to a different kind of input data requiring a different
-   strategy. If the compression level is changed, the input available so far
-   is compressed with the old level (and may be flushed); the new level will
-   take effect only at the next call of deflate().
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression approach (which is a function of the level) or the
+   strategy is changed, and if there have been any deflate() calls since the
+   state was initialized or reset, then the input available so far is
+   compressed with the old level and strategy using deflate(strm, Z_BLOCK).
+   There are three approaches for the compression levels 0, 1..3, and 4..9
+   respectively.  The new level and strategy will take effect at the next call
+   of deflate().
 
-     Before the call of deflateParams, the stream state must be set as for
-   a call of deflate(), since the currently available input may have to
-   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+     If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
+   not have enough output space to complete, then the parameter change will not
+   take effect.  In this case, deflateParams() can be called again with the
+   same parameters and more output space to try again.
 
-     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-   if strm->avail_out was zero.
+     In order to assure a change in the parameters on the first try, the
+   deflate stream should be flushed using deflate() with Z_BLOCK or other flush
+   request until strm.avail_out is not zero, before calling deflateParams().
+   Then no more input data should be provided before the deflateParams() call.
+   If this is done, the old level and strategy will be applied to the data
+   compressed before deflateParams(), and the new level and strategy will be
+   applied to the the data compressed after deflateParams().
+
+     deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
+   state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
+   there was not enough output space to complete the compression of the
+   available input data before a change in the strategy or approach.  Note that
+   in the case of a Z_BUF_ERROR, the parameters are not changed.  A return
+   value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
+   retried with more output space.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
 */
 
 /*
-ZEXTERN(int)  inflateInit2 OF((z_streamp strm,
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
                                      int  windowBits));
 
-     This is another version of inflateInit with an extra parameter. The
+     This is another version of inflateInit with an extra parameter.  The
    fields next_in, avail_in, zalloc, zfree and opaque must be initialized
    before by the caller.
 
      The windowBits parameter is the base two logarithm of the maximum window
    size (the size of the history buffer).  It should be in the range 8..15 for
-   this version of the library. The default value is 15 if inflateInit is used
-   instead. If a compressed stream with a larger window size is given as
-   input, inflate() will return with the error code Z_DATA_ERROR instead of
-   trying to allocate a larger window.
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
 
-      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-   memLevel). msg is set to null if there is no error message.  inflateInit2
-   does not perform any decompression apart from reading the zlib header if
-   present: this will be done by inflate(). (So next_in and avail_in may be
-   modified, but next_out and avail_out are unchanged.)
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an Adler-32 or a CRC-32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   CRC-32 instead of an Adler-32.  Unlike the gunzip utility and gzread() (see
+   below), inflate() will *not* automatically decode concatenated gzip members.
+   inflate() will return Z_STREAM_END at the end of the gzip member.  The state
+   would need to be reset to continue decoding a subsequent gzip member.  This
+   *must* be done if there is more data after a gzip member, in order for the
+   decompression to be compliant with the gzip standard (RFC 1952).
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
 */
 
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
 /*
      Initializes the decompression dictionary from the given uncompressed byte
-   sequence. This function must be called immediately after a call of inflate
-   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-   can be determined from the Adler32 value returned by this call of
-   inflate. The compressor and decompressor must use exactly the same
-   dictionary (see deflateSetDictionary).
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the Adler-32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
 
      inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state is
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
    inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   expected one (incorrect Adler-32 value).  inflateSetDictionary does not
    perform any decompression: this will be done by subsequent calls of
    inflate().
 */
 
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
 /*
-    Skips invalid compressed data until a full flush point (see above the
-  description of deflate with Z_FULL_FLUSH) can be found, or until all
-  available input is skipped. No output is provided.
+     Returns the sliding dictionary being maintained by inflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If inflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similarly, if dictLength is Z_NULL, then it is not set.
 
-    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
-  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-  case, the application may save the current value of total_in which
-  indicates where valid compressed data was found. In the error case, the
-  application may repeatedly call inflateSync, providing more input each time,
-  until success or end of the input data.
+     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
 */
 
-ZEXTERN(int)  inflateReset OF((z_streamp strm));
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurrences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+#endif  /* !Z_FREETYPE */
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
 /*
      This function is equivalent to inflateEnd followed by inflateInit,
-   but does not free and reallocate all the internal decompression state.
-   The stream will keep attributes that may have been set by inflateInit2.
+   but does not free and reallocate the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
 
-      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
 */
 
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.  If the window size is changed, then the
+   memory allocated for the window is freed, and the window will be reallocated
+   by inflate() if needed.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+#ifndef Z_FREETYPE
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above, or -65536 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+#endif  /* !Z_FREETYPE */
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+                                z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+#ifndef Z_FREETYPE
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is potentially more efficient than
+   inflate() for file i/o applications, in that it avoids copying between the
+   output and the sliding window by simply making the window itself the output
+   buffer.  inflate() can be faster on modern CPUs when used with large
+   buffers.  inflateBack() trusts the application to not change the output
+   buffer passed by the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the default
+   behavior of inflate(), which expects a zlib header and trailer around the
+   deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero -- buf is ignored in that
+   case -- and inflateBack() will return a buffer error.  inflateBack() will
+   call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
+   out() should return zero on success, or non-zero on failure.  If out()
+   returns non-zero, inflateBack() will return with an error.  Neither in() nor
+   out() are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.)  Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: ZLIB_DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+#endif  /* !Z_FREETYPE */
+
+#ifndef Z_SOLO
 
                         /* utility functions */
 
 /*
-     The following utility functions are implemented on top of the
-   basic stream-oriented functions. To simplify the interface, some
-   default options are assumed (compression level and memory usage,
-   standard memory allocation functions). The source code of these
-   utility functions can easily be modified if you need special options.
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
 */
 
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
 /*
      Compresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be at least 0.1% larger than
-   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-   compressed buffer.
-     This function can be used to compress a whole file at once if the
-   input file is mmap'ed.
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed data.  compress() is equivalent to compress2() with a level
+   parameter of Z_DEFAULT_COMPRESSION.
+
      compress returns Z_OK if success, Z_MEM_ERROR if there was not
    enough memory, Z_BUF_ERROR if there was not enough room in the output
    buffer.
 */
 
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
 /*
-     Compresses the source buffer into the destination buffer. The level
+     Compresses the source buffer into the destination buffer.  The level
    parameter has the same meaning as in deflateInit.  sourceLen is the byte
-   length of the source buffer. Upon entry, destLen is the total size of the
-   destination buffer, which must be at least 0.1% larger than sourceLen plus
-   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed data.
 
      compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
    memory, Z_BUF_ERROR if there was not enough room in the output buffer,
    Z_STREAM_ERROR if the level parameter is invalid.
 */
 
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
 /*
      Decompresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be large enough to hold the
-   entire uncompressed data. (The size of the uncompressed data must have
-   been saved previously by the compressor and transmitted to the decompressor
-   by some mechanism outside the scope of this compression library.)
-   Upon exit, destLen is the actual size of the compressed buffer.
-     This function can be used to decompress a whole file at once if the
-   input file is mmap'ed.
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed data.
 
      uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
    enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer, or Z_DATA_ERROR if the input data was corrupted.
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
 */
 
+ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
+                                    const Bytef *source, uLong *sourceLen));
+/*
+     Same as uncompress, except that sourceLen is a pointer, where the
+   length of the source is *sourceLen.  On return, *sourceLen is the number of
+   source bytes consumed.
+*/
+
+                        /* gzip file access functions */
 
 /*
-     Opens a gzip (.gz) file for reading or writing. The mode parameter
-   is as in fopen ("rb" or "wb") but can also include a compression level
-   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
-   Huffman only compression as in "wb1h". (See the description
-   of deflateInit2 for more information about the strategy parameter.)
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Open the gzip (.gz) file at path for reading and decompressing, or
+   compressing and writing.  The mode parameter is as in fopen ("rb" or "wb")
+   but can also include a compression level ("wb9") or a strategy: 'f' for
+   filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h",
+   'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression
+   as in "wb9F".  (See the description of deflateInit2 for more information
+   about the strategy parameter.)  'T' will request transparent writing or
+   appending with no compression and not using the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.  The addition of
+   "x" when writing will create the file exclusively, which fails if the file
+   already exists.  On systems that support it, the addition of "e" when
+   reading or writing will set the flag to close the file on an execve() call.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
 
      gzopen can be used to read a file which is not in gzip format; in this
-   case gzread will directly read from the file without decompression.
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
 
-     gzopen returns NULL if the file could not be opened or if there was
-   insufficient memory to allocate the (de)compression state; errno
-   can be checked to distinguish the two cases (if errno is zero, the
-   zlib error is Z_MEM_ERROR).  */
-
-/*
-     gzdopen() associates a gzFile with the file descriptor fd.  File
-   descriptors are obtained from calls like open, dup, creat, pipe or
-   fileno (in the file has been previously opened with fopen).
-   The mode parameter is as in gzopen.
-     The next call of gzclose on the returned gzFile will also close the
-   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-     gzdopen returns NULL if there was insufficient memory to allocate
-   the (de)compression state.
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
 */
 
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
 /*
-     Dynamically update the compression level or strategy. See the description
-   of deflateInit2 for the meaning of these parameters.
-     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
-   opened for writing.
+     Associate a gzFile with the file descriptor fd.  File descriptors are
+   obtained from calls like open, dup, creat, pipe or fileno (if the file has
+   been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
 */
 
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
 /*
-     Reads the given number of uncompressed bytes from the compressed file.
-   If the input file was not in gzip format, gzread copies the given number
-   of bytes into the buffer.
-     gzread returns the number of uncompressed bytes actually read (0 for
-   end of file, -1 for error). */
+     Set the internal buffer size used by this library's functions for file to
+   size.  The default buffer size is 8192 bytes.  This function must be called
+   after gzopen() or gzdopen(), and before any other calls that read or write
+   the file.  The buffer memory allocation is always deferred to the first read
+   or write.  Three times that size in buffer space is allocated.  A larger
+   buffer size of, for example, 64K or 128K bytes will noticeably increase the
+   speed of decompression (reading).
 
-/*
-     Writes the given number of uncompressed bytes into the compressed file.
-   gzwrite returns the number of uncompressed bytes actually written
-   (0 in case of error).
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
 */
 
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
 /*
-     Converts, formats, and writes the args to the compressed file under
-   control of the format string, as in fprintf. gzprintf returns the number of
-   uncompressed bytes actually written (0 in case of error).
+     Dynamically update the compression level and strategy for file.  See the
+   description of deflateInit2 for the meaning of these parameters. Previously
+   provided data is flushed before applying the parameter changes.
+
+     gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
+   opened for writing, Z_ERRNO if there is an error writing the flushed data,
+   or Z_MEM_ERROR if there is a memory allocation error.
 */
 
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
 /*
-      Writes the given null-terminated string to the compressed file, excluding
+     Read and decompress up to len uncompressed bytes from file into buf.  If
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.  If len is too large to fit in an int,
+   then nothing is read, -1 is returned, and the error state is set to
+   Z_STREAM_ERROR.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
+                                     gzFile file));
+/*
+     Read and decompress up to nitems items of size size from file into buf,
+   otherwise operating as gzread() does.  This duplicates the interface of
+   stdio's fread(), with size_t request and return types.  If the library
+   defines size_t, then z_size_t is identical to size_t.  If not, then z_size_t
+   is an unsigned integer type that can contain a pointer.
+
+     gzfread() returns the number of full items read of size size, or zero if
+   the end of the file was reached and a full item could not be read, or if
+   there was an error.  gzerror() must be consulted if zero is returned in
+   order to determine if there was an error.  If the multiplication of size and
+   nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
+   is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
+
+     In the event that the end of file is reached and only a partial item is
+   available at the end, i.e. the remaining uncompressed data length is not a
+   multiple of size, then the final partial item is nevertheless read into buf
+   and the end-of-file flag is set.  The length of the partial item read is not
+   provided, but could be inferred from the result of gztell().  This behavior
+   is the same as the behavior of fread() implementations in common libraries,
+   but it prevents the direct use of gzfread() to read a concurrently written
+   file, resetting and retrying on end-of-file, when size is not 1.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
+/*
+     Compress and write the len uncompressed bytes at buf to file. gzwrite
+   returns the number of uncompressed bytes written or 0 in case of error.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
+                                      z_size_t nitems, gzFile file));
+/*
+     Compress and write nitems items of size size from buf to file, duplicating
+   the interface of stdio's fwrite(), with size_t request and return types.  If
+   the library defines size_t, then z_size_t is identical to size_t.  If not,
+   then z_size_t is an unsigned integer type that can contain a pointer.
+
+     gzfwrite() returns the number of full items written of size size, or zero
+   if there was an error.  If the multiplication of size and nitems overflows,
+   i.e. the product does not fit in a z_size_t, then nothing is written, zero
+   is returned, and the error state is set to Z_STREAM_ERROR.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+     Convert, format, compress, and write the arguments (...) to file under
+   control of the string format, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or a negative zlib error code in case
+   of error.  The number of uncompressed bytes written is limited to 8191, or
+   one less than the buffer size given to gzbuffer().  The caller should assure
+   that this limit is not exceeded.  If it is exceeded, then gzprintf() will
+   return an error (0) with nothing written.  In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf(),
+   because the secure snprintf() or vsnprintf() functions were not available.
+   This can be determined using zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Compress and write the given null-terminated string s to file, excluding
    the terminating null character.
-      gzputs returns the number of characters written, or -1 in case of error.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Read and decompress bytes from file into buf, until len-1 characters are
+   read, or until a newline character is read and transferred to buf, or an
+   end-of-file condition is encountered.  If any characters are read or if len
+   is one, the string is terminated with a null character.  If no characters
+   are read due to an end-of-file or len is less than one, then the buffer is
+   left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Compress and write c, converted to an unsigned char, into file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Read and decompress one byte from file.  gzgetc returns this byte or -1
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push c back onto the stream for file to be read as the first character on
+   the next read.  At least one character of push-back is always allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flush all pending output to file.  The parameter flush is as in the
+   deflate() function.  The return value is the zlib error number (see function
+   gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatenated gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
 */
 
 /*
-      Reads bytes from the compressed file until len-1 characters are read, or
-   a newline character is read and transferred to buf, or an end-of-file
-   condition is encountered.  The string is then terminated with a null
-   character.
-      gzgets returns buf, or Z_NULL in case of error.
-*/
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
 
-/*
-      Writes c, converted to an unsigned char, into the compressed file.
-   gzputc returns the value that was written, or -1 in case of error.
-*/
-
-/*
-      Reads one byte from the compressed file. gzgetc returns this byte
-   or -1 in case of end of file or error.
-*/
-
-/*
-     Flushes all pending output into the compressed file. The parameter
-   flush is as in the deflate() function. The return value is the zlib
-   error number (see function gzerror below). gzflush returns Z_OK if
-   the flush parameter is Z_FINISH and all output could be flushed.
-     gzflush should be called only when strictly necessary because it can
-   degrade compression.
-*/
-
-/*
-      Sets the starting position for the next gzread or gzwrite on the
-   given compressed file. The offset represents a number of bytes in the
-   uncompressed data stream. The whence parameter is defined as in lseek(2);
+     Set the starting position to offset relative to whence for the next gzread
+   or gzwrite on file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
    the value SEEK_END is not supported.
+
      If the file is opened for reading, this function is emulated but can be
-   extremely slow. If the file is opened for writing, only forward seeks are
+   extremely slow.  If the file is opened for writing, only forward seeks are
    supported; gzseek then compresses a sequence of zeroes up to the new
    starting position.
 
-      gzseek returns the resulting offset location as measured in bytes from
+     gzseek returns the resulting offset location as measured in bytes from
    the beginning of the uncompressed stream, or -1 in case of error, in
    particular if the file is opened for writing and the new starting position
    would be before the current position.
 */
 
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
 /*
-     Rewinds the given file. This function is supported only for reading.
+     Rewind file. This function is supported only for reading.
 
-   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET).
 */
 
 /*
-     Returns the starting position for the next gzread or gzwrite on the
-   given compressed file. This position represents a number of bytes in the
-   uncompressed data stream.
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
 
-   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+     Return the starting position for the next gzread or gzwrite on file.
+   This position represents a number of bytes in the uncompressed data stream,
+   and is zero when starting, even if appending or reading a gzip stream from
+   the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
 */
 
 /*
-     Returns 1 when EOF has previously been detected reading the given
-   input stream, otherwise zero.
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Return the current compressed (actual) read or write offset of file.  This
+   offset includes the count of bytes that precede the gzip stream, for example
+   when appending or when using gzdopen() for reading.  When reading, the
+   offset does not include as yet unused buffered input.  This information can
+   be used for a progress indicator.  On error, gzoffset() returns -1.
 */
 
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
 /*
-     Flushes all pending output if necessary, closes the compressed file
-   and deallocates all the (de)compression state. The return value is the zlib
-   error number (see function gzerror below).
+     Return true (1) if the end-of-file indicator for file has been set while
+   reading, false (0) otherwise.  Note that the end-of-file indicator is set
+   only if the read tried to go past the end of the input, but came up short.
+   Therefore, just like feof(), gzeof() may return false even if there is no
+   more data to read, in the event that the last read request was for the exact
+   number of bytes remaining in the input file.  This will happen if the input
+   file size is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
 */
 
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
 /*
-     Returns the error message for the last error which occurred on the
-   given compressed file. errnum is set to zlib error number. If an
-   error occurred in the file system and not in the compression library,
-   errnum is set to Z_ERRNO and the application may consult errno
-   to get the exact error code.
+     Return true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
 */
 
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flush all pending output for file, if necessary, close file and
+   deallocate the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Return the error message for the last error which occurred on file.
+   errnum is set to zlib error number.  If an error occurred in the file system
+   and not in the compression library, errnum is set to Z_ERRNO and the
+   application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clear the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
                         /* checksum functions */
 
 /*
      These functions are not related to compression but are exported
-   anyway because they might be useful in applications using the
-   compression library.
+   anyway because they might be useful in applications using the compression
+   library.
 */
 
-ZEXTERN(uLong)  adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
 /*
      Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-   return the updated checksum. If buf is NULL, this function returns
-   the required initial value for the checksum.
-   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-   much faster. Usage example:
+   return the updated checksum. An Adler-32 value is in the range of a 32-bit
+   unsigned integer. If buf is Z_NULL, this function returns the required
+   initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
+   much faster.
+
+   Usage example:
 
      uLong adler = adler32(0L, Z_NULL, 0);
 
@@ -789,11 +1721,32 @@
      if (adler != original_adler) error();
 */
 
+ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
+                                    z_size_t len));
 /*
-     Update a running crc with the bytes buf[0..len-1] and return the updated
-   crc. If buf is NULL, this function returns the required initial value
-   for the crc. Pre- and post-conditioning (one's complement) is performed
-   within this function so it shouldn't be done by the application.
+     Same as adler32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.
+   If buf is Z_NULL, this function returns the required initial value for the
+   crc. Pre- and post-conditioning (one's complement) is performed within this
+   function so it shouldn't be done by the application.
+
    Usage example:
 
      uLong crc = crc32(0L, Z_NULL, 0);
@@ -804,27 +1757,215 @@
      if (crc != original_crc) error();
 */
 
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
+                                  z_size_t len));
+/*
+     Same as crc32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
+
+     Return the operator corresponding to length len2, to be used with
+   crc32_combine_op().
+*/
+
+#ifndef Z_FREETYPE
+
+ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
+/*
+     Give the same result as crc32_combine(), using op in place of len2. op is
+   is generated from len2 by crc32_combine_gen(). This will be faster than
+   crc32_combine() if the generated op is used more than once.
+*/
+
 
                         /* various hacks, don't look :) */
 
 /* deflateInit and inflateInit are macros to allow checking the zlib version
  * and the compiler's view of z_stream:
  */
-ZEXTERN(int)  inflateInit2_ OF((z_streamp strm, int  windowBits,
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
                                       const char *version, int stream_size));
-#define deflateInit(strm, level) \
-        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
-        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
-        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#ifdef Z_PREFIX_SET
+#  define z_deflateInit(strm, level) \
+          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_inflateInit(strm) \
+          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+#  define z_inflateBackInit(strm, windowBits, window) \
+          inflateBackInit_((strm), (windowBits), (window), \
+                           ZLIB_VERSION, (int)sizeof(z_stream))
+#else
+#  define deflateInit(strm, level) \
+          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define inflateInit(strm) \
+          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+#  define inflateBackInit(strm, windowBits, window) \
+          inflateBackInit_((strm), (windowBits), (window), \
+                           ZLIB_VERSION, (int)sizeof(z_stream))
+#endif
 
+#else  /* Z_FREETYPE */
+
+
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+
+#  define inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+
+#endif  /* Z_FREETYPE */
+
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#  define z_gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#else
+#  define gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#    define z_crc32_combine_gen z_crc32_combine_gen64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#    define crc32_combine_gen crc32_combine_gen64
+#  endif
+#  ifndef Z_LARGE64
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+#ifndef Z_FREETYPE
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
+#endif
+
+#endif /* !Z_SOLO */
+
+/* undocumented functions */
+#ifndef Z_FREETYPE
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateValidate OF((z_streamp, int));
+ZEXTERN unsigned long  ZEXPORT inflateCodesUsed OF((z_streamp));
+#endif  /* !Z_FREETYPE */
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+#ifndef Z_FREETYPE
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
+                                            const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                  const char *format,
+                                                  va_list va));
+#  endif
+#endif
+#endif  /* !Z_FREETYPE */
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* _ZLIB_H */
+#endif /* ZLIB_H */
diff --git a/src/gzip/zutil.c b/src/gzip/zutil.c
index 7ad0c1f..542706c 100644
--- a/src/gzip/zutil.c
+++ b/src/gzip/zutil.c
@@ -1,23 +1,161 @@
 /* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * Copyright (C) 1995-2017 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
 #include "zutil.h"
-
-#ifndef STDC
-extern void exit OF((int));
+#ifndef Z_SOLO
+#  include "gzguts.h"
 #endif
 
+#ifndef Z_FREETYPE
+
+z_const char * const z_errmsg[10] = {
+    (z_const char *)"need dictionary",     /* Z_NEED_DICT       2  */
+    (z_const char *)"stream end",          /* Z_STREAM_END      1  */
+    (z_const char *)"",                    /* Z_OK              0  */
+    (z_const char *)"file error",          /* Z_ERRNO         (-1) */
+    (z_const char *)"stream error",        /* Z_STREAM_ERROR  (-2) */
+    (z_const char *)"data error",          /* Z_DATA_ERROR    (-3) */
+    (z_const char *)"insufficient memory", /* Z_MEM_ERROR     (-4) */
+    (z_const char *)"buffer error",        /* Z_BUF_ERROR     (-5) */
+    (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
+    (z_const char *)""
+};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef ZLIB_DEBUG
+    flags += 1 << 8;
+#endif
+    /*
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+     */
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifdef NO_vsnprintf
+    flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#else
+    flags += 1L << 24;
+#  ifdef NO_snprintf
+    flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef ZLIB_DEBUG
+#include <stdlib.h>
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error(
+    char *m)
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(
+    int err)
+{
+    return ERR_MSG(err);
+}
+
+#endif  /* !Z_FREETYPE */
+
+#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
+    /* The older Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
 
 #ifndef HAVE_MEMCPY
 
-void zmemcpy(dest, source, len)
-    Bytef* dest;
-    const Bytef* source;
-    uInt  len;
+void ZLIB_INTERNAL zmemcpy(
+    Bytef* dest,
+    const Bytef* source,
+    uInt  len)
 {
     if (len == 0) return;
     do {
@@ -25,10 +163,12 @@
     } while (--len != 0);
 }
 
-int zmemcmp(s1, s2, len)
-    const Bytef* s1;
-    const Bytef* s2;
-    uInt  len;
+#ifndef Z_FREETYPE
+
+int ZLIB_INTERNAL zmemcmp(
+    const Bytef* s1,
+    const Bytef* s2,
+    uInt  len)
 {
     uInt j;
 
@@ -38,22 +178,25 @@
     return 0;
 }
 
-void zmemzero(dest, len)
-    Bytef* dest;
-    uInt  len;
+void ZLIB_INTERNAL zmemzero(
+    Bytef* dest,
+    uInt  len)
 {
     if (len == 0) return;
     do {
         *dest++ = 0;  /* ??? to be unrolled */
     } while (--len != 0);
 }
+#endif  /* !Z_FREETYPE */
 #endif
 
-#if defined( MSDOS ) && defined( __TURBOC__ ) && !defined( MY_ZCALLOC )
-#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-/* Small and medium model in Turbo C are for now limited to near allocation
- * with reduced MAX_WBITS and MAX_MEM_LEVEL
- */
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
 #  define MY_ZCALLOC
 
 /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
@@ -80,11 +223,13 @@
  * a protected system like OS/2. Use Microsoft C instead.
  */
 
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
 {
-    voidpf buf = opaque; /* just to make some compilers happy */
+    voidpf buf;
     ulg bsize = (ulg)items*size;
 
+    (void)opaque;
+
     /* If we allocate less than 65520 bytes, we assume that farmalloc
      * will return a usable pointer which doesn't have to be normalized.
      */
@@ -104,9 +249,12 @@
     return buf;
 }
 
-void  zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
 {
     int n;
+
+    (void)opaque;
+
     if (*(ush*)&ptr != 0) { /* object < 64K */
         farfree(ptr);
         return;
@@ -122,14 +270,13 @@
         next_ptr--;
         return;
     }
-    ptr = opaque; /* just to make some compilers happy */
     Assert(0, "zcfree: ptr not found");
 }
-#endif
-#endif /* MSDOS && __TURBOC__ */
+
+#endif /* __TURBOC__ */
 
 
-#if defined(M_I86) && !defined(__32BIT__) && !defined( MY_ZCALLOC )
+#ifdef M_I86
 /* Microsoft C in 16-bit mode */
 
 #  define MY_ZCALLOC
@@ -139,43 +286,49 @@
 #  define _hfree   hfree
 #endif
 
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size)
 {
-    if (opaque) opaque = 0; /* to make compiler happy */
+    (void)opaque;
     return _halloc((long)items, size);
 }
 
-void  zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
 {
-    if (opaque) opaque = 0; /* to make compiler happy */
+    (void)opaque;
     _hfree(ptr);
 }
 
-#endif /* MSC */
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
 
 
 #ifndef MY_ZCALLOC /* Any system without a special alloc function */
 
 #ifndef STDC
-extern voidp  ft_scalloc OF((uInt items, uInt size));
-extern void   ft_sfree   OF((voidpf ptr));
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
 #endif
 
-voidpf zcalloc (opaque, items, size)
-    voidpf opaque;
-    unsigned items;
-    unsigned size;
+voidpf ZLIB_INTERNAL zcalloc(
+    voidpf opaque,
+    unsigned items,
+    unsigned size)
 {
-    if (opaque) items += size - size; /* make compiler happy */
-    return (voidpf)ft_scalloc(items, size);
+    (void)opaque;
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
 }
 
-void  zcfree (opaque, ptr)
-    voidpf opaque;
-    voidpf ptr;
+void ZLIB_INTERNAL zcfree(
+    voidpf opaque,
+    voidpf ptr)
 {
-    ft_sfree(ptr);
-    if (opaque) return; /* make compiler happy */
+    (void)opaque;
+    free(ptr);
 }
 
 #endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/src/gzip/zutil.h b/src/gzip/zutil.h
index c9688cd..055ba8b 100644
--- a/src/gzip/zutil.h
+++ b/src/gzip/zutil.h
@@ -1,5 +1,5 @@
 /* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -10,26 +10,31 @@
 
 /* @(#) $Id$ */
 
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
 
 #include "zlib.h"
 
-#ifdef STDC
-#  include <stddef.h>
+#if defined(STDC) && !defined(Z_SOLO)
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
 #  include <string.h>
 #  include <stdlib.h>
 #endif
-#ifdef NO_ERRNO_H
-    extern int errno;
-#else
-#   include <errno.h>
-#endif
 
 #ifndef local
 #  define local static
 #endif
-/* compile with -Dlocal if your debugger can't find static symbols */
+/* since "static" is used to mean two completely different things in C, we
+   define "local" for the non-static meaning of "static", for readability
+   (compile with -Dlocal if your debugger can't find static symbols) */
 
 typedef unsigned char  uch;
 typedef uch FAR uchf;
@@ -37,9 +42,26 @@
 typedef ush FAR ushf;
 typedef unsigned long  ulg;
 
+#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (ULONG_MAX == 0xffffffffffffffff)
+#    define Z_U8 unsigned long
+#  elif (ULLONG_MAX == 0xffffffffffffffff)
+#    define Z_U8 unsigned long long
+#  elif (UINT_MAX == 0xffffffffffffffff)
+#    define Z_U8 unsigned
+#  endif
+#endif
+
+#ifndef Z_FREETYPE
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+#endif  /* !Z_FREETYPE */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
 
 #define ERR_RETURN(strm,err) \
-  return (strm->msg = (char*)ERR_MSG(err), (err))
+  return (strm->msg = ERR_MSG(err), (err))
 /* To be used only when the state is known to be valid */
 
         /* common constants */
@@ -69,90 +91,130 @@
 
         /* target dependencies */
 
-#ifdef MSDOS
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
 #  define OS_CODE  0x00
-#  if defined(__TURBOC__) || defined(__BORLANDC__)
-#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
-       /* Allow compilation with ANSI keywords only enabled */
-       void _Cdecl farfree( void *block );
-       void *_Cdecl farmalloc( unsigned long nbytes );
-#    else
-#     include <alloc.h>
+#  ifndef Z_SOLO
+#    if defined(__TURBOC__) || defined(__BORLANDC__)
+#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+         /* Allow compilation with ANSI keywords only enabled */
+         void _Cdecl farfree( void *block );
+         void *_Cdecl farmalloc( unsigned long nbytes );
+#      else
+#        include <alloc.h>
+#      endif
+#    else /* MSC or DJGPP */
+#      include <malloc.h>
 #    endif
-#  else /* MSC or DJGPP */
 #  endif
 #endif
 
-#ifdef OS2
-#  define OS_CODE  0x06
-#endif
-
-#ifdef WIN32 /* Window 95 & Windows NT */
-#  define OS_CODE  0x0b
-#endif
-
-#if defined(VAXC) || defined(VMS)
-#  define OS_CODE  0x02
-#  define F_OPEN(name, mode) \
-     ft_fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
 #ifdef AMIGA
-#  define OS_CODE  0x01
+#  define OS_CODE  1
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  2
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef __370__
+#  if __TARGET_LIB__ < 0x20000000
+#    define OS_CODE 4
+#  elif __TARGET_LIB__ < 0x40000000
+#    define OS_CODE 11
+#  else
+#    define OS_CODE 8
+#  endif
 #endif
 
 #if defined(ATARI) || defined(atarist)
-#  define OS_CODE  0x05
+#  define OS_CODE  5
+#endif
+
+#ifdef OS2
+#  define OS_CODE  6
+#  if defined(M_I86) && !defined(Z_SOLO)
+#    include <malloc.h>
+#  endif
 #endif
 
 #if defined(MACOS) || defined(TARGET_OS_MAC)
-#  define OS_CODE  0x07
-#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-#    include <unix.h> /* for fdopen */
-#  else
-#    ifndef fdopen
-#      define fdopen(fd,mode) NULL /* No fdopen() */
+#  define OS_CODE  7
+#  ifndef Z_SOLO
+#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#      include <unix.h> /* for fdopen */
+#    else
+#      ifndef fdopen
+#        define fdopen(fd,mode) NULL /* No fdopen() */
+#      endif
 #    endif
 #  endif
 #endif
 
-#ifdef __50SERIES /* Prime/PRIMOS */
-#  define OS_CODE  0x0F
+#ifdef __acorn
+#  define OS_CODE 13
 #endif
 
-#ifdef TOPS20
-#  define OS_CODE  0x0a
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  define OS_CODE  10
+#endif
+
+#ifdef _BEOS_
+#  define OS_CODE  16
+#endif
+
+#ifdef __TOS_OS400__
+#  define OS_CODE 18
+#endif
+
+#ifdef __APPLE__
+#  define OS_CODE 19
 #endif
 
 #if defined(_BEOS_) || defined(RISCOS)
 #  define fdopen(fd,mode) NULL /* No fdopen() */
 #endif
 
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-#  define fdopen(fd,type)  _fdopen(fd,type)
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
 #endif
 
+#if defined(__BORLANDC__) && !defined(MSDOS)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
 
-        /* Common defaults */
+#ifndef Z_FREETYPE
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+    (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
+#endif
+
+#endif  /* !Z_FREETYPE */
+
+        /* common defaults */
 
 #ifndef OS_CODE
-#  define OS_CODE  0x03  /* assume Unix */
+#  define OS_CODE  3     /* assume Unix */
 #endif
 
 #ifndef F_OPEN
-#  define F_OPEN(name, mode) ft_fopen((name), (mode))
+#  define F_OPEN(name, mode) fopen((name), (mode))
 #endif
 
          /* functions */
 
-#ifdef HAVE_STRERROR
-   extern char *strerror OF((int));
-#  define zstrerror(errnum) strerror(errnum)
-#else
-#  define zstrerror(errnum) ""
-#endif
-
-#if defined(pyr)
+#if defined(pyr) || defined(Z_SOLO)
 #  define NO_MEMCPY
 #endif
 #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
@@ -176,16 +238,16 @@
 #    define zmemzero(dest, len) ft_memset(dest, 0, len)
 #  endif
 #else
-   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
-   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
-   extern void zmemzero OF((Bytef* dest, uInt len));
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
 #endif
 
 /* Diagnostic functions */
-#ifdef DEBUG
+#ifdef ZLIB_DEBUG
 #  include <stdio.h>
-   extern int z_verbose;
-   extern void z_error    OF((char *m));
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
 #  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
 #  define Trace(x) {if (z_verbose>=0) fprintf x ;}
 #  define Tracev(x) {if (z_verbose>0) fprintf x ;}
@@ -201,15 +263,19 @@
 #  define Tracecv(c,x)
 #endif
 
-
-typedef uLong (*check_func) OF((uLong check, const Bytef *buf,
-                                uInt len));
-local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-local void   zcfree  OF((voidpf opaque, voidpf ptr));
+#ifndef Z_SOLO
+   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                                    unsigned size));
+   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+#endif
 
 #define ZALLOC(strm, items, size) \
            (*((strm)->zalloc))((strm)->opaque, (items), (size))
 #define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
 #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
 
-#endif /* _Z_UTIL_H */
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/src/lzw/Jamfile b/src/lzw/Jamfile
deleted file mode 100644
index cb83aa4..0000000
--- a/src/lzw/Jamfile
+++ /dev/null
@@ -1,16 +0,0 @@
-# FreeType 2 src/lzw Jamfile
-#
-# Copyright 2004-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) lzw ;
-
-Library  $(FT2_LIB) : ftlzw.c ;
-
-# end of src/lzw Jamfile
diff --git a/src/lzw/ftlzw.c b/src/lzw/ftlzw.c
index 4a3d70b..8838379 100644
--- a/src/lzw/ftlzw.c
+++ b/src/lzw/ftlzw.c
@@ -8,7 +8,7 @@
  * be used to parse compressed PCF fonts, as found with many X11 server
  * distributions.
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * Albert Chin-A-Young.
  *
  * based on code in `src/gzip/ftgzip.c'
@@ -21,15 +21,14 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_LZW_H
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftlzw.h>
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -37,7 +36,7 @@
 #define FT_ERR_PREFIX  LZW_Err_
 #define FT_ERR_BASE    FT_Mod_Err_LZW
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 
 #ifdef FT_CONFIG_OPTION_USE_LZW
@@ -370,7 +369,7 @@
     FT_ZERO( stream );
     stream->memory = memory;
 
-    if ( !FT_NEW( zip ) )
+    if ( !FT_QNEW( zip ) )
     {
       error = ft_lzw_file_init( zip, stream, source );
       if ( error )
@@ -384,7 +383,7 @@
 
     stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */
     stream->pos   = 0;
-    stream->base  = 0;
+    stream->base  = NULL;
     stream->read  = ft_lzw_stream_io;
     stream->close = ft_lzw_stream_close;
 
diff --git a/src/lzw/ftzopen.c b/src/lzw/ftzopen.c
index b699b2e..e680c4d 100644
--- a/src/lzw/ftzopen.c
+++ b/src/lzw/ftzopen.c
@@ -8,7 +8,7 @@
  * be used to parse compressed PCF fonts, as found with many X11 server
  * distributions.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,9 @@
  */
 
 #include "ftzopen.h"
-#include FT_INTERNAL_MEMORY_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftmemory.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
 
 
   static int
@@ -127,6 +127,7 @@
 
       new_size = new_size + ( new_size >> 1 ) + 4;
 
+      /* if relocating to heap */
       if ( state->stack == state->stack_0 )
       {
         state->stack = NULL;
@@ -142,9 +143,13 @@
           return -1;
       }
 
-      if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) )
+      if ( FT_QREALLOC( state->stack, old_size, new_size ) )
         return -1;
 
+      /* if relocating to heap */
+      if ( old_size == 0 )
+        FT_MEM_COPY( state->stack, state->stack_0, FT_LZW_DEFAULT_STACK_SIZE );
+
       state->stack_size = new_size;
     }
     return 0;
@@ -310,7 +315,7 @@
 
         state->phase = FT_LZW_PHASE_CODE;
       }
-      /* fall-through */
+      FALL_THROUGH;
 
     case FT_LZW_PHASE_CODE:
       {
@@ -368,7 +373,7 @@
 
         state->phase = FT_LZW_PHASE_STACK;
       }
-      /* fall-through */
+      FALL_THROUGH;
 
     case FT_LZW_PHASE_STACK:
       {
diff --git a/src/lzw/ftzopen.h b/src/lzw/ftzopen.h
index 4fbe257..6c75636 100644
--- a/src/lzw/ftzopen.h
+++ b/src/lzw/ftzopen.h
@@ -8,7 +8,7 @@
  * be used to parse compressed PCF fonts, as found with many X11 server
  * distributions.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -22,9 +22,9 @@
 #ifndef FTZOPEN_H_
 #define FTZOPEN_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
+FT_BEGIN_HEADER
 
   /*
    * This is a complete re-implementation of the LZW file reader,
@@ -166,6 +166,8 @@
 
 /* */
 
+FT_END_HEADER
+
 #endif /* FTZOPEN_H_ */
 
 
diff --git a/src/lzw/rules.mk b/src/lzw/rules.mk
index 18933c4..b750216 100644
--- a/src/lzw/rules.mk
+++ b/src/lzw/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2004-2018 by
+# Copyright (C) 2004-2023 by
 # Albert Chin-A-Young.
 #
 # based on `src/lzw/rules.mk'
diff --git a/src/otvalid/Jamfile b/src/otvalid/Jamfile
deleted file mode 100644
index 21b8e0c..0000000
--- a/src/otvalid/Jamfile
+++ /dev/null
@@ -1,37 +0,0 @@
-# FreeType 2 src/otvalid Jamfile
-#
-# Copyright 2004-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) otvalid ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = otvbase
-               otvcommn
-               otvgdef
-               otvgpos
-               otvgsub
-               otvjstf
-               otvmath
-               otvmod
-               ;
-  }
-  else
-  {
-    _sources = otvalid ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/otvalid Jamfile
diff --git a/src/otvalid/module.mk b/src/otvalid/module.mk
index 34f3dab..9013842 100644
--- a/src/otvalid/module.mk
+++ b/src/otvalid/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2004-2018 by
+# Copyright (C) 2004-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/otvalid/otvalid.c b/src/otvalid/otvalid.c
index 144be58..3b1e23a 100644
--- a/src/otvalid/otvalid.c
+++ b/src/otvalid/otvalid.c
@@ -4,7 +4,7 @@
  *
  *   FreeType validator for OpenType tables (body only).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "otvbase.c"
 #include "otvcommn.c"
diff --git a/src/otvalid/otvalid.h b/src/otvalid/otvalid.h
index 1ccdbbf..7edadb7 100644
--- a/src/otvalid/otvalid.h
+++ b/src/otvalid/otvalid.h
@@ -4,7 +4,7 @@
  *
  *   OpenType table validation (specification only).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,13 +20,12 @@
 #define OTVALID_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
-#include "otverror.h"           /* must come before FT_INTERNAL_VALIDATE_H */
+#include "otverror.h"                      /* must come before `ftvalid.h' */
 
-#include FT_INTERNAL_VALIDATE_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftvalid.h>
+#include <freetype/internal/ftstream.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/otvalid/otvbase.c b/src/otvalid/otvbase.c
index 918e383..f449795 100644
--- a/src/otvalid/otvbase.c
+++ b/src/otvalid/otvbase.c
@@ -4,7 +4,7 @@
  *
  *   OpenType BASE table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -27,7 +27,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvbase
+#define FT_COMPONENT  otvbase
 
 
   static void
diff --git a/src/otvalid/otvcommn.c b/src/otvalid/otvcommn.c
index 4a2c95e..b94d8a0 100644
--- a/src/otvalid/otvcommn.c
+++ b/src/otvalid/otvcommn.c
@@ -4,7 +4,7 @@
  *
  *   OpenType common tables validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvcommon
+#define FT_COMPONENT  otvcommon
 
 
   /*************************************************************************/
@@ -151,6 +151,9 @@
     FT_UInt   result = 0;
 
 
+    if ( !count )
+      return result;
+
     switch ( CoverageFormat )
     {
     case 1:
diff --git a/src/otvalid/otvcommn.h b/src/otvalid/otvcommn.h
index 3cd6d86..6702c00 100644
--- a/src/otvalid/otvcommn.h
+++ b/src/otvalid/otvcommn.h
@@ -4,7 +4,7 @@
  *
  *   OpenType common tables validation (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define OTVCOMMN_H_
 
 
-#include <ft2build.h>
 #include "otvalid.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 
 FT_BEGIN_HEADER
@@ -106,10 +105,11 @@
                 FT_Byte*  pp = (FT_Byte*)_size ## _p;               \
                                                                     \
                                                                     \
-                FT_TRACE3(( "\n"                                    \
-                            "Invalid offset to optional table `%s'" \
-                            " set to zero.\n"                       \
-                            "\n", #_size ));                        \
+                FT_TRACE3(( "\n" ));                                \
+                FT_TRACE3(( "Invalid offset to optional table `%s'" \
+                            " set to zero.\n",                      \
+                            #_size ));                              \
+                FT_TRACE3(( "\n" ));                                \
                                                                     \
                 _size = pp[0] = pp[1] = 0;                          \
               }                                                     \
@@ -128,10 +128,11 @@
                 FT_Byte*  pp = (FT_Byte*)_size ## _p;               \
                                                                     \
                                                                     \
-                FT_TRACE3(( "\n"                                    \
-                            "Invalid offset to optional table `%s'" \
-                            " set to zero.\n"                       \
-                            "\n", #_size ));                        \
+                FT_TRACE3(( "\n" ));                                \
+                FT_TRACE3(( "Invalid offset to optional table `%s'" \
+                            " set to zero.\n",                      \
+                            #_size ));                              \
+                FT_TRACE3(( "\n" ));                                \
                                                                     \
                 _size = pp[0] = pp[1] = pp[2] = pp[3] = 0;          \
               }                                                     \
@@ -179,24 +180,24 @@
 #define OTV_ENTER                                                                \
           FT_BEGIN_STMNT                                                         \
             otvalid->debug_indent += 2;                                          \
-            FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 ));                     \
+            FT_TRACE4(( "%*.s", otvalid->debug_indent, "" ));                    \
             FT_TRACE4(( "%s table\n",                                            \
                         otvalid->debug_function_name[otvalid->nesting_level] )); \
           FT_END_STMNT
 
-#define OTV_NAME_ENTER( name )                               \
-          FT_BEGIN_STMNT                                     \
-            otvalid->debug_indent += 2;                      \
-            FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \
-            FT_TRACE4(( "%s table\n", name ));               \
+#define OTV_NAME_ENTER( name )                                \
+          FT_BEGIN_STMNT                                      \
+            otvalid->debug_indent += 2;                       \
+            FT_TRACE4(( "%*.s", otvalid->debug_indent, "" )); \
+            FT_TRACE4(( "%s table\n", name ));                \
           FT_END_STMNT
 
 #define OTV_EXIT  otvalid->debug_indent -= 2
 
-#define OTV_TRACE( s )                                       \
-          FT_BEGIN_STMNT                                     \
-            FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \
-            FT_TRACE4( s );                                  \
+#define OTV_TRACE( s )                                        \
+          FT_BEGIN_STMNT                                      \
+            FT_TRACE4(( "%*.s", otvalid->debug_indent, "" )); \
+            FT_TRACE4( s );                                   \
           FT_END_STMNT
 
 #else   /* !FT_DEBUG_LEVEL_TRACE */
diff --git a/src/otvalid/otverror.h b/src/otvalid/otverror.h
index 24e8d1d..4c4049c 100644
--- a/src/otvalid/otverror.h
+++ b/src/otvalid/otverror.h
@@ -4,7 +4,7 @@
  *
  *   OpenType validation module error codes (specification only).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef OTVERROR_H_
 #define OTVERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  OTV_Err_
 #define FT_ERR_BASE    FT_Mod_Err_OTvalid
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* OTVERROR_H_ */
 
diff --git a/src/otvalid/otvgdef.c b/src/otvalid/otvgdef.c
index 68c00a5..d62e818 100644
--- a/src/otvalid/otvgdef.c
+++ b/src/otvalid/otvgdef.c
@@ -4,7 +4,7 @@
  *
  *   OpenType GDEF table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -27,7 +27,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvgdef
+#define FT_COMPONENT  otvgdef
 
 
   /*************************************************************************/
diff --git a/src/otvalid/otvgpos.c b/src/otvalid/otvgpos.c
index 17f2437..f6102af 100644
--- a/src/otvalid/otvgpos.c
+++ b/src/otvalid/otvgpos.c
@@ -4,7 +4,7 @@
  *
  *   OpenType GPOS table validation (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -28,7 +28,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvgpos
+#define FT_COMPONENT  otvgpos
 
 
   static void
diff --git a/src/otvalid/otvgpos.h b/src/otvalid/otvgpos.h
index c216609..b5d0f54 100644
--- a/src/otvalid/otvgpos.h
+++ b/src/otvalid/otvgpos.h
@@ -4,7 +4,7 @@
  *
  *   OpenType GPOS table validator (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/otvalid/otvgsub.c b/src/otvalid/otvgsub.c
index 0180b1a..5d40d92 100644
--- a/src/otvalid/otvgsub.c
+++ b/src/otvalid/otvgsub.c
@@ -4,7 +4,7 @@
  *
  *   OpenType GSUB table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -27,7 +27,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvgsub
+#define FT_COMPONENT  otvgsub
 
 
   /*************************************************************************/
@@ -61,7 +61,8 @@
       {
         FT_Bytes  Coverage;
         FT_Int    DeltaGlyphID;
-        FT_Long   idx;
+        FT_UInt   first_cov, last_cov;
+        FT_UInt   first_idx, last_idx;
 
 
         OTV_LIMIT_CHECK( 4 );
@@ -70,12 +71,21 @@
 
         otv_Coverage_validate( Coverage, otvalid, -1 );
 
-        idx = (FT_Long)otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
-        if ( idx < 0 )
+        first_cov = otv_Coverage_get_first( Coverage );
+        last_cov  = otv_Coverage_get_last( Coverage );
+
+        /* These additions are modulo 65536. */
+        first_idx = (FT_UInt)( (FT_Int)first_cov + DeltaGlyphID ) & 0xFFFFU;
+        last_idx  = (FT_UInt)( (FT_Int)last_cov + DeltaGlyphID ) & 0xFFFFU;
+
+        /* Since the maximum number of glyphs is 2^16 - 1 = 65535, */
+        /* the largest possible glyph index is 65534.  For this    */
+        /* reason there can't be a wrap-around region, which would */
+        /* imply the use of the invalid glyph index 65535.         */
+        if ( first_idx > last_idx )
           FT_INVALID_DATA;
 
-        idx = (FT_Long)otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
-        if ( (FT_UInt)idx >= otvalid->glyph_count )
+        if ( last_idx >= otvalid->glyph_count )
           FT_INVALID_DATA;
       }
       break;
diff --git a/src/otvalid/otvjstf.c b/src/otvalid/otvjstf.c
index 7a5769a..712039c 100644
--- a/src/otvalid/otvjstf.c
+++ b/src/otvalid/otvjstf.c
@@ -4,7 +4,7 @@
  *
  *   OpenType JSTF table validation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -28,7 +28,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvjstf
+#define FT_COMPONENT  otvjstf
 
 
 #define JstfPriorityFunc  otv_JstfPriority_validate
diff --git a/src/otvalid/otvmath.c b/src/otvalid/otvmath.c
index 4a9f3b0..01fd863 100644
--- a/src/otvalid/otvmath.c
+++ b/src/otvalid/otvmath.c
@@ -4,7 +4,7 @@
  *
  *   OpenType MATH table validation (body).
  *
- * Copyright 2007-2018 by
+ * Copyright (C) 2007-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * Written by George Williams.
@@ -30,7 +30,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvmath
+#define FT_COMPONENT  otvmath
 
 
 
@@ -141,7 +141,7 @@
     OTV_OPTIONAL_TABLE( DeviceTableOffset );
 
 
-    /* OTV_NAME_ENTER( "MathKern" );*/
+    /* OTV_NAME_ENTER( "MathKern" ); */
 
     OTV_LIMIT_CHECK( 2 );
 
diff --git a/src/otvalid/otvmod.c b/src/otvalid/otvmod.c
index 5dd543b..d6057c5 100644
--- a/src/otvalid/otvmod.c
+++ b/src/otvalid/otvmod.c
@@ -4,7 +4,7 @@
  *
  *   FreeType's OpenType validation module implementation (body).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_OPENTYPE_VALIDATE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_OPENTYPE_VALIDATE_H
+#include <freetype/tttables.h>
+#include <freetype/tttags.h>
+#include <freetype/ftotval.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svotval.h>
 
 #include "otvmod.h"
 #include "otvalid.h"
@@ -35,7 +34,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_otvmodule
+#define FT_COMPONENT  otvmodule
 
 
   static FT_Error
@@ -54,7 +53,7 @@
     if ( error )
       goto Exit;
 
-    if ( FT_ALLOC( *table, *table_len ) )
+    if ( FT_QALLOC( *table, *table_len ) )
       goto Exit;
 
     error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
@@ -95,7 +94,7 @@
      */
     if ( face->num_glyphs > 0xFFFFL )
     {
-      FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ",
+      FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08lx) ",
                   face->num_glyphs ));
       FT_TRACE1(( "are not handled by OpenType tables\n" ));
       num_glyphs = 0xFFFF;
diff --git a/src/otvalid/otvmod.h b/src/otvalid/otvmod.h
index a08512f..f0e68db 100644
--- a/src/otvalid/otvmod.h
+++ b/src/otvalid/otvmod.h
@@ -5,7 +5,7 @@
  *   FreeType's OpenType validation module implementation
  *   (specification).
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,8 +21,7 @@
 #define OTVMOD_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/otvalid/rules.mk b/src/otvalid/rules.mk
index d4fc723..800cb87 100644
--- a/src/otvalid/rules.mk
+++ b/src/otvalid/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2004-2018 by
+# Copyright (C) 2004-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/pcf/Jamfile b/src/pcf/Jamfile
deleted file mode 100644
index 7b92b12..0000000
--- a/src/pcf/Jamfile
+++ /dev/null
@@ -1,32 +0,0 @@
-# FreeType 2 src/pcf Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) pcf ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = pcfdrivr
-               pcfread
-               pcfutil
-               ;
-  }
-  else
-  {
-    _sources = pcf ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/pcf Jamfile
diff --git a/src/pcf/pcf.c b/src/pcf/pcf.c
index 8ffd6e2..6b30fb2 100644
--- a/src/pcf/pcf.c
+++ b/src/pcf/pcf.c
@@ -26,7 +26,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "pcfdrivr.c"
 #include "pcfread.c"
diff --git a/src/pcf/pcf.h b/src/pcf/pcf.h
index 3c4eb6a..3134cc3 100644
--- a/src/pcf/pcf.h
+++ b/src/pcf/pcf.h
@@ -29,9 +29,8 @@
 #define PCF_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftdrv.h>
+#include <freetype/internal/ftstream.h>
 
 
 FT_BEGIN_HEADER
@@ -99,11 +98,25 @@
     FT_Short  ascent;
     FT_Short  descent;
     FT_Short  attributes;
-    FT_ULong  bits;
+
+    FT_ULong  bits;  /* offset into the PCF_BITMAPS table */
 
   } PCF_MetricRec, *PCF_Metric;
 
 
+  typedef struct  PCF_EncRec_
+  {
+    FT_UShort   firstCol;
+    FT_UShort   lastCol;
+    FT_UShort   firstRow;
+    FT_UShort   lastRow;
+    FT_UShort   defaultChar;
+
+    FT_UShort*  offset;
+
+  } PCF_EncRec, *PCF_Enc;
+
+
   typedef struct  PCF_AccelRec_
   {
     FT_Byte        noOverlap;
@@ -128,41 +141,28 @@
    * This file uses X11 terminology for PCF data; an `encoding' in X11 speak
    * is the same as a `character code' in FreeType speak.
    */
-  typedef struct  PCF_EncodingRec_
-  {
-    FT_ULong   enc;
-    FT_UShort  glyph;  /* an index into PCF_Face's `metrics' array */
-
-  } PCF_EncodingRec, *PCF_Encoding;
-
-
   typedef struct  PCF_FaceRec_
   {
-    FT_FaceRec     root;
+    FT_FaceRec    root;
 
-    FT_StreamRec   comp_stream;
-    FT_Stream      comp_source;
+    FT_StreamRec  comp_stream;
+    FT_Stream     comp_source;
 
-    char*          charset_encoding;
-    char*          charset_registry;
+    char*         charset_encoding;
+    char*         charset_registry;
 
-    PCF_TocRec     toc;
-    PCF_AccelRec   accel;
+    PCF_TocRec    toc;
+    PCF_AccelRec  accel;
 
-    int            nprops;
-    PCF_Property   properties;
+    int           nprops;
+    PCF_Property  properties;
 
-    FT_ULong       nmetrics;
-    PCF_Metric     metrics;
-    FT_ULong       nencodings;
-    PCF_Encoding   encodings;
+    FT_ULong      nmetrics;
+    PCF_Metric    metrics;
 
-    FT_UShort      defaultChar;
+    PCF_EncRec    enc;
 
-    FT_ULong       bitmapsFormat;
-
-    FT_CharMap     charmap_handle;
-    FT_CharMapRec  charmap;  /* a single charmap per face */
+    FT_ULong      bitmapsFormat;
 
   } PCF_FaceRec, *PCF_Face;
 
diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c
index e2f7e7c..bfa6eac 100644
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -25,17 +25,16 @@
 */
 
 
-#include <ft2build.h>
 
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_GZIP_H
-#include FT_LZW_H
-#include FT_BZIP2_H
-#include FT_ERRORS_H
-#include FT_BDF_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftgzip.h>
+#include <freetype/ftlzw.h>
+#include <freetype/ftbzip2.h>
+#include <freetype/fterrors.h>
+#include <freetype/ftbdf.h>
+#include <freetype/ttnameid.h>
 
 #include "pcf.h"
 #include "pcfdrivr.h"
@@ -45,12 +44,12 @@
 #include "pcfutil.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pcfread
+#define FT_COMPONENT  pcfread
 
-#include FT_SERVICE_BDF_H
-#include FT_SERVICE_FONT_FORMAT_H
-#include FT_SERVICE_PROPERTIES_H
-#include FT_DRIVER_H
+#include <freetype/internal/services/svbdf.h>
+#include <freetype/internal/services/svfntfmt.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/ftdriver.h>
 
 
   /**************************************************************************
@@ -60,7 +59,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pcfdriver
+#define FT_COMPONENT  pcfdriver
 
 
   /*
@@ -69,9 +68,8 @@
    */
   typedef struct  PCF_CMapRec_
   {
-    FT_CMapRec    root;
-    FT_ULong      num_encodings;
-    PCF_Encoding  encodings;
+    FT_CMapRec  root;
+    PCF_Enc     enc;
 
   } PCF_CMapRec, *PCF_CMap;
 
@@ -86,8 +84,7 @@
     FT_UNUSED( init_data );
 
 
-    cmap->num_encodings = face->nencodings;
-    cmap->encodings     = face->encodings;
+    cmap->enc = &face->enc;
 
     return FT_Err_Ok;
   }
@@ -99,8 +96,7 @@
     PCF_CMap  cmap = (PCF_CMap)pcfcmap;
 
 
-    cmap->encodings     = NULL;
-    cmap->num_encodings = 0;
+    cmap->enc = NULL;
   }
 
 
@@ -108,36 +104,19 @@
   pcf_cmap_char_index( FT_CMap    pcfcmap,  /* PCF_CMap */
                        FT_UInt32  charcode )
   {
-    PCF_CMap      cmap      = (PCF_CMap)pcfcmap;
-    PCF_Encoding  encodings = cmap->encodings;
-    FT_ULong      min, max, mid;
-    FT_UInt       result    = 0;
+    PCF_Enc  enc = ( (PCF_CMap)pcfcmap )->enc;
+
+    FT_UInt32  i = ( charcode >> 8   ) - enc->firstRow;
+    FT_UInt32  j = ( charcode & 0xFF ) - enc->firstCol;
+    FT_UInt32  h = enc->lastRow - enc->firstRow + 1;
+    FT_UInt32  w = enc->lastCol - enc->firstCol + 1;
 
 
-    min = 0;
-    max = cmap->num_encodings;
+    /* wrapped around "negative" values are also rejected */
+    if ( i >= h || j >= w )
+      return 0;
 
-    while ( min < max )
-    {
-      FT_ULong  code;
-
-
-      mid  = ( min + max ) >> 1;
-      code = encodings[mid].enc;
-
-      if ( charcode == code )
-      {
-        result = encodings[mid].glyph;
-        break;
-      }
-
-      if ( charcode < code )
-        max = mid;
-      else
-        min = mid + 1;
-    }
-
-    return result;
+    return (FT_UInt)enc->offset[i * w + j];
   }
 
 
@@ -145,52 +124,33 @@
   pcf_cmap_char_next( FT_CMap    pcfcmap,   /* PCF_CMap */
                       FT_UInt32  *acharcode )
   {
-    PCF_CMap      cmap      = (PCF_CMap)pcfcmap;
-    PCF_Encoding  encodings = cmap->encodings;
-    FT_ULong      min, max, mid;
-    FT_ULong      charcode  = *acharcode + 1;
-    FT_UInt       result    = 0;
+    PCF_Enc    enc = ( (PCF_CMap)pcfcmap )->enc;
+    FT_UInt32  charcode = *acharcode + 1;
+
+    FT_UInt32  i = ( charcode >> 8   ) - enc->firstRow;
+    FT_UInt32  j = ( charcode & 0xFF ) - enc->firstCol;
+    FT_UInt32  h = enc->lastRow - enc->firstRow + 1;
+    FT_UInt32  w = enc->lastCol - enc->firstCol + 1;
+
+    FT_UInt  result = 0;
 
 
-    min = 0;
-    max = cmap->num_encodings;
+    /* adjust wrapped around "negative" values */
+    if ( (FT_Int32)i < 0 )
+      i = 0;
+    if ( (FT_Int32)j < 0 )
+      j = 0;
 
-    while ( min < max )
-    {
-      FT_ULong  code;
-
-
-      mid  = ( min + max ) >> 1;
-      code = encodings[mid].enc;
-
-      if ( charcode == code )
+    for ( ; i < h; i++, j = 0 )
+      for ( ; j < w; j++ )
       {
-        result = encodings[mid].glyph;
-        goto Exit;
+        result = (FT_UInt)enc->offset[i * w + j];
+        if ( result != 0xFFFFU )
+          goto Exit;
       }
 
-      if ( charcode < code )
-        max = mid;
-      else
-        min = mid + 1;
-    }
-
-    charcode = 0;
-    if ( min < cmap->num_encodings )
-    {
-      charcode = encodings[min].enc;
-      result   = encodings[min].glyph;
-    }
-
   Exit:
-    if ( charcode > 0xFFFFFFFFUL )
-    {
-      FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));
-      *acharcode = 0;
-      /* XXX: result should be changed to indicate an overflow error */
-    }
-    else
-      *acharcode = (FT_UInt32)charcode;
+    *acharcode = ( ( i + enc->firstRow ) << 8 ) | ( j + enc->firstCol );
 
     return result;
   }
@@ -221,8 +181,8 @@
 
     memory = FT_FACE_MEMORY( face );
 
-    FT_FREE( face->encodings );
     FT_FREE( face->metrics );
+    FT_FREE( face->enc.offset );
 
     /* free properties */
     if ( face->properties )
@@ -630,8 +590,9 @@
         if ( prop->value.l > 0x7FFFFFFFL          ||
              prop->value.l < ( -1 - 0x7FFFFFFFL ) )
         {
-          FT_TRACE1(( "pcf_get_bdf_property:" ));
-          FT_TRACE1(( " too large integer 0x%x is truncated\n" ));
+          FT_TRACE2(( "pcf_get_bdf_property:"
+                      " too large integer 0x%lx is truncated\n",
+                      prop->value.l ));
         }
 
         /*
@@ -728,7 +689,7 @@
 
 #endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
 
-    FT_TRACE0(( "pcf_property_set: missing property `%s'\n",
+    FT_TRACE2(( "pcf_property_set: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
@@ -766,7 +727,7 @@
 
 #endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
 
-    FT_TRACE0(( "pcf_property_get: missing property `%s'\n",
+    FT_TRACE2(( "pcf_property_get: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
diff --git a/src/pcf/pcfdrivr.h b/src/pcf/pcfdrivr.h
index 73db082..d465393 100644
--- a/src/pcf/pcfdrivr.h
+++ b/src/pcf/pcfdrivr.h
@@ -28,8 +28,7 @@
 #ifndef PCFDRIVR_H_
 #define PCFDRIVR_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/pcf/pcferror.h b/src/pcf/pcferror.h
index 2e69d1d..8b9e990 100644
--- a/src/pcf/pcferror.h
+++ b/src/pcf/pcferror.h
@@ -25,7 +25,7 @@
 #ifndef PCFERROR_H_
 #define PCFERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  PCF_Err_
 #define FT_ERR_BASE    FT_Mod_Err_PCF
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* PCFERROR_H_ */
 
diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c
index 14cce67..f167bcb 100644
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -25,11 +25,10 @@
 */
 
 
-#include <ft2build.h>
 
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
 
 #include "pcf.h"
 #include "pcfread.h"
@@ -44,7 +43,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pcfread
+#define FT_COMPONENT  pcfread
 
 
 #ifdef FT_DEBUG_LEVEL_TRACE
@@ -122,13 +121,13 @@
          toc->count > 9                     )
     {
       FT_TRACE0(( "pcf_read_TOC: adjusting number of tables"
-                  " (from %d to %d)\n",
+                  " (from %ld to %ld)\n",
                   toc->count,
                   FT_MIN( stream->size >> 4, 9 ) ));
       toc->count = FT_MIN( stream->size >> 4, 9 );
     }
 
-    if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
+    if ( FT_QNEW_ARRAY( face->toc.tables, toc->count ) )
       return error;
 
     tables = face->toc.tables;
@@ -239,10 +238,10 @@
       {
         for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
               j++ )
-          if ( tables[i].type == (FT_UInt)( 1 << j ) )
+          if ( tables[i].type == 1UL << j )
             name = tableNames[j];
 
-        FT_TRACE4(( "  %d: type=%s, format=0x%X,"
+        FT_TRACE4(( "  %d: type=%s, format=0x%lX,"
                     " size=%ld (0x%lX), offset=%ld (0x%lX)\n",
                     i, name,
                     tables[i].format,
@@ -502,8 +501,8 @@
     if ( FT_READ_ULONG_LE( format ) )
       goto Bail;
 
-    FT_TRACE4(( "pcf_get_properties:\n"
-                "  format: 0x%lX (%s)\n",
+    FT_TRACE4(( "pcf_get_properties:\n" ));
+    FT_TRACE4(( "  format: 0x%lX (%s)\n",
                 format,
                 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
 
@@ -541,7 +540,7 @@
 
     face->nprops = (int)nprops;
 
-    if ( FT_NEW_ARRAY( props, nprops ) )
+    if ( FT_QNEW_ARRAY( props, nprops ) )
       goto Bail;
 
     for ( i = 0; i < nprops; i++ )
@@ -608,13 +607,13 @@
     }
 
     /* allocate one more byte so that we have a final null byte */
-    if ( FT_NEW_ARRAY( strings, string_size + 1 ) )
+    if ( FT_QALLOC( strings, string_size + 1 )  ||
+         FT_STREAM_READ( strings, string_size ) )
       goto Bail;
 
-    error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size );
-    if ( error )
-      goto Bail;
+    strings[string_size] = '\0';
 
+    /* zero out in case of failure */
     if ( FT_NEW_ARRAY( properties, nprops ) )
       goto Bail;
 
@@ -661,7 +660,7 @@
       {
         properties[i].value.l = props[i].value;
 
-        FT_TRACE4(( " %d\n", properties[i].value.l ));
+        FT_TRACE4(( " %ld\n", properties[i].value.l ));
       }
     }
 
@@ -698,8 +697,8 @@
     if ( FT_READ_ULONG_LE( format ) )
       goto Bail;
 
-    FT_TRACE4(( "pcf_get_metrics:\n"
-                "  format: 0x%lX (%s, %s)\n",
+    FT_TRACE4(( "pcf_get_metrics:\n" ));
+    FT_TRACE4(( "  format: 0x%lX (%s, %s)\n",
                 format,
                 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB",
                 PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ?
@@ -743,33 +742,39 @@
     if ( !orig_nmetrics )
       return FT_THROW( Invalid_Table );
 
-    /* PCF is a format from ancient times; Unicode was in its       */
-    /* infancy, and widely used two-byte character sets for CJK     */
-    /* scripts (Big 5, GB 2312, JIS X 0208, etc.) did have at most  */
-    /* 15000 characters.  Even the more exotic CNS 11643 and CCCII  */
-    /* standards, which were essentially three-byte character sets, */
-    /* provided less then 65536 assigned characters.                */
-    /*                                                              */
-    /* While technically possible to have a larger number of glyphs */
-    /* in PCF files, we thus limit the number to 65536.             */
-    if ( orig_nmetrics > 65536 )
+    /*
+     * PCF is a format from ancient times; Unicode was in its infancy, and
+     * widely used two-byte character sets for CJK scripts (Big 5, GB 2312,
+     * JIS X 0208, etc.) did have at most 15000 characters.  Even the more
+     * exotic CNS 11643 and CCCII standards, which were essentially
+     * three-byte character sets, provided less then 65536 assigned
+     * characters.
+     *
+     * While technically possible to have a larger number of glyphs in PCF
+     * files, we thus limit the number to 65535, taking into account that we
+     * synthesize the metrics of glyph 0 to be a copy of the `default
+     * character', and that 0xFFFF in the encodings array indicates a
+     * missing glyph.
+     */
+    if ( orig_nmetrics > 65534 )
     {
       FT_TRACE0(( "pcf_get_metrics:"
-                  " only loading first 65536 metrics\n" ));
-      nmetrics = 65536;
+                  " only loading first 65534 metrics\n" ));
+      nmetrics = 65534;
     }
     else
       nmetrics = orig_nmetrics;
 
-    face->nmetrics = nmetrics;
+    face->nmetrics = nmetrics + 1;
 
-    if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
+    if ( FT_QNEW_ARRAY( face->metrics, face->nmetrics ) )
       return error;
 
-    metrics = face->metrics;
+    /* we handle glyph index 0 later on */
+    metrics = face->metrics + 1;
 
     FT_TRACE4(( "\n" ));
-    for ( i = 0; i < nmetrics; i++, metrics++ )
+    for ( i = 1; i < face->nmetrics; i++, metrics++ )
     {
       FT_TRACE5(( "  idx %ld:", i ));
       error = pcf_get_metric( stream, format, metrics );
@@ -792,7 +797,7 @@
         metrics->descent          = 0;
 
         FT_TRACE0(( "pcf_get_metrics:"
-                    " invalid metrics for glyph %d\n", i ));
+                    " invalid metrics for glyph %ld\n", i ));
       }
     }
 
@@ -808,12 +813,10 @@
   pcf_get_bitmaps( FT_Stream  stream,
                    PCF_Face   face )
   {
-    FT_Error   error;
-    FT_Memory  memory  = FT_FACE( face )->memory;
-    FT_ULong*  offsets = NULL;
-    FT_ULong   bitmapSizes[GLYPHPADOPTIONS];
-    FT_ULong   format, size;
-    FT_ULong   nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
+    FT_Error  error;
+    FT_ULong  bitmapSizes[GLYPHPADOPTIONS];
+    FT_ULong  format, size, pos;
+    FT_ULong  nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
 
 
     error = pcf_seek_to_table_type( stream,
@@ -837,17 +840,16 @@
 
     FT_Stream_ExitFrame( stream );
 
-    FT_TRACE4(( "pcf_get_bitmaps:\n"
-                "  format: 0x%lX\n"
-                "          (%s, %s,\n"
-                "           padding=%d bit%s, scanning=%d bit%s)\n",
-                format,
+    FT_TRACE4(( "pcf_get_bitmaps:\n" ));
+    FT_TRACE4(( "  format: 0x%lX\n", format ));
+    FT_TRACE4(( "          (%s, %s,\n",
                 PCF_BYTE_ORDER( format ) == MSBFirst
                   ? "most significant byte first"
                   : "least significant byte first",
                 PCF_BIT_ORDER( format ) == MSBFirst
                   ? "most significant bit first"
-                  : "least significant bit first",
+                  : "least significant bit first" ));
+    FT_TRACE4(( "           padding=%d bit%s, scanning=%d bit%s)\n",
                 8 << PCF_GLYPH_PAD_INDEX( format ),
                 ( 8 << PCF_GLYPH_PAD_INDEX( format ) ) == 1 ? "" : "s",
                 8 << PCF_SCAN_UNIT_INDEX( format ),
@@ -859,31 +861,46 @@
     FT_TRACE4(( "  number of bitmaps: %ld\n", orig_nbitmaps ));
 
     /* see comment in `pcf_get_metrics' */
-    if ( orig_nbitmaps > 65536 )
+    if ( orig_nbitmaps > 65534 )
     {
       FT_TRACE0(( "pcf_get_bitmaps:"
-                  " only loading first 65536 bitmaps\n" ));
-      nbitmaps = 65536;
+                  " only loading first 65534 bitmaps\n" ));
+      nbitmaps = 65534;
     }
     else
       nbitmaps = orig_nbitmaps;
 
-    if ( nbitmaps != face->nmetrics )
+    /* no extra bitmap for glyph 0 */
+    if ( nbitmaps != face->nmetrics - 1 )
       return FT_THROW( Invalid_File_Format );
 
-    if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
-      return error;
+    /* start position of bitmap data */
+    pos = stream->pos + nbitmaps * 4 + 4 * 4;
 
     FT_TRACE5(( "\n" ));
-    for ( i = 0; i < nbitmaps; i++ )
+    for ( i = 1; i <= nbitmaps; i++ )
     {
+      FT_ULong  offset;
+
+
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-        (void)FT_READ_ULONG( offsets[i] );
+        (void)FT_READ_ULONG( offset );
       else
-        (void)FT_READ_ULONG_LE( offsets[i] );
+        (void)FT_READ_ULONG_LE( offset );
 
       FT_TRACE5(( "  bitmap %lu: offset %lu (0x%lX)\n",
-                  i, offsets[i], offsets[i] ));
+                  i, offset, offset ));
+
+      /* right now, we only check the offset with a rough estimate; */
+      /* actual bitmaps are only loaded on demand                   */
+      if ( offset > size )
+      {
+        FT_TRACE0(( "pcf_get_bitmaps:"
+                    " invalid offset to bitmap data of glyph %lu\n", i ));
+        face->metrics[i].bits = pos;
+      }
+      else
+        face->metrics[i].bits = pos + offset;
     }
     if ( error )
       goto Bail;
@@ -899,35 +916,20 @@
 
       sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
 
-      FT_TRACE4(( "  %ld-bit padding implies a size of %lu\n",
+      FT_TRACE4(( "  %d-bit padding implies a size of %lu\n",
                   8 << i, bitmapSizes[i] ));
     }
 
-    FT_TRACE4(( "  %lu bitmaps, using %ld-bit padding\n",
+    FT_TRACE4(( "  %lu bitmaps, using %d-bit padding\n",
                 nbitmaps,
                 8 << PCF_GLYPH_PAD_INDEX( format ) ));
     FT_TRACE4(( "  bitmap size: %lu\n", sizebitmaps ));
 
     FT_UNUSED( sizebitmaps );       /* only used for debugging */
 
-    /* right now, we only check the bitmap offsets; */
-    /* actual bitmaps are only loaded on demand     */
-    for ( i = 0; i < nbitmaps; i++ )
-    {
-      /* rough estimate */
-      if ( offsets[i] > size )
-      {
-        FT_TRACE0(( "pcf_get_bitmaps:"
-                    " invalid offset to bitmap data of glyph %lu\n", i ));
-      }
-      else
-        face->metrics[i].bits = stream->pos + offsets[i];
-    }
-
     face->bitmapsFormat = format;
 
   Bail:
-    FT_FREE( offsets );
     return error;
   }
 
@@ -936,22 +938,54 @@
    * This file uses X11 terminology for PCF data; an `encoding' in X11 speak
    * is the same as a character code in FreeType speak.
    */
+#define PCF_ENC_SIZE  10
+
+  static
+  const FT_Frame_Field  pcf_enc_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_EncRec
+
+    FT_FRAME_START( PCF_ENC_SIZE ),
+      FT_FRAME_USHORT_LE( firstCol ),
+      FT_FRAME_USHORT_LE( lastCol ),
+      FT_FRAME_USHORT_LE( firstRow ),
+      FT_FRAME_USHORT_LE( lastRow ),
+      FT_FRAME_USHORT_LE( defaultChar ),
+    FT_FRAME_END
+  };
+
+
+  static
+  const FT_Frame_Field  pcf_enc_msb_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_EncRec
+
+    FT_FRAME_START( PCF_ENC_SIZE ),
+      FT_FRAME_USHORT( firstCol ),
+      FT_FRAME_USHORT( lastCol ),
+      FT_FRAME_USHORT( firstRow ),
+      FT_FRAME_USHORT( lastRow ),
+      FT_FRAME_USHORT( defaultChar ),
+    FT_FRAME_END
+  };
+
+
   static FT_Error
   pcf_get_encodings( FT_Stream  stream,
                      PCF_Face   face )
   {
-    FT_Error      error;
-    FT_Memory     memory = FT_FACE( face )->memory;
-    FT_ULong      format, size;
-    FT_UShort     firstCol, lastCol;
-    FT_UShort     firstRow, lastRow;
-    FT_ULong      nencoding;
-    FT_UShort     defaultCharRow, defaultCharCol;
-    FT_UShort     encodingOffset, defaultCharEncodingOffset;
-    FT_UShort     i, j;
-    FT_Byte*      pos;
-    FT_ULong      k;
-    PCF_Encoding  encoding = NULL;
+    FT_Error    error;
+    FT_Memory   memory = FT_FACE( face )->memory;
+    FT_ULong    format, size;
+    PCF_Enc     enc = &face->enc;
+    FT_ULong    nencoding;
+    FT_UShort*  offset;
+    FT_UShort   defaultCharRow, defaultCharCol;
+    FT_UShort   encodingOffset, defaultCharEncodingOffset;
+    FT_UShort   i, j;
+    FT_Byte*    pos;
 
 
     error = pcf_seek_to_table_type( stream,
@@ -961,126 +995,125 @@
                                     &format,
                                     &size );
     if ( error )
-      return error;
+      goto Bail;
 
-    error = FT_Stream_EnterFrame( stream, 14 );
-    if ( error )
-      return error;
+    if ( FT_READ_ULONG_LE( format ) )
+      goto Bail;
 
-    format = FT_GET_ULONG_LE();
-
-    /* X11's reference implementation uses the equivalent to  */
-    /* `FT_GET_SHORT' for `defaultChar', however this doesn't */
-    /* make sense for most encodings.                         */
-    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-    {
-      firstCol          = FT_GET_USHORT();
-      lastCol           = FT_GET_USHORT();
-      firstRow          = FT_GET_USHORT();
-      lastRow           = FT_GET_USHORT();
-      face->defaultChar = FT_GET_USHORT();
-    }
-    else
-    {
-      firstCol          = FT_GET_USHORT_LE();
-      lastCol           = FT_GET_USHORT_LE();
-      firstRow          = FT_GET_USHORT_LE();
-      lastRow           = FT_GET_USHORT_LE();
-      face->defaultChar = FT_GET_USHORT_LE();
-    }
-
-    FT_Stream_ExitFrame( stream );
-
-    FT_TRACE4(( "pcf_get_encodings:\n"
-                "  format: 0x%lX (%s)\n",
+    FT_TRACE4(( "pcf_get_encodings:\n" ));
+    FT_TRACE4(( "  format: 0x%lX (%s)\n",
                 format,
                 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
 
-    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
+         !PCF_FORMAT_MATCH( format, PCF_BDF_ENCODINGS )  )
       return FT_THROW( Invalid_File_Format );
 
-    FT_TRACE4(( "  firstCol 0x%X, lastCol 0x%X\n"
-                "  firstRow 0x%X, lastRow 0x%X\n"
-                "  defaultChar 0x%X\n",
-                firstCol, lastCol,
-                firstRow, lastRow,
-                face->defaultChar ));
+    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+    {
+      if ( FT_STREAM_READ_FIELDS( pcf_enc_msb_header, enc ) )
+        goto Bail;
+    }
+    else
+    {
+      if ( FT_STREAM_READ_FIELDS( pcf_enc_header, enc ) )
+        goto Bail;
+    }
+
+    FT_TRACE4(( "  firstCol 0x%X, lastCol 0x%X\n",
+                enc->firstCol, enc->lastCol ));
+    FT_TRACE4(( "  firstRow 0x%X, lastRow 0x%X\n",
+                enc->firstRow, enc->lastRow ));
+    FT_TRACE4(( "  defaultChar 0x%X\n",
+                enc->defaultChar ));
 
     /* sanity checks; we limit numbers of rows and columns to 256 */
-    if ( firstCol > lastCol ||
-         lastCol  > 0xFF    ||
-         firstRow > lastRow ||
-         lastRow  > 0xFF    )
+    if ( enc->firstCol > enc->lastCol ||
+         enc->lastCol  > 0xFF         ||
+         enc->firstRow > enc->lastRow ||
+         enc->lastRow  > 0xFF         )
       return FT_THROW( Invalid_Table );
 
-    nencoding = (FT_ULong)( lastCol - firstCol + 1 ) *
-                (FT_ULong)( lastRow - firstRow + 1 );
+    FT_TRACE5(( "\n" ));
 
-    if ( FT_NEW_ARRAY( encoding, nencoding ) )
-      return error;
+    defaultCharRow = enc->defaultChar >> 8;
+    defaultCharCol = enc->defaultChar & 0xFF;
+
+    /* validate default character */
+    if ( defaultCharRow < enc->firstRow ||
+         defaultCharRow > enc->lastRow  ||
+         defaultCharCol < enc->firstCol ||
+         defaultCharCol > enc->lastCol  )
+    {
+      enc->defaultChar = enc->firstRow * 256U + enc->firstCol;
+      FT_TRACE0(( "pcf_get_encodings:"
+                  " Invalid default character set to %u\n",
+                  enc->defaultChar ));
+
+      defaultCharRow = enc->firstRow;
+      defaultCharCol = enc->firstCol;
+    }
+
+    nencoding = (FT_ULong)( enc->lastCol - enc->firstCol + 1 ) *
+                (FT_ULong)( enc->lastRow - enc->firstRow + 1 );
 
     error = FT_Stream_EnterFrame( stream, 2 * nencoding );
     if ( error )
       goto Bail;
 
-    FT_TRACE5(( "\n" ));
-
-    defaultCharRow = face->defaultChar >> 8;
-    defaultCharCol = face->defaultChar & 0xFF;
-
-    /* validate default character */
-    if ( defaultCharRow < firstRow ||
-         defaultCharRow > lastRow  ||
-         defaultCharCol < firstCol ||
-         defaultCharCol > lastCol  )
-    {
-      face->defaultChar = firstRow * 256U + firstCol;
-      FT_TRACE0(( "pcf_get_encodings:"
-                  " Invalid default character set to %u\n",
-                  face->defaultChar ));
-
-      defaultCharRow = face->defaultChar >> 8;
-      defaultCharCol = face->defaultChar & 0xFF;
-    }
-
-    /* FreeType mandates that glyph index 0 is the `undefined glyph',  */
-    /* which PCF calls the `default character'.  For this reason, we   */
-    /* swap the positions of glyph index 0 and the index corresponding */
-    /* to `defaultChar' in case they are different.                    */
-
-    /* `stream->cursor' still points at the beginning of the frame; */
-    /* we can thus easily get the offset to the default character   */
+    /*
+     * FreeType mandates that glyph index 0 is the `undefined glyph', which
+     * PCF calls the `default character'.  However, FreeType needs glyph
+     * index 0 to be used for the undefined glyph only, which is is not the
+     * case for PCF.  For this reason, we add one slot for glyph index 0 and
+     * simply copy the default character to it.
+     *
+     * `stream->cursor' still points to the beginning of the frame; we can
+     * thus easily get the offset to the default character.
+     */
     pos = stream->cursor +
-            2 * ( ( defaultCharRow - firstRow ) * ( lastCol - firstCol + 1 ) +
-                  defaultCharCol - firstCol );
+            2 * ( ( defaultCharRow - enc->firstRow ) *
+                    ( enc->lastCol - enc->firstCol + 1 ) +
+                  defaultCharCol - enc->firstCol );
 
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
       defaultCharEncodingOffset = FT_PEEK_USHORT( pos );
     else
       defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos );
 
-    if ( defaultCharEncodingOffset >= face->nmetrics )
+    if ( defaultCharEncodingOffset == 0xFFFF )
     {
       FT_TRACE0(( "pcf_get_encodings:"
-                  " Invalid glyph index for default character,"
-                  " setting to zero\n" ));
-      defaultCharEncodingOffset = 0;
+                  " No glyph for default character,\n" ));
+      FT_TRACE0(( "                  "
+                  " setting it to the first glyph of the font\n" ));
+      defaultCharEncodingOffset = 1;
+    }
+    else
+    {
+      defaultCharEncodingOffset++;
+
+      if ( defaultCharEncodingOffset >= face->nmetrics )
+      {
+        FT_TRACE0(( "pcf_get_encodings:"
+                    " Invalid glyph index for default character,\n" ));
+        FT_TRACE0(( "                  "
+                    " setting it to the first glyph of the font\n" ));
+        defaultCharEncodingOffset = 1;
+      }
     }
 
-    if ( defaultCharEncodingOffset )
+    /* copy metrics of default character to index 0 */
+    face->metrics[0] = face->metrics[defaultCharEncodingOffset];
+
+    if ( FT_QNEW_ARRAY( enc->offset, nencoding ) )
+      goto Bail;
+
+    /* now loop over all values */
+    offset = enc->offset;
+    for ( i = enc->firstRow; i <= enc->lastRow; i++ )
     {
-      /* do the swapping */
-      PCF_MetricRec  tmp = face->metrics[defaultCharEncodingOffset];
-
-
-      face->metrics[defaultCharEncodingOffset] = face->metrics[0];
-      face->metrics[0]                         = tmp;
-    }
-
-    k = 0;
-    for ( i = firstRow; i <= lastRow; i++ )
-    {
-      for ( j = firstCol; j <= lastCol; j++ )
+      for ( j = enc->firstCol; j <= enc->lastCol; j++ )
       {
         /* X11's reference implementation uses the equivalent to  */
         /* `FT_GET_SHORT', however PCF fonts with more than 32768 */
@@ -1091,35 +1124,14 @@
         else
           encodingOffset = FT_GET_USHORT_LE();
 
-        if ( encodingOffset != 0xFFFFU )
-        {
-          if ( encodingOffset == defaultCharEncodingOffset )
-            encodingOffset = 0;
-          else if ( encodingOffset == 0 )
-            encodingOffset = defaultCharEncodingOffset;
-
-          encoding[k].enc   = i * 256U + j;
-          encoding[k].glyph = encodingOffset;
-
-          FT_TRACE5(( "  code %u (0x%04X): idx %u\n",
-                      encoding[k].enc, encoding[k].enc, encoding[k].glyph ));
-
-          k++;
-        }
+        /* everything is off by 1 due to the artificial glyph 0 */
+        *offset++ = encodingOffset == 0xFFFF ? 0xFFFF
+                                             : encodingOffset + 1;
       }
     }
     FT_Stream_ExitFrame( stream );
 
-    if ( FT_RENEW_ARRAY( encoding, nencoding, k ) )
-      goto Bail;
-
-    face->nencodings = k;
-    face->encodings  = encoding;
-
-    return error;
-
   Bail:
-    FT_FREE( encoding );
     return error;
   }
 
@@ -1190,10 +1202,10 @@
     if ( FT_READ_ULONG_LE( format ) )
       goto Bail;
 
-    FT_TRACE4(( "pcf_get_accel%s:\n"
-                "  format: 0x%lX (%s, %s)\n",
+    FT_TRACE4(( "pcf_get_accel%s:\n",
                 type == PCF_BDF_ACCELERATORS ? " (getting BDF accelerators)"
-                                             : "",
+                                             : "" ));
+    FT_TRACE4(( "  format: 0x%lX (%s, %s)\n",
                 format,
                 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB",
                 PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ?
@@ -1215,16 +1227,16 @@
     }
 
     FT_TRACE5(( "  noOverlap=%s, constantMetrics=%s,"
-                " terminalFont=%s, constantWidth=%s\n"
-                "  inkInside=%s, inkMetrics=%s, drawDirection=%s\n"
-                "  fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n",
+                " terminalFont=%s, constantWidth=%s\n",
                 accel->noOverlap ? "yes" : "no",
                 accel->constantMetrics ? "yes" : "no",
                 accel->terminalFont ? "yes" : "no",
-                accel->constantWidth ? "yes" : "no",
+                accel->constantWidth ? "yes" : "no" ));
+    FT_TRACE5(( "  inkInside=%s, inkMetrics=%s, drawDirection=%s\n",
                 accel->inkInside ? "yes" : "no",
                 accel->inkMetrics ? "yes" : "no",
-                accel->drawDirection ? "RTL" : "LTR",
+                accel->drawDirection ? "RTL" : "LTR" ));
+    FT_TRACE5(( "  fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n",
                 accel->fontAscent,
                 accel->fontDescent,
                 accel->maxOverlap ));
@@ -1233,13 +1245,13 @@
     if ( FT_ABS( accel->fontAscent ) > 0x7FFF )
     {
       accel->fontAscent = accel->fontAscent < 0 ? -0x7FFF : 0x7FFF;
-      FT_TRACE0(( "pfc_get_accel: clamping font ascent to value %d\n",
+      FT_TRACE0(( "pfc_get_accel: clamping font ascent to value %ld\n",
                   accel->fontAscent ));
     }
     if ( FT_ABS( accel->fontDescent ) > 0x7FFF )
     {
       accel->fontDescent = accel->fontDescent < 0 ? -0x7FFF : 0x7FFF;
-      FT_TRACE0(( "pfc_get_accel: clamping font descent to value %d\n",
+      FT_TRACE0(( "pfc_get_accel: clamping font descent to value %ld\n",
                   accel->fontDescent ));
     }
 
@@ -1293,9 +1305,8 @@
 
     PCF_Property  prop;
 
-    size_t  nn, len;
-    char*   strings[4] = { NULL, NULL, NULL, NULL };
-    size_t  lengths[4];
+    const char*  strings[4] = { NULL, NULL, NULL, NULL };
+    size_t       lengths[4], nn, len;
 
 
     face->style_flags = 0;
@@ -1307,8 +1318,8 @@
     {
       face->style_flags |= FT_STYLE_FLAG_ITALIC;
       strings[2] = ( *(prop->value.atom) == 'O' ||
-                     *(prop->value.atom) == 'o' ) ? (char *)"Oblique"
-                                                  : (char *)"Italic";
+                     *(prop->value.atom) == 'o' ) ? "Oblique"
+                                                  : "Italic";
     }
 
     prop = pcf_find_property( pcf, "WEIGHT_NAME" );
@@ -1316,20 +1327,20 @@
          ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
     {
       face->style_flags |= FT_STYLE_FLAG_BOLD;
-      strings[1] = (char*)"Bold";
+      strings[1] = "Bold";
     }
 
     prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
     if ( prop && prop->isString                                        &&
          *(prop->value.atom)                                           &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[3] = (char*)( prop->value.atom );
+      strings[3] = (const char*)( prop->value.atom );
 
     prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
     if ( prop && prop->isString                                        &&
          *(prop->value.atom)                                           &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[0] = (char*)( prop->value.atom );
+      strings[0] = (const char*)( prop->value.atom );
 
     for ( len = 0, nn = 0; nn < 4; nn++ )
     {
@@ -1343,7 +1354,7 @@
 
     if ( len == 0 )
     {
-      strings[0] = (char*)"Regular";
+      strings[0] = "Regular";
       lengths[0] = ft_strlen( strings[0] );
       len        = lengths[0] + 1;
     }
@@ -1352,14 +1363,14 @@
       char*  s;
 
 
-      if ( FT_ALLOC( face->style_name, len ) )
+      if ( FT_QALLOC( face->style_name, len ) )
         return error;
 
       s = face->style_name;
 
       for ( nn = 0; nn < 4; nn++ )
       {
-        char*  src = strings[nn];
+        const char*  src = strings[nn];
 
 
         len = lengths[nn];
@@ -1516,7 +1527,7 @@
           {
             l += ft_strlen( foundry_prop->value.atom ) + 1;
 
-            if ( FT_NEW_ARRAY( root->family_name, l ) )
+            if ( FT_QALLOC( root->family_name, l ) )
               goto Exit;
 
             ft_strcpy( root->family_name, foundry_prop->value.atom );
@@ -1525,7 +1536,7 @@
           }
           else
           {
-            if ( FT_NEW_ARRAY( root->family_name, l ) )
+            if ( FT_QALLOC( root->family_name, l ) )
               goto Exit;
 
             ft_strcpy( root->family_name, prop->value.atom );
@@ -1549,7 +1560,7 @@
       root->num_glyphs = (FT_Long)face->nmetrics;
 
       root->num_fixed_sizes = 1;
-      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
+      if ( FT_NEW( root->available_sizes ) )
         goto Exit;
 
       {
@@ -1557,8 +1568,6 @@
         FT_Short         resolution_x = 0, resolution_y = 0;
 
 
-        FT_ZERO( bsize );
-
         /* for simplicity, we take absolute values of integer properties */
 
 #if 0
@@ -1599,7 +1608,7 @@
         else
         {
           /* this is a heuristical value */
-          bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 );
+          bsize->width = ( bsize->height * 2 + 1 ) / 3;
         }
 
         prop = pcf_find_property( face, "POINT_SIZE" );
@@ -1613,7 +1622,7 @@
           if ( FT_ABS( prop->value.l ) > 0x504C2L ) /* 0x7FFF * 72270/7200 */
           {
             bsize->size = 0x7FFF;
-            FT_TRACE0(( "pcf_load_font: clamping point size to value %d\n",
+            FT_TRACE0(( "pcf_load_font: clamping point size to value %ld\n",
                         bsize->size ));
           }
           else
@@ -1632,7 +1641,7 @@
           if ( FT_ABS( prop->value.l ) > 0x7FFF )
           {
             bsize->y_ppem = 0x7FFF << 6;
-            FT_TRACE0(( "pcf_load_font: clamping pixel size to value %d\n",
+            FT_TRACE0(( "pcf_load_font: clamping pixel size to value %ld\n",
                         bsize->y_ppem ));
           }
           else
diff --git a/src/pcf/pcfread.h b/src/pcf/pcfread.h
index bed30e5..a54648f 100644
--- a/src/pcf/pcfread.h
+++ b/src/pcf/pcfread.h
@@ -29,7 +29,6 @@
 #define PCFREAD_H_
 
 
-#include <ft2build.h>
 
 FT_BEGIN_HEADER
 
diff --git a/src/pcf/pcfutil.c b/src/pcf/pcfutil.c
index 045c42d..9575726 100644
--- a/src/pcf/pcfutil.c
+++ b/src/pcf/pcfutil.c
@@ -32,7 +32,6 @@
 /* Modified for use with FreeType */
 
 
-#include <ft2build.h>
 #include "pcfutil.h"
 
 
@@ -58,6 +57,34 @@
   }
 
 
+#if defined( __clang__ )                                            || \
+    ( defined( __GNUC__ )                                          &&  \
+      ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) ) )
+
+#define BSWAP16( x )  __builtin_bswap16( x )
+#define BSWAP32( x )  __builtin_bswap32( x )
+
+#elif defined( _MSC_VER ) && _MSC_VER >= 1300
+
+#pragma intrinsic( _byteswap_ushort )
+#pragma intrinsic( _byteswap_ulong )
+
+#define BSWAP16( x )  _byteswap_ushort( x )
+#define BSWAP32( x )  _byteswap_ulong( x )
+
+#else
+
+#define BSWAP16( x )                             \
+        (FT_UInt16)( ( ( ( x ) >> 8 ) & 0xff ) | \
+                     ( ( ( x ) & 0xff ) << 8 ) )
+#define BSWAP32( x )                   \
+        (FT_UInt32)( ( ( ( x ) & 0xff000000u ) >> 24 ) | \
+                     ( ( ( x ) & 0x00ff0000u ) >> 8  ) | \
+                     ( ( ( x ) & 0x0000ff00u ) << 8  ) | \
+                     ( ( ( x ) & 0x000000ffu ) << 24 ) )
+
+#endif
+
   /*
    * Invert byte order within each 16-bits of an array.
    */
@@ -66,15 +93,11 @@
   TwoByteSwap( unsigned char*  buf,
                size_t          nbytes )
   {
-    for ( ; nbytes >= 2; nbytes -= 2, buf += 2 )
-    {
-      unsigned char  c;
+    FT_UInt16*  b = (FT_UInt16*)buf;
 
 
-      c      = buf[0];
-      buf[0] = buf[1];
-      buf[1] = c;
-    }
+    for ( ; nbytes >= 2; nbytes -= 2, b++ )
+      *b = BSWAP16( *b );
   }
 
   /*
@@ -85,19 +108,11 @@
   FourByteSwap( unsigned char*  buf,
                 size_t          nbytes )
   {
-    for ( ; nbytes >= 4; nbytes -= 4, buf += 4 )
-    {
-      unsigned char  c;
+    FT_UInt32*  b = (FT_UInt32*)buf;
 
 
-      c      = buf[0];
-      buf[0] = buf[3];
-      buf[3] = c;
-
-      c      = buf[1];
-      buf[1] = buf[2];
-      buf[2] = c;
-    }
+    for ( ; nbytes >= 4; nbytes -= 4, b++ )
+      *b = BSWAP32( *b );
   }
 
 
diff --git a/src/pcf/pcfutil.h b/src/pcf/pcfutil.h
index be986e7..a197c15 100644
--- a/src/pcf/pcfutil.h
+++ b/src/pcf/pcfutil.h
@@ -31,7 +31,7 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-
+#include <freetype/internal/compiler-macros.h>
 
 FT_BEGIN_HEADER
 
diff --git a/src/pfr/Jamfile b/src/pfr/Jamfile
deleted file mode 100644
index cb55a7e..0000000
--- a/src/pfr/Jamfile
+++ /dev/null
@@ -1,35 +0,0 @@
-# FreeType 2 src/pfr Jamfile
-#
-# Copyright 2002-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) pfr ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = pfrcmap
-               pfrdrivr
-               pfrgload
-               pfrload
-               pfrobjs
-               pfrsbit
-               ;
-  }
-  else
-  {
-    _sources = pfr ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/pfr Jamfile
diff --git a/src/pfr/module.mk b/src/pfr/module.mk
index 27fec8e..388a38e 100644
--- a/src/pfr/module.mk
+++ b/src/pfr/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/pfr/pfr.c b/src/pfr/pfr.c
index 2d34615..d373815 100644
--- a/src/pfr/pfr.c
+++ b/src/pfr/pfr.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR driver component.
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "pfrcmap.c"
 #include "pfrdrivr.c"
diff --git a/src/pfr/pfrcmap.c b/src/pfr/pfrcmap.c
index d83dc58..312a9ff 100644
--- a/src/pfr/pfrcmap.c
+++ b/src/pfr/pfrcmap.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR cmap handling (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,8 +16,7 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 #include "pfrcmap.h"
 #include "pfrobjs.h"
 
@@ -70,17 +69,14 @@
   pfr_cmap_char_index( PFR_CMap   cmap,
                        FT_UInt32  char_code )
   {
-    FT_UInt  min = 0;
-    FT_UInt  max = cmap->num_chars;
+    FT_UInt   min = 0;
+    FT_UInt   max = cmap->num_chars;
+    FT_UInt   mid = min + ( max - min ) / 2;
+    PFR_Char  gchar;
 
 
     while ( min < max )
     {
-      PFR_Char  gchar;
-      FT_UInt   mid;
-
-
-      mid   = min + ( max - min ) / 2;
       gchar = cmap->chars + mid;
 
       if ( gchar->char_code == char_code )
@@ -90,6 +86,11 @@
         min = mid + 1;
       else
         max = mid;
+
+      /* reasonable prediction in a continuous block */
+      mid += char_code - gchar->char_code;
+      if ( mid >= max || mid < min )
+        mid = min + ( max - min ) / 2;
     }
     return 0;
   }
@@ -107,13 +108,12 @@
     {
       FT_UInt   min = 0;
       FT_UInt   max = cmap->num_chars;
-      FT_UInt   mid;
+      FT_UInt   mid = min + ( max - min ) / 2;
       PFR_Char  gchar;
 
 
       while ( min < max )
       {
-        mid   = min + ( ( max - min ) >> 1 );
         gchar = cmap->chars + mid;
 
         if ( gchar->char_code == char_code )
@@ -133,6 +133,11 @@
           min = mid + 1;
         else
           max = mid;
+
+        /* reasonable prediction in a continuous block */
+        mid += char_code - gchar->char_code;
+        if ( mid >= max || mid < min )
+          mid = min + ( max - min ) / 2;
       }
 
       /* we didn't find it, but we have a pair just above it */
diff --git a/src/pfr/pfrcmap.h b/src/pfr/pfrcmap.h
index 6a43bdb..8110f17 100644
--- a/src/pfr/pfrcmap.h
+++ b/src/pfr/pfrcmap.h
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR cmap handling (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef PFRCMAP_H_
 #define PFRCMAP_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 #include "pfrtypes.h"
 
 
diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c
index 4b8707f..78c6c68 100644
--- a/src/pfr/pfrdrivr.c
+++ b/src/pfr/pfrdrivr.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR driver interface (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_SERVICE_PFR_H
-#include FT_SERVICE_FONT_FORMAT_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/services/svpfr.h>
+#include <freetype/internal/services/svfntfmt.h>
 #include "pfrdrivr.h"
 #include "pfrobjs.h"
 
diff --git a/src/pfr/pfrdrivr.h b/src/pfr/pfrdrivr.h
index 6adb2fd..da14468 100644
--- a/src/pfr/pfrdrivr.h
+++ b/src/pfr/pfrdrivr.h
@@ -4,7 +4,7 @@
  *
  *   High-level Type PFR driver interface (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define PFRDRIVR_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/pfr/pfrerror.h b/src/pfr/pfrerror.h
index f9fde3a..5dfb254 100644
--- a/src/pfr/pfrerror.h
+++ b/src/pfr/pfrerror.h
@@ -4,7 +4,7 @@
  *
  *   PFR error codes (specification only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef PFRERROR_H_
 #define PFRERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  PFR_Err_
 #define FT_ERR_BASE    FT_Mod_Err_PFR
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* PFRERROR_H_ */
 
diff --git a/src/pfr/pfrgload.c b/src/pfr/pfrgload.c
index 06723ff..14f2ec3 100644
--- a/src/pfr/pfrgload.c
+++ b/src/pfr/pfrgload.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR glyph loader (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,12 +19,12 @@
 #include "pfrgload.h"
 #include "pfrsbit.h"
 #include "pfrload.h"            /* for macro definitions */
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "pfrerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pfr
+#define FT_COMPONENT  pfr
 
 
   /*************************************************************************/
@@ -42,8 +42,7 @@
   {
     FT_ZERO( glyph );
 
-    glyph->loader     = loader;
-    glyph->path_begun = 0;
+    glyph->loader = loader;
 
     FT_GlyphLoader_Rewind( loader );
   }
@@ -409,7 +408,7 @@
           break;
 
         case 6:                            /* horizontal to vertical curve */
-          FT_TRACE6(( "- hv curve " ));
+          FT_TRACE6(( "- hv curve" ));
           args_format = 0xB8E;
           args_count  = 3;
           break;
@@ -451,7 +450,7 @@
           case 1:                           /* 16-bit absolute value */
             PFR_CHECK( 2 );
             cur->x = PFR_NEXT_SHORT( p );
-            FT_TRACE7(( " x.%d", cur->x ));
+            FT_TRACE7(( " x.%ld", cur->x ));
             break;
 
           case 2:                           /* 8-bit delta */
@@ -481,7 +480,7 @@
           case 1:                           /* 16-bit absolute value */
             PFR_CHECK( 2 );
             cur->y = PFR_NEXT_SHORT( p );
-            FT_TRACE7(( " y.%d", cur->y ));
+            FT_TRACE7(( " y.%ld", cur->y ));
             break;
 
           case 2:                           /* 8-bit delta */
diff --git a/src/pfr/pfrgload.h b/src/pfr/pfrgload.h
index 6a5de29..92a59bc 100644
--- a/src/pfr/pfrgload.h
+++ b/src/pfr/pfrgload.h
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR glyph loader (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/pfr/pfrload.c b/src/pfr/pfrload.c
index e9c0099..de85ee6 100644
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR loader (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,13 +17,13 @@
 
 
 #include "pfrload.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
 
 #include "pfrerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pfr
+#define FT_COMPONENT  pfr
 
 
   /*
@@ -268,9 +268,7 @@
          header->version     > 4           ||
          header->header_size < 58          ||
          header->signature2 != 0x0D0A      )    /* CR/LF  */
-    {
       result = 0;
-    }
 
     return result;
   }
@@ -406,11 +404,9 @@
       }
 
       if ( flags & PFR_LOG_BOLD )
-      {
         log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD )
                                    ? PFR_NEXT_SHORT( p )
                                    : PFR_NEXT_BYTE( p );
-      }
 
       if ( flags & PFR_LOG_EXTRA_ITEMS )
       {
@@ -565,7 +561,7 @@
     if ( phy_font->font_id )
       goto Exit;
 
-    if ( FT_ALLOC( phy_font->font_id, len + 1 ) )
+    if ( FT_QALLOC( phy_font->font_id, len + 1 ) )
       goto Exit;
 
     /* copy font ID name, and terminate it for safety */
@@ -601,10 +597,10 @@
 
     PFR_CHECK( count * 2 );
 
-    if ( FT_NEW_ARRAY( snaps, count ) )
+    if ( FT_QNEW_ARRAY( snaps, count ) )
       goto Exit;
 
-    phy_font->vertical.stem_snaps = snaps;
+    phy_font->vertical.stem_snaps   = snaps;
     phy_font->horizontal.stem_snaps = snaps + num_vert;
 
     for ( ; count > 0; count--, snaps++ )
@@ -621,7 +617,6 @@
   }
 
 
-
   /* load kerning pair data */
   FT_CALLBACK_DEF( FT_Error )
   pfr_extra_item_load_kerning_pairs( FT_Byte*     p,
@@ -761,7 +756,7 @@
 
     if ( ok )
     {
-      if ( FT_ALLOC( result, len + 1 ) )
+      if ( FT_QALLOC( result, len + 1 ) )
         goto Exit;
 
       FT_MEM_COPY( result, p, len );
@@ -857,8 +852,16 @@
     phy_font->bbox.yMax          = PFR_NEXT_SHORT( p );
     phy_font->flags      = flags = PFR_NEXT_BYTE( p );
 
+    if ( !phy_font->outline_resolution ||
+         !phy_font->metrics_resolution )
+    {
+      error = FT_THROW( Invalid_Table );
+      FT_ERROR(( "pfr_phy_font_load: invalid resolution\n" ));
+      goto Fail;
+    }
+
     /* get the standard advance for non-proportional fonts */
-    if ( !(flags & PFR_PHY_PROPORTIONAL) )
+    if ( !( flags & PFR_PHY_PROPORTIONAL ) )
     {
       PFR_CHECK( 2 );
       phy_font->standard_advance = PFR_NEXT_SHORT( p );
@@ -869,14 +872,13 @@
     {
       error = pfr_extra_items_parse( &p, limit,
                                      pfr_phy_font_extra_items, phy_font );
-
       if ( error )
         goto Fail;
     }
 
     /* In certain fonts, the auxiliary bytes contain interesting   */
     /* information.  These are not in the specification but can be */
-    /* guessed by looking at the content of a few PFR0 fonts.      */
+    /* guessed by looking at the content of a few 'PFR0' fonts.    */
     PFR_CHECK( 3 );
     num_aux = PFR_NEXT_ULONG( p );
 
@@ -953,7 +955,7 @@
 
       PFR_CHECK( count * 2 );
 
-      if ( FT_NEW_ARRAY( phy_font->blue_values, count ) )
+      if ( FT_QNEW_ARRAY( phy_font->blue_values, count ) )
         goto Fail;
 
       for ( n = 0; n < count; n++ )
@@ -975,6 +977,13 @@
       phy_font->num_chars    = count = PFR_NEXT_USHORT( p );
       phy_font->chars_offset = offset + (FT_Offset)( p - stream->cursor );
 
+      if ( !phy_font->num_chars )
+      {
+        error = FT_THROW( Invalid_Table );
+        FT_ERROR(( "pfr_phy_font_load: no glyphs\n" ));
+        goto Fail;
+      }
+
       Size = 1 + 1 + 2;
       if ( flags & PFR_PHY_2BYTE_CHARCODE )
         Size += 1;
@@ -993,7 +1002,7 @@
 
       PFR_CHECK_SIZE( count * Size );
 
-      if ( FT_NEW_ARRAY( phy_font->chars, count ) )
+      if ( FT_QNEW_ARRAY( phy_font->chars, count ) )
         goto Fail;
 
       for ( n = 0; n < count; n++ )
diff --git a/src/pfr/pfrload.h b/src/pfr/pfrload.h
index ef29973..d7b20a4 100644
--- a/src/pfr/pfrload.h
+++ b/src/pfr/pfrload.h
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR loader (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,7 @@
 #define PFRLOAD_H_
 
 #include "pfrobjs.h"
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftstream.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index e51a842..3db8f0a 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR object methods (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,15 +21,15 @@
 #include "pfrgload.h"
 #include "pfrcmap.h"
 #include "pfrsbit.h"
-#include FT_OUTLINE_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/ftoutln.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/ttnameid.h>
 
 #include "pfrerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pfr
+#define FT_COMPONENT  pfr
 
 
   /*************************************************************************/
@@ -83,7 +83,11 @@
     /* load the header and check it */
     error = pfr_header_load( &face->header, stream );
     if ( error )
+    {
+      FT_TRACE2(( "  not a PFR font\n" ));
+      error = FT_THROW( Unknown_File_Format );
       goto Exit;
+    }
 
     if ( !pfr_header_check( &face->header ) )
     {
@@ -122,18 +126,18 @@
               stream,
               (FT_UInt)( face_index & 0xFFFF ),
               face->header.log_dir_offset,
-              FT_BOOL( face->header.phy_font_max_size_high != 0 ) );
+              FT_BOOL( face->header.phy_font_max_size_high ) );
     if ( error )
       goto Exit;
 
-    /* now load the physical font descriptor */
+    /* load the physical font descriptor */
     error = pfr_phy_font_load( &face->phy_font, stream,
                                face->log_font.phys_offset,
                                face->log_font.phys_size );
     if ( error )
       goto Exit;
 
-    /* now set up all root face fields */
+    /* set up all root face fields */
     {
       PFR_PhyFont  phy_font = &face->phy_font;
 
@@ -156,7 +160,7 @@
         if ( nn == phy_font->num_chars )
         {
           if ( phy_font->num_strikes > 0 )
-            pfrface->face_flags = 0;        /* not scalable */
+            pfrface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
           else
           {
             FT_ERROR(( "pfr_face_init: font doesn't contain glyphs\n" ));
@@ -166,7 +170,7 @@
         }
       }
 
-      if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 )
+      if ( !( phy_font->flags & PFR_PHY_PROPORTIONAL ) )
         pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
       if ( phy_font->flags & PFR_PHY_VERTICAL )
@@ -203,7 +207,7 @@
 
       pfrface->height = (FT_Short)( ( pfrface->units_per_EM * 12 ) / 10 );
       if ( pfrface->height < pfrface->ascender - pfrface->descender )
-        pfrface->height = (FT_Short)(pfrface->ascender - pfrface->descender);
+        pfrface->height = (FT_Short)( pfrface->ascender - pfrface->descender );
 
       if ( phy_font->num_strikes > 0 )
       {
@@ -213,7 +217,7 @@
         FT_Memory        memory = pfrface->stream->memory;
 
 
-        if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) )
+        if ( FT_QNEW_ARRAY( pfrface->available_sizes, count ) )
           goto Exit;
 
         size   = pfrface->available_sizes;
@@ -334,7 +338,7 @@
     }
 
     /* try to load an embedded bitmap */
-    if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )
+    if ( !( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) )
     {
       error = pfr_slot_load_bitmap(
                 slot,
@@ -370,7 +374,7 @@
       FT_Bool            scaling;
 
 
-      scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
+      scaling = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) );
 
       /* copy outline data */
       *outline = slot->glyph.loader->base.outline;
@@ -378,7 +382,7 @@
       outline->flags &= ~FT_OUTLINE_OWNER;
       outline->flags |= FT_OUTLINE_REVERSE_FILL;
 
-      if ( size && pfrsize->metrics.y_ppem < 24 )
+      if ( pfrsize->metrics.y_ppem < 24 )
         outline->flags |= FT_OUTLINE_HIGH_PRECISION;
 
       /* compute the advance vector */
@@ -482,17 +486,16 @@
     kerning->x = 0;
     kerning->y = 0;
 
-    if ( glyph1 > 0 )
-      glyph1--;
+    /* PFR indexing skips .notdef, which becomes UINT_MAX */
+    glyph1--;
+    glyph2--;
 
-    if ( glyph2 > 0 )
-      glyph2--;
-
-    /* convert glyph indices to character codes */
-    if ( glyph1 > phy_font->num_chars ||
-         glyph2 > phy_font->num_chars )
+    /* check the array bounds, .notdef is automatically out */
+    if ( glyph1 >= phy_font->num_chars ||
+         glyph2 >= phy_font->num_chars )
       goto Exit;
 
+    /* convert glyph indices to character codes */
     code1 = phy_font->chars[glyph1].char_code;
     code2 = phy_font->chars[glyph2].char_code;
     pair  = PFR_KERN_INDEX( code1, code2 );
diff --git a/src/pfr/pfrobjs.h b/src/pfr/pfrobjs.h
index e03573f..fcf8c38 100644
--- a/src/pfr/pfrobjs.h
+++ b/src/pfr/pfrobjs.h
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR object methods (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/pfr/pfrsbit.c b/src/pfr/pfrsbit.c
index f5d3077..46a988e 100644
--- a/src/pfr/pfrsbit.c
+++ b/src/pfr/pfrsbit.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR bitmap loader (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,13 +18,13 @@
 
 #include "pfrsbit.h"
 #include "pfrload.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
 
 #include "pfrerror.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pfr
+#define FT_COMPONENT  pfr
 
 
   /*************************************************************************/
@@ -282,7 +282,7 @@
                           FT_ULong*  found_offset,
                           FT_ULong*  found_size )
   {
-    FT_UInt   min, max, char_len;
+    FT_UInt   min, max, mid, char_len;
     FT_Bool   two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE );
     FT_Byte*  buff;
 
@@ -310,8 +310,8 @@
       if ( lim > limit )
       {
         FT_TRACE0(( "pfr_lookup_bitmap_data:"
-                    " number of bitmap records too large,\n"
-                    "                       "
+                    " number of bitmap records too large,\n" ));
+        FT_TRACE0(( "                       "
                     " thus ignoring all bitmaps in this strike\n" ));
         *flags &= ~PFR_BITMAP_VALID_CHARCODES;
       }
@@ -328,8 +328,8 @@
           if ( (FT_Long)code <= prev_code )
           {
             FT_TRACE0(( "pfr_lookup_bitmap_data:"
-                        " bitmap records are not sorted,\n"
-                        "                       "
+                        " bitmap records are not sorted,\n" ));
+            FT_TRACE0(( "                       "
                         " thus ignoring all bitmaps in this strike\n" ));
             *flags &= ~PFR_BITMAP_VALID_CHARCODES;
             break;
@@ -349,14 +349,14 @@
 
     min = 0;
     max = count;
+    mid = min + ( max - min ) / 2;
 
     /* binary search */
     while ( min < max )
     {
-      FT_UInt  mid, code;
+      FT_UInt  code;
 
 
-      mid  = ( min + max ) >> 1;
       buff = base + mid * char_len;
 
       if ( two )
@@ -370,6 +370,11 @@
         min = mid + 1;
       else
         goto Found_It;
+
+      /* reasonable prediction in a continuous block */
+      mid += char_code - code;
+      if ( mid >= max || mid < min )
+        mid = min + ( max - min ) / 2;
     }
 
   Fail:
@@ -391,7 +396,7 @@
   }
 
 
-  /* load bitmap metrics.  `*padvance' must be set to the default value */
+  /* load bitmap metrics.  `*aadvance' must be set to the default value */
   /* before calling this function                                       */
   /*                                                                    */
   static FT_Error
@@ -575,7 +580,7 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL_DEF( FT_Error )
   pfr_slot_load_bitmap( PFR_Slot  glyph,
                         PFR_Size  size,
                         FT_UInt   glyph_index,
@@ -628,7 +633,7 @@
       if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET )
         char_len += 1;
 
-      /* access data directly in the frame to speed lookups */
+      /* access data directly in the frame to speed up lookups */
       if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
            FT_FRAME_ENTER( char_len * strike->num_bitmaps )        )
         goto Exit;
@@ -744,8 +749,8 @@
            ypos > FT_INT_MAX - (FT_Long)ysize ||
            ypos + (FT_Long)ysize < FT_INT_MIN )
       {
-        FT_TRACE1(( "pfr_slot_load_bitmap:" ));
-        FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",
+        FT_TRACE1(( "pfr_slot_load_bitmap:"
+                    " huge bitmap glyph %ldx%ld over FT_GlyphSlot\n",
                      xpos, ypos ));
         error = FT_THROW( Invalid_Pixel_Size );
       }
diff --git a/src/pfr/pfrsbit.h b/src/pfr/pfrsbit.h
index 7002df4..3e1dba9 100644
--- a/src/pfr/pfrsbit.h
+++ b/src/pfr/pfrsbit.h
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR bitmap loader (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/pfr/pfrtypes.h b/src/pfr/pfrtypes.h
index 794706b..2f8909f 100644
--- a/src/pfr/pfrtypes.h
+++ b/src/pfr/pfrtypes.h
@@ -4,7 +4,7 @@
  *
  *   FreeType PFR data structures (specification only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,8 +19,7 @@
 #ifndef PFRTYPES_H_
 #define PFRTYPES_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 
 FT_BEGIN_HEADER
 
@@ -110,7 +109,7 @@
 #define PFR_BITMAP_2BYTE_SIZE      0x02U
 #define PFR_BITMAP_3BYTE_OFFSET    0x04U
 
-  /*not part of the specification but used for implementation */
+  /* not part of the specification but used for implementation */
 #define PFR_BITMAP_CHARCODES_VALIDATED  0x40U
 #define PFR_BITMAP_VALID_CHARCODES      0x80U
 
diff --git a/src/pfr/rules.mk b/src/pfr/rules.mk
index 3acb795..50695fd 100644
--- a/src/pfr/rules.mk
+++ b/src/pfr/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/psaux/Jamfile b/src/psaux/Jamfile
deleted file mode 100644
index a231d59..0000000
--- a/src/psaux/Jamfile
+++ /dev/null
@@ -1,45 +0,0 @@
-# FreeType 2 src/psaux Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) psaux ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = afmparse
-               psauxmod
-               psconv
-               psobjs
-               t1cmap
-               t1decode
-               cffdecode
-               psarrst
-               psblues
-               pserror
-               psfont
-               psft
-               pshints
-               psintrp
-               psread
-               psstack
-               ;
-  }
-  else
-  {
-    _sources = psaux ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/psaux Jamfile
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 04c191f..68f9569 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
  *
  *   AFM parser (body).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -15,10 +15,9 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/psaux.h>
 
 #ifndef T1_CONFIG_OPTION_NO_AFM
 
@@ -30,6 +29,16 @@
 
   /**************************************************************************
    *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  afmparse
+
+
+  /**************************************************************************
+   *
    * AFM_Stream
    *
    * The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib.
@@ -554,7 +563,7 @@
   }
 
 
-  FT_LOCAL( void )
+  FT_LOCAL_DEF( void )
   afm_parser_done( AFM_Parser  parser )
   {
     FT_Memory  memory = parser->memory;
@@ -587,21 +596,39 @@
   static FT_Error
   afm_parse_track_kern( AFM_Parser  parser )
   {
-    AFM_FontInfo   fi = parser->FontInfo;
+    AFM_FontInfo   fi     = parser->FontInfo;
+    AFM_Stream     stream = parser->stream;
     AFM_TrackKern  tk;
-    char*          key;
-    FT_Offset      len;
-    int            n = -1;
-    FT_Int         tmp;
+
+    char*      key;
+    FT_Offset  len;
+    int        n = -1;
+    FT_Int     tmp;
 
 
     if ( afm_parser_read_int( parser, &tmp ) )
         goto Fail;
 
     if ( tmp < 0 )
+    {
+      FT_ERROR(( "afm_parse_track_kern: invalid number of track kerns\n" ));
       goto Fail;
+    }
 
     fi->NumTrackKern = (FT_UInt)tmp;
+    FT_TRACE3(( "afm_parse_track_kern: %u track kern%s expected\n",
+                fi->NumTrackKern,
+                fi->NumTrackKern == 1 ? "" : "s" ));
+
+    /* Rough sanity check: The minimum line length of the `TrackKern` */
+    /* command is 20 characters (including the EOL character).        */
+    if ( (FT_ULong)( stream->limit - stream->cursor ) / 20 <
+           fi->NumTrackKern )
+    {
+      FT_ERROR(( "afm_parse_track_kern:"
+                 " number of track kern entries exceeds stream size\n" ));
+      goto Fail;
+    }
 
     if ( fi->NumTrackKern )
     {
@@ -624,7 +651,10 @@
         n++;
 
         if ( n >= (int)fi->NumTrackKern )
-          goto Fail;
+          {
+            FT_ERROR(( "afm_parse_track_kern: too many track kern data\n" ));
+            goto Fail;
+          }
 
         tk = fi->TrackKerns + n;
 
@@ -634,7 +664,12 @@
         shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
         shared_vals[4].type = AFM_VALUE_TYPE_FIXED;
         if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )
+        {
+          FT_ERROR(( "afm_parse_track_kern:"
+                     " insufficient number of parameters for entry %d\n",
+                     n ));
           goto Fail;
+        }
 
         tk->degree     = shared_vals[0].u.i;
         tk->min_ptsize = shared_vals[1].u.f;
@@ -647,7 +682,19 @@
       case AFM_TOKEN_ENDTRACKKERN:
       case AFM_TOKEN_ENDKERNDATA:
       case AFM_TOKEN_ENDFONTMETRICS:
-        fi->NumTrackKern = (FT_UInt)( n + 1 );
+        tmp = n + 1;
+        if ( (FT_UInt)tmp != fi->NumTrackKern )
+        {
+          FT_TRACE1(( "afm_parse_track_kern: %s%d track kern entr%s seen\n",
+                      tmp == 0 ? "" : "only ",
+                      tmp,
+                      tmp == 1 ? "y" : "ies" ));
+          fi->NumTrackKern = (FT_UInt)tmp;
+        }
+        else
+          FT_TRACE3(( "afm_parse_track_kern: %d track kern entr%s seen\n",
+                      tmp,
+                      tmp == 1 ? "y" : "ies" ));
         return FT_Err_Ok;
 
       case AFM_TOKEN_UNKNOWN:
@@ -668,7 +715,7 @@
 
 
   /* compare two kerning pairs */
-  FT_CALLBACK_DEF( int )
+  FT_COMPARE_DEF( int )
   afm_compare_kern_pairs( const void*  a,
                           const void*  b )
   {
@@ -691,7 +738,8 @@
   static FT_Error
   afm_parse_kern_pairs( AFM_Parser  parser )
   {
-    AFM_FontInfo  fi = parser->FontInfo;
+    AFM_FontInfo  fi     = parser->FontInfo;
+    AFM_Stream    stream = parser->stream;
     AFM_KernPair  kp;
     char*         key;
     FT_Offset     len;
@@ -703,9 +751,26 @@
       goto Fail;
 
     if ( tmp < 0 )
+    {
+      FT_ERROR(( "afm_parse_kern_pairs: invalid number of kern pairs\n" ));
       goto Fail;
+    }
 
     fi->NumKernPair = (FT_UInt)tmp;
+    FT_TRACE3(( "afm_parse_kern_pairs: %u kern pair%s expected\n",
+                fi->NumKernPair,
+                fi->NumKernPair == 1 ? "" : "s" ));
+
+    /* Rough sanity check: The minimum line length of the `KP`,    */
+    /* `KPH`,`KPX`, and `KPY` commands is 10 characters (including */
+    /* the EOL character).                                         */
+    if ( (FT_ULong)( stream->limit - stream->cursor ) / 10 <
+           fi->NumKernPair )
+    {
+      FT_ERROR(( "afm_parse_kern_pairs:"
+                 " number of kern pairs exceeds stream size\n" ));
+      goto Fail;
+    }
 
     if ( fi->NumKernPair )
     {
@@ -735,7 +800,10 @@
           n++;
 
           if ( n >= (int)fi->NumKernPair )
+          {
+            FT_ERROR(( "afm_parse_kern_pairs: too many kern pairs\n" ));
             goto Fail;
+          }
 
           kp = fi->KernPairs + n;
 
@@ -745,7 +813,12 @@
           shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;
           r = afm_parser_read_vals( parser, shared_vals, 4 );
           if ( r < 3 )
+          {
+            FT_ERROR(( "afm_parse_kern_pairs:"
+                       " insufficient number of parameters for entry %d\n",
+                       n ));
             goto Fail;
+          }
 
           /* index values can't be negative */
           kp->index1 = shared_vals[0].u.u;
@@ -767,7 +840,20 @@
       case AFM_TOKEN_ENDKERNPAIRS:
       case AFM_TOKEN_ENDKERNDATA:
       case AFM_TOKEN_ENDFONTMETRICS:
-        fi->NumKernPair = (FT_UInt)( n + 1 );
+        tmp = n + 1;
+        if ( (FT_UInt)tmp != fi->NumKernPair )
+        {
+          FT_TRACE1(( "afm_parse_kern_pairs: %s%d kern pair%s seen\n",
+                      tmp == 0 ? "" : "only ",
+                      tmp,
+                      tmp == 1 ? "" : "s" ));
+          fi->NumKernPair = (FT_UInt)tmp;
+        }
+        else
+          FT_TRACE3(( "afm_parse_kern_pairs: %d kern pair%s seen\n",
+                      tmp,
+                      tmp == 1 ? "" : "s" ));
+
         ft_qsort( fi->KernPairs, fi->NumKernPair,
                   sizeof ( AFM_KernPairRec ),
                   afm_compare_kern_pairs );
@@ -793,22 +879,43 @@
     char*      key;
     FT_Offset  len;
 
+    int  have_trackkern = 0;
+    int  have_kernpairs = 0;
+
 
     while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
     {
       switch ( afm_tokenize( key, len ) )
       {
       case AFM_TOKEN_STARTTRACKKERN:
+        if ( have_trackkern )
+        {
+          FT_ERROR(( "afm_parse_kern_data:"
+                     " invalid second horizontal track kern section\n" ));
+          goto Fail;
+        }
+
         error = afm_parse_track_kern( parser );
         if ( error )
           return error;
+
+        have_trackkern = 1;
         break;
 
       case AFM_TOKEN_STARTKERNPAIRS:
       case AFM_TOKEN_STARTKERNPAIRS0:
+        if ( have_kernpairs )
+        {
+          FT_ERROR(( "afm_parse_kern_data:"
+                     " invalid second horizontal kern pair section\n" ));
+          goto Fail;
+        }
+
         error = afm_parse_kern_pairs( parser );
         if ( error )
           return error;
+
+        have_kernpairs = 1;
         break;
 
       case AFM_TOKEN_ENDKERNDATA:
@@ -953,7 +1060,8 @@
         error = afm_parse_kern_data( parser );
         if ( error )
           goto Fail;
-        /* fall through since we only support kern data */
+        /* we only support kern data, so ... */
+        FALL_THROUGH;
 
       case AFM_TOKEN_ENDFONTMETRICS:
         return FT_Err_Ok;
diff --git a/src/psaux/afmparse.h b/src/psaux/afmparse.h
index 2fcc80e..2d3b6e6 100644
--- a/src/psaux/afmparse.h
+++ b/src/psaux/afmparse.h
@@ -4,7 +4,7 @@
  *
  *   AFM parser (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define AFMPARSE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/psaux.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/psaux/cffdecode.c b/src/psaux/cffdecode.c
index 024eb9c..2cd91c9 100644
--- a/src/psaux/cffdecode.c
+++ b/src/psaux/cffdecode.c
@@ -4,7 +4,7 @@
  *
  *   PostScript CFF (Type 2) decoding routines (body).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_SERVICE_H
-#include FT_SERVICE_CFF_TABLE_LOAD_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftserv.h>
+#include <freetype/internal/services/svcfftl.h>
 
 #include "cffdecode.h"
 #include "psobjs.h"
@@ -35,7 +34,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffdecode
+#define FT_COMPONENT  cffdecode
 
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
@@ -235,8 +234,8 @@
       return FT_THROW( Syntax_Error );
     }
 
-    adx += decoder->builder.left_bearing.x;
-    ady += decoder->builder.left_bearing.y;
+    adx = ADD_LONG( adx, decoder->builder.left_bearing.x );
+    ady = ADD_LONG( ady, decoder->builder.left_bearing.y );
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     /* Incremental fonts don't necessarily have valid charsets.        */
@@ -249,7 +248,7 @@
     else
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
     {
-      CFF_Font cff = (CFF_Font)(face->extra.data);
+      CFF_Font cff = (CFF_Font)( face->extra.data );
 
 
       bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
@@ -330,7 +329,7 @@
     builder->left_bearing.x = 0;
     builder->left_bearing.y = 0;
 
-    builder->pos_x = adx - asb;
+    builder->pos_x = SUB_LONG( adx, asb );
     builder->pos_y = ady;
 
     /* Now load `achar' on top of the base outline. */
@@ -530,6 +529,9 @@
 
     builder->path_begun = 0;
 
+    if ( !charstring_base )
+      return FT_Err_Ok;
+
     zone->base           = charstring_base;
     limit = zone->limit  = charstring_base + charstring_len;
     ip    = zone->cursor = zone->base;
@@ -860,6 +862,15 @@
           case cff_op_flex1:
           case cff_op_callsubr:
           case cff_op_callgsubr:
+            /* deprecated opcodes */
+          case cff_op_dotsection:
+            /* invalid Type 1 opcodes */
+          case cff_op_hsbw:
+          case cff_op_closepath:
+          case cff_op_callothersubr:
+          case cff_op_seac:
+          case cff_op_sbw:
+          case cff_op_setcurrentpoint:
             goto MM_Error;
 
           default:
@@ -955,10 +966,10 @@
         case cff_op_hstemhm:
         case cff_op_vstemhm:
           /* the number of arguments is always even here */
-          FT_TRACE4((
-              op == cff_op_hstem   ? " hstem\n"   :
-            ( op == cff_op_vstem   ? " vstem\n"   :
-            ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
+          FT_TRACE4(( "%s\n",
+              op == cff_op_hstem   ? " hstem"   :
+            ( op == cff_op_vstem   ? " vstem"   :
+            ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
 
           if ( hinter )
             hinter->stems( hinter->hints,
@@ -972,7 +983,8 @@
 
         case cff_op_hintmask:
         case cff_op_cntrmask:
-          FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
+          FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask"
+                                                  : " cntrmask" ));
 
           /* implement vstem when needed --                        */
           /* the specification doesn't say it, but this also works */
@@ -1085,8 +1097,8 @@
             FT_Int  phase = ( op == cff_op_hlineto );
 
 
-            FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
-                                             : " vlineto\n" ));
+            FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto"
+                                                     : " vlineto" ));
 
             if ( num_args < 0 )
               goto Stack_Underflow;
@@ -1257,8 +1269,8 @@
             FT_Int  nargs;
 
 
-            FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
-                                               : " hvcurveto\n" ));
+            FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto"
+                                                       : " hvcurveto" ));
 
             if ( cff_builder_start_point( builder, x, y ) )
               goto Fail;
@@ -1546,9 +1558,9 @@
             }
 
             if ( dx < 0 )
-              dx = -dx;
+              dx = NEG_LONG( dx );
             if ( dy < 0 )
-              dy = -dy;
+              dy = NEG_LONG( dy );
 
             /* strange test, but here it is... */
             horizontal = ( dx > dy );
@@ -1558,7 +1570,7 @@
               x = ADD_LONG( x, args[0] );
               y = ADD_LONG( y, args[1] );
               cff_builder_add_point( builder, x, y,
-                                     (FT_Bool)( count == 3 ) );
+                                     FT_BOOL( count == 3 ) );
               args += 2;
             }
 
@@ -1596,7 +1608,7 @@
               x = ADD_LONG( x, args[0] );
               y = ADD_LONG( y, args[1] );
               cff_builder_add_point( builder, x, y,
-                                     (FT_Bool)( count == 4 || count == 1 ) );
+                                     FT_BOOL( count == 4 || count == 1 ) );
               args += 2;
             }
 
@@ -1712,16 +1724,20 @@
           break;
 
         case cff_op_random:
-          FT_TRACE4(( " random\n" ));
+          {
+            FT_UInt32*  randval = in_dict ? &decoder->cff->top_font.random
+                                          : &decoder->current_subfont->random;
 
-          /* only use the lower 16 bits of `random'  */
-          /* to generate a number in the range (0;1] */
-          args[0] = (FT_Fixed)
-                      ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
-          args++;
 
-          decoder->current_subfont->random =
-            cff_random( decoder->current_subfont->random );
+            FT_TRACE4(( " random\n" ));
+
+            /* only use the lower 16 bits of `random'  */
+            /* to generate a number in the range (0;1] */
+            args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 );
+            args++;
+
+            *randval = cff_random( *randval );
+          }
           break;
 
         case cff_op_mul:
@@ -1734,7 +1750,10 @@
         case cff_op_sqrt:
           FT_TRACE4(( " sqrt\n" ));
 
-          if ( args[0] > 0 )
+          /* without upper limit the loop below might not finish */
+          if ( args[0] > 0x7FFFFFFFL )
+            args[0] = 46341;
+          else if ( args[0] > 0 )
           {
             FT_Fixed  root = args[0];
             FT_Fixed  new_root;
@@ -1807,6 +1826,7 @@
 
             if ( idx >= 0 )
             {
+              idx = idx % count;
               while ( idx > 0 )
               {
                 FT_Fixed  tmp = args[count - 1];
@@ -1821,6 +1841,10 @@
             }
             else
             {
+              /* before C99 it is implementation-defined whether    */
+              /* the result of `%' is negative if the first operand */
+              /* is negative                                        */
+              idx = -( NEG_INT( idx ) % count );
               while ( idx < 0 )
               {
                 FT_Fixed  tmp = args[0];
@@ -1847,7 +1871,7 @@
         case cff_op_put:
           {
             FT_Fixed  val = args[0];
-            FT_Int    idx = (FT_Int)( args[1] >> 16 );
+            FT_UInt   idx = (FT_UInt)( args[1] >> 16 );
 
 
             FT_TRACE4(( " put\n" ));
@@ -1856,20 +1880,20 @@
             /* didn't give a hard-coded size limit of the temporary */
             /* storage array; instead, an argument of the           */
             /* `MultipleMaster' operator set the size               */
-            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
+            if ( idx < CFF_MAX_TRANS_ELEMENTS )
               decoder->buildchar[idx] = val;
           }
           break;
 
         case cff_op_get:
           {
-            FT_Int    idx = (FT_Int)( args[0] >> 16 );
+            FT_UInt   idx = (FT_UInt)( args[0] >> 16 );
             FT_Fixed  val = 0;
 
 
             FT_TRACE4(( " get\n" ));
 
-            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
+            if ( idx < CFF_MAX_TRANS_ELEMENTS )
               val = decoder->buildchar[idx];
 
             args[0] = val;
@@ -1890,9 +1914,9 @@
           /* this operator was removed from the Type2 specification */
           /* in version 16-March-2000                               */
           {
-            FT_Int  reg_idx = (FT_Int)args[0];
-            FT_Int  idx     = (FT_Int)args[1];
-            FT_Int  count   = (FT_Int)args[2];
+            FT_UInt  reg_idx = (FT_UInt)args[0];
+            FT_UInt  idx     = (FT_UInt)args[1];
+            FT_UInt  count   = (FT_UInt)args[2];
 
 
             FT_TRACE4(( " load\n" ));
@@ -1900,11 +1924,11 @@
             /* since we currently don't handle interpolation of multiple */
             /* master fonts, we store a vector [1 0 0 ...] in the        */
             /* temporary storage array regardless of the Registry index  */
-            if ( reg_idx >= 0 && reg_idx <= 2             &&
-                 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
-                 count >= 0 && count <= num_axes          )
+            if ( reg_idx <= 2                 &&
+                 idx < CFF_MAX_TRANS_ELEMENTS &&
+                 count <= num_axes            )
             {
-              FT_Int  end, i;
+              FT_UInt  end, i;
 
 
               end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
@@ -1921,6 +1945,7 @@
         case cff_op_blend:
           /* this operator was removed from the Type2 specification */
           /* in version 16-March-2000                               */
+          if ( num_designs )
           {
             FT_Int  num_results = (FT_Int)( args[0] >> 16 );
 
@@ -1930,7 +1955,8 @@
             if ( num_results < 0 )
               goto Syntax_Error;
 
-            if ( num_results * (FT_Int)num_designs > num_args )
+            if ( num_results > num_args                       ||
+                 num_results * (FT_Int)num_designs > num_args )
               goto Stack_Underflow;
 
             /* since we currently don't handle interpolation of multiple */
@@ -1939,6 +1965,8 @@
             args     -= num_results * ( num_designs - 1 );
             num_args -= num_results * ( num_designs - 1 );
           }
+          else
+            goto Syntax_Error;
           break;
 
         case cff_op_dotsection:
@@ -2005,20 +2033,31 @@
           break;
 
         case cff_op_callothersubr:
-          /* this is an invalid Type 2 operator; however, there        */
-          /* exist fonts which are incorrectly converted from probably */
-          /* Type 1 to CFF, and some parsers seem to accept it         */
+          {
+            FT_Fixed  arg;
 
-          FT_TRACE4(( " callothersubr (invalid op)\n" ));
 
-          /* subsequent `pop' operands should add the arguments,       */
-          /* this is the implementation described for `unknown' other  */
-          /* subroutines in the Type1 spec.                            */
-          /*                                                           */
-          /* XXX Fix return arguments (see discussion below).          */
-          args -= 2 + ( args[-2] >> 16 );
-          if ( args < stack )
-            goto Stack_Underflow;
+            /* this is an invalid Type 2 operator; however, there      */
+            /* exist fonts which are incorrectly converted from        */
+            /* probably Type 1 to CFF, and some parsers seem to accept */
+            /* it                                                      */
+
+            FT_TRACE4(( " callothersubr (invalid op)\n" ));
+
+            /* subsequent `pop' operands should add the arguments,     */
+            /* this is the implementation described for `unknown'      */
+            /* other subroutines in the Type1 spec.                    */
+            /*                                                         */
+            /* XXX Fix return arguments (see discussion below).        */
+
+            arg = 2 + ( args[-2] >> 16 );
+            if ( arg >= CFF_MAX_OPERANDS )
+              goto Stack_Underflow;
+
+            args -= arg;
+            if ( args < stack )
+              goto Stack_Underflow;
+          }
           break;
 
         case cff_op_pop:
@@ -2114,7 +2153,7 @@
                                       decoder->locals_bias );
 
 
-            FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
+            FT_TRACE4(( " callsubr (idx %d, entering level %ld)\n",
                         idx,
                         zone - decoder->zones + 1 ));
 
@@ -2158,7 +2197,7 @@
                                       decoder->globals_bias );
 
 
-            FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
+            FT_TRACE4(( " callgsubr (idx %d, entering level %ld)\n",
                         idx,
                         zone - decoder->zones + 1 ));
 
@@ -2197,7 +2236,7 @@
           break;
 
         case cff_op_return:
-          FT_TRACE4(( " return (leaving level %d)\n",
+          FT_TRACE4(( " return (leaving level %ld)\n",
                       decoder->zone - decoder->zones ));
 
           if ( decoder->zone <= decoder->zones )
@@ -2232,7 +2271,8 @@
 
     } /* while ip < limit */
 
-    FT_TRACE4(( "..end..\n\n" ));
+    FT_TRACE4(( "..end..\n" ));
+    FT_TRACE4(( "\n" ));
 
   Fail:
     return error;
diff --git a/src/psaux/cffdecode.h b/src/psaux/cffdecode.h
index b4003bc..e8bb400 100644
--- a/src/psaux/cffdecode.h
+++ b/src/psaux/cffdecode.h
@@ -4,7 +4,7 @@
  *
  *   PostScript CFF (Type 2) decoding routines (specification).
  *
- * Copyright 2017-2018 by
+ * Copyright (C) 2017-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define CFFDECODE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/psaux.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/psaux/module.mk b/src/psaux/module.mk
index 6584d07..c6fb4eb 100644
--- a/src/psaux/module.mk
+++ b/src/psaux/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/psaux/psarrst.c b/src/psaux/psarrst.c
index 011803b..70313d2 100644
--- a/src/psaux/psarrst.c
+++ b/src/psaux/psarrst.c
@@ -37,7 +37,7 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psglue.h"
 #include "psarrst.h"
@@ -65,7 +65,6 @@
     arrstack->error     = error;
     arrstack->sizeItem  = sizeItem;
     arrstack->allocated = 0;
-    arrstack->chunk     = 10;    /* chunks of 10 items */
     arrstack->count     = 0;
     arrstack->totalSize = 0;
     arrstack->ptr       = NULL;
@@ -110,7 +109,7 @@
 
       FT_ASSERT( newSize > 0 );   /* avoid realloc with zero size */
 
-      if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
+      if ( !FT_QREALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
       {
         arrstack->allocated = numElements;
         arrstack->totalSize = newSize;
@@ -216,9 +215,9 @@
 
     if ( arrstack->count == arrstack->allocated )
     {
-      /* grow the buffer by one chunk */
+      /* increase the buffer size */
       if ( !cf2_arrstack_setNumElements(
-             arrstack, arrstack->allocated + arrstack->chunk ) )
+             arrstack, arrstack->allocated * 2 + 16 ) )
       {
         /* on error, ignore the push */
         return;
diff --git a/src/psaux/psarrst.h b/src/psaux/psarrst.h
index 098617b..31e5330 100644
--- a/src/psaux/psarrst.h
+++ b/src/psaux/psarrst.h
@@ -55,7 +55,6 @@
 
     size_t  sizeItem;       /* bytes per element             */
     size_t  allocated;      /* items allocated               */
-    size_t  chunk;          /* allocation increment in items */
     size_t  count;          /* number of elements allocated  */
     size_t  totalSize;      /* total bytes allocated         */
 
diff --git a/src/psaux/psaux.c b/src/psaux/psaux.c
index 3718876..5879ed1 100644
--- a/src/psaux/psaux.c
+++ b/src/psaux/psaux.c
@@ -4,7 +4,7 @@
  *
  *   FreeType auxiliary PostScript driver component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "afmparse.c"
 #include "psauxmod.c"
diff --git a/src/psaux/psauxerr.h b/src/psaux/psauxerr.h
index 3062ae5..895ffa4 100644
--- a/src/psaux/psauxerr.h
+++ b/src/psaux/psauxerr.h
@@ -4,7 +4,7 @@
  *
  *   PS auxiliary module error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef PSAUXERR_H_
 #define PSAUXERR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  PSaux_Err_
 #define FT_ERR_BASE    FT_Mod_Err_PSaux
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* PSAUXERR_H_ */
 
diff --git a/src/psaux/psauxmod.c b/src/psaux/psauxmod.c
index 41ce294..45e35aa 100644
--- a/src/psaux/psauxmod.c
+++ b/src/psaux/psauxmod.c
@@ -4,7 +4,7 @@
  *
  *   FreeType auxiliary PostScript module implementation (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,7 +16,6 @@
  */
 
 
-#include <ft2build.h>
 #include "psauxmod.h"
 #include "psobjs.h"
 #include "t1decode.h"
@@ -171,9 +170,9 @@
   };
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Module_Class  psaux_module_class =
-  {
+  FT_DEFINE_MODULE(
+    psaux_module_class,
+
     0,
     sizeof ( FT_ModuleRec ),
     "psaux",
@@ -185,7 +184,7 @@
     (FT_Module_Constructor)NULL,  /* module_init   */
     (FT_Module_Destructor) NULL,  /* module_done   */
     (FT_Module_Requester)  NULL   /* get_interface */
-  };
+  )
 
 
 /* END */
diff --git a/src/psaux/psauxmod.h b/src/psaux/psauxmod.h
index 9d894f7..94dbf48 100644
--- a/src/psaux/psauxmod.h
+++ b/src/psaux/psauxmod.h
@@ -4,7 +4,7 @@
  *
  *   FreeType auxiliary PostScript module implementation (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,10 +20,9 @@
 #define PSAUXMOD_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/psaux.h>
 
 
 FT_BEGIN_HEADER
@@ -35,10 +34,24 @@
   FT_CALLBACK_TABLE
   const PS_Builder_FuncsRec   ps_builder_funcs;
 
+#ifndef T1_CONFIG_OPTION_NO_AFM
+  FT_CALLBACK_TABLE
+  const AFM_Parser_FuncsRec  afm_parser_funcs;
+#endif
+
+  FT_CALLBACK_TABLE
+  const T1_CMap_ClassesRec  t1_cmap_classes;
+
+  FT_CALLBACK_TABLE
+  const CFF_Decoder_FuncsRec  cff_decoder_funcs;
+
 
   FT_EXPORT_VAR( const FT_Module_Class )  psaux_driver_class;
 
 
+  FT_DECLARE_MODULE( psaux_module_class )
+
+
 FT_END_HEADER
 
 #endif /* PSAUXMOD_H_ */
diff --git a/src/psaux/psblues.c b/src/psaux/psblues.c
index e44f3c7..f9c864f 100644
--- a/src/psaux/psblues.c
+++ b/src/psaux/psblues.c
@@ -37,7 +37,7 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psblues.h"
 #include "pshints.h"
@@ -51,7 +51,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cf2blues
+#define FT_COMPONENT  cf2blues
 
 
   /*
@@ -506,7 +506,8 @@
             /* guarantee minimum of 1 pixel overshoot */
             dsNew = FT_MIN(
                       cf2_fixedRound( bottomHintEdge->dsCoord ),
-                      blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) );
+                      SUB_INT32( blues->zone[i].dsFlatEdge,
+                                 cf2_intToFixed( 1 ) ) );
           }
 
           else
diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
index 74273f7..b9c7138 100644
--- a/src/psaux/psconv.c
+++ b/src/psaux/psconv.c
@@ -4,7 +4,7 @@
  *
  *   Some convenience conversions (body).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,9 +16,8 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/ftdebug.h>
 
 #include "psconv.h"
 #include "psauxerr.h"
@@ -31,7 +30,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_psconv
+#define FT_COMPONENT  psconv
 
 
   /* The following array is used by various functions to quickly convert */
@@ -536,11 +535,11 @@
 
       if ( r & 1 )
       {
-        *buffer = (FT_Byte)(*buffer + c);
+        *buffer = (FT_Byte)( *buffer + c );
         buffer++;
       }
       else
-        *buffer = (FT_Byte)(c << 4);
+        *buffer = (FT_Byte)( c << 4 );
 
       r++;
     }
@@ -573,8 +572,8 @@
     if ( p >= limit )
       return 0;
 
-    if ( n > (FT_UInt)(limit - p) )
-      n = (FT_UInt)(limit - p);
+    if ( n > (FT_UInt)( limit - p ) )
+      n = (FT_UInt)( limit - p );
 
     for ( r = 0; r < n; r++ )
     {
diff --git a/src/psaux/psconv.h b/src/psaux/psconv.h
index 2472942..b7c3ee0 100644
--- a/src/psaux/psconv.h
+++ b/src/psaux/psconv.h
@@ -4,7 +4,7 @@
  *
  *   Some convenience conversions (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define PSCONV_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/psaux.h>
 
 FT_BEGIN_HEADER
 
diff --git a/src/psaux/pserror.h b/src/psaux/pserror.h
index b2156b3..5738853 100644
--- a/src/psaux/pserror.h
+++ b/src/psaux/pserror.h
@@ -40,7 +40,7 @@
 #define PSERROR_H_
 
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -49,7 +49,8 @@
 #define FT_ERR_BASE    FT_Mod_Err_CF2
 
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
+#include <freetype/internal/compiler-macros.h>
 #include "psft.h"
 
 
diff --git a/src/psaux/psfixed.h b/src/psaux/psfixed.h
index fd3460f..299d076 100644
--- a/src/psaux/psfixed.h
+++ b/src/psaux/psfixed.h
@@ -2,7 +2,7 @@
  *
  * psfixed.h
  *
- *   Adobe's code for Fixed Point Mathematics (specification only).
+ *   Adobe's code for Fixed-Point Mathematics (specification only).
  *
  * Copyright 2007-2013 Adobe Systems Incorporated.
  *
@@ -43,10 +43,10 @@
 FT_BEGIN_HEADER
 
 
-  /* rasterizer integer and fixed point arithmetic must be 32-bit */
+  /* rasterizer integer and fixed-point arithmetic must be 32-bit */
 
 #define   CF2_Fixed  CF2_F16Dot16
-  typedef FT_Int32   CF2_Frac;   /* 2.30 fixed point */
+  typedef FT_Int32   CF2_Frac;   /* 2.30 fixed-point */
 
 
 #define CF2_FIXED_MAX      ( (CF2_Fixed)0x7FFFFFFFL )
@@ -72,8 +72,7 @@
 #define cf2_fixedFraction( x )                                           \
           ( (x) - cf2_fixedFloor( x ) )
 #define cf2_fracToFixed( x )                                             \
-          ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 )                       \
-                    :  ( (  (x) + 0x2000 ) >> 14 ) )
+          ( ( (x) + 0x2000 - ( (x) < 0 ) ) >> 14 )
 
 
   /* signed numeric types */
diff --git a/src/psaux/psfont.c b/src/psaux/psfont.c
index a7e743d..0db1f0c 100644
--- a/src/psaux/psfont.c
+++ b/src/psaux/psfont.c
@@ -36,8 +36,7 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_CALC_H
+#include <freetype/internal/ftcalc.h>
 
 #include "psft.h"
 
@@ -274,9 +273,6 @@
 
     if ( !font->isT1 )
     {
-      FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)font->cffload;
-
-
       /* check for variation vectors */
       vstore        = cf2_getVStore( decoder );
       hasVariations = ( vstore->dataCount != 0 );
@@ -284,6 +280,9 @@
       if ( hasVariations )
       {
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)font->cffload;
+
+
         /* check whether Private DICT in this subfont needs to be reparsed */
         font->error = cf2_getNormalizedVector( decoder,
                                                &lenNormalizedV,
@@ -331,7 +330,7 @@
     }
 
     /* copy hinted flag on each call */
-    font->hinted = (FT_Bool)( font->renderingFlags & CF2_FlagsHinted );
+    font->hinted = FT_BOOL( font->renderingFlags & CF2_FlagsHinted );
 
     /* determine if transform has changed;       */
     /* include Fontmatrix but ignore translation */
@@ -366,7 +365,7 @@
     if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) )
     {
       font->stemDarkened =
-        (FT_Bool)( font->renderingFlags & CF2_FlagsDarkened );
+        FT_BOOL( font->renderingFlags & CF2_FlagsDarkened );
 
       /* blue zones depend on darkened flag */
       needExtraSetup = TRUE;
diff --git a/src/psaux/psfont.h b/src/psaux/psfont.h
index 8fbacbb..836fce4 100644
--- a/src/psaux/psfont.h
+++ b/src/psaux/psfont.h
@@ -40,7 +40,7 @@
 #define PSFONT_H_
 
 
-#include FT_SERVICE_CFF_TABLE_LOAD_H
+#include <freetype/internal/services/svcfftl.h>
 
 #include "psft.h"
 #include "psblues.h"
diff --git a/src/psaux/psft.c b/src/psaux/psft.c
index 54be468..618864e 100644
--- a/src/psaux/psft.c
+++ b/src/psaux/psft.c
@@ -37,7 +37,7 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psfont.h"
 #include "pserror.h"
@@ -45,11 +45,11 @@
 #include "cffdecode.h"
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/services/svmm.h>
 #endif
 
-#include FT_SERVICE_CFF_TABLE_LOAD_H
+#include <freetype/internal/services/svcfftl.h>
 
 
 #define CF2_MAX_SIZE  cf2_intToFixed( 2000 )    /* max ppem */
@@ -68,11 +68,10 @@
     CF2_Fixed  maxScale;
 
 
-    FT_ASSERT( unitsPerEm > 0 );
-
     if ( transform->a <= 0 || transform->d <= 0 )
       return FT_THROW( Invalid_Size_Handle );
 
+    FT_ASSERT( unitsPerEm > 0 );
     FT_ASSERT( transform->b == 0 && transform->c == 0 );
     FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
 
@@ -297,7 +296,6 @@
   cf2_getUnitsPerEm( PS_Decoder*  decoder )
   {
     FT_ASSERT( decoder && decoder->builder.face );
-    FT_ASSERT( decoder->builder.face->units_per_EM );
 
     return decoder->builder.face->units_per_EM;
   }
@@ -313,7 +311,7 @@
     FT_Error   error = FT_Err_Ok;
     CF2_Font   font;
 
-    FT_Bool    is_t1 = decoder->builder.is_t1;
+    FT_Bool  is_t1 = decoder->builder.is_t1;
 
 
     FT_ASSERT( decoder &&
@@ -385,7 +383,7 @@
       FT_ZERO( &buf );
       buf.start =
       buf.ptr   = charstring_base;
-      buf.end   = charstring_base + charstring_len;
+      buf.end   = FT_OFFSET( charstring_base, charstring_len );
 
       FT_ZERO( &transform );
 
@@ -697,7 +695,7 @@
     FT_ASSERT( charstring + len >= charstring );
 
     buf->start = charstring;
-    buf->end   = charstring + len;
+    buf->end   = FT_OFFSET( charstring, len );
     buf->ptr   = buf->start;
 
     return FT_Err_Ok;
@@ -742,13 +740,13 @@
     /* For ordinary fonts get the character data stored in the face record. */
     {
       glyph_data.pointer = type1->charstrings[glyph_index];
-      glyph_data.length  = (FT_Int)type1->charstrings_len[glyph_index];
+      glyph_data.length  = type1->charstrings_len[glyph_index];
     }
 
     if ( !error )
     {
       FT_Byte*  charstring_base = (FT_Byte*)glyph_data.pointer;
-      FT_ULong  charstring_len  = (FT_ULong)glyph_data.length;
+      FT_ULong  charstring_len  = glyph_data.length;
 
 
       FT_ASSERT( charstring_base + charstring_len >= charstring_base );
@@ -778,7 +776,7 @@
     face = (T1_Face)decoder->builder.face;
 
     data.pointer = buf->start;
-    data.length  = (FT_Int)( buf->end - buf->start );
+    data.length  = (FT_UInt)( buf->end - buf->start );
 
     if ( face->root.internal->incremental_interface )
       face->root.internal->incremental_interface->funcs->free_glyph_data(
@@ -820,7 +818,7 @@
       /* The CID driver stores subroutines with seed bytes.  This     */
       /* case is taken care of when decoder->subrs_len == 0.          */
       if ( decoder->locals_len )
-        buf->end = buf->start + decoder->locals_len[idx];
+        buf->end = FT_OFFSET( buf->start, decoder->locals_len[idx] );
       else
       {
         /* We are using subroutines from a CID font.  We must adjust */
diff --git a/src/psaux/psft.h b/src/psaux/psft.h
index 4c930f0..3da454e 100644
--- a/src/psaux/psft.h
+++ b/src/psaux/psft.h
@@ -40,17 +40,17 @@
 #define PSFT_H_
 
 
+#include <freetype/internal/compiler-macros.h>
 #include "pstypes.h"
 
-
   /* TODO: disable asserts for now */
 #define CF2_NDEBUG
 
 
-#include FT_SYSTEM_H
+#include <freetype/ftsystem.h>
 
 #include "psglue.h"
-#include FT_INTERNAL_POSTSCRIPT_AUX_H    /* for PS_Decoder */
+#include <freetype/internal/psaux.h>    /* for PS_Decoder */
 
 
 FT_BEGIN_HEADER
diff --git a/src/psaux/psglue.h b/src/psaux/psglue.h
index 022aafb..63085d7 100644
--- a/src/psaux/psglue.h
+++ b/src/psaux/psglue.h
@@ -72,7 +72,7 @@
   } CF2_PathOp;
 
 
-  /* a matrix of fixed point values */
+  /* a matrix of fixed-point values */
   typedef struct  CF2_Matrix_
   {
     CF2_F16Dot16  a;
diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c
index 4560fb8..6f44d0a 100644
--- a/src/psaux/pshints.c
+++ b/src/psaux/pshints.c
@@ -37,7 +37,7 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psglue.h"
 #include "psfont.h"
@@ -52,7 +52,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cf2hints
+#define FT_COMPONENT  cf2hints
 
 
   typedef struct  CF2_HintMoveRec_
@@ -217,52 +217,49 @@
   FT_LOCAL_DEF( FT_Bool )
   cf2_hint_isValid( const CF2_Hint  hint )
   {
-    return (FT_Bool)( hint->flags != 0 );
+    return FT_BOOL( hint->flags );
   }
 
 
   static FT_Bool
   cf2_hint_isPair( const CF2_Hint  hint )
   {
-    return (FT_Bool)( ( hint->flags                      &
-                        ( CF2_PairBottom | CF2_PairTop ) ) != 0 );
+    return FT_BOOL( hint->flags & ( CF2_PairBottom | CF2_PairTop ) );
   }
 
 
   static FT_Bool
   cf2_hint_isPairTop( const CF2_Hint  hint )
   {
-    return (FT_Bool)( ( hint->flags & CF2_PairTop ) != 0 );
+    return FT_BOOL( hint->flags & CF2_PairTop );
   }
 
 
   FT_LOCAL_DEF( FT_Bool )
   cf2_hint_isTop( const CF2_Hint  hint )
   {
-    return (FT_Bool)( ( hint->flags                    &
-                        ( CF2_PairTop | CF2_GhostTop ) ) != 0 );
+    return FT_BOOL( hint->flags & ( CF2_PairTop | CF2_GhostTop ) );
   }
 
 
   FT_LOCAL_DEF( FT_Bool )
   cf2_hint_isBottom( const CF2_Hint  hint )
   {
-    return (FT_Bool)( ( hint->flags                          &
-                        ( CF2_PairBottom | CF2_GhostBottom ) ) != 0 );
+    return FT_BOOL( hint->flags & ( CF2_PairBottom | CF2_GhostBottom ) );
   }
 
 
   static FT_Bool
   cf2_hint_isLocked( const CF2_Hint  hint )
   {
-    return (FT_Bool)( ( hint->flags & CF2_Locked ) != 0 );
+    return FT_BOOL( hint->flags & CF2_Locked );
   }
 
 
   static FT_Bool
   cf2_hint_isSynthetic( const CF2_Hint  hint )
   {
-    return (FT_Bool)( ( hint->flags & CF2_Synthetic ) != 0 );
+    return FT_BOOL( hint->flags & CF2_Synthetic );
   }
 
 
@@ -313,7 +310,7 @@
       CF2_Hint  hint = &hintmap->edge[i];
 
 
-      FT_TRACE6(( "  %3d    %7.2f  %7.2f  %5d  %s%s%s%s\n",
+      FT_TRACE6(( "  %3ld    %7.2f  %7.2f  %5d  %s%s%s%s\n",
                   hint->index,
                   hint->csCoord / 65536.0,
                   hint->dsCoord / ( hint->scale * 1.0 ),
@@ -334,7 +331,7 @@
   cf2_hintmap_map( CF2_HintMap  hintmap,
                    CF2_Fixed    csCoord )
   {
-    if ( hintmap->count == 0 || ! hintmap->hinted )
+    if ( hintmap->count == 0 || !hintmap->hinted )
     {
       /* there are no hints; use uniform scale and zero offset */
       return FT_MulFix( csCoord, hintmap->scale );
@@ -415,6 +412,12 @@
     {
       FT_Bool  isPair = cf2_hint_isPair( &hintmap->edge[i] );
 
+      /* final amount to move edge or edge pair */
+      CF2_Fixed  move = 0;
+
+      CF2_Fixed  dsCoord_i;
+      CF2_Fixed  dsCoord_j;
+
 
       /* index of upper edge (same value for ghost hint) */
       j = isPair ? i + 1 : i;
@@ -425,11 +428,14 @@
       FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) ==
                    cf2_hint_isLocked( &hintmap->edge[j] ) );
 
+      dsCoord_i = hintmap->edge[i].dsCoord;
+      dsCoord_j = hintmap->edge[j].dsCoord;
+
       if ( !cf2_hint_isLocked( &hintmap->edge[i] ) )
       {
         /* hint edge is not locked, we can adjust it */
-        CF2_Fixed  fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord );
-        CF2_Fixed  fracUp   = cf2_fixedFraction( hintmap->edge[j].dsCoord );
+        CF2_Fixed  fracDown = cf2_fixedFraction( dsCoord_i );
+        CF2_Fixed  fracUp   = cf2_fixedFraction( dsCoord_j );
 
         /* calculate all four possibilities; moves down are negative */
         CF2_Fixed  downMoveDown = 0 - fracDown;
@@ -446,9 +452,6 @@
         /* smallest move down */
         CF2_Fixed  moveDown = FT_MAX( downMoveDown, upMoveDown );
 
-        /* final amount to move edge or edge pair */
-        CF2_Fixed  move;
-
         CF2_Fixed  downMinCounter = CF2_MIN_COUNTER;
         CF2_Fixed  upMinCounter   = CF2_MIN_COUNTER;
         FT_Bool    saveEdge       = FALSE;
@@ -470,16 +473,14 @@
         /* is there room to move up?                                    */
         /* there is if we are at top of array or the next edge is at or */
         /* beyond proposed move up?                                     */
-        if ( j >= hintmap->count - 1                ||
+        if ( j >= hintmap->count - 1                         ||
              hintmap->edge[j + 1].dsCoord >=
-               ADD_INT32( hintmap->edge[j].dsCoord,
-                          moveUp + upMinCounter )   )
+               ADD_INT32( dsCoord_j, moveUp + upMinCounter ) )
         {
           /* there is room to move up; is there also room to move down? */
-          if ( i == 0                                   ||
+          if ( i == 0                                              ||
                hintmap->edge[i - 1].dsCoord <=
-                 ADD_INT32( hintmap->edge[i].dsCoord,
-                            moveDown - downMinCounter ) )
+                 ADD_INT32( dsCoord_i, moveDown - downMinCounter ) )
           {
             /* move smaller absolute amount */
             move = ( -moveDown < moveUp ) ? moveDown : moveUp;  /* optimum */
@@ -490,14 +491,13 @@
         else
         {
           /* is there room to move down? */
-          if ( i == 0                                   ||
+          if ( i == 0                                              ||
                hintmap->edge[i - 1].dsCoord <=
-                 ADD_INT32( hintmap->edge[i].dsCoord,
-                            moveDown - downMinCounter ) )
+                 ADD_INT32( dsCoord_i, moveDown - downMinCounter ) )
           {
             move     = moveDown;
             /* true if non-optimum move */
-            saveEdge = (FT_Bool)( moveUp < -moveDown );
+            saveEdge = FT_BOOL( moveUp < -moveDown );
           }
           else
           {
@@ -527,17 +527,21 @@
         }
 
         /* move the edge(s) */
-        hintmap->edge[i].dsCoord = ADD_INT32( hintmap->edge[i].dsCoord,
-                                              move );
+        hintmap->edge[i].dsCoord = ADD_INT32( dsCoord_i, move );
         if ( isPair )
-          hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord,
-                                                move );
+          hintmap->edge[j].dsCoord = ADD_INT32( dsCoord_j, move );
       }
 
-      /* assert there are no overlaps in device space */
+      /* assert there are no overlaps in device space;     */
+      /* ignore tests if there was overflow (that is, if   */
+      /* operands have the same sign but the sum does not) */
       FT_ASSERT( i == 0                                                   ||
+                 ( ( dsCoord_i ^ move ) >= 0                    &&
+                   ( dsCoord_i ^ hintmap->edge[i].dsCoord ) < 0 )         ||
                  hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord );
       FT_ASSERT( i < j                                                ||
+                 ( ( dsCoord_j ^ move ) >= 0                    &&
+                   ( dsCoord_j ^ hintmap->edge[j].dsCoord ) < 0 )     ||
                  hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord );
 
       /* adjust the scales, avoiding divide by zero */
@@ -689,8 +693,10 @@
         CF2_Fixed  midpoint =
                      cf2_hintmap_map(
                        hintmap->initialHintMap,
-                       ADD_INT32( secondHintEdge->csCoord,
-                                  firstHintEdge->csCoord ) / 2 );
+                       ADD_INT32(
+                         firstHintEdge->csCoord,
+                         SUB_INT32 ( secondHintEdge->csCoord,
+                                     firstHintEdge->csCoord ) / 2 ) );
         CF2_Fixed  halfWidth =
                      FT_MulFix( SUB_INT32( secondHintEdge->csCoord,
                                            firstHintEdge->csCoord ) / 2,
@@ -1025,10 +1031,17 @@
       }
     }
 
-    FT_TRACE6(( initialMap ? "flags: [p]air [g]host [t]op "
-                             "[b]ottom [L]ocked [S]ynthetic\n"
-                             "Initial hintmap\n"
-                           : "Hints:\n" ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( initialMap )
+    {
+      FT_TRACE6(( "flags: [p]air [g]host [t]op"
+                  " [b]ottom [L]ocked [S]ynthetic\n" ));
+      FT_TRACE6(( "Initial hintmap:\n" ));
+    }
+    else
+      FT_TRACE6(( "Hints:\n" ));
+#endif
+
     cf2_hintmap_dump( hintmap );
 
     /*
@@ -1043,7 +1056,7 @@
     /* adjust positions of hint edges that are not locked to blue zones */
     cf2_hintmap_adjustHints( hintmap );
 
-    FT_TRACE6(( "(adjusted)\n" ));
+    FT_TRACE6(( "Hints adjusted:\n" ));
     cf2_hintmap_dump( hintmap );
 
     /* save the position of all hints that were used in this hint map; */
@@ -1215,7 +1228,7 @@
      * (`u').
      *
      * See notation in
-     * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm.
+     * http://geomalgorithms.com/a05-_intersect-1.html.
      * Calculations are done in 16.16, but must handle the squaring of
      * line lengths in character space.  We scale all vectors by 1/32 to
      * avoid overflow.  This allows values up to 4095 to be squared.  The
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c
index 145b672..6c640ee 100644
--- a/src/psaux/psintrp.c
+++ b/src/psaux/psintrp.c
@@ -37,8 +37,8 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_SERVICE_CFF_TABLE_LOAD_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/services/svcfftl.h>
 
 #include "psglue.h"
 #include "psfont.h"
@@ -59,7 +59,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cf2interp
+#define FT_COMPONENT  cf2interp
 
 
   FT_LOCAL_DEF( void )
@@ -287,7 +287,7 @@
   {
     CF2_UInt  i;
     CF2_UInt  count       = cf2_stack_count( opStack );
-    FT_Bool   hasWidthArg = (FT_Bool)( count & 1 );
+    FT_Bool   hasWidthArg = FT_BOOL( count & 1 );
 
     /* variable accumulates delta values from operand stack */
     CF2_Fixed  position = hintOffset;
@@ -364,7 +364,7 @@
 
     if ( doConditionalLastRead )
     {
-      FT_Bool    lastIsX = (FT_Bool)(
+      FT_Bool    lastIsX = FT_BOOL(
                              cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) >
                              cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) );
       CF2_Fixed  lastVal = cf2_stack_getReal( opStack, idx );
@@ -469,7 +469,7 @@
    */
   FT_LOCAL_DEF( void )
   cf2_interpT2CharString( CF2_Font              font,
-                          CF2_Buffer            buf,
+                          const CF2_Buffer      buf,
                           CF2_OutlineCallbacks  callbacks,
                           const FT_Vector*      translation,
                           FT_Bool               doingSeac,
@@ -612,14 +612,14 @@
     cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 );
 
     charstring  = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack );
-    *charstring = *buf;    /* structure copy */
-
-    charstringIndex = 0;       /* entry is valid now */
 
     /* catch errors so far */
     if ( *error )
       goto exit;
 
+    *charstring     = *buf;    /* structure copy     */
+    charstringIndex = 0;       /* entry is valid now */
+
     /* main interpreter loop */
     while ( 1 )
     {
@@ -776,7 +776,8 @@
 
       case cf2_cmdHSTEMHM:
       case cf2_cmdHSTEM:
-        FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" ));
+        FT_TRACE4(( "%s\n", op1 == cf2_cmdHSTEMHM ? " hstemhm"
+                                                  : " hstem" ));
 
         if ( !font->isT1 )
         {
@@ -806,7 +807,8 @@
 
       case cf2_cmdVSTEMHM:
       case cf2_cmdVSTEM:
-        FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" ));
+        FT_TRACE4(( "%s\n", op1 == cf2_cmdVSTEMHM ? " vstemhm"
+                                                  : " vstem" ));
 
         if ( !font->isT1 )
         {
@@ -889,7 +891,7 @@
           FT_Bool  isX = FT_BOOL( op1 == cf2_cmdHLINETO );
 
 
-          FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" ));
+          FT_TRACE4(( "%s\n", isX ? " hlineto" : " vlineto" ));
 
           for ( idx = 0; idx < count; idx++ )
           {
@@ -917,8 +919,8 @@
           CF2_UInt  idx   = 0;
 
 
-          FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n"
-                                               : " rrcurveto\n" ));
+          FT_TRACE4(( "%s\n", op1 == cf2_cmdRCURVELINE ? " rcurveline"
+                                                       : " rrcurveto" ));
 
           while ( idx + 6 <= count )
           {
@@ -958,10 +960,10 @@
           FT_TRACE4(( " unknown op (%d)\n", op1 ));
         else
         {
-          FT_TRACE4(( " closepath" ));
+          FT_TRACE4(( " closepath\n" ));
 
           /* if there is no path, `closepath' is a no-op */
-          ps_builder_close_contour( &decoder->builder );
+          cf2_glyphpath_closeOpenPath( &glyphPath );
 
           haveWidth = TRUE;
         }
@@ -973,8 +975,8 @@
           CF2_Int  subrNum;
 
 
-          FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
-                                              : " callsubr" ));
+          FT_TRACE4(( "%s", op1 == cf2_cmdCALLGSUBR ? " callgsubr"
+                                                    : " callsubr" ));
 
           if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR )       ||
                (  font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
@@ -1213,8 +1215,8 @@
                       FT_Bool  isV = FT_BOOL( op2 == cf2_escVSTEM3 );
 
 
-                      FT_TRACE4(( isV ? " vstem3\n"
-                                      : " hstem3\n" ));
+                      FT_TRACE4(( "%s\n", isV ? " vstem3"
+                                              : " hstem3" ));
 
                       FT_ASSERT( cf2_stack_count( opStack ) == 6 );
 
@@ -1338,9 +1340,9 @@
                       if ( decoder->glyph_names == 0 )
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
                       {
-                        FT_ERROR((
-                          "cf2_interpT2CharString: (Type 1 seac)"
-                          " glyph names table not available in this font\n" ));
+                        FT_ERROR(( "cf2_interpT2CharString:\n" ));
+                        FT_ERROR(( "  (Type 1 seac) glyph names table"
+                                   " not available in this font\n" ));
                         lastError = FT_THROW( Invalid_Glyph_Format );
                         goto exit;
                       }
@@ -1366,9 +1368,9 @@
 
                     if ( bchar_index < 0 || achar_index < 0 )
                     {
-                      FT_ERROR((
-                        "cf2_interpT2CharString: (Type 1 seac)"
-                        " invalid seac character code arguments\n" ));
+                      FT_ERROR(( "cf2_interpT2CharString:\n" ));
+                      FT_ERROR(( "  (Type 1 seac) invalid"
+                                 " seac character code arguments\n" ));
                       lastError = FT_THROW( Invalid_Glyph_Format );
                       goto exit;
                     }
@@ -1431,6 +1433,13 @@
                       lastError = error2; /* pass FreeType error through */
                       goto exit;
                     }
+
+                    /* save the left bearing and width of the SEAC   */
+                    /* glyph as they will be erased by the next load */
+
+                    left_bearing = *decoder->builder.left_bearing;
+                    advance      = *decoder->builder.advance;
+
                     cf2_interpT2CharString( font,
                                             &component,
                                             callbacks,
@@ -1441,11 +1450,14 @@
                                             &dummyWidth );
                     cf2_freeT1SeacComponent( decoder, &component );
 
-                    /* save the left bearing and width of the base       */
-                    /* character as they will be erased by the next load */
+                    /* If the SEAC glyph doesn't have a (H)SBW of its */
+                    /* own use the values from the base glyph.        */
 
-                    left_bearing = *decoder->builder.left_bearing;
-                    advance      = *decoder->builder.advance;
+                    if ( !haveWidth )
+                    {
+                      left_bearing = *decoder->builder.left_bearing;
+                      advance      = *decoder->builder.advance;
+                    }
 
                     decoder->builder.left_bearing->x = 0;
                     decoder->builder.left_bearing->y = 0;
@@ -1471,8 +1483,8 @@
                                             &dummyWidth );
                     cf2_freeT1SeacComponent( decoder, &component );
 
-                    /* restore the left side bearing and   */
-                    /* advance width of the base character */
+                    /* restore the left side bearing and advance width   */
+                    /* of the SEAC glyph or base character (saved above) */
 
                     *decoder->builder.left_bearing = left_bearing;
                     *decoder->builder.advance      = advance;
@@ -1658,7 +1670,13 @@
                      */
 
                     count = cf2_stack_count( opStack );
-                    FT_ASSERT( (CF2_UInt)arg_cnt <= count );
+                    if ( (CF2_UInt)arg_cnt > count )
+                    {
+                      FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
+                                 " stack underflow\n" ));
+                      lastError = FT_THROW( Invalid_Glyph_Format );
+                      goto exit;
+                    }
 
                     opIdx += count - (CF2_UInt)arg_cnt;
 
@@ -1881,24 +1899,25 @@
                       /*     cvi( <idx> ) of BuildCharArray with  */
                       /*     WeightVector                         */
                       {
-                        FT_Int    idx;
-                        PS_Blend  blend = decoder->blend;
+                        FT_UInt   idx;
+                        PS_Blend  blend         = decoder->blend;
+                        FT_UInt   len_buildchar = decoder->len_buildchar;
 
 
                         if ( arg_cnt != 1 || !blend )
                           goto Unexpected_OtherSubr;
 
-                        idx = cf2_stack_popInt( opStack );
+                        idx = (FT_UInt)cf2_stack_popInt( opStack );
 
-                        if ( idx < 0                             ||
-                             (FT_UInt)idx + blend->num_designs >
-                               decoder->len_buildchar            )
+                        if ( len_buildchar < blend->num_designs       ||
+                             len_buildchar - blend->num_designs < idx )
                           goto Unexpected_OtherSubr;
 
-                        ft_memcpy( &decoder->buildchar[idx],
-                                   blend->weight_vector,
-                                   blend->num_designs *
-                                   sizeof ( blend->weight_vector[0] ) );
+                        if ( decoder->buildchar && blend->weight_vector )
+                          ft_memcpy( &decoder->buildchar[idx],
+                                     blend->weight_vector,
+                                     blend->num_designs *
+                                       sizeof ( blend->weight_vector[0] ) );
                       }
                       break;
 
@@ -1992,17 +2011,16 @@
                       /* <val> <idx> 2 24 callothersubr               */
                       /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
                       {
-                        CF2_Int   idx;
+                        CF2_UInt  idx;
                         PS_Blend  blend = decoder->blend;
 
 
                         if ( arg_cnt != 2 || !blend )
                           goto Unexpected_OtherSubr;
 
-                        idx = cf2_stack_popInt( opStack );
+                        idx = (CF2_UInt)cf2_stack_popInt( opStack );
 
-                        if ( idx < 0                                ||
-                             (FT_UInt)idx >= decoder->len_buildchar )
+                        if ( idx >= decoder->len_buildchar )
                           goto Unexpected_OtherSubr;
 
                         decoder->buildchar[idx] =
@@ -2015,17 +2033,16 @@
                       /* ==> push BuildCharArray[cvi( idx )] */
                       /*     onto T1 stack                   */
                       {
-                        CF2_Int   idx;
+                        CF2_UInt  idx;
                         PS_Blend  blend = decoder->blend;
 
 
                         if ( arg_cnt != 1 || !blend )
                           goto Unexpected_OtherSubr;
 
-                        idx = cf2_stack_popInt( opStack );
+                        idx = (CF2_UInt)cf2_stack_popInt( opStack );
 
-                        if ( idx < 0                                ||
-                             (FT_UInt)idx >= decoder->len_buildchar )
+                        if ( idx >= decoder->len_buildchar )
                           goto Unexpected_OtherSubr;
 
                         cf2_stack_pushFixed( opStack,
@@ -2167,29 +2184,29 @@
                 case cf2_escPUT:
                   {
                     CF2_F16Dot16  val;
-                    CF2_Int       idx;
+                    CF2_UInt      idx;
 
 
                     FT_TRACE4(( " put\n" ));
 
-                    idx = cf2_stack_popInt( opStack );
+                    idx = (CF2_UInt)cf2_stack_popInt( opStack );
                     val = cf2_stack_popFixed( opStack );
 
-                    if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
+                    if ( idx < CF2_STORAGE_SIZE )
                       storage[idx] = val;
                   }
                   continue; /* do not clear the stack */
 
                 case cf2_escGET:
                   {
-                    CF2_Int  idx;
+                    CF2_UInt  idx;
 
 
                     FT_TRACE4(( " get\n" ));
 
-                    idx = cf2_stack_popInt( opStack );
+                    idx = (CF2_UInt)cf2_stack_popInt( opStack );
 
-                    if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
+                    if ( idx < CF2_STORAGE_SIZE )
                       cf2_stack_pushFixed( opStack, storage[idx] );
                   }
                   continue; /* do not clear the stack */
@@ -2418,7 +2435,7 @@
           PS_Builder*  builder;
 
 
-          FT_TRACE4(( " hsbw" ));
+          FT_TRACE4(( " hsbw\n" ));
 
           builder = &decoder->builder;
 
@@ -2564,7 +2581,7 @@
       case cf2_cmdHINTMASK:
         /* the final \n in the tracing message gets added in      */
         /* `cf2_hintmask_read' (which also traces the mask bytes) */
-        FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
+        FT_TRACE4(( "%s", op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
 
         /* never add hints after the mask is computed */
         if ( cf2_stack_count( opStack ) > 1    &&
@@ -2830,7 +2847,7 @@
           count = count1 & ~2U;
           idx  += count1 - count;
 
-          FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" ));
+          FT_TRACE4(( "%s\n", alternate ? " hvcurveto" : " vhcurveto" ));
 
           while ( idx < count )
           {
diff --git a/src/psaux/psintrp.h b/src/psaux/psintrp.h
index 669c09c..d8b9342 100644
--- a/src/psaux/psintrp.h
+++ b/src/psaux/psintrp.h
@@ -65,7 +65,7 @@
 
   FT_LOCAL( void )
   cf2_interpT2CharString( CF2_Font              font,
-                          CF2_Buffer            charstring,
+                          const CF2_Buffer      buf,
                           CF2_OutlineCallbacks  callbacks,
                           const FT_Vector*      translation,
                           FT_Bool               doingSeac,
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index 36ee663..8da755d 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
  *
  *   Auxiliary functions for PostScript fonts (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_DRIVER_H
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/ftdriver.h>
 
 #include "psobjs.h"
 #include "psconv.h"
@@ -36,7 +35,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_psobjs
+#define FT_COMPONENT  psobjs
 
 
   /*************************************************************************/
@@ -85,7 +84,6 @@
 
     table->max_elems = count;
     table->init      = 0xDEADBEEFUL;
-    table->num_elems = 0;
     table->block     = NULL;
     table->capacity  = 0;
     table->cursor    = 0;
@@ -100,45 +98,31 @@
   }
 
 
-  static void
-  shift_elements( PS_Table  table,
-                  FT_Byte*  old_base )
-  {
-    FT_PtrDist  delta  = table->block - old_base;
-    FT_Byte**   offset = table->elements;
-    FT_Byte**   limit  = offset + table->max_elems;
-
-
-    for ( ; offset < limit; offset++ )
-    {
-      if ( offset[0] )
-        offset[0] += delta;
-    }
-  }
-
-
   static FT_Error
-  reallocate_t1_table( PS_Table   table,
-                       FT_Offset  new_size )
+  ps_table_realloc( PS_Table   table,
+                    FT_Offset  new_size )
   {
     FT_Memory  memory   = table->memory;
     FT_Byte*   old_base = table->block;
     FT_Error   error;
 
 
-    /* allocate new base block */
-    if ( FT_ALLOC( table->block, new_size ) )
-    {
-      table->block = old_base;
+    /* (re)allocate the base block */
+    if ( FT_REALLOC( table->block, table->capacity, new_size ) )
       return error;
-    }
 
-    /* copy elements and shift offsets */
-    if ( old_base )
+    /* rebase offsets if necessary */
+    if ( old_base && table->block != old_base )
     {
-      FT_MEM_COPY( table->block, old_base, table->capacity );
-      shift_elements( table, old_base );
-      FT_FREE( old_base );
+      FT_Byte**   offset = table->elements;
+      FT_Byte**   limit  = offset + table->max_elems;
+
+
+      for ( ; offset < limit; offset++ )
+      {
+        if ( *offset )
+          *offset = table->block + ( *offset - old_base );
+      }
     }
 
     table->capacity = new_size;
@@ -174,10 +158,10 @@
    *   reallocation fails.
    */
   FT_LOCAL_DEF( FT_Error )
-  ps_table_add( PS_Table  table,
-                FT_Int    idx,
-                void*     object,
-                FT_UInt   length )
+  ps_table_add( PS_Table     table,
+                FT_Int       idx,
+                const void*  object,
+                FT_UInt      length )
   {
     if ( idx < 0 || idx >= table->max_elems )
     {
@@ -205,7 +189,7 @@
         new_size  = FT_PAD_CEIL( new_size, 1024 );
       }
 
-      error = reallocate_t1_table( table, new_size );
+      error = ps_table_realloc( table, new_size );
       if ( error )
         return error;
 
@@ -214,7 +198,7 @@
     }
 
     /* add the object to the base block and adjust offset */
-    table->elements[idx] = table->block + table->cursor;
+    table->elements[idx] = FT_OFFSET( table->block, table->cursor );
     table->lengths [idx] = length;
     FT_MEM_COPY( table->block + table->cursor, object, length );
 
@@ -235,32 +219,12 @@
    * @InOut:
    *   table ::
    *     The target table.
-   *
-   * @Note:
-   *   This function does NOT release the heap's memory block.  It is up
-   *   to the caller to clean it, or reference it in its own structures.
    */
   FT_LOCAL_DEF( void )
   ps_table_done( PS_Table  table )
   {
-    FT_Memory  memory = table->memory;
-    FT_Error   error;
-    FT_Byte*   old_base = table->block;
-
-
-    /* should never fail, because rec.cursor <= rec.size */
-    if ( !old_base )
-      return;
-
-    if ( FT_ALLOC( table->block, table->cursor ) )
-      return;
-    FT_MEM_COPY( table->block, old_base, table->cursor );
-    shift_elements( table, old_base );
-
-    table->capacity = table->cursor;
-    FT_FREE( old_base );
-
-    FT_UNUSED( error );
+    /* no problem if shrinking fails */
+    ps_table_realloc( table, table->cursor );
   }
 
 
@@ -270,7 +234,7 @@
     FT_Memory  memory = table->memory;
 
 
-    if ( (FT_ULong)table->init == 0xDEADBEEFUL )
+    if ( table->init == 0xDEADBEEFUL )
     {
       FT_FREE( table->block );
       FT_FREE( table->elements );
@@ -553,7 +517,7 @@
 
     if ( *cur == '<' )                              /* <...> */
     {
-      if ( cur + 1 < limit && *(cur + 1) == '<' )   /* << */
+      if ( cur + 1 < limit && *( cur + 1 ) == '<' ) /* << */
       {
         cur++;
         cur++;
@@ -596,10 +560,10 @@
     if ( cur < limit && cur == parser->cursor )
     {
       FT_ERROR(( "ps_parser_skip_PS_token:"
-                 " current token is `%c' which is self-delimiting\n"
-                 "                        "
-                 " but invalid at this point\n",
+                 " current token is `%c' which is self-delimiting\n",
                  *cur ));
+      FT_ERROR(( "                        "
+                 " but invalid at this point\n" ));
 
       error = FT_THROW( Invalid_File_Format );
     }
@@ -980,7 +944,7 @@
     }
 
     len = (FT_UInt)( cur - *cursor );
-    if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
+    if ( cur >= limit || FT_QALLOC( result, len + 1 ) )
       return 0;
 
     /* now copy the string */
@@ -1099,7 +1063,6 @@
     {
       FT_Byte*    q      = (FT_Byte*)objects[idx] + field->offset;
       FT_Long     val;
-      FT_String*  string = NULL;
 
 
       skip_spaces( &cur, limit );
@@ -1149,8 +1112,9 @@
       case T1_FIELD_TYPE_STRING:
       case T1_FIELD_TYPE_KEY:
         {
-          FT_Memory  memory = parser->memory;
-          FT_UInt    len    = (FT_UInt)( limit - cur );
+          FT_Memory   memory = parser->memory;
+          FT_UInt     len    = (FT_UInt)( limit - cur );
+          FT_String*  string = NULL;
 
 
           if ( cur >= limit )
@@ -1176,8 +1140,8 @@
           else
           {
             FT_ERROR(( "ps_parser_load_field:"
-                       " expected a name or string\n"
-                       "                     "
+                       " expected a name or string\n" ));
+            FT_ERROR(( "                     "
                        " but found token of type %d instead\n",
                        token.type ));
             error = FT_THROW( Invalid_File_Format );
@@ -1191,10 +1155,9 @@
             FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
                         field->ident ));
             FT_FREE( *(FT_String**)q );
-            *(FT_String**)q = NULL;
           }
 
-          if ( FT_ALLOC( string, len + 1 ) )
+          if ( FT_QALLOC( string, len + 1 ) )
             goto Exit;
 
           FT_MEM_COPY( string, cur, len );
@@ -1233,7 +1196,7 @@
           bbox->xMax = FT_RoundFix( temp[2] );
           bbox->yMax = FT_RoundFix( temp[3] );
 
-          FT_TRACE4(( " [%d %d %d %d]",
+          FT_TRACE4(( " [%ld %ld %ld %ld]",
                       bbox->xMin / 65536,
                       bbox->yMin / 65536,
                       bbox->xMax / 65536,
@@ -1249,7 +1212,7 @@
           FT_UInt    i;
 
 
-          if ( FT_NEW_ARRAY( temp, max_objects * 4 ) )
+          if ( FT_QNEW_ARRAY( temp, max_objects * 4 ) )
             goto Exit;
 
           for ( i = 0; i < 4; i++ )
@@ -1259,14 +1222,14 @@
             if ( result < 0 || (FT_UInt)result < max_objects )
             {
               FT_ERROR(( "ps_parser_load_field:"
-                         " expected %d integer%s in the %s subarray\n"
-                         "                     "
-                         " of /FontBBox in the /Blend dictionary\n",
+                         " expected %d integer%s in the %s subarray\n",
                          max_objects, max_objects > 1 ? "s" : "",
                          i == 0 ? "first"
                                 : ( i == 1 ? "second"
                                            : ( i == 2 ? "third"
                                                       : "fourth" ) ) ));
+              FT_ERROR(( "                     "
+                         " of /FontBBox in the /Blend dictionary\n" ));
               error = FT_THROW( Invalid_File_Format );
 
               FT_FREE( temp );
@@ -1287,7 +1250,7 @@
             bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] );
             bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] );
 
-            FT_TRACE4(( " [%d %d %d %d]",
+            FT_TRACE4(( " [%ld %ld %ld %ld]",
                         bbox->xMin / 65536,
                         bbox->yMin / 65536,
                         bbox->xMax / 65536,
@@ -1447,6 +1410,8 @@
                                           bytes,
                                           max_bytes );
 
+    parser->cursor = cur;
+
     if ( delimiters )
     {
       if ( cur < parser->limit && *cur != '>' )
@@ -1456,11 +1421,9 @@
         goto Exit;
       }
 
-      cur++;
+      parser->cursor++;
     }
 
-    parser->cursor = cur;
-
   Exit:
     return error;
   }
@@ -2042,6 +2005,14 @@
     first = outline->n_contours <= 1
             ? 0 : outline->contours[outline->n_contours - 2] + 1;
 
+    /* in malformed fonts it can happen that a contour was started */
+    /* but no points were added                                    */
+    if ( outline->n_contours && first == outline->n_points )
+    {
+      outline->n_contours--;
+      return;
+    }
+
     /* We must not include the last point in the path if it */
     /* is located on the first point.                       */
     if ( outline->n_points > 1 )
@@ -2569,7 +2540,7 @@
               FT_UShort  seed )
   {
     PS_Conv_EexecDecode( &buffer,
-                         buffer + length,
+                         FT_OFFSET( buffer, length ),
                          buffer,
                          length,
                          &seed );
diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h
index 6184193..d5bce54 100644
--- a/src/psaux/psobjs.h
+++ b/src/psaux/psobjs.h
@@ -4,7 +4,7 @@
  *
  *   Auxiliary functions for PostScript fonts (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define PSOBJS_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/cffotypes.h>
 
 
 FT_BEGIN_HEADER
@@ -53,10 +52,10 @@
                 FT_Memory  memory );
 
   FT_LOCAL( FT_Error )
-  ps_table_add( PS_Table  table,
-                FT_Int    idx,
-                void*     object,
-                FT_UInt   length );
+  ps_table_add( PS_Table     table,
+                FT_Int       idx,
+                const void*  object,
+                FT_UInt      length );
 
   FT_LOCAL( void )
   ps_table_done( PS_Table  table );
diff --git a/src/psaux/psread.c b/src/psaux/psread.c
index 6f3a361..7f657f2 100644
--- a/src/psaux/psread.c
+++ b/src/psaux/psread.c
@@ -37,7 +37,7 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psglue.h"
 
@@ -105,7 +105,7 @@
   FT_LOCAL_DEF( FT_Bool )
   cf2_buf_isEnd( CF2_Buffer  buf )
   {
-    return (FT_Bool)( buf->ptr >= buf->end );
+    return FT_BOOL( buf->ptr >= buf->end );
   }
 
 
diff --git a/src/psaux/psstack.c b/src/psaux/psstack.c
index d49cf25..7974865 100644
--- a/src/psaux/psstack.c
+++ b/src/psaux/psstack.c
@@ -37,7 +37,7 @@
 
 
 #include "psft.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psglue.h"
 #include "psfont.h"
@@ -54,20 +54,18 @@
                   FT_Error*  e,
                   FT_UInt    stackSize )
   {
-    FT_Error  error = FT_Err_Ok;     /* for FT_NEW */
-
+    FT_Error   error;        /* for FT_QNEW */
     CF2_Stack  stack = NULL;
 
 
-    if ( !FT_NEW( stack ) )
-    {
-      /* initialize the structure; FT_NEW zeroes it */
-      stack->memory = memory;
-      stack->error  = e;
-    }
+    if ( FT_QNEW( stack ) )
+      return NULL;
+
+    stack->memory = memory;
+    stack->error  = e;
 
     /* allocate the stack buffer */
-    if ( FT_NEW_ARRAY( stack->buffer, stackSize ) )
+    if ( FT_QNEW_ARRAY( stack->buffer, stackSize ) )
     {
       FT_FREE( stack );
       return NULL;
@@ -258,6 +256,9 @@
       return;
     }
 
+    /* before C99 it is implementation-defined whether    */
+    /* the result of `%' is negative if the first operand */
+    /* is negative                                        */
     if ( shift < 0 )
       shift = -( ( -shift ) % count );
     else
diff --git a/src/psaux/psstack.h b/src/psaux/psstack.h
index 18cd39b..907b424 100644
--- a/src/psaux/psstack.h
+++ b/src/psaux/psstack.h
@@ -39,6 +39,7 @@
 #ifndef PSSTACK_H_
 #define PSSTACK_H_
 
+#include <freetype/internal/compiler-macros.h>
 
 FT_BEGIN_HEADER
 
@@ -48,8 +49,8 @@
   {
     union
     {
-      CF2_Fixed  r;      /* 16.16 fixed point */
-      CF2_Frac   f;      /* 2.30 fixed point (for font matrix) */
+      CF2_Fixed  r;      /* 16.16 fixed-point */
+      CF2_Frac   f;      /* 2.30 fixed-point (for font matrix) */
       CF2_Int    i;
     } u;
 
diff --git a/src/psaux/pstypes.h b/src/psaux/pstypes.h
index 041287e..435ef7e 100644
--- a/src/psaux/pstypes.h
+++ b/src/psaux/pstypes.h
@@ -39,8 +39,7 @@
 #ifndef PSTYPES_H_
 #define PSTYPES_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <freetype/freetype.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/psaux/rules.mk b/src/psaux/rules.mk
index a87bfe9..d542ab8 100644
--- a/src/psaux/rules.mk
+++ b/src/psaux/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/psaux/t1cmap.c b/src/psaux/t1cmap.c
index 0c9f916..bf0a393 100644
--- a/src/psaux/t1cmap.c
+++ b/src/psaux/t1cmap.c
@@ -4,7 +4,7 @@
  *
  *   Type 1 character map support (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,7 +18,7 @@
 
 #include "t1cmap.h"
 
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
 #include "psauxerr.h"
 
@@ -305,6 +305,9 @@
     FT_UNUSED( pointer );
 
 
+    if ( !psnames->unicodes_init )
+      return FT_THROW( Unimplemented_Feature );
+
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    (FT_UInt)face->type1.num_glyphs,
diff --git a/src/psaux/t1cmap.h b/src/psaux/t1cmap.h
index 277419f..b370249 100644
--- a/src/psaux/t1cmap.h
+++ b/src/psaux/t1cmap.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 character map support (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,9 +19,8 @@
 #ifndef T1CMAP_H_
 #define T1CMAP_H_
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/t1types.h>
 
 FT_BEGIN_HEADER
 
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 6745603..bfed45b 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -4,7 +4,7 @@
  *
  *   PostScript Type 1 decoding routines (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,20 +16,22 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
-#include FT_INTERNAL_HASH_H
-#include FT_OUTLINE_H
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/pshints.h>
+#include <freetype/internal/fthash.h>
+#include <freetype/ftoutln.h>
 
 #include "t1decode.h"
 #include "psobjs.h"
 
 #include "psauxerr.h"
 
+
 /* ensure proper sign extension */
-#define Fix2Int( f )  ( (FT_Int)(FT_Short)( (f) >> 16 ) )
+#define Fix2Int( f )   ( (FT_Int) (FT_Short)( (f) >> 16 ) )
+#define Fix2UInt( f )  ( (FT_UInt)(FT_Short)( (f) >> 16 ) )
+
 
   /**************************************************************************
    *
@@ -38,7 +40,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1decode
+#define FT_COMPONENT  t1decode
 
 
   typedef enum  T1_Operator_
@@ -367,6 +369,12 @@
 
     FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
 
+    /* save the left bearing and width of the SEAC   */
+    /* glyph as they will be erased by the next load */
+
+    left_bearing = decoder->builder.left_bearing;
+    advance      = decoder->builder.advance;
+
     /* the seac operator must not be nested */
     decoder->seac = TRUE;
     error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
@@ -374,11 +382,14 @@
     if ( error )
       goto Exit;
 
-    /* save the left bearing and width of the base character */
-    /* as they will be erased by the next load.              */
+    /* If the SEAC glyph doesn't have a (H)SBW of its */
+    /* own use the values from the base glyph.        */
 
-    left_bearing = decoder->builder.left_bearing;
-    advance      = decoder->builder.advance;
+    if ( decoder->builder.parse_state != T1_Parse_Have_Width )
+    {
+      left_bearing = decoder->builder.left_bearing;
+      advance      = decoder->builder.advance;
+    }
 
     decoder->builder.left_bearing.x = 0;
     decoder->builder.left_bearing.y = 0;
@@ -396,8 +407,8 @@
     if ( error )
       goto Exit;
 
-    /* restore the left side bearing and   */
-    /* advance width of the base character */
+    /* restore the left side bearing and advance width   */
+    /* of the SEAC glyph or base character (saved above) */
 
     decoder->builder.left_bearing = left_bearing;
     decoder->builder.advance      = advance;
@@ -509,7 +520,7 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( bol )
       {
-        FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
+        FT_TRACE5(( " (%ld)", decoder->top - decoder->stack ));
         bol = FALSE;
       }
 #endif
@@ -650,10 +661,8 @@
         if ( value > 32000 || value < -32000 )
         {
           if ( large_int )
-          {
             FT_ERROR(( "t1_decoder_parse_charstrings:"
                        " no `div' after large integer\n" ));
-          }
           else
             large_int = TRUE;
         }
@@ -1019,16 +1028,16 @@
           /* <val> <idx> 2 24 callothersubr               */
           /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
           {
-            FT_Int    idx;
+            FT_UInt   idx;
             PS_Blend  blend = decoder->blend;
 
 
             if ( arg_cnt != 2 || !blend )
               goto Unexpected_OtherSubr;
 
-            idx = Fix2Int( top[1] );
+            idx = Fix2UInt( top[1] );
 
-            if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
+            if ( idx >= decoder->len_buildchar )
               goto Unexpected_OtherSubr;
 
             decoder->buildchar[idx] = top[0];
@@ -1040,16 +1049,16 @@
           /* ==> push BuildCharArray[cvi( idx )] */
           /*     onto T1 stack                   */
           {
-            FT_Int    idx;
+            FT_UInt   idx;
             PS_Blend  blend = decoder->blend;
 
 
             if ( arg_cnt != 1 || !blend )
               goto Unexpected_OtherSubr;
 
-            idx = Fix2Int( top[0] );
+            idx = Fix2UInt( top[0] );
 
-            if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
+            if ( idx >= decoder->len_buildchar )
               goto Unexpected_OtherSubr;
 
             top[0] = decoder->buildchar[idx];
@@ -1156,9 +1165,9 @@
           if ( top - decoder->stack != num_args )
             FT_TRACE0(( "t1_decoder_parse_charstrings:"
                         " too much operands on the stack"
-                        " (seen %d, expected %d)\n",
+                        " (seen %ld, expected %d)\n",
                         top - decoder->stack, num_args ));
-            break;
+          break;
         }
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
@@ -1203,7 +1212,7 @@
             FT_TRACE4(( "BuildCharArray = [ " ));
 
             for ( i = 0; i < decoder->len_buildchar; i++ )
-              FT_TRACE4(( "%d ", decoder->buildchar[i] ));
+              FT_TRACE4(( "%ld ", decoder->buildchar[i] ));
 
             FT_TRACE4(( "]\n" ));
           }
@@ -1231,8 +1240,8 @@
 
           FT_UNUSED( orig_y );
 
-          /* the `metrics_only' indicates that we only want to compute */
-          /* the glyph's metrics (lsb + advance width), not load the   */
+          /* `metrics_only' indicates that we only want to compute the */
+          /* glyph's metrics (lsb + advance width) without loading the */
           /* rest of it; so exit immediately                           */
           if ( builder->metrics_only )
           {
@@ -1266,8 +1275,8 @@
           x = ADD_LONG( builder->pos_x, top[0] );
           y = ADD_LONG( builder->pos_y, top[1] );
 
-          /* the `metrics_only' indicates that we only want to compute */
-          /* the glyph's metrics (lsb + advance width), not load the   */
+          /* `metrics_only' indicates that we only want to compute the */
+          /* glyph's metrics (lsb + advance width) without loading the */
           /* rest of it; so exit immediately                           */
           if ( builder->metrics_only )
           {
@@ -1644,7 +1653,8 @@
 
     } /* while ip < limit */
 
-    FT_TRACE4(( "..end..\n\n" ));
+    FT_TRACE4(( "..end..\n" ));
+    FT_TRACE4(( "\n" ));
 
   Fail:
     return error;
@@ -1690,6 +1700,7 @@
     FT_Byte*         ip;
     FT_Byte*         limit;
     T1_Builder       builder = &decoder->builder;
+    FT_Bool          large_int;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     FT_Bool          bol = TRUE;
@@ -1707,6 +1718,8 @@
     limit = zone->limit  = charstring_base + charstring_len;
     ip    = zone->cursor = zone->base;
 
+    large_int = FALSE;
+
     /* now, execute loop */
     while ( ip < limit )
     {
@@ -1718,7 +1731,7 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( bol )
       {
-        FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
+        FT_TRACE5(( " (%ld)", decoder->top - decoder->stack ));
         bol = FALSE;
       }
 #endif
@@ -1740,8 +1753,6 @@
       case 7:
       case 8:
       case 9:
-      case 10:
-      case 11:
       case 14:
       case 15:
       case 21:
@@ -1750,6 +1761,13 @@
       case 31:
         goto No_Width;
 
+      case 10:
+        op = op_callsubr;
+        break;
+      case 11:
+        op = op_return;
+        break;
+
       case 13:
         op = op_hsbw;
         break;
@@ -1767,6 +1785,9 @@
         case 7:
           op = op_sbw;
           break;
+        case 12:
+          op = op_div;
+          break;
 
         default:
           goto No_Width;
@@ -1796,13 +1817,19 @@
         /* anyway.                                                         */
         if ( value > 32000 || value < -32000 )
         {
-          FT_ERROR(( "t1_decoder_parse_metrics:"
-                     " large integer found for width\n" ));
-          goto Syntax_Error;
+          if ( large_int )
+          {
+            FT_ERROR(( "t1_decoder_parse_metrics:"
+                       " no `div' after large integer\n" ));
+            goto Syntax_Error;
+          }
+          else
+            large_int = TRUE;
         }
         else
         {
-          value = (FT_Int32)( (FT_UInt32)value << 16 );
+          if ( !large_int )
+            value = (FT_Int32)( (FT_UInt32)value << 16 );
         }
 
         break;
@@ -1827,7 +1854,8 @@
               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
           }
 
-          value = (FT_Int32)( (FT_UInt32)value << 16 );
+          if ( !large_int )
+            value = (FT_Int32)( (FT_UInt32)value << 16 );
         }
         else
         {
@@ -1837,6 +1865,13 @@
         }
       }
 
+      if ( large_int && !( op == op_none || op == op_div ) )
+      {
+        FT_ERROR(( "t1_decoder_parse_metrics:"
+                   " no `div' after large integer\n" ));
+        goto Syntax_Error;
+      }
+
       /**********************************************************************
        *
        * Push value on stack, or process operator
@@ -1851,6 +1886,9 @@
         }
 
 #ifdef FT_DEBUG_LEVEL_TRACE
+        if ( large_int )
+          FT_TRACE4(( " %d", value ));
+        else
           FT_TRACE4(( " %d", value / 65536 ));
 #endif
 
@@ -1869,11 +1907,21 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-        if ( top - decoder->stack != num_args )
-          FT_TRACE0(( "t1_decoder_parse_metrics:"
-                      " too much operands on the stack"
-                      " (seen %d, expected %d)\n",
-                      top - decoder->stack, num_args ));
+        switch ( op )
+        {
+        case op_callsubr:
+        case op_div:
+        case op_return:
+          break;
+
+        default:
+          if ( top - decoder->stack != num_args )
+            FT_TRACE0(( "t1_decoder_parse_metrics:"
+                        " too much operands on the stack"
+                        " (seen %ld, expected %d)\n",
+                        top - decoder->stack, num_args ));
+          break;
+        }
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
@@ -1893,8 +1941,8 @@
           builder->advance.y = 0;
 
           /* we only want to compute the glyph's metrics */
-          /* (lsb + advance width), not load the rest of */
-          /* it; so exit immediately                     */
+          /* (lsb + advance width) without loading the   */
+          /* rest of it; so exit immediately             */
           FT_TRACE4(( "\n" ));
           return FT_Err_Ok;
 
@@ -1912,22 +1960,122 @@
           builder->advance.y = top[3];
 
           /* we only want to compute the glyph's metrics */
-          /* (lsb + advance width), not load the rest of */
-          /* it; so exit immediately                     */
+          /* (lsb + advance width), without loading the  */
+          /* rest of it; so exit immediately             */
           FT_TRACE4(( "\n" ));
           return FT_Err_Ok;
 
+        case op_div:
+          FT_TRACE4(( " div" ));
+
+          /* if `large_int' is set, we divide unscaled numbers; */
+          /* otherwise, we divide numbers in 16.16 format --    */
+          /* in both cases, it is the same operation            */
+          *top = FT_DivFix( top[0], top[1] );
+          top++;
+
+          large_int = FALSE;
+          break;
+
+        case op_callsubr:
+          {
+            FT_Int  idx;
+
+
+            FT_TRACE4(( " callsubr" ));
+
+            idx = Fix2Int( top[0] );
+
+            if ( decoder->subrs_hash )
+            {
+              size_t*  val = ft_hash_num_lookup( idx,
+                                                 decoder->subrs_hash );
+
+
+              if ( val )
+                idx = *val;
+              else
+                idx = -1;
+            }
+
+            if ( idx < 0 || idx >= decoder->num_subrs )
+            {
+              FT_ERROR(( "t1_decoder_parse_metrics:"
+                         " invalid subrs index\n" ));
+              goto Syntax_Error;
+            }
+
+            if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
+            {
+              FT_ERROR(( "t1_decoder_parse_metrics:"
+                         " too many nested subrs\n" ));
+              goto Syntax_Error;
+            }
+
+            zone->cursor = ip;  /* save current instruction pointer */
+
+            zone++;
+
+            /* The Type 1 driver stores subroutines without the seed bytes. */
+            /* The CID driver stores subroutines with seed bytes.  This     */
+            /* case is taken care of when decoder->subrs_len == 0.          */
+            zone->base = decoder->subrs[idx];
+
+            if ( decoder->subrs_len )
+              zone->limit = zone->base + decoder->subrs_len[idx];
+            else
+            {
+              /* We are using subroutines from a CID font.  We must adjust */
+              /* for the seed bytes.                                       */
+              zone->base  += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
+              zone->limit  = decoder->subrs[idx + 1];
+            }
+
+            zone->cursor = zone->base;
+
+            if ( !zone->base )
+            {
+              FT_ERROR(( "t1_decoder_parse_metrics:"
+                         " invoking empty subrs\n" ));
+              goto Syntax_Error;
+            }
+
+            decoder->zone = zone;
+            ip            = zone->base;
+            limit         = zone->limit;
+            break;
+          }
+
+        case op_return:
+          FT_TRACE4(( " return" ));
+
+          if ( zone <= decoder->zones )
+          {
+            FT_ERROR(( "t1_decoder_parse_metrics:"
+                       " unexpected return\n" ));
+            goto Syntax_Error;
+          }
+
+          zone--;
+          ip            = zone->cursor;
+          limit         = zone->limit;
+          decoder->zone = zone;
+          break;
+
         default:
           FT_ERROR(( "t1_decoder_parse_metrics:"
                      " unhandled opcode %d\n", op ));
           goto Syntax_Error;
         }
 
+        decoder->top = top;
+
       } /* general operator processing */
 
     } /* while ip < limit */
 
-    FT_TRACE4(( "..end..\n\n" ));
+    FT_TRACE4(( "..end..\n" ));
+    FT_TRACE4(( "\n" ));
 
   No_Width:
     FT_ERROR(( "t1_decoder_parse_metrics:"
@@ -1957,7 +2105,7 @@
   {
     FT_ZERO( decoder );
 
-    /* retrieve PSNames interface from list of current modules */
+    /* retrieve `psnames' interface from list of current modules */
     {
       FT_Service_PsCMaps  psnames;
 
diff --git a/src/psaux/t1decode.h b/src/psaux/t1decode.h
index 62956ac..0970def 100644
--- a/src/psaux/t1decode.h
+++ b/src/psaux/t1decode.h
@@ -4,7 +4,7 @@
  *
  *   PostScript Type 1 decoding routines (specification).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define T1DECODE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/t1types.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/pshinter/Jamfile b/src/pshinter/Jamfile
deleted file mode 100644
index 3f5f0ae..0000000
--- a/src/pshinter/Jamfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# FreeType 2 src/pshinter Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) pshinter ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = pshalgo
-               pshglob
-               pshmod
-               pshpic
-               pshrec
-               ;
-  }
-  else
-  {
-    _sources = pshinter ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/pshinter Jamfile
diff --git a/src/pshinter/module.mk b/src/pshinter/module.mk
index 06707be..dbc137d 100644
--- a/src/pshinter/module.mk
+++ b/src/pshinter/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index 925b3d6..a7f3212 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -4,7 +4,7 @@
  *
  *   PostScript hinting algorithm (body).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used
@@ -16,17 +16,16 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
 #include "pshalgo.h"
 
 #include "pshnterr.h"
 
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pshalgo
+#define FT_COMPONENT  pshalgo
 
 
 #ifdef DEBUG_HINTER
@@ -53,8 +52,8 @@
   psh_hint_overlap( PSH_Hint  hint1,
                     PSH_Hint  hint2 )
   {
-    return hint1->org_pos + hint1->org_len >= hint2->org_pos &&
-           hint2->org_pos + hint2->org_len >= hint1->org_pos;
+    return ADD_INT( hint1->org_pos, hint1->org_len ) >= hint2->org_pos &&
+           ADD_INT( hint2->org_pos, hint2->org_len ) >= hint1->org_pos;
   }
 
 
@@ -183,13 +182,13 @@
     count = hints->num_hints;
 
     /* allocate our tables */
-    if ( FT_NEW_ARRAY( table->sort,  2 * count     ) ||
-         FT_NEW_ARRAY( table->hints,     count     ) ||
-         FT_NEW_ARRAY( table->zones, 2 * count + 1 ) )
+    if ( FT_QNEW_ARRAY( table->sort,  2 * count     ) ||
+         FT_QNEW_ARRAY( table->hints,     count     ) ||
+         FT_QNEW_ARRAY( table->zones, 2 * count + 1 ) )
       goto Exit;
 
     table->max_hints   = count;
-    table->sort_global = table->sort + count;
+    table->sort_global = FT_OFFSET( table->sort, count );
     table->num_hints   = 0;
     table->num_zones   = 0;
     table->zone        = NULL;
@@ -306,17 +305,18 @@
     /* now, sort the hints; they are guaranteed to not overlap */
     /* so we can compare their "org_pos" field directly        */
     {
-      FT_Int     i1, i2;
+      FT_UInt    i1, i2;
       PSH_Hint   hint1, hint2;
       PSH_Hint*  sort = table->sort;
 
 
       /* a simple bubble sort will do, since in 99% of cases, the hints */
       /* will be already sorted -- and the sort will be linear          */
-      for ( i1 = 1; i1 < (FT_Int)count; i1++ )
+      for ( i1 = 1; i1 < count; i1++ )
       {
         hint1 = sort[i1];
-        for ( i2 = i1 - 1; i2 >= 0; i2-- )
+        /* this loop stops when i2 wraps around after reaching 0 */
+        for ( i2 = i1 - 1; i2 < i1; i2-- )
         {
           hint2 = sort[i2];
 
@@ -479,7 +479,7 @@
 
       if ( dimension == 1 )
         psh_blues_snap_stem( &globals->blues,
-                             hint->org_pos + hint->org_len,
+                             ADD_INT( hint->org_pos, hint->org_len ),
                              hint->org_pos,
                              &align );
 
@@ -703,7 +703,7 @@
 
       if ( dimension == 1 )
         psh_blues_snap_stem( &globals->blues,
-                             hint->org_pos + hint->org_len,
+                             ADD_INT( hint->org_pos, hint->org_len ),
                              hint->org_pos,
                              &align );
 
@@ -870,7 +870,7 @@
       return;
     }
 
-#endif /* DEBUG_HINTER*/
+#endif /* DEBUG_HINTER */
 
     hint  = table->hints;
     count = table->max_hints;
@@ -1050,12 +1050,12 @@
   }
 
 
-  static int
+  static PSH_Dir
   psh_compute_dir( FT_Pos  dx,
                    FT_Pos  dy )
   {
-    FT_Pos  ax, ay;
-    int     result = PSH_DIR_NONE;
+    FT_Pos   ax, ay;
+    PSH_Dir  result = PSH_DIR_NONE;
 
 
     ax = FT_ABS( dx );
@@ -1167,8 +1167,8 @@
     memory = glyph->memory = globals->memory;
 
     /* allocate and setup points + contours arrays */
-    if ( FT_NEW_ARRAY( glyph->points,   outline->n_points   ) ||
-         FT_NEW_ARRAY( glyph->contours, outline->n_contours ) )
+    if ( FT_QNEW_ARRAY( glyph->points,   outline->n_points   ) ||
+         FT_QNEW_ARRAY( glyph->contours, outline->n_contours ) )
       goto Exit;
 
     glyph->num_points   = (FT_UInt)outline->n_points;
@@ -1228,28 +1228,29 @@
         FT_Pos  dxi, dyi, dxo, dyo;
 
 
+        point->flags = 0;
         if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) )
-          point->flags = PSH_POINT_OFF;
+          psh_point_set_off( point );
 
         dxi = vec[n].x - vec[n_prev].x;
         dyi = vec[n].y - vec[n_prev].y;
 
-        point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi );
+        point->dir_in = psh_compute_dir( dxi, dyi );
 
         dxo = vec[n_next].x - vec[n].x;
         dyo = vec[n_next].y - vec[n].y;
 
-        point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo );
+        point->dir_out = psh_compute_dir( dxo, dyo );
 
         /* detect smooth points */
-        if ( point->flags & PSH_POINT_OFF )
-          point->flags |= PSH_POINT_SMOOTH;
+        if ( psh_point_is_off( point ) )
+          psh_point_set_smooth( point );
 
         else if ( point->dir_in == point->dir_out )
         {
           if ( point->dir_out != PSH_DIR_NONE           ||
                psh_corner_is_flat( dxi, dyi, dxo, dyo ) )
-            point->flags |= PSH_POINT_SMOOTH;
+            psh_point_set_smooth( point );
         }
       }
     }
@@ -1404,16 +1405,13 @@
   }
 
 
-  /* major_dir is the direction for points on the bottom/left of the stem; */
-  /* Points on the top/right of the stem will have a direction of          */
-  /* -major_dir.                                                           */
-
+  /* the min and max are based on contour orientation and fill rule */
   static void
   psh_hint_table_find_strong_points( PSH_Hint_Table  table,
                                      PSH_Point       point,
                                      FT_UInt         count,
                                      FT_Int          threshold,
-                                     FT_Int          major_dir )
+                                     PSH_Dir         major_dir )
   {
     PSH_Hint*  sort      = table->sort;
     FT_UInt    num_hints = table->num_hints;
@@ -1421,59 +1419,53 @@
 
     for ( ; count > 0; count--, point++ )
     {
-      FT_Int  point_dir = 0;
-      FT_Pos  org_u     = point->org_u;
+      PSH_Dir  point_dir;
+      FT_Pos   org_u = point->org_u;
 
 
       if ( psh_point_is_strong( point ) )
         continue;
 
-      if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )
-        point_dir = point->dir_in;
+      point_dir =
+        (PSH_Dir)( ( point->dir_in | point->dir_out ) & major_dir );
 
-      else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )
-        point_dir = point->dir_out;
-
-      if ( point_dir )
+      if ( point_dir & ( PSH_DIR_DOWN | PSH_DIR_RIGHT ) )
       {
-        if ( point_dir == major_dir )
+        FT_UInt  nn;
+
+
+        for ( nn = 0; nn < num_hints; nn++ )
         {
-          FT_UInt  nn;
+          PSH_Hint  hint = sort[nn];
+          FT_Pos    d    = org_u - hint->org_pos;
 
 
-          for ( nn = 0; nn < num_hints; nn++ )
+          if ( d < threshold && -d < threshold )
           {
-            PSH_Hint  hint = sort[nn];
-            FT_Pos    d    = org_u - hint->org_pos;
-
-
-            if ( d < threshold && -d < threshold )
-            {
-              psh_point_set_strong( point );
-              point->flags2 |= PSH_POINT_EDGE_MIN;
-              point->hint    = hint;
-              break;
-            }
+            psh_point_set_strong( point );
+            point->flags2 |= PSH_POINT_EDGE_MIN;
+            point->hint    = hint;
+            break;
           }
         }
-        else if ( point_dir == -major_dir )
+      }
+      else if ( point_dir & ( PSH_DIR_UP | PSH_DIR_LEFT ) )
+      {
+        FT_UInt  nn;
+
+
+        for ( nn = 0; nn < num_hints; nn++ )
         {
-          FT_UInt  nn;
+          PSH_Hint  hint = sort[nn];
+          FT_Pos    d    = org_u - hint->org_pos - hint->org_len;
 
 
-          for ( nn = 0; nn < num_hints; nn++ )
+          if ( d < threshold && -d < threshold )
           {
-            PSH_Hint  hint = sort[nn];
-            FT_Pos    d    = org_u - hint->org_pos - hint->org_len;
-
-
-            if ( d < threshold && -d < threshold )
-            {
-              psh_point_set_strong( point );
-              point->flags2 |= PSH_POINT_EDGE_MAX;
-              point->hint    = hint;
-              break;
-            }
+            psh_point_set_strong( point );
+            point->flags2 |= PSH_POINT_EDGE_MAX;
+            point->hint    = hint;
+            break;
           }
         }
       }
@@ -1538,8 +1530,8 @@
             PSH_Hint  hint = sort[nn];
 
 
-            if ( org_u >= hint->org_pos                 &&
-                org_u <= hint->org_pos + hint->org_len )
+            if ( org_u >=          hint->org_pos                  &&
+                 org_u <= ADD_INT( hint->org_pos, hint->org_len ) )
             {
               point->hint = hint;
               break;
@@ -1556,8 +1548,9 @@
   /* the accepted shift for strong points in fractional pixels */
 #define PSH_STRONG_THRESHOLD  32
 
-  /* the maximum shift value in font units */
-#define PSH_STRONG_THRESHOLD_MAXIMUM  30
+  /* the maximum shift value in font units tuned to distinguish */
+  /* between stems and serifs in URW+ font collection           */
+#define PSH_STRONG_THRESHOLD_MAXIMUM  12
 
 
   /* find strong points in a glyph */
@@ -1572,7 +1565,7 @@
     PS_Mask         mask      = table->hint_masks->masks;
     FT_UInt         num_masks = table->hint_masks->num_masks;
     FT_UInt         first     = 0;
-    FT_Int          major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL
+    PSH_Dir         major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL
                                                    : PSH_DIR_HORIZONTAL;
     PSH_Dimension   dim       = &glyph->globals->dimension[dimension];
     FT_Fixed        scale     = dim->scale_mult;
@@ -1657,8 +1650,8 @@
 
 
       /* check tangents */
-      if ( !PSH_DIR_COMPARE( point->dir_in,  PSH_DIR_HORIZONTAL ) &&
-           !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) )
+      if ( !( point->dir_in  & PSH_DIR_HORIZONTAL ) &&
+           !( point->dir_out & PSH_DIR_HORIZONTAL ) )
         continue;
 
       /* skip strong points */
@@ -1806,7 +1799,7 @@
       FT_Error  error;
 
 
-      if ( FT_NEW_ARRAY( strongs, num_strongs ) )
+      if ( FT_QNEW_ARRAY( strongs, num_strongs ) )
         return;
     }
 
@@ -2119,14 +2112,17 @@
       FT_Fixed  old_x_scale = x_scale;
       FT_Fixed  old_y_scale = y_scale;
 
-      FT_Fixed  scaled;
-      FT_Fixed  fitted;
+      FT_Fixed  scaled = 0;
+      FT_Fixed  fitted = 0;
 
       FT_Bool  rescale = FALSE;
 
 
-      scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );
-      fitted = FT_PIX_ROUND( scaled );
+      if ( globals->blues.normal_top.count )
+      {
+        scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );
+        fitted = FT_PIX_ROUND( scaled );
+      }
 
       if ( fitted != 0 && scaled != fitted )
       {
diff --git a/src/pshinter/pshalgo.h b/src/pshinter/pshalgo.h
index f27e668..3f0ba28 100644
--- a/src/pshinter/pshalgo.h
+++ b/src/pshinter/pshalgo.h
@@ -4,7 +4,7 @@
  *
  *   PostScript hinting algorithm (specification).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -93,21 +93,17 @@
   typedef struct PSH_PointRec_*    PSH_Point;
   typedef struct PSH_ContourRec_*  PSH_Contour;
 
-  enum
+  typedef enum PSH_Dir_
   {
-    PSH_DIR_NONE  =  4,
-    PSH_DIR_UP    = -1,
-    PSH_DIR_DOWN  =  1,
-    PSH_DIR_LEFT  = -2,
-    PSH_DIR_RIGHT =  2
-  };
+    PSH_DIR_NONE       = 0,
+    PSH_DIR_UP         = 1,
+    PSH_DIR_DOWN       = 2,
+    PSH_DIR_VERTICAL   = 1 | 2,
+    PSH_DIR_LEFT       = 4,
+    PSH_DIR_RIGHT      = 8,
+    PSH_DIR_HORIZONTAL = 4 | 8
 
-#define PSH_DIR_HORIZONTAL  2
-#define PSH_DIR_VERTICAL    1
-
-#define PSH_DIR_COMPARE( d1, d2 )   ( (d1) == (d2) || (d1) == -(d2) )
-#define PSH_DIR_IS_HORIZONTAL( d )  PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL )
-#define PSH_DIR_IS_VERTICAL( d )    PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL )
+  } PSH_Dir;
 
 
   /* the following bit-flags are computed once by the glyph */
@@ -160,8 +156,8 @@
     PSH_Contour  contour;
     FT_UInt      flags;
     FT_UInt      flags2;
-    FT_Char      dir_in;
-    FT_Char      dir_out;
+    PSH_Dir      dir_in;
+    PSH_Dir      dir_out;
     PSH_Hint     hint;
     FT_Pos       org_u;
     FT_Pos       org_v;
@@ -199,10 +195,6 @@
     PSH_Globals        globals;
     PSH_Hint_TableRec  hint_tables[2];
 
-    FT_Bool            vertical;
-    FT_Int             major_dir;
-    FT_Int             minor_dir;
-
     FT_Bool            do_horz_hints;
     FT_Bool            do_vert_hints;
     FT_Bool            do_horz_snapping;
diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c
index f6859cd..d4c5eb3 100644
--- a/src/pshinter/pshglob.c
+++ b/src/pshinter/pshglob.c
@@ -5,7 +5,7 @@
  *   PostScript hinter global hinting management (body).
  *   Inspired by the new auto-hinter module.
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used
@@ -17,9 +17,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftcalc.h>
 #include "pshglob.h"
 
 #ifdef DEBUG_HINTER
@@ -568,7 +568,7 @@
 
     for ( ; count > 0; count--, zone++ )
     {
-      delta = stem_top - zone->org_bottom;
+      delta = SUB_LONG( stem_top, zone->org_bottom );
       if ( delta < -blues->blue_fuzz )
         break;
 
@@ -590,7 +590,7 @@
 
     for ( ; count > 0; count--, zone-- )
     {
-      delta = zone->org_top - stem_bot;
+      delta = SUB_LONG( zone->org_top, stem_bot );
       if ( delta < -blues->blue_fuzz )
         break;
 
@@ -650,7 +650,7 @@
     FT_Error     error;
 
 
-    if ( !FT_NEW( globals ) )
+    if ( !FT_QNEW( globals ) )
     {
       FT_UInt    count;
       FT_Short*  read;
diff --git a/src/pshinter/pshglob.h b/src/pshinter/pshglob.h
index c3aa0ae..579eb21 100644
--- a/src/pshinter/pshglob.h
+++ b/src/pshinter/pshglob.h
@@ -4,7 +4,7 @@
  *
  *   PostScript hinter global hinting management.
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,8 @@
 #define PSHGLOB_H_
 
 
-#include FT_FREETYPE_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include <freetype/freetype.h>
+#include <freetype/internal/pshints.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/pshinter/pshinter.c b/src/pshinter/pshinter.c
index fd703d6..54ed410 100644
--- a/src/pshinter/pshinter.c
+++ b/src/pshinter/pshinter.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PostScript Hinting module
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "pshalgo.c"
 #include "pshglob.c"
diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c
index e040d60..a12e485 100644
--- a/src/pshinter/pshmod.c
+++ b/src/pshinter/pshmod.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PostScript hinter module implementation (body).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 #include "pshrec.h"
 #include "pshalgo.h"
+#include "pshmod.h"
 
 
   /* the Postscript Hinter module structure */
diff --git a/src/pshinter/pshmod.h b/src/pshinter/pshmod.h
index 368740c..4bd781a 100644
--- a/src/pshinter/pshmod.h
+++ b/src/pshinter/pshmod.h
@@ -4,7 +4,7 @@
  *
  *   PostScript hinter module interface (specification).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define PSHMOD_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/pshinter/pshnterr.h b/src/pshinter/pshnterr.h
index 60814e1..9762495 100644
--- a/src/pshinter/pshnterr.h
+++ b/src/pshinter/pshnterr.h
@@ -4,7 +4,7 @@
  *
  *   PS Hinter error codes (specification only).
  *
- * Copyright 2003-2018 by
+ * Copyright (C) 2003-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef PSHNTERR_H_
 #define PSHNTERR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  PSH_Err_
 #define FT_ERR_BASE    FT_Mod_Err_PShinter
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* PSHNTERR_H_ */
 
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index 50d66ca..58c8cf1 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
  *
  *   FreeType PostScript hints recorder (body).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
 
 #include "pshrec.h"
 #include "pshalgo.h"
@@ -28,7 +27,7 @@
 #include "pshnterr.h"
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_pshrec
+#define FT_COMPONENT  pshrec
 
 #ifdef DEBUG_HINTER
   PS_Hints  ps_debug_hints         = NULL;
@@ -64,16 +63,14 @@
   {
     FT_UInt   old_max = table->max_hints;
     FT_UInt   new_max = count;
-    FT_Error  error   = FT_Err_Ok;
+    FT_Error  error;
 
 
-    if ( new_max > old_max )
-    {
-      /* try to grow the table */
-      new_max = FT_PAD_CEIL( new_max, 8 );
-      if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) )
-        table->max_hints = new_max;
-    }
+    /* try to grow the table */
+    new_max = FT_PAD_CEIL( new_max, 8 );
+    if ( !FT_QRENEW_ARRAY( table->hints, old_max, new_max ) )
+      table->max_hints = new_max;
+
     return error;
   }
 
@@ -91,17 +88,14 @@
     count = table->num_hints;
     count++;
 
-    if ( count >= table->max_hints )
+    if ( count > table->max_hints )
     {
       error = ps_hint_table_ensure( table, count, memory );
       if ( error )
         goto Exit;
     }
 
-    hint        = table->hints + count - 1;
-    hint->pos   = 0;
-    hint->len   = 0;
-    hint->flags = 0;
+    hint = table->hints + count - 1;  /* initialized upstream */
 
     table->num_hints = count;
 
@@ -137,14 +131,15 @@
                   FT_UInt    count,
                   FT_Memory  memory )
   {
-    FT_UInt   old_max = ( mask->max_bits + 7 ) >> 3;
-    FT_UInt   new_max = ( count          + 7 ) >> 3;
+    FT_UInt   old_max = mask->max_bits >> 3;
+    FT_UInt   new_max = ( count + 7 ) >> 3;
     FT_Error  error   = FT_Err_Ok;
 
 
     if ( new_max > old_max )
     {
       new_max = FT_PAD_CEIL( new_max, 8 );
+      /* added bytes are zeroed here */
       if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) )
         mask->max_bits = new_max * 8;
     }
@@ -155,31 +150,15 @@
   /* test a bit value in a given mask */
   static FT_Int
   ps_mask_test_bit( PS_Mask  mask,
-                    FT_Int   idx )
+                    FT_UInt  idx )
   {
-    if ( (FT_UInt)idx >= mask->num_bits )
+    if ( idx >= mask->num_bits )
       return 0;
 
     return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) );
   }
 
 
-  /* clear a given bit */
-  static void
-  ps_mask_clear_bit( PS_Mask  mask,
-                     FT_UInt  idx )
-  {
-    FT_Byte*  p;
-
-
-    if ( idx >= mask->num_bits )
-      return;
-
-    p    = mask->bytes + ( idx >> 3 );
-    p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) );
-  }
-
-
   /* set a given bit, possibly grow the mask */
   static FT_Error
   ps_mask_set_bit( PS_Mask    mask,
@@ -270,6 +249,10 @@
     mask             = table->masks + count - 1;
     mask->num_bits   = 0;
     mask->end_point  = 0;
+    /* reused mask must be cleared */
+    if ( mask->max_bits )
+      FT_MEM_ZERO( mask->bytes, mask->max_bits >> 3 );
+
     table->num_masks = count;
 
   Exit:
@@ -427,7 +410,7 @@
       PS_Mask  mask2  = table->masks + index2;
       FT_UInt  count1 = mask1->num_bits;
       FT_UInt  count2 = mask2->num_bits;
-      FT_Int   delta;
+      FT_UInt  delta;
 
 
       if ( count2 > 0 )
@@ -438,15 +421,14 @@
 
 
         /* if "count2" is greater than "count1", we need to grow the */
-        /* first bitset, and clear the highest bits                  */
+        /* first bitset                                              */
         if ( count2 > count1 )
         {
           error = ps_mask_ensure( mask1, count2, memory );
           if ( error )
             goto Exit;
 
-          for ( pos = count1; pos < count2; pos++ )
-            ps_mask_clear_bit( mask1, pos );
+          mask1->num_bits = count2;
         }
 
         /* merge (unite) the bitsets */
@@ -468,7 +450,7 @@
       mask2->end_point = 0;
 
       /* number of masks to move */
-      delta = (FT_Int)( table->num_masks - 1 - index2 );
+      delta = table->num_masks - 1 - index2;
       if ( delta > 0 )
       {
         /* move to end of table for reuse */
@@ -477,7 +459,7 @@
 
         ft_memmove( mask2,
                     mask2 + 1,
-                    (FT_UInt)delta * sizeof ( PS_MaskRec ) );
+                    delta * sizeof ( PS_MaskRec ) );
 
         mask2[delta] = dummy;
       }
@@ -500,23 +482,18 @@
   ps_mask_table_merge_all( PS_Mask_Table  table,
                            FT_Memory      memory )
   {
-    FT_Int    index1, index2;
+    FT_UInt   index1, index2;
     FT_Error  error = FT_Err_Ok;
 
 
-    /* both loops go down to 0, thus FT_Int for index1 and index2 */
-    for ( index1 = (FT_Int)table->num_masks - 1; index1 > 0; index1-- )
+    /* the loops stop when unsigned indices wrap around after 0 */
+    for ( index1 = table->num_masks - 1; index1 < table->num_masks; index1-- )
     {
-      for ( index2 = index1 - 1; index2 >= 0; index2-- )
+      for ( index2 = index1 - 1; index2 < index1; index2-- )
       {
-        if ( ps_mask_table_test_intersect( table,
-                                           (FT_UInt)index1,
-                                           (FT_UInt)index2 ) )
+        if ( ps_mask_table_test_intersect( table, index1, index2 ) )
         {
-          error = ps_mask_table_merge( table,
-                                       (FT_UInt)index2,
-                                       (FT_UInt)index1,
-                                       memory );
+          error = ps_mask_table_merge( table, index2, index1, memory );
           if ( error )
             goto Exit;
 
@@ -653,7 +630,7 @@
                            FT_Int        pos,
                            FT_Int        len,
                            FT_Memory     memory,
-                           FT_Int       *aindex )
+                           FT_UInt      *aindex )
   {
     FT_Error  error = FT_Err_Ok;
     FT_UInt   flags = 0;
@@ -666,14 +643,11 @@
       if ( len == -21 )
       {
         flags |= PS_HINT_FLAG_BOTTOM;
-        pos   += len;
+        pos    = ADD_INT( pos, len );
       }
       len = 0;
     }
 
-    if ( aindex )
-      *aindex = -1;
-
     /* now, lookup stem in the current hints table */
     {
       PS_Mask  mask;
@@ -710,7 +684,7 @@
         goto Exit;
 
       if ( aindex )
-        *aindex = (FT_Int)idx;
+        *aindex = idx;
     }
 
   Exit:
@@ -721,9 +695,9 @@
   /* add a "hstem3/vstem3" counter to our dimension table */
   static FT_Error
   ps_dimension_add_counter( PS_Dimension  dim,
-                            FT_Int        hint1,
-                            FT_Int        hint2,
-                            FT_Int        hint3,
+                            FT_UInt       hint1,
+                            FT_UInt       hint2,
+                            FT_UInt       hint3,
                             FT_Memory     memory )
   {
     FT_Error  error   = FT_Err_Ok;
@@ -750,26 +724,17 @@
     }
 
     /* now, set the bits for our hints in the counter mask */
-    if ( hint1 >= 0 )
-    {
-      error = ps_mask_set_bit( counter, (FT_UInt)hint1, memory );
-      if ( error )
-        goto Exit;
-    }
+    error = ps_mask_set_bit( counter, hint1, memory );
+    if ( error )
+      goto Exit;
 
-    if ( hint2 >= 0 )
-    {
-      error = ps_mask_set_bit( counter, (FT_UInt)hint2, memory );
-      if ( error )
-        goto Exit;
-    }
+    error = ps_mask_set_bit( counter, hint2, memory );
+    if ( error )
+      goto Exit;
 
-    if ( hint3 >= 0 )
-    {
-      error = ps_mask_set_bit( counter, (FT_UInt)hint3, memory );
-      if ( error )
-        goto Exit;
-    }
+    error = ps_mask_set_bit( counter, hint3, memory );
+    if ( error )
+      goto Exit;
 
   Exit:
     return error;
@@ -800,7 +765,7 @@
 
 
   /* destroy hints */
-  FT_LOCAL( void )
+  FT_LOCAL_DEF( void )
   ps_hints_done( PS_Hints  hints )
   {
     FT_Memory  memory = hints->memory;
@@ -814,7 +779,7 @@
   }
 
 
-  FT_LOCAL( void )
+  FT_LOCAL_DEF( void )
   ps_hints_init( PS_Hints   hints,
                  FT_Memory  memory )
   {
@@ -875,7 +840,7 @@
       if ( error )
       {
         FT_ERROR(( "ps_hints_stem: could not add stem"
-                   " (%d,%d) to hints table\n", stems[0], stems[1] ));
+                   " (%ld,%ld) to hints table\n", stems[0], stems[1] ));
 
         hints->error = error;
         return;
@@ -898,7 +863,7 @@
       PS_Dimension  dim;
       FT_Memory     memory = hints->memory;
       FT_Int        count;
-      FT_Int        idx[3];
+      FT_UInt       idx[3];
 
 
       /* limit "dimension" to 0..1 */
@@ -1187,7 +1152,7 @@
       /* compute integer stem positions in font units */
       for ( n = 0; n < count * 2; n++ )
       {
-        y       += coords[n];
+        y        = ADD_LONG( y, coords[n] );
         stems[n] = FIXED_TO_INT( y );
       }
 
diff --git a/src/pshinter/pshrec.h b/src/pshinter/pshrec.h
index 56c0f99..0b2484a 100644
--- a/src/pshinter/pshrec.h
+++ b/src/pshinter/pshrec.h
@@ -4,7 +4,7 @@
  *
  *   Postscript (Type1/Type2) hints recorder (specification).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -32,8 +32,7 @@
 #define PSHREC_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include <freetype/internal/pshints.h>
 #include "pshglob.h"
 
 
diff --git a/src/pshinter/rules.mk b/src/pshinter/rules.mk
index 0e2fb8d..50058e8 100644
--- a/src/pshinter/rules.mk
+++ b/src/pshinter/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2001-2018 by
+# Copyright (C) 2001-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/psnames/Jamfile b/src/psnames/Jamfile
deleted file mode 100644
index a0fd373..0000000
--- a/src/psnames/Jamfile
+++ /dev/null
@@ -1,31 +0,0 @@
-# FreeType 2 src/psnames Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) psnames ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = psmodule
-               pspic
-               ;
-  }
-  else
-  {
-    _sources = psnames ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/psnames Jamfile
diff --git a/src/psnames/module.mk b/src/psnames/module.mk
index 410f48a..1ee0ef8 100644
--- a/src/psnames/module.mk
+++ b/src/psnames/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 719e94d..db454e5 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -2,9 +2,9 @@
  *
  * psmodule.c
  *
- *   PSNames module implementation (body).
+ *   psnames module implementation (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/services/svpscmap.h>
 
 #include "psmodule.h"
 
@@ -156,31 +155,30 @@
     /* Look for a non-initial dot in the glyph name in order to */
     /* find variants like `A.swash', `e.final', etc.            */
     {
-      const char*  p   = glyph_name;
-      const char*  dot = NULL;
+      FT_UInt32    value = 0;
+      const char*  p     = glyph_name;
 
 
-      for ( ; *p; p++ )
+      for ( ; *p && *p != '.'; p++ )
+        ;
+
+      /* now look up the glyph in the Adobe Glyph List;      */
+      /* `.notdef', `.null' and the empty name are short cut */
+      if ( p > glyph_name )
       {
-        if ( *p == '.' && p > glyph_name )
-        {
-          dot = p;
-          break;
-        }
+        value = (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
+
+        if ( *p == '.' )
+          value |= (FT_UInt32)VARIANT_BIT;
       }
 
-      /* now look up the glyph in the Adobe Glyph List */
-      if ( !dot )
-        return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
-      else
-        return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
-                            VARIANT_BIT );
+      return value;
     }
   }
 
 
   /* ft_qsort callback to sort the unicode map */
-  FT_CALLBACK_DEF( int )
+  FT_COMPARE_DEF( int )
   compare_uni_maps( const void*  a,
                     const void*  b )
   {
@@ -327,9 +325,8 @@
 
     /* we first allocate the table */
     table->num_maps = 0;
-    table->maps     = NULL;
 
-    if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
+    if ( !FT_QNEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
     {
       FT_UInt     n;
       FT_UInt     count;
@@ -344,7 +341,7 @@
         const char*  gname = get_glyph_name( glyph_data, n );
 
 
-        if ( gname )
+        if ( gname && *gname )
         {
           ps_check_extra_glyph_name( gname, n,
                                      extra_glyphs, extra_glyph_list_states );
@@ -392,9 +389,9 @@
         /* Reallocate if the number of used entries is much smaller. */
         if ( count < num_glyphs / 2 )
         {
-          (void)FT_RENEW_ARRAY( table->maps,
-                                num_glyphs + EXTRA_GLYPH_LIST_SIZE,
-                                count );
+          FT_MEM_QRENEW_ARRAY( table->maps,
+                               num_glyphs + EXTRA_GLYPH_LIST_SIZE,
+                               count );
           error = FT_Err_Ok;
         }
 
@@ -415,21 +412,18 @@
   ps_unicodes_char_index( PS_Unicodes  table,
                           FT_UInt32    unicode )
   {
-    PS_UniMap  *min, *max, *mid, *result = NULL;
+    PS_UniMap  *result = NULL;
+    PS_UniMap  *min = table->maps;
+    PS_UniMap  *max = min + table->num_maps;
+    PS_UniMap  *mid = min + ( ( max - min ) >> 1 );
 
 
     /* Perform a binary search on the table. */
-
-    min = table->maps;
-    max = min + table->num_maps - 1;
-
-    while ( min <= max )
+    while ( min < max )
     {
       FT_UInt32  base_glyph;
 
 
-      mid = min + ( ( max - min ) >> 1 );
-
       if ( mid->unicode == unicode )
       {
         result = mid;
@@ -441,13 +435,15 @@
       if ( base_glyph == unicode )
         result = mid; /* remember match but continue search for base glyph */
 
-      if ( min == max )
-        break;
-
       if ( base_glyph < unicode )
         min = mid + 1;
       else
-        max = mid - 1;
+        max = mid;
+
+      /* reasonable prediction in a continuous block */
+      mid += unicode - base_glyph;
+      if ( mid >= max || mid < min )
+        mid = min + ( ( max - min ) >> 1 );
     }
 
     if ( result )
@@ -468,14 +464,13 @@
     {
       FT_UInt     min = 0;
       FT_UInt     max = table->num_maps;
-      FT_UInt     mid;
+      FT_UInt     mid = min + ( ( max - min ) >> 1 );
       PS_UniMap*  map;
       FT_UInt32   base_glyph;
 
 
       while ( min < max )
       {
-        mid = min + ( ( max - min ) >> 1 );
         map = table->maps + mid;
 
         if ( map->unicode == char_code )
@@ -493,6 +488,11 @@
           min = mid + 1;
         else
           max = mid;
+
+        /* reasonable prediction in a continuous block */
+        mid += char_code - base_glyph;
+        if ( mid >= max || mid < min )
+          mid = min + ( max - min ) / 2;
       }
 
       if ( result )
diff --git a/src/psnames/psmodule.h b/src/psnames/psmodule.h
index 8b026ee..0904700 100644
--- a/src/psnames/psmodule.h
+++ b/src/psnames/psmodule.h
@@ -2,9 +2,9 @@
  *
  * psmodule.h
  *
- *   High-level PSNames module interface (specification).
+ *   High-level psnames module interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define PSMODULE_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/psnames/psnamerr.h b/src/psnames/psnamerr.h
index af89157..0073f82 100644
--- a/src/psnames/psnamerr.h
+++ b/src/psnames/psnamerr.h
@@ -4,7 +4,7 @@
  *
  *   PS names module error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef PSNAMERR_H_
 #define PSNAMERR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  PSnames_Err_
 #define FT_ERR_BASE    FT_Mod_Err_PSnames
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* PSNAMERR_H_ */
 
diff --git a/src/psnames/psnames.c b/src/psnames/psnames.c
index bfa5b85..93ed933 100644
--- a/src/psnames/psnames.c
+++ b/src/psnames/psnames.c
@@ -2,9 +2,9 @@
  *
  * psnames.c
  *
- *   FreeType PSNames module component (body only).
+ *   FreeType psnames module component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "psmodule.c"
 
diff --git a/src/psnames/pstables.h b/src/psnames/pstables.h
index e574122..7f92cce 100644
--- a/src/psnames/pstables.h
+++ b/src/psnames/pstables.h
@@ -4,7 +4,7 @@
  *
  *   PostScript glyph names.
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/psnames/rules.mk b/src/psnames/rules.mk
index 46ec5df..8d7c580 100644
--- a/src/psnames/rules.mk
+++ b/src/psnames/rules.mk
@@ -1,9 +1,9 @@
 #
-# FreeType 2 PSNames driver configuration rules
+# FreeType 2 psnames driver configuration rules
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -13,7 +13,7 @@
 # fully.
 
 
-# PSNames driver directory
+# psnames driver directory
 #
 PSNAMES_DIR := $(SRC_DIR)/psnames
 
@@ -26,19 +26,19 @@
                          $(FT_CFLAGS)
 
 
-# PSNames driver sources (i.e., C files)
+# psnames driver sources (i.e., C files)
 #
 PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c
 
 
-# PSNames driver headers
+# psnames driver headers
 #
 PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \
                  $(PSNAMES_DIR)/psnamerr.h  \
                  $(PSNAMES_DIR)/pstables.h
 
 
-# PSNames driver object(s)
+# psnames driver object(s)
 #
 #   PSNAMES_DRV_OBJ_M is used during `multi' builds
 #   PSNAMES_DRV_OBJ_S is used during `single' builds
@@ -46,19 +46,19 @@
 PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR)/%.c=$(OBJ_DIR)/%.$O)
 PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O
 
-# PSNames driver source file for single build
+# psnames driver source file for single build
 #
 PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psnames.c
 
 
-# PSNames driver - single object
+# psnames driver - single object
 #
 $(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \
                       $(FREETYPE_H) $(PSNAMES_DRV_H)
 	$(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSNAMES_DRV_SRC_S))
 
 
-# PSNames driver - multiple objects
+# psnames driver - multiple objects
 #
 $(OBJ_DIR)/%.$O: $(PSNAMES_DIR)/%.c $(FREETYPE_H) $(PSNAMES_DRV_H)
 	$(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
diff --git a/src/raster/Jamfile b/src/raster/Jamfile
deleted file mode 100644
index 838e7ef..0000000
--- a/src/raster/Jamfile
+++ /dev/null
@@ -1,32 +0,0 @@
-# FreeType 2 src/raster Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) raster ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = ftraster
-               ftrend1
-               rastpic
-               ;
-  }
-  else
-  {
-    _sources = raster ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/raster Jamfile
diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h
index 97db371..33dbfd6 100644
--- a/src/raster/ftmisc.h
+++ b/src/raster/ftmisc.h
@@ -5,7 +5,7 @@
  *   Miscellaneous macros for stand-alone rasterizer (specification
  *   only).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used
@@ -47,11 +47,8 @@
   typedef signed long    FT_F26Dot6;
   typedef int            FT_Error;
 
-#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
-          ( ( (FT_ULong)_x1 << 24 ) |     \
-            ( (FT_ULong)_x2 << 16 ) |     \
-            ( (FT_ULong)_x3 <<  8 ) |     \
-              (FT_ULong)_x4         )
+
+#define FT_STATIC_BYTE_CAST( type, var )  (type)(FT_Byte)(var)
 
 
   /* from include/freetype/ftsystem.h */
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 8a583ea..67cbfd5 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph rasterizer (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -62,10 +62,9 @@
 
 #else /* !STANDALONE_ */
 
-#include <ft2build.h>
 #include "ftraster.h"
-#include FT_INTERNAL_CALC_H   /* for FT_MulDiv and FT_MulDiv_No_Round */
-#include FT_OUTLINE_H         /* for FT_Outline_Get_CBox              */
+#include <freetype/internal/ftcalc.h> /* for FT_MulDiv and FT_MulDiv_No_Round */
+#include <freetype/ftoutln.h>         /* for FT_Outline_Get_CBox              */
 
 #endif /* !STANDALONE_ */
 
@@ -99,7 +98,7 @@
    *   built from the bottom of the render pool, used as a stack.  The
    *   following graphics shows the profile list under construction:
    *
-   *     __________________________________________________________ _ _
+   *    __________________________________________________________ _ _
    *   |         |                 |         |                 |
    *   | profile | coordinates for | profile | coordinates for |-->
    *   |    1    |  profile 1      |    2    |  profile 2      |-->
@@ -125,8 +124,8 @@
    *
    *     _ _ _______________________________________
    *                           |                    |
-   *                         <--| sorted list of     |
-   *                         <--|  extrema scanlines |
+   *                        <--| sorted list of     |
+   *                        <--|  extrema scanlines |
    *     _ _ __________________|____________________|
    *
    *                           ^                    ^
@@ -150,9 +149,6 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /* define DEBUG_RASTER if you want to compile a debugging version */
-/* #define DEBUG_RASTER */
-
 
   /*************************************************************************/
   /*************************************************************************/
@@ -169,7 +165,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_raster
+#define FT_COMPONENT  raster
 
 
 #ifdef STANDALONE_
@@ -201,12 +197,13 @@
 #define FT_THROW( e )  FT_ERR_CAT( Raster_Err_, e )
 #endif
 
-#define Raster_Err_None          0
-#define Raster_Err_Not_Ini      -1
-#define Raster_Err_Overflow     -2
-#define Raster_Err_Neg_Height   -3
-#define Raster_Err_Invalid      -4
-#define Raster_Err_Unsupported  -5
+#define Raster_Err_Ok                       0
+#define Raster_Err_Invalid_Outline         -1
+#define Raster_Err_Cannot_Render_Glyph     -2
+#define Raster_Err_Invalid_Argument        -3
+#define Raster_Err_Raster_Overflow         -4
+#define Raster_Err_Raster_Uninitialized    -5
+#define Raster_Err_Raster_Negative_Height  -6
 
 #define ft_memset  memset
 
@@ -226,18 +223,11 @@
 #else /* !STANDALONE_ */
 
 
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H       /* for FT_TRACE, FT_ERROR, and FT_THROW */
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h> /* for FT_TRACE, FT_ERROR, and FT_THROW */
 
 #include "rasterrs.h"
 
-#define Raster_Err_None         FT_Err_Ok
-#define Raster_Err_Not_Ini      Raster_Err_Raster_Uninitialized
-#define Raster_Err_Overflow     Raster_Err_Raster_Overflow
-#define Raster_Err_Neg_Height   Raster_Err_Raster_Negative_Height
-#define Raster_Err_Invalid      Raster_Err_Invalid_Outline
-#define Raster_Err_Unsupported  Raster_Err_Cannot_Render_Glyph
-
 
 #endif /* !STANDALONE_ */
 
@@ -376,16 +366,6 @@
   typedef PProfile*  PProfileList;
 
 
-  /* Simple record used to implement a stack of bands, required */
-  /* by the sub-banding mechanism                               */
-  typedef struct  black_TBand_
-  {
-    Short  y_min;   /* band's minimum */
-    Short  y_max;   /* band's maximum */
-
-  } black_TBand;
-
-
 #define AlignProfileSize \
   ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) )
 
@@ -399,7 +379,7 @@
 
 
 #define RAS_ARGS       /* void */
-#define RAS_ARG        /* void */
+#define RAS_ARG        void
 
 #define RAS_VARS       /* void */
 #define RAS_VAR        /* void */
@@ -427,8 +407,8 @@
 
   /* prototypes used for sweep function dispatch */
   typedef void
-  Function_Sweep_Init( RAS_ARGS Short*  min,
-                                Short*  max );
+  Function_Sweep_Init( RAS_ARGS Short  min,
+                                Short  max );
 
   typedef void
   Function_Sweep_Span( RAS_ARGS Short       y,
@@ -460,6 +440,11 @@
 #define IS_TOP_OVERSHOOT( x )    \
           (Bool)( x - FLOOR( x ) >= ras.precision_half )
 
+  /* Smart dropout rounding to find which pixel is closer to span ends. */
+  /* To mimick Windows, symmetric cases break down indepenently of the  */
+  /* precision.                                                         */
+#define SMART( p, q )  FLOOR( ( (p) + (q) + ras.precision * 63 / 64 ) >> 1 )
+
 #if FT_RENDER_POOL_SIZE > 2048
 #define FT_MAX_BLACK_POOL  ( FT_RENDER_POOL_SIZE / sizeof ( Long ) )
 #else
@@ -488,10 +473,11 @@
 
     Int         numTurns;           /* number of Y-turns in outline        */
 
-    TPoint*     arc;                /* current Bezier arc pointer          */
+    Byte        dropOutControl;     /* current drop_out control method     */
 
     UShort      bWidth;             /* target bitmap width                 */
     PByte       bOrigin;            /* target bitmap bottom-left origin    */
+    PByte       bLine;              /* target bitmap current line          */
 
     Long        lastX, lastY;
     Long        minY, maxY;
@@ -513,9 +499,6 @@
     FT_Bitmap   target;             /* description of target bit/pixmap    */
     FT_Outline  outline;
 
-    Long        traceOfs;           /* current offset in target bitmap     */
-    Short       traceIncr;          /* sweep's increment in target bitmap  */
-
     /* dispatch variables */
 
     Function_Sweep_Init*  Proc_Sweep_Init;
@@ -523,18 +506,6 @@
     Function_Sweep_Span*  Proc_Sweep_Drop;
     Function_Sweep_Step*  Proc_Sweep_Step;
 
-    Byte        dropOutControl;     /* current drop_out control method     */
-
-    Bool        second_pass;        /* indicates whether a horizontal pass */
-                                    /* should be performed to control      */
-                                    /* drop-out accurately when calling    */
-                                    /* Render_Glyph.                       */
-
-    TPoint      arcs[3 * MaxBezier + 1]; /* The Bezier stack               */
-
-    black_TBand  band_stack[16];    /* band stack used for sub-banding     */
-    Int          band_top;          /* band stack top                      */
-
   };
 
 
@@ -546,8 +517,7 @@
 
 #ifdef FT_STATIC_RASTER
 
-  static black_TWorker  cur_ras;
-#define ras  cur_ras
+  static black_TWorker  ras;
 
 #else /* !FT_STATIC_RASTER */
 
@@ -657,11 +627,10 @@
 
     if ( ras.top >= ras.maxBuff )
     {
-      ras.error = FT_THROW( Overflow );
+      ras.error = FT_THROW( Raster_Overflow );
       return FAILURE;
     }
 
-    ras.cProfile->flags  = 0;
     ras.cProfile->start  = 0;
     ras.cProfile->height = 0;
     ras.cProfile->offset = ras.top;
@@ -676,18 +645,18 @@
       if ( overshoot )
         ras.cProfile->flags |= Overshoot_Bottom;
 
-      FT_TRACE6(( "  new ascending profile = %p\n", ras.cProfile ));
+      FT_TRACE6(( "  new ascending profile = %p\n", (void *)ras.cProfile ));
       break;
 
     case Descending_State:
       if ( overshoot )
         ras.cProfile->flags |= Overshoot_Top;
-      FT_TRACE6(( "  new descending profile = %p\n", ras.cProfile ));
+      FT_TRACE6(( "  new descending profile = %p\n", (void *)ras.cProfile ));
       break;
 
     default:
       FT_ERROR(( "New_Profile: invalid profile direction\n" ));
-      ras.error = FT_THROW( Invalid );
+      ras.error = FT_THROW( Invalid_Outline );
       return FAILURE;
     }
 
@@ -729,7 +698,7 @@
     if ( h < 0 )
     {
       FT_ERROR(( "End_Profile: negative height encountered\n" ));
-      ras.error = FT_THROW( Neg_Height );
+      ras.error = FT_THROW( Raster_Negative_Height );
       return FAILURE;
     }
 
@@ -739,7 +708,7 @@
 
 
       FT_TRACE6(( "  ending profile %p, start = %ld, height = %ld\n",
-                  ras.cProfile, ras.cProfile->start, h ));
+                  (void *)ras.cProfile, ras.cProfile->start, h ));
 
       ras.cProfile->height = h;
       if ( overshoot )
@@ -765,7 +734,7 @@
     if ( ras.top >= ras.maxBuff )
     {
       FT_TRACE1(( "overflow in End_Profile\n" ));
-      ras.error = FT_THROW( Overflow );
+      ras.error = FT_THROW( Raster_Overflow );
       return FAILURE;
     }
 
@@ -820,7 +789,7 @@
       ras.maxBuff--;
       if ( ras.maxBuff <= ras.top )
       {
-        ras.error = FT_THROW( Overflow );
+        ras.error = FT_THROW( Raster_Overflow );
         return FAILURE;
       }
       ras.numTurns++;
@@ -914,16 +883,18 @@
 
 
     base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b ) / 2;
-    b = base[1].x = ( base[0].x + b ) / 2;
-    base[2].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    base[3].x = b >> 1;
+    base[2].x = ( a + b ) >> 2;
+    base[1].x = a >> 1;
 
     base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b ) / 2;
-    b = base[1].y = ( base[0].y + b ) / 2;
-    base[2].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    base[3].y = b >> 1;
+    base[2].y = ( a + b ) >> 2;
+    base[1].y = a >> 1;
 
     /* hand optimized.  gcc doesn't seem to be too good at common      */
     /* expression substitution and instruction scheduling ;-)          */
@@ -947,28 +918,32 @@
   static void
   Split_Cubic( TPoint*  base )
   {
-    Long  a, b, c, d;
+    Long  a, b, c;
 
 
     base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c + 1 ) >> 1;
-    base[5].x = b = ( base[3].x + d + 1 ) >> 1;
-    c = ( c + d + 1 ) >> 1;
-    base[2].x = a = ( a + c + 1 ) >> 1;
-    base[4].x = b = ( b + c + 1 ) >> 1;
-    base[3].x = ( a + b + 1 ) >> 1;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c >> 1;
+    c += b;
+    base[4].x = c >> 2;
+    base[1].x = a >> 1;
+    a += b;
+    base[2].x = a >> 2;
+    base[3].x = ( a + c ) >> 3;
 
     base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c + 1 ) >> 1;
-    base[5].y = b = ( base[3].y + d + 1 ) >> 1;
-    c = ( c + d + 1 ) >> 1;
-    base[2].y = a = ( a + c + 1 ) >> 1;
-    base[4].y = b = ( b + c + 1 ) >> 1;
-    base[3].y = ( a + b + 1 ) >> 1;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c >> 1;
+    c += b;
+    base[4].y = c >> 2;
+    base[1].y = a >> 1;
+    a += b;
+    base[2].y = a >> 2;
+    base[3].y = ( a + c ) >> 3;
   }
 
 
@@ -1078,7 +1053,7 @@
     size = e2 - e1 + 1;
     if ( ras.top + size >= ras.maxBuff )
     {
-      ras.error = FT_THROW( Overflow );
+      ras.error = FT_THROW( Raster_Overflow );
       return FAILURE;
     }
 
@@ -1201,6 +1176,7 @@
    */
   static Bool
   Bezier_Up( RAS_ARGS Int        degree,
+                      TPoint*    arc,
                       TSplitter  splitter,
                       Long       miny,
                       Long       maxy )
@@ -1208,13 +1184,11 @@
     Long   y1, y2, e, e2, e0;
     Short  f1;
 
-    TPoint*  arc;
     TPoint*  start_arc;
 
     PLong top;
 
 
-    arc = ras.arc;
     y1  = arc[degree].y;
     y2  = arc[0].y;
     top = ras.top;
@@ -1263,7 +1237,7 @@
     if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
     {
       ras.top   = top;
-      ras.error = FT_THROW( Overflow );
+      ras.error = FT_THROW( Raster_Overflow );
       return FAILURE;
     }
 
@@ -1306,7 +1280,6 @@
 
   Fin:
     ras.top  = top;
-    ras.arc -= degree;
     return SUCCESS;
   }
 
@@ -1338,11 +1311,11 @@
    */
   static Bool
   Bezier_Down( RAS_ARGS Int        degree,
+                        TPoint*    arc,
                         TSplitter  splitter,
                         Long       miny,
                         Long       maxy )
   {
-    TPoint*  arc = ras.arc;
     Bool     result, fresh;
 
 
@@ -1354,7 +1327,7 @@
 
     fresh = ras.fresh;
 
-    result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );
+    result = Bezier_Up( RAS_VARS degree, arc, splitter, -maxy, -miny );
 
     if ( fresh && !ras.fresh )
       ras.cProfile->start = -ras.cProfile->start;
@@ -1495,22 +1468,24 @@
   {
     Long     y1, y2, y3, x3, ymin, ymax;
     TStates  state_bez;
+    TPoint   arcs[2 * MaxBezier + 1]; /* The Bezier stack           */
+    TPoint*  arc;                     /* current Bezier arc pointer */
 
 
-    ras.arc      = ras.arcs;
-    ras.arc[2].x = ras.lastX;
-    ras.arc[2].y = ras.lastY;
-    ras.arc[1].x = cx;
-    ras.arc[1].y = cy;
-    ras.arc[0].x = x;
-    ras.arc[0].y = y;
+    arc      = arcs;
+    arc[2].x = ras.lastX;
+    arc[2].y = ras.lastY;
+    arc[1].x = cx;
+    arc[1].y = cy;
+    arc[0].x = x;
+    arc[0].y = y;
 
     do
     {
-      y1 = ras.arc[2].y;
-      y2 = ras.arc[1].y;
-      y3 = ras.arc[0].y;
-      x3 = ras.arc[0].x;
+      y1 = arc[2].y;
+      y2 = arc[1].y;
+      y3 = arc[0].y;
+      x3 = arc[0].x;
 
       /* first, categorize the Bezier arc */
 
@@ -1528,13 +1503,13 @@
       if ( y2 < ymin || y2 > ymax )
       {
         /* this arc has no given direction, split it! */
-        Split_Conic( ras.arc );
-        ras.arc += 2;
+        Split_Conic( arc );
+        arc += 2;
       }
       else if ( y1 == y3 )
       {
         /* this arc is flat, ignore it and pop it from the Bezier stack */
-        ras.arc -= 2;
+        arc -= 2;
       }
       else
       {
@@ -1561,15 +1536,18 @@
         /* now call the appropriate routine */
         if ( state_bez == Ascending_State )
         {
-          if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
+          if ( Bezier_Up( RAS_VARS 2, arc, Split_Conic,
+                                   ras.minY, ras.maxY ) )
             goto Fail;
         }
         else
-          if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
+          if ( Bezier_Down( RAS_VARS 2, arc, Split_Conic,
+                                     ras.minY, ras.maxY ) )
             goto Fail;
+        arc -= 2;
       }
 
-    } while ( ras.arc >= ras.arcs );
+    } while ( arc >= arcs );
 
     ras.lastX = x3;
     ras.lastY = y3;
@@ -1624,25 +1602,27 @@
   {
     Long     y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
     TStates  state_bez;
+    TPoint   arcs[3 * MaxBezier + 1]; /* The Bezier stack           */
+    TPoint*  arc;                     /* current Bezier arc pointer */
 
 
-    ras.arc      = ras.arcs;
-    ras.arc[3].x = ras.lastX;
-    ras.arc[3].y = ras.lastY;
-    ras.arc[2].x = cx1;
-    ras.arc[2].y = cy1;
-    ras.arc[1].x = cx2;
-    ras.arc[1].y = cy2;
-    ras.arc[0].x = x;
-    ras.arc[0].y = y;
+    arc      = arcs;
+    arc[3].x = ras.lastX;
+    arc[3].y = ras.lastY;
+    arc[2].x = cx1;
+    arc[2].y = cy1;
+    arc[1].x = cx2;
+    arc[1].y = cy2;
+    arc[0].x = x;
+    arc[0].y = y;
 
     do
     {
-      y1 = ras.arc[3].y;
-      y2 = ras.arc[2].y;
-      y3 = ras.arc[1].y;
-      y4 = ras.arc[0].y;
-      x4 = ras.arc[0].x;
+      y1 = arc[3].y;
+      y2 = arc[2].y;
+      y3 = arc[1].y;
+      y4 = arc[0].y;
+      x4 = arc[0].x;
 
       /* first, categorize the Bezier arc */
 
@@ -1671,13 +1651,13 @@
       if ( ymin2 < ymin1 || ymax2 > ymax1 )
       {
         /* this arc has no given direction, split it! */
-        Split_Cubic( ras.arc );
-        ras.arc += 3;
+        Split_Cubic( arc );
+        arc += 3;
       }
       else if ( y1 == y4 )
       {
         /* this arc is flat, ignore it and pop it from the Bezier stack */
-        ras.arc -= 3;
+        arc -= 3;
       }
       else
       {
@@ -1703,15 +1683,18 @@
         /* compute intersections */
         if ( state_bez == Ascending_State )
         {
-          if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
+          if ( Bezier_Up( RAS_VARS 3, arc, Split_Cubic,
+                                   ras.minY, ras.maxY ) )
             goto Fail;
         }
         else
-          if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
+          if ( Bezier_Down( RAS_VARS 3, arc, Split_Cubic,
+                                     ras.minY, ras.maxY ) )
             goto Fail;
+        arc -= 3;
       }
 
-    } while ( ras.arc >= ras.arcs );
+    } while ( arc >= arcs );
 
     ras.lastX = x4;
     ras.lastY = y4;
@@ -1959,7 +1942,7 @@
     return SUCCESS;
 
   Invalid_Outline:
-    ras.error = FT_THROW( Invalid );
+    ras.error = FT_THROW( Invalid_Outline );
 
   Fail:
     return FAILURE;
@@ -2112,8 +2095,8 @@
    *   Removes an old profile from a linked list.
    */
   static void
-  DelOld( PProfileList  list,
-          PProfile      profile )
+  DelOld( PProfileList    list,
+          const PProfile  profile )
   {
     PProfile  *old, current;
 
@@ -2206,16 +2189,13 @@
    */
 
   static void
-  Vertical_Sweep_Init( RAS_ARGS Short*  min,
-                                Short*  max )
+  Vertical_Sweep_Init( RAS_ARGS Short  min,
+                                Short  max )
   {
-    Long  pitch = ras.target.pitch;
-
     FT_UNUSED( max );
 
 
-    ras.traceIncr = (Short)-pitch;
-    ras.traceOfs  = -*min * pitch;
+    ras.bLine = ras.bOrigin - min * ras.target.pitch;
   }
 
 
@@ -2226,8 +2206,7 @@
                                 PProfile    left,
                                 PProfile    right )
   {
-    Long   e1, e2;
-    Byte*  target;
+    Long  e1, e2;
 
     Int  dropOutControl = left->flags & 7;
 
@@ -2238,24 +2217,30 @@
 
     /* in high-precision mode, we need 12 digits after the comma to */
     /* represent multiples of 1/(1<<12) = 1/4096                    */
-    FT_TRACE7(( "  y=%d x=[%.12f;%.12f], drop-out=%d",
+    FT_TRACE7(( "  y=%d x=[% .12f;% .12f]",
                 y,
-                x1 / (double)ras.precision,
-                x2 / (double)ras.precision,
-                dropOutControl ));
+                (double)x1 / (double)ras.precision,
+                (double)x2 / (double)ras.precision ));
 
     /* Drop-out control */
 
-    e1 = TRUNC( CEILING( x1 ) );
+    e1 = CEILING( x1 );
+    e2 = FLOOR( x2 );
 
+    /* take care of the special case where both the left */
+    /* and right contour lie exactly on pixel centers    */
     if ( dropOutControl != 2                             &&
-         x2 - x1 - ras.precision <= ras.precision_jitter )
+         x2 - x1 - ras.precision <= ras.precision_jitter &&
+         e1 != x1 && e2 != x2                            )
       e2 = e1;
-    else
-      e2 = TRUNC( FLOOR( x2 ) );
+
+    e1 = TRUNC( e1 );
+    e2 = TRUNC( e2 );
 
     if ( e2 >= 0 && e1 < ras.bWidth )
     {
+      Byte*  target;
+
       Int   c1, c2;
       Byte  f1, f2;
 
@@ -2265,7 +2250,7 @@
       if ( e2 >= ras.bWidth )
         e2 = ras.bWidth - 1;
 
-      FT_TRACE7(( " -> x=[%d;%d]", e1, e2 ));
+      FT_TRACE7(( " -> x=[%ld;%ld]", e1, e2 ));
 
       c1 = (Short)( e1 >> 3 );
       c2 = (Short)( e2 >> 3 );
@@ -2273,7 +2258,7 @@
       f1 = (Byte)  ( 0xFF >> ( e1 & 7 ) );
       f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
 
-      target = ras.bOrigin + ras.traceOfs + c1;
+      target = ras.bLine + c1;
       c2 -= c1;
 
       if ( c2 > 0 )
@@ -2284,7 +2269,7 @@
         /* This is due to the fact that, in the vast majority of cases,  */
         /* the span length in bytes is relatively small.                 */
         while ( --c2 > 0 )
-          *(++target) = 0xFF;
+          *( ++target ) = 0xFF;
 
         target[1] |= f2;
       }
@@ -2307,10 +2292,10 @@
     Short  c1, f1;
 
 
-    FT_TRACE7(( "  y=%d x=[%.12f;%.12f]",
+    FT_TRACE7(( "  y=%d x=[% .12f;% .12f]",
                 y,
-                x1 / (double)ras.precision,
-                x2 / (double)ras.precision ));
+                (double)x1 / (double)ras.precision,
+                (double)x2 / (double)ras.precision ));
 
     /* Drop-out control */
 
@@ -2344,8 +2329,6 @@
       Int  dropOutControl = left->flags & 7;
 
 
-      FT_TRACE7(( ", drop-out=%d", dropOutControl ));
-
       if ( e1 == e2 + ras.precision )
       {
         switch ( dropOutControl )
@@ -2355,7 +2338,7 @@
           break;
 
         case 4: /* smart drop-outs including stubs */
-          pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
+          pxl = SMART( x1, x2 );
           break;
 
         case 1: /* simple drop-outs excluding stubs */
@@ -2404,7 +2387,7 @@
           if ( dropOutControl == 1 )
             pxl = e2;
           else
-            pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
+            pxl = SMART( x1, x2 );
           break;
 
         default: /* modes 2, 3, 6, 7 */
@@ -2427,8 +2410,8 @@
         c1 = (Short)( e1 >> 3 );
         f1 = (Short)( e1 &  7 );
 
-        if ( e1 >= 0 && e1 < ras.bWidth                      &&
-             ras.bOrigin[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
+        if ( e1 >= 0 && e1 < ras.bWidth     &&
+             ras.bLine[c1] & ( 0x80 >> f1 ) )
           goto Exit;
       }
       else
@@ -2439,23 +2422,23 @@
 
     if ( e1 >= 0 && e1 < ras.bWidth )
     {
-      FT_TRACE7(( " -> x=%d (drop-out)", e1 ));
+      FT_TRACE7(( " -> x=%ld", e1 ));
 
       c1 = (Short)( e1 >> 3 );
       f1 = (Short)( e1 & 7 );
 
-      ras.bOrigin[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
+      ras.bLine[c1] |= (char)( 0x80 >> f1 );
     }
 
   Exit:
-    FT_TRACE7(( "\n" ));
+    FT_TRACE7(( " dropout=%d\n", left->flags & 7 ));
   }
 
 
   static void
   Vertical_Sweep_Step( RAS_ARG )
   {
-    ras.traceOfs += ras.traceIncr;
+    ras.bLine -= ras.target.pitch;
   }
 
 
@@ -2469,8 +2452,8 @@
    */
 
   static void
-  Horizontal_Sweep_Init( RAS_ARGS Short*  min,
-                                  Short*  max )
+  Horizontal_Sweep_Init( RAS_ARGS Short  min,
+                                  Short  max )
   {
     /* nothing, really */
     FT_UNUSED_RASTER;
@@ -2486,44 +2469,68 @@
                                   PProfile    left,
                                   PProfile    right )
   {
+    Long  e1, e2;
+
     FT_UNUSED( left );
     FT_UNUSED( right );
 
 
-    if ( x2 - x1 < ras.precision )
+    FT_TRACE7(( "  x=%d y=[% .12f;% .12f]",
+                y,
+                (double)x1 / (double)ras.precision,
+                (double)x2 / (double)ras.precision ));
+
+    /* We should not need this procedure but the vertical sweep   */
+    /* mishandles horizontal lines through pixel centers.  So we  */
+    /* have to check perfectly aligned span edges here.           */
+    /*                                                            */
+    /* XXX: Can we handle horizontal lines better and drop this?  */
+
+    e1 = CEILING( x1 );
+
+    if ( x1 == e1 )
     {
-      Long  e1, e2;
+      e1 = TRUNC( e1 );
 
-
-      FT_TRACE7(( "  x=%d y=[%.12f;%.12f]",
-                  y,
-                  x1 / (double)ras.precision,
-                  x2 / (double)ras.precision ));
-
-      e1 = CEILING( x1 );
-      e2 = FLOOR  ( x2 );
-
-      if ( e1 == e2 )
+      if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
       {
-        e1 = TRUNC( e1 );
-
-        if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
-        {
-          Byte   f1;
-          PByte  bits;
+        Byte   f1;
+        PByte  bits;
 
 
-          FT_TRACE7(( " -> y=%d (drop-out)", e1 ));
+        bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch;
+        f1   = (Byte)( 0x80 >> ( y & 7 ) );
 
-          bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch;
-          f1   = (Byte)( 0x80 >> ( y & 7 ) );
+        FT_TRACE7(( bits[0] & f1 ? " redundant"
+                                 : " -> y=%ld edge", e1 ));
 
-          bits[0] |= f1;
-        }
+        bits[0] |= f1;
       }
-
-      FT_TRACE7(( "\n" ));
     }
+
+    e2 = FLOOR  ( x2 );
+
+    if ( x2 == e2 )
+    {
+      e2 = TRUNC( e2 );
+
+      if ( e2 >= 0 && (ULong)e2 < ras.target.rows )
+      {
+        Byte   f1;
+        PByte  bits;
+
+
+        bits = ras.bOrigin + ( y >> 3 ) - e2 * ras.target.pitch;
+        f1   = (Byte)( 0x80 >> ( y & 7 ) );
+
+        FT_TRACE7(( bits[0] & f1 ? " redundant"
+                                 : " -> y=%ld edge", e2 ));
+
+        bits[0] |= f1;
+      }
+    }
+
+    FT_TRACE7(( "\n" ));
   }
 
 
@@ -2539,10 +2546,10 @@
     Byte   f1;
 
 
-    FT_TRACE7(( "  x=%d y=[%.12f;%.12f]",
+    FT_TRACE7(( "  x=%d y=[% .12f;% .12f]",
                 y,
-                x1 / (double)ras.precision,
-                x2 / (double)ras.precision ));
+                (double)x1 / (double)ras.precision,
+                (double)x2 / (double)ras.precision ));
 
     /* During the horizontal sweep, we only take care of drop-outs */
 
@@ -2565,8 +2572,6 @@
       Int  dropOutControl = left->flags & 7;
 
 
-      FT_TRACE7(( ", dropout=%d", dropOutControl ));
-
       if ( e1 == e2 + ras.precision )
       {
         switch ( dropOutControl )
@@ -2576,7 +2581,7 @@
           break;
 
         case 4: /* smart drop-outs including stubs */
-          pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
+          pxl = SMART( x1, x2 );
           break;
 
         case 1: /* simple drop-outs excluding stubs */
@@ -2600,7 +2605,7 @@
           if ( dropOutControl == 1 )
             pxl = e2;
           else
-            pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
+            pxl = SMART( x1, x2 );
           break;
 
         default: /* modes 2, 3, 6, 7 */
@@ -2636,7 +2641,7 @@
 
     if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
     {
-      FT_TRACE7(( " -> y=%d (drop-out)", e1 ));
+      FT_TRACE7(( " -> y=%ld", e1 ));
 
       bits  = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch;
       f1    = (Byte)( 0x80 >> ( y & 7 ) );
@@ -2645,7 +2650,7 @@
     }
 
   Exit:
-    FT_TRACE7(( "\n" ));
+    FT_TRACE7(( " dropout=%d\n", left->flags & 7 ));
   }
 
 
@@ -2712,13 +2717,13 @@
     /* check the Y-turns */
     if ( ras.numTurns == 0 )
     {
-      ras.error = FT_THROW( Invalid );
+      ras.error = FT_THROW( Invalid_Outline );
       return FAILURE;
     }
 
     /* now initialize the sweep */
 
-    ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y );
+    ras.Proc_Sweep_Init( RAS_VARS min_Y, max_Y );
 
     /* then compute the distance of each profile from min_Y */
 
@@ -2779,7 +2784,7 @@
         P_Left  = draw_left;
         P_Right = draw_right;
 
-        while ( P_Left )
+        while ( P_Left && P_Right )
         {
           x1 = P_Left ->X;
           x2 = P_Right->X;
@@ -2880,7 +2885,7 @@
     P_Left  = draw_left;
     P_Right = draw_right;
 
-    while ( P_Left )
+    while ( P_Left && P_Right )
     {
       if ( P_Left->countL )
       {
@@ -2945,11 +2950,11 @@
   FT_Outline_Get_CBox( const FT_Outline*  outline,
                        FT_BBox           *acbox )
   {
-    Long  xMin, yMin, xMax, yMax;
-
-
     if ( outline && acbox )
     {
+      Long  xMin, yMin, xMax, yMax;
+
+
       if ( outline->n_points == 0 )
       {
         xMin = 0;
@@ -3007,63 +3012,54 @@
    *   Renderer error code.
    */
   static int
-  Render_Single_Pass( RAS_ARGS Bool  flipped )
+  Render_Single_Pass( RAS_ARGS Bool  flipped,
+                               Int   y_min,
+                               Int   y_max )
   {
-    Short  i, j, k;
+    Int  y_mid;
+    Int  band_top = 0;
+    Int  band_stack[32];  /* enough to bisect 32-bit int bands */
 
 
-    while ( ras.band_top >= 0 )
+    while ( 1 )
     {
-      ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;
-      ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;
+      ras.minY = (Long)y_min * ras.precision;
+      ras.maxY = (Long)y_max * ras.precision;
 
       ras.top = ras.buff;
 
-      ras.error = Raster_Err_None;
+      ras.error = Raster_Err_Ok;
 
       if ( Convert_Glyph( RAS_VARS flipped ) )
       {
-        if ( ras.error != Raster_Err_Overflow )
-          return FAILURE;
-
-        ras.error = Raster_Err_None;
+        if ( ras.error != Raster_Err_Raster_Overflow )
+          return ras.error;
 
         /* sub-banding */
 
-#ifdef DEBUG_RASTER
-        ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
-#endif
+        if ( y_min == y_max )
+          return ras.error;  /* still Raster_Overflow */
 
-        i = ras.band_stack[ras.band_top].y_min;
-        j = ras.band_stack[ras.band_top].y_max;
+        y_mid = ( y_min + y_max ) >> 1;
 
-        k = (Short)( ( i + j ) / 2 );
-
-        if ( ras.band_top >= 7 || k < i )
-        {
-          ras.band_top = 0;
-          ras.error    = FT_THROW( Invalid );
-
-          return ras.error;
-        }
-
-        ras.band_stack[ras.band_top + 1].y_min = k;
-        ras.band_stack[ras.band_top + 1].y_max = j;
-
-        ras.band_stack[ras.band_top].y_max = (Short)( k - 1 );
-
-        ras.band_top++;
+        band_stack[band_top++] = y_min;
+        y_min                  = y_mid + 1;
       }
       else
       {
         if ( ras.fProfile )
           if ( Draw_Sweep( RAS_VAR ) )
              return ras.error;
-        ras.band_top--;
+
+        if ( --band_top < 0 )
+          break;
+
+        y_max = y_min - 1;
+        y_min = band_stack[band_top];
       }
     }
 
-    return SUCCESS;
+    return Raster_Err_Ok;
   }
 
 
@@ -3100,9 +3096,6 @@
         ras.dropOutControl += 1;
     }
 
-    ras.second_pass = (Bool)( !( ras.outline.flags      &
-                                 FT_OUTLINE_SINGLE_PASS ) );
-
     /* Vertical Sweep */
     FT_TRACE7(( "Vertical pass (ftraster)\n" ));
 
@@ -3111,21 +3104,18 @@
     ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
     ras.Proc_Sweep_Step = Vertical_Sweep_Step;
 
-    ras.band_top            = 0;
-    ras.band_stack[0].y_min = 0;
-    ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 );
-
     ras.bWidth  = (UShort)ras.target.width;
     ras.bOrigin = (Byte*)ras.target.buffer;
 
     if ( ras.target.pitch > 0 )
       ras.bOrigin += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
 
-    if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
+    error = Render_Single_Pass( RAS_VARS 0, 0, (Int)ras.target.rows - 1 );
+    if ( error )
       return error;
 
     /* Horizontal Sweep */
-    if ( ras.second_pass && ras.dropOutControl != 2 )
+    if ( !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ) )
     {
       FT_TRACE7(( "Horizontal pass (ftraster)\n" ));
 
@@ -3134,22 +3124,12 @@
       ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
       ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
 
-      ras.band_top            = 0;
-      ras.band_stack[0].y_min = 0;
-      ras.band_stack[0].y_max = (Short)( ras.target.width - 1 );
-
-      if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
+      error = Render_Single_Pass( RAS_VARS 1, 0, (Int)ras.target.width - 1 );
+      if ( error )
         return error;
     }
 
-    return Raster_Err_None;
-  }
-
-
-  static void
-  ft_black_init( black_PRaster  raster )
-  {
-    FT_UNUSED( raster );
+    return Raster_Err_Ok;
   }
 
 
@@ -3170,7 +3150,6 @@
 
      *araster = (FT_Raster)&the_raster;
      FT_ZERO( &the_raster );
-     ft_black_init( &the_raster );
 
      return 0;
   }
@@ -3195,14 +3174,10 @@
     black_PRaster  raster = NULL;
 
 
-    *araster = 0;
     if ( !FT_NEW( raster ) )
-    {
       raster->memory = memory;
-      ft_black_init( raster );
 
-      *araster = raster;
-    }
+    *araster = raster;
 
     return error;
   }
@@ -3252,50 +3227,50 @@
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
 
+#ifndef FT_STATIC_RASTER
     black_TWorker  worker[1];
+#endif
 
     Long  buffer[FT_MAX_BLACK_POOL];
 
 
     if ( !raster )
-      return FT_THROW( Not_Ini );
+      return FT_THROW( Raster_Uninitialized );
 
     if ( !outline )
-      return FT_THROW( Invalid );
+      return FT_THROW( Invalid_Outline );
 
     /* return immediately if the outline is empty */
     if ( outline->n_points == 0 || outline->n_contours <= 0 )
-      return Raster_Err_None;
+      return Raster_Err_Ok;
 
     if ( !outline->contours || !outline->points )
-      return FT_THROW( Invalid );
+      return FT_THROW( Invalid_Outline );
 
     if ( outline->n_points !=
            outline->contours[outline->n_contours - 1] + 1 )
-      return FT_THROW( Invalid );
+      return FT_THROW( Invalid_Outline );
 
     /* this version of the raster does not support direct rendering, sorry */
-    if ( params->flags & FT_RASTER_FLAG_DIRECT )
-      return FT_THROW( Unsupported );
-
-    if ( params->flags & FT_RASTER_FLAG_AA )
-      return FT_THROW( Unsupported );
+    if ( params->flags & FT_RASTER_FLAG_DIRECT ||
+         params->flags & FT_RASTER_FLAG_AA     )
+      return FT_THROW( Cannot_Render_Glyph );
 
     if ( !target_map )
-      return FT_THROW( Invalid );
+      return FT_THROW( Invalid_Argument );
 
     /* nothing to do */
     if ( !target_map->width || !target_map->rows )
-      return Raster_Err_None;
+      return Raster_Err_Ok;
 
     if ( !target_map->buffer )
-      return FT_THROW( Invalid );
+      return FT_THROW( Invalid_Argument );
 
     ras.outline = *outline;
     ras.target  = *target_map;
 
-    worker->buff     = buffer;
-    worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
+    ras.buff     = buffer;
+    ras.sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
 
     return Render_Glyph( RAS_VAR );
   }
diff --git a/src/raster/ftraster.h b/src/raster/ftraster.h
index 3f13793..b511b3a 100644
--- a/src/raster/ftraster.h
+++ b/src/raster/ftraster.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph rasterizer (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used
@@ -22,8 +22,9 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_IMAGE_H
+#include <freetype/ftimage.h>
 
+#include <freetype/internal/compiler-macros.h>
 
 FT_BEGIN_HEADER
 
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index e8ea9cb..0b5d867 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph rasterizer interface (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_OUTLINE_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftoutln.h>
 #include "ftrend1.h"
 #include "ftraster.h"
 
@@ -127,12 +126,8 @@
       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     }
 
-    ft_glyphslot_preset_bitmap( slot, mode, origin );
-
-    if ( bitmap->width > 0x7FFF || bitmap->rows > 0x7FFF )
+    if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
     {
-      FT_ERROR(( "ft_raster1_render: glyph is too large: %u x %u\n",
-                 bitmap->width, bitmap->rows ));
       error = FT_THROW( Raster_Overflow );
       goto Exit;
     }
diff --git a/src/raster/ftrend1.h b/src/raster/ftrend1.h
index 05be54f..cec35c8 100644
--- a/src/raster/ftrend1.h
+++ b/src/raster/ftrend1.h
@@ -4,7 +4,7 @@
  *
  *   The FreeType glyph rasterizer interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTREND1_H_
 
 
-#include <ft2build.h>
-#include FT_RENDER_H
+#include <freetype/ftrender.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/raster/module.mk b/src/raster/module.mk
index b115f41..6ad1aa7 100644
--- a/src/raster/module.mk
+++ b/src/raster/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/raster/raster.c b/src/raster/raster.c
index ffd8994..82f4745 100644
--- a/src/raster/raster.c
+++ b/src/raster/raster.c
@@ -4,7 +4,7 @@
  *
  *   FreeType monochrome rasterer module component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "ftraster.c"
 #include "ftrend1.c"
diff --git a/src/raster/rasterrs.h b/src/raster/rasterrs.h
index ab242ac..989d8b4 100644
--- a/src/raster/rasterrs.h
+++ b/src/raster/rasterrs.h
@@ -4,7 +4,7 @@
  *
  *   monochrome renderer error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef RASTERRS_H_
 #define RASTERRS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  Raster_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Raster
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* RASTERRS_H_ */
 
diff --git a/src/raster/rules.mk b/src/raster/rules.mk
index 444d0ad..031b85f 100644
--- a/src/raster/rules.mk
+++ b/src/raster/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
new file mode 100644
index 0000000..901d8b7
--- /dev/null
+++ b/src/sdf/ftbsdf.c
@@ -0,0 +1,1347 @@
+/****************************************************************************
+ *
+ * ftbsdf.c
+ *
+ *   Signed Distance Field support for bitmap fonts (body only).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftmemory.h>
+#include <freetype/fttrigon.h>
+
+#include "ftsdf.h"
+#include "ftsdferrs.h"
+#include "ftsdfcommon.h"
+
+
+  /**************************************************************************
+   *
+   * A brief technical overview of how the BSDF rasterizer works
+   * -----------------------------------------------------------
+   *
+   * [Notes]:
+   *   * SDF stands for Signed Distance Field everywhere.
+   *
+   *   * BSDF stands for Bitmap to Signed Distance Field rasterizer.
+   *
+   *   * This renderer converts rasterized bitmaps to SDF.  There is another
+   *     renderer called 'sdf', which generates SDF directly from outlines;
+   *     see file `ftsdf.c` for more.
+   *
+   *   * The idea of generating SDF from bitmaps is taken from two research
+   *     papers, where one is dependent on the other:
+   *
+   *     - Per-Erik Danielsson: Euclidean Distance Mapping
+   *       http://webstaff.itn.liu.se/~stegu/JFA/Danielsson.pdf
+   *
+   *       From this paper we use the eight-point sequential Euclidean
+   *       distance mapping (8SED).  This is the heart of the process used
+   *       in this rasterizer.
+   *
+   *     - Stefan Gustavson, Robin Strand: Anti-aliased Euclidean distance transform.
+   *       http://weber.itn.liu.se/~stegu/aadist/edtaa_preprint.pdf
+   *
+   *       The original 8SED algorithm discards the pixels' alpha values,
+   *       which can contain information about the actual outline of the
+   *       glyph.  This paper takes advantage of those alpha values and
+   *       approximates outline pretty accurately.
+   *
+   *   * This rasterizer also works for monochrome bitmaps.  However, the
+   *     result is not as accurate since we don't have any way to
+   *     approximate outlines from binary bitmaps.
+   *
+   * ========================================================================
+   *
+   * Generating SDF from bitmap is done in several steps.
+   *
+   * (1) The only information we have is the bitmap itself.  It can
+   *     be monochrome or anti-aliased.  If it is anti-aliased, pixel values
+   *     are nothing but coverage values.  These coverage values can be used
+   *     to extract information about the outline of the image.  For
+   *     example, if the pixel's alpha value is 0.5, then we can safely
+   *     assume that the outline passes through the center of the pixel.
+   *
+   * (2) Find edge pixels in the bitmap (see `bsdf_is_edge` for more).  For
+   *     all edge pixels we use the Anti-aliased Euclidean distance
+   *     transform algorithm and compute approximate edge distances (see
+   *     `compute_edge_distance` and/or the second paper for more).
+   *
+   * (3) Now that we have computed approximate distances for edge pixels we
+   *     use the 8SED algorithm to basically sweep the entire bitmap and
+   *     compute distances for the rest of the pixels.  (Since the algorithm
+   *     is pretty convoluted it is only explained briefly in a comment to
+   *     function `edt8`.  To see the actual algorithm refer to the first
+   *     paper.)
+   *
+   * (4) Finally, compute the sign for each pixel.  This is done in function
+   *     `finalize_sdf`.  The basic idea is that if a pixel's original
+   *     alpha/coverage value is greater than 0.5 then it is 'inside' (and
+   *     'outside' otherwise).
+   *
+   * Pseudo Code:
+   *
+   * ```
+   * b  = source bitmap;
+   * t  = target bitmap;
+   * dm = list of distances; // dimension equal to b
+   *
+   * foreach grid_point (x, y) in b:
+   * {
+   *   if (is_edge(x, y)):
+   *     dm = approximate_edge_distance(b, x, y);
+   *
+   *   // do the 8SED on the distances
+   *   edt8(dm);
+   *
+   *   // determine the signs
+   *   determine_signs(dm):
+   *
+   *   // copy SDF data to the target bitmap
+   *   copy(dm to t);
+   * }
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  bsdf
+
+
+  /**************************************************************************
+   *
+   * useful macros
+   *
+   */
+
+#define ONE  65536 /* 1 in 16.16 */
+
+
+  /**************************************************************************
+   *
+   * structs
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   BSDF_TRaster
+   *
+   * @Description:
+   *   This struct is used in place of @FT_Raster and is stored within the
+   *   internal FreeType renderer struct.  While rasterizing this is passed
+   *   to the @FT_Raster_RenderFunc function, which then can be used however
+   *   we want.
+   *
+   * @Fields:
+   *   memory ::
+   *     Used internally to allocate intermediate memory while raterizing.
+   *
+   */
+  typedef struct  BSDF_TRaster_
+  {
+    FT_Memory  memory;
+
+  } BSDF_TRaster, *BSDF_PRaster;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   ED
+   *
+   * @Description:
+   *   Euclidean distance.  It gets used for Euclidean distance transforms;
+   *   it can also be interpreted as an edge distance.
+   *
+   * @Fields:
+   *   dist ::
+   *     Vector length of the `prox` parameter.  Can be squared or absolute
+   *     depending on the `USE_SQUARED_DISTANCES` macro defined in file
+   *     `ftsdfcommon.h`.
+   *
+   *   prox ::
+   *     Vector to the nearest edge.  Can also be interpreted as shortest
+   *     distance of a point.
+   *
+   *   alpha ::
+   *     Alpha value of the original bitmap from which we generate SDF.
+   *     Needed for computing the gradient and determining the proper sign
+   *     of a pixel.
+   *
+   */
+  typedef struct  ED_
+  {
+    FT_16D16      dist;
+    FT_16D16_Vec  prox;
+    FT_Byte       alpha;
+
+  } ED;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   BSDF_Worker
+   *
+   * @Description:
+   *   A convenience struct that is passed to functions while generating
+   *   SDF; most of those functions require the same parameters.
+   *
+   * @Fields:
+   *   distance_map ::
+   *     A one-dimensional array that gets interpreted as two-dimensional
+   *     one.  It contains the Euclidean distances of all points of the
+   *     bitmap.
+   *
+   *   width ::
+   *     Width of the above `distance_map`.
+   *
+   *   rows ::
+   *     Number of rows in the above `distance_map`.
+   *
+   *   params ::
+   *     Internal parameters and properties required by the rasterizer.  See
+   *     file `ftsdf.h` for more.
+   *
+   */
+  typedef struct  BSDF_Worker_
+  {
+    ED*  distance_map;
+
+    FT_Int  width;
+    FT_Int  rows;
+
+    SDF_Raster_Params  params;
+
+  } BSDF_Worker;
+
+
+  /**************************************************************************
+   *
+   * initializer
+   *
+   */
+
+  static const ED  zero_ed = { 0, { 0, 0 }, 0 };
+
+
+  /**************************************************************************
+   *
+   * rasterizer functions
+   *
+   */
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   bsdf_is_edge
+   *
+   * @Description:
+   *   Check whether a pixel is an edge pixel, i.e., whether it is
+   *   surrounded by a completely black pixel (zero alpha), and the current
+   *   pixel is not a completely black pixel.
+   *
+   * @Input:
+   *   dm ::
+   *     Array of distances.  The parameter must point to the current
+   *     pixel, i.e., the pixel that is to be checked for being an edge.
+   *
+   *   x ::
+   *     The x position of the current pixel.
+   *
+   *   y ::
+   *     The y position of the current pixel.
+   *
+   *   w ::
+   *     Width of the bitmap.
+   *
+   *   r ::
+   *     Number of rows in the bitmap.
+   *
+   * @Return:
+   *   1~if the current pixel is an edge pixel, 0~otherwise.
+   *
+   */
+
+#ifdef CHECK_NEIGHBOR
+#undef CHECK_NEIGHBOR
+#endif
+
+#define CHECK_NEIGHBOR( x_offset, y_offset )              \
+          do                                              \
+          {                                               \
+            if ( x + x_offset >= 0 && x + x_offset < w && \
+                 y + y_offset >= 0 && y + y_offset < r )  \
+            {                                             \
+              num_neighbors++;                            \
+                                                          \
+              to_check = dm + y_offset * w + x_offset;    \
+              if ( to_check->alpha == 0 )                 \
+              {                                           \
+                is_edge = 1;                              \
+                goto Done;                                \
+              }                                           \
+            }                                             \
+          } while ( 0 )
+
+  static FT_Bool
+  bsdf_is_edge( ED*     dm,   /* distance map              */
+                FT_Int  x,    /* x index of point to check */
+                FT_Int  y,    /* y index of point to check */
+                FT_Int  w,    /* width                     */
+                FT_Int  r )   /* rows                      */
+  {
+    FT_Bool  is_edge       = 0;
+    ED*      to_check      = NULL;
+    FT_Int   num_neighbors = 0;
+
+
+    if ( dm->alpha == 0 )
+      goto Done;
+
+    if ( dm->alpha > 0 && dm->alpha < 255 )
+    {
+      is_edge = 1;
+      goto Done;
+    }
+
+    /* up */
+    CHECK_NEIGHBOR(  0, -1 );
+
+    /* down */
+    CHECK_NEIGHBOR(  0,  1 );
+
+    /* left */
+    CHECK_NEIGHBOR( -1,  0 );
+
+    /* right */
+    CHECK_NEIGHBOR(  1,  0 );
+
+    /* up left */
+    CHECK_NEIGHBOR( -1, -1 );
+
+    /* up right */
+    CHECK_NEIGHBOR(  1, -1 );
+
+    /* down left */
+    CHECK_NEIGHBOR( -1,  1 );
+
+    /* down right */
+    CHECK_NEIGHBOR(  1,  1 );
+
+    if ( num_neighbors != 8 )
+      is_edge = 1;
+
+  Done:
+    return is_edge;
+  }
+
+#undef CHECK_NEIGHBOR
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   compute_edge_distance
+   *
+   * @Description:
+   *   Approximate the outline and compute the distance from `current`
+   *   to the approximated outline.
+   *
+   * @Input:
+   *   current ::
+   *     Array of Euclidean distances.  `current` must point to the position
+   *     for which the distance is to be caculated.  We treat this array as
+   *     a two-dimensional array mapped to a one-dimensional array.
+   *
+   *   x ::
+   *     The x coordinate of the `current` parameter in the array.
+   *
+   *   y ::
+   *     The y coordinate of the `current` parameter in the array.
+   *
+   *   w ::
+   *     The width of the distances array.
+   *
+   *   r ::
+   *     Number of rows in the distances array.
+   *
+   * @Return:
+   *   A vector pointing to the approximate edge distance.
+   *
+   * @Note:
+   *   This is a computationally expensive function.  Try to reduce the
+   *   number of calls to this function.  Moreover, this must only be used
+   *   for edge pixel positions.
+   *
+   */
+  static FT_16D16_Vec
+  compute_edge_distance( ED*     current,
+                         FT_Int  x,
+                         FT_Int  y,
+                         FT_Int  w,
+                         FT_Int  r )
+  {
+    /*
+     * This function, based on the paper presented by Stefan Gustavson and
+     * Robin Strand, gets used to approximate edge distances from
+     * anti-aliased bitmaps.
+     *
+     * The algorithm is as follows.
+     *
+     * (1) In anti-aliased images, the pixel's alpha value is the coverage
+     *     of the pixel by the outline.  For example, if the alpha value is
+     *     0.5f we can assume that the outline passes through the center of
+     *     the pixel.
+     *
+     * (2) For this reason we can use that alpha value to approximate the real
+     *     distance of the pixel to edge pretty accurately.  A simple
+     *     approximation is `(0.5f - alpha)`, assuming that the outline is
+     *     parallel to the x or y~axis.  However, in this algorithm we use a
+     *     different approximation which is quite accurate even for
+     *     non-axis-aligned edges.
+     *
+     * (3) The only remaining piece of information that we cannot
+     *     approximate directly from the alpha is the direction of the edge.
+     *     This is where we use Sobel's operator to compute the gradient of
+     *     the pixel.  The gradient give us a pretty good approximation of
+     *     the edge direction.  We use a 3x3 kernel filter to compute the
+     *     gradient.
+     *
+     * (4) After the above two steps we have both the direction and the
+     *     distance to the edge which is used to generate the Signed
+     *     Distance Field.
+     *
+     * References:
+     *
+     * - Anti-Aliased Euclidean Distance Transform:
+     *     http://weber.itn.liu.se/~stegu/aadist/edtaa_preprint.pdf
+     * - Sobel Operator:
+     *     https://en.wikipedia.org/wiki/Sobel_operator
+     */
+
+    FT_16D16_Vec  g = { 0, 0 };
+    FT_16D16      dist, current_alpha;
+    FT_16D16      a1, temp;
+    FT_16D16      gx, gy;
+    FT_16D16      alphas[9];
+
+
+    /* Since our spread cannot be 0, this condition */
+    /* can never be true.                           */
+    if ( x <= 0 || x >= w - 1 ||
+         y <= 0 || y >= r - 1 )
+      return g;
+
+    /* initialize the alphas */
+    alphas[0] = 256 * (FT_16D16)current[-w - 1].alpha;
+    alphas[1] = 256 * (FT_16D16)current[-w    ].alpha;
+    alphas[2] = 256 * (FT_16D16)current[-w + 1].alpha;
+    alphas[3] = 256 * (FT_16D16)current[    -1].alpha;
+    alphas[4] = 256 * (FT_16D16)current[     0].alpha;
+    alphas[5] = 256 * (FT_16D16)current[     1].alpha;
+    alphas[6] = 256 * (FT_16D16)current[ w - 1].alpha;
+    alphas[7] = 256 * (FT_16D16)current[ w    ].alpha;
+    alphas[8] = 256 * (FT_16D16)current[ w + 1].alpha;
+
+    current_alpha = alphas[4];
+
+    /* Compute the gradient using the Sobel operator. */
+    /* In this case we use the following 3x3 filters: */
+    /*                                                */
+    /* For x: |   -1     0   -1    |                  */
+    /*        | -root(2) 0 root(2) |                  */
+    /*        |    -1    0    1    |                  */
+    /*                                                */
+    /* For y: |   -1 -root(2) -1   |                  */
+    /*        |    0    0      0   |                  */
+    /*        |    1  root(2)  1   |                  */
+    /*                                                */
+    /* [Note]: 92681 is root(2) in 16.16 format.      */
+    g.x = -alphas[0] -
+           FT_MulFix( alphas[3], 92681 ) -
+           alphas[6] +
+           alphas[2] +
+           FT_MulFix( alphas[5], 92681 ) +
+           alphas[8];
+
+    g.y = -alphas[0] -
+           FT_MulFix( alphas[1], 92681 ) -
+           alphas[2] +
+           alphas[6] +
+           FT_MulFix( alphas[7], 92681 ) +
+           alphas[8];
+
+    FT_Vector_NormLen( &g );
+
+    /* The gradient gives us the direction of the    */
+    /* edge for the current pixel.  Once we have the */
+    /* approximate direction of the edge, we can     */
+    /* approximate the edge distance much better.    */
+
+    if ( g.x == 0 || g.y == 0 )
+      dist = ONE / 2 - alphas[4];
+    else
+    {
+      gx = g.x;
+      gy = g.y;
+
+      gx = FT_ABS( gx );
+      gy = FT_ABS( gy );
+
+      if ( gx < gy )
+      {
+        temp = gx;
+        gx   = gy;
+        gy   = temp;
+      }
+
+      a1 = FT_DivFix( gy, gx ) / 2;
+
+      if ( current_alpha < a1 )
+        dist = ( gx + gy ) / 2 -
+               square_root( 2 * FT_MulFix( gx,
+                                           FT_MulFix( gy,
+                                                      current_alpha ) ) );
+
+      else if ( current_alpha < ( ONE - a1 ) )
+        dist = FT_MulFix( ONE / 2 - current_alpha, gx );
+
+      else
+        dist = -( gx + gy ) / 2 +
+               square_root( 2 * FT_MulFix( gx,
+                                           FT_MulFix( gy,
+                                                      ONE - current_alpha ) ) );
+    }
+
+    g.x = FT_MulFix( g.x, dist );
+    g.y = FT_MulFix( g.y, dist );
+
+    return g;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   bsdf_approximate_edge
+   *
+   * @Description:
+   *   Loops over all the pixels and call `compute_edge_distance` only for
+   *   edge pixels.  This maked the process a lot faster since
+   *   `compute_edge_distance` uses functions such as `FT_Vector_NormLen',
+   *   which are quite slow.
+   *
+   * @InOut:
+   *   worker ::
+   *     Contains the distance map as well as all the relevant parameters
+   *     required by the function.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   * @Note:
+   *   The function directly manipulates `worker->distance_map`.
+   *
+   */
+  static FT_Error
+  bsdf_approximate_edge( BSDF_Worker*  worker )
+  {
+    FT_Error  error = FT_Err_Ok;
+    FT_Int    i, j;
+    FT_Int    index;
+    ED*       ed;
+
+
+    if ( !worker || !worker->distance_map )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    ed = worker->distance_map;
+
+    for ( j = 0; j < worker->rows; j++ )
+    {
+      for ( i = 0; i < worker->width; i++ )
+      {
+        index = j * worker->width + i;
+
+        if ( bsdf_is_edge( worker->distance_map + index,
+                           i, j,
+                           worker->width,
+                           worker->rows ) )
+        {
+          /* approximate the edge distance for edge pixels */
+          ed[index].prox = compute_edge_distance( ed + index,
+                                                  i, j,
+                                                  worker->width,
+                                                  worker->rows );
+          ed[index].dist = VECTOR_LENGTH_16D16( ed[index].prox );
+        }
+        else
+        {
+          /* for non-edge pixels assign far away distances */
+          ed[index].dist   = 400 * ONE;
+          ed[index].prox.x = 200 * ONE;
+          ed[index].prox.y = 200 * ONE;
+        }
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   bsdf_init_distance_map
+   *
+   * @Description:
+   *   Initialize the distance map according to the '8-point sequential
+   *   Euclidean distance mapping' (8SED) algorithm.  Basically it copies
+   *   the `source` bitmap alpha values to the `distance_map->alpha`
+   *   parameter of `worker`.
+   *
+   * @Input:
+   *   source ::
+   *     Source bitmap to copy the data from.
+   *
+   * @Output:
+   *   worker ::
+   *     Target distance map to copy the data to.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  bsdf_init_distance_map( const FT_Bitmap*  source,
+                          BSDF_Worker*      worker )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    FT_Int    x_diff, y_diff;
+    FT_Int    t_i, t_j, s_i, s_j;
+    FT_Byte*  s;
+    ED*       t;
+
+
+    /* again check the parameters (probably unnecessary) */
+    if ( !source || !worker )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* Because of the way we convert a bitmap to SDF, */
+    /* i.e., aligning the source to the center of the */
+    /* target, the target's width and rows must be    */
+    /* checked before copying.                        */
+    if ( worker->width < (FT_Int)source->width ||
+         worker->rows  < (FT_Int)source->rows  )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* check pixel mode */
+    if ( source->pixel_mode == FT_PIXEL_MODE_NONE )
+    {
+      FT_ERROR(( "bsdf_copy_source_to_target:"
+                 " Invalid pixel mode of source bitmap" ));
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( source->pixel_mode == FT_PIXEL_MODE_MONO )
+    {
+      FT_TRACE0(( "bsdf_copy_source_to_target:"
+                  " The `bsdf' renderer can convert monochrome\n" ));
+      FT_TRACE0(( "                           "
+                  " bitmaps to SDF but the results are not perfect\n" ));
+      FT_TRACE0(( "                           "
+                  " because there is no way to approximate actual\n" ));
+      FT_TRACE0(( "                           "
+                  " outlines from monochrome bitmaps.  Consider\n" ));
+      FT_TRACE0(( "                           "
+                  " using an anti-aliased bitmap instead.\n" ));
+    }
+#endif
+
+    /* Calculate the width and row differences */
+    /* between target and source.              */
+    x_diff = worker->width - (int)source->width;
+    y_diff = worker->rows - (int)source->rows;
+
+    x_diff /= 2;
+    y_diff /= 2;
+
+    t = (ED*)worker->distance_map;
+    s = source->buffer;
+
+    /* For now we only support pixel mode `FT_PIXEL_MODE_MONO`  */
+    /* and `FT_PIXEL_MODE_GRAY`.  More will be added later.     */
+    /*                                                          */
+    /* [NOTE]: We can also use @FT_Bitmap_Convert to convert    */
+    /*         bitmap to 8bpp.  To avoid extra allocation and   */
+    /*         since the target bitmap can be 16bpp we manually */
+    /*         convert the source bitmap to the desired bpp.    */
+
+    switch ( source->pixel_mode )
+    {
+    case FT_PIXEL_MODE_MONO:
+      {
+        FT_Int  t_width = worker->width;
+        FT_Int  t_rows  = worker->rows;
+        FT_Int  s_width = (int)source->width;
+        FT_Int  s_rows  = (int)source->rows;
+
+
+        for ( t_j = 0; t_j < t_rows; t_j++ )
+        {
+          for ( t_i = 0; t_i < t_width; t_i++ )
+          {
+            FT_Int   t_index = t_j * t_width + t_i;
+            FT_Int   s_index;
+            FT_Int   div, mod;
+            FT_Byte  pixel, byte;
+
+
+            t[t_index] = zero_ed;
+
+            s_i = t_i - x_diff;
+            s_j = t_j - y_diff;
+
+            /* Assign 0 to padding similar to */
+            /* the source bitmap.             */
+            if ( s_i < 0 || s_i >= s_width ||
+                 s_j < 0 || s_j >= s_rows  )
+              continue;
+
+            if ( worker->params.flip_y )
+              s_index = ( s_rows - s_j - 1 ) * source->pitch;
+            else
+              s_index = s_j * source->pitch;
+
+            div = s_index + s_i / 8;
+            mod = 7 - s_i % 8;
+
+            pixel = s[div];
+            byte  = (FT_Byte)( 1 << mod );
+
+            t[t_index].alpha = pixel & byte ? 255 : 0;
+          }
+        }
+      }
+      break;
+
+    case FT_PIXEL_MODE_GRAY:
+      {
+        FT_Int  t_width = worker->width;
+        FT_Int  t_rows  = worker->rows;
+        FT_Int  s_width = (int)source->width;
+        FT_Int  s_rows  = (int)source->rows;
+
+
+        /* loop over all pixels and assign pixel values from source */
+        for ( t_j = 0; t_j < t_rows; t_j++ )
+        {
+          for ( t_i = 0; t_i < t_width; t_i++ )
+          {
+            FT_Int  t_index = t_j * t_width + t_i;
+            FT_Int  s_index;
+
+
+            t[t_index] = zero_ed;
+
+            s_i = t_i - x_diff;
+            s_j = t_j - y_diff;
+
+            /* Assign 0 to padding similar to */
+            /* the source bitmap.             */
+            if ( s_i < 0 || s_i >= s_width ||
+                 s_j < 0 || s_j >= s_rows  )
+              continue;
+
+            if ( worker->params.flip_y )
+              s_index = ( s_rows - s_j - 1 ) * s_width + s_i;
+            else
+              s_index = s_j * s_width + s_i;
+
+            /* simply copy the alpha values */
+            t[t_index].alpha = s[s_index];
+          }
+        }
+      }
+      break;
+
+    default:
+      FT_ERROR(( "bsdf_copy_source_to_target:"
+                 " unsopported pixel mode of source bitmap\n" ));
+
+      error = FT_THROW( Unimplemented_Feature );
+      break;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   compare_neighbor
+   *
+   * @Description:
+   *   Compare neighbor pixel (which is defined by the offset) and update
+   *   `current` distance if the new distance is shorter than the original.
+   *
+   * @Input:
+   *   x_offset ::
+   *     X offset of the neighbor to be checked.  The offset is relative to
+   *     the `current`.
+   *
+   *   y_offset ::
+   *     Y offset of the neighbor to be checked.  The offset is relative to
+   *     the `current`.
+   *
+   *   width ::
+   *     Width of the `current` array.
+   *
+   * @InOut:
+   *   current ::
+   *     Pointer into array of distances.  This parameter must point to the
+   *     position whose neighbor is to be checked.  The array is treated as
+   *     a two-dimensional array.
+   *
+   */
+  static void
+  compare_neighbor( ED*     current,
+                    FT_Int  x_offset,
+                    FT_Int  y_offset,
+                    FT_Int  width )
+  {
+    ED*           to_check;
+    FT_16D16      dist;
+    FT_16D16_Vec  dist_vec;
+
+
+    to_check = current + ( y_offset * width ) + x_offset;
+
+    /*
+     * While checking for the nearest point we first approximate the
+     * distance of `current` by adding the deviation (which is sqrt(2) at
+     * most).  Only if the new value is less than the current value we
+     * calculate the actual distances using `FT_Vector_Length`.  This last
+     * step can be omitted by using squared distances.
+     */
+
+    /*
+     * Approximate the distance.  We subtract 1 to avoid precision errors,
+     * which could happen because the two directions can be opposite.
+     */
+    dist = to_check->dist - ONE;
+
+    if ( dist < current->dist )
+    {
+      dist_vec = to_check->prox;
+
+      dist_vec.x += x_offset * ONE;
+      dist_vec.y += y_offset * ONE;
+      dist = VECTOR_LENGTH_16D16( dist_vec );
+
+      if ( dist < current->dist )
+      {
+        current->dist = dist;
+        current->prox = dist_vec;
+      }
+    }
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   first_pass
+   *
+   * @Description:
+   *   First pass of the 8SED algorithm.  Loop over the bitmap from top to
+   *   bottom and scan each row left to right, updating the distances in
+   *   `worker->distance_map`.
+   *
+   * @InOut:
+   *   worker::
+   *     Contains all the relevant parameters.
+   *
+   */
+  static void
+  first_pass( BSDF_Worker*  worker )
+  {
+    FT_Int  i, j; /* iterators    */
+    FT_Int  w, r; /* width, rows  */
+    ED*     dm;   /* distance map */
+
+
+    dm = worker->distance_map;
+    w  = worker->width;
+    r  = worker->rows;
+
+    /* Start scanning from top to bottom and sweep each    */
+    /* row back and forth comparing the distances of the   */
+    /* neighborhood.  Leave the first row as it has no top */
+    /* neighbor; it will be covered in the second scan of  */
+    /* the image (from bottom to top).                     */
+    for ( j = 1; j < r; j++ )
+    {
+      FT_Int  index;
+      ED*     current;
+
+
+      /* Forward pass of rows (left -> right).  Leave the first  */
+      /* column, which gets covered in the backward pass.        */
+      for ( i = 1; i < w - 1; i++ )
+      {
+        index   = j * w + i;
+        current = dm + index;
+
+        /* left-up */
+        compare_neighbor( current, -1, -1, w );
+        /* up */
+        compare_neighbor( current,  0, -1, w );
+        /* up-right */
+        compare_neighbor( current,  1, -1, w );
+        /* left */
+        compare_neighbor( current, -1,  0, w );
+      }
+
+      /* Backward pass of rows (right -> left).  Leave the last */
+      /* column, which was already covered in the forward pass. */
+      for ( i = w - 2; i >= 0; i-- )
+      {
+        index   = j * w + i;
+        current = dm + index;
+
+        /* right */
+        compare_neighbor( current, 1, 0, w );
+      }
+    }
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   second_pass
+   *
+   * @Description:
+   *   Second pass of the 8SED algorithm.  Loop over the bitmap from bottom
+   *   to top and scan each row left to right, updating the distances in
+   *   `worker->distance_map`.
+   *
+   * @InOut:
+   *   worker::
+   *     Contains all the relevant parameters.
+   *
+   */
+  static void
+  second_pass( BSDF_Worker*  worker )
+  {
+    FT_Int  i, j; /* iterators    */
+    FT_Int  w, r; /* width, rows  */
+    ED*     dm;   /* distance map */
+
+
+    dm = worker->distance_map;
+    w  = worker->width;
+    r  = worker->rows;
+
+    /* Start scanning from bottom to top and sweep each    */
+    /* row back and forth comparing the distances of the   */
+    /* neighborhood.  Leave the last row as it has no down */
+    /* neighbor; it is already covered in the first scan   */
+    /* of the image (from top to bottom).                  */
+    for ( j = r - 2; j >= 0; j-- )
+    {
+      FT_Int  index;
+      ED*     current;
+
+
+      /* Forward pass of rows (left -> right).  Leave the first */
+      /* column, which gets covered in the backward pass.       */
+      for ( i = 1; i < w - 1; i++ )
+      {
+        index   = j * w + i;
+        current = dm + index;
+
+        /* left-up */
+        compare_neighbor( current, -1, 1, w );
+        /* up */
+        compare_neighbor( current,  0, 1, w );
+        /* up-right */
+        compare_neighbor( current,  1, 1, w );
+        /* left */
+        compare_neighbor( current, -1, 0, w );
+      }
+
+      /* Backward pass of rows (right -> left).  Leave the last */
+      /* column, which was already covered in the forward pass. */
+      for ( i = w - 2; i >= 0; i-- )
+      {
+        index   = j * w + i;
+        current = dm + index;
+
+        /* right */
+        compare_neighbor( current, 1, 0, w );
+      }
+    }
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   edt8
+   *
+   * @Description:
+   *   Compute the distance map of the a bitmap.  Execute both first and
+   *   second pass of the 8SED algorithm.
+   *
+   * @InOut:
+   *   worker::
+   *     Contains all the relevant parameters.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  edt8( BSDF_Worker*  worker )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( !worker || !worker->distance_map )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* first scan of the image */
+    first_pass( worker );
+
+    /* second scan of the image */
+    second_pass( worker );
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   finalize_sdf
+   *
+   * @Description:
+   *   Copy the SDF data from `worker->distance_map` to the `target` bitmap.
+   *   Also transform the data to output format, (which is 6.10 fixed-point
+   *   format at the moment).
+   *
+   * @Input:
+   *   worker ::
+   *     Contains source distance map and other SDF data.
+   *
+   * @Output:
+   *   target ::
+   *     Target bitmap to which the SDF data is copied to.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  finalize_sdf( BSDF_Worker*      worker,
+                const FT_Bitmap*  target )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    FT_Int  w, r;
+    FT_Int  i, j;
+
+    FT_SDFFormat*  t_buffer;
+    FT_16D16       sp_sq, spread;
+
+
+    if ( !worker || !target )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    w        = (int)target->width;
+    r        = (int)target->rows;
+    t_buffer = (FT_SDFFormat*)target->buffer;
+
+    if ( w != worker->width ||
+         r != worker->rows  )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    spread = (FT_16D16)FT_INT_16D16( worker->params.spread );
+
+#if USE_SQUARED_DISTANCES
+    sp_sq = (FT_16D16)FT_INT_16D16( worker->params.spread *
+                                    worker->params.spread );
+#else
+    sp_sq = (FT_16D16)FT_INT_16D16( worker->params.spread );
+#endif
+
+    for ( j = 0; j < r; j++ )
+    {
+      for ( i = 0; i < w; i++ )
+      {
+        FT_Int        index;
+        FT_16D16      dist;
+        FT_SDFFormat  final_dist;
+        FT_Char       sign;
+
+
+        index = j * w + i;
+        dist  = worker->distance_map[index].dist;
+
+        if ( dist < 0 || dist > sp_sq )
+          dist = sp_sq;
+
+#if USE_SQUARED_DISTANCES
+        dist = square_root( dist );
+#endif
+
+        /* We assume that if the pixel is inside a contour */
+        /* its coverage value must be > 127.               */
+        sign = worker->distance_map[index].alpha < 127 ? -1 : 1;
+
+        /* flip the sign according to the property */
+        if ( worker->params.flip_sign )
+          sign = -sign;
+
+        /* concatenate from 16.16 to appropriate format */
+        final_dist = map_fixed_to_sdf( dist * sign, spread );
+
+        t_buffer[index] = final_dist;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * interface functions
+   *
+   */
+
+  /* called when adding a new module through @FT_Add_Module */
+  static FT_Error
+  bsdf_raster_new( FT_Memory      memory,
+                   BSDF_PRaster*  araster )
+  {
+    FT_Error      error;
+    BSDF_PRaster  raster = NULL;
+
+
+    if ( !FT_NEW( raster ) )
+      raster->memory = memory;
+
+    *araster = raster;
+
+    return error;
+  }
+
+
+  /* unused */
+  static void
+  bsdf_raster_reset( FT_Raster       raster,
+                     unsigned char*  pool_base,
+                     unsigned long   pool_size )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( pool_base );
+    FT_UNUSED( pool_size );
+  }
+
+
+  /* unused */
+  static FT_Error
+  bsdf_raster_set_mode( FT_Raster      raster,
+                        unsigned long  mode,
+                        void*          args )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( mode );
+    FT_UNUSED( args );
+
+    return FT_Err_Ok;
+  }
+
+
+  /* called while rendering through @FT_Render_Glyph */
+  static FT_Error
+  bsdf_raster_render( FT_Raster                raster,
+                      const FT_Raster_Params*  params )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = NULL;
+
+    const FT_Bitmap*  source = NULL;
+    const FT_Bitmap*  target = NULL;
+
+    BSDF_TRaster*  bsdf_raster = (BSDF_TRaster*)raster;
+    BSDF_Worker    worker;
+
+    const SDF_Raster_Params*  sdf_params = (const SDF_Raster_Params*)params;
+
+
+    worker.distance_map = NULL;
+
+    /* check for valid parameters */
+    if ( !raster || !params )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* check whether the flag is set */
+    if ( sdf_params->root.flags != FT_RASTER_FLAG_SDF )
+    {
+      error = FT_THROW( Raster_Corrupted );
+      goto Exit;
+    }
+
+    source = (const FT_Bitmap*)sdf_params->root.source;
+    target = (const FT_Bitmap*)sdf_params->root.target;
+
+    /* check source and target bitmap */
+    if ( !source || !target )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    memory = bsdf_raster->memory;
+    if ( !memory )
+    {
+      FT_TRACE0(( "bsdf_raster_render: Raster not set up properly,\n" ));
+      FT_TRACE0(( "                    unable to find memory handle.\n" ));
+
+      error = FT_THROW( Invalid_Handle );
+      goto Exit;
+    }
+
+    /* check whether spread is set properly */
+    if ( sdf_params->spread > MAX_SPREAD ||
+         sdf_params->spread < MIN_SPREAD )
+    {
+      FT_TRACE0(( "bsdf_raster_render:"
+                  " The `spread' field of `SDF_Raster_Params'\n" ));
+      FT_TRACE0(( "                   "
+                  " is invalid; the value of this field must be\n" ));
+      FT_TRACE0(( "                   "
+                  " within [%d, %d].\n",
+                  MIN_SPREAD, MAX_SPREAD ));
+      FT_TRACE0(( "                   "
+                  " Also, you must pass `SDF_Raster_Params'\n" ));
+      FT_TRACE0(( "                   "
+                  " instead of the default `FT_Raster_Params'\n" ));
+      FT_TRACE0(( "                   "
+                  " while calling this function and set the fields\n" ));
+      FT_TRACE0(( "                   "
+                  " accordingly.\n" ));
+
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* set up the worker */
+
+    /* allocate the distance map */
+    if ( FT_QALLOC_MULT( worker.distance_map, target->rows,
+                         target->width * sizeof ( *worker.distance_map ) ) )
+      goto Exit;
+
+    worker.width  = (int)target->width;
+    worker.rows   = (int)target->rows;
+    worker.params = *sdf_params;
+
+    FT_CALL( bsdf_init_distance_map( source, &worker ) );
+    FT_CALL( bsdf_approximate_edge( &worker ) );
+    FT_CALL( edt8( &worker ) );
+    FT_CALL( finalize_sdf( &worker, target ) );
+
+    FT_TRACE0(( "bsdf_raster_render: Total memory used = %ld\n",
+                worker.width * worker.rows *
+                  (long)sizeof ( *worker.distance_map ) ));
+
+  Exit:
+    if ( worker.distance_map )
+      FT_FREE( worker.distance_map );
+
+    return error;
+  }
+
+
+  /* called while deleting `FT_Library` only if the module is added */
+  static void
+  bsdf_raster_done( FT_Raster  raster )
+  {
+    FT_Memory  memory = (FT_Memory)((BSDF_TRaster*)raster)->memory;
+
+
+    FT_FREE( raster );
+  }
+
+
+  FT_DEFINE_RASTER_FUNCS(
+    ft_bitmap_sdf_raster,
+
+    FT_GLYPH_FORMAT_BITMAP,
+
+    (FT_Raster_New_Func)     bsdf_raster_new,       /* raster_new      */
+    (FT_Raster_Reset_Func)   bsdf_raster_reset,     /* raster_reset    */
+    (FT_Raster_Set_Mode_Func)bsdf_raster_set_mode,  /* raster_set_mode */
+    (FT_Raster_Render_Func)  bsdf_raster_render,    /* raster_render   */
+    (FT_Raster_Done_Func)    bsdf_raster_done       /* raster_done     */
+  )
+
+
+/* END */
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
new file mode 100644
index 0000000..26a6d00
--- /dev/null
+++ b/src/sdf/ftsdf.c
@@ -0,0 +1,3927 @@
+/****************************************************************************
+ *
+ * ftsdf.c
+ *
+ *   Signed Distance Field support for outline fonts (body).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftoutln.h>
+#include <freetype/fttrigon.h>
+#include <freetype/ftbitmap.h>
+#include "ftsdf.h"
+
+#include "ftsdferrs.h"
+
+
+  /**************************************************************************
+   *
+   * A brief technical overview of how the SDF rasterizer works
+   * ----------------------------------------------------------
+   *
+   * [Notes]:
+   *   * SDF stands for Signed Distance Field everywhere.
+   *
+   *   * This renderer generates SDF directly from outlines.  There is
+   *     another renderer called 'bsdf', which converts bitmaps to SDF; see
+   *     file `ftbsdf.c` for more.
+   *
+   *   * The basic idea of generating the SDF is taken from Viktor Chlumsky's
+   *     research paper.  The paper explains both single and multi-channel
+   *     SDF, however, this implementation only generates single-channel SDF.
+   *
+   *       Chlumsky, Viktor: Shape Decomposition for Multi-channel Distance
+   *       Fields.  Master's thesis.  Czech Technical University in Prague,
+   *       Faculty of InformationTechnology, 2015.
+   *
+   *     For more information: https://github.com/Chlumsky/msdfgen
+   *
+   * ========================================================================
+   *
+   * Generating SDF from outlines is pretty straightforward.
+   *
+   * (1) We have a set of contours that make the outline of a shape/glyph.
+   *     Each contour comprises of several edges, with three types of edges.
+   *
+   *     * line segments
+   *     * conic Bezier curves
+   *     * cubic Bezier curves
+   *
+   * (2) Apart from the outlines we also have a two-dimensional grid, namely
+   *     the bitmap that is used to represent the final SDF data.
+   *
+   * (3) In order to generate SDF, our task is to find shortest signed
+   *     distance from each grid point to the outline.  The 'signed
+   *     distance' means that if the grid point is filled by any contour
+   *     then its sign is positive, otherwise it is negative.  The pseudo
+   *     code is as follows.
+   *
+   *     ```
+   *     foreach grid_point (x, y):
+   *     {
+   *       int min_dist = INT_MAX;
+   *
+   *       foreach contour in outline:
+   *       {
+   *         foreach edge in contour:
+   *         {
+   *           // get shortest distance from point (x, y) to the edge
+   *           d = get_min_dist(x, y, edge);
+   *
+   *           if (d < min_dist)
+   *             min_dist = d;
+   *         }
+   *
+   *         bitmap[x, y] = min_dist;
+   *       }
+   *     }
+   *     ```
+   *
+   * (4) After running this algorithm the bitmap contains information about
+   *     the shortest distance from each point to the outline of the shape.
+   *     Of course, while this is the most straightforward way of generating
+   *     SDF, we use various optimizations in our implementation.  See the
+   *     `sdf_generate_*' functions in this file for all details.
+   *
+   *     The optimization currently used by default is subdivision; see
+   *     function `sdf_generate_subdivision` for more.
+   *
+   *     Also, to see how we compute the shortest distance from a point to
+   *     each type of edge, check out the `get_min_distance_*' functions.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  sdf
+
+
+  /**************************************************************************
+   *
+   * definitions
+   *
+   */
+
+  /*
+   * If set to 1, the rasterizer uses Newton-Raphson's method for finding
+   * the shortest distance from a point to a conic curve.
+   *
+   * If set to 0, an analytical method gets used instead, which computes the
+   * roots of a cubic polynomial to find the shortest distance.  However,
+   * the analytical method can currently underflow; we thus use Newton's
+   * method by default.
+   */
+#ifndef USE_NEWTON_FOR_CONIC
+#define USE_NEWTON_FOR_CONIC  1
+#endif
+
+  /*
+   * The number of intervals a Bezier curve gets sampled and checked to find
+   * the shortest distance.
+   */
+#define MAX_NEWTON_DIVISIONS  4
+
+  /*
+   * The number of steps of Newton's iterations in each interval of the
+   * Bezier curve.  Basically, we run Newton's approximation
+   *
+   *   x -= Q(t) / Q'(t)
+   *
+   * for each division to get the shortest distance.
+   */
+#define MAX_NEWTON_STEPS  4
+
+  /*
+   * The epsilon distance (in 16.16 fractional units) used for corner
+   * resolving.  If the difference of two distances is less than this value
+   * they will be checked for a corner if they are ambiguous.
+   */
+#define CORNER_CHECK_EPSILON  32
+
+#if 0
+  /*
+   * Coarse grid dimension.  Will probably be removed in the future because
+   * coarse grid optimization is the slowest algorithm.
+   */
+#define CG_DIMEN  8
+#endif
+
+
+  /**************************************************************************
+   *
+   * macros
+   *
+   */
+
+#define MUL_26D6( a, b )  ( ( ( a ) * ( b ) ) / 64 )
+#define VEC_26D6_DOT( p, q )  ( MUL_26D6( p.x, q.x ) + \
+                                MUL_26D6( p.y, q.y ) )
+
+
+  /**************************************************************************
+   *
+   * structures and enums
+   *
+   */
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   SDF_TRaster
+   *
+   * @Description:
+   *   This struct is used in place of @FT_Raster and is stored within the
+   *   internal FreeType renderer struct.  While rasterizing it is passed to
+   *   the @FT_Raster_RenderFunc function, which then can be used however we
+   *   want.
+   *
+   * @Fields:
+   *   memory ::
+   *     Used internally to allocate intermediate memory while raterizing.
+   *
+   */
+  typedef struct  SDF_TRaster_
+  {
+    FT_Memory  memory;
+
+  } SDF_TRaster, *SDF_PRaster;
+
+
+  /**************************************************************************
+   *
+   * @Enum:
+   *   SDF_Edge_Type
+   *
+   * @Description:
+   *   Enumeration of all curve types present in fonts.
+   *
+   * @Fields:
+   *   SDF_EDGE_UNDEFINED ::
+   *     Undefined edge, simply used to initialize and detect errors.
+   *
+   *   SDF_EDGE_LINE ::
+   *     Line segment with start and end point.
+   *
+   *   SDF_EDGE_CONIC ::
+   *     A conic/quadratic Bezier curve with start, end, and one control
+   *     point.
+   *
+   *   SDF_EDGE_CUBIC ::
+   *     A cubic Bezier curve with start, end, and two control points.
+   *
+   */
+  typedef enum  SDF_Edge_Type_
+  {
+    SDF_EDGE_UNDEFINED = 0,
+    SDF_EDGE_LINE      = 1,
+    SDF_EDGE_CONIC     = 2,
+    SDF_EDGE_CUBIC     = 3
+
+  } SDF_Edge_Type;
+
+
+  /**************************************************************************
+   *
+   * @Enum:
+   *   SDF_Contour_Orientation
+   *
+   * @Description:
+   *   Enumeration of all orientation values of a contour.  We determine the
+   *   orientation by calculating the area covered by a contour.  Contrary
+   *   to values returned by @FT_Outline_Get_Orientation,
+   *   `SDF_Contour_Orientation` is independent of the fill rule, which can
+   *   be different for different font formats.
+   *
+   * @Fields:
+   *   SDF_ORIENTATION_NONE ::
+   *     Undefined orientation, used for initialization and error detection.
+   *
+   *   SDF_ORIENTATION_CW ::
+   *     Clockwise orientation (positive area covered).
+   *
+   *   SDF_ORIENTATION_CCW ::
+   *     Counter-clockwise orientation (negative area covered).
+   *
+   * @Note:
+   *   See @FT_Outline_Get_Orientation for more details.
+   *
+   */
+  typedef enum  SDF_Contour_Orientation_
+  {
+    SDF_ORIENTATION_NONE = 0,
+    SDF_ORIENTATION_CW   = 1,
+    SDF_ORIENTATION_CCW  = 2
+
+  } SDF_Contour_Orientation;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   SDF_Edge
+   *
+   * @Description:
+   *   Represent an edge of a contour.
+   *
+   * @Fields:
+   *   start_pos ::
+   *     Start position of an edge.  Valid for all types of edges.
+   *
+   *   end_pos ::
+   *     Etart position of an edge.  Valid for all types of edges.
+   *
+   *   control_a ::
+   *     A control point of the edge.  Valid only for `SDF_EDGE_CONIC`
+   *     and `SDF_EDGE_CUBIC`.
+   *
+   *   control_b ::
+   *     Another control point of the edge.  Valid only for
+   *     `SDF_EDGE_CONIC`.
+   *
+   *   edge_type ::
+   *     Type of the edge, see @SDF_Edge_Type for all possible edge types.
+   *
+   *   next ::
+   *     Used to create a singly linked list, which can be interpreted
+   *     as a contour.
+   *
+   */
+  typedef struct  SDF_Edge_
+  {
+    FT_26D6_Vec  start_pos;
+    FT_26D6_Vec  end_pos;
+    FT_26D6_Vec  control_a;
+    FT_26D6_Vec  control_b;
+
+    SDF_Edge_Type  edge_type;
+
+    struct SDF_Edge_*  next;
+
+  } SDF_Edge;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   SDF_Contour
+   *
+   * @Description:
+   *   Represent a complete contour, which contains a list of edges.
+   *
+   * @Fields:
+   *   last_pos ::
+   *     Contains the value of `end_pos' of the last edge in the list of
+   *     edges.  Useful while decomposing the outline with
+   *     @FT_Outline_Decompose.
+   *
+   *   edges ::
+   *     Linked list of all the edges that make the contour.
+   *
+   *   next ::
+   *     Used to create a singly linked list, which can be interpreted as a
+   *     complete shape or @FT_Outline.
+   *
+   */
+  typedef struct  SDF_Contour_
+  {
+    FT_26D6_Vec  last_pos;
+    SDF_Edge*    edges;
+
+    struct SDF_Contour_*  next;
+
+  } SDF_Contour;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   SDF_Shape
+   *
+   * @Description:
+   *   Represent a complete shape, which is the decomposition of
+   *   @FT_Outline.
+   *
+   * @Fields:
+   *   memory ::
+   *     Used internally to allocate memory.
+   *
+   *   contours ::
+   *     Linked list of all the contours that make the shape.
+   *
+   */
+  typedef struct  SDF_Shape_
+  {
+    FT_Memory     memory;
+    SDF_Contour*  contours;
+
+  } SDF_Shape;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   SDF_Signed_Distance
+   *
+   * @Description:
+   *   Represent signed distance of a point, i.e., the distance of the edge
+   *   nearest to the point.
+   *
+   * @Fields:
+   *   distance ::
+   *     Distance of the point from the nearest edge.  Can be squared or
+   *     absolute depending on the `USE_SQUARED_DISTANCES` macro defined in
+   *     file `ftsdfcommon.h`.
+   *
+   *   cross ::
+   *     Cross product of the shortest distance vector (i.e., the vector
+   *     from the point to the nearest edge) and the direction of the edge
+   *     at the nearest point.  This is used to resolve ambiguities of
+   *     `sign`.
+   *
+   *   sign ::
+   *     A value used to indicate whether the distance vector is outside or
+   *     inside the contour corresponding to the edge.
+   *
+   * @Note:
+   *   `sign` may or may not be correct, therefore it must be checked
+   *   properly in case there is an ambiguity.
+   *
+   */
+  typedef struct SDF_Signed_Distance_
+  {
+    FT_16D16  distance;
+    FT_16D16  cross;
+    FT_Char   sign;
+
+  } SDF_Signed_Distance;
+
+
+  /**************************************************************************
+   *
+   * @Struct:
+   *   SDF_Params
+   *
+   * @Description:
+   *   Yet another internal parameters required by the rasterizer.
+   *
+   * @Fields:
+   *   orientation ::
+   *     This is not the @SDF_Contour_Orientation value but @FT_Orientation,
+   *     which determines whether clockwise-oriented outlines are to be
+   *     filled or counter-clockwise-oriented ones.
+   *
+   *   flip_sign ::
+   *     If set to true, flip the sign.  By default the points filled by the
+   *     outline are positive.
+   *
+   *   flip_y ::
+   *     If set to true the output bitmap is upside-down.  Can be useful
+   *     because OpenGL and DirectX use different coordinate systems for
+   *     textures.
+   *
+   *   overload_sign ::
+   *     In the subdivision and bounding box optimization, the default
+   *     outside sign is taken as -1.  This parameter can be used to modify
+   *     that behaviour.  For example, while generating SDF for a single
+   *     counter-clockwise contour, the outside sign should be 1.
+   *
+   */
+  typedef struct SDF_Params_
+  {
+    FT_Orientation  orientation;
+    FT_Bool         flip_sign;
+    FT_Bool         flip_y;
+
+    FT_Int  overload_sign;
+
+  } SDF_Params;
+
+
+  /**************************************************************************
+   *
+   * constants, initializer, and destructor
+   *
+   */
+
+  static
+  const FT_Vector  zero_vector = { 0, 0 };
+
+  static
+  const SDF_Edge  null_edge = { { 0, 0 }, { 0, 0 },
+                                { 0, 0 }, { 0, 0 },
+                                SDF_EDGE_UNDEFINED, NULL };
+
+  static
+  const SDF_Contour  null_contour = { { 0, 0 }, NULL, NULL };
+
+  static
+  const SDF_Shape  null_shape = { NULL, NULL };
+
+  static
+  const SDF_Signed_Distance  max_sdf = { INT_MAX, 0, 0 };
+
+
+  /* Create a new @SDF_Edge on the heap and assigns the `edge` */
+  /* pointer to the newly allocated memory.                    */
+  static FT_Error
+  sdf_edge_new( FT_Memory   memory,
+                SDF_Edge**  edge )
+  {
+    FT_Error   error = FT_Err_Ok;
+    SDF_Edge*  ptr   = NULL;
+
+
+    if ( !memory || !edge )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( !FT_QNEW( ptr ) )
+    {
+      *ptr = null_edge;
+      *edge = ptr;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /* Free the allocated `edge` variable. */
+  static void
+  sdf_edge_done( FT_Memory   memory,
+                 SDF_Edge**  edge )
+  {
+    if ( !memory || !edge || !*edge )
+      return;
+
+    FT_FREE( *edge );
+  }
+
+
+  /* Create a new @SDF_Contour on the heap and assign     */
+  /* the `contour` pointer to the newly allocated memory. */
+  static FT_Error
+  sdf_contour_new( FT_Memory      memory,
+                   SDF_Contour**  contour )
+  {
+    FT_Error      error = FT_Err_Ok;
+    SDF_Contour*  ptr   = NULL;
+
+
+    if ( !memory || !contour )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( !FT_QNEW( ptr ) )
+    {
+      *ptr     = null_contour;
+      *contour = ptr;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /* Free the allocated `contour` variable. */
+  /* Also free the list of edges.           */
+  static void
+  sdf_contour_done( FT_Memory      memory,
+                    SDF_Contour**  contour )
+  {
+    SDF_Edge*  edges;
+    SDF_Edge*  temp;
+
+
+    if ( !memory || !contour || !*contour )
+      return;
+
+    edges = (*contour)->edges;
+
+    /* release all edges */
+    while ( edges )
+    {
+      temp  = edges;
+      edges = edges->next;
+
+      sdf_edge_done( memory, &temp );
+    }
+
+    FT_FREE( *contour );
+  }
+
+
+  /* Create a new @SDF_Shape on the heap and assign     */
+  /* the `shape` pointer to the newly allocated memory. */
+  static FT_Error
+  sdf_shape_new( FT_Memory    memory,
+                 SDF_Shape**  shape )
+  {
+    FT_Error    error = FT_Err_Ok;
+    SDF_Shape*  ptr   = NULL;
+
+
+    if ( !memory || !shape )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( !FT_QNEW( ptr ) )
+    {
+      *ptr        = null_shape;
+      ptr->memory = memory;
+      *shape      = ptr;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /* Free the allocated `shape` variable. */
+  /* Also free the list of contours.      */
+  static void
+  sdf_shape_done( SDF_Shape**  shape )
+  {
+    FT_Memory     memory;
+    SDF_Contour*  contours;
+    SDF_Contour*  temp;
+
+
+    if ( !shape || !*shape )
+      return;
+
+    memory   = (*shape)->memory;
+    contours = (*shape)->contours;
+
+    if ( !memory )
+      return;
+
+    /* release all contours */
+    while ( contours )
+    {
+      temp     = contours;
+      contours = contours->next;
+
+      sdf_contour_done( memory, &temp );
+    }
+
+    /* release the allocated shape struct  */
+    FT_FREE( *shape );
+  }
+
+
+  /**************************************************************************
+   *
+   * shape decomposition functions
+   *
+   */
+
+  /* This function is called when starting a new contour at `to`, */
+  /* which gets added to the shape's list.                        */
+  static FT_Error
+  sdf_move_to( const FT_26D6_Vec* to,
+               void*              user )
+  {
+    SDF_Shape*    shape   = ( SDF_Shape* )user;
+    SDF_Contour*  contour = NULL;
+
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = shape->memory;
+
+
+    if ( !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    FT_CALL( sdf_contour_new( memory, &contour ) );
+
+    contour->last_pos = *to;
+    contour->next     = shape->contours;
+    shape->contours   = contour;
+
+  Exit:
+    return error;
+  }
+
+
+  /* This function is called when there is a line in the      */
+  /* contour.  The line starts at the previous edge point and */
+  /* stops at `to`.                                           */
+  static FT_Error
+  sdf_line_to( const FT_26D6_Vec*  to,
+               void*               user )
+  {
+    SDF_Shape*    shape    = ( SDF_Shape* )user;
+    SDF_Edge*     edge     = NULL;
+    SDF_Contour*  contour  = NULL;
+
+    FT_Error      error    = FT_Err_Ok;
+    FT_Memory     memory   = shape->memory;
+
+
+    if ( !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contour = shape->contours;
+
+    if ( contour->last_pos.x == to->x &&
+         contour->last_pos.y == to->y )
+      goto Exit;
+
+    FT_CALL( sdf_edge_new( memory, &edge ) );
+
+    edge->edge_type = SDF_EDGE_LINE;
+    edge->start_pos = contour->last_pos;
+    edge->end_pos   = *to;
+
+    edge->next        = contour->edges;
+    contour->edges    = edge;
+    contour->last_pos = *to;
+
+  Exit:
+    return error;
+  }
+
+
+  /* This function is called when there is a conic Bezier curve   */
+  /* in the contour.  The curve starts at the previous edge point */
+  /* and stops at `to`, with control point `control_1`.           */
+  static FT_Error
+  sdf_conic_to( const FT_26D6_Vec*  control_1,
+                const FT_26D6_Vec*  to,
+                void*               user )
+  {
+    SDF_Shape*    shape    = ( SDF_Shape* )user;
+    SDF_Edge*     edge     = NULL;
+    SDF_Contour*  contour  = NULL;
+
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = shape->memory;
+
+
+    if ( !control_1 || !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contour = shape->contours;
+
+    /* If the control point coincides with any of the end points */
+    /* then it is a line and should be treated as one to avoid   */
+    /* unnecessary complexity later in the algorithm.            */
+    if ( ( contour->last_pos.x == control_1->x &&
+           contour->last_pos.y == control_1->y ) ||
+         ( control_1->x == to->x &&
+           control_1->y == to->y )               )
+    {
+      sdf_line_to( to, user );
+      goto Exit;
+    }
+
+    FT_CALL( sdf_edge_new( memory, &edge ) );
+
+    edge->edge_type = SDF_EDGE_CONIC;
+    edge->start_pos = contour->last_pos;
+    edge->control_a = *control_1;
+    edge->end_pos   = *to;
+
+    edge->next        = contour->edges;
+    contour->edges    = edge;
+    contour->last_pos = *to;
+
+  Exit:
+    return error;
+  }
+
+
+  /* This function is called when there is a cubic Bezier curve   */
+  /* in the contour.  The curve starts at the previous edge point */
+  /* and stops at `to`, with two control points `control_1` and   */
+  /* `control_2`.                                                 */
+  static FT_Error
+  sdf_cubic_to( const FT_26D6_Vec*  control_1,
+                const FT_26D6_Vec*  control_2,
+                const FT_26D6_Vec*  to,
+                void*               user )
+  {
+    SDF_Shape*    shape   = ( SDF_Shape* )user;
+    SDF_Edge*     edge    = NULL;
+    SDF_Contour*  contour = NULL;
+
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = shape->memory;
+
+
+    if ( !control_2 || !control_1 || !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contour = shape->contours;
+
+    FT_CALL( sdf_edge_new( memory, &edge ) );
+
+    edge->edge_type = SDF_EDGE_CUBIC;
+    edge->start_pos = contour->last_pos;
+    edge->control_a = *control_1;
+    edge->control_b = *control_2;
+    edge->end_pos   = *to;
+
+    edge->next        = contour->edges;
+    contour->edges    = edge;
+    contour->last_pos = *to;
+
+  Exit:
+    return error;
+  }
+
+
+  /* Construct the structure to hold all four outline */
+  /* decomposition functions.                         */
+  FT_DEFINE_OUTLINE_FUNCS(
+    sdf_decompose_funcs,
+
+    (FT_Outline_MoveTo_Func) sdf_move_to,   /* move_to  */
+    (FT_Outline_LineTo_Func) sdf_line_to,   /* line_to  */
+    (FT_Outline_ConicTo_Func)sdf_conic_to,  /* conic_to */
+    (FT_Outline_CubicTo_Func)sdf_cubic_to,  /* cubic_to */
+
+    0,                                      /* shift    */
+    0                                       /* delta    */
+  )
+
+
+  /* Decompose `outline` and put it into the `shape` structure.  */
+  static FT_Error
+  sdf_outline_decompose( FT_Outline*  outline,
+                         SDF_Shape*   shape )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( !outline || !shape )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    error = FT_Outline_Decompose( outline,
+                                  &sdf_decompose_funcs,
+                                  (void*)shape );
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * utility functions
+   *
+   */
+
+  /* Return the control box of an edge.  The control box is a rectangle */
+  /* in which all the control points can fit tightly.                   */
+  static FT_CBox
+  get_control_box( SDF_Edge  edge )
+  {
+    FT_CBox  cbox   = { 0, 0, 0, 0 };
+    FT_Bool  is_set = 0;
+
+
+    switch ( edge.edge_type )
+    {
+    case SDF_EDGE_CUBIC:
+      cbox.xMin = edge.control_b.x;
+      cbox.xMax = edge.control_b.x;
+      cbox.yMin = edge.control_b.y;
+      cbox.yMax = edge.control_b.y;
+
+      is_set = 1;
+      FALL_THROUGH;
+
+    case SDF_EDGE_CONIC:
+      if ( is_set )
+      {
+        cbox.xMin = edge.control_a.x < cbox.xMin
+                    ? edge.control_a.x
+                    : cbox.xMin;
+        cbox.xMax = edge.control_a.x > cbox.xMax
+                    ? edge.control_a.x
+                    : cbox.xMax;
+
+        cbox.yMin = edge.control_a.y < cbox.yMin
+                    ? edge.control_a.y
+                    : cbox.yMin;
+        cbox.yMax = edge.control_a.y > cbox.yMax
+                    ? edge.control_a.y
+                    : cbox.yMax;
+      }
+      else
+      {
+        cbox.xMin = edge.control_a.x;
+        cbox.xMax = edge.control_a.x;
+        cbox.yMin = edge.control_a.y;
+        cbox.yMax = edge.control_a.y;
+
+        is_set = 1;
+      }
+      FALL_THROUGH;
+
+    case SDF_EDGE_LINE:
+      if ( is_set )
+      {
+        cbox.xMin = edge.start_pos.x < cbox.xMin
+                    ? edge.start_pos.x
+                    : cbox.xMin;
+        cbox.xMax = edge.start_pos.x > cbox.xMax
+                    ? edge.start_pos.x
+                    : cbox.xMax;
+
+        cbox.yMin = edge.start_pos.y < cbox.yMin
+                    ? edge.start_pos.y
+                    : cbox.yMin;
+        cbox.yMax = edge.start_pos.y > cbox.yMax
+                    ? edge.start_pos.y
+                    : cbox.yMax;
+      }
+      else
+      {
+        cbox.xMin = edge.start_pos.x;
+        cbox.xMax = edge.start_pos.x;
+        cbox.yMin = edge.start_pos.y;
+        cbox.yMax = edge.start_pos.y;
+      }
+
+      cbox.xMin = edge.end_pos.x < cbox.xMin
+                  ? edge.end_pos.x
+                  : cbox.xMin;
+      cbox.xMax = edge.end_pos.x > cbox.xMax
+                  ? edge.end_pos.x
+                  : cbox.xMax;
+
+      cbox.yMin = edge.end_pos.y < cbox.yMin
+                  ? edge.end_pos.y
+                  : cbox.yMin;
+      cbox.yMax = edge.end_pos.y > cbox.yMax
+                  ? edge.end_pos.y
+                  : cbox.yMax;
+
+      break;
+
+    default:
+      break;
+    }
+
+    return cbox;
+  }
+
+
+  /* Return orientation of a single contour.                    */
+  /* Note that the orientation is independent of the fill rule! */
+  /* So, for TTF a clockwise-oriented contour has to be filled  */
+  /* and the opposite for OTF fonts.                            */
+  static SDF_Contour_Orientation
+  get_contour_orientation ( SDF_Contour*  contour )
+  {
+    SDF_Edge*  head = NULL;
+    FT_26D6    area = 0;
+
+
+    /* return none if invalid parameters */
+    if ( !contour || !contour->edges )
+      return SDF_ORIENTATION_NONE;
+
+    head = contour->edges;
+
+    /* Calculate the area of the control box for all edges. */
+    while ( head )
+    {
+      switch ( head->edge_type )
+      {
+      case SDF_EDGE_LINE:
+        area += MUL_26D6( ( head->end_pos.x - head->start_pos.x ),
+                          ( head->end_pos.y + head->start_pos.y ) );
+        break;
+
+      case SDF_EDGE_CONIC:
+        area += MUL_26D6( head->control_a.x - head->start_pos.x,
+                          head->control_a.y + head->start_pos.y );
+        area += MUL_26D6( head->end_pos.x - head->control_a.x,
+                          head->end_pos.y + head->control_a.y );
+        break;
+
+      case SDF_EDGE_CUBIC:
+        area += MUL_26D6( head->control_a.x - head->start_pos.x,
+                          head->control_a.y + head->start_pos.y );
+        area += MUL_26D6( head->control_b.x - head->control_a.x,
+                          head->control_b.y + head->control_a.y );
+        area += MUL_26D6( head->end_pos.x - head->control_b.x,
+                          head->end_pos.y + head->control_b.y );
+        break;
+
+      default:
+        return SDF_ORIENTATION_NONE;
+      }
+
+      head = head->next;
+    }
+
+    /* Clockwise contours cover a positive area, and counter-clockwise */
+    /* contours cover a negative area.                                 */
+    if ( area > 0 )
+      return SDF_ORIENTATION_CW;
+    else
+      return SDF_ORIENTATION_CCW;
+  }
+
+
+  /* This function is exactly the same as the one */
+  /* in the smooth renderer.  It splits a conic   */
+  /* into two conics exactly half way at t = 0.5. */
+  static void
+  split_conic( FT_26D6_Vec*  base )
+  {
+    FT_26D6  a, b;
+
+
+    base[4].x = base[2].x;
+    a         = base[0].x + base[1].x;
+    b         = base[1].x + base[2].x;
+    base[3].x = b / 2;
+    base[2].x = ( a + b ) / 4;
+    base[1].x = a / 2;
+
+    base[4].y = base[2].y;
+    a         = base[0].y + base[1].y;
+    b         = base[1].y + base[2].y;
+    base[3].y = b / 2;
+    base[2].y = ( a + b ) / 4;
+    base[1].y = a / 2;
+  }
+
+
+  /* This function is exactly the same as the one */
+  /* in the smooth renderer.  It splits a cubic   */
+  /* into two cubics exactly half way at t = 0.5. */
+  static void
+  split_cubic( FT_26D6_Vec*  base )
+  {
+    FT_26D6  a, b, c;
+
+
+    base[6].x = base[3].x;
+    a         = base[0].x + base[1].x;
+    b         = base[1].x + base[2].x;
+    c         = base[2].x + base[3].x;
+    base[5].x = c / 2;
+    c        += b;
+    base[4].x = c / 4;
+    base[1].x = a / 2;
+    a        += b;
+    base[2].x = a / 4;
+    base[3].x = ( a + c ) / 8;
+
+    base[6].y = base[3].y;
+    a         = base[0].y + base[1].y;
+    b         = base[1].y + base[2].y;
+    c         = base[2].y + base[3].y;
+    base[5].y = c / 2;
+    c        += b;
+    base[4].y = c / 4;
+    base[1].y = a / 2;
+    a        += b;
+    base[2].y = a / 4;
+    base[3].y = ( a + c ) / 8;
+  }
+
+
+  /* Split a conic Bezier curve into a number of lines */
+  /* and add them to `out'.                            */
+  /*                                                   */
+  /* This function uses recursion; we thus need        */
+  /* parameter `max_splits' for stopping.              */
+  static FT_Error
+  split_sdf_conic( FT_Memory     memory,
+                   FT_26D6_Vec*  control_points,
+                   FT_UInt       max_splits,
+                   SDF_Edge**    out )
+  {
+    FT_Error     error = FT_Err_Ok;
+    FT_26D6_Vec  cpos[5];
+    SDF_Edge*    left,*  right;
+
+
+    if ( !memory || !out  )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* split conic outline */
+    cpos[0] = control_points[0];
+    cpos[1] = control_points[1];
+    cpos[2] = control_points[2];
+
+    split_conic( cpos );
+
+    /* If max number of splits is done */
+    /* then stop and add the lines to  */
+    /* the list.                       */
+    if ( max_splits <= 2 )
+      goto Append;
+
+    /* Otherwise keep splitting. */
+    FT_CALL( split_sdf_conic( memory, &cpos[0], max_splits / 2, out ) );
+    FT_CALL( split_sdf_conic( memory, &cpos[2], max_splits / 2, out ) );
+
+    /* [NOTE]: This is not an efficient way of   */
+    /* splitting the curve.  Check the deviation */
+    /* instead and stop if the deviation is less */
+    /* than a pixel.                             */
+
+    goto Exit;
+
+  Append:
+    /* Do allocation and add the lines to the list. */
+
+    FT_CALL( sdf_edge_new( memory, &left ) );
+    FT_CALL( sdf_edge_new( memory, &right ) );
+
+    left->start_pos  = cpos[0];
+    left->end_pos    = cpos[2];
+    left->edge_type  = SDF_EDGE_LINE;
+
+    right->start_pos = cpos[2];
+    right->end_pos   = cpos[4];
+    right->edge_type = SDF_EDGE_LINE;
+
+    left->next  = right;
+    right->next = (*out);
+    *out        = left;
+
+  Exit:
+    return error;
+  }
+
+
+  /* Split a cubic Bezier curve into a number of lines */
+  /* and add them to `out`.                            */
+  /*                                                   */
+  /* This function uses recursion; we thus need        */
+  /* parameter `max_splits' for stopping.              */
+  static FT_Error
+  split_sdf_cubic( FT_Memory     memory,
+                   FT_26D6_Vec*  control_points,
+                   FT_UInt       max_splits,
+                   SDF_Edge**    out )
+  {
+    FT_Error       error = FT_Err_Ok;
+    FT_26D6_Vec    cpos[7];
+    SDF_Edge*      left, *right;
+    const FT_26D6  threshold = ONE_PIXEL / 4;
+
+
+    if ( !memory || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* split the cubic */
+    cpos[0] = control_points[0];
+    cpos[1] = control_points[1];
+    cpos[2] = control_points[2];
+    cpos[3] = control_points[3];
+
+    /* If the segment is flat enough we won't get any benefit by */
+    /* splitting it further, so we can just stop splitting.      */
+    /*                                                           */
+    /* Check the deviation of the Bezier curve and stop if it is */
+    /* smaller than the pre-defined `threshold` value.           */
+    if ( FT_ABS( 2 * cpos[0].x - 3 * cpos[1].x + cpos[3].x ) < threshold &&
+         FT_ABS( 2 * cpos[0].y - 3 * cpos[1].y + cpos[3].y ) < threshold &&
+         FT_ABS( cpos[0].x - 3 * cpos[2].x + 2 * cpos[3].x ) < threshold &&
+         FT_ABS( cpos[0].y - 3 * cpos[2].y + 2 * cpos[3].y ) < threshold )
+    {
+      split_cubic( cpos );
+      goto Append;
+    }
+
+    split_cubic( cpos );
+
+    /* If max number of splits is done */
+    /* then stop and add the lines to  */
+    /* the list.                       */
+    if ( max_splits <= 2 )
+      goto Append;
+
+    /* Otherwise keep splitting. */
+    FT_CALL( split_sdf_cubic( memory, &cpos[0], max_splits / 2, out ) );
+    FT_CALL( split_sdf_cubic( memory, &cpos[3], max_splits / 2, out ) );
+
+    /* [NOTE]: This is not an efficient way of   */
+    /* splitting the curve.  Check the deviation */
+    /* instead and stop if the deviation is less */
+    /* than a pixel.                             */
+
+    goto Exit;
+
+  Append:
+    /* Do allocation and add the lines to the list. */
+
+    FT_CALL( sdf_edge_new( memory, &left) );
+    FT_CALL( sdf_edge_new( memory, &right) );
+
+    left->start_pos  = cpos[0];
+    left->end_pos    = cpos[3];
+    left->edge_type  = SDF_EDGE_LINE;
+
+    right->start_pos = cpos[3];
+    right->end_pos   = cpos[6];
+    right->edge_type = SDF_EDGE_LINE;
+
+    left->next  = right;
+    right->next = (*out);
+    *out        = left;
+
+  Exit:
+    return error;
+  }
+
+
+  /* Subdivide an entire shape into line segments */
+  /* such that it doesn't look visually different */
+  /* from the original curve.                     */
+  static FT_Error
+  split_sdf_shape( SDF_Shape*  shape )
+  {
+    FT_Error   error = FT_Err_Ok;
+    FT_Memory  memory;
+
+    SDF_Contour*  contours;
+    SDF_Contour*  new_contours = NULL;
+
+
+    if ( !shape || !shape->memory )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contours = shape->contours;
+    memory   = shape->memory;
+
+    /* for each contour */
+    while ( contours )
+    {
+      SDF_Edge*  edges     = contours->edges;
+      SDF_Edge*  new_edges = NULL;
+
+      SDF_Contour*  tempc;
+
+
+      /* for each edge */
+      while ( edges )
+      {
+        SDF_Edge*  edge = edges;
+        SDF_Edge*  temp;
+
+        switch ( edge->edge_type )
+        {
+        case SDF_EDGE_LINE:
+          /* Just create a duplicate edge in case     */
+          /* it is a line.  We can use the same edge. */
+          FT_CALL( sdf_edge_new( memory, &temp ) );
+
+          ft_memcpy( temp, edge, sizeof ( *edge ) );
+
+          temp->next = new_edges;
+          new_edges  = temp;
+          break;
+
+        case SDF_EDGE_CONIC:
+          /* Subdivide the curve and add it to the list. */
+          {
+            FT_26D6_Vec  ctrls[3];
+            FT_26D6      dx, dy;
+            FT_UInt      num_splits;
+
+
+            ctrls[0] = edge->start_pos;
+            ctrls[1] = edge->control_a;
+            ctrls[2] = edge->end_pos;
+
+            dx = FT_ABS( ctrls[2].x + ctrls[0].x - 2 * ctrls[1].x );
+            dy = FT_ABS( ctrls[2].y + ctrls[0].y - 2 * ctrls[1].y );
+            if ( dx < dy )
+              dx = dy;
+
+            /* Calculate the number of necessary bisections.  Each      */
+            /* bisection causes a four-fold reduction of the deviation, */
+            /* hence we bisect the Bezier curve until the deviation     */
+            /* becomes less than 1/8 of a pixel.  For more details      */
+            /* check file `ftgrays.c`.                                  */
+            num_splits = 1;
+            while ( dx > ONE_PIXEL / 8 )
+            {
+              dx         >>= 2;
+              num_splits <<= 1;
+            }
+
+            error = split_sdf_conic( memory, ctrls, num_splits, &new_edges );
+          }
+          break;
+
+        case SDF_EDGE_CUBIC:
+          /* Subdivide the curve and add it to the list. */
+          {
+            FT_26D6_Vec  ctrls[4];
+
+
+            ctrls[0] = edge->start_pos;
+            ctrls[1] = edge->control_a;
+            ctrls[2] = edge->control_b;
+            ctrls[3] = edge->end_pos;
+
+            error = split_sdf_cubic( memory, ctrls, 32, &new_edges );
+          }
+          break;
+
+        default:
+          error = FT_THROW( Invalid_Argument );
+        }
+
+        if ( error != FT_Err_Ok )
+          goto Exit;
+
+        edges = edges->next;
+      }
+
+      /* add to the contours list */
+      FT_CALL( sdf_contour_new( memory, &tempc ) );
+
+      tempc->next  = new_contours;
+      tempc->edges = new_edges;
+      new_contours = tempc;
+      new_edges    = NULL;
+
+      /* deallocate the contour */
+      tempc    = contours;
+      contours = contours->next;
+
+      sdf_contour_done( memory, &tempc );
+    }
+
+    shape->contours = new_contours;
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * for debugging
+   *
+   */
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+  static void
+  sdf_shape_dump( SDF_Shape*  shape )
+  {
+    FT_UInt  num_contours = 0;
+
+    FT_UInt  total_edges = 0;
+    FT_UInt  total_lines = 0;
+    FT_UInt  total_conic = 0;
+    FT_UInt  total_cubic = 0;
+
+    SDF_Contour*  contour_list;
+
+
+    if ( !shape )
+    {
+      FT_TRACE5(( "sdf_shape_dump: null shape\n" ));
+      return;
+    }
+
+    contour_list = shape->contours;
+
+    FT_TRACE5(( "sdf_shape_dump (values are in 26.6 format):\n" ));
+
+    while ( contour_list )
+    {
+      FT_UInt       num_edges = 0;
+      SDF_Edge*     edge_list;
+      SDF_Contour*  contour = contour_list;
+
+
+      FT_TRACE5(( "  Contour %d\n", num_contours ));
+
+      edge_list = contour->edges;
+
+      while ( edge_list )
+      {
+        SDF_Edge*  edge = edge_list;
+
+
+        FT_TRACE5(( "  %3d: ", num_edges ));
+
+        switch ( edge->edge_type )
+        {
+        case SDF_EDGE_LINE:
+          FT_TRACE5(( "Line:  (%ld, %ld) -- (%ld, %ld)\n",
+                      edge->start_pos.x, edge->start_pos.y,
+                      edge->end_pos.x, edge->end_pos.y ));
+          total_lines++;
+          break;
+
+        case SDF_EDGE_CONIC:
+          FT_TRACE5(( "Conic: (%ld, %ld) .. (%ld, %ld) .. (%ld, %ld)\n",
+                      edge->start_pos.x, edge->start_pos.y,
+                      edge->control_a.x, edge->control_a.y,
+                      edge->end_pos.x, edge->end_pos.y ));
+          total_conic++;
+          break;
+
+        case SDF_EDGE_CUBIC:
+          FT_TRACE5(( "Cubic: (%ld, %ld) .. (%ld, %ld)"
+                      " .. (%ld, %ld) .. (%ld %ld)\n",
+                      edge->start_pos.x, edge->start_pos.y,
+                      edge->control_a.x, edge->control_a.y,
+                      edge->control_b.x, edge->control_b.y,
+                      edge->end_pos.x, edge->end_pos.y ));
+          total_cubic++;
+          break;
+
+        default:
+          break;
+        }
+
+        num_edges++;
+        total_edges++;
+        edge_list = edge_list->next;
+      }
+
+      num_contours++;
+      contour_list = contour_list->next;
+    }
+
+    FT_TRACE5(( "\n" ));
+    FT_TRACE5(( "  total number of contours = %d\n", num_contours ));
+    FT_TRACE5(( "  total number of edges    = %d\n", total_edges ));
+    FT_TRACE5(( "    |__lines = %d\n", total_lines ));
+    FT_TRACE5(( "    |__conic = %d\n", total_conic ));
+    FT_TRACE5(( "    |__cubic = %d\n", total_cubic ));
+  }
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+
+  /**************************************************************************
+   *
+   * math functions
+   *
+   */
+
+#if !USE_NEWTON_FOR_CONIC
+
+  /* [NOTE]: All the functions below down until rasterizer */
+  /*         can be avoided if we decide to subdivide the  */
+  /*         curve into lines.                             */
+
+  /* This function uses Newton's iteration to find */
+  /* the cube root of a fixed-point integer.       */
+  static FT_16D16
+  cube_root( FT_16D16  val )
+  {
+    /* [IMPORTANT]: This function is not good as it may */
+    /* not break, so use a lookup table instead.  Or we */
+    /* can use an algorithm similar to `square_root`.   */
+
+    FT_Int  v, g, c;
+
+
+    if ( val == 0                  ||
+         val == -FT_INT_16D16( 1 ) ||
+         val ==  FT_INT_16D16( 1 ) )
+      return val;
+
+    v = val < 0 ? -val : val;
+    g = square_root( v );
+    c = 0;
+
+    while ( 1 )
+    {
+      c = FT_MulFix( FT_MulFix( g, g ), g ) - v;
+      c = FT_DivFix( c, 3 * FT_MulFix( g, g ) );
+
+      g -= c;
+
+      if ( ( c < 0 ? -c : c ) < 30 )
+        break;
+    }
+
+    return val < 0 ? -g : g;
+  }
+
+
+  /* Calculate the perpendicular by using '1 - base^2'. */
+  /* Then use arctan to compute the angle.              */
+  static FT_16D16
+  arc_cos( FT_16D16  val )
+  {
+    FT_16D16  p;
+    FT_16D16  b   = val;
+    FT_16D16  one = FT_INT_16D16( 1 );
+
+
+    if ( b > one )
+      b = one;
+    if ( b < -one )
+      b = -one;
+
+    p = one - FT_MulFix( b, b );
+    p = square_root( p );
+
+    return FT_Atan2( b, p );
+  }
+
+
+  /* Compute roots of a quadratic polynomial, assign them to `out`, */
+  /* and return number of real roots.                               */
+  /*                                                                */
+  /* The procedure can be found at                                  */
+  /*                                                                */
+  /*   https://mathworld.wolfram.com/QuadraticFormula.html          */
+  static FT_UShort
+  solve_quadratic_equation( FT_26D6   a,
+                            FT_26D6   b,
+                            FT_26D6   c,
+                            FT_16D16  out[2] )
+  {
+    FT_16D16  discriminant = 0;
+
+
+    a = FT_26D6_16D16( a );
+    b = FT_26D6_16D16( b );
+    c = FT_26D6_16D16( c );
+
+    if ( a == 0 )
+    {
+      if ( b == 0 )
+        return 0;
+      else
+      {
+        out[0] = FT_DivFix( -c, b );
+
+        return 1;
+      }
+    }
+
+    discriminant = FT_MulFix( b, b ) - 4 * FT_MulFix( a, c );
+
+    if ( discriminant < 0 )
+      return 0;
+    else if ( discriminant == 0 )
+    {
+      out[0] = FT_DivFix( -b, 2 * a );
+
+      return 1;
+    }
+    else
+    {
+      discriminant = square_root( discriminant );
+
+      out[0] = FT_DivFix( -b + discriminant, 2 * a );
+      out[1] = FT_DivFix( -b - discriminant, 2 * a );
+
+      return 2;
+    }
+  }
+
+
+  /* Compute roots of a cubic polynomial, assign them to `out`, */
+  /* and return number of real roots.                           */
+  /*                                                            */
+  /* The procedure can be found at                              */
+  /*                                                            */
+  /*   https://mathworld.wolfram.com/CubicFormula.html          */
+  static FT_UShort
+  solve_cubic_equation( FT_26D6   a,
+                        FT_26D6   b,
+                        FT_26D6   c,
+                        FT_26D6   d,
+                        FT_16D16  out[3] )
+  {
+    FT_16D16  q = 0;      /* intermediate */
+    FT_16D16  r = 0;      /* intermediate */
+
+    FT_16D16  a2 = b;     /* x^2 coefficients */
+    FT_16D16  a1 = c;     /* x coefficients   */
+    FT_16D16  a0 = d;     /* constant         */
+
+    FT_16D16  q3   = 0;
+    FT_16D16  r2   = 0;
+    FT_16D16  a23  = 0;
+    FT_16D16  a22  = 0;
+    FT_16D16  a1x2 = 0;
+
+
+    /* cutoff value for `a` to be a cubic, otherwise solve quadratic */
+    if ( a == 0 || FT_ABS( a ) < 16 )
+      return solve_quadratic_equation( b, c, d, out );
+
+    if ( d == 0 )
+    {
+      out[0] = 0;
+
+      return solve_quadratic_equation( a, b, c, out + 1 ) + 1;
+    }
+
+    /* normalize the coefficients; this also makes them 16.16 */
+    a2 = FT_DivFix( a2, a );
+    a1 = FT_DivFix( a1, a );
+    a0 = FT_DivFix( a0, a );
+
+    /* compute intermediates */
+    a1x2 = FT_MulFix( a1, a2 );
+    a22  = FT_MulFix( a2, a2 );
+    a23  = FT_MulFix( a22, a2 );
+
+    q = ( 3 * a1 - a22 ) / 9;
+    r = ( 9 * a1x2 - 27 * a0 - 2 * a23 ) / 54;
+
+    /* [BUG]: `q3` and `r2` still cause underflow. */
+
+    q3 = FT_MulFix( q, q );
+    q3 = FT_MulFix( q3, q );
+
+    r2 = FT_MulFix( r, r );
+
+    if ( q3 < 0 && r2 < -q3 )
+    {
+      FT_16D16  t = 0;
+
+
+      q3 = square_root( -q3 );
+      t  = FT_DivFix( r, q3 );
+
+      if ( t > ( 1 << 16 ) )
+        t =  ( 1 << 16 );
+      if ( t < -( 1 << 16 ) )
+        t = -( 1 << 16 );
+
+      t   = arc_cos( t );
+      a2 /= 3;
+      q   = 2 * square_root( -q );
+
+      out[0] = FT_MulFix( q, FT_Cos( t / 3 ) ) - a2;
+      out[1] = FT_MulFix( q, FT_Cos( ( t + FT_ANGLE_PI * 2 ) / 3 ) ) - a2;
+      out[2] = FT_MulFix( q, FT_Cos( ( t + FT_ANGLE_PI * 4 ) / 3 ) ) - a2;
+
+      return 3;
+    }
+
+    else if ( r2 == -q3 )
+    {
+      FT_16D16  s = 0;
+
+
+      s   = cube_root( r );
+      a2 /= -3;
+
+      out[0] = a2 + ( 2 * s );
+      out[1] = a2 - s;
+
+      return 2;
+    }
+
+    else
+    {
+      FT_16D16  s    = 0;
+      FT_16D16  t    = 0;
+      FT_16D16  dis  = 0;
+
+
+      if ( q3 == 0 )
+        dis = FT_ABS( r );
+      else
+        dis = square_root( q3 + r2 );
+
+      s = cube_root( r + dis );
+      t = cube_root( r - dis );
+      a2 /= -3;
+      out[0] = ( a2 + ( s + t ) );
+
+      return 1;
+    }
+  }
+
+#endif /* !USE_NEWTON_FOR_CONIC */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  RASTERIZER                                                         **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   resolve_corner
+   *
+   * @Description:
+   *   At some places on the grid two edges can give opposite directions;
+   *   this happens when the closest point is on one of the endpoint.  In
+   *   that case we need to check the proper sign.
+   *
+   *   This can be visualized by an example:
+   *
+   *   ```
+   *                x
+   *
+   *                   o
+   *                  ^ \
+   *                 /   \
+   *                /     \
+   *           (a) /       \  (b)
+   *              /         \
+   *             /           \
+   *            /             v
+   *   ```
+   *
+   *   Suppose `x` is the point whose shortest distance from an arbitrary
+   *   contour we want to find out.  It is clear that `o` is the nearest
+   *   point on the contour.  Now to determine the sign we do a cross
+   *   product of the shortest distance vector and the edge direction, i.e.,
+   *
+   *   ```
+   *   => sign = cross(x - o, direction(a))
+   *   ```
+   *
+   *   Using the right hand thumb rule we can see that the sign will be
+   *   positive.
+   *
+   *   If we use `b', however, we have
+   *
+   *   ```
+   *   => sign = cross(x - o, direction(b))
+   *   ```
+   *
+   *   In this case the sign will be negative.  To determine the correct
+   *   sign we thus divide the plane in two halves and check which plane the
+   *   point lies in.
+   *
+   *   ```
+   *                   |
+   *                x  |
+   *                   |
+   *                   o
+   *                  ^|\
+   *                 / | \
+   *                /  |  \
+   *           (a) /   |   \  (b)
+   *              /    |    \
+   *             /           \
+   *            /             v
+   *   ```
+   *
+   *   We can see that `x` lies in the plane of `a`, so we take the sign
+   *   determined by `a`.  This test can be easily done by calculating the
+   *   orthogonality and taking the greater one.
+   *
+   *   The orthogonality is simply the sinus of the two vectors (i.e.,
+   *   x - o) and the corresponding direction.  We efficiently pre-compute
+   *   the orthogonality with the corresponding `get_min_distance_*`
+   *   functions.
+   *
+   * @Input:
+   *   sdf1 ::
+   *     First signed distance (can be any of `a` or `b`).
+   *
+   *   sdf1 ::
+   *     Second signed distance (can be any of `a` or `b`).
+   *
+   * @Return:
+   *   The correct signed distance, which is computed by using the above
+   *   algorithm.
+   *
+   * @Note:
+   *   The function does not care about the actual distance, it simply
+   *   returns the signed distance which has a larger cross product.  As a
+   *   consequence, this function should not be used if the two distances
+   *   are fairly apart.  In that case simply use the signed distance with
+   *   a shorter absolute distance.
+   *
+   */
+  static SDF_Signed_Distance
+  resolve_corner( SDF_Signed_Distance  sdf1,
+                  SDF_Signed_Distance  sdf2 )
+  {
+    return FT_ABS( sdf1.cross ) > FT_ABS( sdf2.cross ) ? sdf1 : sdf2;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   get_min_distance_line
+   *
+   * @Description:
+   *   Find the shortest distance from the `line` segment to a given `point`
+   *   and assign it to `out`.  Use it for line segments only.
+   *
+   * @Input:
+   *   line ::
+   *     The line segment to which the shortest distance is to be computed.
+   *
+   *   point ::
+   *     Point from which the shortest distance is to be computed.
+   *
+   * @Output:
+   *   out ::
+   *     Signed distance from `point` to `line`.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   * @Note:
+   *   The `line' parameter must have an edge type of `SDF_EDGE_LINE`.
+   *
+   */
+  static FT_Error
+  get_min_distance_line( SDF_Edge*             line,
+                         FT_26D6_Vec           point,
+                         SDF_Signed_Distance*  out )
+  {
+    /*
+     * In order to calculate the shortest distance from a point to
+     * a line segment, we do the following.  Let's assume that
+     *
+     * ```
+     * a = start point of the line segment
+     * b = end point of the line segment
+     * p = point from which shortest distance is to be calculated
+     * ```
+     *
+     * (1) Write the parametric equation of the line.
+     *
+     *     ```
+     *     point_on_line = a + (b - a) * t   (t is the factor)
+     *     ```
+     *
+     * (2) Find the projection of point `p` on the line.  The projection
+     *     will be perpendicular to the line, which allows us to get the
+     *     solution by making the dot product zero.
+     *
+     *     ```
+     *     (point_on_line - a) . (p - point_on_line) = 0
+     *
+     *                (point_on_line)
+     *      (a) x-------o----------------x (b)
+     *                |_|
+     *                  |
+     *                  |
+     *                 (p)
+     *     ```
+     *
+     * (3) Simplification of the above equation yields the factor of
+     *     `point_on_line`:
+     *
+     *     ```
+     *     t = ((p - a) . (b - a)) / |b - a|^2
+     *     ```
+     *
+     * (4) We clamp factor `t` between [0.0f, 1.0f] because `point_on_line`
+     *     can be outside of the line segment:
+     *
+     *     ```
+     *                                          (point_on_line)
+     *     (a) x------------------------x (b) -----o---
+     *                                           |_|
+     *                                             |
+     *                                             |
+     *                                            (p)
+     *     ```
+     *
+     * (5) Finally, the distance we are interested in is
+     *
+     *     ```
+     *     |point_on_line - p|
+     *     ```
+     */
+
+    FT_Error  error = FT_Err_Ok;
+
+    FT_Vector  a;                   /* start position */
+    FT_Vector  b;                   /* end position   */
+    FT_Vector  p;                   /* current point  */
+
+    FT_26D6_Vec  line_segment;      /* `b` - `a` */
+    FT_26D6_Vec  p_sub_a;           /* `p` - `a` */
+
+    FT_26D6   sq_line_length;       /* squared length of `line_segment` */
+    FT_16D16  factor;               /* factor of the nearest point      */
+    FT_26D6   cross;                /* used to determine sign           */
+
+    FT_16D16_Vec  nearest_point;    /* `point_on_line`       */
+    FT_16D16_Vec  nearest_vector;   /* `p` - `nearest_point` */
+
+
+    if ( !line || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( line->edge_type != SDF_EDGE_LINE )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    a = line->start_pos;
+    b = line->end_pos;
+    p = point;
+
+    line_segment.x = b.x - a.x;
+    line_segment.y = b.y - a.y;
+
+    p_sub_a.x = p.x - a.x;
+    p_sub_a.y = p.y - a.y;
+
+    sq_line_length = ( line_segment.x * line_segment.x ) / 64 +
+                     ( line_segment.y * line_segment.y ) / 64;
+
+    /* currently factor is 26.6 */
+    factor = ( p_sub_a.x * line_segment.x ) / 64 +
+             ( p_sub_a.y * line_segment.y ) / 64;
+
+    /* now factor is 16.16 */
+    factor = FT_DivFix( factor, sq_line_length );
+
+    /* clamp the factor between 0.0 and 1.0 in fixed-point */
+    if ( factor > FT_INT_16D16( 1 ) )
+      factor = FT_INT_16D16( 1 );
+    if ( factor < 0 )
+      factor = 0;
+
+    nearest_point.x = FT_MulFix( FT_26D6_16D16( line_segment.x ),
+                                 factor );
+    nearest_point.y = FT_MulFix( FT_26D6_16D16( line_segment.y ),
+                                 factor );
+
+    nearest_point.x = FT_26D6_16D16( a.x ) + nearest_point.x;
+    nearest_point.y = FT_26D6_16D16( a.y ) + nearest_point.y;
+
+    nearest_vector.x = nearest_point.x - FT_26D6_16D16( p.x );
+    nearest_vector.y = nearest_point.y - FT_26D6_16D16( p.y );
+
+    cross = FT_MulFix( nearest_vector.x, line_segment.y ) -
+            FT_MulFix( nearest_vector.y, line_segment.x );
+
+    /* assign the output */
+    out->sign     = cross < 0 ? 1 : -1;
+    out->distance = VECTOR_LENGTH_16D16( nearest_vector );
+
+    /* Instead of finding `cross` for checking corner we */
+    /* directly set it here.  This is more efficient     */
+    /* because if the distance is perpendicular we can   */
+    /* directly set it to 1.                             */
+    if ( factor != 0 && factor != FT_INT_16D16( 1 ) )
+      out->cross = FT_INT_16D16( 1 );
+    else
+    {
+      /* [OPTIMIZATION]: Pre-compute this direction. */
+      /* If not perpendicular then compute `cross`.  */
+      FT_Vector_NormLen( &line_segment );
+      FT_Vector_NormLen( &nearest_vector );
+
+      out->cross = FT_MulFix( line_segment.x, nearest_vector.y ) -
+                   FT_MulFix( line_segment.y, nearest_vector.x );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   get_min_distance_conic
+   *
+   * @Description:
+   *   Find the shortest distance from the `conic` Bezier curve to a given
+   *   `point` and assign it to `out`.  Use it for conic/quadratic curves
+   *   only.
+   *
+   * @Input:
+   *   conic ::
+   *     The conic Bezier curve to which the shortest distance is to be
+   *     computed.
+   *
+   *   point ::
+   *     Point from which the shortest distance is to be computed.
+   *
+   * @Output:
+   *   out ::
+   *     Signed distance from `point` to `conic`.
+   *
+   * @Return:
+   *     FreeType error, 0 means success.
+   *
+   * @Note:
+   *   The `conic` parameter must have an edge type of `SDF_EDGE_CONIC`.
+   *
+   */
+
+#if !USE_NEWTON_FOR_CONIC
+
+  /*
+   * The function uses an analytical method to find the shortest distance
+   * which is faster than the Newton-Raphson method, but has underflows at
+   * the moment.  Use Newton's method if you can see artifacts in the SDF.
+   */
+  static FT_Error
+  get_min_distance_conic( SDF_Edge*             conic,
+                          FT_26D6_Vec           point,
+                          SDF_Signed_Distance*  out )
+  {
+    /*
+     * The procedure to find the shortest distance from a point to a
+     * quadratic Bezier curve is similar to the line segment algorithm.  The
+     * shortest distance is perpendicular to the Bezier curve; the only
+     * difference from line is that there can be more than one
+     * perpendicular, and we also have to check the endpoints, because the
+     * perpendicular may not be the shortest.
+     *
+     * Let's assume that
+     * ```
+     * p0 = first endpoint
+     * p1 = control point
+     * p2 = second endpoint
+     * p  = point from which shortest distance is to be calculated
+     * ```
+     *
+     * (1) The equation of a quadratic Bezier curve can be written as
+     *
+     *     ```
+     *     B(t) = (1 - t)^2 * p0 + 2(1 - t)t * p1 + t^2 * p2
+     *     ```
+     *
+     *     with `t` a factor in the range [0.0f, 1.0f].  This equation can
+     *     be rewritten as
+     *
+     *     ```
+     *     B(t) = t^2 * (p0 - 2p1 + p2) + 2t * (p1 - p0) + p0
+     *     ```
+     *
+     *     With
+     *
+     *     ```
+     *     A = p0 - 2p1 + p2
+     *     B = p1 - p0
+     *     ```
+     *
+     *     we have
+     *
+     *     ```
+     *     B(t) = t^2 * A + 2t * B + p0
+     *     ```
+     *
+     * (2) The derivative of the last equation above is
+     *
+     *     ```
+     *     B'(t) = 2 *(tA + B)
+     *     ```
+     *
+     * (3) To find the shortest distance from `p` to `B(t)` we find the
+     *     point on the curve at which the shortest distance vector (i.e.,
+     *     `B(t) - p`) and the direction (i.e., `B'(t)`) make 90 degrees.
+     *     In other words, we make the dot product zero.
+     *
+     *     ```
+     *     (B(t) - p) . (B'(t)) = 0
+     *     (t^2 * A + 2t * B + p0 - p) . (2 * (tA + B)) = 0
+     *     ```
+     *
+     *     After simplifying we get a cubic equation
+     *
+     *     ```
+     *     at^3 + bt^2 + ct + d = 0
+     *     ```
+     *
+     *     with
+     *
+     *     ```
+     *     a = A.A
+     *     b = 3A.B
+     *     c = 2B.B + A.p0 - A.p
+     *     d = p0.B - p.B
+     *     ```
+     *
+     * (4) Now the roots of the equation can be computed using 'Cardano's
+     *     Cubic formula'; we clamp the roots in the range [0.0f, 1.0f].
+     *
+     * [note]: `B` and `B(t)` are different in the above equations.
+     */
+
+    FT_Error  error = FT_Err_Ok;
+
+    FT_26D6_Vec  aA, bB;         /* A, B in the above comment             */
+    FT_26D6_Vec  nearest_point = { 0, 0 };
+                                 /* point on curve nearest to `point`     */
+    FT_26D6_Vec  direction;      /* direction of curve at `nearest_point` */
+
+    FT_26D6_Vec  p0, p1, p2;     /* control points of a conic curve       */
+    FT_26D6_Vec  p;              /* `point` to which shortest distance    */
+
+    FT_26D6  a, b, c, d;         /* cubic coefficients                    */
+
+    FT_16D16  roots[3] = { 0, 0, 0 };    /* real roots of the cubic eq.   */
+    FT_16D16  min_factor;                /* factor at `nearest_point`     */
+    FT_16D16  cross;                     /* to determine the sign         */
+    FT_16D16  min      = FT_INT_MAX;     /* shortest squared distance     */
+
+    FT_UShort  num_roots;                /* number of real roots of cubic */
+    FT_UShort  i;
+
+
+    if ( !conic || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( conic->edge_type != SDF_EDGE_CONIC )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    p0 = conic->start_pos;
+    p1 = conic->control_a;
+    p2 = conic->end_pos;
+    p  = point;
+
+    /* compute substitution coefficients */
+    aA.x = p0.x - 2 * p1.x + p2.x;
+    aA.y = p0.y - 2 * p1.y + p2.y;
+
+    bB.x = p1.x - p0.x;
+    bB.y = p1.y - p0.y;
+
+    /* compute cubic coefficients */
+    a = VEC_26D6_DOT( aA, aA );
+
+    b = 3 * VEC_26D6_DOT( aA, bB );
+
+    c = 2 * VEC_26D6_DOT( bB, bB ) +
+            VEC_26D6_DOT( aA, p0 ) -
+            VEC_26D6_DOT( aA, p );
+
+    d = VEC_26D6_DOT( p0, bB ) -
+        VEC_26D6_DOT( p, bB );
+
+    /* find the roots */
+    num_roots = solve_cubic_equation( a, b, c, d, roots );
+
+    if ( num_roots == 0 )
+    {
+      roots[0]  = 0;
+      roots[1]  = FT_INT_16D16( 1 );
+      num_roots = 2;
+    }
+
+    /* [OPTIMIZATION]: Check the roots, clamp them and discard */
+    /*                 duplicate roots.                        */
+
+    /* convert these values to 16.16 for further computation */
+    aA.x = FT_26D6_16D16( aA.x );
+    aA.y = FT_26D6_16D16( aA.y );
+
+    bB.x = FT_26D6_16D16( bB.x );
+    bB.y = FT_26D6_16D16( bB.y );
+
+    p0.x = FT_26D6_16D16( p0.x );
+    p0.y = FT_26D6_16D16( p0.y );
+
+    p.x = FT_26D6_16D16( p.x );
+    p.y = FT_26D6_16D16( p.y );
+
+    for ( i = 0; i < num_roots; i++ )
+    {
+      FT_16D16  t    = roots[i];
+      FT_16D16  t2   = 0;
+      FT_16D16  dist = 0;
+
+      FT_16D16_Vec  curve_point;
+      FT_16D16_Vec  dist_vector;
+
+      /*
+       * Ideally we should discard the roots which are outside the range
+       * [0.0, 1.0] and check the endpoints of the Bezier curve, but Behdad
+       * Esfahbod proved the following lemma.
+       *
+       * Lemma:
+       *
+       * (1) If the closest point on the curve [0, 1] is to the endpoint at
+       *     `t` = 1 and the cubic has no real roots at `t` = 1 then the
+       *     cubic must have a real root at some `t` > 1.
+       *
+       * (2) Similarly, if the closest point on the curve [0, 1] is to the
+       *     endpoint at `t` = 0 and the cubic has no real roots at `t` = 0
+       *     then the cubic must have a real root at some `t` < 0.
+       *
+       * Now because of this lemma we only need to clamp the roots and that
+       * will take care of the endpoints.
+       *
+       * For more details see
+       *
+       *   https://lists.nongnu.org/archive/html/freetype-devel/2020-06/msg00147.html
+       */
+
+      if ( t < 0 )
+        t = 0;
+      if ( t > FT_INT_16D16( 1 ) )
+        t = FT_INT_16D16( 1 );
+
+      t2 = FT_MulFix( t, t );
+
+      /* B(t) = t^2 * A + 2t * B + p0 - p */
+      curve_point.x = FT_MulFix( aA.x, t2 ) +
+                      2 * FT_MulFix( bB.x, t ) + p0.x;
+      curve_point.y = FT_MulFix( aA.y, t2 ) +
+                      2 * FT_MulFix( bB.y, t ) + p0.y;
+
+      /* `curve_point` - `p` */
+      dist_vector.x = curve_point.x - p.x;
+      dist_vector.y = curve_point.y - p.y;
+
+      dist = VECTOR_LENGTH_16D16( dist_vector );
+
+      if ( dist < min )
+      {
+        min           = dist;
+        nearest_point = curve_point;
+        min_factor    = t;
+      }
+    }
+
+    /* B'(t) = 2 * (tA + B) */
+    direction.x = 2 * FT_MulFix( aA.x, min_factor ) + 2 * bB.x;
+    direction.y = 2 * FT_MulFix( aA.y, min_factor ) + 2 * bB.y;
+
+    /* determine the sign */
+    cross = FT_MulFix( nearest_point.x - p.x, direction.y ) -
+            FT_MulFix( nearest_point.y - p.y, direction.x );
+
+    /* assign the values */
+    out->distance = min;
+    out->sign     = cross < 0 ? 1 : -1;
+
+    if ( min_factor != 0 && min_factor != FT_INT_16D16( 1 ) )
+      out->cross = FT_INT_16D16( 1 );   /* the two are perpendicular */
+    else
+    {
+      /* convert to nearest vector */
+      nearest_point.x -= FT_26D6_16D16( p.x );
+      nearest_point.y -= FT_26D6_16D16( p.y );
+
+      /* compute `cross` if not perpendicular */
+      FT_Vector_NormLen( &direction );
+      FT_Vector_NormLen( &nearest_point );
+
+      out->cross = FT_MulFix( direction.x, nearest_point.y ) -
+                   FT_MulFix( direction.y, nearest_point.x );
+    }
+
+  Exit:
+    return error;
+  }
+
+#else /* USE_NEWTON_FOR_CONIC */
+
+  /*
+   * The function uses Newton's approximation to find the shortest distance,
+   * which is a bit slower than the analytical method but doesn't cause
+   * underflow.
+   */
+  static FT_Error
+  get_min_distance_conic( SDF_Edge*             conic,
+                          FT_26D6_Vec           point,
+                          SDF_Signed_Distance*  out )
+  {
+    /*
+     * This method uses Newton-Raphson's approximation to find the shortest
+     * distance from a point to a conic curve.  It does not involve solving
+     * any cubic equation, that is why there is no risk of underflow.
+     *
+     * Let's assume that
+     *
+     * ```
+     * p0 = first endpoint
+     * p1 = control point
+     * p3 = second endpoint
+     * p  = point from which shortest distance is to be calculated
+     * ```
+     *
+     * (1) The equation of a quadratic Bezier curve can be written as
+     *
+     *     ```
+     *     B(t) = (1 - t)^2 * p0 + 2(1 - t)t * p1 + t^2 * p2
+     *     ```
+     *
+     *     with `t` the factor in the range [0.0f, 1.0f].  The above
+     *     equation can be rewritten as
+     *
+     *     ```
+     *     B(t) = t^2 * (p0 - 2p1 + p2) + 2t * (p1 - p0) + p0
+     *     ```
+     *
+     *     With
+     *
+     *     ```
+     *     A = p0 - 2p1 + p2
+     *     B = 2 * (p1 - p0)
+     *     ```
+     *
+     *     we have
+     *
+     *     ```
+     *     B(t) = t^2 * A + t * B + p0
+     *     ```
+     *
+     * (2) The derivative of the above equation is
+     *
+     *     ```
+     *     B'(t) = 2t * A + B
+     *     ```
+     *
+     * (3) The second derivative of the above equation is
+     *
+     *     ```
+     *     B''(t) = 2A
+     *     ```
+     *
+     * (4) The equation `P(t)` of the distance from point `p` to the curve
+     *     can be written as
+     *
+     *     ```
+     *     P(t) = t^2 * A + t^2 * B + p0 - p
+     *     ```
+     *
+     *     With
+     *
+     *     ```
+     *     C = p0 - p
+     *     ```
+     *
+     *     we have
+     *
+     *     ```
+     *     P(t) = t^2 * A + t * B + C
+     *     ```
+     *
+     * (5) Finally, the equation of the angle between `B(t)` and `P(t)` can
+     *     be written as
+     *
+     *     ```
+     *     Q(t) = P(t) . B'(t)
+     *     ```
+     *
+     * (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
+     *     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
+     *     improve.
+     *
+     *     ```
+     *     t := Q(t) / Q'(t)
+     *     ```
+     *
+     *     Putting the value of `Q(t)` from the above equation gives
+     *
+     *     ```
+     *     t := P(t) . B'(t) / derivative(P(t) . B'(t))
+     *     t := P(t) . B'(t) /
+     *            (P'(t) . B'(t) + P(t) . B''(t))
+     *     ```
+     *
+     *     Note that `P'(t)` is the same as `B'(t)` because the constant is
+     *     gone due to the derivative.
+     *
+     * (8) Finally we get the equation to improve the factor as
+     *
+     *     ```
+     *     t := P(t) . B'(t) /
+     *            (B'(t) . B'(t) + P(t) . B''(t))
+     *     ```
+     *
+     * [note]: `B` and `B(t)` are different in the above equations.
+     */
+
+    FT_Error  error = FT_Err_Ok;
+
+    FT_26D6_Vec  aA, bB, cC;     /* A, B, C in the above comment          */
+    FT_26D6_Vec  nearest_point = { 0, 0 };
+                                 /* point on curve nearest to `point`     */
+    FT_26D6_Vec  direction;      /* direction of curve at `nearest_point` */
+
+    FT_26D6_Vec  p0, p1, p2;     /* control points of a conic curve       */
+    FT_26D6_Vec  p;              /* `point` to which shortest distance    */
+
+    FT_16D16  min_factor = 0;            /* factor at `nearest_point'     */
+    FT_16D16  cross;                     /* to determine the sign         */
+    FT_16D16  min        = FT_INT_MAX;   /* shortest squared distance     */
+
+    FT_UShort  iterations;
+    FT_UShort  steps;
+
+
+    if ( !conic || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( conic->edge_type != SDF_EDGE_CONIC )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    p0 = conic->start_pos;
+    p1 = conic->control_a;
+    p2 = conic->end_pos;
+    p  = point;
+
+    /* compute substitution coefficients */
+    aA.x = p0.x - 2 * p1.x + p2.x;
+    aA.y = p0.y - 2 * p1.y + p2.y;
+
+    bB.x = 2 * ( p1.x - p0.x );
+    bB.y = 2 * ( p1.y - p0.y );
+
+    cC.x = p0.x;
+    cC.y = p0.y;
+
+    /* do Newton's iterations */
+    for ( iterations = 0; iterations <= MAX_NEWTON_DIVISIONS; iterations++ )
+    {
+      FT_16D16  factor = FT_INT_16D16( iterations ) / MAX_NEWTON_DIVISIONS;
+      FT_16D16  factor2;
+      FT_16D16  length;
+
+      FT_16D16_Vec  curve_point; /* point on the curve  */
+      FT_16D16_Vec  dist_vector; /* `curve_point` - `p` */
+
+      FT_26D6_Vec  d1;           /* first  derivative   */
+      FT_26D6_Vec  d2;           /* second derivative   */
+
+      FT_16D16  temp1;
+      FT_16D16  temp2;
+
+
+      for ( steps = 0; steps < MAX_NEWTON_STEPS; steps++ )
+      {
+        factor2 = FT_MulFix( factor, factor );
+
+        /* B(t) = t^2 * A + t * B + p0 */
+        curve_point.x = FT_MulFix( aA.x, factor2 ) +
+                        FT_MulFix( bB.x, factor ) + cC.x;
+        curve_point.y = FT_MulFix( aA.y, factor2 ) +
+                        FT_MulFix( bB.y, factor ) + cC.y;
+
+        /* convert to 16.16 */
+        curve_point.x = FT_26D6_16D16( curve_point.x );
+        curve_point.y = FT_26D6_16D16( curve_point.y );
+
+        /* P(t) in the comment */
+        dist_vector.x = curve_point.x - FT_26D6_16D16( p.x );
+        dist_vector.y = curve_point.y - FT_26D6_16D16( p.y );
+
+        length = VECTOR_LENGTH_16D16( dist_vector );
+
+        if ( length < min )
+        {
+          min           = length;
+          min_factor    = factor;
+          nearest_point = curve_point;
+        }
+
+        /* This is Newton's approximation.          */
+        /*                                          */
+        /*   t := P(t) . B'(t) /                    */
+        /*          (B'(t) . B'(t) + P(t) . B''(t)) */
+
+        /* B'(t) = 2tA + B */
+        d1.x = FT_MulFix( aA.x, 2 * factor ) + bB.x;
+        d1.y = FT_MulFix( aA.y, 2 * factor ) + bB.y;
+
+        /* B''(t) = 2A */
+        d2.x = 2 * aA.x;
+        d2.y = 2 * aA.y;
+
+        dist_vector.x /= 1024;
+        dist_vector.y /= 1024;
+
+        /* temp1 = P(t) . B'(t) */
+        temp1 = VEC_26D6_DOT( dist_vector, d1 );
+
+        /* temp2 = B'(t) . B'(t) + P(t) . B''(t) */
+        temp2 = VEC_26D6_DOT( d1, d1 ) +
+                VEC_26D6_DOT( dist_vector, d2 );
+
+        factor -= FT_DivFix( temp1, temp2 );
+
+        if ( factor < 0 || factor > FT_INT_16D16( 1 ) )
+          break;
+      }
+    }
+
+    /* B'(t) = 2t * A + B */
+    direction.x = 2 * FT_MulFix( aA.x, min_factor ) + bB.x;
+    direction.y = 2 * FT_MulFix( aA.y, min_factor ) + bB.y;
+
+    /* determine the sign */
+    cross = FT_MulFix( nearest_point.x - FT_26D6_16D16( p.x ),
+                       direction.y )                           -
+            FT_MulFix( nearest_point.y - FT_26D6_16D16( p.y ),
+                       direction.x );
+
+    /* assign the values */
+    out->distance = min;
+    out->sign     = cross < 0 ? 1 : -1;
+
+    if ( min_factor != 0 && min_factor != FT_INT_16D16( 1 ) )
+      out->cross = FT_INT_16D16( 1 );   /* the two are perpendicular */
+    else
+    {
+      /* convert to nearest vector */
+      nearest_point.x -= FT_26D6_16D16( p.x );
+      nearest_point.y -= FT_26D6_16D16( p.y );
+
+      /* compute `cross` if not perpendicular */
+      FT_Vector_NormLen( &direction );
+      FT_Vector_NormLen( &nearest_point );
+
+      out->cross = FT_MulFix( direction.x, nearest_point.y ) -
+                   FT_MulFix( direction.y, nearest_point.x );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+#endif /* USE_NEWTON_FOR_CONIC */
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   get_min_distance_cubic
+   *
+   * @Description:
+   *   Find the shortest distance from the `cubic` Bezier curve to a given
+   *   `point` and assigns it to `out`.  Use it for cubic curves only.
+   *
+   * @Input:
+   *   cubic ::
+   *     The cubic Bezier curve to which the shortest distance is to be
+   *     computed.
+   *
+   *   point ::
+   *     Point from which the shortest distance is to be computed.
+   *
+   * @Output:
+   *   out ::
+   *     Signed distance from `point` to `cubic`.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   * @Note:
+   *   The function uses Newton's approximation to find the shortest
+   *   distance.  Another way would be to divide the cubic into conic or
+   *   subdivide the curve into lines, but that is not implemented.
+   *
+   *   The `cubic` parameter must have an edge type of `SDF_EDGE_CUBIC`.
+   *
+   */
+  static FT_Error
+  get_min_distance_cubic( SDF_Edge*             cubic,
+                          FT_26D6_Vec           point,
+                          SDF_Signed_Distance*  out )
+  {
+    /*
+     * The procedure to find the shortest distance from a point to a cubic
+     * Bezier curve is similar to quadratic curve algorithm.  The only
+     * difference is that while calculating factor `t`, instead of a cubic
+     * polynomial equation we have to find the roots of a 5th degree
+     * polynomial equation.  Solving this would require a significant amount
+     * of time, and still the results may not be accurate.  We are thus
+     * going to directly approximate the value of `t` using the Newton-Raphson
+     * method.
+     *
+     * Let's assume that
+     *
+     * ```
+     * p0 = first endpoint
+     * p1 = first control point
+     * p2 = second control point
+     * p3 = second endpoint
+     * p  = point from which shortest distance is to be calculated
+     * ```
+     *
+     * (1) The equation of a cubic Bezier curve can be written as
+     *
+     *     ```
+     *     B(t) = (1 - t)^3 * p0 + 3(1 - t)^2 t * p1 +
+     *              3(1 - t)t^2 * p2 + t^3 * p3
+     *     ```
+     *
+     *     The equation can be expanded and written as
+     *
+     *     ```
+     *     B(t) = t^3 * (-p0 + 3p1 - 3p2 + p3) +
+     *              3t^2 * (p0 - 2p1 + p2) + 3t * (-p0 + p1) + p0
+     *     ```
+     *
+     *     With
+     *
+     *     ```
+     *     A = -p0 + 3p1 - 3p2 + p3
+     *     B = 3(p0 - 2p1 + p2)
+     *     C = 3(-p0 + p1)
+     *     ```
+     *
+     *     we have
+     *
+     *     ```
+     *     B(t) = t^3 * A + t^2 * B + t * C + p0
+     *     ```
+     *
+     * (2) The derivative of the above equation is
+     *
+     *     ```
+     *     B'(t) = 3t^2 * A + 2t * B + C
+     *     ```
+     *
+     * (3) The second derivative of the above equation is
+     *
+     *     ```
+     *     B''(t) = 6t * A + 2B
+     *     ```
+     *
+     * (4) The equation `P(t)` of the distance from point `p` to the curve
+     *     can be written as
+     *
+     *     ```
+     *     P(t) = t^3 * A + t^2 * B + t * C + p0 - p
+     *     ```
+     *
+     *     With
+     *
+     *     ```
+     *     D = p0 - p
+     *     ```
+     *
+     *     we have
+     *
+     *     ```
+     *     P(t) = t^3 * A + t^2 * B + t * C + D
+     *     ```
+     *
+     * (5) Finally the equation of the angle between `B(t)` and `P(t)` can
+     *     be written as
+     *
+     *     ```
+     *     Q(t) = P(t) . B'(t)
+     *     ```
+     *
+     * (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
+     *     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
+     *     improve.
+     *
+     *     ```
+     *     t := Q(t) / Q'(t)
+     *     ```
+     *
+     *     Putting the value of `Q(t)` from the above equation gives
+     *
+     *     ```
+     *     t := P(t) . B'(t) / derivative(P(t) . B'(t))
+     *     t := P(t) . B'(t) /
+     *            (P'(t) . B'(t) + P(t) . B''(t))
+     *     ```
+     *
+     *     Note that `P'(t)` is the same as `B'(t)` because the constant is
+     *     gone due to the derivative.
+     *
+     * (8) Finally we get the equation to improve the factor as
+     *
+     *     ```
+     *     t := P(t) . B'(t) /
+     *            (B'(t) . B'( t ) + P(t) . B''(t))
+     *     ```
+     *
+     * [note]: `B` and `B(t)` are different in the above equations.
+     */
+
+    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_16D16_Vec  direction;      /* direction of curve at `nearest_point` */
+
+    FT_26D6_Vec  p0, p1, p2, p3;  /* control points of a cubic curve       */
+    FT_26D6_Vec  p;               /* `point` to which shortest distance    */
+
+    FT_16D16  min_factor    = 0;            /* factor at shortest distance */
+    FT_16D16  min_factor_sq = 0;            /* factor at shortest distance */
+    FT_16D16  cross;                        /* to determine the sign       */
+    FT_16D16  min           = FT_INT_MAX;   /* shortest distance           */
+
+    FT_UShort  iterations;
+    FT_UShort  steps;
+
+
+    if ( !cubic || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( cubic->edge_type != SDF_EDGE_CUBIC )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    p0 = cubic->start_pos;
+    p1 = cubic->control_a;
+    p2 = cubic->control_b;
+    p3 = cubic->end_pos;
+    p  = point;
+
+    /* compute substitution coefficients */
+    aA.x = -p0.x + 3 * ( p1.x - p2.x ) + p3.x;
+    aA.y = -p0.y + 3 * ( p1.y - p2.y ) + p3.y;
+
+    bB.x = 3 * ( p0.x - 2 * p1.x + p2.x );
+    bB.y = 3 * ( p0.y - 2 * p1.y + p2.y );
+
+    cC.x = 3 * ( p1.x - p0.x );
+    cC.y = 3 * ( p1.y - p0.y );
+
+    dD.x = p0.x;
+    dD.y = p0.y;
+
+    for ( iterations = 0; iterations <= MAX_NEWTON_DIVISIONS; iterations++ )
+    {
+      FT_16D16  factor  = FT_INT_16D16( iterations ) / MAX_NEWTON_DIVISIONS;
+
+      FT_16D16  factor2;         /* factor^2            */
+      FT_16D16  factor3;         /* factor^3            */
+      FT_16D16  length;
+
+      FT_16D16_Vec  curve_point; /* point on the curve  */
+      FT_16D16_Vec  dist_vector; /* `curve_point' - `p' */
+
+      FT_26D6_Vec  d1;           /* first  derivative   */
+      FT_26D6_Vec  d2;           /* second derivative   */
+
+      FT_16D16  temp1;
+      FT_16D16  temp2;
+
+
+      for ( steps = 0; steps < MAX_NEWTON_STEPS; steps++ )
+      {
+        factor2 = FT_MulFix( factor, factor );
+        factor3 = FT_MulFix( factor2, factor );
+
+        /* B(t) = t^3 * A + t^2 * B + t * C + D */
+        curve_point.x = FT_MulFix( aA.x, factor3 ) +
+                        FT_MulFix( bB.x, factor2 ) +
+                        FT_MulFix( cC.x, factor ) + dD.x;
+        curve_point.y = FT_MulFix( aA.y, factor3 ) +
+                        FT_MulFix( bB.y, factor2 ) +
+                        FT_MulFix( cC.y, factor ) + dD.y;
+
+        /* convert to 16.16 */
+        curve_point.x = FT_26D6_16D16( curve_point.x );
+        curve_point.y = FT_26D6_16D16( curve_point.y );
+
+        /* P(t) in the comment */
+        dist_vector.x = curve_point.x - FT_26D6_16D16( p.x );
+        dist_vector.y = curve_point.y - FT_26D6_16D16( p.y );
+
+        length = VECTOR_LENGTH_16D16( dist_vector );
+
+        if ( length < min )
+        {
+          min           = length;
+          min_factor    = factor;
+          min_factor_sq = factor2;
+          nearest_point = curve_point;
+        }
+
+        /* This the Newton's approximation.         */
+        /*                                          */
+        /*   t := P(t) . B'(t) /                    */
+        /*          (B'(t) . B'(t) + P(t) . B''(t)) */
+
+        /* B'(t) = 3t^2 * A + 2t * B + C */
+        d1.x = FT_MulFix( aA.x, 3 * factor2 ) +
+               FT_MulFix( bB.x, 2 * factor ) + cC.x;
+        d1.y = FT_MulFix( aA.y, 3 * factor2 ) +
+               FT_MulFix( bB.y, 2 * factor ) + cC.y;
+
+        /* B''(t) = 6t * A + 2B */
+        d2.x = FT_MulFix( aA.x, 6 * factor ) + 2 * bB.x;
+        d2.y = FT_MulFix( aA.y, 6 * factor ) + 2 * bB.y;
+
+        dist_vector.x /= 1024;
+        dist_vector.y /= 1024;
+
+        /* temp1 = P(t) . B'(t) */
+        temp1 = VEC_26D6_DOT( dist_vector, d1 );
+
+        /* temp2 = B'(t) . B'(t) + P(t) . B''(t) */
+        temp2 = VEC_26D6_DOT( d1, d1 ) +
+                VEC_26D6_DOT( dist_vector, d2 );
+
+        factor -= FT_DivFix( temp1, temp2 );
+
+        if ( factor < 0 || factor > FT_INT_16D16( 1 ) )
+          break;
+      }
+    }
+
+    /* B'(t) = 3t^2 * A + 2t * B + C */
+    direction.x = FT_MulFix( aA.x, 3 * min_factor_sq ) +
+                  FT_MulFix( bB.x, 2 * min_factor ) + cC.x;
+    direction.y = FT_MulFix( aA.y, 3 * min_factor_sq ) +
+                  FT_MulFix( bB.y, 2 * min_factor ) + cC.y;
+
+    /* determine the sign */
+    cross = FT_MulFix( nearest_point.x - FT_26D6_16D16( p.x ),
+                       direction.y )                           -
+            FT_MulFix( nearest_point.y - FT_26D6_16D16( p.y ),
+                       direction.x );
+
+    /* assign the values */
+    out->distance = min;
+    out->sign     = cross < 0 ? 1 : -1;
+
+    if ( min_factor != 0 && min_factor != FT_INT_16D16( 1 ) )
+      out->cross = FT_INT_16D16( 1 );   /* the two are perpendicular */
+    else
+    {
+      /* convert to nearest vector */
+      nearest_point.x -= FT_26D6_16D16( p.x );
+      nearest_point.y -= FT_26D6_16D16( p.y );
+
+      /* compute `cross` if not perpendicular */
+      FT_Vector_NormLen( &direction );
+      FT_Vector_NormLen( &nearest_point );
+
+      out->cross = FT_MulFix( direction.x, nearest_point.y ) -
+                   FT_MulFix( direction.y, nearest_point.x );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   sdf_edge_get_min_distance
+   *
+   * @Description:
+   *   Find shortest distance from `point` to any type of `edge`.  It checks
+   *   the edge type and then calls the relevant `get_min_distance_*`
+   *   function.
+   *
+   * @Input:
+   *   edge ::
+   *     An edge to which the shortest distance is to be computed.
+   *
+   *   point ::
+   *     Point from which the shortest distance is to be computed.
+   *
+   * @Output:
+   *   out ::
+   *     Signed distance from `point` to `edge`.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  sdf_edge_get_min_distance( SDF_Edge*             edge,
+                             FT_26D6_Vec           point,
+                             SDF_Signed_Distance*  out )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( !edge || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* edge-specific distance calculation */
+    switch ( edge->edge_type )
+    {
+    case SDF_EDGE_LINE:
+      get_min_distance_line( edge, point, out );
+      break;
+
+    case SDF_EDGE_CONIC:
+      get_min_distance_conic( edge, point, out );
+      break;
+
+    case SDF_EDGE_CUBIC:
+      get_min_distance_cubic( edge, point, out );
+      break;
+
+    default:
+      error = FT_THROW( Invalid_Argument );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /* `sdf_generate' is not used at the moment */
+#if 0
+
+  #error "DO NOT USE THIS!"
+  #error "The function still outputs 16-bit data, which might cause memory"
+  #error "corruption.  If required I will add this later."
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   sdf_contour_get_min_distance
+   *
+   * @Description:
+   *   Iterate over all edges that make up the contour, find the shortest
+   *   distance from a point to this contour, and assigns result to `out`.
+   *
+   * @Input:
+   *   contour ::
+   *     A contour to which the shortest distance is to be computed.
+   *
+   *   point ::
+   *     Point from which the shortest distance is to be computed.
+   *
+   * @Output:
+   *   out ::
+   *     Signed distance from the `point' to the `contour'.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   * @Note:
+   *   The function does not return a signed distance for each edge which
+   *   makes up the contour, it simply returns the shortest of all the
+   *   edges.
+   *
+   */
+  static FT_Error
+  sdf_contour_get_min_distance( SDF_Contour*          contour,
+                                FT_26D6_Vec           point,
+                                SDF_Signed_Distance*  out )
+  {
+    FT_Error             error    = FT_Err_Ok;
+    SDF_Signed_Distance  min_dist = max_sdf;
+    SDF_Edge*            edge_list;
+
+
+    if ( !contour || !out )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    edge_list = contour->edges;
+
+    /* iterate over all the edges manually */
+    while ( edge_list )
+    {
+      SDF_Signed_Distance  current_dist = max_sdf;
+      FT_16D16             diff;
+
+
+      FT_CALL( sdf_edge_get_min_distance( edge_list,
+                                          point,
+                                          &current_dist ) );
+
+      if ( current_dist.distance >= 0 )
+      {
+        diff = current_dist.distance - min_dist.distance;
+
+
+        if ( FT_ABS( diff ) < CORNER_CHECK_EPSILON )
+          min_dist = resolve_corner( min_dist, current_dist );
+        else if ( diff < 0 )
+          min_dist = current_dist;
+      }
+      else
+        FT_TRACE0(( "sdf_contour_get_min_distance: Overflow.\n" ));
+
+      edge_list = edge_list->next;
+    }
+
+    *out = min_dist;
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   sdf_generate
+   *
+   * @Description:
+   *   This is the main function that is responsible for generating signed
+   *   distance fields.  The function does not align or compute the size of
+   *   `bitmap`; therefore the calling application must set up `bitmap`
+   *   properly and transform the `shape' appropriately in advance.
+   *
+   *   Currently we check all pixels against all contours and all edges.
+   *
+   * @Input:
+   *   internal_params ::
+   *     Internal parameters and properties required by the rasterizer.  See
+   *     @SDF_Params for more.
+   *
+   *   shape ::
+   *     A complete shape which is used to generate SDF.
+   *
+   *   spread ::
+   *     Maximum distances to be allowed in the output bitmap.
+   *
+   * @Output:
+   *   bitmap ::
+   *     The output bitmap which will contain the SDF information.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  sdf_generate( const SDF_Params  internal_params,
+                const SDF_Shape*  shape,
+                FT_UInt           spread,
+                const FT_Bitmap*  bitmap )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    FT_UInt  width = 0;
+    FT_UInt  rows  = 0;
+    FT_UInt  x     = 0;   /* used to loop in x direction, i.e., width     */
+    FT_UInt  y     = 0;   /* used to loop in y direction, i.e., rows      */
+    FT_UInt  sp_sq = 0;   /* `spread` [* `spread`] as a 16.16 fixed value */
+
+    FT_Short*  buffer;
+
+
+    if ( !shape || !bitmap )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( spread < MIN_SPREAD || spread > MAX_SPREAD )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    width  = bitmap->width;
+    rows   = bitmap->rows;
+    buffer = (FT_Short*)bitmap->buffer;
+
+    if ( USE_SQUARED_DISTANCES )
+      sp_sq = FT_INT_16D16( spread * spread );
+    else
+      sp_sq = FT_INT_16D16( spread );
+
+    if ( width == 0 || rows == 0 )
+    {
+      FT_TRACE0(( "sdf_generate:"
+                  " Cannot render glyph with width/height == 0\n" ));
+      FT_TRACE0(( "             "
+                  " (width, height provided [%d, %d])\n",
+                  width, rows ));
+
+      error = FT_THROW( Cannot_Render_Glyph );
+      goto Exit;
+    }
+
+    /* loop over all rows */
+    for ( y = 0; y < rows; y++ )
+    {
+      /* loop over all pixels of a row */
+      for ( x = 0; x < width; x++ )
+      {
+        /* `grid_point` is the current pixel position; */
+        /* our task is to find the shortest distance   */
+        /* from this point to the entire shape.        */
+        FT_26D6_Vec          grid_point = zero_vector;
+        SDF_Signed_Distance  min_dist   = max_sdf;
+        SDF_Contour*         contour_list;
+
+        FT_UInt   index;
+        FT_Short  value;
+
+
+        grid_point.x = FT_INT_26D6( x );
+        grid_point.y = FT_INT_26D6( y );
+
+        /* This `grid_point' is at the corner, but we */
+        /* use the center of the pixel.               */
+        grid_point.x += FT_INT_26D6( 1 ) / 2;
+        grid_point.y += FT_INT_26D6( 1 ) / 2;
+
+        contour_list = shape->contours;
+
+        /* iterate over all contours manually */
+        while ( contour_list )
+        {
+          SDF_Signed_Distance  current_dist = max_sdf;
+
+
+          FT_CALL( sdf_contour_get_min_distance( contour_list,
+                                                 grid_point,
+                                                 &current_dist ) );
+
+          if ( current_dist.distance < min_dist.distance )
+            min_dist = current_dist;
+
+          contour_list = contour_list->next;
+        }
+
+        /* [OPTIMIZATION]: if (min_dist > sp_sq) then simply clamp  */
+        /*                 the value to spread to avoid square_root */
+
+        /* clamp the values to spread */
+        if ( min_dist.distance > sp_sq )
+          min_dist.distance = sp_sq;
+
+        /* square_root the values and fit in a 6.10 fixed-point */
+        if ( USE_SQUARED_DISTANCES )
+          min_dist.distance = square_root( min_dist.distance );
+
+        if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT )
+          min_dist.sign = -min_dist.sign;
+        if ( internal_params.flip_sign )
+          min_dist.sign = -min_dist.sign;
+
+        min_dist.distance /= 64; /* convert from 16.16 to 22.10 */
+
+        value  = min_dist.distance & 0x0000FFFF; /* truncate to 6.10 */
+        value *= min_dist.sign;
+
+        if ( internal_params.flip_y )
+          index = y * width + x;
+        else
+          index = ( rows - y - 1 ) * width + x;
+
+        buffer[index] = value;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+#endif /* 0 */
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   sdf_generate_bounding_box
+   *
+   * @Description:
+   *   This function does basically the same thing as `sdf_generate` above
+   *   but more efficiently.
+   *
+   *   Instead of checking all pixels against all edges, we loop over all
+   *   edges and only check pixels around the control box of the edge; the
+   *   control box is increased by the spread in all directions.  Anything
+   *   outside of the control box that exceeds `spread` doesn't need to be
+   *   computed.
+   *
+   *   Lastly, to determine the sign of unchecked pixels, we do a single
+   *   pass of all rows starting with a '+' sign and flipping when we come
+   *   across a '-' sign and continue.  This also eliminates the possibility
+   *   of overflow because we only check the proximity of the curve.
+   *   Therefore we can use squared distanced safely.
+   *
+   * @Input:
+   *   internal_params ::
+   *     Internal parameters and properties required by the rasterizer.
+   *     See @SDF_Params for more.
+   *
+   *   shape ::
+   *     A complete shape which is used to generate SDF.
+   *
+   *   spread ::
+   *     Maximum distances to be allowed in the output bitmap.
+   *
+   * @Output:
+   *   bitmap ::
+   *     The output bitmap which will contain the SDF information.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  sdf_generate_bounding_box( const SDF_Params  internal_params,
+                             const SDF_Shape*  shape,
+                             FT_UInt           spread,
+                             const FT_Bitmap*  bitmap )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = NULL;
+
+    FT_Int  width, rows, i, j;
+    FT_Int  sp_sq;            /* max value to check   */
+
+    SDF_Contour*   contours;  /* list of all contours */
+    FT_SDFFormat*  buffer;    /* the bitmap buffer    */
+
+    /* This buffer has the same size in indices as the    */
+    /* bitmap buffer.  When we check a pixel position for */
+    /* a shortest distance we keep it in this buffer.     */
+    /* This way we can find out which pixel is set,       */
+    /* and also determine the signs properly.             */
+    SDF_Signed_Distance*  dists = NULL;
+
+    const FT_16D16  fixed_spread = (FT_16D16)FT_INT_16D16( spread );
+
+
+    if ( !shape || !bitmap )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( spread < MIN_SPREAD || spread > MAX_SPREAD )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    memory = shape->memory;
+    if ( !memory )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( FT_ALLOC( dists,
+                   bitmap->width * bitmap->rows * sizeof ( *dists ) ) )
+      goto Exit;
+
+    contours = shape->contours;
+    width    = (FT_Int)bitmap->width;
+    rows     = (FT_Int)bitmap->rows;
+    buffer   = (FT_SDFFormat*)bitmap->buffer;
+
+    if ( USE_SQUARED_DISTANCES )
+      sp_sq = FT_INT_16D16( (FT_Int)( spread * spread ) );
+    else
+      sp_sq = fixed_spread;
+
+    if ( width == 0 || rows == 0 )
+    {
+      FT_TRACE0(( "sdf_generate:"
+                  " Cannot render glyph with width/height == 0\n" ));
+      FT_TRACE0(( "             "
+                  " (width, height provided [%d, %d])", width, rows ));
+
+      error = FT_THROW( Cannot_Render_Glyph );
+      goto Exit;
+    }
+
+    /* loop over all contours */
+    while ( contours )
+    {
+      SDF_Edge*  edges = contours->edges;
+
+
+      /* loop over all edges */
+      while ( edges )
+      {
+        FT_CBox  cbox;
+        FT_Int   x, y;
+
+
+        /* get the control box and increase it by `spread' */
+        cbox = get_control_box( *edges );
+
+        cbox.xMin = ( cbox.xMin - 63 ) / 64 - ( FT_Pos )spread;
+        cbox.xMax = ( cbox.xMax + 63 ) / 64 + ( FT_Pos )spread;
+        cbox.yMin = ( cbox.yMin - 63 ) / 64 - ( FT_Pos )spread;
+        cbox.yMax = ( cbox.yMax + 63 ) / 64 + ( FT_Pos )spread;
+
+        /* now loop over the pixels in the control box. */
+        for ( y = cbox.yMin; y < cbox.yMax; y++ )
+        {
+          for ( x = cbox.xMin; x < cbox.xMax; x++ )
+          {
+            FT_26D6_Vec          grid_point = zero_vector;
+            SDF_Signed_Distance  dist       = max_sdf;
+            FT_UInt              index      = 0;
+            FT_16D16             diff       = 0;
+
+
+            if ( x < 0 || x >= width )
+              continue;
+            if ( y < 0 || y >= rows )
+              continue;
+
+            grid_point.x = FT_INT_26D6( x );
+            grid_point.y = FT_INT_26D6( y );
+
+            /* This `grid_point` is at the corner, but we */
+            /* use the center of the pixel.               */
+            grid_point.x += FT_INT_26D6( 1 ) / 2;
+            grid_point.y += FT_INT_26D6( 1 ) / 2;
+
+            FT_CALL( sdf_edge_get_min_distance( edges,
+                                                grid_point,
+                                                &dist ) );
+
+            if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT )
+              dist.sign = -dist.sign;
+
+            /* ignore if the distance is greater than spread;       */
+            /* otherwise it creates artifacts due to the wrong sign */
+            if ( dist.distance > sp_sq )
+              continue;
+
+            /* take the square root of the distance if required */
+            if ( USE_SQUARED_DISTANCES )
+              dist.distance = square_root( dist.distance );
+
+            if ( internal_params.flip_y )
+              index = (FT_UInt)( y * width + x );
+            else
+              index = (FT_UInt)( ( rows - y - 1 ) * width + x );
+
+            /* check whether the pixel is set or not */
+            if ( dists[index].sign == 0 )
+              dists[index] = dist;
+            else
+            {
+              diff = FT_ABS( dists[index].distance - dist.distance );
+
+              if ( diff <= CORNER_CHECK_EPSILON )
+                dists[index] = resolve_corner( dists[index], dist );
+              else if ( dists[index].distance > dist.distance )
+                dists[index] = dist;
+            }
+          }
+        }
+
+        edges = edges->next;
+      }
+
+      contours = contours->next;
+    }
+
+    /* final pass */
+    for ( j = 0; j < rows; j++ )
+    {
+      /* We assume the starting pixel of each row is outside. */
+      FT_Char  current_sign = -1;
+      FT_UInt  index;
+
+
+      if ( internal_params.overload_sign != 0 )
+        current_sign = internal_params.overload_sign < 0 ? -1 : 1;
+
+      for ( i = 0; i < width; i++ )
+      {
+        index = (FT_UInt)( j * width + i );
+
+        /* if the pixel is not set                     */
+        /* its shortest distance is more than `spread` */
+        if ( dists[index].sign == 0 )
+          dists[index].distance = fixed_spread;
+        else
+          current_sign = dists[index].sign;
+
+        /* clamp the values */
+        if ( dists[index].distance > fixed_spread )
+          dists[index].distance = fixed_spread;
+
+        /* flip sign if required */
+        dists[index].distance *= internal_params.flip_sign ? -current_sign
+                                                           :  current_sign;
+
+        /* concatenate to appropriate format */
+        buffer[index] = map_fixed_to_sdf( dists[index].distance,
+                                          fixed_spread );
+      }
+    }
+
+  Exit:
+    FT_FREE( dists );
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   sdf_generate_subdivision
+   *
+   * @Description:
+   *   Subdivide the shape into a number of straight lines, then use the
+   *   above `sdf_generate_bounding_box` function to generate the SDF.
+   *
+   *   Note: After calling this function `shape` no longer has the original
+   *         edges, it only contains lines.
+   *
+   * @Input:
+   *   internal_params ::
+   *     Internal parameters and properties required by the rasterizer.
+   *     See @SDF_Params for more.
+   *
+   *   shape ::
+   *     A complete shape which is used to generate SDF.
+   *
+   *   spread ::
+   *     Maximum distances to be allowed inthe output bitmap.
+   *
+   * @Output:
+   *   bitmap ::
+   *     The output bitmap which will contain the SDF information.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  sdf_generate_subdivision( const SDF_Params  internal_params,
+                            SDF_Shape*        shape,
+                            FT_UInt           spread,
+                            const FT_Bitmap*  bitmap )
+  {
+    /*
+     * Thanks to Alexei for providing the idea of this optimization.
+     *
+     * We take advantage of two facts.
+     *
+     * (1) Computing the shortest distance from a point to a line segment is
+     *     very fast.
+     * (2) We don't have to compute the shortest distance for the entire
+     *     two-dimensional grid.
+     *
+     * Both ideas lead to the following optimization.
+     *
+     * (1) Split the outlines into a number of line segments.
+     *
+     * (2) For each line segment, only process its neighborhood.
+     *
+     * (3) Compute the closest distance to the line only for neighborhood
+     *     grid points.
+     *
+     * This greatly reduces the number of grid points to check.
+     */
+
+    FT_Error  error = FT_Err_Ok;
+
+
+    FT_CALL( split_sdf_shape( shape ) );
+    FT_CALL( sdf_generate_bounding_box( internal_params,
+                                        shape, spread, bitmap ) );
+
+  Exit:
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   sdf_generate_with_overlaps
+   *
+   * @Description:
+   *   This function can be used to generate SDF for glyphs with overlapping
+   *   contours.  The function generates SDF for contours separately on
+   *   separate bitmaps (to generate SDF it uses
+   *   `sdf_generate_subdivision`).  At the end it simply combines all the
+   *   SDF into the output bitmap; this fixes all the signs and removes
+   *   overlaps.
+   *
+   * @Input:
+   *   internal_params ::
+   *     Internal parameters and properties required by the rasterizer.  See
+   *     @SDF_Params for more.
+   *
+   *   shape ::
+   *     A complete shape which is used to generate SDF.
+   *
+   *   spread ::
+   *     Maximum distances to be allowed in the output bitmap.
+   *
+   * @Output:
+   *   bitmap ::
+   *     The output bitmap which will contain the SDF information.
+   *
+   * @Return:
+   *   FreeType error, 0 means success.
+   *
+   * @Note:
+   *   The function cannot generate a proper SDF for glyphs with
+   *   self-intersecting contours because we cannot separate them into two
+   *   separate bitmaps.  In case of self-intersecting contours it is
+   *   necessary to remove the overlaps before generating the SDF.
+   *
+   */
+  static FT_Error
+  sdf_generate_with_overlaps( SDF_Params        internal_params,
+                              SDF_Shape*        shape,
+                              FT_UInt           spread,
+                              const FT_Bitmap*  bitmap )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    FT_Int      num_contours;        /* total number of contours      */
+    FT_Int      i, j;                /* iterators                     */
+    FT_Int      width, rows;         /* width and rows of the bitmap  */
+    FT_Bitmap*  bitmaps;             /* separate bitmaps for contours */
+
+    SDF_Contour*  contour;           /* temporary variable to iterate */
+    SDF_Contour*  temp_contour;      /* temporary contour             */
+    SDF_Contour*  head;              /* head of the contour list      */
+    SDF_Shape     temp_shape;        /* temporary shape               */
+
+    FT_Memory      memory;           /* to allocate memory            */
+    FT_SDFFormat*  t;                /* target bitmap buffer          */
+    FT_Bool        flip_sign;        /* flip sign?                    */
+
+    /* orientation of all the separate contours */
+    SDF_Contour_Orientation*  orientations;
+
+
+    bitmaps      = NULL;
+    orientations = NULL;
+    head         = NULL;
+
+    if ( !shape || !bitmap || !shape->memory )
+      return FT_THROW( Invalid_Argument );
+
+    /* Disable `flip_sign` to avoid extra complication */
+    /* during the combination phase.                   */
+    flip_sign                 = internal_params.flip_sign;
+    internal_params.flip_sign = 0;
+
+    contour           = shape->contours;
+    memory            = shape->memory;
+    temp_shape.memory = memory;
+    width             = (FT_Int)bitmap->width;
+    rows              = (FT_Int)bitmap->rows;
+    num_contours      = 0;
+
+    /* find the number of contours in the shape */
+    while ( contour )
+    {
+      num_contours++;
+      contour = contour->next;
+    }
+
+    /* allocate the bitmaps to generate SDF for separate contours */
+    if ( FT_ALLOC( bitmaps,
+                   (FT_UInt)num_contours * sizeof ( *bitmaps ) ) )
+      goto Exit;
+
+    /* allocate array to hold orientation for all contours */
+    if ( FT_ALLOC( orientations,
+                   (FT_UInt)num_contours * sizeof ( *orientations ) ) )
+      goto Exit;
+
+    contour = shape->contours;
+
+    /* Iterate over all contours and generate SDF separately. */
+    for ( i = 0; i < num_contours; i++ )
+    {
+      /* initialize the corresponding bitmap */
+      FT_Bitmap_Init( &bitmaps[i] );
+
+      bitmaps[i].width      = bitmap->width;
+      bitmaps[i].rows       = bitmap->rows;
+      bitmaps[i].pitch      = bitmap->pitch;
+      bitmaps[i].num_grays  = bitmap->num_grays;
+      bitmaps[i].pixel_mode = bitmap->pixel_mode;
+
+      /* allocate memory for the buffer */
+      if ( FT_ALLOC( bitmaps[i].buffer,
+                     bitmap->rows * (FT_UInt)bitmap->pitch ) )
+        goto Exit;
+
+      /* determine the orientation */
+      orientations[i] = get_contour_orientation( contour );
+
+      /* The `overload_sign` property is specific to  */
+      /* `sdf_generate_bounding_box`.  This basically */
+      /* overloads the default sign of the outside    */
+      /* pixels, which is necessary for               */
+      /* counter-clockwise contours.                  */
+      if ( orientations[i] == SDF_ORIENTATION_CCW                   &&
+           internal_params.orientation == FT_ORIENTATION_FILL_RIGHT )
+        internal_params.overload_sign = 1;
+      else if ( orientations[i] == SDF_ORIENTATION_CW                   &&
+                internal_params.orientation == FT_ORIENTATION_FILL_LEFT )
+        internal_params.overload_sign = 1;
+      else
+        internal_params.overload_sign = 0;
+
+      /* Make `contour->next` NULL so that there is   */
+      /* one contour in the list.  Also hold the next */
+      /* contour in a temporary variable so as to     */
+      /* restore the original value.                  */
+      temp_contour  = contour->next;
+      contour->next = NULL;
+
+      /* Use `temp_shape` to hold the new contour. */
+      /* Now, `temp_shape` has only one contour.   */
+      temp_shape.contours = contour;
+
+      /* finally generate the SDF */
+      FT_CALL( sdf_generate_subdivision( internal_params,
+                                         &temp_shape,
+                                         spread,
+                                         &bitmaps[i] ) );
+
+      /* Restore the original `next` variable. */
+      contour->next = temp_contour;
+
+      /* Since `split_sdf_shape` deallocated the original */
+      /* contours list we need to assign the new value to */
+      /* the shape's contour.                             */
+      temp_shape.contours->next = head;
+      head                      = temp_shape.contours;
+
+      /* Simply flip the orientation in case of post-script fonts */
+      /* so as to avoid modificatons in the combining phase.      */
+      if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT )
+      {
+        if ( orientations[i] == SDF_ORIENTATION_CW )
+          orientations[i] = SDF_ORIENTATION_CCW;
+        else if ( orientations[i] == SDF_ORIENTATION_CCW )
+          orientations[i] = SDF_ORIENTATION_CW;
+      }
+
+      contour = contour->next;
+    }
+
+    /* assign the new contour list to `shape->contours` */
+    shape->contours = head;
+
+    /* cast the output bitmap buffer */
+    t = (FT_SDFFormat*)bitmap->buffer;
+
+    /* Iterate over all pixels and combine all separate    */
+    /* contours.  These are the rules for combining:       */
+    /*                                                     */
+    /* (1) For all clockwise contours, compute the largest */
+    /*     value.  Name this as `val_c`.                   */
+    /* (2) For all counter-clockwise contours, compute the */
+    /*     smallest value.  Name this as `val_ac`.         */
+    /* (3) Now, finally use the smaller value of `val_c'   */
+    /*     and `val_ac'.                                   */
+    for ( j = 0; j < rows; j++ )
+    {
+      for ( i = 0; i < width; i++ )
+      {
+        FT_Int  id = j * width + i;       /* index of current pixel    */
+        FT_Int  c;                        /* contour iterator          */
+
+        FT_SDFFormat  val_c  = 0;         /* max clockwise value       */
+        FT_SDFFormat  val_ac = UCHAR_MAX; /* min counter-clockwise val */
+
+
+        /* iterate through all the contours */
+        for ( c = 0; c < num_contours; c++ )
+        {
+          /* current contour value */
+          FT_SDFFormat  temp = ( (FT_SDFFormat*)bitmaps[c].buffer )[id];
+
+
+          if ( orientations[c] == SDF_ORIENTATION_CW )
+            val_c = FT_MAX( val_c, temp );   /* clockwise         */
+          else
+            val_ac = FT_MIN( val_ac, temp ); /* counter-clockwise */
+        }
+
+        /* Finally find the smaller of the two and assign to output. */
+        /* Also apply `flip_sign` if set.                            */
+        t[id] = FT_MIN( val_c, val_ac );
+
+        if ( flip_sign )
+          t[id] = invert_sign( t[id] );
+      }
+    }
+
+  Exit:
+    /* deallocate orientations array */
+    if ( orientations )
+      FT_FREE( orientations );
+
+    /* deallocate temporary bitmaps */
+    if ( bitmaps )
+    {
+      if ( num_contours == 0 )
+        error = FT_THROW( Raster_Corrupted );
+      else
+      {
+        for ( i = 0; i < num_contours; i++ )
+          FT_FREE( bitmaps[i].buffer );
+
+        FT_FREE( bitmaps );
+      }
+    }
+
+    /* restore the `flip_sign` property */
+    internal_params.flip_sign = flip_sign;
+
+    return error;
+  }
+
+
+  /**************************************************************************
+   *
+   * interface functions
+   *
+   */
+
+  static FT_Error
+  sdf_raster_new( FT_Memory     memory,
+                  SDF_PRaster*  araster )
+  {
+    FT_Error     error;
+    SDF_PRaster  raster = NULL;
+
+
+    if ( !FT_NEW( raster ) )
+      raster->memory = memory;
+
+    *araster = raster;
+
+   return error;
+  }
+
+
+  static void
+  sdf_raster_reset( FT_Raster       raster,
+                    unsigned char*  pool_base,
+                    unsigned long   pool_size )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( pool_base );
+    FT_UNUSED( pool_size );
+  }
+
+
+  static FT_Error
+  sdf_raster_set_mode( FT_Raster      raster,
+                       unsigned long  mode,
+                       void*          args )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( mode );
+    FT_UNUSED( args );
+
+    return FT_Err_Ok;
+  }
+
+
+  static FT_Error
+  sdf_raster_render( FT_Raster                raster,
+                     const FT_Raster_Params*  params )
+  {
+    FT_Error                  error      = FT_Err_Ok;
+    SDF_TRaster*              sdf_raster = (SDF_TRaster*)raster;
+    FT_Outline*               outline    = NULL;
+    const SDF_Raster_Params*  sdf_params = (const SDF_Raster_Params*)params;
+
+    FT_Memory   memory = NULL;
+    SDF_Shape*  shape  = NULL;
+    SDF_Params  internal_params;
+
+
+    /* check for valid arguments */
+    if ( !sdf_raster || !sdf_params )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    outline = (FT_Outline*)sdf_params->root.source;
+
+    /* check whether outline is valid */
+    if ( !outline )
+    {
+      error = FT_THROW( Invalid_Outline );
+      goto Exit;
+    }
+
+    /* if the outline is empty, return */
+    if ( outline->n_points <= 0 || outline->n_contours <= 0 )
+      goto Exit;
+
+    /* check whether the outline has valid fields */
+    if ( !outline->contours || !outline->points )
+    {
+      error = FT_THROW( Invalid_Outline );
+      goto Exit;
+    }
+
+    /* check whether spread is set properly */
+    if ( sdf_params->spread > MAX_SPREAD ||
+         sdf_params->spread < MIN_SPREAD )
+    {
+      FT_TRACE0(( "sdf_raster_render:"
+                  " The `spread' field of `SDF_Raster_Params' is invalid,\n" ));
+      FT_TRACE0(( "                  "
+                  " the value of this field must be within [%d, %d].\n",
+                  MIN_SPREAD, MAX_SPREAD ));
+      FT_TRACE0(( "                  "
+                  " Also, you must pass `SDF_Raster_Params' instead of\n" ));
+      FT_TRACE0(( "                  "
+                  " the default `FT_Raster_Params' while calling\n" ));
+      FT_TRACE0(( "                  "
+                  " this function and set the fields properly.\n" ));
+
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    memory = sdf_raster->memory;
+    if ( !memory )
+    {
+      FT_TRACE0(( "sdf_raster_render:"
+                  " Raster not setup properly,\n" ));
+      FT_TRACE0(( "                  "
+                  " unable to find memory handle.\n" ));
+
+      error = FT_THROW( Invalid_Handle );
+      goto Exit;
+    }
+
+    /* set up the parameters */
+    internal_params.orientation   = FT_Outline_Get_Orientation( outline );
+    internal_params.flip_sign     = sdf_params->flip_sign;
+    internal_params.flip_y        = sdf_params->flip_y;
+    internal_params.overload_sign = 0;
+
+    FT_CALL( sdf_shape_new( memory, &shape ) );
+
+    FT_CALL( sdf_outline_decompose( outline, shape ) );
+
+    if ( sdf_params->overlaps )
+      FT_CALL( sdf_generate_with_overlaps( internal_params,
+                                           shape, sdf_params->spread,
+                                           sdf_params->root.target ) );
+    else
+      FT_CALL( sdf_generate_subdivision( internal_params,
+                                         shape, sdf_params->spread,
+                                         sdf_params->root.target ) );
+
+    if ( shape )
+      sdf_shape_done( &shape );
+
+  Exit:
+    return error;
+  }
+
+
+  static void
+  sdf_raster_done( FT_Raster  raster )
+  {
+    FT_Memory  memory = (FT_Memory)((SDF_TRaster*)raster)->memory;
+
+
+    FT_FREE( raster );
+  }
+
+
+  FT_DEFINE_RASTER_FUNCS(
+    ft_sdf_raster,
+
+    FT_GLYPH_FORMAT_OUTLINE,
+
+    (FT_Raster_New_Func)     sdf_raster_new,       /* raster_new      */
+    (FT_Raster_Reset_Func)   sdf_raster_reset,     /* raster_reset    */
+    (FT_Raster_Set_Mode_Func)sdf_raster_set_mode,  /* raster_set_mode */
+    (FT_Raster_Render_Func)  sdf_raster_render,    /* raster_render   */
+    (FT_Raster_Done_Func)    sdf_raster_done       /* raster_done     */
+  )
+
+
+/* END */
diff --git a/src/sdf/ftsdf.h b/src/sdf/ftsdf.h
new file mode 100644
index 0000000..234c075
--- /dev/null
+++ b/src/sdf/ftsdf.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+ *
+ * ftsdf.h
+ *
+ *   Signed Distance Field support (specification).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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 FTSDF_H_
+#define FTSDF_H_
+
+#include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
+#include <freetype/ftimage.h>
+
+/* common properties and function */
+#include "ftsdfcommon.h"
+
+FT_BEGIN_HEADER
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   SDF_Raster_Params
+   *
+   * @description:
+   *   This struct must be passed to the raster render function
+   *   @FT_Raster_RenderFunc instead of @FT_Raster_Params because the
+   *   rasterizer requires some additional information to render properly.
+   *
+   * @fields:
+   *   root ::
+   *     The native raster parameters structure.
+   *
+   *   spread ::
+   *     This is an essential parameter/property required by the renderer.
+   *     `spread` defines the maximum unsigned value that is present in the
+   *     final SDF output.  For the default value check file
+   *     `ftsdfcommon.h`.
+   *
+   *   flip_sign ::
+   *     By default positive values indicate positions inside of contours,
+   *     i.e., filled by a contour.  If this property is true then that
+   *     output will be the opposite of the default, i.e., negative values
+   *     indicate positions inside of contours.
+   *
+   *   flip_y ::
+   *     Setting this parameter to true maked the output image flipped
+   *     along the y-axis.
+   *
+   *   overlaps ::
+   *     Set this to true to generate SDF for glyphs having overlapping
+   *     contours.  The overlapping support is limited to glyphs that do not
+   *     have self-intersecting contours.  Also, removing overlaps require a
+   *     considerable amount of extra memory; additionally, it will not work
+   *     if generating SDF from bitmap.
+   *
+   * @note:
+   *   All properties are valid for both the 'sdf' and 'bsdf' renderers; the
+   *   exception is `overlaps`, which gets ignored by the 'bsdf' renderer.
+   *
+   */
+  typedef struct  SDF_Raster_Params_
+  {
+    FT_Raster_Params  root;
+    FT_UInt           spread;
+    FT_Bool           flip_sign;
+    FT_Bool           flip_y;
+    FT_Bool           overlaps;
+
+  } SDF_Raster_Params;
+
+
+  /* rasterizer to convert outline to SDF */
+  FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_sdf_raster;
+
+  /* rasterizer to convert bitmap to SDF */
+  FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_bitmap_sdf_raster;
+
+FT_END_HEADER
+
+#endif /* FTSDF_H_ */
+
+
+/* END */
diff --git a/src/sdf/ftsdfcommon.c b/src/sdf/ftsdfcommon.c
new file mode 100644
index 0000000..5052201
--- /dev/null
+++ b/src/sdf/ftsdfcommon.c
@@ -0,0 +1,147 @@
+/****************************************************************************
+ *
+ * ftsdfcommon.c
+ *
+ *   Auxiliary data for Signed Distance Field support (body).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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 "ftsdf.h"
+#include "ftsdfcommon.h"
+
+
+  /**************************************************************************
+   *
+   * common functions
+   *
+   */
+
+  /*
+   * Original algorithm:
+   *
+   *   https://github.com/chmike/fpsqrt
+   *
+   * Use this to compute the square root of a 16.16 fixed-point number.
+   */
+  FT_LOCAL_DEF( FT_16D16 )
+  square_root( FT_16D16  val )
+  {
+    FT_ULong  t, q, b, r;
+
+
+    r = (FT_ULong)val;
+    b = 0x40000000L;
+    q = 0;
+
+    while ( b > 0x40L )
+    {
+      t = q + b;
+
+      if ( r >= t )
+      {
+        r -= t;
+        q  = t + b;
+      }
+
+      r <<= 1;
+      b >>= 1;
+    }
+
+    q >>= 8;
+
+    return (FT_16D16)q;
+  }
+
+
+  /**************************************************************************
+   *
+   * format and sign manipulating functions
+   *
+   */
+
+  /*
+   * Convert 16.16 fixed-point values to the desired output format.
+   * In this case we reduce 16.16 fixed-point values to normalized
+   * 8-bit values.
+   *
+   * The `max_value` in the parameter is the maximum value in the
+   * distance field map and is equal to the spread.  We normalize
+   * the distances using this value instead of computing the maximum
+   * value for the entire bitmap.
+   *
+   * You can use this function to map the 16.16 signed values to any
+   * format required.  Do note that the output buffer is 8-bit, so only
+   * use an 8-bit format for `FT_SDFFormat`, or increase the buffer size in
+   * `ftsdfrend.c`.
+   */
+  FT_LOCAL_DEF( FT_SDFFormat )
+  map_fixed_to_sdf( FT_16D16  dist,
+                    FT_16D16  max_value )
+  {
+    FT_SDFFormat  out;
+    FT_16D16      udist;
+
+
+    /* normalize the distance values */
+    dist = FT_DivFix( dist, max_value );
+
+    udist = dist < 0 ? -dist : dist;
+
+    /* Reduce the distance values to 8 bits.                   */
+    /*                                                         */
+    /* Since +1/-1 in 16.16 takes the 16th bit, we right-shift */
+    /* the number by 9 to make it fit into the 7-bit range.    */
+    /*                                                         */
+    /* One bit is reserved for the sign.                       */
+    udist >>= 9;
+
+    /* Since `char` can only store a maximum positive value    */
+    /* of 127 we need to make sure it does not wrap around and */
+    /* give a negative value.                                  */
+    if ( dist > 0 && udist > 127 )
+      udist = 127;
+    if ( dist < 0 && udist > 128 )
+      udist = 128;
+
+    /* Output the data; negative values are from [0, 127] and positive    */
+    /* from [128, 255].  One important thing is that negative values      */
+    /* are inverted here, that means [0, 128] maps to [-128, 0] linearly. */
+    /* More on that in `freetype.h` near the documentation of             */
+    /* `FT_RENDER_MODE_SDF`.                                              */
+    out = dist < 0 ? 128 - (FT_SDFFormat)udist
+                   : (FT_SDFFormat)udist + 128;
+
+    return out;
+  }
+
+
+  /*
+   * Invert the signed distance packed into the corresponding format.
+   * So if the values are negative they will become positive in the
+   * chosen format.
+   *
+   * [Note]: This function should only be used after converting the
+   *         16.16 signed distance values to `FT_SDFFormat`.  If that
+   *         conversion has not been done, then simply invert the sign
+   *         and use the above function to pack the values.
+   */
+  FT_LOCAL_DEF( FT_SDFFormat )
+  invert_sign( FT_SDFFormat  dist )
+  {
+    return 255 - dist;
+  }
+
+
+/* END */
diff --git a/src/sdf/ftsdfcommon.h b/src/sdf/ftsdfcommon.h
new file mode 100644
index 0000000..60ca977
--- /dev/null
+++ b/src/sdf/ftsdfcommon.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+ *
+ * ftsdfcommon.h
+ *
+ *   Auxiliary data for Signed Distance Field support (specification).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+  /****************************************************
+   *
+   * This file contains common functions and properties
+   * for both the 'sdf' and 'bsdf' renderers.
+   *
+   */
+
+#ifndef FTSDFCOMMON_H_
+#define FTSDFCOMMON_H_
+
+#include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
+#include <freetype/internal/ftobjs.h>
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * default values (cannot be set individually for each renderer)
+   *
+   */
+
+  /* default spread value */
+#define DEFAULT_SPREAD  8
+  /* minimum spread supported by the renderer */
+#define MIN_SPREAD      2
+  /* maximum spread supported by the renderer */
+#define MAX_SPREAD      32
+  /* pixel size in 26.6 */
+#define ONE_PIXEL       ( 1 << 6 )
+
+
+  /**************************************************************************
+   *
+   * common definitions (cannot be set individually for each renderer)
+   *
+   */
+
+  /* If this macro is set to 1 the rasterizer uses squared distances for */
+  /* computation.  It can greatly improve the performance but there is a */
+  /* chance of overflow and artifacts.  You can safely use it up to a    */
+  /* pixel size of 128.                                                  */
+#ifndef USE_SQUARED_DISTANCES
+#define USE_SQUARED_DISTANCES  0
+#endif
+
+
+  /**************************************************************************
+   *
+   * common macros
+   *
+   */
+
+  /* convert int to 26.6 fixed-point   */
+#define FT_INT_26D6( x )   ( x * 64 )
+  /* convert int to 16.16 fixed-point  */
+#define FT_INT_16D16( x )  ( x * 65536 )
+  /* convert 26.6 to 16.16 fixed-point */
+#define FT_26D6_16D16( x ) ( x * 1024 )
+
+
+  /* Convenience macro to call a function; it  */
+  /* jumps to label `Exit` if an error occurs. */
+#define FT_CALL( x ) do                          \
+                     {                           \
+                       error = ( x );            \
+                       if ( error != FT_Err_Ok ) \
+                         goto Exit;              \
+                     } while ( 0 )
+
+
+  /*
+   * The macro `VECTOR_LENGTH_16D16` computes either squared distances or
+   * actual distances, depending on the value of `USE_SQUARED_DISTANCES`.
+   *
+   * By using squared distances the performance can be greatly improved but
+   * there is a risk of overflow.
+   */
+#if USE_SQUARED_DISTANCES
+#define VECTOR_LENGTH_16D16( v )  ( FT_MulFix( v.x, v.x ) + \
+                                    FT_MulFix( v.y, v.y ) )
+#else
+#define VECTOR_LENGTH_16D16( v )  FT_Vector_Length( &v )
+#endif
+
+
+  /**************************************************************************
+   *
+   * common typedefs
+   *
+   */
+
+  typedef FT_Vector FT_26D6_Vec;   /* with 26.6 fixed-point components  */
+  typedef FT_Vector FT_16D16_Vec;  /* with 16.16 fixed-point components */
+
+  typedef FT_Int32  FT_16D16;      /* 16.16 fixed-point representation  */
+  typedef FT_Int32  FT_26D6;       /* 26.6 fixed-point representation   */
+  typedef FT_Byte   FT_SDFFormat;  /* format to represent SDF data      */
+
+  typedef FT_BBox   FT_CBox;       /* control box of a curve            */
+
+
+  FT_LOCAL( FT_16D16 )
+  square_root( FT_16D16  val );
+
+  FT_LOCAL( FT_SDFFormat )
+  map_fixed_to_sdf( FT_16D16  dist,
+                    FT_16D16  max_value );
+
+  FT_LOCAL( FT_SDFFormat )
+  invert_sign( FT_SDFFormat  dist );
+
+
+FT_END_HEADER
+
+#endif /* FTSDFCOMMON_H_ */
+
+
+/* END */
diff --git a/src/sdf/ftsdferrs.h b/src/sdf/ftsdferrs.h
new file mode 100644
index 0000000..519db0f
--- /dev/null
+++ b/src/sdf/ftsdferrs.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ *
+ * ftsdferrs.h
+ *
+ *   Signed Distance Field error codes (specification only).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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 FTSDFERRS_H_
+#define FTSDFERRS_H_
+
+#include <freetype/ftmoderr.h>
+
+#undef FTERRORS_H_
+
+#undef  FT_ERR_PREFIX
+#define FT_ERR_PREFIX  Sdf_Err_
+#define FT_ERR_BASE    FT_Mod_Err_Sdf
+
+#include <freetype/fterrors.h>
+
+#endif /* FTSDFERRS_H_ */
+
+
+/* END */
diff --git a/src/sdf/ftsdfrend.c b/src/sdf/ftsdfrend.c
new file mode 100644
index 0000000..9ac7d6f
--- /dev/null
+++ b/src/sdf/ftsdfrend.c
@@ -0,0 +1,604 @@
+/****************************************************************************
+ *
+ * ftsdfrend.c
+ *
+ *   Signed Distance Field renderer interface (body).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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/ftobjs.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/ftoutln.h>
+#include <freetype/ftbitmap.h>
+#include "ftsdfrend.h"
+#include "ftsdf.h"
+
+#include "ftsdferrs.h"
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  sdf
+
+
+  /**************************************************************************
+   *
+   * macros and default property values
+   *
+   */
+#define SDF_RENDERER( rend )  ( (SDF_Renderer)rend )
+
+
+  /**************************************************************************
+   *
+   * for setting properties
+   *
+   */
+
+  /* property setter function */
+  static FT_Error
+  sdf_property_set( FT_Module    module,
+                    const char*  property_name,
+                    const void*  value,
+                    FT_Bool      value_is_string )
+  {
+    FT_Error      error  = FT_Err_Ok;
+    SDF_Renderer  render = SDF_RENDERER( FT_RENDERER( module ) );
+
+    FT_UNUSED( value_is_string );
+
+
+    if ( ft_strcmp( property_name, "spread" ) == 0 )
+    {
+      FT_Int  val = *(const FT_Int*)value;
+
+
+      if ( val > MAX_SPREAD || val < MIN_SPREAD )
+      {
+        FT_TRACE0(( "[sdf] sdf_property_set:"
+                    " the `spread' property can have a value\n" ));
+        FT_TRACE0(( "                       "
+                    " within range [%d, %d] (value provided: %d)\n",
+                    MIN_SPREAD, MAX_SPREAD, val ));
+
+        error = FT_THROW( Invalid_Argument );
+        goto Exit;
+      }
+
+      render->spread = (FT_UInt)val;
+      FT_TRACE7(( "[sdf] sdf_property_set:"
+                  " updated property `spread' to %d\n", val ));
+    }
+
+    else if ( ft_strcmp( property_name, "flip_sign" ) == 0 )
+    {
+      FT_Int  val = *(const FT_Int*)value;
+
+
+      render->flip_sign = val ? 1 : 0;
+      FT_TRACE7(( "[sdf] sdf_property_set:"
+                  " updated property `flip_sign' to %d\n", val ));
+    }
+
+    else if ( ft_strcmp( property_name, "flip_y" ) == 0 )
+    {
+      FT_Int  val = *(const FT_Int*)value;
+
+
+      render->flip_y = val ? 1 : 0;
+      FT_TRACE7(( "[sdf] sdf_property_set:"
+                  " updated property `flip_y' to %d\n", val ));
+    }
+
+    else if ( ft_strcmp( property_name, "overlaps" ) == 0 )
+    {
+      FT_Bool  val = *(const FT_Bool*)value;
+
+
+      render->overlaps = val;
+      FT_TRACE7(( "[sdf] sdf_property_set:"
+                  " updated property `overlaps' to %d\n", val ));
+    }
+
+    else
+    {
+      FT_TRACE0(( "[sdf] sdf_property_set:"
+                  " missing property `%s'\n", property_name ));
+      error = FT_THROW( Missing_Property );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /* property getter function */
+  static FT_Error
+  sdf_property_get( FT_Module    module,
+                    const char*  property_name,
+                    void*        value )
+  {
+    FT_Error      error  = FT_Err_Ok;
+    SDF_Renderer  render = SDF_RENDERER( FT_RENDERER( module ) );
+
+
+    if ( ft_strcmp( property_name, "spread" ) == 0 )
+    {
+      FT_UInt*  val = (FT_UInt*)value;
+
+
+      *val = render->spread;
+    }
+
+    else if ( ft_strcmp( property_name, "flip_sign" ) == 0 )
+    {
+      FT_Int*  val = (FT_Int*)value;
+
+
+      *val = render->flip_sign;
+    }
+
+    else if ( ft_strcmp( property_name, "flip_y" ) == 0 )
+    {
+      FT_Int*  val = (FT_Int*)value;
+
+
+      *val = render->flip_y;
+    }
+
+    else if ( ft_strcmp( property_name, "overlaps" ) == 0 )
+    {
+      FT_Int*  val = (FT_Int*)value;
+
+
+      *val = render->overlaps;
+    }
+
+    else
+    {
+      FT_TRACE0(( "[sdf] sdf_property_get:"
+                  " missing property `%s'\n", property_name ));
+      error = FT_THROW( Missing_Property );
+    }
+
+    return error;
+  }
+
+
+  FT_DEFINE_SERVICE_PROPERTIESREC(
+    sdf_service_properties,
+
+    (FT_Properties_SetFunc)sdf_property_set,        /* set_property */
+    (FT_Properties_GetFunc)sdf_property_get )       /* get_property */
+
+
+  FT_DEFINE_SERVICEDESCREC1(
+    sdf_services,
+
+    FT_SERVICE_ID_PROPERTIES, &sdf_service_properties )
+
+
+  static FT_Module_Interface
+  ft_sdf_requester( FT_Renderer  render,
+                    const char*  module_interface )
+  {
+    FT_UNUSED( render );
+
+    return ft_service_list_lookup( sdf_services, module_interface );
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  OUTLINE TO SDF CONVERTER                                           **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /**************************************************************************
+   *
+   * interface functions
+   *
+   */
+
+  static FT_Error
+  ft_sdf_init( FT_Renderer  render )
+  {
+    SDF_Renderer  sdf_render = SDF_RENDERER( render );
+
+
+    sdf_render->spread    = DEFAULT_SPREAD;
+    sdf_render->flip_sign = 0;
+    sdf_render->flip_y    = 0;
+    sdf_render->overlaps  = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+  static void
+  ft_sdf_done( FT_Renderer  render )
+  {
+    FT_UNUSED( render );
+  }
+
+
+  /* generate signed distance field from a glyph's slot image */
+  static FT_Error
+  ft_sdf_render( FT_Renderer       module,
+                 FT_GlyphSlot      slot,
+                 FT_Render_Mode    mode,
+                 const FT_Vector*  origin )
+  {
+    FT_Error     error   = FT_Err_Ok;
+    FT_Outline*  outline = &slot->outline;
+    FT_Bitmap*   bitmap  = &slot->bitmap;
+    FT_Memory    memory  = NULL;
+    FT_Renderer  render  = NULL;
+
+    FT_Pos  x_shift = 0;
+    FT_Pos  y_shift = 0;
+
+    FT_Pos  x_pad = 0;
+    FT_Pos  y_pad = 0;
+
+    SDF_Raster_Params  params;
+    SDF_Renderer       sdf_module = SDF_RENDERER( module );
+
+
+    render = &sdf_module->root;
+    memory = render->root.memory;
+
+    /* check whether slot format is correct before rendering */
+    if ( slot->format != render->glyph_format )
+    {
+      error = FT_THROW( Invalid_Glyph_Format );
+      goto Exit;
+    }
+
+    /* check whether render mode is correct */
+    if ( mode != FT_RENDER_MODE_SDF )
+    {
+      error = FT_THROW( Cannot_Render_Glyph );
+      goto Exit;
+    }
+
+    /* deallocate the previously allocated bitmap */
+    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+    {
+      FT_FREE( bitmap->buffer );
+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+    }
+
+    /* preset the bitmap using the glyph's outline;         */
+    /* the sdf bitmap is similar to an anti-aliased bitmap  */
+    /* with a slightly bigger size and different pixel mode */
+    if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) )
+    {
+      error = FT_THROW( Raster_Overflow );
+      goto Exit;
+    }
+
+    /* nothing to render */
+    if ( !bitmap->rows || !bitmap->pitch )
+      return FT_Err_Ok;
+
+    /* the padding will simply be equal to the `spread' */
+    x_pad = sdf_module->spread;
+    y_pad = sdf_module->spread;
+
+    /* apply the padding; will be in all the directions */
+    bitmap->rows  += y_pad * 2;
+    bitmap->width += x_pad * 2;
+
+    /* ignore the pitch, pixel mode and set custom */
+    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
+    bitmap->pitch      = (int)( bitmap->width );
+    bitmap->num_grays  = 255;
+
+    /* allocate new buffer */
+    if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
+      goto Exit;
+
+    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+
+    slot->bitmap_top  += y_pad;
+    slot->bitmap_left -= x_pad;
+
+    x_shift  = 64 * -slot->bitmap_left;
+    y_shift  = 64 * -slot->bitmap_top;
+    y_shift += 64 * (FT_Int)bitmap->rows;
+
+    if ( origin )
+    {
+      x_shift += origin->x;
+      y_shift += origin->y;
+    }
+
+    /* translate outline to render it into the bitmap */
+    if ( x_shift || y_shift )
+      FT_Outline_Translate( outline, x_shift, y_shift );
+
+    /* set up parameters */
+    params.root.target = bitmap;
+    params.root.source = outline;
+    params.root.flags  = FT_RASTER_FLAG_SDF;
+    params.spread      = sdf_module->spread;
+    params.flip_sign   = sdf_module->flip_sign;
+    params.flip_y      = sdf_module->flip_y;
+    params.overlaps    = sdf_module->overlaps;
+
+    /* render the outline */
+    error = render->raster_render( render->raster,
+                                   (const FT_Raster_Params*)&params );
+
+    /* transform the outline back to the original state */
+    if ( x_shift || y_shift )
+      FT_Outline_Translate( outline, -x_shift, -y_shift );
+
+  Exit:
+    if ( !error )
+    {
+      /* the glyph is successfully rendered to a bitmap */
+      slot->format = FT_GLYPH_FORMAT_BITMAP;
+    }
+    else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+    {
+      FT_FREE( bitmap->buffer );
+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+    }
+
+    return error;
+  }
+
+
+  /* transform the glyph using matrix and/or delta */
+  static FT_Error
+  ft_sdf_transform( FT_Renderer       render,
+                    FT_GlyphSlot      slot,
+                    const FT_Matrix*  matrix,
+                    const FT_Vector*  delta )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( slot->format != render->glyph_format )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( matrix )
+      FT_Outline_Transform( &slot->outline, matrix );
+
+    if ( delta )
+      FT_Outline_Translate( &slot->outline, delta->x, delta->y );
+
+  Exit:
+    return error;
+  }
+
+
+  /* return the control box of a glyph's outline */
+  static void
+  ft_sdf_get_cbox( FT_Renderer   render,
+                   FT_GlyphSlot  slot,
+                   FT_BBox*      cbox )
+  {
+    FT_ZERO( cbox );
+
+    if ( slot->format == render->glyph_format )
+      FT_Outline_Get_CBox( &slot->outline, cbox );
+  }
+
+
+  /* set render specific modes or attributes */
+  static FT_Error
+  ft_sdf_set_mode( FT_Renderer  render,
+                   FT_ULong     mode_tag,
+                   FT_Pointer   data )
+  {
+    /* pass it to the rasterizer */
+    return render->clazz->raster_class->raster_set_mode( render->raster,
+                                                         mode_tag,
+                                                         data );
+  }
+
+
+  FT_DEFINE_RENDERER(
+    ft_sdf_renderer_class,
+
+    FT_MODULE_RENDERER,
+    sizeof ( SDF_Renderer_Module ),
+
+    "sdf",
+    0x10000L,
+    0x20000L,
+
+    NULL,
+
+    (FT_Module_Constructor)ft_sdf_init,
+    (FT_Module_Destructor) ft_sdf_done,
+    (FT_Module_Requester)  ft_sdf_requester,
+
+    FT_GLYPH_FORMAT_OUTLINE,
+
+    (FT_Renderer_RenderFunc)   ft_sdf_render,     /* render_glyph    */
+    (FT_Renderer_TransformFunc)ft_sdf_transform,  /* transform_glyph */
+    (FT_Renderer_GetCBoxFunc)  ft_sdf_get_cbox,   /* get_glyph_cbox  */
+    (FT_Renderer_SetModeFunc)  ft_sdf_set_mode,   /* set_mode        */
+
+    (FT_Raster_Funcs*)&ft_sdf_raster              /* raster_class    */
+  )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  BITMAP TO SDF CONVERTER                                            **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* generate signed distance field from glyph's bitmap */
+  static FT_Error
+  ft_bsdf_render( FT_Renderer       module,
+                  FT_GlyphSlot      slot,
+                  FT_Render_Mode    mode,
+                  const FT_Vector*  origin )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = NULL;
+
+    FT_Bitmap*   bitmap  = &slot->bitmap;
+    FT_Renderer  render  = NULL;
+    FT_Bitmap    target;
+
+    FT_Pos  x_pad = 0;
+    FT_Pos  y_pad = 0;
+
+    SDF_Raster_Params  params;
+    SDF_Renderer       sdf_module = SDF_RENDERER( module );
+
+
+    /* initialize the bitmap in case any error occurs */
+    FT_Bitmap_Init( &target );
+
+    render = &sdf_module->root;
+    memory = render->root.memory;
+
+    /* check whether slot format is correct before rendering */
+    if ( slot->format != render->glyph_format )
+    {
+      error = FT_THROW( Invalid_Glyph_Format );
+      goto Exit;
+    }
+
+    /* check whether render mode is correct */
+    if ( mode != FT_RENDER_MODE_SDF )
+    {
+      error = FT_THROW( Cannot_Render_Glyph );
+      goto Exit;
+    }
+
+    if ( origin )
+    {
+      FT_ERROR(( "ft_bsdf_render: can't translate the bitmap\n" ));
+
+      error = FT_THROW( Unimplemented_Feature );
+      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 ) )
+    {
+      FT_ERROR(( "ft_bsdf_render: can't generate SDF from"
+                 " unowned source bitmap\n" ));
+
+      error = FT_THROW( Invalid_Argument );
+      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` */
+    x_pad = sdf_module->spread;
+    y_pad = sdf_module->spread;
+
+    /* apply padding, which extends to all directions */
+    target.rows  = bitmap->rows  + y_pad * 2;
+    target.width = bitmap->width + x_pad * 2;
+
+    /* set up the target bitmap */
+    target.pixel_mode = FT_PIXEL_MODE_GRAY;
+    target.pitch      = (int)( target.width );
+    target.num_grays  = 255;
+
+    if ( FT_ALLOC_MULT( target.buffer, target.rows, target.pitch ) )
+      goto Exit;
+
+    /* set up parameters */
+    params.root.target = &target;
+    params.root.source = bitmap;
+    params.root.flags  = FT_RASTER_FLAG_SDF;
+    params.spread      = sdf_module->spread;
+    params.flip_sign   = sdf_module->flip_sign;
+    params.flip_y      = sdf_module->flip_y;
+
+    error = render->raster_render( render->raster,
+                                   (const FT_Raster_Params*)&params );
+
+  Exit:
+    if ( !error )
+    {
+      /* 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;
+    }
+    else if ( target.buffer )
+      FT_FREE( target.buffer );
+
+    return error;
+  }
+
+
+  FT_DEFINE_RENDERER(
+    ft_bitmap_sdf_renderer_class,
+
+    FT_MODULE_RENDERER,
+    sizeof ( SDF_Renderer_Module ),
+
+    "bsdf",
+    0x10000L,
+    0x20000L,
+
+    NULL,
+
+    (FT_Module_Constructor)ft_sdf_init,
+    (FT_Module_Destructor) ft_sdf_done,
+    (FT_Module_Requester)  ft_sdf_requester,
+
+    FT_GLYPH_FORMAT_BITMAP,
+
+    (FT_Renderer_RenderFunc)   ft_bsdf_render,    /* render_glyph    */
+    (FT_Renderer_TransformFunc)ft_sdf_transform,  /* transform_glyph */
+    (FT_Renderer_GetCBoxFunc)  ft_sdf_get_cbox,   /* get_glyph_cbox  */
+    (FT_Renderer_SetModeFunc)  ft_sdf_set_mode,   /* set_mode        */
+
+    (FT_Raster_Funcs*)&ft_bitmap_sdf_raster       /* raster_class    */
+  )
+
+
+/* END */
diff --git a/src/sdf/ftsdfrend.h b/src/sdf/ftsdfrend.h
new file mode 100644
index 0000000..571ac83
--- /dev/null
+++ b/src/sdf/ftsdfrend.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+ *
+ * ftsdfrend.h
+ *
+ *   Signed Distance Field renderer interface (specification).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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 FTSDFREND_H_
+#define FTSDFREND_H_
+
+#include <freetype/ftrender.h>
+#include <freetype/ftmodapi.h>
+#include <freetype/internal/ftobjs.h>
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   SDF_Renderer_Module
+   *
+   * @description:
+   *   This struct extends the native renderer struct `FT_RendererRec`.  It
+   *   is basically used to store various parameters required by the
+   *   renderer and some additional parameters that can be used to tweak the
+   *   output of the renderer.
+   *
+   * @fields:
+   *   root ::
+   *     The native rendere struct.
+   *
+   *   spread ::
+   *     This is an essential parameter/property required by the renderer.
+   *     `spread` defines the maximum unsigned value that is present in the
+   *     final SDF output.  For the default value check file
+   *     `ftsdfcommon.h`.
+   *
+   *   flip_sign ::
+   *     By default positive values indicate positions inside of contours,
+   *     i.e., filled by a contour.  If this property is true then that
+   *     output will be the opposite of the default, i.e., negative values
+   *     indicate positions inside of contours.
+   *
+   *   flip_y ::
+   *     Setting this parameter to true makes the output image flipped
+   *     along the y-axis.
+   *
+   *   overlaps ::
+   *     Set this to true to generate SDF for glyphs having overlapping
+   *     contours.  The overlapping support is limited to glyphs that do not
+   *     have self-intersecting contours.  Also, removing overlaps require a
+   *     considerable amount of extra memory; additionally, it will not work
+   *     if generating SDF from bitmap.
+   *
+   * @note:
+   *   All properties except `overlaps` are valid for both the 'sdf' and
+   *   'bsdf' renderers.
+   *
+   */
+  typedef struct  SDF_Renderer_Module_
+  {
+    FT_RendererRec  root;
+    FT_UInt         spread;
+    FT_Bool         flip_sign;
+    FT_Bool         flip_y;
+    FT_Bool         overlaps;
+
+  } SDF_Renderer_Module, *SDF_Renderer;
+
+
+  /**************************************************************************
+   *
+   * @renderer:
+   *   ft_sdf_renderer_class
+   *
+   * @description:
+   *   Renderer to convert @FT_Outline to signed distance fields.
+   *
+   */
+  FT_DECLARE_RENDERER( ft_sdf_renderer_class )
+
+
+  /**************************************************************************
+   *
+   * @renderer:
+   *   ft_bitmap_sdf_renderer_class
+   *
+   * @description:
+   *   This is not exactly a renderer; it is just a converter that
+   *   transforms bitmaps to signed distance fields.
+   *
+   * @note:
+   *   This is not a separate module, it is part of the 'sdf' module.
+   *
+   */
+  FT_DECLARE_RENDERER( ft_bitmap_sdf_renderer_class )
+
+
+FT_END_HEADER
+
+#endif /* FTSDFREND_H_ */
+
+
+/* END */
diff --git a/src/sdf/module.mk b/src/sdf/module.mk
new file mode 100644
index 0000000..e896d20
--- /dev/null
+++ b/src/sdf/module.mk
@@ -0,0 +1,29 @@
+#
+# FreeType 2 Signed Distance Field module definition
+#
+
+
+# Copyright (C) 2020-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.
+
+
+FTMODULE_H_COMMANDS += SDF_RENDERER
+FTMODULE_H_COMMANDS += BSDF_RENDERER
+
+define SDF_RENDERER
+$(OPEN_DRIVER) FT_Renderer_Class, ft_sdf_renderer_class $(CLOSE_DRIVER)
+$(ECHO_DRIVER)sdf       $(ECHO_DRIVER_DESC)signed distance field renderer$(ECHO_DRIVER_DONE)
+endef
+
+define BSDF_RENDERER
+$(OPEN_DRIVER) FT_Renderer_Class, ft_bitmap_sdf_renderer_class $(CLOSE_DRIVER)
+$(ECHO_DRIVER)bsdf      $(ECHO_DRIVER_DESC)bitmap to signed distance field converter$(ECHO_DRIVER_DONE)
+endef
+
+#EOF
diff --git a/src/sdf/rules.mk b/src/sdf/rules.mk
new file mode 100644
index 0000000..d774241
--- /dev/null
+++ b/src/sdf/rules.mk
@@ -0,0 +1,78 @@
+#
+# FreeType 2 Signed Distance Field driver configuration rules
+#
+
+
+# Copyright (C) 2020-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.
+
+
+# sdf driver directory
+#
+SDF_DIR := $(SRC_DIR)/sdf
+
+
+# compilation flags for the driver
+#
+SDF_COMPILE := $(CC) $(ANSIFLAGS)                            \
+                     $I$(subst /,$(COMPILER_SEP),$(SDF_DIR)) \
+                     $(INCLUDE_FLAGS)                        \
+                     $(FT_CFLAGS)
+
+
+# sdf driver sources (i.e., C files)
+#
+SDF_DRV_SRC := $(SDF_DIR)/ftsdfrend.c   \
+               $(SDF_DIR)/ftsdf.c       \
+               $(SDF_DIR)/ftbsdf.c      \
+               $(SDF_DIR)/ftsdfcommon.c
+
+
+# sdf driver headers
+#
+SDF_DRV_H := $(SDF_DIR)/ftsdfrend.h   \
+             $(SDF_DIR)/ftsdf.h       \
+             $(SDF_DIR)/ftsdferrs.h   \
+             $(SDF_DIR)/ftsdfcommon.h
+
+
+# sdf driver object(s)
+#
+#   SDF_DRV_OBJ_M is used during `multi' builds.
+#   SDF_DRV_OBJ_S is used during `single' builds.
+#
+SDF_DRV_OBJ_M := $(SDF_DRV_SRC:$(SDF_DIR)/%.c=$(OBJ_DIR)/%.$O)
+SDF_DRV_OBJ_S := $(OBJ_DIR)/sdf.$O
+
+
+# sdf driver source file for single build
+#
+SDF_DRV_SRC_S := $(SDF_DIR)/sdf.c
+
+
+# sdf driver - single object
+#
+$(SDF_DRV_OBJ_S): $(SDF_DRV_SRC_S) $(SDF_DRV_SRC) \
+                  $(FREETYPE_H) $(SDF_DRV_H)
+	$(SDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SDF_DRV_SRC_S))
+
+
+# sdf driver - multiple objects
+#
+$(OBJ_DIR)/%.$O: $(SDF_DIR)/%.c $(FREETYPE_H) $(SDF_DRV_H)
+	$(SDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+
+
+# update main driver list
+#
+DRV_OBJS_S += $(SDF_DRV_OBJ_S)
+DRV_OBJS_M += $(SDF_DRV_OBJ_M)
+
+
+# EOF
diff --git a/src/sdf/sdf.c b/src/sdf/sdf.c
new file mode 100644
index 0000000..c159b08
--- /dev/null
+++ b/src/sdf/sdf.c
@@ -0,0 +1,29 @@
+/****************************************************************************
+ *
+ * sdf.c
+ *
+ *   FreeType Signed Distance Field renderer module component (body only).
+ *
+ * Copyright (C) 2020-2023 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * Written by Anuj Verma.
+ *
+ * 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.
+ *
+ */
+
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+#include "ftsdfrend.c"
+#include "ftsdfcommon.c"
+#include "ftbsdf.c"
+#include "ftsdf.c"
+
+
+/* END */
diff --git a/src/sfnt/Jamfile b/src/sfnt/Jamfile
deleted file mode 100644
index 635aa60..0000000
--- a/src/sfnt/Jamfile
+++ /dev/null
@@ -1,42 +0,0 @@
-# FreeType 2 src/sfnt Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) sfnt ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = pngshim
-               sfdriver
-               sfntpic
-               sfobjs
-               ttbdf
-               ttcmap
-               ttcolr
-               ttcpal
-               ttkern
-               ttload
-               ttmtx
-               ttpost
-               ttsbit
-               ;
-  }
-  else
-  {
-    _sources = sfnt ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/sfnt Jamfile
diff --git a/src/sfnt/module.mk b/src/sfnt/module.mk
index 51ca67e..4491a1b 100644
--- a/src/sfnt/module.mk
+++ b/src/sfnt/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index 0674bda..423b07b 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -4,7 +4,7 @@
  *
  *   PNG Bitmap glyph support.
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * Google, Inc.
  * Written by Stuart Gill and Behdad Esfahbod.
  *
@@ -17,10 +17,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
 
@@ -61,13 +60,19 @@
     /* predates clang; the `__BYTE_ORDER__' preprocessor symbol was */
     /* introduced in gcc 4.6 and clang 3.2, respectively.           */
     /* `__builtin_shuffle' for gcc was introduced in gcc 4.7.0.     */
-#if ( ( defined( __GNUC__ )                                &&             \
+    /*                                                              */
+    /* Intel compilers do not currently support __builtin_shuffle;  */
+
+    /* The Intel check must be first. */
+#if !defined( __INTEL_COMPILER )                                       && \
+    ( ( defined( __GNUC__ )                                &&             \
         ( ( __GNUC__ >= 5 )                              ||               \
         ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 7 ) ) ) )         ||   \
       ( defined( __clang__ )                                       &&     \
         ( ( __clang_major__ >= 4 )                               ||       \
         ( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \
     defined( __OPTIMIZE__ )                                            && \
+    defined( __SSE__ )                                                 && \
     __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 
 #ifdef __clang__
@@ -234,7 +239,7 @@
       *e = FT_THROW( Invalid_Stream_Read );
       png_error( png, NULL );
 
-      return;
+      /* return; (never reached) */
     }
 
     ft_memcpy( data, stream->cursor, length );
@@ -265,7 +270,10 @@
 
     int         bitdepth, color_type, interlace;
     FT_Int      i;
-    png_byte*  *rows = NULL; /* pacify compiler */
+
+    /* `rows` gets modified within a 'setjmp' scope; */
+    /* we thus need the `volatile` keyword.          */
+    png_byte* *volatile  rows = NULL;
 
 
     if ( x_offset < 0 ||
@@ -327,6 +335,13 @@
 
     if ( populate_map_and_metrics )
     {
+      /* reject too large bitmaps similarly to the rasterizer */
+      if ( imgHeight > 0x7FFF || imgWidth > 0x7FFF )
+      {
+        error = FT_THROW( Array_Too_Large );
+        goto DestroyExit;
+      }
+
       metrics->width  = (FT_UShort)imgWidth;
       metrics->height = (FT_UShort)imgHeight;
 
@@ -335,13 +350,6 @@
       map->pixel_mode = FT_PIXEL_MODE_BGRA;
       map->pitch      = (int)( map->width * 4 );
       map->num_grays  = 256;
-
-      /* reject too large bitmaps similarly to the rasterizer */
-      if ( map->rows > 0x7FFF || map->width > 0x7FFF )
-      {
-        error = FT_THROW( Array_Too_Large );
-        goto DestroyExit;
-      }
     }
 
     /* convert palette/gray image to rgb */
@@ -359,7 +367,7 @@
     }
 
     /* transform transparency to alpha */
-    if ( png_get_valid(png, info, PNG_INFO_tRNS ) )
+    if ( png_get_valid( png, info, PNG_INFO_tRNS ) )
       png_set_tRNS_to_alpha( png );
 
     if ( bitdepth == 16 )
@@ -379,7 +387,7 @@
     png_set_filler( png, 0xFF, PNG_FILLER_AFTER );
 
     /* recheck header after setting EXPAND options */
-    png_read_update_info(png, info );
+    png_read_update_info( png, info );
     png_get_IHDR( png, info,
                   &imgWidth, &imgHeight,
                   &bitdepth, &color_type, &interlace,
@@ -399,7 +407,8 @@
     switch ( color_type )
     {
     default:
-      /* Shouldn't happen, but fall through. */
+      /* Shouldn't happen, but ... */
+      FALL_THROUGH;
 
     case PNG_COLOR_TYPE_RGB_ALPHA:
       png_set_read_user_transform_fn( png, premultiply_data );
@@ -422,7 +431,7 @@
         goto DestroyExit;
     }
 
-    if ( FT_NEW_ARRAY( rows, imgHeight ) )
+    if ( FT_QNEW_ARRAY( rows, imgHeight ) )
     {
       error = FT_THROW( Out_Of_Memory );
       goto DestroyExit;
@@ -433,11 +442,11 @@
 
     png_read_image( png, rows );
 
-    FT_FREE( rows );
-
     png_read_end( png, info );
 
   DestroyExit:
+    /* even if reading fails with longjmp, rows must be freed */
+    FT_FREE( rows );
     png_destroy_read_struct( &png, &info, NULL );
     FT_Stream_Close( &stream );
 
diff --git a/src/sfnt/pngshim.h b/src/sfnt/pngshim.h
index 049a1ed..903bd2b 100644
--- a/src/sfnt/pngshim.h
+++ b/src/sfnt/pngshim.h
@@ -4,7 +4,7 @@
  *
  *   PNG Bitmap glyph support.
  *
- * Copyright 2013-2018 by
+ * Copyright (C) 2013-2023 by
  * Google, Inc.
  * Written by Stuart Gill and Behdad Esfahbod.
  *
@@ -21,7 +21,6 @@
 #define PNGSHIM_H_
 
 
-#include <ft2build.h>
 #include "ttload.h"
 
 
diff --git a/src/sfnt/rules.mk b/src/sfnt/rules.mk
index ff7d7c7..4d2d7e8 100644
--- a/src/sfnt/rules.mk
+++ b/src/sfnt/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -28,18 +28,22 @@
 
 # SFNT driver sources (i.e., C files)
 #
-SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c  \
-                $(SFNT_DIR)/sfdriver.c \
-                $(SFNT_DIR)/sfobjs.c   \
-                $(SFNT_DIR)/ttbdf.c    \
-                $(SFNT_DIR)/ttcmap.c   \
-                $(SFNT_DIR)/ttcolr.c   \
-                $(SFNT_DIR)/ttcpal.c   \
-                $(SFNT_DIR)/ttkern.c   \
-                $(SFNT_DIR)/ttload.c   \
-                $(SFNT_DIR)/ttmtx.c    \
-                $(SFNT_DIR)/ttpost.c   \
-                $(SFNT_DIR)/ttsbit.c
+SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c   \
+                $(SFNT_DIR)/sfdriver.c  \
+                $(SFNT_DIR)/sfobjs.c    \
+                $(SFNT_DIR)/sfwoff.c    \
+                $(SFNT_DIR)/sfwoff2.c   \
+                $(SFNT_DIR)/ttbdf.c     \
+                $(SFNT_DIR)/ttcmap.c    \
+                $(SFNT_DIR)/ttcolr.c    \
+                $(SFNT_DIR)/ttsvg.c     \
+                $(SFNT_DIR)/ttcpal.c    \
+                $(SFNT_DIR)/ttkern.c    \
+                $(SFNT_DIR)/ttload.c    \
+                $(SFNT_DIR)/ttmtx.c     \
+                $(SFNT_DIR)/ttpost.c    \
+                $(SFNT_DIR)/ttsbit.c    \
+                $(SFNT_DIR)/woff2tags.c
 
 # SFNT driver headers
 #
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index ae6d6cd..762883d 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
  *
  *   High-level SFNT driver interface (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_SFNT_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ttnameid.h>
 
 #include "sfdriver.h"
 #include "ttload.h"
@@ -37,27 +36,31 @@
 #include "ttcpal.h"
 #endif
 
+#ifdef FT_CONFIG_OPTION_SVG
+#include "ttsvg.h"
+#endif
+
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 #include "ttpost.h"
 #endif
 
 #ifdef TT_CONFIG_OPTION_BDF
 #include "ttbdf.h"
-#include FT_SERVICE_BDF_H
+#include <freetype/internal/services/svbdf.h>
 #endif
 
 #include "ttcmap.h"
 #include "ttkern.h"
 #include "ttmtx.h"
 
-#include FT_SERVICE_GLYPH_DICT_H
-#include FT_SERVICE_POSTSCRIPT_NAME_H
-#include FT_SERVICE_SFNT_H
-#include FT_SERVICE_TT_CMAP_H
+#include <freetype/internal/services/svgldict.h>
+#include <freetype/internal/services/svpostnm.h>
+#include <freetype/internal/services/svsfnt.h>
+#include <freetype/internal/services/svttcmap.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/services/svmm.h>
 #endif
 
 
@@ -68,7 +71,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_sfdriver
+#define FT_COMPONENT  sfdriver
 
 
   /*
@@ -182,8 +185,8 @@
 
 
   static FT_UInt
-  sfnt_get_name_index( FT_Face     face,
-                       FT_String*  glyph_name )
+  sfnt_get_name_index( FT_Face           face,
+                       const FT_String*  glyph_name )
   {
     TT_Face  ttface = (TT_Face)face;
 
@@ -195,7 +198,7 @@
     else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX )
       max_gid = (FT_UInt)face->num_glyphs;
     else
-      FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
+      FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08lx\n",
                   FT_UINT_MAX, face->num_glyphs ));
 
     for ( i = 0; i < max_gid; i++ )
@@ -375,47 +378,61 @@
       {
       case 15:
         k4 ^= (FT_UInt32)tail[14] << 16;
+        FALL_THROUGH;
       case 14:
         k4 ^= (FT_UInt32)tail[13] << 8;
+        FALL_THROUGH;
       case 13:
         k4 ^= (FT_UInt32)tail[12];
         k4 *= c4;
         k4  = ROTL32( k4, 18 );
         k4 *= c1;
         h4 ^= k4;
+        FALL_THROUGH;
 
       case 12:
         k3 ^= (FT_UInt32)tail[11] << 24;
+        FALL_THROUGH;
       case 11:
         k3 ^= (FT_UInt32)tail[10] << 16;
+        FALL_THROUGH;
       case 10:
         k3 ^= (FT_UInt32)tail[9] << 8;
+        FALL_THROUGH;
       case 9:
         k3 ^= (FT_UInt32)tail[8];
         k3 *= c3;
         k3  = ROTL32( k3, 17 );
         k3 *= c4;
         h3 ^= k3;
+        FALL_THROUGH;
 
       case 8:
         k2 ^= (FT_UInt32)tail[7] << 24;
+        FALL_THROUGH;
       case 7:
         k2 ^= (FT_UInt32)tail[6] << 16;
+        FALL_THROUGH;
       case 6:
         k2 ^= (FT_UInt32)tail[5] << 8;
+        FALL_THROUGH;
       case 5:
         k2 ^= (FT_UInt32)tail[4];
         k2 *= c2;
         k2  = ROTL32( k2, 16 );
         k2 *= c3;
         h2 ^= k2;
+        FALL_THROUGH;
 
       case 4:
         k1 ^= (FT_UInt32)tail[3] << 24;
+        FALL_THROUGH;
       case 3:
         k1 ^= (FT_UInt32)tail[2] << 16;
+        FALL_THROUGH;
       case 2:
         k1 ^= (FT_UInt32)tail[1] << 8;
+        FALL_THROUGH;
       case 1:
         k1 ^= (FT_UInt32)tail[0];
         k1 *= c1;
@@ -464,14 +481,12 @@
   typedef int (*char_type_func)( int  c );
 
 
-  /* handling of PID/EID 3/0 and 3/1 is the same */
+  /* Handling of PID/EID 3/0 and 3/1 is the same. */
 #define IS_WIN( n )  ( (n)->platformID == 3                             && \
-                       ( (n)->encodingID == 1 || (n)->encodingID == 0 ) && \
-                       (n)->languageID == 0x409                         )
+                       ( (n)->encodingID == 1 || (n)->encodingID == 0 ) )
 
 #define IS_APPLE( n )  ( (n)->platformID == 1 && \
-                         (n)->encodingID == 0 && \
-                         (n)->languageID == 0 )
+                         (n)->encodingID == 0 )
 
   static char*
   get_win_string( FT_Memory       memory,
@@ -480,57 +495,53 @@
                   char_type_func  char_type,
                   FT_Bool         report_invalid_characters )
   {
-    FT_Error  error = FT_Err_Ok;
+    FT_Error  error;
 
     char*       result = NULL;
     FT_String*  r;
     FT_Char*    p;
     FT_UInt     len;
 
-    FT_UNUSED( error );
 
-
-    if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) )
+    if ( FT_QALLOC( result, entry->stringLength / 2 + 1 ) )
       return NULL;
 
     if ( FT_STREAM_SEEK( entry->stringOffset ) ||
          FT_FRAME_ENTER( entry->stringLength ) )
-    {
-      FT_FREE( result );
-      entry->stringLength = 0;
-      entry->stringOffset = 0;
-      FT_FREE( entry->string );
-
-      return NULL;
-    }
+      goto get_win_string_error;
 
     r = (FT_String*)result;
     p = (FT_Char*)stream->cursor;
 
     for ( len = entry->stringLength / 2; len > 0; len--, p += 2 )
     {
-      if ( p[0] == 0 )
+      if ( p[0] == 0 && char_type( p[1] ) )
+        *r++ = p[1];
+      else
       {
-        if ( char_type( p[1] ) )
-          *r++ = p[1];
-        else
-        {
-          if ( report_invalid_characters )
-          {
-            FT_TRACE0(( "get_win_string:"
-                        " Character `%c' (0x%X) invalid in PS name string\n",
-                        p[1], p[1] ));
-            /* it's not the job of FreeType to correct PS names... */
-            *r++ = p[1];
-          }
-        }
+        if ( report_invalid_characters )
+          FT_TRACE0(( "get_win_string:"
+                      " Character 0x%X invalid in PS name string\n",
+                      ((unsigned)p[0])*256 + (unsigned)p[1] ));
+        break;
       }
     }
-    *r = '\0';
+    if ( !len )
+      *r = '\0';
 
     FT_FRAME_EXIT();
 
-    return result;
+    if ( !len )
+      return result;
+
+  get_win_string_error:
+    FT_FREE( result );
+
+    entry->stringLength = 0;
+    entry->stringOffset = 0;
+    FT_FREE( entry->string );
+
+    return NULL;
   }
 
 
@@ -541,29 +552,20 @@
                     char_type_func  char_type,
                     FT_Bool         report_invalid_characters )
   {
-    FT_Error  error = FT_Err_Ok;
+    FT_Error  error;
 
     char*       result = NULL;
     FT_String*  r;
     FT_Char*    p;
     FT_UInt     len;
 
-    FT_UNUSED( error );
 
-
-    if ( FT_ALLOC( result, entry->stringLength + 1 ) )
+    if ( FT_QALLOC( result, entry->stringLength + 1 ) )
       return NULL;
 
     if ( FT_STREAM_SEEK( entry->stringOffset ) ||
          FT_FRAME_ENTER( entry->stringLength ) )
-    {
-      FT_FREE( result );
-      entry->stringOffset = 0;
-      entry->stringLength = 0;
-      FT_FREE( entry->string );
-
-      return NULL;
-    }
+      goto get_apple_string_error;
 
     r = (FT_String*)result;
     p = (FT_Char*)stream->cursor;
@@ -575,20 +577,28 @@
       else
       {
         if ( report_invalid_characters )
-        {
           FT_TRACE0(( "get_apple_string:"
                       " Character `%c' (0x%X) invalid in PS name string\n",
                       *p, *p ));
-          /* it's not the job of FreeType to correct PS names... */
-          *r++ = *p;
-        }
+        break;
       }
     }
-    *r = '\0';
+    if ( !len )
+      *r = '\0';
 
     FT_FRAME_EXIT();
 
-    return result;
+    if ( !len )
+      return result;
+
+  get_apple_string_error:
+    FT_FREE( result );
+
+    entry->stringOffset = 0;
+    entry->stringLength = 0;
+    FT_FREE( entry->string );
+
+    return NULL;
   }
 
 
@@ -611,10 +621,10 @@
 
       if ( name->nameID == id && name->stringLength > 0 )
       {
-        if ( IS_WIN( name ) )
+        if ( IS_WIN( name ) && ( name->languageID == 0x409 || *win == -1 ) )
           *win = n;
 
-        if ( IS_APPLE( name ) )
+        if ( IS_APPLE( name ) && ( name->languageID == 0 || *apple == -1 ) )
           *apple = n;
       }
     }
@@ -647,7 +657,7 @@
 
 
   /*
-   * Find the shortest decimal representation of a 16.16 fixed point
+   * Find the shortest decimal representation of a 16.16 fixed-point
    * number.  The function fills `buf' with the result, returning a pointer
    * to the position after the representation's last byte.
    */
@@ -723,7 +733,7 @@
         an equivalent representation of `fixed'.
 
         The above FOR loop always finds the larger of the two values; I
-        verified this by iterating over all possible fixed point numbers.
+        verified this by iterating over all possible fixed-point numbers.
 
         If the remainder is 17232*10, both values are equally good, and we
         take the next even number (following IEEE 754's `round to nearest,
@@ -731,7 +741,7 @@
 
         If the remainder is smaller than 17232*10, the lower of the two
         numbers is nearer to the exact result (values 17232 and 34480 were
-        also found by testing all possible fixed point values).
+        also found by testing all possible fixed-point values).
 
         We use this to find a shorter decimal representation.  If not ending
         with digit zero, we take the representation with less error.
@@ -832,13 +842,20 @@
                                  face->name_table.names + win,
                                  sfnt_is_alphanumeric,
                                  0 );
-      else
+      if ( !result && apple != -1 )
         result = get_apple_string( face->root.memory,
                                    face->name_table.stream,
                                    face->name_table.names + apple,
                                    sfnt_is_alphanumeric,
                                    0 );
 
+      if ( !result )
+      {
+        FT_TRACE0(( "sfnt_get_var_ps_name:"
+                    " No valid PS name prefix for font instances found\n" ));
+        return NULL;
+      }
+
       len = ft_strlen( result );
 
       /* sanitize if necessary; we reserve space for 36 bytes (a 128bit  */
@@ -851,8 +868,8 @@
         result[len] = '\0';
 
         FT_TRACE0(( "sfnt_get_var_ps_name:"
-                    " Shortening variation PS name prefix\n"
-                    "                     "
+                    " Shortening variation PS name prefix\n" ));
+        FT_TRACE0(( "                     "
                     " to %d characters\n", len ));
       }
 
@@ -903,16 +920,16 @@
         if ( !subfamily_name )
         {
           FT_TRACE1(( "sfnt_get_var_ps_name:"
-                      " can't construct named instance PS name;\n"
-                      "                     "
+                      " can't construct named instance PS name;\n" ));
+          FT_TRACE1(( "                     "
                       " trying to construct normal instance PS name\n" ));
           goto construct_instance_name;
         }
 
         /* after the prefix we have character `-' followed by the   */
         /* subfamily name (using only characters a-z, A-Z, and 0-9) */
-        if ( FT_ALLOC( result, face->var_postscript_prefix_len +
-                               1 + ft_strlen( subfamily_name ) + 1 ) )
+        if ( FT_QALLOC( result, face->var_postscript_prefix_len +
+                                1 + ft_strlen( subfamily_name ) + 1 ) )
           return NULL;
 
         ft_strcpy( result, face->var_postscript_prefix );
@@ -940,9 +957,9 @@
     construct_instance_name:
       axis = mm_var->axis;
 
-      if ( FT_ALLOC( result,
-                     face->var_postscript_prefix_len +
-                       num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) )
+      if ( FT_QALLOC( result,
+                      face->var_postscript_prefix_len +
+                        num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) )
         return NULL;
 
       p = result;
@@ -976,6 +993,7 @@
         if ( t != ' ' && ft_isalnum( t ) )
           *p++ = t;
       }
+      *p++ = '\0';
     }
 
   check_length:
@@ -1056,7 +1074,7 @@
                                face->name_table.names + win,
                                sfnt_is_postscript,
                                1 );
-    else
+    if ( !result && apple != -1 )
       result = get_apple_string( face->root.memory,
                                  face->name_table.stream,
                                  face->name_table.names + apple,
@@ -1196,6 +1214,14 @@
 #define PUT_COLOR_LAYERS( a )  NULL
 #endif
 
+#ifdef FT_CONFIG_OPTION_SVG
+#define PUT_SVG_SUPPORT( a )  a
+#else
+#define PUT_SVG_SUPPORT( a )  NULL
+#endif
+
+#define PUT_COLOR_LAYERS_V1( a )  PUT_COLOR_LAYERS( a )
+
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 #define PUT_PS_NAMES( a )  a
 #else
@@ -1254,9 +1280,9 @@
                             /* TT_Free_Table_Func      free_eblc       */
 
     PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike     ),
-                   /* TT_Set_SBit_Strike_Func      set_sbit_strike     */
+                  /* TT_Set_SBit_Strike_Func      set_sbit_strike      */
     PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
-                   /* TT_Load_Strike_Metrics_Func  load_strike_metrics */
+                  /* TT_Load_Strike_Metrics_Func  load_strike_metrics  */
 
     PUT_COLOR_LAYERS( tt_face_load_cpal ),
                             /* TT_Load_Table_Func      load_cpal       */
@@ -1270,13 +1296,32 @@
                             /* TT_Set_Palette_Func     set_palette     */
     PUT_COLOR_LAYERS( tt_face_get_colr_layer ),
                             /* TT_Get_Colr_Layer_Func  get_colr_layer  */
+
+    PUT_COLOR_LAYERS_V1( tt_face_get_colr_glyph_paint ),
+              /* TT_Get_Color_Glyph_Paint_Func    get_colr_glyph_paint */
+    PUT_COLOR_LAYERS_V1( tt_face_get_color_glyph_clipbox ),
+              /* TT_Get_Color_Glyph_ClipBox_Func  get_clipbox          */
+    PUT_COLOR_LAYERS_V1( tt_face_get_paint_layers ),
+              /* TT_Get_Paint_Layers_Func         get_paint_layers     */
+    PUT_COLOR_LAYERS_V1( tt_face_get_colorline_stops ),
+              /* TT_Get_Paint                     get_paint            */
+    PUT_COLOR_LAYERS_V1( tt_face_get_paint ),
+              /* TT_Get_Colorline_Stops_Func      get_colorline_stops  */
+
     PUT_COLOR_LAYERS( tt_face_colr_blend_layer ),
                             /* TT_Blend_Colr_Func      colr_blend      */
 
     tt_face_get_metrics,    /* TT_Get_Metrics_Func     get_metrics     */
 
     tt_face_get_name,       /* TT_Get_Name_Func        get_name        */
-    sfnt_get_name_id        /* TT_Get_Name_ID_Func     get_name_id     */
+    sfnt_get_name_id,       /* TT_Get_Name_ID_Func     get_name_id     */
+
+    PUT_SVG_SUPPORT( tt_face_load_svg ),
+                            /* TT_Load_Table_Func      load_svg        */
+    PUT_SVG_SUPPORT( tt_face_free_svg ),
+                            /* TT_Free_Table_Func      free_svg        */
+    PUT_SVG_SUPPORT( tt_face_load_svg_doc )
+                            /* TT_Load_Svg_Doc_Func    load_svg_doc    */
   )
 
 
diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h
index 02d8d3d..2445958 100644
--- a/src/sfnt/sfdriver.h
+++ b/src/sfnt/sfdriver.h
@@ -4,7 +4,7 @@
  *
  *   High-level SFNT driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define SFDRIVER_H_
 
 
-#include <ft2build.h>
-#include FT_MODULE_H
+#include <freetype/ftmodapi.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/sfnt/sferrors.h b/src/sfnt/sferrors.h
index 6f78063..e7a8eb0 100644
--- a/src/sfnt/sferrors.h
+++ b/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
  *
  *   SFNT error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef SFERRORS_H_
 #define SFERRORS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  SFNT_Err_
 #define FT_ERR_BASE    FT_Mod_Err_SFNT
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* SFERRORS_H_ */
 
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index 9b4e3c0..8e4f08a 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
  *
  *   Single object library component.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,21 +17,24 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "pngshim.c"
 #include "sfdriver.c"
 #include "sfobjs.c"
+#include "sfwoff.c"
+#include "sfwoff2.c"
 #include "ttbdf.c"
 #include "ttcmap.c"
 #include "ttcolr.c"
 #include "ttcpal.c"
+#include "ttsvg.c"
 
 #include "ttkern.c"
 #include "ttload.c"
 #include "ttmtx.c"
 #include "ttpost.c"
 #include "ttsbit.c"
+#include "woff2tags.c"
 
 
 /* END */
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 9dfc20e..e018934 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
  *
  *   SFNT object management (base).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,22 +16,22 @@
  */
 
 
-#include <ft2build.h>
 #include "sfobjs.h"
 #include "ttload.h"
 #include "ttcmap.h"
 #include "ttkern.h"
-#include FT_INTERNAL_SFNT_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_TRUETYPE_IDS_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_SFNT_NAMES_H
-#include FT_GZIP_H
+#include "sfwoff.h"
+#include "sfwoff2.h"
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ttnameid.h>
+#include <freetype/tttags.h>
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/ftsnames.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_SERVICE_MULTIPLE_MASTERS_H
-#include FT_SERVICE_METRICS_VARIATIONS_H
+#include <freetype/internal/services/svmm.h>
+#include <freetype/internal/services/svmetric.h>
 #endif
 
 #include "sferrors.h"
@@ -48,7 +48,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_sfobjs
+#define FT_COMPONENT  sfobjs
 
 
 
@@ -65,7 +65,7 @@
 
     len = (FT_UInt)entry->stringLength / 2;
 
-    if ( FT_NEW_ARRAY( string, len + 1 ) )
+    if ( FT_QNEW_ARRAY( string, len + 1 ) )
       return NULL;
 
     for ( n = 0; n < len; n++ )
@@ -100,7 +100,7 @@
 
     len = (FT_UInt)entry->stringLength;
 
-    if ( FT_NEW_ARRAY( string, len + 1 ) )
+    if ( FT_QNEW_ARRAY( string, len + 1 ) )
       return NULL;
 
     for ( n = 0; n < len; n++ )
@@ -337,408 +337,13 @@
   }
 
 
-#define WRITE_USHORT( p, v )                \
-          do                                \
-          {                                 \
-            *(p)++ = (FT_Byte)( (v) >> 8 ); \
-            *(p)++ = (FT_Byte)( (v) >> 0 ); \
-                                            \
-          } while ( 0 )
-
-#define WRITE_ULONG( p, v )                  \
-          do                                 \
-          {                                  \
-            *(p)++ = (FT_Byte)( (v) >> 24 ); \
-            *(p)++ = (FT_Byte)( (v) >> 16 ); \
-            *(p)++ = (FT_Byte)( (v) >>  8 ); \
-            *(p)++ = (FT_Byte)( (v) >>  0 ); \
-                                             \
-          } while ( 0 )
-
-
-  static void
-  sfnt_stream_close( FT_Stream  stream )
-  {
-    FT_Memory  memory = stream->memory;
-
-
-    FT_FREE( stream->base );
-
-    stream->size  = 0;
-    stream->base  = NULL;
-    stream->close = NULL;
-  }
-
-
-  FT_CALLBACK_DEF( int )
-  compare_offsets( const void*  a,
-                   const void*  b )
-  {
-    WOFF_Table  table1 = *(WOFF_Table*)a;
-    WOFF_Table  table2 = *(WOFF_Table*)b;
-
-    FT_ULong  offset1 = table1->Offset;
-    FT_ULong  offset2 = table2->Offset;
-
-
-    if ( offset1 > offset2 )
-      return 1;
-    else if ( offset1 < offset2 )
-      return -1;
-    else
-      return 0;
-  }
-
-
-  /* Replace `face->root.stream' with a stream containing the extracted */
-  /* SFNT of a WOFF font.                                               */
-
-  static FT_Error
-  woff_open_font( FT_Stream  stream,
-                  TT_Face    face )
-  {
-    FT_Memory       memory = stream->memory;
-    FT_Error        error  = FT_Err_Ok;
-
-    WOFF_HeaderRec  woff;
-    WOFF_Table      tables  = NULL;
-    WOFF_Table*     indices = NULL;
-
-    FT_ULong        woff_offset;
-
-    FT_Byte*        sfnt        = NULL;
-    FT_Stream       sfnt_stream = NULL;
-
-    FT_Byte*        sfnt_header;
-    FT_ULong        sfnt_offset;
-
-    FT_Int          nn;
-    FT_ULong        old_tag = 0;
-
-    static const FT_Frame_Field  woff_header_fields[] =
-    {
-#undef  FT_STRUCTURE
-#define FT_STRUCTURE  WOFF_HeaderRec
-
-      FT_FRAME_START( 44 ),
-        FT_FRAME_ULONG ( signature ),
-        FT_FRAME_ULONG ( flavor ),
-        FT_FRAME_ULONG ( length ),
-        FT_FRAME_USHORT( num_tables ),
-        FT_FRAME_USHORT( reserved ),
-        FT_FRAME_ULONG ( totalSfntSize ),
-        FT_FRAME_USHORT( majorVersion ),
-        FT_FRAME_USHORT( minorVersion ),
-        FT_FRAME_ULONG ( metaOffset ),
-        FT_FRAME_ULONG ( metaLength ),
-        FT_FRAME_ULONG ( metaOrigLength ),
-        FT_FRAME_ULONG ( privOffset ),
-        FT_FRAME_ULONG ( privLength ),
-      FT_FRAME_END
-    };
-
-
-    FT_ASSERT( stream == face->root.stream );
-    FT_ASSERT( FT_STREAM_POS() == 0 );
-
-    if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
-      return error;
-
-    /* Make sure we don't recurse back here or hit TTC code. */
-    if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
-      return FT_THROW( Invalid_Table );
-
-    /* Miscellaneous checks. */
-    if ( woff.length != stream->size                              ||
-         woff.num_tables == 0                                     ||
-         44 + woff.num_tables * 20UL >= woff.length               ||
-         12 + woff.num_tables * 16UL >= woff.totalSfntSize        ||
-         ( woff.totalSfntSize & 3 ) != 0                          ||
-         ( woff.metaOffset == 0 && ( woff.metaLength != 0     ||
-                                     woff.metaOrigLength != 0 ) ) ||
-         ( woff.metaLength != 0 && woff.metaOrigLength == 0 )     ||
-         ( woff.privOffset == 0 && woff.privLength != 0 )         )
-    {
-      FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
-      return FT_THROW( Invalid_Table );
-    }
-
-    /* Don't trust `totalSfntSize' before thorough checks. */
-    if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
-         FT_NEW( sfnt_stream )                         )
-      goto Exit;
-
-    sfnt_header = sfnt;
-
-    /* Write sfnt header. */
-    {
-      FT_UInt  searchRange, entrySelector, rangeShift, x;
-
-
-      x             = woff.num_tables;
-      entrySelector = 0;
-      while ( x )
-      {
-        x            >>= 1;
-        entrySelector += 1;
-      }
-      entrySelector--;
-
-      searchRange = ( 1 << entrySelector ) * 16;
-      rangeShift  = woff.num_tables * 16 - searchRange;
-
-      WRITE_ULONG ( sfnt_header, woff.flavor );
-      WRITE_USHORT( sfnt_header, woff.num_tables );
-      WRITE_USHORT( sfnt_header, searchRange );
-      WRITE_USHORT( sfnt_header, entrySelector );
-      WRITE_USHORT( sfnt_header, rangeShift );
-    }
-
-    /* While the entries in the sfnt header must be sorted by the */
-    /* tag value, the tables themselves are not.  We thus have to */
-    /* sort them by offset and check that they don't overlap.     */
-
-    if ( FT_NEW_ARRAY( tables, woff.num_tables )  ||
-         FT_NEW_ARRAY( indices, woff.num_tables ) )
-      goto Exit;
-
-    FT_TRACE2(( "\n"
-                "  tag    offset    compLen  origLen  checksum\n"
-                "  -------------------------------------------\n" ));
-
-    if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
-      goto Exit;
-
-    for ( nn = 0; nn < woff.num_tables; nn++ )
-    {
-      WOFF_Table  table = tables + nn;
-
-      table->Tag        = FT_GET_TAG4();
-      table->Offset     = FT_GET_ULONG();
-      table->CompLength = FT_GET_ULONG();
-      table->OrigLength = FT_GET_ULONG();
-      table->CheckSum   = FT_GET_ULONG();
-
-      FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx  %08lx\n",
-                  (FT_Char)( table->Tag >> 24 ),
-                  (FT_Char)( table->Tag >> 16 ),
-                  (FT_Char)( table->Tag >> 8  ),
-                  (FT_Char)( table->Tag       ),
-                  table->Offset,
-                  table->CompLength,
-                  table->OrigLength,
-                  table->CheckSum ));
-
-      if ( table->Tag <= old_tag )
-      {
-        FT_FRAME_EXIT();
-
-        FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      old_tag     = table->Tag;
-      indices[nn] = table;
-    }
-
-    FT_FRAME_EXIT();
-
-    /* Sort by offset. */
-
-    ft_qsort( indices,
-              woff.num_tables,
-              sizeof ( WOFF_Table ),
-              compare_offsets );
-
-    /* Check offsets and lengths. */
-
-    woff_offset = 44 + woff.num_tables * 20L;
-    sfnt_offset = 12 + woff.num_tables * 16L;
-
-    for ( nn = 0; nn < woff.num_tables; nn++ )
-    {
-      WOFF_Table  table = indices[nn];
-
-
-      if ( table->Offset != woff_offset                         ||
-           table->CompLength > woff.length                      ||
-           table->Offset > woff.length - table->CompLength      ||
-           table->OrigLength > woff.totalSfntSize               ||
-           sfnt_offset > woff.totalSfntSize - table->OrigLength ||
-           table->CompLength > table->OrigLength                )
-      {
-        FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      table->OrigOffset = sfnt_offset;
-
-      /* The offsets must be multiples of 4. */
-      woff_offset += ( table->CompLength + 3 ) & ~3U;
-      sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
-    }
-
-    /*
-     * Final checks!
-     *
-     * We don't decode and check the metadata block.
-     * We don't check table checksums either.
-     * But other than those, I think we implement all
-     * `MUST' checks from the spec.
-     */
-
-    if ( woff.metaOffset )
-    {
-      if ( woff.metaOffset != woff_offset                  ||
-           woff.metaOffset + woff.metaLength > woff.length )
-      {
-        FT_ERROR(( "woff_font_open:"
-                   " invalid `metadata' offset or length\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      /* We have padding only ... */
-      woff_offset += woff.metaLength;
-    }
-
-    if ( woff.privOffset )
-    {
-      /* ... if it isn't the last block. */
-      woff_offset = ( woff_offset + 3 ) & ~3U;
-
-      if ( woff.privOffset != woff_offset                  ||
-           woff.privOffset + woff.privLength > woff.length )
-      {
-        FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      /* No padding for the last block. */
-      woff_offset += woff.privLength;
-    }
-
-    if ( sfnt_offset != woff.totalSfntSize ||
-         woff_offset != woff.length        )
-    {
-      FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
-      error = FT_THROW( Invalid_Table );
-      goto Exit;
-    }
-
-    /* Now use `totalSfntSize'. */
-    if ( FT_REALLOC( sfnt,
-                     12 + woff.num_tables * 16UL,
-                     woff.totalSfntSize ) )
-      goto Exit;
-
-    sfnt_header = sfnt + 12;
-
-    /* Write the tables. */
-
-    for ( nn = 0; nn < woff.num_tables; nn++ )
-    {
-      WOFF_Table  table = tables + nn;
-
-
-      /* Write SFNT table entry. */
-      WRITE_ULONG( sfnt_header, table->Tag );
-      WRITE_ULONG( sfnt_header, table->CheckSum );
-      WRITE_ULONG( sfnt_header, table->OrigOffset );
-      WRITE_ULONG( sfnt_header, table->OrigLength );
-
-      /* Write table data. */
-      if ( FT_STREAM_SEEK( table->Offset )     ||
-           FT_FRAME_ENTER( table->CompLength ) )
-        goto Exit;
-
-      if ( table->CompLength == table->OrigLength )
-      {
-        /* Uncompressed data; just copy. */
-        ft_memcpy( sfnt + table->OrigOffset,
-                   stream->cursor,
-                   table->OrigLength );
-      }
-      else
-      {
-#ifdef FT_CONFIG_OPTION_USE_ZLIB
-
-        /* Uncompress with zlib. */
-        FT_ULong  output_len = table->OrigLength;
-
-
-        error = FT_Gzip_Uncompress( memory,
-                                    sfnt + table->OrigOffset, &output_len,
-                                    stream->cursor, table->CompLength );
-        if ( error )
-          goto Exit;
-        if ( output_len != table->OrigLength )
-        {
-          FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
-          error = FT_THROW( Invalid_Table );
-          goto Exit;
-        }
-
-#else /* !FT_CONFIG_OPTION_USE_ZLIB */
-
-        error = FT_THROW( Unimplemented_Feature );
-        goto Exit;
-
-#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
-      }
-
-      FT_FRAME_EXIT();
-
-      /* We don't check whether the padding bytes in the WOFF file are     */
-      /* actually '\0'.  For the output, however, we do set them properly. */
-      sfnt_offset = table->OrigOffset + table->OrigLength;
-      while ( sfnt_offset & 3 )
-      {
-        sfnt[sfnt_offset] = '\0';
-        sfnt_offset++;
-      }
-    }
-
-    /* Ok!  Finally ready.  Swap out stream and return. */
-    FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
-    sfnt_stream->memory = stream->memory;
-    sfnt_stream->close  = sfnt_stream_close;
-
-    FT_Stream_Free(
-      face->root.stream,
-      ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
-
-    face->root.stream = sfnt_stream;
-
-    face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
-
-  Exit:
-    FT_FREE( tables );
-    FT_FREE( indices );
-
-    if ( error )
-    {
-      FT_FREE( sfnt );
-      FT_Stream_Close( sfnt_stream );
-      FT_FREE( sfnt_stream );
-    }
-
-    return error;
-  }
-
-
-#undef WRITE_USHORT
-#undef WRITE_ULONG
-
-
   /* Fill in face->ttc_header.  If the font is not a TTC, it is */
   /* synthesized into a TTC with one offset table.              */
   static FT_Error
   sfnt_open_font( FT_Stream  stream,
-                  TT_Face    face )
+                  TT_Face    face,
+                  FT_Int*    face_instance_index,
+                  FT_Long*   woff2_num_faces )
   {
     FT_Memory  memory = stream->memory;
     FT_Error   error;
@@ -755,17 +360,27 @@
       FT_FRAME_END
     };
 
+#ifndef FT_CONFIG_OPTION_USE_BROTLI
+    FT_UNUSED( face_instance_index );
+    FT_UNUSED( woff2_num_faces );
+#endif
+
 
     face->ttc_header.tag     = 0;
     face->ttc_header.version = 0;
     face->ttc_header.count   = 0;
 
+#if defined( FT_CONFIG_OPTION_USE_ZLIB )   || \
+    defined( FT_CONFIG_OPTION_USE_BROTLI )
   retry:
+#endif
+
     offset = FT_STREAM_POS();
 
     if ( FT_READ_ULONG( tag ) )
       return error;
 
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
     if ( tag == TTAG_wOFF )
     {
       FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" ));
@@ -781,6 +396,28 @@
       stream = face->root.stream;
       goto retry;
     }
+#endif
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+    if ( tag == TTAG_wOF2 )
+    {
+      FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" ));
+
+      if ( FT_STREAM_SEEK( offset ) )
+        return error;
+
+      error = woff2_open_font( stream,
+                               face,
+                               face_instance_index,
+                               woff2_num_faces );
+      if ( error )
+        return error;
+
+      /* Swap out stream and retry! */
+      stream = face->root.stream;
+      goto retry;
+    }
+#endif
 
     if ( tag != 0x00010000UL &&
          tag != TTAG_ttcf    &&
@@ -822,7 +459,7 @@
         return FT_THROW( Array_Too_Large );
 
       /* now read the offsets of each font in the file */
-      if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
+      if ( FT_QNEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
         return error;
 
       if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
@@ -840,7 +477,7 @@
       face->ttc_header.version = 1 << 16;
       face->ttc_header.count   = 1;
 
-      if ( FT_NEW( face->ttc_header.offsets ) )
+      if ( FT_QNEW( face->ttc_header.offsets ) )
         return error;
 
       face->ttc_header.offsets[0] = offset;
@@ -858,9 +495,10 @@
                   FT_Parameter*  params )
   {
     FT_Error      error;
-    FT_Library    library = face->root.driver->root.library;
+    FT_Library    library         = face->root.driver->root.library;
     SFNT_Service  sfnt;
     FT_Int        face_index;
+    FT_Long       woff2_num_faces = 0;
 
 
     /* for now, parameters are unused */
@@ -911,21 +549,24 @@
 
     FT_TRACE2(( "SFNT driver\n" ));
 
-    error = sfnt_open_font( stream, face );
+    error = sfnt_open_font( stream,
+                            face,
+                            &face_instance_index,
+                            &woff2_num_faces );
     if ( error )
       return error;
 
     /* Stream may have changed in sfnt_open_font. */
     stream = face->root.stream;
 
-    FT_TRACE2(( "sfnt_init_face: %08p (index %d)\n",
-                face,
+    FT_TRACE2(( "sfnt_init_face: %p (index %d)\n",
+                (void *)face,
                 face_instance_index ));
 
     face_index = FT_ABS( face_instance_index ) & 0xFFFF;
 
     /* value -(N+1) requests information on index N */
-    if ( face_instance_index < 0 )
+    if ( face_instance_index < 0 && face_index > 0 )
       face_index--;
 
     if ( face_index >= face->ttc_header.count )
@@ -1015,8 +656,8 @@
        */
 
       if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) &&
-           !( FT_ALLOC( default_values, num_axes * 4 )  ||
-              FT_ALLOC( instance_values, num_axes * 4 ) )      )
+           !( FT_QALLOC(  default_values, num_axes * 4 ) ||
+              FT_QALLOC( instance_values, num_axes * 4 ) )     )
       {
         /* the current stream position is 16 bytes after the table start */
         FT_ULong  array_start = FT_STREAM_POS() - 16 + offset;
@@ -1086,6 +727,10 @@
     face->root.num_faces  = face->ttc_header.count;
     face->root.face_index = face_instance_index;
 
+    /* `num_faces' for a WOFF2 needs to be handled separately. */
+    if ( woff2_num_faces )
+      face->root.num_faces = woff2_num_faces;
+
     return error;
   }
 
@@ -1139,17 +784,23 @@
                   FT_Int         num_params,
                   FT_Parameter*  params )
   {
-    FT_Error      error;
+    FT_Error  error;
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-    FT_Error      psnames_error;
+    FT_Error  psnames_error;
 #endif
-    FT_Bool       has_outline;
-    FT_Bool       is_apple_sbit;
-    FT_Bool       is_apple_sbix;
-    FT_Bool       has_CBLC;
-    FT_Bool       has_CBDT;
-    FT_Bool       ignore_typographic_family    = FALSE;
-    FT_Bool       ignore_typographic_subfamily = FALSE;
+
+    FT_Bool  has_outline;
+    FT_Bool  is_apple_sbit;
+
+    FT_Bool  has_CBLC;
+    FT_Bool  has_CBDT;
+    FT_Bool  has_EBLC;
+    FT_Bool  has_bloc;
+    FT_Bool  has_sbix;
+
+    FT_Bool  ignore_typographic_family    = FALSE;
+    FT_Bool  ignore_typographic_subfamily = FALSE;
+    FT_Bool  ignore_sbix                  = FALSE;
 
     SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
@@ -1168,6 +819,8 @@
           ignore_typographic_family = TRUE;
         else if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY )
           ignore_typographic_subfamily = TRUE;
+        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_SBIX )
+          ignore_sbix = TRUE;
       }
     }
 
@@ -1188,7 +841,8 @@
     /* it doesn't contain outlines.                                */
     /*                                                             */
 
-    FT_TRACE2(( "sfnt_load_face: %08p\n\n", face ));
+    FT_TRACE2(( "sfnt_load_face: %p\n", (void *)face ));
+    FT_TRACE2(( "\n" ));
 
     /* do we have outlines in there? */
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
@@ -1202,14 +856,17 @@
                            tt_face_lookup_table( face, TTAG_CFF2 ) );
 #endif
 
-    is_apple_sbit = 0;
-    is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
+    /* check which sbit formats are present */
+    has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
+    has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
+    has_EBLC = !face->goto_table( face, TTAG_EBLC, stream, 0 );
+    has_bloc = !face->goto_table( face, TTAG_bloc, stream, 0 );
+    has_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
 
-    /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
-     * outline rendered on top.  We don't support that yet, so just ignore
-     * the 'glyf' outline and advertise it as a bitmap-only font. */
-    if ( is_apple_sbix )
-      has_outline = FALSE;
+    is_apple_sbit = FALSE;
+
+    if ( ignore_sbix )
+      has_sbix = FALSE;
 
     /* if this font doesn't contain outlines, we try to load */
     /* a `bhed' table                                        */
@@ -1221,16 +878,13 @@
 
     /* load the font header (`head' table) if this isn't an Apple */
     /* sbit font file                                             */
-    if ( !is_apple_sbit || is_apple_sbix )
+    if ( !is_apple_sbit || has_sbix )
     {
       LOAD_( head );
       if ( error )
         goto Exit;
     }
 
-    has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
-    has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
-
     /* Ignore outlines for CBLC/CBDT fonts. */
     if ( has_CBLC || has_CBDT )
       has_outline = FALSE;
@@ -1340,7 +994,11 @@
     /* the optional tables */
 
     /* embedded bitmap support */
-    if ( sfnt->load_eblc )
+    /* TODO: Replace this clumsy check for all possible sbit tables     */
+    /*       with something better (for example, by passing a parameter */
+    /*       to suppress 'sbix' loading).                               */
+    if ( sfnt->load_eblc                                  &&
+         ( has_CBLC || has_EBLC || has_bloc || has_sbix ) )
       LOAD_( eblc );
 
     /* colored glyph support */
@@ -1350,6 +1008,10 @@
       LOAD_( colr );
     }
 
+    /* OpenType-SVG glyph support */
+    if ( sfnt->load_svg )
+      LOAD_( svg );
+
     /* consider the pclt, kerning, and gasp tables as optional */
     LOAD_( pclt );
     LOAD_( gasp );
@@ -1404,11 +1066,19 @@
        */
       if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC ||
            face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ||
-           face->colr                                       )
+           face->colr                                       ||
+           face->svg                                        )
         flags |= FT_FACE_FLAG_COLOR;      /* color glyphs */
 
       if ( has_outline == TRUE )
-        flags |= FT_FACE_FLAG_SCALABLE;   /* scalable outlines */
+      {
+        /* by default (and for backward compatibility) we handle */
+        /* fonts with an 'sbix' table as bitmap-only             */
+        if ( has_sbix )
+          flags |= FT_FACE_FLAG_SBIX;     /* with 'sbix' bitmaps */
+        else
+          flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
+      }
 
       /* The sfnt driver only supports bitmap fonts natively, thus we */
       /* don't set FT_FACE_FLAG_HINTER.                               */
@@ -1437,13 +1107,7 @@
       /* Don't bother to load the tables unless somebody asks for them. */
       /* No need to do work which will (probably) not be used.          */
       if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
-      {
-        if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
-             tt_face_lookup_table( face, TTAG_gvar ) != 0 )
-          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
-        if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 )
-          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
-      }
+        flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
 #endif
 
       root->face_flags = flags;
@@ -1517,9 +1181,10 @@
         }
 
         /* synthesize Unicode charmap if one is missing */
-        if ( !has_unicode )
+        if ( !has_unicode                                &&
+             root->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
         {
-          FT_CharMapRec cmaprec;
+          FT_CharMapRec  cmaprec;
 
 
           cmaprec.face        = root;
@@ -1531,7 +1196,8 @@
           error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec,
                                NULL, &cmaprec, NULL );
           if ( error                                      &&
-               FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
+               FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
+               FT_ERR_NEQ( error, Unimplemented_Feature ) )
             goto Exit;
           error = FT_Err_Ok;
 
@@ -1574,7 +1240,7 @@
           /* of `FT_Face', we map `available_sizes' indices to strike    */
           /* indices                                                     */
           if ( FT_NEW_ARRAY( root->available_sizes, count ) ||
-               FT_NEW_ARRAY( sbit_strike_map, count ) )
+               FT_QNEW_ARRAY( sbit_strike_map, count ) )
             goto Exit;
 
           bsize_idx = 0;
@@ -1603,7 +1269,7 @@
           }
 
           /* reduce array size to the actually used elements */
-          (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx );
+          FT_MEM_QRENEW_ARRAY( sbit_strike_map, count, bsize_idx );
 
           /* from now on, all strike indices are mapped */
           /* using `sbit_strike_map'                    */
@@ -1629,7 +1295,8 @@
        *
        * Set up metrics.
        */
-      if ( FT_IS_SCALABLE( root ) )
+      if ( FT_IS_SCALABLE( root ) ||
+           FT_HAS_SBIX( root )    )
       {
         /* XXX What about if outline header is missing */
         /*     (e.g. sfnt wrapped bitmap)?             */
@@ -1640,59 +1307,73 @@
         root->units_per_EM = face->header.Units_Per_EM;
 
 
-        /* XXX: Computing the ascender/descender/height is very different */
-        /*      from what the specification tells you.  Apparently, we    */
-        /*      must be careful because                                   */
-        /*                                                                */
-        /*      - not all fonts have an OS/2 table; in this case, we take */
-        /*        the values in the horizontal header.  However, these    */
-        /*        values very often are not reliable.                     */
-        /*                                                                */
-        /*      - otherwise, the correct typographic values are in the    */
-        /*        sTypoAscender, sTypoDescender & sTypoLineGap fields.    */
-        /*                                                                */
-        /*        However, certain fonts have these fields set to 0.      */
-        /*        Rather, they have usWinAscent & usWinDescent correctly  */
-        /*        set (but with different values).                        */
-        /*                                                                */
-        /*      As an example, Arial Narrow is implemented through four   */
-        /*      files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */
-        /*                                                                */
-        /*      Strangely, all fonts have the same values in their        */
-        /*      sTypoXXX fields, except ARIALNB which sets them to 0.     */
-        /*                                                                */
-        /*      On the other hand, they all have different                */
-        /*      usWinAscent/Descent values -- as a conclusion, the OS/2   */
-        /*      table cannot be used to compute the text height reliably! */
-        /*                                                                */
+        /*
+         * Computing the ascender/descender/height is tricky.
+         *
+         * The OpenType specification v1.8.3 says:
+         *
+         *   [OS/2's] sTypoAscender, sTypoDescender and sTypoLineGap fields
+         *   are intended to allow applications to lay out documents in a
+         *   typographically-correct and portable fashion.
+         *
+         * This is somewhat at odds with the decades of backwards
+         * compatibility, operating systems and applications doing whatever
+         * they want, not to mention broken fonts.
+         *
+         * Not all fonts have an OS/2 table; in this case, we take the values
+         * in the horizontal header, although there is nothing stopping the
+         * values from being unreliable. Even with a OS/2 table, certain fonts
+         * set the sTypoAscender, sTypoDescender and sTypoLineGap fields to 0
+         * and instead correctly set usWinAscent and usWinDescent.
+         *
+         * As an example, Arial Narrow is shipped as four files ARIALN.TTF,
+         * ARIALNI.TTF, ARIALNB.TTF and ARIALNBI.TTF. Strangely, all fonts have
+         * the same values in their sTypo* fields, except ARIALNB.ttf which
+         * sets them to 0. All of them have different usWinAscent/Descent
+         * values. The OS/2 table therefore cannot be trusted for computing the
+         * text height reliably.
+         *
+         * As a compromise, do the following:
+         *
+         * 1. If the OS/2 table exists and the fsSelection bit 7 is set
+         *    (USE_TYPO_METRICS), trust the font and use the sTypo* metrics.
+         * 2. Otherwise, use the `hhea' table's metrics.
+         * 3. If they are zero and the OS/2 table exists,
+         *    1. use the OS/2 table's sTypo* metrics if they are non-zero.
+         *    2. Otherwise, use the OS/2 table's usWin* metrics.
+         */
 
-        /* The ascender and descender are taken from the `hhea' table. */
-        /* If zero, they are taken from the `OS/2' table.              */
-
-        root->ascender  = face->horizontal.Ascender;
-        root->descender = face->horizontal.Descender;
-
-        root->height = root->ascender - root->descender +
-                       face->horizontal.Line_Gap;
-
-        if ( !( root->ascender || root->descender ) )
+        if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 128 )
         {
-          if ( face->os2.version != 0xFFFFU )
+          root->ascender  = face->os2.sTypoAscender;
+          root->descender = face->os2.sTypoDescender;
+          root->height    = root->ascender - root->descender +
+                            face->os2.sTypoLineGap;
+        }
+        else
+        {
+          root->ascender  = face->horizontal.Ascender;
+          root->descender = face->horizontal.Descender;
+          root->height    = root->ascender - root->descender +
+                            face->horizontal.Line_Gap;
+
+          if ( !( root->ascender || root->descender ) )
           {
-            if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
+            if ( face->os2.version != 0xFFFFU )
             {
-              root->ascender  = face->os2.sTypoAscender;
-              root->descender = face->os2.sTypoDescender;
-
-              root->height = root->ascender - root->descender +
-                             face->os2.sTypoLineGap;
-            }
-            else
-            {
-              root->ascender  =  (FT_Short)face->os2.usWinAscent;
-              root->descender = -(FT_Short)face->os2.usWinDescent;
-
-              root->height = root->ascender - root->descender;
+              if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
+              {
+                root->ascender  = face->os2.sTypoAscender;
+                root->descender = face->os2.sTypoDescender;
+                root->height    = root->ascender - root->descender +
+                                  face->os2.sTypoLineGap;
+              }
+              else
+              {
+                root->ascender  =  (FT_Short)face->os2.usWinAscent;
+                root->descender = -(FT_Short)face->os2.usWinDescent;
+                root->height    =  root->ascender - root->descender;
+              }
             }
           }
         }
@@ -1754,6 +1435,12 @@
         sfnt->free_cpal( face );
         sfnt->free_colr( face );
       }
+
+#ifdef FT_CONFIG_OPTION_SVG
+      /* free SVG data */
+      if ( sfnt->free_svg )
+        sfnt->free_svg( face );
+#endif
     }
 
 #ifdef TT_CONFIG_OPTION_BDF
diff --git a/src/sfnt/sfobjs.h b/src/sfnt/sfobjs.h
index d3bbaf1..906aebb 100644
--- a/src/sfnt/sfobjs.h
+++ b/src/sfnt/sfobjs.h
@@ -4,7 +4,7 @@
  *
  *   SFNT object management (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define SFOBJS_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_SFNT_H
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftobjs.h>
 
 
 FT_BEGIN_HEADER
@@ -53,7 +52,7 @@
 
 FT_END_HEADER
 
-#endif /* SFDRIVER_H_ */
+#endif /* SFOBJS_H_ */
 
 
 /* END */
diff --git a/src/sfnt/sfwoff.c b/src/sfnt/sfwoff.c
new file mode 100644
index 0000000..9559bf3
--- /dev/null
+++ b/src/sfnt/sfwoff.c
@@ -0,0 +1,434 @@
+/****************************************************************************
+ *
+ * sfwoff.c
+ *
+ *   WOFF format management (base).
+ *
+ * Copyright (C) 1996-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 "sfwoff.h"
+#include <freetype/tttags.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/ftgzip.h>
+
+
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  sfwoff
+
+
+#define WRITE_USHORT( p, v )                \
+          do                                \
+          {                                 \
+            *(p)++ = (FT_Byte)( (v) >> 8 ); \
+            *(p)++ = (FT_Byte)( (v) >> 0 ); \
+                                            \
+          } while ( 0 )
+
+#define WRITE_ULONG( p, v )                  \
+          do                                 \
+          {                                  \
+            *(p)++ = (FT_Byte)( (v) >> 24 ); \
+            *(p)++ = (FT_Byte)( (v) >> 16 ); \
+            *(p)++ = (FT_Byte)( (v) >>  8 ); \
+            *(p)++ = (FT_Byte)( (v) >>  0 ); \
+                                             \
+          } while ( 0 )
+
+
+  static void
+  sfnt_stream_close( FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+
+
+    FT_FREE( stream->base );
+
+    stream->size  = 0;
+    stream->close = NULL;
+  }
+
+
+  FT_COMPARE_DEF( int )
+  compare_offsets( const void*  a,
+                   const void*  b )
+  {
+    WOFF_Table  table1 = *(WOFF_Table*)a;
+    WOFF_Table  table2 = *(WOFF_Table*)b;
+
+    FT_ULong  offset1 = table1->Offset;
+    FT_ULong  offset2 = table2->Offset;
+
+
+    if ( offset1 > offset2 )
+      return 1;
+    else if ( offset1 < offset2 )
+      return -1;
+    else
+      return 0;
+  }
+
+
+  /* Replace `face->root.stream' with a stream containing the extracted */
+  /* SFNT of a WOFF font.                                               */
+
+  FT_LOCAL_DEF( FT_Error )
+  woff_open_font( FT_Stream  stream,
+                  TT_Face    face )
+  {
+    FT_Memory       memory = stream->memory;
+    FT_Error        error  = FT_Err_Ok;
+
+    WOFF_HeaderRec  woff;
+    WOFF_Table      tables  = NULL;
+    WOFF_Table*     indices = NULL;
+
+    FT_ULong        woff_offset;
+
+    FT_Byte*        sfnt        = NULL;
+    FT_Stream       sfnt_stream = NULL;
+
+    FT_Byte*        sfnt_header;
+    FT_ULong        sfnt_offset;
+
+    FT_Int          nn;
+    FT_Tag          old_tag = 0;
+
+    static const FT_Frame_Field  woff_header_fields[] =
+    {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  WOFF_HeaderRec
+
+      FT_FRAME_START( 44 ),
+        FT_FRAME_ULONG ( signature ),
+        FT_FRAME_ULONG ( flavor ),
+        FT_FRAME_ULONG ( length ),
+        FT_FRAME_USHORT( num_tables ),
+        FT_FRAME_USHORT( reserved ),
+        FT_FRAME_ULONG ( totalSfntSize ),
+        FT_FRAME_USHORT( majorVersion ),
+        FT_FRAME_USHORT( minorVersion ),
+        FT_FRAME_ULONG ( metaOffset ),
+        FT_FRAME_ULONG ( metaLength ),
+        FT_FRAME_ULONG ( metaOrigLength ),
+        FT_FRAME_ULONG ( privOffset ),
+        FT_FRAME_ULONG ( privLength ),
+      FT_FRAME_END
+    };
+
+
+    FT_ASSERT( stream == face->root.stream );
+    FT_ASSERT( FT_STREAM_POS() == 0 );
+
+    if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
+      return error;
+
+    /* Make sure we don't recurse back here or hit TTC code. */
+    if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
+      return FT_THROW( Invalid_Table );
+
+    /* Miscellaneous checks. */
+    if ( woff.length != stream->size                              ||
+         woff.num_tables == 0                                     ||
+         44 + woff.num_tables * 20UL >= woff.length               ||
+         12 + woff.num_tables * 16UL >= woff.totalSfntSize        ||
+         ( woff.totalSfntSize & 3 ) != 0                          ||
+         ( woff.metaOffset == 0 && ( woff.metaLength != 0     ||
+                                     woff.metaOrigLength != 0 ) ) ||
+         ( woff.metaLength != 0 && woff.metaOrigLength == 0 )     ||
+         ( woff.privOffset == 0 && woff.privLength != 0 )         )
+    {
+      FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    /* Don't trust `totalSfntSize' before thorough checks. */
+    if ( FT_QALLOC( sfnt, 12 ) || FT_NEW( sfnt_stream ) )
+      goto Exit;
+
+    sfnt_header = sfnt;
+
+    /* Write sfnt header. */
+    {
+      FT_UInt  searchRange, entrySelector, rangeShift, x;
+
+
+      x             = woff.num_tables;
+      entrySelector = 0;
+      while ( x )
+      {
+        x            >>= 1;
+        entrySelector += 1;
+      }
+      entrySelector--;
+
+      searchRange = ( 1 << entrySelector ) * 16;
+      rangeShift  = woff.num_tables * 16 - searchRange;
+
+      WRITE_ULONG ( sfnt_header, woff.flavor );
+      WRITE_USHORT( sfnt_header, woff.num_tables );
+      WRITE_USHORT( sfnt_header, searchRange );
+      WRITE_USHORT( sfnt_header, entrySelector );
+      WRITE_USHORT( sfnt_header, rangeShift );
+    }
+
+    /* While the entries in the sfnt header must be sorted by the */
+    /* tag value, the tables themselves are not.  We thus have to */
+    /* sort them by offset and check that they don't overlap.     */
+
+    if ( FT_QNEW_ARRAY( tables, woff.num_tables )  ||
+         FT_QNEW_ARRAY( indices, woff.num_tables ) )
+      goto Exit;
+
+    FT_TRACE2(( "\n" ));
+    FT_TRACE2(( "  tag    offset    compLen  origLen  checksum\n" ));
+    FT_TRACE2(( "  -------------------------------------------\n" ));
+
+    if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
+      goto Exit;
+
+    for ( nn = 0; nn < woff.num_tables; nn++ )
+    {
+      WOFF_Table  table = tables + nn;
+
+      table->Tag        = FT_GET_TAG4();
+      table->Offset     = FT_GET_ULONG();
+      table->CompLength = FT_GET_ULONG();
+      table->OrigLength = FT_GET_ULONG();
+      table->CheckSum   = FT_GET_ULONG();
+
+      FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx  %08lx\n",
+                  (FT_Char)( table->Tag >> 24 ),
+                  (FT_Char)( table->Tag >> 16 ),
+                  (FT_Char)( table->Tag >> 8  ),
+                  (FT_Char)( table->Tag       ),
+                  table->Offset,
+                  table->CompLength,
+                  table->OrigLength,
+                  table->CheckSum ));
+
+      if ( table->Tag <= old_tag )
+      {
+        FT_FRAME_EXIT();
+
+        FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      old_tag     = table->Tag;
+      indices[nn] = table;
+    }
+
+    FT_FRAME_EXIT();
+
+    /* Sort by offset. */
+
+    ft_qsort( indices,
+              woff.num_tables,
+              sizeof ( WOFF_Table ),
+              compare_offsets );
+
+    /* Check offsets and lengths. */
+
+    woff_offset = 44 + woff.num_tables * 20L;
+    sfnt_offset = 12 + woff.num_tables * 16L;
+
+    for ( nn = 0; nn < woff.num_tables; nn++ )
+    {
+      WOFF_Table  table = indices[nn];
+
+
+      if ( table->Offset != woff_offset                         ||
+           table->CompLength > woff.length                      ||
+           table->Offset > woff.length - table->CompLength      ||
+           table->OrigLength > woff.totalSfntSize               ||
+           sfnt_offset > woff.totalSfntSize - table->OrigLength ||
+           table->CompLength > table->OrigLength                )
+      {
+        FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      table->OrigOffset = sfnt_offset;
+
+      /* The offsets must be multiples of 4. */
+      woff_offset += ( table->CompLength + 3 ) & ~3U;
+      sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
+    }
+
+    /*
+     * Final checks!
+     *
+     * We don't decode and check the metadata block.
+     * We don't check table checksums either.
+     * But other than those, I think we implement all
+     * `MUST' checks from the spec.
+     */
+
+    if ( woff.metaOffset )
+    {
+      if ( woff.metaOffset != woff_offset                  ||
+           woff.metaOffset + woff.metaLength > woff.length )
+      {
+        FT_ERROR(( "woff_font_open:"
+                   " invalid `metadata' offset or length\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      /* We have padding only ... */
+      woff_offset += woff.metaLength;
+    }
+
+    if ( woff.privOffset )
+    {
+      /* ... if it isn't the last block. */
+      woff_offset = ( woff_offset + 3 ) & ~3U;
+
+      if ( woff.privOffset != woff_offset                  ||
+           woff.privOffset + woff.privLength > woff.length )
+      {
+        FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      /* No padding for the last block. */
+      woff_offset += woff.privLength;
+    }
+
+    if ( sfnt_offset != woff.totalSfntSize ||
+         woff_offset != woff.length        )
+    {
+      FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* Now use `totalSfntSize'. */
+    if ( FT_QREALLOC( sfnt, 12, woff.totalSfntSize ) )
+      goto Exit;
+
+    sfnt_header = sfnt + 12;
+
+    /* Write the tables. */
+
+    for ( nn = 0; nn < woff.num_tables; nn++ )
+    {
+      WOFF_Table  table = tables + nn;
+
+
+      /* Write SFNT table entry. */
+      WRITE_ULONG( sfnt_header, table->Tag );
+      WRITE_ULONG( sfnt_header, table->CheckSum );
+      WRITE_ULONG( sfnt_header, table->OrigOffset );
+      WRITE_ULONG( sfnt_header, table->OrigLength );
+
+      /* Write table data. */
+      if ( FT_STREAM_SEEK( table->Offset )     ||
+           FT_FRAME_ENTER( table->CompLength ) )
+        goto Exit;
+
+      if ( table->CompLength == table->OrigLength )
+      {
+        /* Uncompressed data; just copy. */
+        ft_memcpy( sfnt + table->OrigOffset,
+                   stream->cursor,
+                   table->OrigLength );
+      }
+      else
+      {
+        /* Uncompress with zlib. */
+        FT_ULong  output_len = table->OrigLength;
+
+
+        error = FT_Gzip_Uncompress( memory,
+                                    sfnt + table->OrigOffset, &output_len,
+                                    stream->cursor, table->CompLength );
+        if ( error )
+          goto Exit1;
+        if ( output_len != table->OrigLength )
+        {
+          FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit1;
+        }
+      }
+
+      FT_FRAME_EXIT();
+
+      /* We don't check whether the padding bytes in the WOFF file are     */
+      /* actually '\0'.  For the output, however, we do set them properly. */
+      sfnt_offset = table->OrigOffset + table->OrigLength;
+      while ( sfnt_offset & 3 )
+      {
+        sfnt[sfnt_offset] = '\0';
+        sfnt_offset++;
+      }
+    }
+
+    /* Ok!  Finally ready.  Swap out stream and return. */
+    FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
+    sfnt_stream->memory = stream->memory;
+    sfnt_stream->close  = sfnt_stream_close;
+
+    FT_Stream_Free(
+      face->root.stream,
+      ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
+
+    face->root.stream = sfnt_stream;
+
+    face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
+
+  Exit:
+    FT_FREE( tables );
+    FT_FREE( indices );
+
+    if ( error )
+    {
+      FT_FREE( sfnt );
+      FT_Stream_Close( sfnt_stream );
+      FT_FREE( sfnt_stream );
+    }
+
+    return error;
+
+  Exit1:
+    FT_FRAME_EXIT();
+    goto Exit;
+  }
+
+
+#undef WRITE_USHORT
+#undef WRITE_ULONG
+
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+  /* ANSI C doesn't like empty source files */
+  typedef int  _sfwoff_dummy;
+
+#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+
+/* END */
diff --git a/src/sfnt/sfwoff.h b/src/sfnt/sfwoff.h
new file mode 100644
index 0000000..d438422
--- /dev/null
+++ b/src/sfnt/sfwoff.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ *
+ * sfwoff.h
+ *
+ *   WOFFF format management (specification).
+ *
+ * Copyright (C) 1996-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 SFWOFF_H_
+#define SFWOFF_H_
+
+
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftobjs.h>
+
+
+FT_BEGIN_HEADER
+
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
+  FT_LOCAL( FT_Error )
+  woff_open_font( FT_Stream  stream,
+                  TT_Face    face );
+
+
+#endif
+
+FT_END_HEADER
+
+#endif /* SFWOFF_H_ */
+
+
+/* END */
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
new file mode 100644
index 0000000..7a01977
--- /dev/null
+++ b/src/sfnt/sfwoff2.c
@@ -0,0 +1,2386 @@
+/****************************************************************************
+ *
+ * sfwoff2.c
+ *
+ *   WOFF2 format management (base).
+ *
+ * Copyright (C) 2019-2023 by
+ * Nikhil Ramakrishnan, 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 "sfwoff2.h"
+#include "woff2tags.h"
+#include <freetype/tttags.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+#include <brotli/decode.h>
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  sfwoff2
+
+
+#define READ_255USHORT( var )  FT_SET_ERROR( Read255UShort( stream, &var ) )
+
+#define READ_BASE128( var )    FT_SET_ERROR( ReadBase128( stream, &var ) )
+
+  /* `var' should be FT_ULong */
+#define ROUND4( var )          ( ( var + 3 ) & ~3UL )
+
+#define WRITE_USHORT( p, v )                \
+          do                                \
+          {                                 \
+            *(p)++ = (FT_Byte)( (v) >> 8 ); \
+            *(p)++ = (FT_Byte)( (v) >> 0 ); \
+                                            \
+          } while ( 0 )
+
+#define WRITE_ULONG( p, v )                  \
+          do                                 \
+          {                                  \
+            *(p)++ = (FT_Byte)( (v) >> 24 ); \
+            *(p)++ = (FT_Byte)( (v) >> 16 ); \
+            *(p)++ = (FT_Byte)( (v) >>  8 ); \
+            *(p)++ = (FT_Byte)( (v) >>  0 ); \
+                                             \
+          } while ( 0 )
+
+#define WRITE_SHORT( p, v )                 \
+          do                                \
+          {                                 \
+            *(p)++ = (FT_Byte)( (v) >> 8 ); \
+            *(p)++ = (FT_Byte)( (v) >> 0 ); \
+                                            \
+          } while ( 0 )
+
+#define WRITE_SFNT_BUF( buf, s ) \
+          write_buf( &sfnt, sfnt_size, &dest_offset, buf, s, memory )
+
+#define WRITE_SFNT_BUF_AT( offset, buf, s ) \
+          write_buf( &sfnt, sfnt_size, &offset, buf, s, memory )
+
+#define N_CONTOUR_STREAM    0
+#define N_POINTS_STREAM     1
+#define FLAG_STREAM         2
+#define GLYPH_STREAM        3
+#define COMPOSITE_STREAM    4
+#define BBOX_STREAM         5
+#define INSTRUCTION_STREAM  6
+
+#define HAVE_OVERLAP_SIMPLE_BITMAP  0x1
+
+
+  static void
+  stream_close( FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+
+
+    FT_FREE( stream->base );
+
+    stream->size  = 0;
+    stream->close = NULL;
+  }
+
+
+  FT_COMPARE_DEF( int )
+  compare_tags( const void*  a,
+                const void*  b )
+  {
+    WOFF2_Table  table1 = *(WOFF2_Table*)a;
+    WOFF2_Table  table2 = *(WOFF2_Table*)b;
+
+    FT_Tag  tag1 = table1->Tag;
+    FT_Tag  tag2 = table2->Tag;
+
+
+    if ( tag1 > tag2 )
+      return 1;
+    else if ( tag1 < tag2 )
+      return -1;
+    else
+      return 0;
+  }
+
+
+  static FT_Error
+  Read255UShort( FT_Stream   stream,
+                 FT_UShort*  value )
+  {
+    const FT_Byte    oneMoreByteCode1 = 255;
+    const FT_Byte    oneMoreByteCode2 = 254;
+    const FT_Byte    wordCode         = 253;
+    const FT_UShort  lowestUCode      = 253;
+
+    FT_Error   error        = FT_Err_Ok;
+    FT_Byte    code;
+    FT_Byte    result_byte  = 0;
+    FT_UShort  result_short = 0;
+
+
+    if ( FT_READ_BYTE( code ) )
+      return error;
+    if ( code == wordCode )
+    {
+      /* Read next two bytes and store `FT_UShort' value. */
+      if ( FT_READ_USHORT( result_short ) )
+        return error;
+      *value = result_short;
+      return FT_Err_Ok;
+    }
+    else if ( code == oneMoreByteCode1 )
+    {
+      if ( FT_READ_BYTE( result_byte ) )
+        return error;
+      *value = result_byte + lowestUCode;
+      return FT_Err_Ok;
+    }
+    else if ( code == oneMoreByteCode2 )
+    {
+      if ( FT_READ_BYTE( result_byte ) )
+        return error;
+      *value = result_byte + lowestUCode * 2;
+      return FT_Err_Ok;
+    }
+    else
+    {
+      *value = code;
+      return FT_Err_Ok;
+    }
+  }
+
+
+  static FT_Error
+  ReadBase128( FT_Stream  stream,
+               FT_ULong*  value )
+  {
+    FT_ULong  result = 0;
+    FT_Int    i;
+    FT_Byte   code;
+    FT_Error  error  = FT_Err_Ok;
+
+
+    for ( i = 0; i < 5; ++i )
+    {
+      code = 0;
+      if ( FT_READ_BYTE( code ) )
+        return error;
+
+      /* Leading zeros are invalid. */
+      if ( i == 0 && code == 0x80 )
+        return FT_THROW( Invalid_Table );
+
+      /* If any of top seven bits are set then we're about to overflow. */
+      if ( result & 0xfe000000 )
+        return FT_THROW( Invalid_Table );
+
+      result = ( result << 7 ) | ( code & 0x7f );
+
+      /* Spin until most significant bit of data byte is false. */
+      if ( ( code & 0x80 ) == 0 )
+      {
+        *value = result;
+        return FT_Err_Ok;
+      }
+    }
+
+    /* Make sure not to exceed the size bound. */
+    return FT_THROW( Invalid_Table );
+  }
+
+
+  /* Extend memory of `dst_bytes' buffer and copy data from `src'. */
+  static FT_Error
+  write_buf( FT_Byte**  dst_bytes,
+             FT_ULong*  dst_size,
+             FT_ULong*  offset,
+             FT_Byte*   src,
+             FT_ULong   size,
+             FT_Memory  memory )
+  {
+    FT_Error  error = FT_Err_Ok;
+    /* We are reallocating memory for `dst', so its pointer may change. */
+    FT_Byte*  dst   = *dst_bytes;
+
+
+    /* Check whether we are within limits. */
+    if ( ( *offset + size ) > WOFF2_DEFAULT_MAX_SIZE  )
+      return FT_THROW( Array_Too_Large );
+
+    /* Reallocate `dst'. */
+    if ( ( *offset + size ) > *dst_size )
+    {
+      FT_TRACE6(( "Reallocating %lu to %lu.\n",
+                  *dst_size, (*offset + size) ));
+      if ( FT_QREALLOC( dst,
+                        (FT_ULong)( *dst_size ),
+                        (FT_ULong)( *offset + size ) ) )
+        goto Exit;
+
+      *dst_size = *offset + size;
+    }
+
+    /* Copy data. */
+    ft_memcpy( dst + *offset, src, size );
+
+    *offset += size;
+    /* Set pointer of `dst' to its correct value. */
+    *dst_bytes = dst;
+
+  Exit:
+    return error;
+  }
+
+
+  /* Pad buffer to closest multiple of 4. */
+  static FT_Error
+  pad4( FT_Byte**  sfnt_bytes,
+        FT_ULong*  sfnt_size,
+        FT_ULong*  out_offset,
+        FT_Memory  memory )
+  {
+    FT_Byte*  sfnt        = *sfnt_bytes;
+    FT_ULong  dest_offset = *out_offset;
+
+    FT_Byte   zeroes[] = { 0, 0, 0 };
+    FT_ULong  pad_bytes;
+
+
+    if ( dest_offset + 3 < dest_offset )
+      return FT_THROW( Invalid_Table );
+
+    pad_bytes = ROUND4( dest_offset ) - dest_offset;
+    if ( pad_bytes > 0 )
+    {
+      if ( WRITE_SFNT_BUF( &zeroes[0], pad_bytes ) )
+        return FT_THROW( Invalid_Table );
+    }
+
+    *sfnt_bytes = sfnt;
+    *out_offset = dest_offset;
+    return FT_Err_Ok;
+  }
+
+
+  /* Calculate table checksum of `buf'. */
+  static FT_ULong
+  compute_ULong_sum( FT_Byte*  buf,
+                     FT_ULong  size )
+  {
+    FT_ULong  checksum     = 0;
+    FT_ULong  aligned_size = size & ~3UL;
+    FT_ULong  i;
+    FT_ULong  v;
+
+
+    for ( i = 0; i < aligned_size; i += 4 )
+      checksum += ( (FT_ULong)buf[i    ] << 24 ) |
+                  ( (FT_ULong)buf[i + 1] << 16 ) |
+                  ( (FT_ULong)buf[i + 2] <<  8 ) |
+                  ( (FT_ULong)buf[i + 3] <<  0 );
+
+    /* If size is not aligned to 4, treat as if it is padded with 0s. */
+    if ( size != aligned_size )
+    {
+      v = 0;
+      for ( i = aligned_size ; i < size; ++i )
+        v |= (FT_ULong)buf[i] << ( 24 - 8 * ( i & 3 ) );
+      checksum += v;
+    }
+
+    return checksum;
+  }
+
+
+  static FT_Error
+  woff2_decompress( FT_Byte*        dst,
+                    FT_ULong        dst_size,
+                    const FT_Byte*  src,
+                    FT_ULong        src_size )
+  {
+    /* this cast is only of importance on 32bit systems; */
+    /* we don't validate it                              */
+    FT_Offset            uncompressed_size = (FT_Offset)dst_size;
+    BrotliDecoderResult  result;
+
+
+    result = BrotliDecoderDecompress( src_size,
+                                      src,
+                                      &uncompressed_size,
+                                      dst );
+
+    if ( result != BROTLI_DECODER_RESULT_SUCCESS ||
+         uncompressed_size != dst_size           )
+    {
+      FT_ERROR(( "woff2_decompress: Stream length mismatch.\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    FT_TRACE2(( "woff2_decompress: Brotli stream decompressed.\n" ));
+    return FT_Err_Ok;
+  }
+
+
+  static WOFF2_Table
+  find_table( WOFF2_Table*  tables,
+              FT_UShort     num_tables,
+              FT_Tag        tag )
+  {
+    FT_Int  i;
+
+
+    for ( i = 0; i < num_tables; i++ )
+    {
+      if ( tables[i]->Tag == tag )
+        return tables[i];
+    }
+    return NULL;
+  }
+
+
+  /* Read `numberOfHMetrics' field from `hhea' table. */
+  static FT_Error
+  read_num_hmetrics( FT_Stream   stream,
+                     FT_UShort*  num_hmetrics )
+  {
+    FT_Error   error = FT_Err_Ok;
+    FT_UShort  num_metrics;
+
+
+    if ( FT_STREAM_SKIP( 34 )  )
+      return FT_THROW( Invalid_Table );
+
+    if ( FT_READ_USHORT( num_metrics ) )
+      return FT_THROW( Invalid_Table );
+
+    *num_hmetrics = num_metrics;
+
+    return error;
+  }
+
+
+  /* An auxiliary function for overflow-safe addition. */
+  static FT_Int
+  with_sign( FT_Byte  flag,
+             FT_Int   base_val )
+  {
+    /* Precondition: 0 <= base_val < 65536 (to avoid overflow). */
+    return ( flag & 1 ) ? base_val : -base_val;
+  }
+
+
+  /* An auxiliary function for overflow-safe addition. */
+  static FT_Int
+  safe_int_addition( FT_Int   a,
+                     FT_Int   b,
+                     FT_Int*  result )
+  {
+    if ( ( ( a > 0 ) && ( b > FT_INT_MAX - a ) ) ||
+         ( ( a < 0 ) && ( b < FT_INT_MIN - a ) ) )
+      return FT_THROW( Invalid_Table );
+
+    *result = a + b;
+    return FT_Err_Ok;
+  }
+
+
+  /*
+   * Decode variable-length (flag, xCoordinate, yCoordinate) triplet for a
+   * simple glyph.  See
+   *
+   *   https://www.w3.org/TR/WOFF2/#triplet_decoding
+   */
+  static FT_Error
+  triplet_decode( const FT_Byte*  flags_in,
+                  const FT_Byte*  in,
+                  FT_ULong        in_size,
+                  FT_ULong        n_points,
+                  WOFF2_Point     result,
+                  FT_ULong*       in_bytes_used )
+  {
+    FT_Int  x = 0;
+    FT_Int  y = 0;
+    FT_Int  dx;
+    FT_Int  dy;
+    FT_Int  b0, b1, b2;
+
+    FT_ULong  triplet_index = 0;
+    FT_ULong  data_bytes;
+
+    FT_UInt  i;
+
+
+    if ( n_points > in_size )
+      return FT_THROW( Invalid_Table );
+
+    for ( i = 0; i < n_points; ++i )
+    {
+      FT_Byte  flag     = flags_in[i];
+      FT_Bool  on_curve = !( flag >> 7 );
+
+
+      flag &= 0x7f;
+      if ( flag < 84 )
+        data_bytes = 1;
+      else if ( flag < 120 )
+        data_bytes = 2;
+      else if ( flag < 124 )
+        data_bytes = 3;
+      else
+        data_bytes = 4;
+
+      /* Overflow checks */
+      if ( triplet_index + data_bytes > in_size       ||
+           triplet_index + data_bytes < triplet_index )
+        return FT_THROW( Invalid_Table );
+
+      if ( flag < 10 )
+      {
+        dx = 0;
+        dy = with_sign( flag,
+                        ( ( flag & 14 ) << 7 ) + in[triplet_index] );
+      }
+      else if ( flag < 20 )
+      {
+        dx = with_sign( flag,
+                        ( ( ( flag - 10 ) & 14 ) << 7 ) +
+                          in[triplet_index] );
+        dy = 0;
+      }
+      else if ( flag < 84 )
+      {
+        b0 = flag - 20;
+        b1 = in[triplet_index];
+        dx = with_sign( flag,
+                        1 + ( b0 & 0x30 ) + ( b1 >> 4 ) );
+        dy = with_sign( flag >> 1,
+                        1 + ( ( b0 & 0x0c ) << 2 ) + ( b1 & 0x0f ) );
+      }
+      else if ( flag < 120 )
+      {
+        b0 = flag - 84;
+        dx = with_sign( flag,
+                        1 + ( ( b0 / 12 ) << 8 ) + in[triplet_index] );
+        dy = with_sign( flag >> 1,
+                        1 + ( ( ( b0 % 12 ) >> 2 ) << 8 ) +
+                          in[triplet_index + 1] );
+      }
+      else if ( flag < 124 )
+      {
+        b2 = in[triplet_index + 1];
+        dx = with_sign( flag,
+                        ( in[triplet_index] << 4 ) + ( b2 >> 4 ) );
+        dy = with_sign( flag >> 1,
+                        ( ( b2 & 0x0f ) << 8 ) + in[triplet_index + 2] );
+      }
+      else
+      {
+        dx = with_sign( flag,
+                        ( in[triplet_index] << 8 ) +
+                          in[triplet_index + 1] );
+        dy = with_sign( flag >> 1,
+                        ( in[triplet_index + 2] << 8 ) +
+                          in[triplet_index + 3] );
+      }
+
+      triplet_index += data_bytes;
+
+      if ( safe_int_addition( x, dx, &x ) )
+        return FT_THROW( Invalid_Table );
+
+      if ( safe_int_addition( y, dy, &y ) )
+        return FT_THROW( Invalid_Table );
+
+      result[i].x        = x;
+      result[i].y        = y;
+      result[i].on_curve = on_curve;
+    }
+
+    *in_bytes_used = triplet_index;
+    return FT_Err_Ok;
+  }
+
+
+  /* Store decoded points in glyph buffer. */
+  static FT_Error
+  store_points( FT_ULong           n_points,
+                const WOFF2_Point  points,
+                FT_UShort          n_contours,
+                FT_UShort          instruction_len,
+                FT_Bool            have_overlap,
+                FT_Byte*           dst,
+                FT_ULong           dst_size,
+                FT_ULong*          glyph_size )
+  {
+    FT_UInt   flag_offset  = 10 + ( 2 * n_contours ) + 2 + instruction_len;
+    FT_Byte   last_flag    = 0xFFU;
+    FT_Byte   repeat_count = 0;
+    FT_Int    last_x       = 0;
+    FT_Int    last_y       = 0;
+    FT_UInt   x_bytes      = 0;
+    FT_UInt   y_bytes      = 0;
+    FT_UInt   xy_bytes;
+    FT_UInt   i;
+    FT_UInt   x_offset;
+    FT_UInt   y_offset;
+    FT_Byte*  pointer;
+
+
+    for ( i = 0; i < n_points; ++i )
+    {
+      const WOFF2_PointRec  point = points[i];
+
+      FT_Byte  flag = point.on_curve ? GLYF_ON_CURVE : 0;
+      FT_Int   dx   = point.x - last_x;
+      FT_Int   dy   = point.y - last_y;
+
+
+      if ( i == 0 && have_overlap )
+        flag |= GLYF_OVERLAP_SIMPLE;
+
+      if ( dx == 0 )
+        flag |= GLYF_THIS_X_IS_SAME;
+      else if ( dx > -256 && dx < 256 )
+      {
+        flag |= GLYF_X_SHORT | ( dx > 0 ? GLYF_THIS_X_IS_SAME : 0 );
+        x_bytes += 1;
+      }
+      else
+        x_bytes += 2;
+
+      if ( dy == 0 )
+        flag |= GLYF_THIS_Y_IS_SAME;
+      else if ( dy > -256 && dy < 256 )
+      {
+        flag |= GLYF_Y_SHORT | ( dy > 0 ? GLYF_THIS_Y_IS_SAME : 0 );
+        y_bytes += 1;
+      }
+      else
+        y_bytes += 2;
+
+      if ( flag == last_flag && repeat_count != 255 )
+      {
+        dst[flag_offset - 1] |= GLYF_REPEAT;
+        repeat_count++;
+      }
+      else
+      {
+        if ( repeat_count != 0 )
+        {
+          if ( flag_offset >= dst_size )
+            return FT_THROW( Invalid_Table );
+
+          dst[flag_offset++] = repeat_count;
+        }
+        if ( flag_offset >= dst_size )
+          return FT_THROW( Invalid_Table );
+
+        dst[flag_offset++] = flag;
+        repeat_count       = 0;
+      }
+
+      last_x    = point.x;
+      last_y    = point.y;
+      last_flag = flag;
+    }
+
+    if ( repeat_count != 0 )
+    {
+      if ( flag_offset >= dst_size )
+        return FT_THROW( Invalid_Table );
+
+      dst[flag_offset++] = repeat_count;
+    }
+
+    xy_bytes = x_bytes + y_bytes;
+    if ( xy_bytes < x_bytes                   ||
+         flag_offset + xy_bytes < flag_offset ||
+         flag_offset + xy_bytes > dst_size    )
+      return FT_THROW( Invalid_Table );
+
+    x_offset = flag_offset;
+    y_offset = flag_offset + x_bytes;
+    last_x = 0;
+    last_y = 0;
+
+    for ( i = 0; i < n_points; ++i )
+    {
+      FT_Int  dx = points[i].x - last_x;
+      FT_Int  dy = points[i].y - last_y;
+
+
+      if ( dx == 0 )
+        ;
+      else if ( dx > -256 && dx < 256 )
+        dst[x_offset++] = (FT_Byte)FT_ABS( dx );
+      else
+      {
+        pointer = dst + x_offset;
+        WRITE_SHORT( pointer, dx );
+        x_offset += 2;
+      }
+
+      last_x += dx;
+
+      if ( dy == 0 )
+        ;
+      else if ( dy > -256 && dy < 256 )
+        dst[y_offset++] = (FT_Byte)FT_ABS( dy );
+      else
+      {
+        pointer = dst + y_offset;
+        WRITE_SHORT( pointer, dy );
+        y_offset += 2;
+      }
+
+      last_y += dy;
+    }
+
+    *glyph_size = y_offset;
+    return FT_Err_Ok;
+  }
+
+
+  static void
+  compute_bbox( FT_ULong           n_points,
+                const WOFF2_Point  points,
+                FT_Byte*           dst,
+                FT_UShort*         src_x_min )
+  {
+    FT_Int  x_min = 0;
+    FT_Int  y_min = 0;
+    FT_Int  x_max = 0;
+    FT_Int  y_max = 0;
+
+    FT_UInt  i;
+
+    FT_ULong  offset;
+    FT_Byte*  pointer;
+
+
+    if ( n_points > 0 )
+    {
+      x_min = points[0].x;
+      y_min = points[0].y;
+      x_max = points[0].x;
+      y_max = points[0].y;
+    }
+
+    for ( i = 1; i < n_points; ++i )
+    {
+      FT_Int  x = points[i].x;
+      FT_Int  y = points[i].y;
+
+
+      x_min = FT_MIN( x, x_min );
+      y_min = FT_MIN( y, y_min );
+      x_max = FT_MAX( x, x_max );
+      y_max = FT_MAX( y, y_max );
+    }
+
+    /* Write values to `glyf' record. */
+    offset  = 2;
+    pointer = dst + offset;
+
+    WRITE_SHORT( pointer, x_min );
+    WRITE_SHORT( pointer, y_min );
+    WRITE_SHORT( pointer, x_max );
+    WRITE_SHORT( pointer, y_max );
+
+    *src_x_min = (FT_UShort)x_min;
+  }
+
+
+  static FT_Error
+  compositeGlyph_size( FT_Stream  stream,
+                       FT_ULong   offset,
+                       FT_ULong*  size,
+                       FT_Bool*   have_instructions )
+  {
+    FT_Error   error        = FT_Err_Ok;
+    FT_ULong   start_offset = offset;
+    FT_Bool    we_have_inst = FALSE;
+    FT_UShort  flags        = FLAG_MORE_COMPONENTS;
+
+
+    if ( FT_STREAM_SEEK( start_offset ) )
+      goto Exit;
+    while ( flags & FLAG_MORE_COMPONENTS )
+    {
+      FT_ULong  arg_size;
+
+
+      if ( FT_READ_USHORT( flags ) )
+        goto Exit;
+      we_have_inst |= ( flags & FLAG_WE_HAVE_INSTRUCTIONS ) != 0;
+      /* glyph index */
+      arg_size = 2;
+      if ( flags & FLAG_ARG_1_AND_2_ARE_WORDS )
+        arg_size += 4;
+      else
+        arg_size += 2;
+
+      if ( flags & FLAG_WE_HAVE_A_SCALE )
+        arg_size += 2;
+      else if ( flags & FLAG_WE_HAVE_AN_X_AND_Y_SCALE )
+        arg_size += 4;
+      else if ( flags & FLAG_WE_HAVE_A_TWO_BY_TWO )
+        arg_size += 8;
+
+      if ( FT_STREAM_SKIP( arg_size ) )
+        goto Exit;
+    }
+
+    *size              = FT_STREAM_POS() - start_offset;
+    *have_instructions = we_have_inst;
+
+  Exit:
+    return error;
+  }
+
+
+  /* Store loca values (provided by `reconstruct_glyf') to output stream. */
+  static FT_Error
+  store_loca( FT_ULong*  loca_values,
+              FT_ULong   loca_values_size,
+              FT_UShort  index_format,
+              FT_ULong*  checksum,
+              FT_Byte**  sfnt_bytes,
+              FT_ULong*  sfnt_size,
+              FT_ULong*  out_offset,
+              FT_Memory  memory )
+  {
+    FT_Error  error       = FT_Err_Ok;
+    FT_Byte*  sfnt        = *sfnt_bytes;
+    FT_ULong  dest_offset = *out_offset;
+
+    FT_Byte*  loca_buf = NULL;
+    FT_Byte*  dst      = NULL;
+
+    FT_UInt   i = 0;
+    FT_ULong  loca_buf_size;
+
+    const FT_ULong  offset_size = index_format ? 4 : 2;
+
+
+    if ( ( loca_values_size << 2 ) >> 2 != loca_values_size )
+      goto Fail;
+
+    loca_buf_size = loca_values_size * offset_size;
+    if ( FT_QALLOC( loca_buf, loca_buf_size ) )
+      goto Fail;
+
+    dst = loca_buf;
+    for ( i = 0; i < loca_values_size; i++ )
+    {
+      FT_ULong  value = loca_values[i];
+
+
+      if ( index_format )
+        WRITE_ULONG( dst, value );
+      else
+        WRITE_USHORT( dst, ( value >> 1 ) );
+    }
+
+    *checksum = compute_ULong_sum( loca_buf, loca_buf_size );
+    /* Write `loca' table to sfnt buffer. */
+    if ( WRITE_SFNT_BUF( loca_buf, loca_buf_size ) )
+      goto Fail;
+
+    /* Set pointer `sfnt_bytes' to its correct value. */
+    *sfnt_bytes = sfnt;
+    *out_offset = dest_offset;
+
+    FT_FREE( loca_buf );
+    return error;
+
+  Fail:
+    if ( !error )
+      error = FT_THROW( Invalid_Table );
+
+    FT_FREE( loca_buf );
+
+    return error;
+  }
+
+
+  static FT_Error
+  reconstruct_glyf( FT_Stream    stream,
+                    FT_ULong*    glyf_checksum,
+                    FT_ULong*    loca_checksum,
+                    FT_Byte**    sfnt_bytes,
+                    FT_ULong*    sfnt_size,
+                    FT_ULong*    out_offset,
+                    WOFF2_Info   info,
+                    FT_Memory    memory )
+  {
+    FT_Error  error = FT_Err_Ok;
+    FT_Byte*  sfnt  = *sfnt_bytes;
+
+    /* current position in stream */
+    const FT_ULong  pos = FT_STREAM_POS();
+
+    FT_UInt  num_substreams = 7;
+
+    FT_UShort  option_flags;
+    FT_UShort  num_glyphs;
+    FT_UShort  index_format;
+    FT_ULong   expected_loca_length;
+    FT_UInt    offset;
+    FT_UInt    i;
+    FT_ULong   points_size;
+    FT_ULong   glyph_buf_size;
+    FT_ULong   bbox_bitmap_offset;
+    FT_ULong   bbox_bitmap_length;
+    FT_ULong   overlap_bitmap_offset = 0;
+    FT_ULong   overlap_bitmap_length = 0;
+
+    const FT_ULong  glyf_start  = *out_offset;
+    FT_ULong        dest_offset = *out_offset;
+
+    WOFF2_Substream  substreams = NULL;
+
+    FT_ULong*    loca_values  = NULL;
+    FT_UShort*   n_points_arr = NULL;
+    FT_Byte*     glyph_buf    = NULL;
+    WOFF2_Point  points       = NULL;
+
+
+    if ( FT_QNEW_ARRAY( substreams, num_substreams ) )
+      goto Fail;
+
+    if ( FT_STREAM_SKIP( 2 ) )
+      goto Fail;
+    if ( FT_READ_USHORT( option_flags ) )
+      goto Fail;
+    if ( FT_READ_USHORT( num_glyphs ) )
+      goto Fail;
+    if ( FT_READ_USHORT( index_format ) )
+      goto Fail;
+
+    FT_TRACE4(( "option_flags = %u; num_glyphs = %u; index_format = %u\n",
+                option_flags, num_glyphs, index_format ));
+
+    info->num_glyphs = num_glyphs;
+
+    /* Calculate expected length of loca and compare.          */
+    /* See https://www.w3.org/TR/WOFF2/#conform-mustRejectLoca */
+    /* index_format = 0 => Short version `loca'.               */
+    /* index_format = 1 => Long version `loca'.                */
+    expected_loca_length = ( index_format ? 4 : 2 ) *
+                             ( (FT_ULong)num_glyphs + 1 );
+    if ( info->loca_table->dst_length != expected_loca_length )
+      goto Fail;
+
+    offset = 2 + 2 + 2 + 2 + ( num_substreams * 4 );
+    if ( offset > info->glyf_table->TransformLength )
+      goto Fail;
+
+    for ( i = 0; i < num_substreams; ++i )
+    {
+      FT_ULong  substream_size;
+
+
+      if ( FT_READ_ULONG( substream_size ) )
+        goto Fail;
+      if ( substream_size > info->glyf_table->TransformLength - offset )
+        goto Fail;
+
+      substreams[i].start  = pos + offset;
+      substreams[i].offset = pos + offset;
+      substreams[i].size   = substream_size;
+
+      FT_TRACE5(( "  Substream %d: offset = %lu; size = %lu;\n",
+                  i, substreams[i].offset, substreams[i].size ));
+      offset += substream_size;
+    }
+
+    if ( option_flags & HAVE_OVERLAP_SIMPLE_BITMAP )
+    {
+      /* Size of overlapBitmap = floor((numGlyphs + 7) / 8) */
+      overlap_bitmap_length = ( num_glyphs + 7U ) >> 3;
+      if ( overlap_bitmap_length > info->glyf_table->TransformLength - offset )
+        goto Fail;
+
+      overlap_bitmap_offset = pos + offset;
+
+      FT_TRACE5(( "  Overlap bitmap: offset = %lu; size = %lu;\n",
+                  overlap_bitmap_offset, overlap_bitmap_length ));
+      offset += overlap_bitmap_length;
+    }
+
+    if ( FT_QNEW_ARRAY( loca_values, num_glyphs + 1 ) )
+      goto Fail;
+
+    points_size        = 0;
+    bbox_bitmap_offset = substreams[BBOX_STREAM].offset;
+
+    /* Size of bboxBitmap = 4 * floor((numGlyphs + 31) / 32) */
+    bbox_bitmap_length              = ( ( num_glyphs + 31U ) >> 5 ) << 2;
+    /* bboxStreamSize is the combined size of bboxBitmap and bboxStream. */
+    substreams[BBOX_STREAM].offset += bbox_bitmap_length;
+
+    glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
+    if ( FT_QALLOC( glyph_buf, glyph_buf_size ) )
+      goto Fail;
+
+    if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
+      goto Fail;
+
+    for ( i = 0; i < num_glyphs; ++i )
+    {
+      FT_ULong   glyph_size = 0;
+      FT_UShort  n_contours = 0;
+      FT_Bool    have_bbox  = FALSE;
+      FT_Byte    bbox_bitmap;
+      FT_ULong   bbox_offset;
+      FT_UShort  x_min      = 0;
+
+
+      /* Set `have_bbox'. */
+      bbox_offset = bbox_bitmap_offset + ( i >> 3 );
+      if ( FT_STREAM_SEEK( bbox_offset ) ||
+           FT_READ_BYTE( bbox_bitmap )   )
+        goto Fail;
+      if ( bbox_bitmap & ( 0x80 >> ( i & 7 ) ) )
+        have_bbox = TRUE;
+
+      /* Read value from `nContourStream'. */
+      if ( FT_STREAM_SEEK( substreams[N_CONTOUR_STREAM].offset ) ||
+           FT_READ_USHORT( n_contours )                          )
+        goto Fail;
+      substreams[N_CONTOUR_STREAM].offset += 2;
+
+      if ( n_contours == 0xffff )
+      {
+        /* composite glyph */
+        FT_Bool    have_instructions = FALSE;
+        FT_UShort  instruction_size  = 0;
+        FT_ULong   composite_size    = 0;
+        FT_ULong   size_needed;
+        FT_Byte*   pointer           = NULL;
+
+
+        /* Composite glyphs must have explicit bbox. */
+        if ( !have_bbox )
+          goto Fail;
+
+        if ( compositeGlyph_size( stream,
+                                  substreams[COMPOSITE_STREAM].offset,
+                                  &composite_size,
+                                  &have_instructions) )
+          goto Fail;
+
+        if ( have_instructions )
+        {
+          if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
+               READ_255USHORT( instruction_size )                )
+            goto Fail;
+          substreams[GLYPH_STREAM].offset = FT_STREAM_POS();
+        }
+
+        size_needed = 12 + composite_size + instruction_size;
+        if ( glyph_buf_size < size_needed )
+        {
+          if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
+            goto Fail;
+          glyph_buf_size = size_needed;
+        }
+
+        pointer = glyph_buf + glyph_size;
+        WRITE_USHORT( pointer, n_contours );
+        glyph_size += 2;
+
+        /* Read x_min for current glyph. */
+        if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+             FT_READ_USHORT( x_min )                          )
+          goto Fail;
+        /* No increment here because we read again. */
+
+        if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+             FT_STREAM_READ( glyph_buf + glyph_size, 8 )      )
+          goto Fail;
+
+        substreams[BBOX_STREAM].offset += 8;
+        glyph_size                     += 8;
+
+        if ( FT_STREAM_SEEK( substreams[COMPOSITE_STREAM].offset )    ||
+             FT_STREAM_READ( glyph_buf + glyph_size, composite_size ) )
+          goto Fail;
+
+        substreams[COMPOSITE_STREAM].offset += composite_size;
+        glyph_size                          += composite_size;
+
+        if ( have_instructions )
+        {
+          pointer = glyph_buf + glyph_size;
+          WRITE_USHORT( pointer, instruction_size );
+          glyph_size += 2;
+
+          if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset )    ||
+               FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
+            goto Fail;
+
+          substreams[INSTRUCTION_STREAM].offset += instruction_size;
+          glyph_size                            += instruction_size;
+        }
+      }
+      else if ( n_contours > 0 )
+      {
+        /* simple glyph */
+        FT_ULong   total_n_points = 0;
+        FT_UShort  n_points_contour;
+        FT_UInt    j;
+        FT_ULong   flag_size;
+        FT_ULong   triplet_size;
+        FT_ULong   triplet_bytes_used;
+        FT_Bool    have_overlap  = FALSE;
+        FT_Byte    overlap_bitmap;
+        FT_ULong   overlap_offset;
+        FT_Byte*   flags_buf     = NULL;
+        FT_Byte*   triplet_buf   = NULL;
+        FT_UShort  instruction_size;
+        FT_ULong   size_needed;
+        FT_Int     end_point;
+        FT_UInt    contour_ix;
+
+        FT_Byte*   pointer = NULL;
+
+
+        /* Set `have_overlap`. */
+        if ( overlap_bitmap_offset )
+        {
+          overlap_offset = overlap_bitmap_offset + ( i >> 3 );
+          if ( FT_STREAM_SEEK( overlap_offset ) ||
+               FT_READ_BYTE( overlap_bitmap )   )
+            goto Fail;
+          if ( overlap_bitmap & ( 0x80 >> ( i & 7 ) ) )
+            have_overlap = TRUE;
+        }
+
+        if ( FT_QNEW_ARRAY( n_points_arr, n_contours ) )
+          goto Fail;
+
+        if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
+          goto Fail;
+
+        for ( j = 0; j < n_contours; ++j )
+        {
+          if ( READ_255USHORT( n_points_contour ) )
+            goto Fail;
+          n_points_arr[j] = n_points_contour;
+          /* Prevent negative/overflow. */
+          if ( total_n_points + n_points_contour < total_n_points )
+            goto Fail;
+          total_n_points += n_points_contour;
+        }
+        substreams[N_POINTS_STREAM].offset = FT_STREAM_POS();
+
+        flag_size = total_n_points;
+        if ( flag_size > substreams[FLAG_STREAM].size )
+          goto Fail;
+
+        flags_buf   = stream->base + substreams[FLAG_STREAM].offset;
+        triplet_buf = stream->base + substreams[GLYPH_STREAM].offset;
+
+        if ( substreams[GLYPH_STREAM].size <
+               ( substreams[GLYPH_STREAM].offset -
+                 substreams[GLYPH_STREAM].start ) )
+          goto Fail;
+
+        triplet_size       = substreams[GLYPH_STREAM].size -
+                               ( substreams[GLYPH_STREAM].offset -
+                                 substreams[GLYPH_STREAM].start );
+        triplet_bytes_used = 0;
+
+        /* Create array to store point information. */
+        points_size = total_n_points;
+        if ( FT_QNEW_ARRAY( points, points_size ) )
+          goto Fail;
+
+        if ( triplet_decode( flags_buf,
+                             triplet_buf,
+                             triplet_size,
+                             total_n_points,
+                             points,
+                             &triplet_bytes_used ) )
+          goto Fail;
+
+        substreams[FLAG_STREAM].offset  += flag_size;
+        substreams[GLYPH_STREAM].offset += triplet_bytes_used;
+
+        if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
+             READ_255USHORT( instruction_size )                )
+          goto Fail;
+
+        substreams[GLYPH_STREAM].offset = FT_STREAM_POS();
+
+        if ( total_n_points >= ( 1 << 27 ) )
+          goto Fail;
+
+        size_needed = 12 +
+                      ( 2 * n_contours ) +
+                      ( 5 * total_n_points ) +
+                      instruction_size;
+        if ( glyph_buf_size < size_needed )
+        {
+          if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
+            goto Fail;
+          glyph_buf_size = size_needed;
+        }
+
+        pointer = glyph_buf + glyph_size;
+        WRITE_USHORT( pointer, n_contours );
+        glyph_size += 2;
+
+        if ( have_bbox )
+        {
+          /* Read x_min for current glyph. */
+          if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+               FT_READ_USHORT( x_min )                          )
+            goto Fail;
+          /* No increment here because we read again. */
+
+          if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+               FT_STREAM_READ( glyph_buf + glyph_size, 8 )      )
+            goto Fail;
+          substreams[BBOX_STREAM].offset += 8;
+        }
+        else
+          compute_bbox( total_n_points, points, glyph_buf, &x_min );
+
+        glyph_size = CONTOUR_OFFSET_END_POINT;
+
+        pointer   = glyph_buf + glyph_size;
+        end_point = -1;
+
+        for ( contour_ix = 0; contour_ix < n_contours; ++contour_ix )
+        {
+          end_point += n_points_arr[contour_ix];
+          if ( end_point >= 65536 )
+            goto Fail;
+
+          WRITE_SHORT( pointer, end_point );
+          glyph_size += 2;
+        }
+
+        WRITE_USHORT( pointer, instruction_size );
+        glyph_size += 2;
+
+        if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset )    ||
+             FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
+          goto Fail;
+
+        substreams[INSTRUCTION_STREAM].offset += instruction_size;
+        glyph_size                            += instruction_size;
+
+        if ( store_points( total_n_points,
+                           points,
+                           n_contours,
+                           instruction_size,
+                           have_overlap,
+                           glyph_buf,
+                           glyph_buf_size,
+                           &glyph_size ) )
+          goto Fail;
+
+        FT_FREE( points );
+        FT_FREE( n_points_arr );
+      }
+      else
+      {
+        /* Empty glyph.          */
+        /* Must not have a bbox. */
+        if ( have_bbox )
+        {
+          FT_ERROR(( "Empty glyph has a bbox.\n" ));
+          goto Fail;
+        }
+      }
+
+      loca_values[i] = dest_offset - glyf_start;
+
+      if ( WRITE_SFNT_BUF( glyph_buf, glyph_size ) )
+        goto Fail;
+
+      if ( pad4( &sfnt, sfnt_size, &dest_offset, memory ) )
+        goto Fail;
+
+      *glyf_checksum += compute_ULong_sum( glyph_buf, glyph_size );
+
+      /* Store x_mins, may be required to reconstruct `hmtx'. */
+      info->x_mins[i] = (FT_Short)x_min;
+    }
+
+    info->glyf_table->dst_length = dest_offset - info->glyf_table->dst_offset;
+    info->loca_table->dst_offset = dest_offset;
+
+    /* `loca[n]' will be equal to the length of the `glyf' table. */
+    loca_values[num_glyphs] = info->glyf_table->dst_length;
+
+    if ( store_loca( loca_values,
+                     num_glyphs + 1,
+                     index_format,
+                     loca_checksum,
+                     &sfnt,
+                     sfnt_size,
+                     &dest_offset,
+                     memory ) )
+      goto Fail;
+
+    info->loca_table->dst_length = dest_offset - info->loca_table->dst_offset;
+
+    FT_TRACE4(( "  loca table info:\n" ));
+    FT_TRACE4(( "    dst_offset = %lu\n", info->loca_table->dst_offset ));
+    FT_TRACE4(( "    dst_length = %lu\n", info->loca_table->dst_length ));
+    FT_TRACE4(( "    checksum = %09lx\n", *loca_checksum ));
+
+    /* Set pointer `sfnt_bytes' to its correct value. */
+    *sfnt_bytes = sfnt;
+    *out_offset = dest_offset;
+
+    FT_FREE( substreams );
+    FT_FREE( loca_values );
+    FT_FREE( n_points_arr );
+    FT_FREE( glyph_buf );
+    FT_FREE( points );
+
+    return error;
+
+  Fail:
+    if ( !error )
+      error = FT_THROW( Invalid_Table );
+
+    /* Set pointer `sfnt_bytes' to its correct value. */
+    *sfnt_bytes = sfnt;
+
+    FT_FREE( substreams );
+    FT_FREE( loca_values );
+    FT_FREE( n_points_arr );
+    FT_FREE( glyph_buf );
+    FT_FREE( points );
+
+    return error;
+  }
+
+
+  /* Get `x_mins' for untransformed `glyf' table. */
+  static FT_Error
+  get_x_mins( FT_Stream     stream,
+              WOFF2_Table*  tables,
+              FT_UShort     num_tables,
+              WOFF2_Info    info,
+              FT_Memory     memory )
+  {
+    FT_UShort  num_glyphs;
+    FT_UShort  index_format;
+    FT_ULong   glyf_offset;
+    FT_UShort  glyf_offset_short;
+    FT_ULong   loca_offset;
+    FT_Int     i;
+    FT_Error   error = FT_Err_Ok;
+    FT_ULong   offset_size;
+
+    /* At this point of time those tables might not have been read yet. */
+    const WOFF2_Table  maxp_table = find_table( tables, num_tables,
+                                                TTAG_maxp );
+    const WOFF2_Table  head_table = find_table( tables, num_tables,
+                                                TTAG_head );
+
+
+    if ( !maxp_table )
+    {
+      FT_ERROR(( "`maxp' table is missing.\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    if ( !head_table )
+    {
+      FT_ERROR(( "`head' table is missing.\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    if ( !info->loca_table )
+    {
+      FT_ERROR(( "`loca' table is missing.\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    /* Read `numGlyphs' field from `maxp' table. */
+    if ( FT_STREAM_SEEK( maxp_table->src_offset ) || FT_STREAM_SKIP( 8 ) )
+      return error;
+
+    if ( FT_READ_USHORT( num_glyphs ) )
+      return error;
+
+    info->num_glyphs = num_glyphs;
+
+    /* Read `indexToLocFormat' field from `head' table. */
+    if ( FT_STREAM_SEEK( head_table->src_offset ) ||
+         FT_STREAM_SKIP( 50 )                     )
+      return error;
+
+    if ( FT_READ_USHORT( index_format ) )
+      return error;
+
+    offset_size = index_format ? 4 : 2;
+
+    /* Create `x_mins' array. */
+    if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
+      return error;
+
+    loca_offset = info->loca_table->src_offset;
+
+    for ( i = 0; i < num_glyphs; ++i )
+    {
+      if ( FT_STREAM_SEEK( loca_offset ) )
+        return error;
+
+      loca_offset += offset_size;
+
+      if ( index_format )
+      {
+        if ( FT_READ_ULONG( glyf_offset ) )
+          return error;
+      }
+      else
+      {
+        if ( FT_READ_USHORT( glyf_offset_short ) )
+          return error;
+
+        glyf_offset = (FT_ULong)( glyf_offset_short );
+        glyf_offset = glyf_offset << 1;
+      }
+
+      glyf_offset += info->glyf_table->src_offset;
+
+      if ( FT_STREAM_SEEK( glyf_offset ) || FT_STREAM_SKIP( 2 ) )
+        return error;
+
+      if ( FT_READ_SHORT( info->x_mins[i] ) )
+        return error;
+    }
+
+    return error;
+  }
+
+
+  static FT_Error
+  reconstruct_hmtx( FT_Stream  stream,
+                    FT_UShort  num_glyphs,
+                    FT_UShort  num_hmetrics,
+                    FT_Short*  x_mins,
+                    FT_ULong*  checksum,
+                    FT_Byte**  sfnt_bytes,
+                    FT_ULong*  sfnt_size,
+                    FT_ULong*  out_offset,
+                    FT_Memory  memory )
+  {
+    FT_Error  error       = FT_Err_Ok;
+    FT_Byte*  sfnt        = *sfnt_bytes;
+    FT_ULong  dest_offset = *out_offset;
+
+    FT_Byte   hmtx_flags;
+    FT_Bool   has_proportional_lsbs, has_monospace_lsbs;
+    FT_ULong  hmtx_table_size;
+    FT_Int    i;
+
+    FT_UShort*  advance_widths = NULL;
+    FT_Short*   lsbs           = NULL;
+    FT_Byte*    hmtx_table     = NULL;
+    FT_Byte*    dst            = NULL;
+
+
+    if ( FT_READ_BYTE( hmtx_flags ) )
+      goto Fail;
+
+    has_proportional_lsbs = ( hmtx_flags & 1 ) == 0;
+    has_monospace_lsbs    = ( hmtx_flags & 2 ) == 0;
+
+    /* Bits 2-7 are reserved and MUST be zero. */
+    if ( ( hmtx_flags & 0xFC ) != 0 )
+      goto Fail;
+
+    /* Are you REALLY transformed? */
+    if ( has_proportional_lsbs && has_monospace_lsbs )
+      goto Fail;
+
+    /* Cannot have a transformed `hmtx' without `glyf'. */
+    if ( ( num_hmetrics > num_glyphs ) ||
+         ( num_hmetrics < 1 )          )
+      goto Fail;
+
+    /* Must have at least one entry. */
+    if ( num_hmetrics < 1 )
+      goto Fail;
+
+    if ( FT_QNEW_ARRAY( advance_widths, num_hmetrics ) ||
+         FT_QNEW_ARRAY( lsbs, num_glyphs )             )
+      goto Fail;
+
+    /* Read `advanceWidth' stream.  Always present. */
+    for ( i = 0; i < num_hmetrics; i++ )
+    {
+      FT_UShort  advance_width;
+
+
+      if ( FT_READ_USHORT( advance_width ) )
+        goto Fail;
+
+      advance_widths[i] = advance_width;
+    }
+
+    /* lsb values for proportional glyphs. */
+    for ( i = 0; i < num_hmetrics; i++ )
+    {
+      FT_Short  lsb;
+
+
+      if ( has_proportional_lsbs )
+      {
+        if ( FT_READ_SHORT( lsb ) )
+          goto Fail;
+      }
+      else
+        lsb = x_mins[i];
+
+      lsbs[i] = lsb;
+    }
+
+    /* lsb values for monospaced glyphs. */
+    for ( i = num_hmetrics; i < num_glyphs; i++ )
+    {
+      FT_Short  lsb;
+
+
+      if ( has_monospace_lsbs )
+      {
+        if ( FT_READ_SHORT( lsb ) )
+          goto Fail;
+      }
+      else
+        lsb = x_mins[i];
+
+      lsbs[i] = lsb;
+    }
+
+    /* Build the hmtx table. */
+    hmtx_table_size = 2 * num_hmetrics + 2 * num_glyphs;
+    if ( FT_QALLOC( hmtx_table, hmtx_table_size ) )
+      goto Fail;
+
+    dst = hmtx_table;
+    FT_TRACE6(( "hmtx values: \n" ));
+    for ( i = 0; i < num_glyphs; i++ )
+    {
+      if ( i < num_hmetrics )
+      {
+        WRITE_SHORT( dst, advance_widths[i] );
+        FT_TRACE6(( "%d ", advance_widths[i] ));
+      }
+
+      WRITE_SHORT( dst, lsbs[i] );
+      FT_TRACE6(( "%d ", lsbs[i] ));
+    }
+    FT_TRACE6(( "\n" ));
+
+    *checksum = compute_ULong_sum( hmtx_table, hmtx_table_size );
+    /* Write `hmtx' table to sfnt buffer. */
+    if ( WRITE_SFNT_BUF( hmtx_table, hmtx_table_size ) )
+      goto Fail;
+
+    /* Set pointer `sfnt_bytes' to its correct value. */
+    *sfnt_bytes = sfnt;
+    *out_offset = dest_offset;
+
+    FT_FREE( advance_widths );
+    FT_FREE( lsbs );
+    FT_FREE( hmtx_table );
+
+    return error;
+
+  Fail:
+    FT_FREE( advance_widths );
+    FT_FREE( lsbs );
+    FT_FREE( hmtx_table );
+
+    if ( !error )
+      error = FT_THROW( Invalid_Table );
+
+    return error;
+  }
+
+
+  static FT_Error
+  reconstruct_font( FT_Byte*      transformed_buf,
+                    FT_ULong      transformed_buf_size,
+                    WOFF2_Table*  indices,
+                    WOFF2_Header  woff2,
+                    WOFF2_Info    info,
+                    FT_Byte**     sfnt_bytes,
+                    FT_ULong*     sfnt_size,
+                    FT_Memory     memory )
+  {
+    /* Memory management of `transformed_buf' is handled by the caller. */
+
+    FT_Error   error      = FT_Err_Ok;
+    FT_Stream  stream     = NULL;
+    FT_Byte*   buf_cursor = NULL;
+    FT_Byte    table_entry[16];
+
+    /* We are reallocating memory for `sfnt', so its pointer may change. */
+    FT_Byte*   sfnt = *sfnt_bytes;
+
+    FT_UShort  num_tables  = woff2->num_tables;
+    FT_ULong   dest_offset = 12 + num_tables * 16UL;
+
+    FT_ULong   checksum      = 0;
+    FT_ULong   loca_checksum = 0;
+    FT_Int     nn            = 0;
+    FT_UShort  num_hmetrics  = 0;
+    FT_ULong   font_checksum = info->header_checksum;
+    FT_Bool    is_glyf_xform = FALSE;
+
+    FT_ULong  table_entry_offset = 12;
+
+
+    /* A few table checks before reconstruction. */
+    /* `glyf' must be present with `loca'.       */
+    info->glyf_table = find_table( indices, num_tables, TTAG_glyf );
+    info->loca_table = find_table( indices, num_tables, TTAG_loca );
+
+    if ( ( info->glyf_table == NULL ) ^ ( info->loca_table == NULL ) )
+    {
+      FT_ERROR(( "One of `glyf'/`loca' tables missing.\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    /* Both `glyf' and `loca' must have same transformation. */
+    if ( info->glyf_table != NULL )
+    {
+      if ( ( info->glyf_table->flags & WOFF2_FLAGS_TRANSFORM ) !=
+           ( info->loca_table->flags & WOFF2_FLAGS_TRANSFORM ) )
+      {
+        FT_ERROR(( "Transformation mismatch"
+                   " between `glyf' and `loca' table." ));
+        return FT_THROW( Invalid_Table );
+      }
+    }
+
+    /* Create a stream for the uncompressed buffer. */
+    if ( FT_NEW( stream ) )
+      goto Fail;
+    FT_Stream_OpenMemory( stream, transformed_buf, transformed_buf_size );
+
+    FT_ASSERT( FT_STREAM_POS() == 0 );
+
+    /* Reconstruct/copy tables to output stream. */
+    for ( nn = 0; nn < num_tables; nn++ )
+    {
+      WOFF2_TableRec  table = *( indices[nn] );
+
+
+      FT_TRACE3(( "Seeking to %ld with table size %ld.\n",
+                  table.src_offset, table.src_length ));
+      FT_TRACE3(( "Table tag: %c%c%c%c.\n",
+                  (FT_Char)( table.Tag >> 24 ),
+                  (FT_Char)( table.Tag >> 16 ),
+                  (FT_Char)( table.Tag >> 8  ),
+                  (FT_Char)( table.Tag       ) ));
+
+      if ( FT_STREAM_SEEK( table.src_offset ) )
+        goto Fail;
+
+      if ( table.src_offset + table.src_length > transformed_buf_size )
+        goto Fail;
+
+      /* Get stream size for fields of `hmtx' table. */
+      if ( table.Tag == TTAG_hhea )
+      {
+        if ( read_num_hmetrics( stream, &num_hmetrics ) )
+          goto Fail;
+      }
+
+      info->num_hmetrics = num_hmetrics;
+
+      checksum = 0;
+      if ( ( table.flags & WOFF2_FLAGS_TRANSFORM ) != WOFF2_FLAGS_TRANSFORM )
+      {
+        /* Check whether `head' is at least 12 bytes. */
+        if ( table.Tag == TTAG_head )
+        {
+          if ( table.src_length < 12 )
+            goto Fail;
+
+          buf_cursor = transformed_buf + table.src_offset + 8;
+          /* Set checkSumAdjustment = 0 */
+          WRITE_ULONG( buf_cursor, 0 );
+        }
+
+        table.dst_offset = dest_offset;
+
+        checksum = compute_ULong_sum( transformed_buf + table.src_offset,
+                                      table.src_length );
+        FT_TRACE4(( "Checksum = %09lx.\n", checksum ));
+
+        if ( WRITE_SFNT_BUF( transformed_buf + table.src_offset,
+                             table.src_length ) )
+          goto Fail;
+      }
+      else
+      {
+        FT_TRACE3(( "This table is transformed.\n" ));
+
+        if ( table.Tag == TTAG_glyf )
+        {
+          is_glyf_xform    = TRUE;
+          table.dst_offset = dest_offset;
+
+          if ( reconstruct_glyf( stream,
+                                 &checksum,
+                                 &loca_checksum,
+                                 &sfnt,
+                                 sfnt_size,
+                                 &dest_offset,
+                                 info,
+                                 memory ) )
+            goto Fail;
+
+          FT_TRACE4(( "Checksum = %09lx.\n", checksum ));
+        }
+
+        else if ( table.Tag == TTAG_loca )
+          checksum = loca_checksum;
+
+        else if ( table.Tag == TTAG_hmtx )
+        {
+          /* If glyf is not transformed and hmtx is, handle separately. */
+          if ( !is_glyf_xform )
+          {
+            if ( get_x_mins( stream, indices, num_tables, info, memory ) )
+              goto Fail;
+          }
+
+          table.dst_offset = dest_offset;
+
+          if ( reconstruct_hmtx( stream,
+                                 info->num_glyphs,
+                                 info->num_hmetrics,
+                                 info->x_mins,
+                                 &checksum,
+                                 &sfnt,
+                                 sfnt_size,
+                                 &dest_offset,
+                                 memory ) )
+            goto Fail;
+        }
+        else
+        {
+          /* Unknown transform. */
+          FT_ERROR(( "Unknown table transform.\n" ));
+          goto Fail;
+        }
+      }
+
+      font_checksum += checksum;
+
+      buf_cursor = &table_entry[0];
+      WRITE_ULONG( buf_cursor, table.Tag );
+      WRITE_ULONG( buf_cursor, checksum );
+      WRITE_ULONG( buf_cursor, table.dst_offset );
+      WRITE_ULONG( buf_cursor, table.dst_length );
+
+      WRITE_SFNT_BUF_AT( table_entry_offset, table_entry, 16 );
+
+      /* Update checksum. */
+      font_checksum += compute_ULong_sum( table_entry, 16 );
+
+      if ( pad4( &sfnt, sfnt_size, &dest_offset, memory ) )
+        goto Fail;
+
+      /* Sanity check. */
+      if ( (FT_ULong)( table.dst_offset + table.dst_length ) > dest_offset )
+      {
+        FT_ERROR(( "Table was partially written.\n" ));
+        goto Fail;
+      }
+    }
+
+    /* Update `head' checkSumAdjustment. */
+    info->head_table = find_table( indices, num_tables, TTAG_head );
+    if ( !info->head_table )
+    {
+      FT_ERROR(( "`head' table is missing.\n" ));
+      goto Fail;
+    }
+
+    if ( info->head_table->dst_length < 12 )
+      goto Fail;
+
+    buf_cursor    = sfnt + info->head_table->dst_offset + 8;
+    font_checksum = 0xB1B0AFBA - font_checksum;
+
+    WRITE_ULONG( buf_cursor, font_checksum );
+
+    FT_TRACE2(( "Final checksum = %09lx.\n", font_checksum ));
+
+    woff2->actual_sfnt_size = dest_offset;
+
+    /* Set pointer of sfnt stream to its correct value. */
+    *sfnt_bytes = sfnt;
+
+    FT_Stream_Close( stream );
+    FT_FREE( stream );
+
+    return error;
+
+  Fail:
+    if ( !error )
+      error = FT_THROW( Invalid_Table );
+
+    /* Set pointer of sfnt stream to its correct value. */
+    *sfnt_bytes = sfnt;
+
+    FT_Stream_Close( stream );
+    FT_FREE( stream );
+
+    return error;
+  }
+
+
+  /* Replace `face->root.stream' with a stream containing the extracted */
+  /* SFNT of a WOFF2 font.                                              */
+
+  FT_LOCAL_DEF( FT_Error )
+  woff2_open_font( FT_Stream  stream,
+                   TT_Face    face,
+                   FT_Int*    face_instance_index,
+                   FT_Long*   num_faces )
+  {
+    FT_Memory  memory = stream->memory;
+    FT_Error   error  = FT_Err_Ok;
+    FT_Int     face_index;
+
+    WOFF2_HeaderRec  woff2;
+    WOFF2_InfoRec    info         = { 0, 0, 0, NULL, NULL, NULL, NULL };
+    WOFF2_Table      tables       = NULL;
+    WOFF2_Table*     indices      = NULL;
+    WOFF2_Table*     temp_indices = NULL;
+    WOFF2_Table      last_table;
+
+    FT_Int     nn;
+    FT_ULong   j;
+    FT_ULong   flags;
+    FT_UShort  xform_version;
+    FT_ULong   src_offset = 0;
+
+    FT_UInt    glyf_index;
+    FT_UInt    loca_index;
+    FT_UInt32  file_offset;
+
+    FT_Byte*   sfnt        = NULL;
+    FT_Stream  sfnt_stream = NULL;
+    FT_Byte*   sfnt_header;
+    FT_ULong   sfnt_size;
+
+    FT_Byte*  uncompressed_buf = NULL;
+
+    static const FT_Frame_Field  woff2_header_fields[] =
+    {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  WOFF2_HeaderRec
+
+      FT_FRAME_START( 48 ),
+        FT_FRAME_ULONG     ( signature ),
+        FT_FRAME_ULONG     ( flavor ),
+        FT_FRAME_ULONG     ( length ),
+        FT_FRAME_USHORT    ( num_tables ),
+        FT_FRAME_SKIP_BYTES( 2 ),
+        FT_FRAME_ULONG     ( totalSfntSize ),
+        FT_FRAME_ULONG     ( totalCompressedSize ),
+        FT_FRAME_SKIP_BYTES( 2 * 2 ),
+        FT_FRAME_ULONG     ( metaOffset ),
+        FT_FRAME_ULONG     ( metaLength ),
+        FT_FRAME_ULONG     ( metaOrigLength ),
+        FT_FRAME_ULONG     ( privOffset ),
+        FT_FRAME_ULONG     ( privLength ),
+      FT_FRAME_END
+    };
+
+
+    FT_ASSERT( stream == face->root.stream );
+    FT_ASSERT( FT_STREAM_POS() == 0 );
+
+    face_index = FT_ABS( *face_instance_index ) & 0xFFFF;
+
+    /* Read WOFF2 Header. */
+    if ( FT_STREAM_READ_FIELDS( woff2_header_fields, &woff2 ) )
+      return error;
+
+    FT_TRACE4(( "signature     -> 0x%lX\n", woff2.signature ));
+    FT_TRACE2(( "flavor        -> 0x%08lx\n", woff2.flavor ));
+    FT_TRACE4(( "length        -> %lu\n", woff2.length ));
+    FT_TRACE2(( "num_tables    -> %hu\n", woff2.num_tables ));
+    FT_TRACE4(( "totalSfntSize -> %lu\n", woff2.totalSfntSize ));
+    FT_TRACE4(( "metaOffset    -> %lu\n", woff2.metaOffset ));
+    FT_TRACE4(( "metaLength    -> %lu\n", woff2.metaLength ));
+    FT_TRACE4(( "privOffset    -> %lu\n", woff2.privOffset ));
+    FT_TRACE4(( "privLength    -> %lu\n", woff2.privLength ));
+
+    /* Make sure we don't recurse back here. */
+    if ( woff2.flavor == TTAG_wOF2 )
+      return FT_THROW( Invalid_Table );
+
+    /* Miscellaneous checks. */
+    if ( woff2.length != stream->size                               ||
+         woff2.num_tables == 0                                      ||
+         48 + woff2.num_tables * 20UL >= woff2.length               ||
+         ( woff2.metaOffset == 0 && ( woff2.metaLength != 0     ||
+                                      woff2.metaOrigLength != 0 ) ) ||
+         ( woff2.metaLength != 0 && woff2.metaOrigLength == 0 )     ||
+         ( woff2.metaOffset >= woff2.length )                       ||
+         ( woff2.length - woff2.metaOffset < woff2.metaLength )     ||
+         ( woff2.privOffset == 0 && woff2.privLength != 0 )         ||
+         ( woff2.privOffset >= woff2.length )                       ||
+         ( woff2.length - woff2.privOffset < woff2.privLength )     )
+    {
+      FT_ERROR(( "woff2_open_font: invalid WOFF2 header\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    FT_TRACE2(( "woff2_open_font: WOFF2 Header is valid.\n" ));
+
+    woff2.ttc_fonts = NULL;
+
+    /* Read table directory. */
+    if ( FT_QNEW_ARRAY( tables, woff2.num_tables )  ||
+         FT_QNEW_ARRAY( indices, woff2.num_tables ) )
+      goto Exit;
+
+    FT_TRACE2(( "\n" ));
+    FT_TRACE2(( "  tag    flags    transform  origLen   transformLen   offset\n" ));
+    FT_TRACE2(( "  -----------------------------------------------------------\n" ));
+             /* "  XXXX  XXXXXXXX  XXXXXXXX   XXXXXXXX    XXXXXXXX    XXXXXXXX" */
+
+    for ( nn = 0; nn < woff2.num_tables; nn++ )
+    {
+      WOFF2_Table  table = tables + nn;
+
+
+      if ( FT_READ_BYTE( table->FlagByte ) )
+        goto Exit;
+
+      if ( ( table->FlagByte & 0x3f ) == 0x3f )
+      {
+        if ( FT_READ_ULONG( table->Tag ) )
+          goto Exit;
+      }
+      else
+      {
+        table->Tag = woff2_known_tags( table->FlagByte & 0x3f );
+        if ( !table->Tag )
+        {
+          FT_ERROR(( "woff2_open_font: Unknown table tag." ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit;
+        }
+      }
+
+      flags = 0;
+      xform_version = ( table->FlagByte >> 6 ) & 0x03;
+
+      /* 0 means xform for glyph/loca, non-0 for others. */
+      if ( table->Tag == TTAG_glyf || table->Tag == TTAG_loca )
+      {
+        if ( xform_version == 0 )
+          flags |= WOFF2_FLAGS_TRANSFORM;
+      }
+      else if ( xform_version != 0 )
+        flags |= WOFF2_FLAGS_TRANSFORM;
+
+      flags |= xform_version;
+
+      if ( READ_BASE128( table->dst_length ) )
+        goto Exit;
+
+      table->TransformLength = table->dst_length;
+
+      if ( ( flags & WOFF2_FLAGS_TRANSFORM ) != 0 )
+      {
+        if ( READ_BASE128( table->TransformLength ) )
+          goto Exit;
+
+        if ( table->Tag == TTAG_loca && table->TransformLength )
+        {
+          FT_ERROR(( "woff2_open_font: Invalid loca `transformLength'.\n" ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit;
+        }
+      }
+
+      if ( src_offset + table->TransformLength < src_offset )
+      {
+        FT_ERROR(( "woff2_open_font: invalid WOFF2 table directory.\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      table->flags      = flags;
+      table->src_offset = src_offset;
+      table->src_length = table->TransformLength;
+      src_offset       += table->TransformLength;
+      table->dst_offset = 0;
+
+      FT_TRACE2(( "  %c%c%c%c  %08d  %08d   %08ld    %08ld    %08ld\n",
+                  (FT_Char)( table->Tag >> 24 ),
+                  (FT_Char)( table->Tag >> 16 ),
+                  (FT_Char)( table->Tag >> 8  ),
+                  (FT_Char)( table->Tag       ),
+                  table->FlagByte & 0x3f,
+                  ( table->FlagByte >> 6 ) & 0x03,
+                  table->dst_length,
+                  table->TransformLength,
+                  table->src_offset ));
+
+      indices[nn] = table;
+    }
+
+    /* End of last table is uncompressed size. */
+    last_table = indices[woff2.num_tables - 1];
+
+    woff2.uncompressed_size = last_table->src_offset +
+                              last_table->src_length;
+    if ( woff2.uncompressed_size < last_table->src_offset )
+    {
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    FT_TRACE2(( "Table directory parsed.\n" ));
+
+    /* Check for and read collection directory. */
+    woff2.num_fonts      = 1;
+    woff2.header_version = 0;
+
+    if ( woff2.flavor == TTAG_ttcf )
+    {
+      FT_TRACE2(( "Font is a TTC, reading collection directory.\n" ));
+
+      if ( FT_READ_ULONG( woff2.header_version ) )
+        goto Exit;
+
+      if ( woff2.header_version != 0x00010000 &&
+           woff2.header_version != 0x00020000 )
+      {
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      if ( READ_255USHORT( woff2.num_fonts ) )
+        goto Exit;
+
+      if ( !woff2.num_fonts )
+      {
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      FT_TRACE4(( "Number of fonts in TTC: %d\n", woff2.num_fonts ));
+
+      /* pre-zero pointers within in case of failure */
+      if ( FT_NEW_ARRAY( woff2.ttc_fonts, woff2.num_fonts ) )
+        goto Exit;
+
+      for ( nn = 0; nn < woff2.num_fonts; nn++ )
+      {
+        WOFF2_TtcFont  ttc_font = woff2.ttc_fonts + nn;
+
+
+        if ( READ_255USHORT( ttc_font->num_tables ) )
+          goto Exit;
+        if ( FT_READ_ULONG( ttc_font->flavor ) )
+          goto Exit;
+
+        if ( FT_QNEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
+          goto Exit;
+
+        FT_TRACE5(( "Number of tables in font %d: %d\n",
+                    nn, ttc_font->num_tables ));
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( ttc_font->num_tables )
+          FT_TRACE6(( "  Indices: " ));
+#endif
+
+        glyf_index = 0;
+        loca_index = 0;
+
+        for ( j = 0; j < ttc_font->num_tables; j++ )
+        {
+          FT_UShort    table_index;
+          WOFF2_Table  table;
+
+
+          if ( READ_255USHORT( table_index ) )
+            goto Exit;
+
+          FT_TRACE6(( "%hu ", table_index ));
+          if ( table_index >= woff2.num_tables )
+          {
+            FT_ERROR(( "woff2_open_font: invalid table index\n" ));
+            error = FT_THROW( Invalid_Table );
+            goto Exit;
+          }
+
+          ttc_font->table_indices[j] = table_index;
+
+          table = indices[table_index];
+          if ( table->Tag == TTAG_loca )
+            loca_index = table_index;
+          if ( table->Tag == TTAG_glyf )
+            glyf_index = table_index;
+        }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( ttc_font->num_tables )
+          FT_TRACE6(( "\n" ));
+#endif
+
+        /* glyf and loca must be consecutive */
+        if ( glyf_index > 0 || loca_index > 0 )
+        {
+          if ( glyf_index > loca_index      ||
+               loca_index - glyf_index != 1 )
+          {
+            error = FT_THROW( Invalid_Table );
+            goto Exit;
+          }
+        }
+      }
+
+      /* Collection directory reading complete. */
+      FT_TRACE2(( "WOFF2 collection directory is valid.\n" ));
+    }
+    else
+      woff2.ttc_fonts = NULL;
+
+    woff2.compressed_offset = FT_STREAM_POS();
+    file_offset             = ROUND4( woff2.compressed_offset +
+                                      woff2.totalCompressedSize );
+
+    /* Some more checks before we start reading the tables. */
+    if ( file_offset > woff2.length )
+    {
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    if ( woff2.metaOffset )
+    {
+      if ( file_offset != woff2.metaOffset )
+      {
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+      file_offset = ROUND4( woff2.metaOffset + woff2.metaLength );
+    }
+
+    if ( woff2.privOffset )
+    {
+      if ( file_offset != woff2.privOffset )
+      {
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+      file_offset = ROUND4( woff2.privOffset + woff2.privLength );
+    }
+
+    if ( file_offset != ( ROUND4( woff2.length ) ) )
+    {
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* Validate requested face index. */
+    *num_faces = woff2.num_fonts;
+    /* value -(N+1) requests information on index N */
+    if ( *face_instance_index < 0 && face_index > 0 )
+      face_index--;
+
+    if ( face_index >= woff2.num_fonts )
+    {
+      if ( *face_instance_index >= 0 )
+      {
+        error = FT_THROW( Invalid_Argument );
+        goto Exit;
+      }
+      else
+        face_index = 0;
+    }
+
+    /* Only retain tables of the requested face in a TTC. */
+    if ( woff2.header_version )
+    {
+      WOFF2_TtcFont  ttc_font = woff2.ttc_fonts + face_index;
+
+
+      /* Create a temporary array. */
+      if ( FT_QNEW_ARRAY( temp_indices,
+                          ttc_font->num_tables ) )
+        goto Exit;
+
+      FT_TRACE4(( "Storing tables for TTC face index %d.\n", face_index ));
+      for ( nn = 0; nn < ttc_font->num_tables; nn++ )
+        temp_indices[nn] = indices[ttc_font->table_indices[nn]];
+
+      /* Resize array to required size. */
+      if ( FT_QRENEW_ARRAY( indices,
+                            woff2.num_tables,
+                            ttc_font->num_tables ) )
+        goto Exit;
+
+      for ( nn = 0; nn < ttc_font->num_tables; nn++ )
+        indices[nn] = temp_indices[nn];
+
+      FT_FREE( temp_indices );
+
+      /* Change header values. */
+      woff2.flavor     = ttc_font->flavor;
+      woff2.num_tables = ttc_font->num_tables;
+    }
+
+    /* We need to allocate this much at the minimum. */
+    sfnt_size = 12 + woff2.num_tables * 16UL;
+    /* This is what we normally expect.                              */
+    /* Initially trust `totalSfntSize' and change later as required. */
+    if ( woff2.totalSfntSize > sfnt_size )
+    {
+      /* However, adjust the value to something reasonable. */
+
+      /* Factor 64 is heuristic. */
+      if ( ( woff2.totalSfntSize >> 6 ) > woff2.length )
+        sfnt_size = woff2.length << 6;
+      else
+        sfnt_size = woff2.totalSfntSize;
+
+      /* Value 1<<26 = 67108864 is heuristic. */
+      if (sfnt_size >= (1 << 26))
+        sfnt_size = 1 << 26;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+      if ( sfnt_size != woff2.totalSfntSize )
+        FT_TRACE4(( "adjusting estimate of uncompressed font size"
+                    " to %lu bytes\n",
+                    sfnt_size ));
+#endif
+    }
+
+    /* Write sfnt header. */
+    if ( FT_QALLOC( sfnt, sfnt_size ) ||
+         FT_NEW( sfnt_stream )        )
+      goto Exit;
+
+    sfnt_header = sfnt;
+
+    WRITE_ULONG( sfnt_header, woff2.flavor );
+
+    if ( woff2.num_tables )
+    {
+      FT_UInt  searchRange, entrySelector, rangeShift, x;
+
+
+      x             = woff2.num_tables;
+      entrySelector = 0;
+      while ( x )
+      {
+        x            >>= 1;
+        entrySelector += 1;
+      }
+      entrySelector--;
+
+      searchRange = ( 1 << entrySelector ) * 16;
+      rangeShift  = ( woff2.num_tables * 16 ) - searchRange;
+
+      WRITE_USHORT( sfnt_header, woff2.num_tables );
+      WRITE_USHORT( sfnt_header, searchRange );
+      WRITE_USHORT( sfnt_header, entrySelector );
+      WRITE_USHORT( sfnt_header, rangeShift );
+    }
+
+    info.header_checksum = compute_ULong_sum( sfnt, 12 );
+
+    /* Sort tables by tag. */
+    ft_qsort( indices,
+              woff2.num_tables,
+              sizeof ( WOFF2_Table ),
+              compare_tags );
+
+    /* reject fonts that have multiple tables with the same tag */
+    for ( nn = 1; nn < woff2.num_tables; nn++ )
+    {
+      FT_Tag  tag = indices[nn]->Tag;
+
+
+      if ( tag == indices[nn - 1]->Tag )
+      {
+        FT_ERROR(( "woff2_open_font:"
+                   " multiple tables with tag `%c%c%c%c'.\n",
+                   (FT_Char)( tag >> 24 ),
+                   (FT_Char)( tag >> 16 ),
+                   (FT_Char)( tag >> 8  ),
+                   (FT_Char)( tag       ) ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+    }
+
+    if ( woff2.uncompressed_size < 1 )
+    {
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    if ( woff2.uncompressed_size > sfnt_size )
+    {
+      FT_ERROR(( "woff2_open_font: SFNT table lengths are too large.\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* Allocate memory for uncompressed table data. */
+    if ( FT_QALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
+         FT_FRAME_ENTER( woff2.totalCompressedSize )            )
+      goto Exit;
+
+    /* Uncompress the stream. */
+    error = woff2_decompress( uncompressed_buf,
+                              woff2.uncompressed_size,
+                              stream->cursor,
+                              woff2.totalCompressedSize );
+
+    FT_FRAME_EXIT();
+
+    if ( error )
+      goto Exit;
+
+    error = reconstruct_font( uncompressed_buf,
+                              woff2.uncompressed_size,
+                              indices,
+                              &woff2,
+                              &info,
+                              &sfnt,
+                              &sfnt_size,
+                              memory );
+
+    if ( error )
+      goto Exit;
+
+    /* Resize `sfnt' to actual size of sfnt stream. */
+    if ( woff2.actual_sfnt_size < sfnt_size )
+    {
+      FT_TRACE5(( "Trimming sfnt stream from %lu to %lu.\n",
+                  sfnt_size, woff2.actual_sfnt_size ));
+      if ( FT_QREALLOC( sfnt,
+                        (FT_ULong)( sfnt_size ),
+                        (FT_ULong)( woff2.actual_sfnt_size ) ) )
+        goto Exit;
+    }
+
+    /* `reconstruct_font' has done all the work. */
+    /* Swap out stream and return.               */
+    FT_Stream_OpenMemory( sfnt_stream, sfnt, woff2.actual_sfnt_size );
+    sfnt_stream->memory = stream->memory;
+    sfnt_stream->close  = stream_close;
+
+    FT_Stream_Free(
+      face->root.stream,
+      ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
+
+    face->root.stream      = sfnt_stream;
+    face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
+
+    /* Set face_index to 0 or -1. */
+    if ( *face_instance_index >= 0 )
+      *face_instance_index = 0;
+    else
+      *face_instance_index = -1;
+
+    FT_TRACE2(( "woff2_open_font: SFNT synthesized.\n" ));
+
+  Exit:
+    FT_FREE( tables );
+    FT_FREE( indices );
+    FT_FREE( uncompressed_buf );
+    FT_FREE( info.x_mins );
+
+    if ( woff2.ttc_fonts )
+    {
+      WOFF2_TtcFont  ttc_font = woff2.ttc_fonts;
+
+
+      for ( nn = 0; nn < woff2.num_fonts; nn++ )
+      {
+        FT_FREE( ttc_font->table_indices );
+        ttc_font++;
+      }
+
+      FT_FREE( woff2.ttc_fonts );
+    }
+
+    if ( error )
+    {
+      FT_FREE( sfnt );
+      if ( sfnt_stream )
+      {
+        FT_Stream_Close( sfnt_stream );
+        FT_FREE( sfnt_stream );
+      }
+    }
+
+    return error;
+  }
+
+
+#undef READ_255USHORT
+#undef READ_BASE128
+#undef ROUND4
+#undef WRITE_USHORT
+#undef WRITE_ULONG
+#undef WRITE_SHORT
+#undef WRITE_SFNT_BUF
+#undef WRITE_SFNT_BUF_AT
+
+#undef N_CONTOUR_STREAM
+#undef N_POINTS_STREAM
+#undef FLAG_STREAM
+#undef GLYPH_STREAM
+#undef COMPOSITE_STREAM
+#undef BBOX_STREAM
+#undef INSTRUCTION_STREAM
+
+#else /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+  /* ANSI C doesn't like empty source files */
+  typedef int  _sfwoff2_dummy;
+
+#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+
+/* END */
diff --git a/src/sfnt/sfwoff2.h b/src/sfnt/sfwoff2.h
new file mode 100644
index 0000000..4901286
--- /dev/null
+++ b/src/sfnt/sfwoff2.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ *
+ * sfwoff2.h
+ *
+ *   WOFFF2 format management (specification).
+ *
+ * Copyright (C) 2019-2023 by
+ * Nikhil Ramakrishnan, 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 SFWOFF2_H_
+#define SFWOFF2_H_
+
+
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftobjs.h>
+
+
+FT_BEGIN_HEADER
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+  /* Leave the first byte open to store `flag_byte'. */
+#define WOFF2_FLAGS_TRANSFORM   1 << 8
+
+#define WOFF2_SFNT_HEADER_SIZE  12
+#define WOFF2_SFNT_ENTRY_SIZE   16
+
+  /* Suggested maximum size for output. */
+#define WOFF2_DEFAULT_MAX_SIZE  30 * 1024 * 1024
+
+  /* 98% of Google Fonts have no glyph above 5k bytes. */
+#define WOFF2_DEFAULT_GLYPH_BUF  5120
+
+  /* Composite glyph flags.                                      */
+  /* See `CompositeGlyph.java' in `sfntly' for full definitions. */
+#define FLAG_ARG_1_AND_2_ARE_WORDS     1 << 0
+#define FLAG_WE_HAVE_A_SCALE           1 << 3
+#define FLAG_MORE_COMPONENTS           1 << 5
+#define FLAG_WE_HAVE_AN_X_AND_Y_SCALE  1 << 6
+#define FLAG_WE_HAVE_A_TWO_BY_TWO      1 << 7
+#define FLAG_WE_HAVE_INSTRUCTIONS      1 << 8
+
+  /* Simple glyph flags */
+#define GLYF_ON_CURVE        1 << 0
+#define GLYF_X_SHORT         1 << 1
+#define GLYF_Y_SHORT         1 << 2
+#define GLYF_REPEAT          1 << 3
+#define GLYF_THIS_X_IS_SAME  1 << 4
+#define GLYF_THIS_Y_IS_SAME  1 << 5
+#define GLYF_OVERLAP_SIMPLE  1 << 6
+
+  /* Other constants */
+#define CONTOUR_OFFSET_END_POINT  10
+
+
+  FT_LOCAL( FT_Error )
+  woff2_open_font( FT_Stream  stream,
+                   TT_Face    face,
+                   FT_Int*    face_index,
+                   FT_Long*   num_faces );
+
+#endif /* FT_CONFIG_OPTION_USE_BROTLI */
+
+FT_END_HEADER
+
+#endif /* SFWOFF2_H_ */
+
+
+/* END */
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index a85a687..118f475 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType embedded BDF properties (body).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,10 +16,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 #include "ttbdf.h"
 
 #include "sferrors.h"
@@ -34,7 +33,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttbdf
+#define FT_COMPONENT  ttbdf
 
 
   FT_LOCAL_DEF( void )
diff --git a/src/sfnt/ttbdf.h b/src/sfnt/ttbdf.h
index 5cee599..595aeb7 100644
--- a/src/sfnt/ttbdf.h
+++ b/src/sfnt/ttbdf.h
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType embedded BDF properties (specification).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define TTBDF_H_
 
 
-#include <ft2build.h>
 #include "ttload.h"
-#include FT_BDF_H
+#include <freetype/ftbdf.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index a3a8c52..820cd08 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
  *
  *   TrueType character mapping table (cmap) support (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,14 +16,13 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include "sferrors.h"           /* must come before FT_INTERNAL_VALIDATE_H */
+#include "sferrors.h"                      /* must come before `ftvalid.h' */
 
-#include FT_INTERNAL_VALIDATE_H
-#include FT_INTERNAL_STREAM_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+#include <freetype/internal/ftvalid.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/services/svpscmap.h>
 #include "ttload.h"
 #include "ttcmap.h"
 #include "ttpost.h"
@@ -36,7 +35,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttcmap
+#define FT_COMPONENT  ttcmap
 
 
 #define TT_PEEK_SHORT   FT_PEEK_SHORT
@@ -466,7 +465,7 @@
     if ( subheader )
     {
       FT_Byte*  p   = subheader;
-      FT_UInt   idx = (FT_UInt)(char_code & 0xFF);
+      FT_UInt   idx = (FT_UInt)( char_code & 0xFF );
       FT_UInt   start, count;
       FT_Int    delta;
       FT_UInt   offset;
@@ -917,6 +916,16 @@
       length = (FT_UInt)( valid->limit - table );
     }
 
+    /* it also happens that the `length' field is too small; */
+    /* this is easy to correct                               */
+    if ( length < (FT_UInt)( valid->limit - table ) )
+    {
+      if ( valid->level >= FT_VALIDATE_PARANOID )
+        FT_INVALID_DATA;
+
+      length = (FT_UInt)( valid->limit - table );
+    }
+
     if ( length < 16 )
       FT_INVALID_TOO_SHORT;
 
@@ -2368,10 +2377,7 @@
         /* if `gindex' is invalid, the remaining values */
         /* in this group are invalid, too               */
         if ( gindex >= (FT_UInt)face->num_glyphs )
-        {
-          gindex = 0;
           continue;
-        }
 
         cmap->cur_charcode = char_code;
         cmap->cur_gindex   = gindex;
@@ -3661,7 +3667,7 @@
   tt_get_glyph_name( TT_Face  face,
                      FT_UInt  idx )
   {
-    FT_String*  PSname;
+    FT_String*  PSname = NULL;
 
 
     tt_face_get_ps_name( face, idx, &PSname );
@@ -3681,6 +3687,9 @@
     FT_UNUSED( pointer );
 
 
+    if ( !psnames->unicodes_init )
+      return FT_THROW( Unimplemented_Feature );
+
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    face->root.num_glyphs,
@@ -3752,6 +3761,7 @@
 
   static const TT_CMap_Class  tt_cmap_classes[] =
   {
+#undef  TTCMAPCITEM
 #define TTCMAPCITEM( a )  &a,
 #include "ttcmapc.h"
     NULL,
@@ -3764,29 +3774,33 @@
   FT_LOCAL_DEF( FT_Error )
   tt_face_build_cmaps( TT_Face  face )
   {
-    FT_Byte*           table = face->cmap_table;
-    FT_Byte*           limit = table + face->cmap_size;
+    FT_Byte* const     table   = face->cmap_table;
+    FT_Byte*           limit;
     FT_UInt volatile   num_cmaps;
-    FT_Byte* volatile  p     = table;
+    FT_Byte* volatile  p       = table;
     FT_Library         library = FT_FACE_LIBRARY( face );
 
     FT_UNUSED( library );
 
 
-    if ( !p || p + 4 > limit )
+    if ( !p || face->cmap_size < 4 )
       return FT_THROW( Invalid_Table );
 
-    /* only recognize format 0 */
-    if ( TT_NEXT_USHORT( p ) != 0 )
-    {
-      FT_ERROR(( "tt_face_build_cmaps:"
-                 " unsupported `cmap' table format = %d\n",
-                 TT_PEEK_USHORT( p - 2 ) ));
-      return FT_THROW( Invalid_Table );
-    }
+    /* Version 1.8.3 of the OpenType specification contains the following */
+    /* (https://docs.microsoft.com/en-us/typography/opentype/spec/cmap):  */
+    /*                                                                    */
+    /*   The 'cmap' table version number remains at 0x0000 for fonts that */
+    /*   make use of the newer subtable formats.                          */
+    /*                                                                    */
+    /* This essentially means that a version format test is useless.      */
+
+    /* ignore format */
+    p += 2;
 
     num_cmaps = TT_NEXT_USHORT( p );
+    FT_TRACE4(( "tt_face_build_cmaps: %d cmaps\n", num_cmaps ));
 
+    limit = table + face->cmap_size;
     for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
     {
       FT_CharMapRec  charmap;
@@ -3865,13 +3879,14 @@
   }
 
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL_DEF( FT_Error )
   tt_get_cmap_info( FT_CharMap    charmap,
                     TT_CMapInfo  *cmap_info )
   {
     FT_CMap        cmap  = (FT_CMap)charmap;
     TT_CMap_Class  clazz = (TT_CMap_Class)cmap->clazz;
 
+
     if ( clazz->get_cmap_info )
       return clazz->get_cmap_info( charmap, cmap_info );
     else
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index 14a700d..ff52917 100644
--- a/src/sfnt/ttcmap.h
+++ b/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
  *
  *   TrueType character mapping table (cmap) support (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,10 +20,9 @@
 #define TTCMAP_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_TRUETYPE_TYPES_H
-#include FT_INTERNAL_VALIDATE_H
-#include FT_SERVICE_TT_CMAP_H
+#include <freetype/internal/tttypes.h>
+#include <freetype/internal/ftvalid.h>
+#include <freetype/internal/services/svttcmap.h>
 
 FT_BEGIN_HEADER
 
@@ -91,6 +90,11 @@
   };
 
 
+#undef  TTCMAPCITEM
+#define TTCMAPCITEM( a )  FT_CALLBACK_TABLE  const TT_CMap_ClassRec  a;
+#include "ttcmapc.h"
+
+
   typedef struct  TT_ValidatorRec_
   {
     FT_ValidatorRec  validator;
diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h
index 11d3e98..0af48c2 100644
--- a/src/sfnt/ttcmapc.h
+++ b/src/sfnt/ttcmapc.h
@@ -4,7 +4,7 @@
  *
  *   TT CMAP classes definitions (specification only).
  *
- * Copyright 2009-2018 by
+ * Copyright (C) 2009-2023 by
  * Oran Agra and Mickey Gabel.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index a8ff026..5d98dca 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -4,8 +4,8 @@
  *
  *   TrueType and OpenType colored glyph layer support (body).
  *
- * Copyright 2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
+ * Copyright (C) 2018-2023 by
+ * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg.
  *
  * Originally written by Shao Yu Zhang <shaozhang@fb.com>.
  *
@@ -27,12 +27,16 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_COLOR_H
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
+#include <freetype/ftcolor.h>
+#include <freetype/config/integer-types.h>
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include <freetype/internal/services/svmm.h>
+#endif
 
 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS
 
@@ -40,12 +44,52 @@
 
 
   /* NOTE: These are the table sizes calculated through the specs. */
-#define BASE_GLYPH_SIZE            6
-#define LAYER_SIZE                 4
-#define COLR_HEADER_SIZE          14
+#define BASE_GLYPH_SIZE                   6U
+#define BASE_GLYPH_PAINT_RECORD_SIZE      6U
+#define LAYER_V1_LIST_PAINT_OFFSET_SIZE   4U
+#define LAYER_V1_LIST_NUM_LAYERS_SIZE     4U
+#define COLOR_STOP_SIZE                   6U
+#define VAR_IDX_BASE_SIZE                 4U
+#define LAYER_SIZE                        4U
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#colr-header */
+/* 3 * uint16 + 2 * Offset32 */
+#define COLRV0_HEADER_SIZE               14U
+/* COLRV0_HEADER_SIZE + 5 * Offset32 */
+#define COLRV1_HEADER_SIZE               34U
 
 
-  typedef struct BaseGlyphRecord_
+#define ENSURE_READ_BYTES( byte_size )                             \
+  if ( p < colr->paints_start_v1                                || \
+       p > (FT_Byte*)colr->table + colr->table_size - byte_size )  \
+    return 0
+
+
+  typedef enum  FT_PaintFormat_Internal_
+  {
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID                = 3,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT      = 5,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT      = 7,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT       = 9,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM            = 13,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE            = 15,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE                = 17,
+    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER             = 18,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER         = 19,
+    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM            = 20,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM        = 21,
+    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER     = 22,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER = 23,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE               = 25,
+    FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER            = 26,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER        = 27,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW                 = 29,
+    FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER              = 30,
+    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER          = 31,
+
+  } FT_PaintFormat_Internal;
+
+
+  typedef struct  BaseGlyphRecord_
   {
     FT_UShort  gid;
     FT_UShort  first_layer_index;
@@ -54,7 +98,16 @@
   } BaseGlyphRecord;
 
 
-  typedef struct Colr_
+  typedef struct  BaseGlyphV1Record_
+  {
+    FT_UShort  gid;
+    /* Offset from start of BaseGlyphV1List, i.e., from base_glyphs_v1. */
+    FT_ULong   paint_offset;
+
+  } BaseGlyphV1Record;
+
+
+  typedef struct  Colr_
   {
     FT_UShort  version;
     FT_UShort  num_base_glyphs;
@@ -63,7 +116,29 @@
     FT_Byte*  base_glyphs;
     FT_Byte*  layers;
 
-    /* The memory which backs up the `COLR' table. */
+    FT_ULong  num_base_glyphs_v1;
+    /* Points at beginning of BaseGlyphV1List. */
+    FT_Byte*  base_glyphs_v1;
+
+    FT_ULong  num_layers_v1;
+    FT_Byte*  layers_v1;
+
+    FT_Byte*  clip_list;
+
+    /*
+     * Paint tables start at the minimum of the end of the LayerList and the
+     * end of the BaseGlyphList.  Record this location in a field here for
+     * safety checks when accessing paint tables.
+     */
+    FT_Byte*  paints_start_v1;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    /* Item Variation Store for variable 'COLR' v1. */
+    GX_ItemVarStoreRec    var_store;
+    GX_DeltaSetIdxMapRec  delta_set_idx_map;
+#endif
+
+    /* The memory that backs up the `COLR' table. */
     void*     table;
     FT_ULong  table_size;
 
@@ -77,7 +152,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttcolr
+#define FT_COMPONENT  ttcolr
 
 
   FT_LOCAL_DEF( FT_Error )
@@ -89,11 +164,18 @@
 
     FT_Byte*  table = NULL;
     FT_Byte*  p     = NULL;
+    /* Needed for reading array lengths in referenced tables. */
+    FT_Byte*  p1    = NULL;
 
     Colr*  colr = NULL;
 
     FT_ULong  base_glyph_offset, layer_offset;
+    FT_ULong  base_glyphs_offset_v1, num_base_glyphs_v1;
+    FT_ULong  layer_offset_v1, num_layers_v1, clip_list_offset;
     FT_ULong  table_size;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    FT_ULong  colr_offset_in_stream;
+#endif
 
 
     /* `COLR' always needs `CPAL' */
@@ -104,8 +186,12 @@
     if ( error )
       goto NoColr;
 
-    if ( table_size < COLR_HEADER_SIZE )
-      goto InvalidTable;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    colr_offset_in_stream = FT_STREAM_POS();
+#endif
+
+    if ( table_size < COLRV0_HEADER_SIZE )
+      goto NoColr;
 
     if ( FT_FRAME_EXTRACT( table_size, table ) )
       goto NoColr;
@@ -116,7 +202,7 @@
       goto NoColr;
 
     colr->version = FT_NEXT_USHORT( p );
-    if ( colr->version != 0 )
+    if ( colr->version != 0 && colr->version != 1 )
       goto InvalidTable;
 
     colr->num_base_glyphs = FT_NEXT_USHORT( p );
@@ -136,6 +222,131 @@
     if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset )
       goto InvalidTable;
 
+    if ( colr->version == 1 )
+    {
+      if ( table_size < COLRV1_HEADER_SIZE )
+        goto InvalidTable;
+
+      base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
+
+      if ( base_glyphs_offset_v1 + 4 >= table_size )
+        goto InvalidTable;
+
+      p1                 = (FT_Byte*)( table + base_glyphs_offset_v1 );
+      num_base_glyphs_v1 = FT_PEEK_ULONG( p1 );
+
+      if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE >
+             table_size - base_glyphs_offset_v1 )
+        goto InvalidTable;
+
+      colr->num_base_glyphs_v1 = num_base_glyphs_v1;
+      colr->base_glyphs_v1     = p1;
+
+      layer_offset_v1 = FT_NEXT_ULONG( p );
+
+      if ( layer_offset_v1 >= table_size )
+        goto InvalidTable;
+
+      if ( layer_offset_v1 )
+      {
+        if ( layer_offset_v1 + 4 >= table_size )
+          goto InvalidTable;
+
+        p1            = (FT_Byte*)( table + layer_offset_v1 );
+        num_layers_v1 = FT_PEEK_ULONG( p1 );
+
+        if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE >
+               table_size - layer_offset_v1 )
+          goto InvalidTable;
+
+        colr->num_layers_v1 = num_layers_v1;
+        colr->layers_v1     = p1;
+
+        colr->paints_start_v1 =
+            FT_MIN( colr->base_glyphs_v1 +
+                    colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE,
+                    colr->layers_v1 +
+                    colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE );
+      }
+      else
+      {
+        colr->num_layers_v1   = 0;
+        colr->layers_v1       = 0;
+        colr->paints_start_v1 =
+          colr->base_glyphs_v1 +
+          colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE;
+      }
+
+      clip_list_offset = FT_NEXT_ULONG( p );
+
+      if ( clip_list_offset >= table_size )
+        goto InvalidTable;
+
+      if ( clip_list_offset )
+        colr->clip_list = (FT_Byte*)( table + clip_list_offset );
+      else
+        colr->clip_list = 0;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      colr->var_store.dataCount     = 0;
+      colr->var_store.varData       = NULL;
+      colr->var_store.axisCount     = 0;
+      colr->var_store.regionCount   = 0;
+      colr->var_store.varRegionList = 0;
+
+      colr->delta_set_idx_map.mapCount   = 0;
+      colr->delta_set_idx_map.outerIndex = NULL;
+      colr->delta_set_idx_map.innerIndex = NULL;
+
+      if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
+      {
+        FT_ULong  var_idx_map_offset, var_store_offset;
+
+        FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+        var_idx_map_offset = FT_NEXT_ULONG( p );
+
+        if ( var_idx_map_offset >= table_size )
+          goto InvalidTable;
+
+        var_store_offset = FT_NEXT_ULONG( p );
+        if ( var_store_offset >= table_size )
+          goto InvalidTable;
+
+        if ( var_store_offset )
+        {
+          /* If variation info has not been initialized yet, try doing so, */
+          /* otherwise loading the variation store will fail as it         */
+          /* requires access to `blend` for checking the number of axes.   */
+          if ( !face->blend )
+            if ( mm->get_mm_var( FT_FACE( face ), NULL ) )
+              goto InvalidTable;
+
+          /* Try loading `VarIdxMap` and `VarStore`. */
+          error = mm->load_item_var_store(
+                    FT_FACE( face ),
+                    colr_offset_in_stream + var_store_offset,
+                    &colr->var_store );
+          if ( error != FT_Err_Ok )
+            goto InvalidTable;
+        }
+
+        if ( colr->var_store.axisCount && var_idx_map_offset )
+        {
+          error = mm->load_delta_set_idx_map(
+                    FT_FACE( face ),
+                    colr_offset_in_stream + var_idx_map_offset,
+                    &colr->delta_set_idx_map,
+                    &colr->var_store,
+                    table_size );
+          if ( error != FT_Err_Ok )
+            goto InvalidTable;
+        }
+      }
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+    }
+
     colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset );
     colr->layers      = (FT_Byte*)( table + layer_offset      );
     colr->table       = table;
@@ -146,6 +357,18 @@
     return FT_Err_Ok;
 
   InvalidTable:
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    {
+      FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+      mm->done_delta_set_idx_map( FT_FACE( face ),
+                                  &colr->delta_set_idx_map );
+      mm->done_item_var_store( FT_FACE( face ),
+                               &colr->var_store );
+    }
+#endif
+
     error = FT_THROW( Invalid_Table );
 
   NoColr:
@@ -167,6 +390,17 @@
 
     if ( colr )
     {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      {
+        FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+        mm->done_delta_set_idx_map( FT_FACE( face ),
+                                    &colr->delta_set_idx_map );
+        mm->done_item_var_store( FT_FACE( face ),
+                                 &colr->var_store );
+      }
+#endif
       FT_FRAME_RELEASE( colr->table );
       FT_FREE( colr );
     }
@@ -175,17 +409,17 @@
 
   static FT_Bool
   find_base_glyph_record( FT_Byte*          base_glyph_begin,
-                          FT_Int            num_base_glyph,
+                          FT_UInt           num_base_glyph,
                           FT_UInt           glyph_id,
                           BaseGlyphRecord*  record )
   {
-    FT_Int  min = 0;
-    FT_Int  max = num_base_glyph - 1;
+    FT_UInt  min = 0;
+    FT_UInt  max = num_base_glyph;
 
 
-    while ( min <= max )
+    while ( min < max )
     {
-      FT_Int    mid = min + ( max - min ) / 2;
+      FT_UInt   mid = min + ( max - min ) / 2;
       FT_Byte*  p   = base_glyph_begin + mid * BASE_GLYPH_SIZE;
 
       FT_UShort  gid = FT_NEXT_USHORT( p );
@@ -194,7 +428,7 @@
       if ( gid < glyph_id )
         min = mid + 1;
       else if (gid > glyph_id )
-        max = mid - 1;
+        max = mid;
       else
       {
         record->gid               = gid;
@@ -249,7 +483,9 @@
       iterator->p = colr->layers + offset;
     }
 
-    if ( iterator->layer >= iterator->num_layers )
+    if ( iterator->layer >= iterator->num_layers                     ||
+         iterator->p < colr->layers                                  ||
+         iterator->p >= ( (FT_Byte*)colr->table + colr->table_size ) )
       return 0;
 
     *aglyph_index = FT_NEXT_USHORT( iterator->p );
@@ -266,6 +502,1240 @@
   }
 
 
+  static FT_Bool
+  read_color_line( Colr*          colr,
+                   FT_Byte*       color_line_p,
+                   FT_ColorLine*  colorline,
+                   FT_Bool        read_variable )
+  {
+    FT_Byte*        p = color_line_p;
+    FT_PaintExtend  paint_extend;
+
+
+    ENSURE_READ_BYTES( 3 );
+
+    paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p );
+    if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT )
+      return 0;
+
+    colorline->extend = paint_extend;
+
+    colorline->color_stop_iterator.num_color_stops    = FT_NEXT_USHORT( p );
+    colorline->color_stop_iterator.p                  = p;
+    colorline->color_stop_iterator.current_color_stop = 0;
+    colorline->color_stop_iterator.read_variable      = read_variable;
+
+    return 1;
+  }
+
+
+  /*
+   * Read a paint offset for `FT_Paint*` objects that have them and check
+   * whether it is within reasonable limits within the font and the COLR
+   * table.
+   *
+   * Return 1 on success, 0 on failure.
+   */
+  static FT_Bool
+  get_child_table_pointer ( Colr*      colr,
+                            FT_Byte*   paint_base,
+                            FT_Byte**  p,
+                            FT_Byte**  child_table_pointer )
+  {
+    FT_UInt32  paint_offset;
+    FT_Byte*   child_table_p;
+
+
+    if ( !child_table_pointer )
+      return 0;
+
+    if ( *p < colr->paints_start_v1                            ||
+         *p > (FT_Byte*)colr->table + colr->table_size - 1 - 3 )
+      return 0;
+
+    paint_offset = FT_NEXT_UOFF3( *p );
+    if ( !paint_offset )
+      return 0;
+
+    child_table_p = (FT_Byte*)( paint_base + paint_offset );
+
+    if ( child_table_p < colr->paints_start_v1                         ||
+         child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) )
+      return 0;
+
+    *child_table_pointer = child_table_p;
+    return 1;
+  }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+  static FT_Bool
+  get_deltas_for_var_index_base ( TT_Face           face,
+                                  Colr*             colr,
+                                  FT_ULong          var_index_base,
+                                  FT_UInt           num_deltas,
+                                  FT_ItemVarDelta*  deltas )
+  {
+    FT_UInt   outer_index    = 0;
+    FT_UInt   inner_index    = 0;
+    FT_ULong  loop_var_index = var_index_base;
+
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+    FT_UInt  i = 0;
+
+
+    if ( var_index_base == 0xFFFFFFFF )
+    {
+      for ( i = 0; i < num_deltas; ++i )
+        deltas[i] = 0;
+      return 1;
+    }
+
+    for ( i = 0; i < num_deltas; ++i )
+    {
+      loop_var_index = var_index_base + i;
+
+      if ( colr->delta_set_idx_map.innerIndex )
+      {
+        if ( loop_var_index >= colr->delta_set_idx_map.mapCount )
+          loop_var_index = colr->delta_set_idx_map.mapCount - 1;
+
+        outer_index = colr->delta_set_idx_map.outerIndex[loop_var_index];
+        inner_index = colr->delta_set_idx_map.innerIndex[loop_var_index];
+      }
+      else
+      {
+        outer_index = 0;
+        inner_index = loop_var_index;
+      }
+
+      deltas[i] = mm->get_item_delta( FT_FACE( face ), &colr->var_store,
+                                      outer_index, inner_index );
+    }
+
+    return 1;
+  }
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
+
+  static FT_Bool
+  read_paint( TT_Face         face,
+              Colr*           colr,
+              FT_Byte*        p,
+              FT_COLR_Paint*  apaint )
+  {
+    FT_Byte*  paint_base    = p;
+    FT_Byte*  child_table_p = NULL;
+    FT_Bool   do_read_var   = FALSE;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    FT_ULong         var_index_base = 0;
+    /* Longest varIndexBase offset is 5 in the spec. */
+    FT_ItemVarDelta  item_deltas[6] = { 0, 0, 0, 0, 0, 0 };
+#else
+    FT_UNUSED( face );
+#endif
+
+
+    if ( !p || !colr || !colr->table )
+      return 0;
+
+    /* The last byte of the 'COLR' table is at 'size-1'; subtract 1 of    */
+    /* that to account for the expected format byte we are going to read. */
+    if ( p < colr->paints_start_v1                        ||
+         p > (FT_Byte*)colr->table + colr->table_size - 2 )
+      return 0;
+
+    apaint->format = (FT_PaintFormat)FT_NEXT_BYTE( p );
+
+    if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX )
+      return 0;
+
+    if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_LAYERS )
+    {
+      /* Initialize layer iterator/ */
+      FT_Byte    num_layers;
+      FT_UInt32  first_layer_index;
+
+
+      num_layers = FT_NEXT_BYTE( p );
+      if ( num_layers > colr->num_layers_v1 )
+        return 0;
+
+      first_layer_index = FT_NEXT_ULONG( p );
+      if ( first_layer_index + num_layers > colr->num_layers_v1 )
+        return 0;
+
+      apaint->u.colr_layers.layer_iterator.num_layers = num_layers;
+      apaint->u.colr_layers.layer_iterator.layer      = 0;
+      /* TODO: Check whether pointer is outside colr? */
+      apaint->u.colr_layers.layer_iterator.p =
+        colr->layers_v1 +
+        LAYER_V1_LIST_NUM_LAYERS_SIZE +
+        LAYER_V1_LIST_PAINT_OFFSET_SIZE * first_layer_index;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                 FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID   )
+    {
+      ENSURE_READ_BYTES( 4 );
+      apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p );
+      apaint->u.solid.color.alpha         = FT_NEXT_SHORT( p );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+              FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG( p );
+
+        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
+                                             item_deltas ) )
+          return 0;
+
+        apaint->u.solid.color.alpha += item_deltas[0];
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_SOLID;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH )
+    {
+      ENSURE_READ_BYTES(2);
+      apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p );
+
+      return 1;
+    }
+
+    /*
+     * Grouped below here are all paint formats that have an offset to a
+     * child paint table as the first entry (for example, a color line or a
+     * child paint table).  Retrieve that and determine whether that paint
+     * offset is valid first.
+     */
+
+    if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
+      return 0;
+
+    if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT      ||
+         ( do_read_var =
+             ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT ) ) )
+    {
+      if ( !read_color_line( colr,
+                             child_table_p,
+                             &apaint->u.linear_gradient.colorline,
+                             do_read_var ) )
+        return 0;
+
+      /*
+       * In order to support variations expose these as FT_Fixed 16.16
+       * values so that we can support fractional values after
+       * interpolation.
+       */
+      ENSURE_READ_BYTES( 12 );
+      apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.linear_gradient.p1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( do_read_var )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG ( p );
+
+        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
+                                             item_deltas ) )
+          return 0;
+
+        apaint->u.linear_gradient.p0.x += INT_TO_FIXED( item_deltas[0] );
+        apaint->u.linear_gradient.p0.y += INT_TO_FIXED( item_deltas[1] );
+        apaint->u.linear_gradient.p1.x += INT_TO_FIXED( item_deltas[2] );
+        apaint->u.linear_gradient.p1.y += INT_TO_FIXED( item_deltas[3] );
+        apaint->u.linear_gradient.p2.x += INT_TO_FIXED( item_deltas[4] );
+        apaint->u.linear_gradient.p2.y += INT_TO_FIXED( item_deltas[5] );
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_LINEAR_GRADIENT;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT      ||
+              ( do_read_var =
+                  ( (FT_PaintFormat_Internal)apaint->format ==
+                    FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT ) ) )
+    {
+      FT_Pos  tmp;
+
+
+      if ( !read_color_line( colr,
+                             child_table_p,
+                             &apaint->u.radial_gradient.colorline,
+                             do_read_var ) )
+        return 0;
+
+
+      /* In the OpenType specification, `r0` and `r1` are defined as   */
+      /* `UFWORD`.  Since FreeType doesn't have a corresponding 16.16  */
+      /* format we convert to `FWORD` and replace negative values with */
+      /* (32bit) `FT_INT_MAX`.                                         */
+
+      ENSURE_READ_BYTES( 12 );
+
+      apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+      tmp                          = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.radial_gradient.r0 = tmp < 0 ? FT_INT_MAX : tmp;
+
+      apaint->u.radial_gradient.c1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.radial_gradient.c1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+      tmp                          = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.radial_gradient.r1 = tmp < 0 ? FT_INT_MAX : tmp;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( do_read_var )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG ( p );
+
+        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
+                                             item_deltas ) )
+          return 0;
+
+        apaint->u.radial_gradient.c0.x += INT_TO_FIXED( item_deltas[0] );
+        apaint->u.radial_gradient.c0.y += INT_TO_FIXED( item_deltas[1] );
+
+        // TODO: Anything to be done about UFWORD deltas here?
+        apaint->u.radial_gradient.r0 += INT_TO_FIXED( item_deltas[2] );
+
+        apaint->u.radial_gradient.c1.x += INT_TO_FIXED( item_deltas[3] );
+        apaint->u.radial_gradient.c1.y += INT_TO_FIXED( item_deltas[4] );
+
+        apaint->u.radial_gradient.r1 += INT_TO_FIXED( item_deltas[5] );
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_RADIAL_GRADIENT;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT      ||
+              ( do_read_var =
+                  ( (FT_PaintFormat_Internal)apaint->format ==
+                    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT ) ) )
+    {
+      if ( !read_color_line( colr,
+                             child_table_p,
+                             &apaint->u.sweep_gradient.colorline,
+                             do_read_var) )
+        return 0;
+
+      ENSURE_READ_BYTES( 8 );
+
+      apaint->u.sweep_gradient.center.x =
+          INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.sweep_gradient.center.y =
+          INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+      apaint->u.sweep_gradient.start_angle =
+          F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.sweep_gradient.end_angle =
+          F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( do_read_var )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG ( p );
+
+        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+                                             item_deltas ) )
+          return 0;
+
+        // TODO: Handle overflow?
+        apaint->u.sweep_gradient.center.x += INT_TO_FIXED( item_deltas[0] );
+        apaint->u.sweep_gradient.center.y += INT_TO_FIXED( item_deltas[1] );
+
+        apaint->u.sweep_gradient.start_angle +=
+          F2DOT14_TO_FIXED( item_deltas[2] );
+        apaint->u.sweep_gradient.end_angle +=
+          F2DOT14_TO_FIXED( item_deltas[3] );
+      }
+#endif
+      apaint->format = FT_COLR_PAINTFORMAT_SWEEP_GRADIENT;
+
+      return 1;
+    }
+
+    if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH )
+    {
+      ENSURE_READ_BYTES( 2 );
+      apaint->u.glyph.paint.p                     = child_table_p;
+      apaint->u.glyph.paint.insert_root_transform = 0;
+      apaint->u.glyph.glyphID                     = FT_NEXT_USHORT( p );
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM    )
+    {
+      apaint->u.transform.paint.p                     = child_table_p;
+      apaint->u.transform.paint.insert_root_transform = 0;
+
+      if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
+         return 0;
+
+      p = child_table_p;
+
+      /*
+       * The following matrix coefficients are encoded as
+       * OpenType 16.16 fixed-point values.
+       */
+      ENSURE_READ_BYTES( 24 );
+      apaint->u.transform.affine.xx = FT_NEXT_LONG( p );
+      apaint->u.transform.affine.yx = FT_NEXT_LONG( p );
+      apaint->u.transform.affine.xy = FT_NEXT_LONG( p );
+      apaint->u.transform.affine.yy = FT_NEXT_LONG( p );
+      apaint->u.transform.affine.dx = FT_NEXT_LONG( p );
+      apaint->u.transform.affine.dy = FT_NEXT_LONG( p );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG( p );
+
+        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
+                                             item_deltas ) )
+          return 0;
+
+        apaint->u.transform.affine.xx += (FT_Fixed)item_deltas[0];
+        apaint->u.transform.affine.yx += (FT_Fixed)item_deltas[1];
+        apaint->u.transform.affine.xy += (FT_Fixed)item_deltas[2];
+        apaint->u.transform.affine.yy += (FT_Fixed)item_deltas[3];
+        apaint->u.transform.affine.dx += (FT_Fixed)item_deltas[4];
+        apaint->u.transform.affine.dy += (FT_Fixed)item_deltas[5];
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_TRANSFORM;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE    )
+    {
+      apaint->u.translate.paint.p                     = child_table_p;
+      apaint->u.translate.paint.insert_root_transform = 0;
+
+      ENSURE_READ_BYTES( 4 );
+      apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG( p );
+
+        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
+                                             item_deltas ) )
+          return 0;
+
+        apaint->u.translate.dx += INT_TO_FIXED( item_deltas[0] );
+        apaint->u.translate.dy += INT_TO_FIXED( item_deltas[1] );
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_TRANSLATE;
+
+      return 1;
+    }
+
+    else if ( apaint->format >= FT_COLR_PAINTFORMAT_SCALE             &&
+              (FT_PaintFormat_Internal)apaint->format <=
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+    {
+      apaint->u.scale.paint.p                     = child_table_p;
+      apaint->u.scale.paint.insert_root_transform = 0;
+
+      /* All scale paints get at least one scale value. */
+      ENSURE_READ_BYTES( 2 );
+      apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+      /* Non-uniform ones read an extra y value. */
+      if ( apaint->format == FT_COLR_PAINTFORMAT_SCALE     ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE        ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER     ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
+      {
+        ENSURE_READ_BYTES( 2 );
+        apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+      }
+      else
+        apaint->u.scale.scale_y = apaint->u.scale.scale_x;
+
+      /* Scale paints that have a center read center coordinates, */
+      /* otherwise the center is (0,0).                           */
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER             ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER         ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER     ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+      {
+        ENSURE_READ_BYTES( 4 );
+        apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
+        apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
+      }
+      else
+      {
+        apaint->u.scale.center_x = 0;
+        apaint->u.scale.center_y = 0;
+      }
+
+      /* Base values set, now handle variations. */
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE                ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER         ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM        ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG( p );
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
+                                               item_deltas ) )
+            return 0;
+
+          apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[1] );
+        }
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+                                               item_deltas ) )
+            return 0;
+
+          apaint->u.scale.scale_x  += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.scale.scale_y  += F2DOT14_TO_FIXED( item_deltas[1] );
+          apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[2] );
+          apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[3] );
+        }
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
+                                               item_deltas ) )
+            return 0;
+
+          apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[0] );
+        }
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 3,
+                                               item_deltas ) )
+            return 0;
+
+          apaint->u.scale.scale_x  += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.scale.scale_y  += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[1] );
+          apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[2] );
+        }
+      }
+#endif
+
+      /* FT 'COLR' v1 API output format always returns fully defined */
+      /* structs; we thus set the format to the public API value.    */
+      apaint->format = FT_COLR_PAINTFORMAT_SCALE;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE     ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER     ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE        ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+    {
+      apaint->u.rotate.paint.p                     = child_table_p;
+      apaint->u.rotate.paint.insert_root_transform = 0;
+
+      ENSURE_READ_BYTES( 2 );
+      apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER     ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+      {
+        ENSURE_READ_BYTES( 4 );
+        apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+        apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      }
+      else
+      {
+        apaint->u.rotate.center_x = 0;
+        apaint->u.rotate.center_y = 0;
+      }
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE        ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+      {
+        FT_UInt  num_deltas = 0;
+
+
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG( p );
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+          num_deltas = 3;
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE )
+          num_deltas = 1;
+
+        if ( num_deltas > 0 )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base,
+                                               num_deltas, item_deltas ) )
+            return 0;
+
+          apaint->u.rotate.angle += F2DOT14_TO_FIXED( item_deltas[0] );
+
+          if ( num_deltas == 3 )
+          {
+            apaint->u.rotate.center_x += INT_TO_FIXED( item_deltas[1] );
+            apaint->u.rotate.center_y += INT_TO_FIXED( item_deltas[2] );
+          }
+        }
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_ROTATE;
+
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW     ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW        ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER     ||
+              (FT_PaintFormat_Internal)apaint->format ==
+                FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+    {
+      apaint->u.skew.paint.p                     = child_table_p;
+      apaint->u.skew.paint.insert_root_transform = 0;
+
+      ENSURE_READ_BYTES( 4 );
+      apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+      apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER     ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+      {
+        ENSURE_READ_BYTES( 4 );
+        apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+        apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+      }
+      else
+      {
+        apaint->u.skew.center_x = 0;
+        apaint->u.skew.center_y = 0;
+      }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW        ||
+           (FT_PaintFormat_Internal)apaint->format ==
+             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+      {
+        ENSURE_READ_BYTES( 4 );
+        var_index_base = FT_NEXT_ULONG( p );
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
+                                               item_deltas ) )
+            return 0;
+
+          apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
+        }
+
+        if ( (FT_PaintFormat_Internal)apaint->format ==
+               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+        {
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+                                               item_deltas ) )
+            return 0;
+
+          apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
+          apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
+          apaint->u.skew.center_x     += INT_TO_FIXED( item_deltas[2] );
+          apaint->u.skew.center_y     += INT_TO_FIXED( item_deltas[3] );
+        }
+      }
+#endif
+
+      apaint->format = FT_COLR_PAINTFORMAT_SKEW;
+
+      return 1;
+    }
+
+    else if ( apaint->format == FT_COLR_PAINTFORMAT_COMPOSITE )
+    {
+      FT_UInt  composite_mode;
+
+
+      apaint->u.composite.source_paint.p                     = child_table_p;
+      apaint->u.composite.source_paint.insert_root_transform = 0;
+
+      ENSURE_READ_BYTES( 1 );
+      composite_mode = FT_NEXT_BYTE( p );
+      if ( composite_mode >= FT_COLR_COMPOSITE_MAX )
+        return 0;
+
+      apaint->u.composite.composite_mode = (FT_Composite_Mode)composite_mode;
+
+      if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
+         return 0;
+
+      apaint->u.composite.backdrop_paint.p =
+        child_table_p;
+      apaint->u.composite.backdrop_paint.insert_root_transform =
+        0;
+
+      return 1;
+    }
+
+    return 0;
+  }
+
+
+  static FT_Bool
+  find_base_glyph_v1_record( FT_Byte *           base_glyph_begin,
+                             FT_UInt             num_base_glyph,
+                             FT_UInt             glyph_id,
+                             BaseGlyphV1Record  *record )
+  {
+    FT_UInt  min = 0;
+    FT_UInt  max = num_base_glyph;
+
+
+    while ( min < max )
+    {
+      FT_UInt  mid = min + ( max - min ) / 2;
+
+      /*
+       * `base_glyph_begin` is the beginning of `BaseGlyphV1List`;
+       * skip `numBaseGlyphV1Records` by adding 4 to start binary search
+       * in the array of `BaseGlyphV1Record`.
+       */
+      FT_Byte  *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE;
+
+      FT_UShort  gid = FT_NEXT_USHORT( p );
+
+
+      if ( gid < glyph_id )
+        min = mid + 1;
+      else if (gid > glyph_id )
+        max = mid;
+      else
+      {
+        record->gid          = gid;
+        record->paint_offset = FT_NEXT_ULONG ( p );
+        return 1;
+      }
+    }
+
+    return 0;
+  }
+
+
+  FT_LOCAL_DEF( FT_Bool )
+  tt_face_get_colr_glyph_paint( TT_Face                  face,
+                                FT_UInt                  base_glyph,
+                                FT_Color_Root_Transform  root_transform,
+                                FT_OpaquePaint*          opaque_paint )
+  {
+    Colr*              colr = (Colr*)face->colr;
+    BaseGlyphV1Record  base_glyph_v1_record;
+    FT_Byte*           p;
+
+    if ( !colr || !colr->table )
+      return 0;
+
+    if ( colr->version < 1 || !colr->num_base_glyphs_v1 ||
+         !colr->base_glyphs_v1 )
+      return 0;
+
+    if ( opaque_paint->p )
+      return 0;
+
+    if ( !find_base_glyph_v1_record( colr->base_glyphs_v1,
+                                     colr->num_base_glyphs_v1,
+                                     base_glyph,
+                                     &base_glyph_v1_record ) )
+      return 0;
+
+    if ( !base_glyph_v1_record.paint_offset                   ||
+         base_glyph_v1_record.paint_offset > colr->table_size )
+      return 0;
+
+    p = (FT_Byte*)( colr->base_glyphs_v1 +
+                    base_glyph_v1_record.paint_offset );
+    if ( p >= ( (FT_Byte*)colr->table + colr->table_size ) )
+      return 0;
+
+    opaque_paint->p = p;
+
+    if ( root_transform == FT_COLOR_INCLUDE_ROOT_TRANSFORM )
+      opaque_paint->insert_root_transform = 1;
+    else
+      opaque_paint->insert_root_transform = 0;
+
+    return 1;
+  }
+
+
+  FT_LOCAL_DEF( FT_Bool )
+  tt_face_get_color_glyph_clipbox( TT_Face      face,
+                                   FT_UInt      base_glyph,
+                                   FT_ClipBox*  clip_box )
+  {
+    Colr*  colr;
+
+    FT_Byte  *p, *p1, *clip_base, *limit;
+
+    FT_Byte    clip_list_format;
+    FT_ULong   num_clip_boxes, i;
+    FT_UShort  gid_start, gid_end;
+    FT_UInt32  clip_box_offset;
+    FT_Byte    format;
+
+    const FT_Byte  num_corners = 4;
+    FT_Vector      corners[4];
+    FT_Byte        j;
+    FT_BBox        font_clip_box;
+
+
+    colr = (Colr*)face->colr;
+    if ( !colr )
+      return 0;
+
+    if ( !colr->clip_list )
+      return 0;
+
+    p = colr->clip_list;
+
+    /* Limit points to the first byte after the end of the color table.    */
+    /* Thus, in subsequent limit checks below we need to check whether the */
+    /* read pointer is strictly greater than a position offset by certain  */
+    /* field sizes to the left of that position.                           */
+    limit = (FT_Byte*)colr->table + colr->table_size;
+
+    /* Check whether we can extract one `uint8` and one `uint32`. */
+    if ( p > limit - ( 1 + 4 ) )
+      return 0;
+
+    clip_base        = p;
+    clip_list_format = FT_NEXT_BYTE ( p );
+
+    /* Format byte used here to be able to upgrade ClipList for >16bit */
+    /* glyph ids; for now we can expect it to be 1.                    */
+    if ( !( clip_list_format == 1 ) )
+      return 0;
+
+    num_clip_boxes = FT_NEXT_ULONG( p );
+
+    /* Check whether we can extract two `uint16` and one `Offset24`, */
+    /* `num_clip_boxes` times.                                       */
+    if ( colr->table_size / ( 2 + 2 + 3 ) < num_clip_boxes ||
+         p > limit - ( 2 + 2 + 3 ) * num_clip_boxes        )
+      return 0;
+
+    for ( i = 0; i < num_clip_boxes; ++i )
+    {
+      gid_start       = FT_NEXT_USHORT( p );
+      gid_end         = FT_NEXT_USHORT( p );
+      clip_box_offset = FT_NEXT_UOFF3( p );
+
+      if ( base_glyph >= gid_start && base_glyph <= gid_end )
+      {
+        p1 = (FT_Byte*)( clip_base + clip_box_offset );
+
+        /* Check whether we can extract one `uint8`. */
+        if ( p1 > limit - 1 )
+          return 0;
+
+        format = FT_NEXT_BYTE( p1 );
+
+        if ( format > 2 )
+          return 0;
+
+        /* Check whether we can extract four `FWORD`. */
+        if ( p1 > limit - ( 2 + 2 + 2 + 2 ) )
+          return 0;
+
+        /* `face->root.size->metrics.x_scale` and `y_scale` are factors   */
+        /* that scale a font unit value in integers to a 26.6 fixed value */
+        /* according to the requested size, see for example               */
+        /* `ft_recompute_scaled_metrics`.                                 */
+        font_clip_box.xMin = FT_MulFix( FT_NEXT_SHORT( p1 ),
+                                        face->root.size->metrics.x_scale );
+        font_clip_box.yMin = FT_MulFix( FT_NEXT_SHORT( p1 ),
+                                        face->root.size->metrics.y_scale );
+        font_clip_box.xMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
+                                        face->root.size->metrics.x_scale );
+        font_clip_box.yMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
+                                        face->root.size->metrics.y_scale );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        if ( format == 2 )
+        {
+          FT_ULong         var_index_base = 0;
+          /* varIndexBase offset for clipbox is 3 at most. */
+          FT_ItemVarDelta  item_deltas[4] = { 0, 0, 0, 0 };
+
+
+          /* Check whether we can extract a 32-bit varIndexBase now. */
+          if ( p1 > limit - 4 )
+            return 0;
+
+          var_index_base = FT_NEXT_ULONG( p1 );
+
+          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+                                               item_deltas ) )
+            return 0;
+
+          font_clip_box.xMin +=
+            FT_MulFix( item_deltas[0], face->root.size->metrics.x_scale );
+          font_clip_box.yMin +=
+            FT_MulFix( item_deltas[1], face->root.size->metrics.y_scale );
+          font_clip_box.xMax +=
+            FT_MulFix( item_deltas[2], face->root.size->metrics.x_scale );
+          font_clip_box.yMax +=
+            FT_MulFix( item_deltas[3], face->root.size->metrics.y_scale );
+        }
+#endif
+
+        /* Make 4 corner points (xMin, yMin), (xMax, yMax) and transform */
+        /* them.  If we we would only transform two corner points and    */
+        /* span a rectangle based on those, the rectangle may become too */
+        /* small to cover the glyph.                                     */
+        corners[0].x = font_clip_box.xMin;
+        corners[1].x = font_clip_box.xMin;
+        corners[2].x = font_clip_box.xMax;
+        corners[3].x = font_clip_box.xMax;
+
+        corners[0].y = font_clip_box.yMin;
+        corners[1].y = font_clip_box.yMax;
+        corners[2].y = font_clip_box.yMax;
+        corners[3].y = font_clip_box.yMin;
+
+        for ( j = 0; j < num_corners; ++j )
+        {
+          if ( face->root.internal->transform_flags & 1 )
+            FT_Vector_Transform( &corners[j],
+                                 &face->root.internal->transform_matrix );
+
+          if ( face->root.internal->transform_flags & 2 )
+          {
+            corners[j].x += face->root.internal->transform_delta.x;
+            corners[j].y += face->root.internal->transform_delta.y;
+          }
+        }
+
+        clip_box->bottom_left  = corners[0];
+        clip_box->top_left     = corners[1];
+        clip_box->top_right    = corners[2];
+        clip_box->bottom_right = corners[3];
+
+        return 1;
+      }
+    }
+
+    return 0;
+  }
+
+
+  FT_LOCAL_DEF( FT_Bool )
+  tt_face_get_paint_layers( TT_Face            face,
+                            FT_LayerIterator*  iterator,
+                            FT_OpaquePaint*    opaque_paint )
+  {
+    FT_Byte*   p             = NULL;
+    FT_Byte*   p_first_layer = NULL;
+    FT_Byte*   p_paint       = NULL;
+    FT_UInt32  paint_offset;
+
+    Colr*  colr;
+
+
+    if ( iterator->layer == iterator->num_layers )
+      return 0;
+
+    colr = (Colr*)face->colr;
+    if ( !colr )
+      return 0;
+
+    /*
+     * We have an iterator pointing at a paint offset as part of the
+     * `paintOffset` array in `LayerV1List`.
+     */
+    p = iterator->p;
+
+    /*
+     * Do a cursor sanity check of the iterator.  Counting backwards from
+     * where it stands, we need to end up at a position after the beginning
+     * of the `LayerV1List` table and not after the end of the
+     * `LayerV1List`.
+     */
+    p_first_layer = p -
+                      iterator->layer * LAYER_V1_LIST_PAINT_OFFSET_SIZE -
+                      LAYER_V1_LIST_NUM_LAYERS_SIZE;
+    if ( p_first_layer < (FT_Byte*)colr->layers_v1 )
+      return 0;
+    if ( p_first_layer >= (FT_Byte*)(
+           colr->layers_v1 + LAYER_V1_LIST_NUM_LAYERS_SIZE +
+           colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) )
+      return 0;
+
+    /*
+     * Before reading, ensure that `p` is within 'COLR' v1 and we can read a
+     * 4-byte ULONG.
+     */
+    if ( p < colr->layers_v1                              ||
+         p > (FT_Byte*)colr->table + colr->table_size - 4 )
+      return 0;
+
+    paint_offset =
+      FT_NEXT_ULONG( p );
+    opaque_paint->insert_root_transform =
+      0;
+
+    p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset );
+
+    if ( p_paint < colr->paints_start_v1                         ||
+         p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) )
+      return 0;
+
+    opaque_paint->p = p_paint;
+
+    iterator->p = p;
+
+    iterator->layer++;
+
+    return 1;
+  }
+
+
+  FT_LOCAL_DEF( FT_Bool )
+  tt_face_get_colorline_stops( TT_Face                face,
+                               FT_ColorStop*          color_stop,
+                               FT_ColorStopIterator  *iterator )
+  {
+    Colr*  colr = (Colr*)face->colr;
+
+    FT_Byte*  p;
+    FT_ULong  var_index_base;
+    FT_Byte*  last_entry_p = NULL;
+    FT_UInt   entry_size   = COLOR_STOP_SIZE;
+
+
+    if ( !colr || !colr->table || !iterator )
+      return 0;
+
+    if ( iterator->current_color_stop >= iterator->num_color_stops )
+      return 0;
+
+    if ( iterator->read_variable )
+      entry_size += VAR_IDX_BASE_SIZE;
+
+    /* Calculate the start pointer for the last to-be-read (Var)ColorStop */
+    /* and check whether we can read a full (Var)ColorStop at that        */
+    /* position by comparing it to the position that is the size of one   */
+    /* (Var)ColorStop before the end of the 'COLR' table.                 */
+    last_entry_p =
+      iterator->p + ( iterator->num_color_stops - 1 -
+                      iterator->current_color_stop ) * entry_size;
+    if ( iterator->p < colr->paints_start_v1          ||
+         last_entry_p > (FT_Byte*)colr->table +
+                        colr->table_size - entry_size )
+      return 0;
+
+    /* Iterator points at first `ColorStop` of `ColorLine`. */
+    p = iterator->p;
+
+    color_stop->stop_offset = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+    color_stop->color.palette_index = FT_NEXT_USHORT( p );
+
+    color_stop->color.alpha = FT_NEXT_SHORT( p );
+
+    if ( iterator->read_variable )
+    {
+      /* Pointer p needs to be advanced independently of whether we intend */
+      /* to take variable deltas into account or not.  Otherwise iteration */
+      /* would fail due to wrong offsets.                                  */
+      var_index_base = FT_NEXT_ULONG( p );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      {
+        FT_Int  item_deltas[2];
+
+
+        if ( !get_deltas_for_var_index_base( face, colr,
+                                             var_index_base,
+                                             2,
+                                             item_deltas ) )
+          return 0;
+
+        color_stop->stop_offset += F2DOT14_TO_FIXED( item_deltas[0] );
+        color_stop->color.alpha += item_deltas[1];
+      }
+#else
+      FT_UNUSED( var_index_base );
+#endif
+    }
+
+    iterator->p = p;
+    iterator->current_color_stop++;
+
+    return 1;
+  }
+
+
+  FT_LOCAL_DEF( FT_Bool )
+  tt_face_get_paint( TT_Face         face,
+                     FT_OpaquePaint  opaque_paint,
+                     FT_COLR_Paint*  paint )
+  {
+    Colr*           colr = (Colr*)face->colr;
+    FT_OpaquePaint  next_paint;
+    FT_Matrix       ft_root_scale;
+
+    if ( !colr || !colr->base_glyphs_v1 || !colr->table )
+      return 0;
+
+    if ( opaque_paint.insert_root_transform )
+    {
+      /* 'COLR' v1 glyph information is returned in unscaled coordinates,
+       * i.e., `FT_Size` is not applied or multiplied into the values.  When
+       * client applications draw color glyphs, they can request to include
+       * a top-level transform, which includes the active `x_scale` and
+       * `y_scale` information for scaling the glyph, as well the additional
+       * transform and translate configured through `FT_Set_Transform`.
+       * This allows client applications to apply this top-level transform
+       * to the graphics context first and only once, then have gradient and
+       * contour scaling applied correctly when performing the additional
+       * drawing operations for subsequenct paints.  Prepare this initial
+       * transform here.
+       */
+      paint->format = FT_COLR_PAINTFORMAT_TRANSFORM;
+
+      next_paint.p                     = opaque_paint.p;
+      next_paint.insert_root_transform = 0;
+      paint->u.transform.paint         = next_paint;
+
+      /* `x_scale` and `y_scale` are in 26.6 format, representing the scale
+       * factor to get from font units to requested size.  However, expected
+       * return values are in 16.16, so we shift accordingly with rounding.
+       */
+      ft_root_scale.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6;
+      ft_root_scale.xy = 0;
+      ft_root_scale.yx = 0;
+      ft_root_scale.yy = ( face->root.size->metrics.y_scale + 32 ) >> 6;
+
+      if ( face->root.internal->transform_flags & 1 )
+        FT_Matrix_Multiply( &face->root.internal->transform_matrix,
+                            &ft_root_scale );
+
+      paint->u.transform.affine.xx = ft_root_scale.xx;
+      paint->u.transform.affine.xy = ft_root_scale.xy;
+      paint->u.transform.affine.yx = ft_root_scale.yx;
+      paint->u.transform.affine.yy = ft_root_scale.yy;
+
+      /* The translation is specified in 26.6 format and, according to the
+       * documentation of `FT_Set_Translate`, is performed on the character
+       * size given in the last call to `FT_Set_Char_Size`.  The
+       * 'PaintTransform' paint table's `FT_Affine23` format expects
+       * values in 16.16 format, thus we need to shift by 10 bits.
+       */
+      if ( face->root.internal->transform_flags & 2 )
+      {
+        paint->u.transform.affine.dx =
+          face->root.internal->transform_delta.x * ( 1 << 10 );
+        paint->u.transform.affine.dy =
+          face->root.internal->transform_delta.y * ( 1 << 10 );
+      }
+      else
+      {
+        paint->u.transform.affine.dx = 0;
+        paint->u.transform.affine.dy = 0;
+      }
+
+      return 1;
+    }
+
+    return read_paint( face, colr, opaque_paint.p, paint );
+  }
+
+
   FT_LOCAL_DEF( FT_Error )
   tt_face_colr_blend_layer( TT_Face       face,
                             FT_UInt       color_index,
diff --git a/src/sfnt/ttcolr.h b/src/sfnt/ttcolr.h
index 46cc081..20c85f0 100644
--- a/src/sfnt/ttcolr.h
+++ b/src/sfnt/ttcolr.h
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType colored glyph layer support (specification).
  *
- * Copyright 2018 by
+ * Copyright (C) 2018-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * Originally written by Shao Yu Zhang <shaozhang@fb.com>.
@@ -22,7 +22,6 @@
 #define __TTCOLR_H__
 
 
-#include <ft2build.h>
 #include "ttload.h"
 
 
@@ -43,6 +42,32 @@
                           FT_UInt           *acolor_index,
                           FT_LayerIterator*  iterator );
 
+  FT_LOCAL( FT_Bool )
+  tt_face_get_colr_glyph_paint( TT_Face                  face,
+                                FT_UInt                  base_glyph,
+                                FT_Color_Root_Transform  root_transform,
+                                FT_OpaquePaint*          paint );
+
+  FT_LOCAL( FT_Bool )
+  tt_face_get_color_glyph_clipbox( TT_Face      face,
+                                   FT_UInt      base_glyph,
+                                   FT_ClipBox*  clip_box );
+
+  FT_LOCAL( FT_Bool )
+  tt_face_get_paint_layers( TT_Face            face,
+                            FT_LayerIterator*  iterator,
+                            FT_OpaquePaint*    paint );
+
+  FT_LOCAL( FT_Bool )
+  tt_face_get_colorline_stops( TT_Face                face,
+                               FT_ColorStop*          color_stop,
+                               FT_ColorStopIterator*  iterator );
+
+  FT_LOCAL( FT_Bool )
+  tt_face_get_paint( TT_Face         face,
+                     FT_OpaquePaint  opaque_paint,
+                     FT_COLR_Paint*  paint );
+
   FT_LOCAL( FT_Error )
   tt_face_colr_blend_layer( TT_Face       face,
                             FT_UInt       color_index,
diff --git a/src/sfnt/ttcpal.c b/src/sfnt/ttcpal.c
index b4b60e2..4279bc0 100644
--- a/src/sfnt/ttcpal.c
+++ b/src/sfnt/ttcpal.c
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType color palette support (body).
  *
- * Copyright 2018 by
+ * Copyright (C) 2018-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * Originally written by Shao Yu Zhang <shaozhang@fb.com>.
@@ -27,11 +27,10 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_COLOR_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
+#include <freetype/ftcolor.h>
 
 
 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS
@@ -40,8 +39,8 @@
 
 
   /* NOTE: These are the table sizes calculated through the specs. */
-#define CPAL_V0_HEADER_BASE_SIZE  12
-#define COLOR_SIZE                 4
+#define CPAL_V0_HEADER_BASE_SIZE  12U
+#define COLOR_SIZE                 4U
 
 
   /* all data from `CPAL' not covered in FT_Palette_Data */
@@ -68,7 +67,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttcpal
+#define FT_COMPONENT  ttcpal
 
 
   FT_LOCAL_DEF( FT_Error )
@@ -121,6 +120,9 @@
     if ( cpal->num_colors * COLOR_SIZE > table_size - colors_offset )
       goto InvalidTable;
 
+    if ( face->palette_data.num_palette_entries > cpal->num_colors )
+      goto InvalidTable;
+
     cpal->color_indices = p;
     cpal->colors        = (FT_Byte*)( table + colors_offset );
 
@@ -137,7 +139,7 @@
            3U * 4                               > table_size )
         goto InvalidTable;
 
-      p += face->palette_data.num_palettes * 2;
+      p += face->palette_data.num_palettes * 2U;
 
       type_offset        = FT_NEXT_ULONG( p );
       label_offset       = FT_NEXT_ULONG( p );
@@ -147,7 +149,7 @@
       {
         if ( type_offset >= table_size )
           goto InvalidTable;
-        if ( face->palette_data.num_palettes * 2 >
+        if ( face->palette_data.num_palettes * 2U >
                table_size - type_offset )
           goto InvalidTable;
 
@@ -168,7 +170,7 @@
       {
         if ( label_offset >= table_size )
           goto InvalidTable;
-        if ( face->palette_data.num_palettes * 2 >
+        if ( face->palette_data.num_palettes * 2U >
                table_size - label_offset )
           goto InvalidTable;
 
@@ -189,7 +191,7 @@
       {
         if ( entry_label_offset >= table_size )
           goto InvalidTable;
-        if ( face->palette_data.num_palette_entries * 2 >
+        if ( face->palette_data.num_palette_entries * 2U >
                table_size - entry_label_offset )
           goto InvalidTable;
 
@@ -217,7 +219,8 @@
                        face->palette_data.num_palette_entries ) )
       goto NoCpal;
 
-    tt_face_palette_set( face, 0 );
+    if ( tt_face_palette_set( face, 0 ) )
+      goto InvalidTable;
 
     return FT_Err_Ok;
 
@@ -228,6 +231,8 @@
     FT_FRAME_RELEASE( table );
     FT_FREE( cpal );
 
+    face->cpal = NULL;
+
     /* arrays in `face->palette_data' and `face->palette' */
     /* are freed in `sfnt_done_face'                      */
 
@@ -264,20 +269,20 @@
     FT_Color*  q;
     FT_Color*  limit;
 
-    FT_ULong  record_offset;
+    FT_UShort  color_index;
 
 
     if ( !cpal || palette_index >= face->palette_data.num_palettes )
       return FT_THROW( Invalid_Argument );
 
-    offset        = cpal->color_indices + 2 * palette_index;
-    record_offset = COLOR_SIZE * FT_PEEK_USHORT( offset );
+    offset      = cpal->color_indices + 2 * palette_index;
+    color_index = FT_PEEK_USHORT( offset );
 
-    if ( record_offset + COLOR_SIZE * face->palette_data.num_palette_entries >
-           cpal->table_size )
+    if ( color_index + face->palette_data.num_palette_entries >
+           cpal->num_colors )
       return FT_THROW( Invalid_Table );
 
-    p     = cpal->colors + record_offset;
+    p     = cpal->colors + COLOR_SIZE * color_index;
     q     = face->palette;
     limit = q + face->palette_data.num_palette_entries;
 
diff --git a/src/sfnt/ttcpal.h b/src/sfnt/ttcpal.h
index 424ef35..8e9913f 100644
--- a/src/sfnt/ttcpal.h
+++ b/src/sfnt/ttcpal.h
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType color palette support (specification).
  *
- * Copyright 2018 by
+ * Copyright (C) 2018-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * Originally written by Shao Yu Zhang <shaozhang@fb.com>.
@@ -22,7 +22,6 @@
 #define __TTCPAL_H__
 
 
-#include <ft2build.h>
 #include "ttload.h"
 
 
diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 48ad417..a47d08b 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -5,7 +5,7 @@
  *   Load the basic TrueType kerning table.  This doesn't handle
  *   kerning data within the GPOS table at the moment.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,10 +17,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 #include "ttkern.h"
 
 #include "sferrors.h"
@@ -33,7 +32,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttkern
+#define FT_COMPONENT  ttkern
 
 
 #undef  TT_KERN_INDEX
@@ -95,7 +94,7 @@
 
       p_next = p;
 
-      p += 2; /* skip version */
+      p       += 2; /* skip version */
       length   = FT_NEXT_USHORT( p );
       coverage = FT_NEXT_USHORT( p );
 
@@ -145,7 +144,7 @@
 
 
           cur_pair = FT_NEXT_ULONG( p );
-          if ( cur_pair <= old_pair )
+          if ( cur_pair < old_pair )
             break;
 
           p += 2;
@@ -188,11 +187,18 @@
                        FT_UInt  left_glyph,
                        FT_UInt  right_glyph )
   {
-    FT_Int    result = 0;
-    FT_UInt   count, mask;
-    FT_Byte*  p       = face->kern_table;
-    FT_Byte*  p_limit = p + face->kern_table_size;
+    FT_Int   result = 0;
+    FT_UInt  count, mask;
 
+    FT_Byte*  p;
+    FT_Byte*  p_limit;
+
+
+    if ( !face->kern_table )
+      return result;
+
+    p       = face->kern_table;
+    p_limit = p + face->kern_table_size;
 
     p   += 4;
     mask = 0x0001;
diff --git a/src/sfnt/ttkern.h b/src/sfnt/ttkern.h
index c26bb8d..960c7da 100644
--- a/src/sfnt/ttkern.h
+++ b/src/sfnt/ttkern.h
@@ -5,7 +5,7 @@
  *   Load the basic TrueType kerning table.  This doesn't handle
  *   kerning data within the GPOS table at the moment.
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,9 +21,8 @@
 #define TTKERN_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/tttypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index f3fed8f..14f625c 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
  *   Load the basic TrueType tables, i.e., tables that can be either in
  *   TTF or OTF fonts (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,10 +17,9 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 #include "ttload.h"
 
 #include "sferrors.h"
@@ -33,7 +32,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttload
+#define FT_COMPONENT  ttload
 
 
   /**************************************************************************
@@ -65,8 +64,8 @@
 #endif
 
 
-    FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
-                face,
+    FT_TRACE4(( "tt_face_lookup_table: %p, `%c%c%c%c' -- ",
+                (void *)face,
                 (FT_Char)( tag >> 24 ),
                 (FT_Char)( tag >> 16 ),
                 (FT_Char)( tag >> 8  ),
@@ -206,9 +205,8 @@
 
       if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
       {
-        nn--;
         FT_TRACE2(( "check_table_dir:"
-                    " can read only %d table%s in font (instead of %d)\n",
+                    " can read only %hu table%s in font (instead of %hu)\n",
                     nn, nn == 1 ? "" : "s", sfnt->num_tables ));
         sfnt->num_tables = nn;
         break;
@@ -218,7 +216,7 @@
 
       if ( table.Offset > stream->size )
       {
-        FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+        FT_TRACE2(( "check_table_dir: table entry %hu invalid\n", nn ));
         continue;
       }
       else if ( table.Length > stream->size - table.Offset )
@@ -233,7 +231,7 @@
           valid_entries++;
         else
         {
-          FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+          FT_TRACE2(( "check_table_dir: table entry %hu invalid\n", nn ));
           continue;
         }
       }
@@ -363,7 +361,7 @@
     };
 
 
-    FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
+    FT_TRACE2(( "tt_face_load_font_dir: %p\n", (void *)face ));
 
     /* read the offset table */
 
@@ -382,7 +380,7 @@
 
     /* load the table directory */
 
-    FT_TRACE2(( "-- Number of tables: %10u\n",    sfnt.num_tables ));
+    FT_TRACE2(( "-- Number of tables: %10hu\n",   sfnt.num_tables ));
     FT_TRACE2(( "-- Format version:   0x%08lx\n", sfnt.format_tag ));
 
     if ( sfnt.format_tag != TTAG_OTTO )
@@ -397,7 +395,15 @@
       }
     }
     else
+    {
       valid_entries = sfnt.num_tables;
+      if ( !valid_entries )
+      {
+        FT_TRACE2(( "tt_face_load_font_dir: no valid tables found\n" ));
+        error = FT_THROW( Unknown_File_Format );
+        goto Exit;
+      }
+    }
 
     face->num_tables = valid_entries;
     face->format_tag = sfnt.format_tag;
@@ -409,9 +415,9 @@
          FT_FRAME_ENTER( sfnt.num_tables * 16L ) )
       goto Exit;
 
-    FT_TRACE2(( "\n"
-                "  tag    offset    length   checksum\n"
-                "  ----------------------------------\n" ));
+    FT_TRACE2(( "\n" ));
+    FT_TRACE2(( "  tag    offset    length   checksum\n" ));
+    FT_TRACE2(( "  ----------------------------------\n" ));
 
     valid_entries = 0;
     for ( nn = 0; nn < sfnt.num_tables; nn++ )
@@ -498,7 +504,8 @@
 
     FT_FRAME_EXIT();
 
-    FT_TRACE2(( "table directory loaded\n\n" ));
+    FT_TRACE2(( "table directory loaded\n" ));
+    FT_TRACE2(( "\n" ));
 
   Exit:
     return error;
@@ -638,10 +645,10 @@
         FT_FRAME_LONG  ( Magic_Number ),
         FT_FRAME_USHORT( Flags ),
         FT_FRAME_USHORT( Units_Per_EM ),
-        FT_FRAME_LONG  ( Created[0] ),
-        FT_FRAME_LONG  ( Created[1] ),
-        FT_FRAME_LONG  ( Modified[0] ),
-        FT_FRAME_LONG  ( Modified[1] ),
+        FT_FRAME_ULONG ( Created[0] ),
+        FT_FRAME_ULONG ( Created[1] ),
+        FT_FRAME_ULONG ( Modified[0] ),
+        FT_FRAME_ULONG ( Modified[1] ),
         FT_FRAME_SHORT ( xMin ),
         FT_FRAME_SHORT ( yMin ),
         FT_FRAME_SHORT ( xMax ),
@@ -664,8 +671,8 @@
     if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
       goto Exit;
 
-    FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
-    FT_TRACE3(( "IndexToLoc:   %4d\n", header->Index_To_Loc_Format ));
+    FT_TRACE3(( "Units per EM: %4hu\n", header->Units_Per_EM ));
+    FT_TRACE3(( "IndexToLoc:   %4hd\n", header->Index_To_Loc_Format ));
 
   Exit:
     return error;
@@ -787,15 +794,15 @@
       if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
       {
         FT_TRACE0(( "tt_face_load_maxp:"
-                    " too much twilight points in `maxp' table;\n"
-                    "                  "
+                    " too much twilight points in `maxp' table;\n" ));
+        FT_TRACE0(( "                  "
                     " some glyphs might be rendered incorrectly\n" ));
 
         maxProfile->maxTwilightPoints = 0xFFFFU - 4;
       }
     }
 
-    FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
+    FT_TRACE3(( "numGlyphs: %hu\n", maxProfile->numGlyphs ));
 
   Exit:
     return error;
@@ -829,6 +836,8 @@
     FT_ULong      table_pos, table_len;
     FT_ULong      storage_start, storage_limit;
     TT_NameTable  table;
+    TT_Name       names    = NULL;
+    TT_LangTag    langTags = NULL;
 
     static const FT_Frame_Field  name_table_fields[] =
     {
@@ -909,14 +918,14 @@
       storage_start += 2 + 4 * table->numLangTagRecords;
 
       /* allocate language tag records array */
-      if ( FT_NEW_ARRAY( table->langTags, table->numLangTagRecords ) ||
-           FT_FRAME_ENTER( table->numLangTagRecords * 4 )            )
+      if ( FT_QNEW_ARRAY( langTags, table->numLangTagRecords ) ||
+           FT_FRAME_ENTER( table->numLangTagRecords * 4 )      )
         goto Exit;
 
       /* load language tags */
       {
-        TT_LangTag  entry = table->langTags;
-        TT_LangTag  limit = entry + table->numLangTagRecords;
+        TT_LangTag  entry = langTags;
+        TT_LangTag  limit = FT_OFFSET( entry, table->numLangTagRecords );
 
 
         for ( ; entry < limit; entry++ )
@@ -931,7 +940,13 @@
             /* invalid entry; ignore it */
             entry->stringLength = 0;
           }
+
+          /* mark the string as not yet loaded */
+          entry->string = NULL;
         }
+
+        table->langTags = langTags;
+        langTags        = NULL;
       }
 
       FT_FRAME_EXIT();
@@ -940,14 +955,15 @@
     }
 
     /* allocate name records array */
-    if ( FT_NEW_ARRAY( table->names, table->numNameRecords ) ||
-         FT_FRAME_ENTER( table->numNameRecords * 12 )        )
+    if ( FT_QNEW_ARRAY( names, table->numNameRecords ) ||
+         FT_FRAME_ENTER( table->numNameRecords * 12 )  )
       goto Exit;
 
     /* load name records */
     {
-      TT_Name  entry = table->names;
+      TT_Name  entry = names;
       FT_UInt  count = table->numNameRecords;
+      FT_UInt  valid = 0;
 
 
       for ( ; count > 0; count-- )
@@ -980,15 +996,20 @@
           }
         }
 
+        /* mark the string as not yet converted */
+        entry->string = NULL;
+
+        valid++;
         entry++;
       }
 
       /* reduce array size to the actually used elements */
-      count = (FT_UInt)( entry - table->names );
-      (void)FT_RENEW_ARRAY( table->names,
-                            table->numNameRecords,
-                            count );
-      table->numNameRecords = count;
+      FT_MEM_QRENEW_ARRAY( names,
+                           table->numNameRecords,
+                           valid );
+      table->names          = names;
+      names                 = NULL;
+      table->numNameRecords = valid;
     }
 
     FT_FRAME_EXIT();
@@ -997,6 +1018,8 @@
     face->num_names = (FT_UShort)table->numNameRecords;
 
   Exit:
+    FT_FREE( names );
+    FT_FREE( langTags );
     return error;
   }
 
@@ -1242,11 +1265,11 @@
       }
     }
 
-    FT_TRACE3(( "sTypoAscender:  %4d\n",   os2->sTypoAscender ));
-    FT_TRACE3(( "sTypoDescender: %4d\n",   os2->sTypoDescender ));
-    FT_TRACE3(( "usWinAscent:    %4u\n",   os2->usWinAscent ));
-    FT_TRACE3(( "usWinDescent:   %4u\n",   os2->usWinDescent ));
-    FT_TRACE3(( "fsSelection:    0x%2x\n", os2->fsSelection ));
+    FT_TRACE3(( "sTypoAscender:  %4hd\n",   os2->sTypoAscender ));
+    FT_TRACE3(( "sTypoDescender: %4hd\n",   os2->sTypoDescender ));
+    FT_TRACE3(( "usWinAscent:    %4hu\n",   os2->usWinAscent ));
+    FT_TRACE3(( "usWinDescent:   %4hu\n",   os2->usWinDescent ));
+    FT_TRACE3(( "fsSelection:    0x%2hx\n", os2->fsSelection ));
 
   Exit:
     return error;
@@ -1304,10 +1327,16 @@
     if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
       return error;
 
+    if ( post->FormatType != 0x00030000L &&
+         post->FormatType != 0x00025000L &&
+         post->FormatType != 0x00020000L &&
+         post->FormatType != 0x00010000L )
+      return FT_THROW( Invalid_Post_Table_Format );
+
     /* we don't load the glyph names, we do that in another */
     /* module (ttpost).                                     */
 
-    FT_TRACE3(( "FormatType:   0x%x\n", post->FormatType ));
+    FT_TRACE3(( "FormatType:   0x%lx\n", post->FormatType ));
     FT_TRACE3(( "isFixedPitch:   %s\n", post->isFixedPitch
                                         ? "  yes" : "   no" ));
 
@@ -1403,8 +1432,8 @@
     FT_Error   error;
     FT_Memory  memory = stream->memory;
 
-    FT_UInt        j,num_ranges;
-    TT_GaspRange   gaspranges = NULL;
+    FT_UShort      j, num_ranges;
+    TT_GaspRange   gasp_ranges = NULL;
 
 
     /* the gasp table is optional */
@@ -1415,8 +1444,8 @@
     if ( FT_FRAME_ENTER( 4L ) )
       goto Exit;
 
-    face->gasp.version   = FT_GET_USHORT();
-    face->gasp.numRanges = FT_GET_USHORT();
+    face->gasp.version = FT_GET_USHORT();
+    num_ranges         = FT_GET_USHORT();
 
     FT_FRAME_EXIT();
 
@@ -1428,29 +1457,31 @@
       goto Exit;
     }
 
-    num_ranges = face->gasp.numRanges;
-    FT_TRACE3(( "numRanges: %u\n", num_ranges ));
+    FT_TRACE3(( "numRanges: %hu\n", num_ranges ));
 
-    if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) ||
-         FT_FRAME_ENTER( num_ranges * 4L )                  )
+    if ( FT_QNEW_ARRAY( gasp_ranges, num_ranges ) ||
+         FT_FRAME_ENTER( num_ranges * 4L )        )
       goto Exit;
 
-    gaspranges = face->gasp.gaspRanges;
-
     for ( j = 0; j < num_ranges; j++ )
     {
-      gaspranges[j].maxPPEM  = FT_GET_USHORT();
-      gaspranges[j].gaspFlag = FT_GET_USHORT();
+      gasp_ranges[j].maxPPEM  = FT_GET_USHORT();
+      gasp_ranges[j].gaspFlag = FT_GET_USHORT();
 
-      FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
+      FT_TRACE3(( "gaspRange %hu: rangeMaxPPEM %5hu, rangeGaspBehavior 0x%hx\n",
                   j,
-                  gaspranges[j].maxPPEM,
-                  gaspranges[j].gaspFlag ));
+                  gasp_ranges[j].maxPPEM,
+                  gasp_ranges[j].gaspFlag ));
     }
 
+    face->gasp.gaspRanges = gasp_ranges;
+    gasp_ranges           = NULL;
+    face->gasp.numRanges  = num_ranges;
+
     FT_FRAME_EXIT();
 
   Exit:
+    FT_FREE( gasp_ranges );
     return error;
   }
 
diff --git a/src/sfnt/ttload.h b/src/sfnt/ttload.h
index 21d9cb6..1499dd5 100644
--- a/src/sfnt/ttload.h
+++ b/src/sfnt/ttload.h
@@ -5,7 +5,7 @@
  *   Load the basic TrueType tables, i.e., tables that can be either in
  *   TTF or OTF fonts (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,9 +21,8 @@
 #define TTLOAD_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/tttypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 8edf4e6..5e53e6d 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
  *
  *   Load the metrics tables common to TTF and OTF fonts (body).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,13 +16,12 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_SERVICE_METRICS_VARIATIONS_H
+#include <freetype/internal/services/svmetric.h>
 #endif
 
 #include "ttmtx.h"
@@ -45,7 +44,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttmtx
+#define FT_COMPONENT  ttmtx
 
 
   /**************************************************************************
@@ -280,7 +279,7 @@
       else
       {
         table_pos += 4 * ( k - 1 );
-        if ( table_pos + 4 > table_end )
+        if ( table_pos + 2 > table_end )
           goto NoData;
 
         if ( FT_STREAM_SEEK( table_pos ) ||
@@ -292,7 +291,9 @@
           *abearing = 0;
         else
         {
-          if ( !FT_STREAM_SEEK( table_pos ) )
+          if ( FT_STREAM_SEEK( table_pos ) )
+            *abearing = 0;
+          else
             (void)FT_READ_SHORT( *abearing );
         }
       }
@@ -305,7 +306,7 @@
     }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    if ( var )
+    if ( var && face->blend )
     {
       FT_Face  f = FT_FACE( face );
       FT_Int   a = (FT_Int)*aadvance;
diff --git a/src/sfnt/ttmtx.h b/src/sfnt/ttmtx.h
index f360b45..56d2b62 100644
--- a/src/sfnt/ttmtx.h
+++ b/src/sfnt/ttmtx.h
@@ -4,7 +4,7 @@
  *
  *   Load the metrics tables common to TTF and OTF fonts (specification).
  *
- * Copyright 2006-2018 by
+ * Copyright (C) 2006-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define TTMTX_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/tttypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 7148301..0e17c6f 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
  *   PostScript name table processing for TrueType and OpenType fonts
  *   (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,10 +25,9 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 
 
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -45,26 +44,26 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttpost
+#define FT_COMPONENT  ttpost
 
 
-  /* If this configuration macro is defined, we rely on the `PSNames' */
+  /* If this configuration macro is defined, we rely on the `psnames' */
   /* module to grab the glyph names.                                  */
 
 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
 
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+#include <freetype/internal/services/svpscmap.h>
 
 #define MAC_NAME( x )  (FT_String*)psnames->macintosh_name( (FT_UInt)(x) )
 
 
-#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+#else /* !FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
 
-   /* Otherwise, we ignore the `PSNames' module, and provide our own  */
+   /* Otherwise, we ignore the `psnames' module, and provide our own  */
    /* table of Mac names.  Thus, it is possible to build a version of */
-   /* FreeType without the Type 1 driver & PSNames module.            */
+   /* FreeType without the Type 1 driver & psnames module.            */
 
 #define MAC_NAME( x )  (FT_String*)tt_post_default_names[x]
 
@@ -153,13 +152,13 @@
   };
 
 
-#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+#endif /* !FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
 
   static FT_Error
   load_format_20( TT_Face    face,
                   FT_Stream  stream,
-                  FT_ULong   post_limit )
+                  FT_ULong   post_len )
   {
     FT_Memory   memory = stream->memory;
     FT_Error    error;
@@ -169,6 +168,7 @@
 
     FT_UShort*  glyph_indices = NULL;
     FT_Char**   name_strings  = NULL;
+    FT_Byte*    strings       = NULL;
 
 
     if ( FT_READ_USHORT( num_glyphs ) )
@@ -180,7 +180,8 @@
     /* 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 )
+    if ( num_glyphs > face->max_profile.numGlyphs  ||
+         (FT_ULong)num_glyphs * 2UL > post_len - 2 )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
@@ -191,7 +192,7 @@
       FT_Int  n;
 
 
-      if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) ||
+      if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
            FT_FRAME_ENTER( num_glyphs * 2L )          )
         goto Fail;
 
@@ -224,60 +225,56 @@
     }
 
     /* now load the name strings */
+    if ( num_names )
     {
       FT_UShort  n;
+      FT_ULong   p;
 
 
-      if ( FT_NEW_ARRAY( name_strings, num_names ) )
+      post_len -= (FT_ULong)num_glyphs * 2UL + 2;
+
+      if ( FT_QALLOC( strings, post_len + 1 )       ||
+           FT_STREAM_READ( strings, post_len )      ||
+           FT_QNEW_ARRAY( name_strings, num_names ) )
         goto Fail;
 
-      for ( n = 0; n < num_names; n++ )
+      /* convert from Pascal- to C-strings and set pointers */
+      for ( p = 0, n = 0; p < post_len && n < num_names; n++ )
       {
-        FT_UInt  len;
+        FT_UInt  len = strings[p];
 
 
-        if ( FT_STREAM_POS() >= post_limit )
-          break;
-        else
+        if ( len > 63U )
         {
-          FT_TRACE6(( "load_format_20: %d byte left in post table\n",
-                      post_limit - FT_STREAM_POS() ));
-
-          if ( FT_READ_BYTE( len ) )
-            goto Fail1;
+          error = FT_THROW( Invalid_File_Format );
+          goto Fail;
         }
 
-        if ( len > post_limit                   ||
-             FT_STREAM_POS() > post_limit - len )
-        {
-          FT_Int  d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS();
-
-
-          FT_ERROR(( "load_format_20:"
-                     " exceeding string length (%d),"
-                     " truncating at end of post table (%d byte left)\n",
-                     len, d ));
-          len = (FT_UInt)FT_MAX( 0, d );
-        }
-
-        if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) ||
-             FT_STREAM_READ( name_strings[n], len   ) )
-          goto Fail1;
-
-        name_strings[n][len] = '\0';
+        strings[p]      = 0;
+        name_strings[n] = (FT_Char*)strings + p + 1;
+        p              += len + 1;
       }
+      strings[post_len] = 0;
 
+      /* 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;
+
+          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++ )
-          if ( FT_NEW_ARRAY( name_strings[n], 1 ) )
-            goto Fail1;
-          else
-            name_strings[n][0] = '\0';
+          name_strings[n] = (FT_Char*)strings + post_len;
       }
     }
 
@@ -293,17 +290,9 @@
     }
     return FT_Err_Ok;
 
-  Fail1:
-    {
-      FT_UShort  n;
-
-
-      for ( n = 0; n < num_names; n++ )
-        FT_FREE( name_strings[n] );
-    }
-
   Fail:
     FT_FREE( name_strings );
+    FT_FREE( strings );
     FT_FREE( glyph_indices );
 
   Exit:
@@ -314,7 +303,7 @@
   static FT_Error
   load_format_25( TT_Face    face,
                   FT_Stream  stream,
-                  FT_ULong   post_limit )
+                  FT_ULong   post_len )
   {
     FT_Memory  memory = stream->memory;
     FT_Error   error;
@@ -322,7 +311,7 @@
     FT_Int     num_glyphs;
     FT_Char*   offset_table = NULL;
 
-    FT_UNUSED( post_limit );
+    FT_UNUSED( post_len );
 
 
     if ( FT_READ_USHORT( num_glyphs ) )
@@ -337,7 +326,7 @@
       goto Exit;
     }
 
-    if ( FT_NEW_ARRAY( offset_table, num_glyphs )   ||
+    if ( FT_QNEW_ARRAY( offset_table, num_glyphs )  ||
          FT_STREAM_READ( offset_table, num_glyphs ) )
       goto Fail;
 
@@ -385,7 +374,6 @@
     FT_Error   error;
     FT_Fixed   format;
     FT_ULong   post_len;
-    FT_ULong   post_limit;
 
 
     /* get a stream for the face's resource */
@@ -396,8 +384,6 @@
     if ( error )
       goto Exit;
 
-    post_limit = FT_STREAM_POS() + post_len;
-
     format = face->postscript.FormatType;
 
     /* go to beginning of subtable */
@@ -405,10 +391,10 @@
       goto Exit;
 
     /* now read postscript table */
-    if ( format == 0x00020000L )
-      error = load_format_20( face, stream, post_limit );
-    else if ( format == 0x00025000L )
-      error = load_format_25( face, stream, post_limit );
+    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 );
 
@@ -434,17 +420,19 @@
       if ( format == 0x00020000L )
       {
         TT_Post_20  table = &names->names.format_20;
-        FT_UShort   n;
 
 
         FT_FREE( table->glyph_indices );
         table->num_glyphs = 0;
 
-        for ( n = 0; n < table->num_names; n++ )
-          FT_FREE( table->glyph_names[n] );
+        if ( table->num_names )
+        {
+          table->glyph_names[0]--;
+          FT_FREE( table->glyph_names[0] );
 
-        FT_FREE( table->glyph_names );
-        table->num_names = 0;
+          FT_FREE( table->glyph_names );
+          table->num_names = 0;
+        }
       }
       else if ( format == 0x00025000L )
       {
diff --git a/src/sfnt/ttpost.h b/src/sfnt/ttpost.h
index a6f2cf2..528f1c5 100644
--- a/src/sfnt/ttpost.h
+++ b/src/sfnt/ttpost.h
@@ -5,7 +5,7 @@
  *   PostScript name table processing for TrueType and OpenType fonts
  *   (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -23,7 +23,7 @@
 
 #include <ft2build.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/tttypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 322c000..3c06955 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType embedded bitmap support (body).
  *
- * Copyright 2005-2018 by
+ * Copyright (C) 2005-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * Copyright 2013 by Google, Inc.
@@ -19,11 +19,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_BITMAP_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
+#include <freetype/ftbitmap.h>
 
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
@@ -43,7 +42,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttsbit
+#define FT_COMPONENT  ttsbit
 
 
   FT_LOCAL_DEF( FT_Error )
@@ -173,13 +172,8 @@
           goto Exit;
         }
 
-        /* we currently don't support bit 1; however, it is better to */
-        /* draw at least something...                                 */
         if ( flags == 3 )
-          FT_TRACE1(( "tt_face_load_sbit_strikes:"
-                      " sbix overlay not supported yet\n"
-                      "                          "
-                      " expect bad rendering results\n" ));
+          face->root.face_flags |= FT_FACE_FLAG_SBIX_OVERLAY;
 
         /*
          * Count the number of strikes available in the table.  We are a bit
@@ -241,8 +235,8 @@
     if ( !face->ebdt_size )
     {
       FT_TRACE2(( "tt_face_load_sbit_strikes:"
-                  " no embedded bitmap data table found;\n"
-                  "                          "
+                  " no embedded bitmap data table found;\n" ));
+      FT_TRACE2(( "                          "
                   " resetting number of strikes to zero\n" ));
       face->sbit_num_strikes = 0;
     }
@@ -346,9 +340,9 @@
           if ( metrics->ascender == 0 )
           {
             FT_TRACE2(( "tt_face_load_strike_metrics:"
-                        " sanitizing invalid ascender and descender\n"
-                        "                            "
-                        " values for strike %d (%dppem, %dppem)\n",
+                        " sanitizing invalid ascender and descender\n" ));
+            FT_TRACE2(( "                            "
+                        " values for strike %ld (%dppem, %dppem)\n",
                         strike_index,
                         metrics->x_ppem, metrics->y_ppem ));
 
@@ -375,8 +369,8 @@
         if ( metrics->height == 0 )
         {
           FT_TRACE2(( "tt_face_load_strike_metrics:"
-                      " sanitizing invalid height value\n"
-                      "                            "
+                      " sanitizing invalid height value\n" ));
+          FT_TRACE2(( "                            "
                       " for strike (%d, %d)\n",
                       metrics->x_ppem, metrics->y_ppem ));
           metrics->height    = metrics->y_ppem * 64;
@@ -391,11 +385,9 @@
 
         /* set the scale values (in 16.16 units) so advances */
         /* from the hmtx and vmtx table are scaled correctly */
-        metrics->x_scale = FT_MulDiv( metrics->x_ppem,
-                                      64 * 0x10000,
+        metrics->x_scale = FT_DivFix( metrics->x_ppem * 64,
                                       face->header.Units_Per_EM );
-        metrics->y_scale = FT_MulDiv( metrics->y_ppem,
-                                      64 * 0x10000,
+        metrics->y_scale = FT_DivFix( metrics->y_ppem * 64,
                                       face->header.Units_Per_EM );
 
         return FT_Err_Ok;
@@ -405,9 +397,9 @@
       {
         FT_Stream       stream = face->root.stream;
         FT_UInt         offset;
-        FT_UShort       upem, ppem, resolution;
+        FT_UShort       ppem, resolution;
         TT_HoriHeader  *hori;
-        FT_Pos          ppem_; /* to reduce casts */
+        FT_Fixed        scale;
 
         FT_Error  error;
         FT_Byte*  p;
@@ -430,32 +422,23 @@
 
         FT_FRAME_EXIT();
 
-        upem = face->header.Units_Per_EM;
-        hori = &face->horizontal;
-
         metrics->x_ppem = ppem;
         metrics->y_ppem = ppem;
 
-        ppem_ = (FT_Pos)ppem;
+        scale = FT_DivFix( ppem * 64, face->header.Units_Per_EM );
+        hori  = &face->horizontal;
 
-        metrics->ascender =
-          FT_MulDiv( hori->Ascender, ppem_ * 64, upem );
-        metrics->descender =
-          FT_MulDiv( hori->Descender, ppem_ * 64, upem );
-        metrics->height =
-          FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap,
-                     ppem_ * 64, upem );
-        metrics->max_advance =
-          FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem );
+        metrics->ascender    = FT_MulFix( hori->Ascender, scale );
+        metrics->descender   = FT_MulFix( hori->Descender, scale );
+        metrics->height      =
+          FT_MulFix( hori->Ascender - hori->Descender + hori->Line_Gap,
+                     scale );
+        metrics->max_advance = FT_MulFix( hori->advance_Width_Max, scale );
 
         /* set the scale values (in 16.16 units) so advances */
         /* from the hmtx and vmtx table are scaled correctly */
-        metrics->x_scale = FT_MulDiv( metrics->x_ppem,
-                                      64 * 0x10000,
-                                      face->header.Units_Per_EM );
-        metrics->y_scale = FT_MulDiv( metrics->y_ppem,
-                                      64 * 0x10000,
-                                      face->header.Units_Per_EM );
+        metrics->x_scale = scale;
+        metrics->y_scale = scale;
 
         return error;
       }
@@ -727,6 +710,9 @@
     pitch      = bitmap->pitch;
     line       = bitmap->buffer;
 
+    if ( !line )
+      goto Exit;
+
     width  = decoder->metrics->width;
     height = decoder->metrics->height;
 
@@ -1014,8 +1000,8 @@
     for ( nn = 0; nn < num_components; nn++ )
     {
       FT_UInt  gindex = FT_NEXT_USHORT( p );
-      FT_Byte  dx     = FT_NEXT_BYTE( p );
-      FT_Byte  dy     = FT_NEXT_BYTE( p );
+      FT_Char  dx     = FT_NEXT_CHAR( p );
+      FT_Char  dy     = FT_NEXT_CHAR( p );
 
 
       /* NB: a recursive call */
@@ -1207,7 +1193,7 @@
           goto Fail;
 
         p += 1;  /* skip padding */
-        /* fall-through */
+        FALL_THROUGH;
 
       case 9:
         loader = tt_sbit_decoder_load_compound;
@@ -1574,23 +1560,40 @@
 
     if ( !error )
     {
-      FT_Short   abearing;
+      FT_Short   abearing; /* not used here */
       FT_UShort  aadvance;
 
 
       tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
 
       metrics->horiBearingX = (FT_Short)originOffsetX;
-      metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
+      metrics->vertBearingX = (FT_Short)originOffsetX;
+
+      metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
+      metrics->vertBearingY = (FT_Short)originOffsetY;
+
       metrics->horiAdvance  = (FT_UShort)( aadvance *
                                            face->root.size->metrics.x_ppem /
                                            face->header.Units_Per_EM );
+
+      if ( face->vertical_info )
+        tt_face_get_metrics( face, TRUE, glyph_index, &abearing, &aadvance );
+      else if ( face->os2.version != 0xFFFFU )
+        aadvance = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
+                                      face->os2.sTypoDescender );
+      else
+        aadvance = (FT_UShort)FT_ABS( face->horizontal.Ascender -
+                                      face->horizontal.Descender );
+
+      metrics->vertAdvance  = (FT_UShort)( aadvance *
+                                           face->root.size->metrics.x_ppem /
+                                           face->header.Units_Per_EM );
     }
 
     return error;
   }
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL_DEF( FT_Error )
   tt_face_load_sbit_image( TT_Face              face,
                            FT_ULong             strike_index,
                            FT_UInt              glyph_index,
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index 99bf560..07e2db4 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
  *
  *   TrueType and OpenType embedded bitmap support (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define TTSBIT_H_
 
 
-#include <ft2build.h>
 #include "ttload.h"
 
 
diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
new file mode 100644
index 0000000..c1bbb66
--- /dev/null
+++ b/src/sfnt/ttsvg.c
@@ -0,0 +1,413 @@
+/****************************************************************************
+ *
+ * ttsvg.c
+ *
+ *   OpenType SVG Color (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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.
+ *
+ */
+
+
+  /**************************************************************************
+   *
+   * 'SVG' table specification:
+   *
+   *    https://docs.microsoft.com/en-us/typography/opentype/spec/svg
+   *
+   */
+
+#include <ft2build.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/tttags.h>
+#include <freetype/ftgzip.h>
+#include <freetype/otsvg.h>
+
+
+#ifdef FT_CONFIG_OPTION_SVG
+
+#include "ttsvg.h"
+
+
+  /* NOTE: These table sizes are given by the specification. */
+#define SVG_TABLE_HEADER_SIZE           (10U)
+#define SVG_DOCUMENT_RECORD_SIZE        (12U)
+#define SVG_DOCUMENT_LIST_MINIMUM_SIZE  (2U + SVG_DOCUMENT_RECORD_SIZE)
+#define SVG_MINIMUM_SIZE                (SVG_TABLE_HEADER_SIZE +        \
+                                         SVG_DOCUMENT_LIST_MINIMUM_SIZE)
+
+
+  typedef struct  Svg_
+  {
+    FT_UShort  version;                 /* table version (starting at 0)  */
+    FT_UShort  num_entries;             /* number of SVG document records */
+
+    FT_Byte*  svg_doc_list;  /* pointer to the start of SVG Document List */
+
+    void*     table;                          /* memory that backs up SVG */
+    FT_ULong  table_size;
+
+  } Svg;
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, usued to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  ttsvg
+
+
+  FT_LOCAL_DEF( FT_Error )
+  tt_face_load_svg( TT_Face    face,
+                    FT_Stream  stream )
+  {
+    FT_Error   error;
+    FT_Memory  memory = face->root.memory;
+
+    FT_ULong  table_size;
+    FT_Byte*  table = NULL;
+    FT_Byte*  p     = NULL;
+    Svg*      svg   = NULL;
+    FT_ULong  offsetToSVGDocumentList;
+
+
+    error = face->goto_table( face, TTAG_SVG, stream, &table_size );
+    if ( error )
+      goto NoSVG;
+
+    if ( table_size < SVG_MINIMUM_SIZE )
+      goto InvalidTable;
+
+    if ( FT_FRAME_EXTRACT( table_size, table ) )
+      goto NoSVG;
+
+    /* Allocate memory for the SVG object */
+    if ( FT_NEW( svg ) )
+      goto NoSVG;
+
+    p                       = table;
+    svg->version            = FT_NEXT_USHORT( p );
+    offsetToSVGDocumentList = FT_NEXT_ULONG( p );
+
+    if ( offsetToSVGDocumentList < SVG_TABLE_HEADER_SIZE            ||
+         offsetToSVGDocumentList > table_size -
+                                     SVG_DOCUMENT_LIST_MINIMUM_SIZE )
+      goto InvalidTable;
+
+    svg->svg_doc_list = (FT_Byte*)( table + offsetToSVGDocumentList );
+
+    p                = svg->svg_doc_list;
+    svg->num_entries = FT_NEXT_USHORT( p );
+
+    FT_TRACE3(( "version: %d\n", svg->version ));
+    FT_TRACE3(( "number of entries: %d\n", svg->num_entries ));
+
+    if ( offsetToSVGDocumentList + 2U +
+           svg->num_entries * SVG_DOCUMENT_RECORD_SIZE > table_size )
+      goto InvalidTable;
+
+    svg->table      = table;
+    svg->table_size = table_size;
+
+    face->svg              = svg;
+    face->root.face_flags |= FT_FACE_FLAG_SVG;
+
+    return FT_Err_Ok;
+
+  InvalidTable:
+    error = FT_THROW( Invalid_Table );
+
+  NoSVG:
+    FT_FRAME_RELEASE( table );
+    FT_FREE( svg );
+    face->svg = NULL;
+
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( void )
+  tt_face_free_svg( TT_Face  face )
+  {
+    FT_Memory  memory = face->root.memory;
+    FT_Stream  stream = face->root.stream;
+
+    Svg*  svg = (Svg*)face->svg;
+
+
+    if ( svg )
+    {
+      FT_FRAME_RELEASE( svg->table );
+      FT_FREE( svg );
+    }
+  }
+
+
+  typedef struct  Svg_doc_
+  {
+    FT_UShort  start_glyph_id;
+    FT_UShort  end_glyph_id;
+
+    FT_ULong  offset;
+    FT_ULong  length;
+
+  } Svg_doc;
+
+
+  static Svg_doc
+  extract_svg_doc( FT_Byte*  stream )
+  {
+    Svg_doc  doc;
+
+
+    doc.start_glyph_id = FT_NEXT_USHORT( stream );
+    doc.end_glyph_id   = FT_NEXT_USHORT( stream );
+
+    doc.offset = FT_NEXT_ULONG( stream );
+    doc.length = FT_NEXT_ULONG( stream );
+
+    return doc;
+  }
+
+
+  static FT_Int
+  compare_svg_doc( Svg_doc  doc,
+                   FT_UInt  glyph_index )
+  {
+    if ( glyph_index < doc.start_glyph_id )
+      return -1;
+    else if ( glyph_index > doc.end_glyph_id )
+      return 1;
+    else
+      return 0;
+  }
+
+
+  static FT_Error
+  find_doc( FT_Byte*    document_records,
+            FT_UShort   num_entries,
+            FT_UInt     glyph_index,
+            FT_ULong   *doc_offset,
+            FT_ULong   *doc_length,
+            FT_UShort  *start_glyph,
+            FT_UShort  *end_glyph )
+  {
+    FT_Error  error;
+
+    Svg_doc  start_doc;
+    Svg_doc  mid_doc = { 0, 0, 0, 0 }; /* pacify compiler */
+    Svg_doc  end_doc;
+
+    FT_Bool  found = FALSE;
+    FT_UInt  i     = 0;
+
+    FT_UInt  start_index = 0;
+    FT_UInt  end_index   = num_entries - 1;
+    FT_Int   comp_res;
+
+
+    /* search algorithm */
+    if ( num_entries == 0 )
+    {
+      error = FT_THROW( Invalid_Table );
+      return error;
+    }
+
+    start_doc = extract_svg_doc( document_records + start_index * 12 );
+    end_doc   = extract_svg_doc( document_records + end_index * 12 );
+
+    if ( ( compare_svg_doc( start_doc, glyph_index ) == -1 ) ||
+         ( compare_svg_doc( end_doc, glyph_index ) == 1 )    )
+    {
+      error = FT_THROW( Invalid_Glyph_Index );
+      return error;
+    }
+
+    while ( start_index <= end_index )
+    {
+      i        = ( start_index + end_index ) / 2;
+      mid_doc  = extract_svg_doc( document_records + i * 12 );
+      comp_res = compare_svg_doc( mid_doc, glyph_index );
+
+      if ( comp_res == 1 )
+      {
+        start_index = i + 1;
+        start_doc   = extract_svg_doc( document_records + start_index * 4 );
+      }
+      else if ( comp_res == -1 )
+      {
+        end_index = i - 1;
+        end_doc   = extract_svg_doc( document_records + end_index * 4 );
+      }
+      else
+      {
+        found = TRUE;
+        break;
+      }
+    }
+    /* search algorithm end */
+
+    if ( found != TRUE )
+    {
+      FT_TRACE5(( "SVG glyph not found\n" ));
+      error = FT_THROW( Invalid_Glyph_Index );
+    }
+    else
+    {
+      *doc_offset = mid_doc.offset;
+      *doc_length = mid_doc.length;
+
+      *start_glyph = mid_doc.start_glyph_id;
+      *end_glyph   = mid_doc.end_glyph_id;
+
+      error = FT_Err_Ok;
+    }
+
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  tt_face_load_svg_doc( FT_GlyphSlot  glyph,
+                        FT_UInt       glyph_index )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    TT_Face    face   = (TT_Face)glyph->face;
+    FT_Memory  memory = face->root.memory;
+    Svg*       svg    = (Svg*)face->svg;
+
+    FT_Byte*  doc_list;
+    FT_ULong  doc_limit;
+
+    FT_Byte*   doc;
+    FT_ULong   doc_offset;
+    FT_ULong   doc_length;
+    FT_UShort  doc_start_glyph_id;
+    FT_UShort  doc_end_glyph_id;
+
+    FT_SVG_Document  svg_document = (FT_SVG_Document)glyph->other;
+
+
+    FT_ASSERT( !( svg == NULL ) );
+
+    doc_list = svg->svg_doc_list;
+
+    error = find_doc( doc_list + 2, svg->num_entries, glyph_index,
+                                    &doc_offset, &doc_length,
+                                    &doc_start_glyph_id, &doc_end_glyph_id );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    doc_limit = svg->table_size -
+                  (FT_ULong)( doc_list - (FT_Byte*)svg->table );
+    if ( doc_offset > doc_limit              ||
+         doc_length > doc_limit - doc_offset )
+    {
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    doc = doc_list + doc_offset;
+
+    if ( doc_length > 6 &&
+         doc[0] == 0x1F &&
+         doc[1] == 0x8B &&
+         doc[2] == 0x08 )
+    {
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
+      FT_ULong  uncomp_size;
+      FT_Byte*  uncomp_buffer = NULL;
+
+
+      /*
+       * Get the size of the original document.  This helps in allotting the
+       * buffer to accommodate the uncompressed version.  The last 4 bytes
+       * of the compressed document are equal to the original size modulo
+       * 2^32.  Since the size of SVG documents is less than 2^32 bytes we
+       * can use this accurately.  The four bytes are stored in
+       * little-endian format.
+       */
+      FT_TRACE4(( "SVG document is GZIP compressed\n" ));
+      uncomp_size = (FT_ULong)doc[doc_length - 1] << 24 |
+                    (FT_ULong)doc[doc_length - 2] << 16 |
+                    (FT_ULong)doc[doc_length - 3] << 8  |
+                    (FT_ULong)doc[doc_length - 4];
+
+      if ( FT_QALLOC( uncomp_buffer, uncomp_size ) )
+        goto Exit;
+
+      error = FT_Gzip_Uncompress( memory,
+                                  uncomp_buffer,
+                                  &uncomp_size,
+                                  doc,
+                                  doc_length );
+      if ( error )
+      {
+        FT_FREE( uncomp_buffer );
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      glyph->internal->flags |= FT_GLYPH_OWN_GZIP_SVG;
+
+      doc        = uncomp_buffer;
+      doc_length = uncomp_size;
+
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+      error = FT_THROW( Unimplemented_Feature );
+      goto Exit;
+
+#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
+    }
+
+    svg_document->svg_document        = doc;
+    svg_document->svg_document_length = doc_length;
+
+    svg_document->metrics      = glyph->face->size->metrics;
+    svg_document->units_per_EM = glyph->face->units_per_EM;
+
+    svg_document->start_glyph_id = doc_start_glyph_id;
+    svg_document->end_glyph_id   = doc_end_glyph_id;
+
+    svg_document->transform.xx = 0x10000;
+    svg_document->transform.xy = 0;
+    svg_document->transform.yx = 0;
+    svg_document->transform.yy = 0x10000;
+
+    svg_document->delta.x = 0;
+    svg_document->delta.y = 0;
+
+    FT_TRACE5(( "start_glyph_id: %d\n", doc_start_glyph_id ));
+    FT_TRACE5(( "end_glyph_id:   %d\n", doc_end_glyph_id ));
+    FT_TRACE5(( "svg_document:\n" ));
+    FT_TRACE5(( " %.*s\n", (FT_UInt)doc_length, doc ));
+
+    glyph->other = svg_document;
+
+  Exit:
+    return error;
+  }
+
+#else /* !FT_CONFIG_OPTION_SVG */
+
+  /* ANSI C doesn't like empty source files */
+  typedef int  _tt_svg_dummy;
+
+#endif /* !FT_CONFIG_OPTION_SVG */
+
+
+/* END */
diff --git a/src/sfnt/ttsvg.h b/src/sfnt/ttsvg.h
new file mode 100644
index 0000000..3f32321
--- /dev/null
+++ b/src/sfnt/ttsvg.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ *
+ * ttsvg.h
+ *
+ *   OpenType SVG Color (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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 TTSVG_H_
+#define TTSVG_H_
+
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/tttypes.h>
+
+
+FT_BEGIN_HEADER
+
+  FT_LOCAL( FT_Error )
+  tt_face_load_svg( TT_Face    face,
+                    FT_Stream  stream );
+
+  FT_LOCAL( void )
+  tt_face_free_svg( TT_Face  face );
+
+  FT_LOCAL( FT_Error )
+  tt_face_load_svg_doc( FT_GlyphSlot  glyph,
+                        FT_UInt       glyph_index );
+
+FT_END_HEADER
+
+#endif /* TTSVG_H_ */
+
+
+/* END */
diff --git a/src/sfnt/woff2tags.c b/src/sfnt/woff2tags.c
new file mode 100644
index 0000000..7a0a351
--- /dev/null
+++ b/src/sfnt/woff2tags.c
@@ -0,0 +1,119 @@
+/****************************************************************************
+ *
+ * woff2tags.c
+ *
+ *   WOFF2 Font table tags (base).
+ *
+ * Copyright (C) 2019-2023 by
+ * Nikhil Ramakrishnan, 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/tttags.h>
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+#include "woff2tags.h"
+
+  /*
+   * Return tag from index in the order given in WOFF2 specification.
+   *
+   * See
+   *
+   *       https://www.w3.org/TR/WOFF2/#table_dir_format
+   *
+   * for details.
+   */
+  FT_LOCAL_DEF( FT_Tag )
+  woff2_known_tags( FT_Byte  index )
+  {
+    static const FT_Tag  known_tags[63] =
+    {
+      FT_MAKE_TAG('c', 'm', 'a', 'p'),  /*  0  */
+      FT_MAKE_TAG('h', 'e', 'a', 'd'),  /*  1  */
+      FT_MAKE_TAG('h', 'h', 'e', 'a'),  /*  2  */
+      FT_MAKE_TAG('h', 'm', 't', 'x'),  /*  3  */
+      FT_MAKE_TAG('m', 'a', 'x', 'p'),  /*  4  */
+      FT_MAKE_TAG('n', 'a', 'm', 'e'),  /*  5  */
+      FT_MAKE_TAG('O', 'S', '/', '2'),  /*  6  */
+      FT_MAKE_TAG('p', 'o', 's', 't'),  /*  7  */
+      FT_MAKE_TAG('c', 'v', 't', ' '),  /*  8  */
+      FT_MAKE_TAG('f', 'p', 'g', 'm'),  /*  9  */
+      FT_MAKE_TAG('g', 'l', 'y', 'f'),  /*  10 */
+      FT_MAKE_TAG('l', 'o', 'c', 'a'),  /*  11 */
+      FT_MAKE_TAG('p', 'r', 'e', 'p'),  /*  12 */
+      FT_MAKE_TAG('C', 'F', 'F', ' '),  /*  13 */
+      FT_MAKE_TAG('V', 'O', 'R', 'G'),  /*  14 */
+      FT_MAKE_TAG('E', 'B', 'D', 'T'),  /*  15 */
+      FT_MAKE_TAG('E', 'B', 'L', 'C'),  /*  16 */
+      FT_MAKE_TAG('g', 'a', 's', 'p'),  /*  17 */
+      FT_MAKE_TAG('h', 'd', 'm', 'x'),  /*  18 */
+      FT_MAKE_TAG('k', 'e', 'r', 'n'),  /*  19 */
+      FT_MAKE_TAG('L', 'T', 'S', 'H'),  /*  20 */
+      FT_MAKE_TAG('P', 'C', 'L', 'T'),  /*  21 */
+      FT_MAKE_TAG('V', 'D', 'M', 'X'),  /*  22 */
+      FT_MAKE_TAG('v', 'h', 'e', 'a'),  /*  23 */
+      FT_MAKE_TAG('v', 'm', 't', 'x'),  /*  24 */
+      FT_MAKE_TAG('B', 'A', 'S', 'E'),  /*  25 */
+      FT_MAKE_TAG('G', 'D', 'E', 'F'),  /*  26 */
+      FT_MAKE_TAG('G', 'P', 'O', 'S'),  /*  27 */
+      FT_MAKE_TAG('G', 'S', 'U', 'B'),  /*  28 */
+      FT_MAKE_TAG('E', 'B', 'S', 'C'),  /*  29 */
+      FT_MAKE_TAG('J', 'S', 'T', 'F'),  /*  30 */
+      FT_MAKE_TAG('M', 'A', 'T', 'H'),  /*  31 */
+      FT_MAKE_TAG('C', 'B', 'D', 'T'),  /*  32 */
+      FT_MAKE_TAG('C', 'B', 'L', 'C'),  /*  33 */
+      FT_MAKE_TAG('C', 'O', 'L', 'R'),  /*  34 */
+      FT_MAKE_TAG('C', 'P', 'A', 'L'),  /*  35 */
+      FT_MAKE_TAG('S', 'V', 'G', ' '),  /*  36 */
+      FT_MAKE_TAG('s', 'b', 'i', 'x'),  /*  37 */
+      FT_MAKE_TAG('a', 'c', 'n', 't'),  /*  38 */
+      FT_MAKE_TAG('a', 'v', 'a', 'r'),  /*  39 */
+      FT_MAKE_TAG('b', 'd', 'a', 't'),  /*  40 */
+      FT_MAKE_TAG('b', 'l', 'o', 'c'),  /*  41 */
+      FT_MAKE_TAG('b', 's', 'l', 'n'),  /*  42 */
+      FT_MAKE_TAG('c', 'v', 'a', 'r'),  /*  43 */
+      FT_MAKE_TAG('f', 'd', 's', 'c'),  /*  44 */
+      FT_MAKE_TAG('f', 'e', 'a', 't'),  /*  45 */
+      FT_MAKE_TAG('f', 'm', 't', 'x'),  /*  46 */
+      FT_MAKE_TAG('f', 'v', 'a', 'r'),  /*  47 */
+      FT_MAKE_TAG('g', 'v', 'a', 'r'),  /*  48 */
+      FT_MAKE_TAG('h', 's', 't', 'y'),  /*  49 */
+      FT_MAKE_TAG('j', 'u', 's', 't'),  /*  50 */
+      FT_MAKE_TAG('l', 'c', 'a', 'r'),  /*  51 */
+      FT_MAKE_TAG('m', 'o', 'r', 't'),  /*  52 */
+      FT_MAKE_TAG('m', 'o', 'r', 'x'),  /*  53 */
+      FT_MAKE_TAG('o', 'p', 'b', 'd'),  /*  54 */
+      FT_MAKE_TAG('p', 'r', 'o', 'p'),  /*  55 */
+      FT_MAKE_TAG('t', 'r', 'a', 'k'),  /*  56 */
+      FT_MAKE_TAG('Z', 'a', 'p', 'f'),  /*  57 */
+      FT_MAKE_TAG('S', 'i', 'l', 'f'),  /*  58 */
+      FT_MAKE_TAG('G', 'l', 'a', 't'),  /*  59 */
+      FT_MAKE_TAG('G', 'l', 'o', 'c'),  /*  60 */
+      FT_MAKE_TAG('F', 'e', 'a', 't'),  /*  61 */
+      FT_MAKE_TAG('S', 'i', 'l', 'l'),  /*  62 */
+    };
+
+
+    if ( index > 62 )
+      return 0;
+
+    return known_tags[index];
+  }
+
+#else /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+  /* ANSI C doesn't like empty source files */
+  typedef int  _woff2tags_dummy;
+
+#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+
+/* END */
diff --git a/src/sfnt/woff2tags.h b/src/sfnt/woff2tags.h
new file mode 100644
index 0000000..1201848
--- /dev/null
+++ b/src/sfnt/woff2tags.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ *
+ * woff2tags.h
+ *
+ *   WOFF2 Font table tags (specification).
+ *
+ * Copyright (C) 2019-2023 by
+ * Nikhil Ramakrishnan, 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 WOFF2TAGS_H
+#define WOFF2TAGS_H
+
+
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/compiler-macros.h>
+
+
+FT_BEGIN_HEADER
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+  FT_LOCAL( FT_Tag )
+  woff2_known_tags( FT_Byte  index );
+
+#endif
+
+FT_END_HEADER
+
+#endif /* WOFF2TAGS_H */
+
+
+/* END */
diff --git a/src/smooth/Jamfile b/src/smooth/Jamfile
deleted file mode 100644
index 9957d5e..0000000
--- a/src/smooth/Jamfile
+++ /dev/null
@@ -1,32 +0,0 @@
-# FreeType 2 src/smooth Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) smooth ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = ftgrays
-               ftsmooth
-               ftspic
-               ;
-  }
-  else
-  {
-    _sources = smooth ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/smooth Jamfile
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 8f2a600..d9f20ee 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
  *
  *   A new `perfect' anti-aliasing renderer (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -45,10 +45,10 @@
    * This is a new anti-aliasing scan-converter for FreeType 2.  The
    * algorithm used here is _very_ different from the one in the standard
    * `ftraster' module.  Actually, `ftgrays' computes the _exact_
-   * coverage of the outline on each pixel cell.
+   * coverage of the outline on each pixel cell by straight segments.
    *
    * It is based on ideas that I initially found in Raph Levien's
-   * excellent LibArt graphics library (see http://www.levien.com/libart
+   * excellent LibArt graphics library (see https://www.levien.com/libart
    * for more information, though the web pages do not tell anything
    * about the renderer; you'll have to dive into the source code to
    * understand how it works).
@@ -58,6 +58,14 @@
    * different way, and I don't use sorted vector paths.  Also, it doesn't
    * use floating point values.
    *
+   * Bézier segments are flattened by splitting them until their deviation
+   * from straight line becomes much smaller than a pixel.  Therefore, the
+   * pixel coverage by a Bézier curve is calculated approximately.  To
+   * estimate the deviation, we use the distance from the control point
+   * to the conic chord centre or the cubic chord trisection.  These
+   * distances vanish fast after each split.  In the conic case, they vanish
+   * predictably and the number of necessary splits can be calculated.
+   *
    * This renderer has the following advantages:
    *
    * - It doesn't need an intermediate bitmap.  Instead, one can supply a
@@ -67,7 +75,7 @@
    *   callback.
    *
    * - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on
-   *   each pixel cell.
+   *   each pixel cell by straight segments.
    *
    * - It performs a single pass on the outline (the `standard' FT2
    *   renderer makes two passes).
@@ -75,7 +83,7 @@
    * - It can easily be modified to render to _any_ number of gray levels
    *   cheaply.
    *
-   * - For small (< 20) pixel sizes, it is faster than the standard
+   * - For small (< 80) pixel sizes, it is faster than the standard
    *   renderer.
    *
    */
@@ -88,7 +96,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_smooth
+#define FT_COMPONENT  smooth
 
 
 #ifdef STANDALONE_
@@ -141,14 +149,10 @@
 #define FT_INT_MAX    INT_MAX
 #define FT_ULONG_MAX  ULONG_MAX
 
-#define ADD_LONG( a, b )                                    \
-          (long)( (unsigned long)(a) + (unsigned long)(b) )
-#define SUB_LONG( a, b )                                    \
-          (long)( (unsigned long)(a) - (unsigned long)(b) )
-#define MUL_LONG( a, b )                                    \
-          (long)( (unsigned long)(a) * (unsigned long)(b) )
-#define NEG_LONG( a )                                       \
-          (long)( -(unsigned long)(a) )
+#define ADD_INT( a, b )                                  \
+          (int)( (unsigned int)(a) + (unsigned int)(b) )
+
+#define FT_STATIC_BYTE_CAST( type, var )  (type)(unsigned char)(var)
 
 
 #define ft_memset   memset
@@ -160,10 +164,11 @@
 typedef ptrdiff_t  FT_PtrDist;
 
 
-#define ErrRaster_Invalid_Mode      -2
-#define ErrRaster_Invalid_Outline   -1
-#define ErrRaster_Invalid_Argument  -3
-#define ErrRaster_Memory_Overflow   -4
+#define Smooth_Err_Ok                    0
+#define Smooth_Err_Invalid_Outline      -1
+#define Smooth_Err_Cannot_Render_Glyph  -2
+#define Smooth_Err_Invalid_Argument     -3
+#define Smooth_Err_Raster_Overflow      -4
 
 #define FT_BEGIN_HEADER
 #define FT_END_HEADER
@@ -221,23 +226,26 @@
 #define FT_ERROR( varformat )   FT_Message varformat
 #endif
 
-#define FT_THROW( e )                               \
-          ( FT_Throw( FT_ERR_CAT( ErrRaster, e ),   \
-                      __LINE__,                     \
-                      __FILE__ )                  | \
-            FT_ERR_CAT( ErrRaster, e )            )
+#define FT_THROW( e )                                \
+          ( FT_Throw( FT_ERR_CAT( Smooth_Err_, e ),  \
+                      __LINE__,                      \
+                      __FILE__ )                   | \
+            FT_ERR_CAT( Smooth_Err_, e )           )
 
 #else /* !FT_DEBUG_LEVEL_TRACE */
 
 #define FT_TRACE5( x )  do { } while ( 0 )     /* nothing */
 #define FT_TRACE7( x )  do { } while ( 0 )     /* nothing */
 #define FT_ERROR( x )   do { } while ( 0 )     /* nothing */
-#define FT_THROW( e )   FT_ERR_CAT( ErrRaster_, e )
-
+#define FT_THROW( e )   FT_ERR_CAT( Smooth_Err_, e )
 
 #endif /* !FT_DEBUG_LEVEL_TRACE */
 
 
+#define FT_Trace_Enable()   do { } while ( 0 )  /* nothing */
+#define FT_Trace_Disable()  do { } while ( 0 )  /* nothing */
+
+
 #define FT_DEFINE_OUTLINE_FUNCS( class_,               \
                                  move_to_, line_to_,   \
                                  conic_to_, cubic_to_, \
@@ -271,18 +279,15 @@
 
 
 #include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
 #include "ftgrays.h"
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_OUTLINE_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/ftoutln.h>
 
 #include "ftsmerrs.h"
 
-#define Smooth_Err_Invalid_Mode     Smooth_Err_Cannot_Render_Glyph
-#define Smooth_Err_Memory_Overflow  Smooth_Err_Out_Of_Memory
-#define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory
-
 
 #endif /* !STANDALONE_ */
 
@@ -327,17 +332,11 @@
   /* must be at least 6 bits! */
 #define PIXEL_BITS  8
 
-#undef FLOOR
-#undef CEILING
-#undef TRUNC
-#undef SCALED
-
 #define ONE_PIXEL       ( 1 << PIXEL_BITS )
-#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
-#define SUBPIXELS( x )  ( (TPos)(x) * ONE_PIXEL )
-#define FLOOR( x )      ( (x) & -ONE_PIXEL )
-#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
-#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
+#undef TRUNC
+#define TRUNC( x )      (TCoord)( (x) >> PIXEL_BITS )
+#undef FRACT
+#define FRACT( x )      (TCoord)( (x) & ( ONE_PIXEL - 1 ) )
 
 #if PIXEL_BITS >= 6
 #define UPSCALE( x )    ( (x) * ( ONE_PIXEL >> 6 ) )
@@ -363,7 +362,7 @@
     }                                                              \
   FT_END_STMNT
 
-#ifdef  __arm__
+#if defined( __GNUC__ ) && __GNUC__ < 7 && defined( __arm__ )
   /* Work around a bug specific to GCC which make the compiler fail to */
   /* optimize a division and modulo operation on the same parameters   */
   /* into a single call to `__aeabi_idivmod'.  See                     */
@@ -383,14 +382,58 @@
 #endif /* __arm__ */
 
 
-  /* These macros speed up repetitive divisions by replacing them */
-  /* with multiplications and right shifts.                       */
-#define FT_UDIVPREP( c, b )                                        \
-  long  b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \
-                    : 0
-#define FT_UDIV( a, b )                                        \
-  ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >>   \
-    ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
+  /* Calculating coverages for a slanted line requires a division each */
+  /* time the line crosses from cell to cell.  These macros speed up   */
+  /* the repetitive divisions by replacing them with multiplications   */
+  /* and right shifts so that at most two divisions are performed for  */
+  /* each slanted line.  Nevertheless, these divisions are noticeable  */
+  /* in the overall performance because flattened curves produce a     */
+  /* very large number of slanted lines.                               */
+  /*                                                                   */
+  /* The division results here are always within ONE_PIXEL.  Therefore */
+  /* the shift magnitude should be at least PIXEL_BITS wider than the  */
+  /* divisors to provide sufficient accuracy of the multiply-shift.    */
+  /* It should not exceed (64 - PIXEL_BITS) to prevent overflowing and */
+  /* leave enough room for 64-bit unsigned multiplication however.     */
+#define FT_UDIVPREP( c, b )                                \
+  FT_Int64  b ## _r = c ? (FT_Int64)0xFFFFFFFF / ( b ) : 0
+#define FT_UDIV( a, b )                                           \
+  (TCoord)( ( (FT_UInt64)( a ) * (FT_UInt64)( b ## _r ) ) >> 32 )
+
+
+  /* Scale area and apply fill rule to calculate the coverage byte. */
+  /* The top fill bit is used for the non-zero rule. The eighth     */
+  /* fill bit is used for the even-odd rule.  The higher coverage   */
+  /* bytes are either clamped for the non-zero-rule or discarded    */
+  /* later for the even-odd rule.                                   */
+#define FT_FILL_RULE( coverage, area, fill )                \
+  FT_BEGIN_STMNT                                            \
+    coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); \
+    if ( coverage & fill )                                  \
+      coverage = ~coverage;                                 \
+    if ( coverage > 255 && fill & INT_MIN )                 \
+      coverage = 255;                                       \
+  FT_END_STMNT
+
+
+  /* It is faster to write small spans byte-by-byte than calling     */
+  /* `memset'.  This is mainly due to the cost of the function call. */
+#define FT_GRAY_SET( d, s, count )                   \
+  FT_BEGIN_STMNT                                     \
+    unsigned char* q = d;                            \
+    switch ( count )                                 \
+    {                                                \
+      case 7: *q++ = (unsigned char)s; FALL_THROUGH; \
+      case 6: *q++ = (unsigned char)s; FALL_THROUGH; \
+      case 5: *q++ = (unsigned char)s; FALL_THROUGH; \
+      case 4: *q++ = (unsigned char)s; FALL_THROUGH; \
+      case 3: *q++ = (unsigned char)s; FALL_THROUGH; \
+      case 2: *q++ = (unsigned char)s; FALL_THROUGH; \
+      case 1: *q   = (unsigned char)s; FALL_THROUGH; \
+      case 0: break;                                 \
+      default: FT_MEM_SET( d, s, count );            \
+    }                                                \
+  FT_END_STMNT
 
 
   /**************************************************************************
@@ -432,6 +475,9 @@
 #define FT_MAX_GRAY_POOL  ( 2048 / sizeof ( TCell ) )
 #endif
 
+  /* FT_Span buffer size for direct rendering only */
+#define FT_MAX_GRAY_SPANS  16
+
 
 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
   /* We disable the warning `structure was padded due to   */
@@ -445,23 +491,21 @@
   {
     ft_jmp_buf  jump_buffer;
 
-    TCoord  ex, ey;
-    TCoord  min_ex, max_ex;
+    TCoord  min_ex, max_ex;  /* min and max integer pixel coordinates */
     TCoord  min_ey, max_ey;
+    TCoord  count_ey;        /* same as (max_ey - min_ey) */
 
-    TArea   area;
-    TCoord  cover;
-    int     invalid;
+    PCell       cell;        /* current cell                             */
+    PCell       cell_free;   /* call allocation next free slot           */
+    PCell       cell_null;   /* last cell, used as dumpster and limit    */
 
-    PCell*      ycells;
-    PCell       cells;
-    FT_PtrDist  max_cells;
-    FT_PtrDist  num_cells;
+    PCell*      ycells;      /* array of cell linked-lists; one per      */
+                             /* vertical coordinate in the current band  */
 
-    TPos    x,  y;
+    TPos        x,  y;       /* last point position */
 
-    FT_Outline  outline;
-    TPixmap     target;
+    FT_Outline  outline;     /* input outline */
+    TPixmap     target;      /* target pixmap */
 
     FT_Raster_Span_Func  render_span;
     void*                render_span_data;
@@ -472,17 +516,25 @@
 #pragma warning( pop )
 #endif
 
-
 #ifndef FT_STATIC_RASTER
 #define ras  (*worker)
 #else
   static gray_TWorker  ras;
 #endif
 
+  /* The |x| value of the null cell.  Must be the largest possible */
+  /* integer value stored in a `TCell.x` field.                    */
+#define CELL_MAX_X_VALUE    INT_MAX
+
+
+#define FT_INTEGRATE( ras, a, b )                                       \
+          ras.cell->cover = ADD_INT( ras.cell->cover, a ),              \
+          ras.cell->area  = ADD_INT( ras.cell->area, (a) * (TArea)(b) )
+
 
   typedef struct gray_TRaster_
   {
-    void*         memory;
+    void*  memory;
 
   } gray_TRaster, *gray_PRaster;
 
@@ -504,7 +556,7 @@
 
       printf( "%3d:", y );
 
-      for ( ; cell != NULL; cell = cell->next )
+      for ( ; cell != ras.cell_null; cell = cell->next )
         printf( " (%3d, c:%4d, a:%6d)",
                 cell->x, cell->cover, cell->area );
       printf( "\n" );
@@ -516,60 +568,15 @@
 
   /**************************************************************************
    *
-   * Record the current cell in the table.
-   */
-  static void
-  gray_record_cell( RAS_ARG )
-  {
-    PCell  *pcell, cell;
-    TCoord  x = ras.ex;
-
-
-    pcell = &ras.ycells[ras.ey - ras.min_ey];
-    for (;;)
-    {
-      cell = *pcell;
-      if ( !cell || cell->x > x )
-        break;
-
-      if ( cell->x == x )
-        goto Found;
-
-      pcell = &cell->next;
-    }
-
-    if ( ras.num_cells >= ras.max_cells )
-      ft_longjmp( ras.jump_buffer, 1 );
-
-    /* insert new cell */
-    cell        = ras.cells + ras.num_cells++;
-    cell->x     = x;
-    cell->area  = ras.area;
-    cell->cover = ras.cover;
-
-    cell->next  = *pcell;
-    *pcell      = cell;
-
-    return;
-
-  Found:
-    /* update old cell */
-    cell->area  += ras.area;
-    cell->cover += ras.cover;
-  }
-
-
-  /**************************************************************************
-   *
    * Set the current cell to a new position.
    */
   static void
   gray_set_cell( RAS_ARG_ TCoord  ex,
                           TCoord  ey )
   {
-    /* Move the cell pointer to a new position.  We set the `invalid'      */
-    /* flag to indicate that the cell isn't part of those we're interested */
-    /* in during the render phase.  This means that:                       */
+    /* Move the cell pointer to a new position in the linked list. We use  */
+    /* a dumpster null cell for everything outside of the clipping region  */
+    /* during the render phase.  This means that:                          */
     /*                                                                     */
     /* . the new vertical position must be within min_ey..max_ey-1.        */
     /* . the new horizontal position must be strictly less than max_ex     */
@@ -577,24 +584,51 @@
     /* Note that if a cell is to the left of the clipping region, it is    */
     /* actually set to the (min_ex-1) horizontal position.                 */
 
-    if ( ex < ras.min_ex )
-      ex = ras.min_ex - 1;
+    TCoord  ey_index = ey - ras.min_ey;
 
-    /* record the current one if it is valid and substantial */
-    if ( !ras.invalid && ( ras.area || ras.cover ) )
-      gray_record_cell( RAS_VAR );
 
-    ras.area  = 0;
-    ras.cover = 0;
-    ras.ex    = ex;
-    ras.ey    = ey;
+    if ( ey_index < 0 || ey_index >= ras.count_ey || ex >= ras.max_ex )
+      ras.cell = ras.cell_null;
+    else
+    {
+      PCell*  pcell = ras.ycells + ey_index;
+      PCell   cell;
 
-    ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
-                    ex >= ras.max_ex );
+
+      ex = FT_MAX( ex, ras.min_ex - 1 );
+
+      while ( 1 )
+      {
+        cell = *pcell;
+
+        if ( cell->x > ex )
+          break;
+
+        if ( cell->x == ex )
+          goto Found;
+
+        pcell = &cell->next;
+      }
+
+      /* insert new cell */
+      cell = ras.cell_free++;
+      if ( cell >= ras.cell_null )
+        ft_longjmp( ras.jump_buffer, 1 );
+
+      cell->x     = ex;
+      cell->area  = 0;
+      cell->cover = 0;
+
+      cell->next  = *pcell;
+      *pcell      = cell;
+
+    Found:
+      ras.cell = cell;
+    }
   }
 
 
-#ifndef FT_LONG64
+#ifndef FT_INT64
 
   /**************************************************************************
    *
@@ -622,8 +656,8 @@
       return;
     }
 
-    fx1   = (TCoord)( x1 - SUBPIXELS( ex1 ) );
-    fx2   = (TCoord)( x2 - SUBPIXELS( ex2 ) );
+    fx1 = FRACT( x1 );
+    fx2 = FRACT( x2 );
 
     /* everything is located in a single cell.  That is easy! */
     /*                                                        */
@@ -650,12 +684,14 @@
       dx    = -dx;
     }
 
+    /* the fractional part of y-delta is mod/dx. It is essential to */
+    /* keep track of its accumulation for accurate rendering.       */
+    /* XXX: y-delta and x-delta below should be related.            */
     FT_DIV_MOD( TCoord, p, dx, delta, mod );
 
-    ras.area  += (TArea)( ( fx1 + first ) * delta );
-    ras.cover += delta;
-    y1        += delta;
-    ex1       += incr;
+    FT_INTEGRATE( ras, delta, fx1 + first );
+    y1  += delta;
+    ex1 += incr;
     gray_set_cell( RAS_VAR_ ex1, ey );
 
     if ( ex1 != ex2 )
@@ -676,10 +712,9 @@
           delta++;
         }
 
-        ras.area  += (TArea)( ONE_PIXEL * delta );
-        ras.cover += delta;
-        y1        += delta;
-        ex1       += incr;
+        FT_INTEGRATE( ras, delta, ONE_PIXEL );
+        y1  += delta;
+        ex1 += incr;
         gray_set_cell( RAS_VAR_ ex1, ey );
       } while ( ex1 != ex2 );
     }
@@ -687,10 +722,7 @@
     fx1 = ONE_PIXEL - first;
 
   End:
-    dy = y2 - y1;
-
-    ras.area  += (TArea)( ( fx1 + fx2 ) * dy );
-    ras.cover += dy;
+    FT_INTEGRATE( ras, y2 - y1, fx1 + fx2 );
   }
 
 
@@ -715,8 +747,8 @@
          ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
       goto End;
 
-    fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
-    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
+    fy1 = FRACT( ras.y );
+    fy2 = FRACT( to_y );
 
     /* everything is on a single scanline */
     if ( ey1 == ey2 )
@@ -732,8 +764,7 @@
     if ( dx == 0 )
     {
       TCoord  ex     = TRUNC( ras.x );
-      TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
-      TArea   area;
+      TCoord  two_fx = FRACT( ras.x ) << 1;
 
 
       if ( dy > 0)
@@ -747,27 +778,23 @@
         incr  = -1;
       }
 
-      delta      = first - fy1;
-      ras.area  += (TArea)two_fx * delta;
-      ras.cover += delta;
-      ey1       += incr;
+      delta = first - fy1;
+      FT_INTEGRATE( ras, delta, two_fx);
+      ey1 += incr;
 
       gray_set_cell( RAS_VAR_ ex, ey1 );
 
       delta = first + first - ONE_PIXEL;
-      area  = (TArea)two_fx * delta;
       while ( ey1 != ey2 )
       {
-        ras.area  += area;
-        ras.cover += delta;
-        ey1       += incr;
+        FT_INTEGRATE( ras, delta, two_fx);
+        ey1 += incr;
 
         gray_set_cell( RAS_VAR_ ex, ey1 );
       }
 
-      delta      = fy2 - ONE_PIXEL + first;
-      ras.area  += (TArea)two_fx * delta;
-      ras.cover += delta;
+      delta = fy2 - ONE_PIXEL + first;
+      FT_INTEGRATE( ras, delta, two_fx);
 
       goto End;
     }
@@ -787,6 +814,8 @@
       dy    = -dy;
     }
 
+    /* the fractional part of x-delta is mod/dy. It is essential to */
+    /* keep track of its accumulation for accurate rendering.       */
     FT_DIV_MOD( TCoord, p, dy, delta, mod );
 
     x = ras.x + delta;
@@ -843,8 +872,9 @@
   gray_render_line( RAS_ARG_ TPos  to_x,
                              TPos  to_y )
   {
-    TPos    dx, dy, fx1, fy1, fx2, fy2;
-    TCoord  ex1, ex2, ey1, ey2;
+    TPos    dx, dy;
+    TCoord  fx1, fy1, fx2, fy2;
+    TCoord  ex1, ey1, ex2, ey2;
 
 
     ey1 = TRUNC( ras.y );
@@ -858,8 +888,8 @@
     ex1 = TRUNC( ras.x );
     ex2 = TRUNC( to_x );
 
-    fx1 = ras.x - SUBPIXELS( ex1 );
-    fy1 = ras.y - SUBPIXELS( ey1 );
+    fx1 = FRACT( ras.x );
+    fy1 = FRACT( ras.y );
 
     dx = to_x - ras.x;
     dy = to_y - ras.y;
@@ -868,8 +898,8 @@
       ;
     else if ( dy == 0 ) /* ex1 != ex2 */  /* any horizontal line */
     {
-      ex1 = ex2;
-      gray_set_cell( RAS_VAR_ ex1, ey1 );
+      gray_set_cell( RAS_VAR_ ex2, ey2 );
+      goto End;
     }
     else if ( dx == 0 )
     {
@@ -877,8 +907,7 @@
         do
         {
           fy2 = ONE_PIXEL;
-          ras.cover += ( fy2 - fy1 );
-          ras.area  += ( fy2 - fy1 ) * fx1 * 2;
+          FT_INTEGRATE( ras, fy2 - fy1, fx1 * 2 );
           fy1 = 0;
           ey1++;
           gray_set_cell( RAS_VAR_ ex1, ey1 );
@@ -887,8 +916,7 @@
         do
         {
           fy2 = 0;
-          ras.cover += ( fy2 - fy1 );
-          ras.area  += ( fy2 - fy1 ) * fx1 * 2;
+          FT_INTEGRATE( ras, fy2 - fy1, fx1 * 2 );
           fy1 = ONE_PIXEL;
           ey1--;
           gray_set_cell( RAS_VAR_ ex1, ey1 );
@@ -896,7 +924,7 @@
     }
     else                                  /* any other line */
     {
-      TPos  prod = dx * fy1 - dy * fx1;
+      FT_Int64  prod = dx * (FT_Int64)fy1 - dy * (FT_Int64)fx1;
       FT_UDIVPREP( ex1 != ex2, dx );
       FT_UDIVPREP( ey1 != ey2, dy );
 
@@ -906,72 +934,308 @@
       /* also easily updated when moving from one cell to the next.  */
       do
       {
-        if      ( prod                                   <= 0 &&
-                  prod - dx * ONE_PIXEL                  >  0 ) /* left */
+        if      ( prod - dx * ONE_PIXEL                  >  0 &&
+                  prod                                   <= 0 ) /* left */
         {
           fx2 = 0;
-          fy2 = (TPos)FT_UDIV( -prod, -dx );
+          fy2 = FT_UDIV( -prod, -dx );
           prod -= dy * ONE_PIXEL;
-          ras.cover += ( fy2 - fy1 );
-          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
           fx1 = ONE_PIXEL;
           fy1 = fy2;
           ex1--;
         }
-        else if ( prod - dx * ONE_PIXEL                  <= 0 &&
-                  prod - dx * ONE_PIXEL + dy * ONE_PIXEL >  0 ) /* up */
+        else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL >  0 &&
+                  prod - dx * ONE_PIXEL                  <= 0 ) /* up */
         {
           prod -= dx * ONE_PIXEL;
-          fx2 = (TPos)FT_UDIV( -prod, dy );
+          fx2 = FT_UDIV( -prod, dy );
           fy2 = ONE_PIXEL;
-          ras.cover += ( fy2 - fy1 );
-          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
           fx1 = fx2;
           fy1 = 0;
           ey1++;
         }
-        else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 &&
-                  prod                  + dy * ONE_PIXEL >= 0 ) /* right */
+        else if ( prod                  + dy * ONE_PIXEL >= 0 &&
+                  prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 ) /* right */
         {
           prod += dy * ONE_PIXEL;
           fx2 = ONE_PIXEL;
-          fy2 = (TPos)FT_UDIV( prod, dx );
-          ras.cover += ( fy2 - fy1 );
-          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          fy2 = FT_UDIV( prod, dx );
+          FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
           fx1 = 0;
           fy1 = fy2;
           ex1++;
         }
-        else /* ( prod                  + dy * ONE_PIXEL <  0 &&
-                  prod                                   >  0 )    down */
+        else /* ( prod                                   >  0 &&
+                  prod                  + dy * ONE_PIXEL <  0 )    down */
         {
-          fx2 = (TPos)FT_UDIV( prod, -dy );
+          fx2 = FT_UDIV( prod, -dy );
           fy2 = 0;
           prod += dx * ONE_PIXEL;
-          ras.cover += ( fy2 - fy1 );
-          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
           fx1 = fx2;
           fy1 = ONE_PIXEL;
           ey1--;
         }
 
         gray_set_cell( RAS_VAR_ ex1, ey1 );
+
       } while ( ex1 != ex2 || ey1 != ey2 );
     }
 
-    fx2 = to_x - SUBPIXELS( ex2 );
-    fy2 = to_y - SUBPIXELS( ey2 );
+    fx2 = FRACT( to_x );
+    fy2 = FRACT( to_y );
 
-    ras.cover += ( fy2 - fy1 );
-    ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+    FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
 
   End:
-    ras.x       = to_x;
-    ras.y       = to_y;
+    ras.x = to_x;
+    ras.y = to_y;
   }
 
 #endif
 
+  /*
+   * Benchmarking shows that using DDA to flatten the quadratic Bézier arcs
+   * is slightly faster in the following cases:
+   *
+   *   - When the host CPU is 64-bit.
+   *   - When SSE2 SIMD registers and instructions are available (even on
+   *     x86).
+   *
+   * 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 )
+#  define FT_SSE2 1
+#else
+#  define FT_SSE2 0
+#endif
+
+#if FT_SSE2                || \
+    defined( __aarch64__ ) || \
+    defined( _M_ARM64 )
+#  define BEZIER_USE_DDA  1
+#else
+#  define BEZIER_USE_DDA  0
+#endif
+
+  /*
+   * For now, the code that depends on `BEZIER_USE_DDA` requires `FT_Int64`
+   * to be defined.  If `FT_INT64` is not defined, meaning there is no
+   * 64-bit type available, disable it to avoid compilation errors.  See for
+   * example https://gitlab.freedesktop.org/freetype/freetype/-/issues/1071.
+   */
+#if !defined( FT_INT64 )
+#  undef BEZIER_USE_DDA
+#  define BEZIER_USE_DDA  0
+#endif
+
+#if BEZIER_USE_DDA
+
+#if FT_SSE2
+#  include <emmintrin.h>
+#endif
+
+#define LEFT_SHIFT( a, b )  (FT_Int64)( (FT_UInt64)(a) << (b) )
+
+
+  static void
+  gray_render_conic( RAS_ARG_ const FT_Vector*  control,
+                              const FT_Vector*  to )
+  {
+    FT_Vector  p0, p1, p2;
+    TPos       ax, ay, bx, by, dx, dy;
+    int        shift;
+
+    FT_Int64  rx, ry;
+    FT_Int64  qx, qy;
+    FT_Int64  px, py;
+
+    FT_UInt  count;
+
+
+    p0.x = ras.x;
+    p0.y = ras.y;
+    p1.x = UPSCALE( control->x );
+    p1.y = UPSCALE( control->y );
+    p2.x = UPSCALE( to->x );
+    p2.y = UPSCALE( to->y );
+
+    /* short-cut the arc that crosses the current band */
+    if ( ( TRUNC( p0.y ) >= ras.max_ey &&
+           TRUNC( p1.y ) >= ras.max_ey &&
+           TRUNC( p2.y ) >= ras.max_ey ) ||
+         ( TRUNC( p0.y ) <  ras.min_ey &&
+           TRUNC( p1.y ) <  ras.min_ey &&
+           TRUNC( p2.y ) <  ras.min_ey ) )
+    {
+      ras.x = p2.x;
+      ras.y = p2.y;
+      return;
+    }
+
+    bx = p1.x - p0.x;
+    by = p1.y - p0.y;
+    ax = p2.x - p1.x - bx;  /* p0.x + p2.x - 2 * p1.x */
+    ay = p2.y - p1.y - by;  /* p0.y + p2.y - 2 * p1.y */
+
+    dx = FT_ABS( ax );
+    dy = FT_ABS( ay );
+    if ( dx < dy )
+      dx = dy;
+
+    if ( dx <= ONE_PIXEL / 4 )
+    {
+      gray_render_line( RAS_VAR_ p2.x, p2.y );
+      return;
+    }
+
+    /* We can calculate the number of necessary bisections because  */
+    /* each bisection predictably reduces deviation exactly 4-fold. */
+    /* Even 32-bit deviation would vanish after 16 bisections.      */
+    shift = 0;
+    do
+    {
+      dx   >>= 2;
+      shift += 1;
+
+    } while ( dx > ONE_PIXEL / 4 );
+
+    /*
+     * The (P0,P1,P2) arc equation, for t in [0,1] range:
+     *
+     * P(t) = P0*(1-t)^2 + P1*2*t*(1-t) + P2*t^2
+     *
+     * P(t) = P0 + 2*(P1-P0)*t + (P0+P2-2*P1)*t^2
+     *      = P0 + 2*B*t + A*t^2
+     *
+     *    for A = P0 + P2 - 2*P1
+     *    and B = P1 - P0
+     *
+     * Let's consider the difference when advancing by a small
+     * parameter h:
+     *
+     *    Q(h,t) = P(t+h) - P(t) = 2*B*h + A*h^2 + 2*A*h*t
+     *
+     * And then its own difference:
+     *
+     *    R(h,t) = Q(h,t+h) - Q(h,t) = 2*A*h*h = R (constant)
+     *
+     * Since R is always a constant, it is possible to compute
+     * successive positions with:
+     *
+     *     P = P0
+     *     Q = Q(h,0) = 2*B*h + A*h*h
+     *     R = 2*A*h*h
+     *
+     *   loop:
+     *     P += Q
+     *     Q += R
+     *     EMIT(P)
+     *
+     * To ensure accurate results, perform computations on 64-bit
+     * values, after scaling them by 2^32.
+     *
+     *           h = 1 / 2^N
+     *
+     *     R << 32 = 2 * A << (32 - N - N)
+     *             = A << (33 - 2*N)
+     *
+     *     Q << 32 = (2 * B << (32 - N)) + (A << (32 - N - N))
+     *             = (B << (33 - N)) + (A << (32 - 2*N))
+     */
+
+#if FT_SSE2
+    /* Experience shows that for small shift values, */
+    /* SSE2 is actually slower.                      */
+    if ( shift > 2 )
+    {
+      union
+      {
+        struct { FT_Int64  ax, ay, bx, by; }  i;
+        struct { __m128i  a, b; }  vec;
+
+      } u;
+
+      union
+      {
+        struct { FT_Int32  px_lo, px_hi, py_lo, py_hi; }  i;
+        __m128i  vec;
+
+      } v;
+
+      __m128i  a, b;
+      __m128i  r, q, q2;
+      __m128i  p;
+
+
+      u.i.ax = ax;
+      u.i.ay = ay;
+      u.i.bx = bx;
+      u.i.by = by;
+
+      a = _mm_load_si128( &u.vec.a );
+      b = _mm_load_si128( &u.vec.b );
+
+      r  = _mm_slli_epi64( a, 33 - 2 * shift );
+      q  = _mm_slli_epi64( b, 33 - shift );
+      q2 = _mm_slli_epi64( a, 32 - 2 * shift );
+
+      q = _mm_add_epi64( q2, q );
+
+      v.i.px_lo = 0;
+      v.i.px_hi = p0.x;
+      v.i.py_lo = 0;
+      v.i.py_hi = p0.y;
+
+      p = _mm_load_si128( &v.vec );
+
+      for ( count = 1U << shift; count > 0; count-- )
+      {
+        p = _mm_add_epi64( p, q );
+        q = _mm_add_epi64( q, r );
+
+        _mm_store_si128( &v.vec, p );
+
+        gray_render_line( RAS_VAR_ v.i.px_hi, v.i.py_hi );
+      }
+
+      return;
+    }
+#endif  /* FT_SSE2 */
+
+    rx = LEFT_SHIFT( ax, 33 - 2 * shift );
+    ry = LEFT_SHIFT( ay, 33 - 2 * shift );
+
+    qx = LEFT_SHIFT( bx, 33 - shift ) + LEFT_SHIFT( ax, 32 - 2 * shift );
+    qy = LEFT_SHIFT( by, 33 - shift ) + LEFT_SHIFT( ay, 32 - 2 * shift );
+
+    px = LEFT_SHIFT( p0.x, 32 );
+    py = LEFT_SHIFT( p0.y, 32 );
+
+    for ( count = 1U << shift; count > 0; count-- )
+    {
+      px += qx;
+      py += qy;
+      qx += rx;
+      qy += ry;
+
+      gray_render_line( RAS_VAR_ (FT_Pos)( px >> 32 ),
+                                 (FT_Pos)( py >> 32 ) );
+    }
+  }
+
+#else  /* !BEZIER_USE_DDA */
+
+  /*
+   * Note that multiple attempts to speed up the function below
+   * with SSE2 intrinsics, using various data layouts, have turned
+   * out to be slower than the non-SIMD code below.
+   */
   static void
   gray_split_conic( FT_Vector*  base )
   {
@@ -979,16 +1243,18 @@
 
 
     base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b ) / 2;
-    b = base[1].x = ( base[0].x + b ) / 2;
-    base[2].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    base[3].x = b >> 1;
+    base[2].x = ( a + b ) >> 2;
+    base[1].x = a >> 1;
 
     base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b ) / 2;
-    b = base[1].y = ( base[0].y + b ) / 2;
-    base[2].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    base[3].y = b >> 1;
+    base[2].y = ( a + b ) >> 2;
+    base[1].y = a >> 1;
   }
 
 
@@ -999,7 +1265,7 @@
     FT_Vector   bez_stack[16 * 2 + 1];  /* enough to accommodate bisections */
     FT_Vector*  arc = bez_stack;
     TPos        dx, dy;
-    int         draw, split;
+    int         draw;
 
 
     arc[0].x = UPSCALE( to->x );
@@ -1042,12 +1308,13 @@
     /* many times as there are trailing zeros in the counter.         */
     do
     {
-      split = 1;
-      while ( ( draw & split ) == 0 )
+      int  split = draw & ( -draw );  /* isolate the rightmost 1-bit */
+
+
+      while ( ( split >>= 1 ) )
       {
         gray_split_conic( arc );
         arc += 2;
-        split <<= 1;
       }
 
       gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
@@ -1056,32 +1323,46 @@
     } while ( --draw );
   }
 
+#endif  /* !BEZIER_USE_DDA */
 
+
+  /*
+   * For cubic Bézier, binary splits are still faster than DDA
+   * because the splits are adaptive to how quickly each sub-arc
+   * approaches their chord trisection points.
+   *
+   * It might be useful to experiment with SSE2 to speed up
+   * `gray_split_cubic`, though.
+   */
   static void
   gray_split_cubic( FT_Vector*  base )
   {
-    TPos  a, b, c, d;
+    TPos  a, b, c;
 
 
     base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c ) / 2;
-    base[5].x = b = ( base[3].x + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].x = a = ( a + c ) / 2;
-    base[4].x = b = ( b + c ) / 2;
-    base[3].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c >> 1;
+    c += b;
+    base[4].x = c >> 2;
+    base[1].x = a >> 1;
+    a += b;
+    base[2].x = a >> 2;
+    base[3].x = ( a + c ) >> 3;
 
     base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c ) / 2;
-    base[5].y = b = ( base[3].y + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].y = a = ( a + c ) / 2;
-    base[4].y = b = ( b + c ) / 2;
-    base[3].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c >> 1;
+    c += b;
+    base[4].y = c >> 2;
+    base[1].y = a >> 1;
+    a += b;
+    base[2].y = a >> 2;
+    base[3].y = ( a + c ) >> 3;
   }
 
 
@@ -1092,9 +1373,6 @@
   {
     FT_Vector   bez_stack[16 * 3 + 1];  /* enough to accommodate bisections */
     FT_Vector*  arc = bez_stack;
-    TPos        dx, dy, dx_, dy_;
-    TPos        dx1, dy1, dx2, dy2;
-    TPos        L, s, s_limit;
 
 
     arc[0].x = UPSCALE( to->x );
@@ -1123,45 +1401,13 @@
 
     for (;;)
     {
-      /* Decide whether to split or draw. See `Rapid Termination          */
-      /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
-      /* F. Hain, at                                                      */
-      /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
-
-      /* dx and dy are x and y components of the P0-P3 chord vector. */
-      dx = dx_ = arc[3].x - arc[0].x;
-      dy = dy_ = arc[3].y - arc[0].y;
-
-      L = FT_HYPOT( dx_, dy_ );
-
-      /* Avoid possible arithmetic overflow below by splitting. */
-      if ( L > 32767 )
-        goto Split;
-
-      /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
-      s_limit = L * (TPos)( ONE_PIXEL / 6 );
-
-      /* s is L * the perpendicular distance from P1 to the line P0-P3. */
-      dx1 = arc[1].x - arc[0].x;
-      dy1 = arc[1].y - arc[0].y;
-      s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) );
-
-      if ( s > s_limit )
-        goto Split;
-
-      /* s is L * the perpendicular distance from P2 to the line P0-P3. */
-      dx2 = arc[2].x - arc[0].x;
-      dy2 = arc[2].y - arc[0].y;
-      s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) );
-
-      if ( s > s_limit )
-        goto Split;
-
-      /* Split super curvy segments where the off points are so far
-         from the chord that the angles P0-P1-P3 or P0-P2-P3 become
-         acute as detected by appropriate dot products. */
-      if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
-           dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
+      /* with each split, control points quickly converge towards  */
+      /* chord trisection points and the vanishing distances below */
+      /* indicate when the segment is flat enough to draw          */
+      if ( FT_ABS( 2 * arc[0].x - 3 * arc[1].x + arc[3].x ) > ONE_PIXEL / 2 ||
+           FT_ABS( 2 * arc[0].y - 3 * arc[1].y + arc[3].y ) > ONE_PIXEL / 2 ||
+           FT_ABS( arc[0].x - 3 * arc[2].x + 2 * arc[3].x ) > ONE_PIXEL / 2 ||
+           FT_ABS( arc[0].y - 3 * arc[2].y + 2 * arc[3].y ) > ONE_PIXEL / 2 )
         goto Split;
 
       gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
@@ -1229,72 +1475,11 @@
 
 
   static void
-  gray_hline( RAS_ARG_ TCoord  x,
-                       TCoord  y,
-                       TArea   coverage,
-                       TCoord  acount )
-  {
-    /* scale the coverage from 0..(ONE_PIXEL*ONE_PIXEL*2) to 0..256  */
-    coverage >>= PIXEL_BITS * 2 + 1 - 8;
-    if ( coverage < 0 )
-      coverage = -coverage - 1;
-
-    /* compute the line's coverage depending on the outline fill rule */
-    if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
-    {
-      coverage &= 511;
-
-      if ( coverage >= 256 )
-        coverage = 511 - coverage;
-    }
-    else
-    {
-      /* normal non-zero winding rule */
-      if ( coverage >= 256 )
-        coverage = 255;
-    }
-
-    if ( ras.render_span )  /* for FT_RASTER_FLAG_DIRECT only */
-    {
-      FT_Span  span;
-
-
-      span.x        = (short)x;
-      span.len      = (unsigned short)acount;
-      span.coverage = (unsigned char)coverage;
-
-      ras.render_span( y, 1, &span, ras.render_span_data );
-    }
-    else
-    {
-      unsigned char*  q = ras.target.origin - ras.target.pitch * y + x;
-      unsigned char   c = (unsigned char)coverage;
-
-
-      /* For small-spans it is faster to do it by ourselves than
-       * calling `memset'.  This is mainly due to the cost of the
-       * function call.
-       */
-      switch ( acount )
-      {
-      case 7: *q++ = c;
-      case 6: *q++ = c;
-      case 5: *q++ = c;
-      case 4: *q++ = c;
-      case 3: *q++ = c;
-      case 2: *q++ = c;
-      case 1: *q   = c;
-      case 0: break;
-      default:
-        FT_MEM_SET( q, c, acount );
-      }
-    }
-  }
-
-
-  static void
   gray_sweep( RAS_ARG )
   {
+    int  fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100
+                                                                 : INT_MIN;
+    int  coverage;
     int  y;
 
 
@@ -1303,25 +1488,121 @@
       PCell   cell  = ras.ycells[y - ras.min_ey];
       TCoord  x     = ras.min_ex;
       TArea   cover = 0;
-      TArea   area;
+
+      unsigned char*  line = ras.target.origin - ras.target.pitch * y;
 
 
-      for ( ; cell != NULL; cell = cell->next )
+      for ( ; cell != ras.cell_null; cell = cell->next )
       {
+        TArea  area;
+
+
         if ( cover != 0 && cell->x > x )
-          gray_hline( RAS_VAR_ x, y, cover, cell->x - x );
+        {
+          FT_FILL_RULE( coverage, cover, fill );
+          FT_GRAY_SET( line + x, coverage, cell->x - x );
+        }
 
         cover += (TArea)cell->cover * ( ONE_PIXEL * 2 );
         area   = cover - cell->area;
 
         if ( area != 0 && cell->x >= ras.min_ex )
-          gray_hline( RAS_VAR_ cell->x, y, area, 1 );
+        {
+          FT_FILL_RULE( coverage, area, fill );
+          line[cell->x] = (unsigned char)coverage;
+        }
 
         x = cell->x + 1;
       }
 
-      if ( cover != 0 )
-        gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
+      if ( cover != 0 )  /* only if cropped */
+      {
+        FT_FILL_RULE( coverage, cover, fill );
+        FT_GRAY_SET( line + x, coverage, ras.max_ex - x );
+      }
+    }
+  }
+
+
+  static void
+  gray_sweep_direct( RAS_ARG )
+  {
+    int  fill = ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) ? 0x100
+                                                                 : INT_MIN;
+    int  coverage;
+    int  y;
+
+    FT_Span  span[FT_MAX_GRAY_SPANS];
+    int      n = 0;
+
+
+    for ( y = ras.min_ey; y < ras.max_ey; y++ )
+    {
+      PCell   cell  = ras.ycells[y - ras.min_ey];
+      TCoord  x     = ras.min_ex;
+      TArea   cover = 0;
+
+
+      for ( ; cell != ras.cell_null; cell = cell->next )
+      {
+        TArea  area;
+
+
+        if ( cover != 0 && cell->x > x )
+        {
+          FT_FILL_RULE( coverage, cover, fill );
+
+          span[n].coverage = (unsigned char)coverage;
+          span[n].x        = (short)x;
+          span[n].len      = (unsigned short)( cell->x - x );
+
+          if ( ++n == FT_MAX_GRAY_SPANS )
+          {
+            /* flush the span buffer and reset the count */
+            ras.render_span( y, n, span, ras.render_span_data );
+            n = 0;
+          }
+        }
+
+        cover += (TArea)cell->cover * ( ONE_PIXEL * 2 );
+        area   = cover - cell->area;
+
+        if ( area != 0 && cell->x >= ras.min_ex )
+        {
+          FT_FILL_RULE( coverage, area, fill );
+
+          span[n].coverage = (unsigned char)coverage;
+          span[n].x        = (short)cell->x;
+          span[n].len      = 1;
+
+          if ( ++n == FT_MAX_GRAY_SPANS )
+          {
+            /* flush the span buffer and reset the count */
+            ras.render_span( y, n, span, ras.render_span_data );
+            n = 0;
+          }
+        }
+
+        x = cell->x + 1;
+      }
+
+      if ( cover != 0 )  /* only if cropped */
+      {
+        FT_FILL_RULE( coverage, cover, fill );
+
+        span[n].coverage = (unsigned char)coverage;
+        span[n].x        = (short)x;
+        span[n].len      = (unsigned short)( ras.max_ex - x );
+
+        ++n;
+      }
+
+      if ( n )
+      {
+        /* flush the span buffer and reset the count */
+        ras.render_span( y, n, span, ras.render_span_data );
+        n = 0;
+      }
     }
   }
 
@@ -1371,7 +1652,7 @@
                         void*                    user )
   {
 #undef SCALED
-#define SCALED( x )  ( ( (x) << shift ) - delta )
+#define SCALED( x )  ( (x) * ( 1L << shift ) - delta )
 
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -1601,7 +1882,7 @@
     }
 
     FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
-    return 0;
+    return Smooth_Err_Ok;
 
   Exit:
     FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error ));
@@ -1628,10 +1909,10 @@
 
 
   static int
-  gray_convert_glyph_inner( RAS_ARG,
+  gray_convert_glyph_inner( RAS_ARG_
                             int  continued )
   {
-    volatile int  error = 0;
+    volatile int  error;
 
 
     if ( ft_setjmp( ras.jump_buffer ) == 0 )
@@ -1642,18 +1923,15 @@
       if ( continued )
         FT_Trace_Enable();
 
-      if ( !ras.invalid )
-        gray_record_cell( RAS_VAR );
-
-      FT_TRACE7(( "band [%d..%d]: %d cell%s\n",
+      FT_TRACE7(( "band [%d..%d]: %ld cell%s remaining/\n",
                   ras.min_ey,
                   ras.max_ey,
-                  ras.num_cells,
-                  ras.num_cells == 1 ? "" : "s" ));
+                  ras.cell_null - ras.cell_free,
+                  ras.cell_null - ras.cell_free == 1 ? "" : "s" ));
     }
     else
     {
-      error = FT_THROW( Memory_Overflow );
+      error = FT_THROW( Raster_Overflow );
 
       FT_TRACE7(( "band [%d..%d]: to be bisected\n",
                   ras.min_ey, ras.max_ey ));
@@ -1679,7 +1957,16 @@
     int  continued = 0;
 
 
+    /* Initialize the null cell at the end of the poll. */
+    ras.cell_null        = buffer + FT_MAX_GRAY_POOL - 1;
+    ras.cell_null->x     = CELL_MAX_X_VALUE;
+    ras.cell_null->area  = 0;
+    ras.cell_null->cover = 0;
+    ras.cell_null->next  = NULL;
+
     /* set up vertical bands */
+    ras.ycells     = (PCell*)buffer;
+
     if ( height > n )
     {
       /* two divisions rounded up */
@@ -1687,13 +1974,6 @@
       height  = ( height + n - 1 ) / n;
     }
 
-    /* memory management */
-    n = ( height * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / sizeof ( TCell );
-
-    ras.cells     = buffer + n;
-    ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - n );
-    ras.ycells    = (PCell*)buffer;
-
     for ( y = yMin; y < yMax; )
     {
       ras.min_ey = y;
@@ -1707,27 +1987,37 @@
       do
       {
         TCoord  width = band[0] - band[1];
+        TCoord  w;
         int     error;
 
 
-        FT_MEM_ZERO( ras.ycells, height * sizeof ( PCell ) );
+        for ( w = 0; w < width; ++w )
+          ras.ycells[w] = ras.cell_null;
 
-        ras.num_cells = 0;
-        ras.invalid   = 1;
+        /* memory management: skip ycells */
+        n = ( (size_t)width * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
+              sizeof ( TCell );
+
+        ras.cell_free = buffer + n;
+        ras.cell      = ras.cell_null;
         ras.min_ey    = band[1];
         ras.max_ey    = band[0];
+        ras.count_ey  = width;
 
-        error     = gray_convert_glyph_inner( RAS_VAR, continued );
+        error     = gray_convert_glyph_inner( RAS_VAR_ continued );
         continued = 1;
 
         if ( !error )
         {
-          gray_sweep( RAS_VAR );
+          if ( ras.render_span )  /* for FT_RASTER_FLAG_DIRECT only */
+            gray_sweep_direct( RAS_VAR );
+          else
+            gray_sweep( RAS_VAR );
           band--;
           continue;
         }
-        else if ( error != ErrRaster_Memory_Overflow )
-          return 1;
+        else if ( error != Smooth_Err_Raster_Overflow )
+          return error;
 
         /* render pool overflow; we will reduce the render band by half */
         width >>= 1;
@@ -1736,7 +2026,7 @@
         if ( width == 0 )
         {
           FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
-          return 1;
+          return FT_THROW( Raster_Overflow );
         }
 
         band++;
@@ -1745,7 +2035,7 @@
       } while ( band >= bands );
     }
 
-    return 0;
+    return Smooth_Err_Ok;
   }
 
 
@@ -1755,7 +2045,6 @@
   {
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
-    FT_BBox            clip;
 
 #ifndef FT_STATIC_RASTER
     gray_TWorker  worker[1];
@@ -1767,14 +2056,14 @@
 
     /* this version does not support monochrome rendering */
     if ( !( params->flags & FT_RASTER_FLAG_AA ) )
-      return FT_THROW( Invalid_Mode );
+      return FT_THROW( Cannot_Render_Glyph );
 
     if ( !outline )
       return FT_THROW( Invalid_Outline );
 
     /* return immediately if the outline is empty */
     if ( outline->n_points == 0 || outline->n_contours <= 0 )
-      return 0;
+      return Smooth_Err_Ok;
 
     if ( !outline->contours || !outline->points )
       return FT_THROW( Invalid_Outline );
@@ -1788,10 +2077,15 @@
     if ( params->flags & FT_RASTER_FLAG_DIRECT )
     {
       if ( !params->gray_spans )
-        return 0;
+        return Smooth_Err_Ok;
 
       ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
       ras.render_span_data = params->user;
+
+      ras.min_ex = params->clip_box.xMin;
+      ras.min_ey = params->clip_box.yMin;
+      ras.max_ex = params->clip_box.xMax;
+      ras.max_ey = params->clip_box.yMax;
     }
     else
     {
@@ -1801,7 +2095,7 @@
 
       /* nothing to do */
       if ( !target_map->width || !target_map->rows )
-        return 0;
+        return Smooth_Err_Ok;
 
       if ( !target_map->buffer )
         return FT_THROW( Invalid_Argument );
@@ -1816,29 +2110,16 @@
 
       ras.render_span      = (FT_Raster_Span_Func)NULL;
       ras.render_span_data = NULL;
+
+      ras.min_ex = 0;
+      ras.min_ey = 0;
+      ras.max_ex = (FT_Pos)target_map->width;
+      ras.max_ey = (FT_Pos)target_map->rows;
     }
 
-    /* compute clipping box */
-    if ( params->flags & FT_RASTER_FLAG_DIRECT &&
-         params->flags & FT_RASTER_FLAG_CLIP   )
-      clip = params->clip_box;
-    else
-    {
-      /* compute clip box from target pixmap */
-      clip.xMin = 0;
-      clip.yMin = 0;
-      clip.xMax = (FT_Pos)target_map->width;
-      clip.yMax = (FT_Pos)target_map->rows;
-    }
-
-    /* clip to target bitmap, exit if nothing to do */
-    ras.min_ex = clip.xMin;
-    ras.min_ey = clip.yMin;
-    ras.max_ex = clip.xMax;
-    ras.max_ey = clip.yMax;
-
+    /* exit if nothing to do */
     if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
-      return 0;
+      return Smooth_Err_Ok;
 
     return gray_convert_glyph( RAS_VAR );
   }
@@ -1875,19 +2156,17 @@
 #else /* !STANDALONE_ */
 
   static int
-  gray_raster_new( FT_Memory   memory,
-                   FT_Raster*  araster )
+  gray_raster_new( FT_Memory      memory,
+                   gray_PRaster*  araster )
   {
     FT_Error      error;
     gray_PRaster  raster = NULL;
 
 
-    *araster = 0;
-    if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) )
-    {
+    if ( !FT_NEW( raster ) )
       raster->memory = memory;
-      *araster       = (FT_Raster)raster;
-    }
+
+    *araster = raster;
 
     return error;
   }
diff --git a/src/smooth/ftgrays.h b/src/smooth/ftgrays.h
index 6aa7f35..a5001bf 100644
--- a/src/smooth/ftgrays.h
+++ b/src/smooth/ftgrays.h
@@ -4,7 +4,7 @@
  *
  *   FreeType smooth renderer declaration
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -28,7 +28,7 @@
 #include "ftimage.h"
 #else
 #include <ft2build.h>
-#include FT_IMAGE_H
+#include <freetype/ftimage.h>
 #endif
 
 
diff --git a/src/smooth/ftsmerrs.h b/src/smooth/ftsmerrs.h
index 4c55e32..f4ac93d 100644
--- a/src/smooth/ftsmerrs.h
+++ b/src/smooth/ftsmerrs.h
@@ -4,7 +4,7 @@
  *
  *   smooth renderer error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef FTSMERRS_H_
 #define FTSMERRS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  Smooth_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Smooth
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* FTSMERRS_H_ */
 
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index c6b7e21..cdbc78c 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -4,7 +4,7 @@
  *
  *   Anti-aliasing renderer interface (body).
  *
- * Copyright 2000-2018 by
+ * Copyright (C) 2000-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,42 +16,15 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_OUTLINE_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftoutln.h>
 #include "ftsmooth.h"
 #include "ftgrays.h"
 
 #include "ftsmerrs.h"
 
 
-  /* initialize renderer -- init its raster */
-  static FT_Error
-  ft_smooth_init( FT_Renderer  render )
-  {
-
-#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
-
-    FT_Vector*  sub = render->root.library->lcd_geometry;
-
-
-    /* set up default subpixel geometry for striped RGB panels. */
-    sub[0].x = -21;
-    sub[0].y = 0;
-    sub[1].x = 0;
-    sub[1].y = 0;
-    sub[2].x = 21;
-    sub[2].y = 0;
-
-#endif
-
-    render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
-
-    return 0;
-  }
-
-
   /* sets render-specific mode */
   static FT_Error
   ft_smooth_set_mode( FT_Renderer  render,
@@ -103,14 +76,359 @@
       FT_Outline_Get_CBox( &slot->outline, cbox );
   }
 
+  typedef struct TOrigin_
+  {
+    unsigned char*  origin;  /* pixmap origin at the bottom-left */
+    int             pitch;   /* pitch to go down one row */
 
-  /* convert a slot's glyph image into a bitmap */
+  } TOrigin;
+
+#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+
+  /* initialize renderer -- init its raster */
   static FT_Error
-  ft_smooth_render_generic( FT_Renderer       render,
-                            FT_GlyphSlot      slot,
-                            FT_Render_Mode    mode,
-                            const FT_Vector*  origin,
-                            FT_Render_Mode    required_mode )
+  ft_smooth_init( FT_Renderer  render )
+  {
+    FT_Vector*  sub = render->root.library->lcd_geometry;
+
+
+    /* set up default subpixel geometry for striped RGB panels. */
+    sub[0].x = -21;
+    sub[0].y = 0;
+    sub[1].x = 0;
+    sub[1].y = 0;
+    sub[2].x = 21;
+    sub[2].y = 0;
+
+    render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
+
+    return 0;
+  }
+
+
+  /* This function writes every third byte in direct rendering mode */
+  static void
+  ft_smooth_lcd_spans( int             y,
+                       int             count,
+                       const FT_Span*  spans,
+                       TOrigin*        target )
+  {
+    unsigned char*  dst_line = target->origin - y * target->pitch;
+    unsigned char*  dst;
+    unsigned short  w;
+
+
+    for ( ; count--; spans++ )
+      for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 )
+        *dst = spans->coverage;
+  }
+
+
+  static FT_Error
+  ft_smooth_raster_lcd( FT_Renderer  render,
+                        FT_Outline*  outline,
+                        FT_Bitmap*   bitmap )
+  {
+    FT_Error      error = FT_Err_Ok;
+    FT_Vector*    sub   = render->root.library->lcd_geometry;
+    FT_Pos        x, y;
+
+    FT_Raster_Params   params;
+    TOrigin            target;
+
+
+    /* Render 3 separate coverage bitmaps, shifting the outline.  */
+    /* 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.user       = &target;
+
+    params.clip_box.xMin = 0;
+    params.clip_box.yMin = 0;
+    params.clip_box.xMax = bitmap->width;
+    params.clip_box.yMax = bitmap->rows;
+
+    if ( bitmap->pitch < 0 )
+      target.origin = bitmap->buffer;
+    else
+      target.origin = bitmap->buffer
+                      + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
+
+    target.pitch = bitmap->pitch;
+
+    FT_Outline_Translate( outline,
+                          -sub[0].x,
+                          -sub[0].y );
+    error = render->raster_render( render->raster, &params );
+    x = sub[0].x;
+    y = sub[0].y;
+    if ( error )
+      goto Exit;
+
+    target.origin++;
+    FT_Outline_Translate( outline,
+                          sub[0].x - sub[1].x,
+                          sub[0].y - sub[1].y );
+    error = render->raster_render( render->raster, &params );
+    x = sub[1].x;
+    y = sub[1].y;
+    if ( error )
+      goto Exit;
+
+    target.origin++;
+    FT_Outline_Translate( outline,
+                          sub[1].x - sub[2].x,
+                          sub[1].y - sub[2].y );
+    error = render->raster_render( render->raster, &params );
+    x = sub[2].x;
+    y = sub[2].y;
+
+  Exit:
+    FT_Outline_Translate( outline, x, y );
+
+    return error;
+  }
+
+
+  static FT_Error
+  ft_smooth_raster_lcdv( FT_Renderer  render,
+                         FT_Outline*  outline,
+                         FT_Bitmap*   bitmap )
+  {
+    FT_Error     error = FT_Err_Ok;
+    int          pitch = bitmap->pitch;
+    FT_Vector*   sub   = render->root.library->lcd_geometry;
+    FT_Pos       x, y;
+
+    FT_Raster_Params  params;
+
+
+    params.target = bitmap;
+    params.source = outline;
+    params.flags  = FT_RASTER_FLAG_AA;
+
+    /* Render 3 separate coverage bitmaps, shifting the outline. */
+    /* Notice that the subpixel geometry vectors are rotated.    */
+    /* Triple the pitch to render on each third row.            */
+    bitmap->pitch *= 3;
+    bitmap->rows  /= 3;
+
+    FT_Outline_Translate( outline,
+                          -sub[0].y,
+                          sub[0].x );
+    error = render->raster_render( render->raster, &params );
+    x = sub[0].y;
+    y = -sub[0].x;
+    if ( error )
+      goto Exit;
+
+    bitmap->buffer += pitch;
+    FT_Outline_Translate( outline,
+                          sub[0].y - sub[1].y,
+                          sub[1].x - sub[0].x );
+    error = render->raster_render( render->raster, &params );
+    x = sub[1].y;
+    y = -sub[1].x;
+    bitmap->buffer -= pitch;
+    if ( error )
+      goto Exit;
+
+    bitmap->buffer += 2 * pitch;
+    FT_Outline_Translate( outline,
+                          sub[1].y - sub[2].y,
+                          sub[2].x - sub[1].x );
+    error = render->raster_render( render->raster, &params );
+    x = sub[2].y;
+    y = -sub[2].x;
+    bitmap->buffer -= 2 * pitch;
+
+  Exit:
+    FT_Outline_Translate( outline, x, y );
+
+    bitmap->pitch /= 3;
+    bitmap->rows  *= 3;
+
+    return error;
+  }
+
+#else   /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+  /* initialize renderer -- init its raster */
+  static FT_Error
+  ft_smooth_init( FT_Renderer  render )
+  {
+    /* set up default LCD filtering */
+    FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT );
+
+    render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
+
+    return 0;
+  }
+
+
+  static FT_Error
+  ft_smooth_raster_lcd( FT_Renderer  render,
+                        FT_Outline*  outline,
+                        FT_Bitmap*   bitmap )
+  {
+    FT_Error    error      = FT_Err_Ok;
+    FT_Vector*  points     = outline->points;
+    FT_Vector*  points_end = FT_OFFSET( points, outline->n_points );
+    FT_Vector*  vec;
+
+    FT_Raster_Params  params;
+
+
+    params.target = bitmap;
+    params.source = outline;
+    params.flags  = FT_RASTER_FLAG_AA;
+
+    /* implode outline */
+    for ( vec = points; vec < points_end; vec++ )
+      vec->x *= 3;
+
+    /* render outline into the bitmap */
+    error = render->raster_render( render->raster, &params );
+
+    /* deflate outline */
+    for ( vec = points; vec < points_end; vec++ )
+      vec->x /= 3;
+
+    return error;
+  }
+
+
+  static FT_Error
+  ft_smooth_raster_lcdv( FT_Renderer  render,
+                         FT_Outline*  outline,
+                         FT_Bitmap*   bitmap )
+  {
+    FT_Error    error      = FT_Err_Ok;
+    FT_Vector*  points     = outline->points;
+    FT_Vector*  points_end = FT_OFFSET( points, outline->n_points );
+    FT_Vector*  vec;
+
+    FT_Raster_Params  params;
+
+
+    params.target = bitmap;
+    params.source = outline;
+    params.flags  = FT_RASTER_FLAG_AA;
+
+    /* implode outline */
+    for ( vec = points; vec < points_end; vec++ )
+      vec->y *= 3;
+
+    /* render outline into the bitmap */
+    error = render->raster_render( render->raster, &params );
+
+    /* deflate outline */
+    for ( vec = points; vec < points_end; vec++ )
+      vec->y /= 3;
+
+    return error;
+  }
+
+#endif  /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+/* Oversampling scale to be used in rendering overlaps */
+#define SCALE  ( 1 << 2 )
+
+  /* This function averages inflated spans in direct rendering mode */
+  static void
+  ft_smooth_overlap_spans( int             y,
+                           int             count,
+                           const FT_Span*  spans,
+                           TOrigin*        target )
+  {
+    unsigned char*  dst = target->origin - ( y / SCALE ) * target->pitch;
+    unsigned short  x;
+    unsigned int    cover, sum;
+
+
+    /* When accumulating the oversampled spans we need to assure that  */
+    /* fully covered pixels are equal to 255 and do not overflow.      */
+    /* It is important that the SCALE is a power of 2, each subpixel   */
+    /* cover can also reach a power of 2 after rounding, and the total */
+    /* is clamped to 255 when it adds up to 256.                       */
+    for ( ; count--; spans++ )
+    {
+      cover = ( spans->coverage + SCALE * SCALE / 2 ) / ( SCALE * SCALE );
+      for ( x = 0; x < spans->len; x++ )
+      {
+        sum                           = dst[( spans->x + x ) / SCALE] + cover;
+        dst[( spans->x + x ) / SCALE] = (unsigned char)( sum - ( sum >> 8 ) );
+      }
+    }
+  }
+
+
+  static FT_Error
+  ft_smooth_raster_overlap( FT_Renderer  render,
+                            FT_Outline*  outline,
+                            FT_Bitmap*   bitmap )
+  {
+    FT_Error    error      = FT_Err_Ok;
+    FT_Vector*  points     = outline->points;
+    FT_Vector*  points_end = FT_OFFSET( points, outline->n_points );
+    FT_Vector*  vec;
+
+    FT_Raster_Params   params;
+    TOrigin            target;
+
+
+    /* Reject outlines that are too wide for 16-bit FT_Span.       */
+    /* Other limits are applied upstream with the same error code. */
+    if ( bitmap->width * SCALE > 0x7FFF )
+      return FT_THROW( Raster_Overflow );
+
+    /* 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.user       = &target;
+
+    params.clip_box.xMin = 0;
+    params.clip_box.yMin = 0;
+    params.clip_box.xMax = bitmap->width * SCALE;
+    params.clip_box.yMax = bitmap->rows  * SCALE;
+
+    if ( bitmap->pitch < 0 )
+      target.origin = bitmap->buffer;
+    else
+      target.origin = bitmap->buffer
+                      + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
+
+    target.pitch = bitmap->pitch;
+
+    /* inflate outline */
+    for ( vec = points; vec < points_end; vec++ )
+    {
+      vec->x *= SCALE;
+      vec->y *= SCALE;
+    }
+
+    /* render outline into the bitmap */
+    error = render->raster_render( render->raster, &params );
+
+    /* deflate outline */
+    for ( vec = points; vec < points_end; vec++ )
+    {
+      vec->x /= SCALE;
+      vec->y /= SCALE;
+    }
+
+    return error;
+  }
+
+#undef SCALE
+
+  static FT_Error
+  ft_smooth_render( FT_Renderer       render,
+                    FT_GlyphSlot      slot,
+                    FT_Render_Mode    mode,
+                    const FT_Vector*  origin )
   {
     FT_Error     error   = FT_Err_Ok;
     FT_Outline*  outline = &slot->outline;
@@ -118,10 +436,6 @@
     FT_Memory    memory  = render->root.memory;
     FT_Pos       x_shift = 0;
     FT_Pos       y_shift = 0;
-    FT_Int       hmul    = ( mode == FT_RENDER_MODE_LCD );
-    FT_Int       vmul    = ( mode == FT_RENDER_MODE_LCD_V );
-
-    FT_Raster_Params  params;
 
 
     /* check glyph image format */
@@ -132,7 +446,10 @@
     }
 
     /* check mode */
-    if ( mode != required_mode )
+    if ( mode != FT_RENDER_MODE_NORMAL &&
+         mode != FT_RENDER_MODE_LIGHT  &&
+         mode != FT_RENDER_MODE_LCD    &&
+         mode != FT_RENDER_MODE_LCD_V  )
     {
       error = FT_THROW( Cannot_Render_Glyph );
       goto Exit;
@@ -145,16 +462,15 @@
       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     }
 
-    ft_glyphslot_preset_bitmap( slot, mode, origin );
-
-    if ( bitmap->width > 0x7FFF || bitmap->rows > 0x7FFF )
+    if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
     {
-      FT_ERROR(( "ft_smooth_render_generic: glyph is too large: %u x %u\n",
-                 bitmap->width, bitmap->rows ));
       error = FT_THROW( Raster_Overflow );
       goto Exit;
     }
 
+    if ( !bitmap->rows || !bitmap->pitch )
+      goto Exit;
+
     /* allocate new one */
     if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
       goto Exit;
@@ -178,176 +494,57 @@
     if ( x_shift || y_shift )
       FT_Outline_Translate( outline, x_shift, y_shift );
 
-    /* set up parameters */
-    params.target = bitmap;
-    params.source = outline;
-    params.flags  = FT_RASTER_FLAG_AA;
+    if ( mode == FT_RENDER_MODE_NORMAL ||
+         mode == FT_RENDER_MODE_LIGHT  )
+    {
+      if ( outline->flags & FT_OUTLINE_OVERLAP )
+        error = ft_smooth_raster_overlap( render, outline, bitmap );
+      else
+      {
+        FT_Raster_Params  params;
+
+
+        params.target = bitmap;
+        params.source = outline;
+        params.flags  = FT_RASTER_FLAG_AA;
+
+        error = render->raster_render( render->raster, &params );
+      }
+    }
+    else
+    {
+      if ( mode == FT_RENDER_MODE_LCD )
+        error = ft_smooth_raster_lcd ( render, outline, bitmap );
+      else if ( mode == FT_RENDER_MODE_LCD_V )
+        error = ft_smooth_raster_lcdv( render, outline, bitmap );
 
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 
-    /* implode outline if needed */
-    {
-      FT_Vector*  points     = outline->points;
-      FT_Vector*  points_end = points + outline->n_points;
-      FT_Vector*  vec;
-
-
-      if ( hmul )
-        for ( vec = points; vec < points_end; vec++ )
-          vec->x *= 3;
-
-      if ( vmul )
-        for ( vec = points; vec < points_end; vec++ )
-          vec->y *= 3;
-    }
-
-    /* render outline into the bitmap */
-    error = render->raster_render( render->raster, &params );
-
-    /* deflate outline if needed */
-    {
-      FT_Vector*  points     = outline->points;
-      FT_Vector*  points_end = points + outline->n_points;
-      FT_Vector*  vec;
-
-
-      if ( hmul )
-        for ( vec = points; vec < points_end; vec++ )
-          vec->x /= 3;
-
-      if ( vmul )
-        for ( vec = points; vec < points_end; vec++ )
-          vec->y /= 3;
-    }
-
-    if ( error )
-      goto Exit;
-
-    /* finally apply filtering */
-    if ( hmul || vmul )
-    {
-      FT_Byte*                 lcd_weights;
-      FT_Bitmap_LcdFilterFunc  lcd_filter_func;
-
-
-      /* Per-face LCD filtering takes priority if set up. */
-      if ( slot->face && slot->face->internal->lcd_filter_func )
+      /* finally apply filtering */
       {
-        lcd_weights     = slot->face->internal->lcd_weights;
-        lcd_filter_func = slot->face->internal->lcd_filter_func;
-      }
-      else
-      {
-        lcd_weights     = slot->library->lcd_weights;
-        lcd_filter_func = slot->library->lcd_filter_func;
-      }
-
-      if ( lcd_filter_func )
-        lcd_filter_func( bitmap, mode, lcd_weights );
-    }
-
-#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
-    if ( hmul )  /* lcd */
-    {
-      FT_Byte*  line;
-      FT_Byte*  temp = NULL;
-      FT_UInt   i, j;
-
-      unsigned int  height = bitmap->rows;
-      unsigned int  width  = bitmap->width;
-      int           pitch  = bitmap->pitch;
-
-      FT_Vector*  sub = slot->library->lcd_geometry;
+        FT_Byte*                 lcd_weights;
+        FT_Bitmap_LcdFilterFunc  lcd_filter_func;
 
 
-      /* Render 3 separate monochrome bitmaps, shifting the outline.  */
-      width /= 3;
-
-      FT_Outline_Translate( outline,           -sub[0].x,           -sub[0].y );
-      error = render->raster_render( render->raster, &params );
-      if ( error )
-        goto Exit;
-
-      bitmap->buffer += width;
-      FT_Outline_Translate( outline, sub[0].x - sub[1].x, sub[0].y - sub[1].y );
-      error = render->raster_render( render->raster, &params );
-      bitmap->buffer -= width;
-      if ( error )
-        goto Exit;
-
-      bitmap->buffer += 2 * width;
-      FT_Outline_Translate( outline, sub[1].x - sub[2].x, sub[1].y - sub[2].y );
-      error = render->raster_render( render->raster, &params );
-      bitmap->buffer -= 2 * width;
-      if ( error )
-        goto Exit;
-
-      x_shift        -= sub[2].x;
-      y_shift        -= sub[2].y;
-
-      /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD.    */
-      /* XXX: It is more efficient to render every third byte above. */
-
-      if ( FT_ALLOC( temp, (FT_ULong)pitch ) )
-        goto Exit;
-
-      for ( i = 0; i < height; i++ )
-      {
-        line = bitmap->buffer + i * (FT_ULong)pitch;
-        for ( j = 0; j < width; j++ )
+        /* Per-face LCD filtering takes priority if set up. */
+        if ( slot->face && slot->face->internal->lcd_filter_func )
         {
-          temp[3 * j    ] = line[j];
-          temp[3 * j + 1] = line[j + width];
-          temp[3 * j + 2] = line[j + width + width];
+          lcd_weights     = slot->face->internal->lcd_weights;
+          lcd_filter_func = slot->face->internal->lcd_filter_func;
         }
-        FT_MEM_COPY( line, temp, pitch );
+        else
+        {
+          lcd_weights     = slot->library->lcd_weights;
+          lcd_filter_func = slot->library->lcd_filter_func;
+        }
+
+        if ( lcd_filter_func )
+          lcd_filter_func( bitmap, lcd_weights );
       }
 
-      FT_FREE( temp );
+#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
     }
-    else if ( vmul )  /* lcd_v */
-    {
-      int  pitch  = bitmap->pitch;
-
-      FT_Vector*  sub = slot->library->lcd_geometry;
-
-
-      /* Render 3 separate monochrome bitmaps, shifting the outline. */
-      /* Notice that the subpixel geometry vectors are rotated.      */
-      /* Triple the pitch to render on each third row.               */
-      bitmap->pitch *= 3;
-      bitmap->rows  /= 3;
-
-      FT_Outline_Translate( outline,           -sub[0].y, sub[0].x            );
-      error = render->raster_render( render->raster, &params );
-      if ( error )
-        goto Exit;
-
-      bitmap->buffer += pitch;
-      FT_Outline_Translate( outline, sub[0].y - sub[1].y, sub[1].x - sub[0].x );
-      error = render->raster_render( render->raster, &params );
-      bitmap->buffer -= pitch;
-      if ( error )
-        goto Exit;
-
-      bitmap->buffer += 2 * pitch;
-      FT_Outline_Translate( outline, sub[1].y - sub[2].y, sub[2].x - sub[1].x );
-      error = render->raster_render( render->raster, &params );
-      bitmap->buffer -= 2 * pitch;
-      if ( error )
-        goto Exit;
-
-      x_shift        -= sub[2].y;
-      y_shift        += sub[2].x;
-
-      bitmap->pitch /= 3;
-      bitmap->rows  *= 3;
-    }
-    else  /* grayscale */
-      error = render->raster_render( render->raster, &params );
-
-#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
 
   Exit:
     if ( !error )
@@ -368,45 +565,6 @@
   }
 
 
-  /* convert a slot's glyph image into a bitmap */
-  static FT_Error
-  ft_smooth_render( FT_Renderer       render,
-                    FT_GlyphSlot      slot,
-                    FT_Render_Mode    mode,
-                    const FT_Vector*  origin )
-  {
-    if ( mode == FT_RENDER_MODE_LIGHT )
-      mode = FT_RENDER_MODE_NORMAL;
-
-    return ft_smooth_render_generic( render, slot, mode, origin,
-                                     FT_RENDER_MODE_NORMAL );
-  }
-
-
-  /* convert a slot's glyph image into a horizontal LCD bitmap */
-  static FT_Error
-  ft_smooth_render_lcd( FT_Renderer       render,
-                        FT_GlyphSlot      slot,
-                        FT_Render_Mode    mode,
-                        const FT_Vector*  origin )
-  {
-    return ft_smooth_render_generic( render, slot, mode, origin,
-                                     FT_RENDER_MODE_LCD );
-  }
-
-
-  /* convert a slot's glyph image into a vertical LCD bitmap */
-  static FT_Error
-  ft_smooth_render_lcd_v( FT_Renderer       render,
-                          FT_GlyphSlot      slot,
-                          FT_Render_Mode    mode,
-                          const FT_Vector*  origin )
-  {
-    return ft_smooth_render_generic( render, slot, mode, origin,
-                                     FT_RENDER_MODE_LCD_V );
-  }
-
-
   FT_DEFINE_RENDERER(
     ft_smooth_renderer_class,
 
@@ -434,58 +592,4 @@
   )
 
 
-  FT_DEFINE_RENDERER(
-    ft_smooth_lcd_renderer_class,
-
-      FT_MODULE_RENDERER,
-      sizeof ( FT_RendererRec ),
-
-      "smooth-lcd",
-      0x10000L,
-      0x20000L,
-
-      NULL,    /* module specific interface */
-
-      (FT_Module_Constructor)ft_smooth_init,  /* module_init   */
-      (FT_Module_Destructor) NULL,            /* module_done   */
-      (FT_Module_Requester)  NULL,            /* get_interface */
-
-    FT_GLYPH_FORMAT_OUTLINE,
-
-    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd,  /* render_glyph    */
-    (FT_Renderer_TransformFunc)ft_smooth_transform,   /* transform_glyph */
-    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,    /* get_glyph_cbox  */
-    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,    /* set_mode        */
-
-    (FT_Raster_Funcs*)&ft_grays_raster                /* raster_class    */
-  )
-
-
-  FT_DEFINE_RENDERER(
-    ft_smooth_lcdv_renderer_class,
-
-      FT_MODULE_RENDERER,
-      sizeof ( FT_RendererRec ),
-
-      "smooth-lcdv",
-      0x10000L,
-      0x20000L,
-
-      NULL,    /* module specific interface */
-
-      (FT_Module_Constructor)ft_smooth_init,  /* module_init   */
-      (FT_Module_Destructor) NULL,            /* module_done   */
-      (FT_Module_Requester)  NULL,            /* get_interface */
-
-    FT_GLYPH_FORMAT_OUTLINE,
-
-    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd_v,  /* render_glyph    */
-    (FT_Renderer_TransformFunc)ft_smooth_transform,     /* transform_glyph */
-    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,      /* get_glyph_cbox  */
-    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,      /* set_mode        */
-
-    (FT_Raster_Funcs*)&ft_grays_raster                  /* raster_class    */
-  )
-
-
 /* END */
diff --git a/src/smooth/ftsmooth.h b/src/smooth/ftsmooth.h
index 782f11a..f8bdc99 100644
--- a/src/smooth/ftsmooth.h
+++ b/src/smooth/ftsmooth.h
@@ -4,7 +4,7 @@
  *
  *   Anti-aliasing renderer interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define FTSMOOTH_H_
 
 
-#include <ft2build.h>
-#include FT_RENDER_H
+#include <freetype/ftrender.h>
 
 
 FT_BEGIN_HEADER
@@ -29,10 +28,6 @@
 
   FT_DECLARE_RENDERER( ft_smooth_renderer_class )
 
-  FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class )
-
-  FT_DECLARE_RENDERER( ft_smooth_lcdv_renderer_class )
-
 
 FT_END_HEADER
 
diff --git a/src/smooth/module.mk b/src/smooth/module.mk
index 5b8bc3b..82ab2fa 100644
--- a/src/smooth/module.mk
+++ b/src/smooth/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -18,10 +18,6 @@
 define SMOOTH_RENDERER
 $(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_renderer_class $(CLOSE_DRIVER)
 $(ECHO_DRIVER)smooth    $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE)
-$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcd_renderer_class $(CLOSE_DRIVER)
-$(ECHO_DRIVER)smooth    $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for LCDs$(ECHO_DRIVER_DONE)
-$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcdv_renderer_class $(CLOSE_DRIVER)
-$(ECHO_DRIVER)smooth    $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for vertical LCDs$(ECHO_DRIVER_DONE)
 endef
 
 # EOF
diff --git a/src/smooth/rules.mk b/src/smooth/rules.mk
index 8f808f8..5d89c75 100644
--- a/src/smooth/rules.mk
+++ b/src/smooth/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/smooth/smooth.c b/src/smooth/smooth.c
index ac414f3..9a0b824 100644
--- a/src/smooth/smooth.c
+++ b/src/smooth/smooth.c
@@ -4,7 +4,7 @@
  *
  *   FreeType anti-aliasing rasterer module component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "ftgrays.c"
 #include "ftsmooth.c"
diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c
new file mode 100644
index 0000000..7edb1a3
--- /dev/null
+++ b/src/svg/ftsvg.c
@@ -0,0 +1,350 @@
+/****************************************************************************
+ *
+ * ftsvg.c
+ *
+ *   The FreeType SVG renderer interface (body).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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/ftserv.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/otsvg.h>
+#include <freetype/internal/svginterface.h>
+#include <freetype/ftbbox.h>
+
+#include "ftsvg.h"
+#include "svgtypes.h"
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, usued to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  otsvg
+
+
+#ifdef FT_CONFIG_OPTION_SVG
+
+  /* ft_svg_init */
+  static FT_Error
+  ft_svg_init( SVG_Renderer  svg_module )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    svg_module->loaded    = FALSE;
+    svg_module->hooks_set = FALSE;
+
+    return error;
+  }
+
+
+  static void
+  ft_svg_done( SVG_Renderer  svg_module )
+  {
+    if ( svg_module->loaded    == TRUE &&
+         svg_module->hooks_set == TRUE )
+      svg_module->hooks.free_svg( &svg_module->state );
+
+    svg_module->loaded = FALSE;
+  }
+
+
+  static FT_Error
+  ft_svg_preset_slot( FT_Module     module,
+                      FT_GlyphSlot  slot,
+                      FT_Bool       cache )
+  {
+    SVG_Renderer       svg_renderer = (SVG_Renderer)module;
+    SVG_RendererHooks  hooks        = svg_renderer->hooks;
+
+
+    if ( svg_renderer->hooks_set == FALSE )
+    {
+      FT_TRACE1(( "Hooks are NOT set.  Can't render OT-SVG glyphs\n" ));
+      return FT_THROW( Missing_SVG_Hooks );
+    }
+
+    if ( svg_renderer->loaded == FALSE )
+    {
+      FT_TRACE3(( "ft_svg_preset_slot: first presetting call,"
+                  " calling init hook\n" ));
+      hooks.init_svg( &svg_renderer->state );
+
+      svg_renderer->loaded = TRUE;
+    }
+
+    return hooks.preset_slot( slot, cache, &svg_renderer->state );
+  }
+
+
+  static FT_Error
+  ft_svg_render( FT_Renderer       renderer,
+                 FT_GlyphSlot      slot,
+                 FT_Render_Mode    mode,
+                 const FT_Vector*  origin )
+  {
+    SVG_Renderer  svg_renderer = (SVG_Renderer)renderer;
+
+    FT_Library  library = renderer->root.library;
+    FT_Memory   memory  = library->memory;
+    FT_Error    error;
+
+    FT_ULong  size_image_buffer;
+
+    SVG_RendererHooks  hooks = svg_renderer->hooks;
+
+
+    FT_UNUSED( mode );
+    FT_UNUSED( origin );
+
+    if ( mode != FT_RENDER_MODE_NORMAL )
+      return FT_THROW( Bad_Argument );
+
+    if ( svg_renderer->hooks_set == FALSE )
+    {
+      FT_TRACE1(( "Hooks are NOT set.  Can't render OT-SVG glyphs\n" ));
+      return FT_THROW( Missing_SVG_Hooks );
+    }
+
+    if ( svg_renderer->loaded == FALSE )
+    {
+      FT_TRACE3(( "ft_svg_render: first rendering, calling init hook\n" ));
+      error = hooks.init_svg( &svg_renderer->state );
+
+      svg_renderer->loaded = TRUE;
+    }
+
+    ft_svg_preset_slot( (FT_Module)renderer, slot, TRUE );
+
+    size_image_buffer = (FT_ULong)slot->bitmap.pitch * slot->bitmap.rows;
+    /* No `FT_QALLOC` here since we need a clean, empty canvas */
+    /* to start with.                                          */
+    if ( FT_ALLOC( slot->bitmap.buffer, size_image_buffer ) )
+      return error;
+
+    error = hooks.render_svg( slot, &svg_renderer->state );
+    if ( error )
+      FT_FREE( slot->bitmap.buffer );
+    else
+      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+
+    return error;
+  }
+
+
+  static const SVG_Interface  svg_interface =
+  {
+    (Preset_Bitmap_Func)ft_svg_preset_slot
+  };
+
+
+  static FT_Error
+  ft_svg_property_set( FT_Module    module,
+                       const char*  property_name,
+                       const void*  value,
+                       FT_Bool      value_is_string )
+  {
+    FT_Error      error    = FT_Err_Ok;
+    SVG_Renderer  renderer = (SVG_Renderer)module;
+
+
+    if ( !ft_strcmp( property_name, "svg-hooks" ) )
+    {
+      SVG_RendererHooks*  hooks;
+
+
+      if ( value_is_string == TRUE )
+      {
+        error = FT_THROW( Invalid_Argument );
+        goto Exit;
+      }
+
+      hooks = (SVG_RendererHooks*)value;
+
+      if ( !hooks->init_svg    ||
+           !hooks->free_svg    ||
+           !hooks->render_svg  ||
+           !hooks->preset_slot )
+      {
+        FT_TRACE0(( "ft_svg_property_set:"
+                    " SVG rendering hooks not set because\n" ));
+        FT_TRACE0(( "                    "
+                    " at least one function pointer is NULL\n" ));
+
+        error = FT_THROW( Invalid_Argument );
+        goto Exit;
+      }
+
+      renderer->hooks     = *hooks;
+      renderer->hooks_set = TRUE;
+    }
+    else
+      error = FT_THROW( Missing_Property );
+
+  Exit:
+    return error;
+  }
+
+
+  static FT_Error
+  ft_svg_property_get( FT_Module    module,
+                       const char*  property_name,
+                       const void*  value )
+  {
+    FT_Error      error    = FT_Err_Ok;
+    SVG_Renderer  renderer = (SVG_Renderer)module;
+
+
+    if ( !ft_strcmp( property_name, "svg-hooks" ) )
+    {
+      SVG_RendererHooks*  hooks = (SVG_RendererHooks*)value;
+
+
+      *hooks = renderer->hooks;
+    }
+    else
+      error = FT_THROW( Missing_Property );
+
+    return error;
+  }
+
+
+  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_DEFINE_SERVICEDESCREC1(
+    ft_svg_services,
+    FT_SERVICE_ID_PROPERTIES, &ft_svg_service_properties )
+
+
+  FT_CALLBACK_DEF( FT_Module_Interface )
+  ft_svg_get_interface( FT_Module    module,
+                        const char*  ft_svg_interface )
+  {
+    FT_Module_Interface  result;
+
+
+    FT_UNUSED( module );
+
+    result = ft_service_list_lookup( ft_svg_services, ft_svg_interface );
+    if ( result )
+      return result;
+
+    return 0;
+  }
+
+
+  static FT_Error
+  ft_svg_transform( FT_Renderer       renderer,
+                    FT_GlyphSlot      slot,
+                    const FT_Matrix*  _matrix,
+                    const FT_Vector*  _delta )
+  {
+    FT_SVG_Document  doc    = (FT_SVG_Document)slot->other;
+    FT_Matrix*       matrix = (FT_Matrix*)_matrix;
+    FT_Vector*       delta  = (FT_Vector*)_delta;
+
+    FT_Matrix  tmp_matrix;
+    FT_Vector  tmp_delta;
+
+    FT_Matrix  a, b;
+    FT_Pos     x, y;
+
+
+    FT_UNUSED( renderer );
+
+    if ( !matrix )
+    {
+      tmp_matrix.xx = 0x10000;
+      tmp_matrix.xy = 0;
+      tmp_matrix.yx = 0;
+      tmp_matrix.yy = 0x10000;
+
+      matrix = &tmp_matrix;
+    }
+
+    if ( !delta )
+    {
+      tmp_delta.x = 0;
+      tmp_delta.y = 0;
+
+      delta = &tmp_delta;
+    }
+
+    a = doc->transform;
+    b = *matrix;
+    FT_Matrix_Multiply( &b, &a );
+
+
+    x = ADD_LONG( ADD_LONG( FT_MulFix( matrix->xx, doc->delta.x ),
+                            FT_MulFix( matrix->xy, doc->delta.y ) ),
+                  delta->x );
+    y = ADD_LONG( ADD_LONG( FT_MulFix( matrix->yx, doc->delta.x ),
+                            FT_MulFix( matrix->yy, doc->delta.y ) ),
+                  delta->y );
+
+    doc->delta.x   = x;
+    doc->delta.y   = y;
+    doc->transform = a;
+
+    return FT_Err_Ok;
+  }
+
+#endif /* FT_CONFIG_OPTION_SVG */
+
+
+#ifdef FT_CONFIG_OPTION_SVG
+#define PUT_SVG_MODULE( a )  a
+#define SVG_GLYPH_FORMAT     FT_GLYPH_FORMAT_SVG
+#else
+#define PUT_SVG_MODULE( a )  NULL
+#define SVG_GLYPH_FORMAT     FT_GLYPH_FORMAT_NONE
+#endif
+
+
+  FT_DEFINE_RENDERER(
+    ft_svg_renderer_class,
+
+      FT_MODULE_RENDERER,
+      sizeof ( SVG_RendererRec ),
+
+      "ot-svg",
+      0x10000L,
+      0x20000L,
+
+      (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 */
+
+      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    */
+  )
+
+
+/* END */
diff --git a/src/svg/ftsvg.h b/src/svg/ftsvg.h
new file mode 100644
index 0000000..9c496ca
--- /dev/null
+++ b/src/svg/ftsvg.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ *
+ * ftsvg.h
+ *
+ *   The FreeType SVG renderer interface (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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 FTSVG_H_
+#define FTSVG_H_
+
+#include <ft2build.h>
+#include <freetype/ftrender.h>
+#include <freetype/internal/ftobjs.h>
+
+
+FT_BEGIN_HEADER
+
+  FT_DECLARE_RENDERER( ft_svg_renderer_class )
+
+FT_END_HEADER
+
+#endif /* FTSVG_H_ */
+
+
+/* END */
diff --git a/src/svg/module.mk b/src/svg/module.mk
new file mode 100644
index 0000000..00beca6
--- /dev/null
+++ b/src/svg/module.mk
@@ -0,0 +1,23 @@
+#
+# FreeType 2 SVG renderer module definition
+#
+
+
+# Copyright (C) 2022-2023 by
+# David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+#
+# 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.
+
+
+FTMODULE_H_COMMANDS += SVG_MODULE
+
+define SVG_MODULE
+$(OPEN_DRIVER) FT_Renderer_Class, ft_svg_renderer_class $(CLOSE_DRIVER)
+$(ECHO_DRIVER)ot-svg    $(ECHO_DRIVER_DESC)OT-SVG glyph renderer module$(ECHO_DRIVER_DONE)
+endef
+
+# EOF
diff --git a/src/svg/rules.mk b/src/svg/rules.mk
new file mode 100644
index 0000000..4f44097
--- /dev/null
+++ b/src/svg/rules.mk
@@ -0,0 +1,70 @@
+#
+# FreeType 2 SVG renderer module build rules
+#
+
+
+# Copyright (C) 2022-2023 by
+# David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+#
+# 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.
+
+
+# SVG renderer driver directory
+#
+SVG_DIR := $(SRC_DIR)/svg
+
+# compilation flags for the driver
+#
+SVG_COMPILE := $(CC) $(ANSIFLAGS)                            \
+                     $I$(subst /,$(COMPILER_SEP),$(SVG_DIR)) \
+                     $(INCLUDE_FLAGS)                        \
+                     $(FT_CFLAGS)
+
+# SVG renderer sources (i.e., C files)
+#
+SVG_DRV_SRC := $(SVG_DIR)/ftsvg.c
+
+
+# SVG renderer headers
+#
+SVG_DRV_H := $(SVG_DIR)/ftsvg.h    \
+             $(SVG_DIR)/svgtypes.h
+
+
+# SVG renderer object(s)
+#
+#   SVG_DRV_OBJ_M is used during `multi' builds.
+#   SVG_DRV_OBJ_S is used during `single' builds.
+#
+SVG_DRV_OBJ_M := $(SVG_DRV_SRC:$(SVG_DIR)/%.c=$(OBJ_DIR)/%.$O)
+SVG_DRV_OBJ_S := $(OBJ_DIR)/svg.$O
+
+# SVG renderer source file for single build
+#
+SVG_DRV_SRC_S := $(SVG_DIR)/svg.c
+
+
+# SVG renderer - single object
+#
+$(SVG_DRV_OBJ_S): $(SVG_DRV_SRC_S) $(SVG_DRV_SRC) \
+                  $(FREETYPE_H) $(SVG_DRV_H)
+	$(SVG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SVG_DRV_SRC_S))
+
+
+# SVG renderer - multiple objects
+#
+$(OBJ_DIR)/%.$O: $(SVG_DIR)/%.c $(FREETYPE_H) $(SVG_DRV_H)
+	$(SVG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(SVG_DRV_OBJ_S)
+DRV_OBJS_M += $(SVG_DRV_OBJ_M)
+
+
+# EOF
diff --git a/src/svg/svg.c b/src/svg/svg.c
new file mode 100644
index 0000000..373c28e
--- /dev/null
+++ b/src/svg/svg.c
@@ -0,0 +1,24 @@
+/****************************************************************************
+ *
+ * svg.c
+ *
+ *   FreeType SVG renderer module component (body only).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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.
+ *
+ */
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+#include "svgtypes.h"
+#include "ftsvg.c"
+
+
+/* END */
diff --git a/src/svg/svgtypes.h b/src/svg/svgtypes.h
new file mode 100644
index 0000000..1d60803
--- /dev/null
+++ b/src/svg/svgtypes.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ *
+ * svgtypes.h
+ *
+ *   The FreeType SVG renderer internal types (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * 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 SVGTYPES_H_
+#define SVGTYPES_H_
+
+#include <ft2build.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ftrender.h>
+#include <freetype/otsvg.h>
+
+
+  typedef struct SVG_RendererRec_
+  {
+    FT_RendererRec     root;   /* this inherits FT_RendererRec                */
+    FT_Bool            loaded;
+    FT_Bool            hooks_set;
+    SVG_RendererHooks  hooks;  /* this holds hooks for SVG rendering          */
+    FT_Pointer         state;  /* a place for hooks to store state, if needed */
+
+  } SVG_RendererRec;
+
+  typedef struct SVG_RendererRec_*  SVG_Renderer;
+
+#endif /* SVGTYPES_H_ */
+
+
+/* EOF */
diff --git a/src/tools/Jamfile b/src/tools/Jamfile
deleted file mode 100644
index 475161e..0000000
--- a/src/tools/Jamfile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Jamfile for src/tools
-#
-SubDir FT2_TOP src tools ;
-
-Main  apinames : apinames.c ;
diff --git a/src/tools/afblue.pl b/src/tools/afblue.pl
index 7c6f1a7..1098e30 100644
--- a/src/tools/afblue.pl
+++ b/src/tools/afblue.pl
@@ -5,7 +5,7 @@
 #
 # Process a blue zone character data file.
 #
-# Copyright 2013-2018 by
+# Copyright (C) 2013-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used,
diff --git a/src/tools/apinames.c b/src/tools/apinames.c
index 06c3260..8a8b082 100644
--- a/src/tools/apinames.c
+++ b/src/tools/apinames.c
@@ -10,7 +10,7 @@
  * accepted if you are using GCC for compilation (and probably by
  * other compilers too).
  *
- * Author: David Turner, 2005, 2006, 2008-2013, 2015
+ * Author: FreeType team, 2005-2019
  *
  * This code is explicitly placed into the public domain.
  *
@@ -22,16 +22,18 @@
 #include <ctype.h>
 
 #define  PROGRAM_NAME     "apinames"
-#define  PROGRAM_VERSION  "0.3"
+#define  PROGRAM_VERSION  "0.4"
 
 #define  LINEBUFF_SIZE  1024
 
+
 typedef enum  OutputFormat_
 {
   OUTPUT_LIST = 0,      /* output the list of names, one per line             */
   OUTPUT_WINDOWS_DEF,   /* output a Windows .DEF file for Visual C++ or Mingw */
   OUTPUT_BORLAND_DEF,   /* output a Windows .DEF file for Borland C++         */
   OUTPUT_WATCOM_LBC,    /* output a Watcom Linker Command File                */
+  OUTPUT_VMS_OPT,       /* output an OpenVMS Linker Option File               */
   OUTPUT_NETWARE_IMP,   /* output a NetWare ImportFile                        */
   OUTPUT_GNU_VERMAP     /* output a version map for GNU or Solaris linker     */
 
@@ -53,10 +55,12 @@
 
 } NameRec, *Name;
 
+
 static Name  the_names;
 static int   num_names;
 static int   max_names;
 
+
 static void
 names_add( const char*  name,
            const char*  end )
@@ -65,14 +69,16 @@
   int           nn, len;
   Name          nm;
 
+
   if ( end <= name )
     return;
 
   /* compute hash value */
-  len = (int)(end - name);
+  len = (int)( end - name );
   h   = 0;
+
   for ( nn = 0; nn < len; nn++ )
-    h = h*33 + name[nn];
+    h = h * 33 + name[nn];
 
   /* check for an pre-existing name */
   for ( nn = 0; nn < num_names; nn++ )
@@ -88,7 +94,7 @@
   /* add new name */
   if ( num_names >= max_names )
   {
-    max_names += (max_names >> 1) + 4;
+    max_names += ( max_names >> 1 ) + 4;
     the_names  = (NameRec*)realloc( the_names,
                                     sizeof ( the_names[0] ) * max_names );
     if ( !the_names )
@@ -97,7 +103,7 @@
   nm = &the_names[num_names++];
 
   nm->hash = h;
-  nm->name = (char*)malloc( len+1 );
+  nm->name = (char*)malloc( len + 1 );
   if ( !nm->name )
     panic( "not enough memory" );
 
@@ -116,6 +122,7 @@
   return strcmp( n1->name, n2->name );
 }
 
+
 static void
 names_sort( void )
 {
@@ -134,89 +141,105 @@
 
   switch ( format )
   {
-    case OUTPUT_WINDOWS_DEF:
-      if ( dll_name )
-        fprintf( out, "LIBRARY %s\n", dll_name );
+  case OUTPUT_WINDOWS_DEF:
+    if ( dll_name )
+      fprintf( out, "LIBRARY %s\n", dll_name );
 
-      fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
-      fprintf( out, "EXPORTS\n" );
-      for ( nn = 0; nn < num_names; nn++ )
-        fprintf( out, "  %s\n", the_names[nn].name );
-      break;
+    fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
+    fprintf( out, "EXPORTS\n" );
 
-    case OUTPUT_BORLAND_DEF:
-      if ( dll_name )
-        fprintf( out, "LIBRARY %s\n", dll_name );
+    for ( nn = 0; nn < num_names; nn++ )
+      fprintf( out, "  %s\n", the_names[nn].name );
 
-      fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
-      fprintf( out, "EXPORTS\n" );
-      for ( nn = 0; nn < num_names; nn++ )
-        fprintf( out, "  _%s\n", the_names[nn].name );
-      break;
+    break;
 
-    case OUTPUT_WATCOM_LBC:
+  case OUTPUT_BORLAND_DEF:
+    if ( dll_name )
+      fprintf( out, "LIBRARY %s\n", dll_name );
+
+    fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
+    fprintf( out, "EXPORTS\n" );
+
+    for ( nn = 0; nn < num_names; nn++ )
+      fprintf( out, "  _%s\n", the_names[nn].name );
+
+    break;
+
+  case OUTPUT_WATCOM_LBC:
+    {
+      const char*  dot;
+
+
+      if ( !dll_name )
       {
-        const char*  dot;
-        char         temp[512];
-
-
-        if ( !dll_name )
-        {
-          fprintf( stderr,
-                   "you must provide a DLL name with the -d option!\n" );
-          exit( 4 );
-        }
-
-        /* we must omit the .dll suffix from the library name */
-        dot = strchr( dll_name, '.' );
-        if ( dot )
-        {
-          int  len = dot - dll_name;
-
-
-          if ( len > (int)( sizeof ( temp ) - 1 ) )
-            len = sizeof ( temp ) - 1;
-
-          memcpy( temp, dll_name, len );
-          temp[len] = 0;
-
-          dll_name = (const char*)temp;
-        }
-
-        for ( nn = 0; nn < num_names; nn++ )
-          fprintf( out, "++_%s.%s.%s\n", the_names[nn].name, dll_name,
-                        the_names[nn].name );
+        fprintf( stderr,
+                 "you must provide a DLL name with the -d option!\n" );
+        exit( 4 );
       }
-      break;
 
-    case OUTPUT_NETWARE_IMP:
+      /* we must omit the `.dll' suffix from the library name */
+      dot = strchr( dll_name, '.' );
+      if ( dot )
       {
-        if ( dll_name )
-          fprintf( out, "  (%s)\n", dll_name );
-        for ( nn = 0; nn < num_names - 1; nn++ )
-          fprintf( out, "  %s,\n", the_names[nn].name );
-        fprintf( out, "  %s\n", the_names[num_names - 1].name );
-      }
-      break;
+        char  temp[512];
+        int   len = dot - dll_name;
 
-    case OUTPUT_GNU_VERMAP:
-      {
-        fprintf( out, "{\n\tglobal:\n" );
-        for ( nn = 0; nn < num_names; nn++ )
-          fprintf( out, "\t\t%s;\n", the_names[nn].name );
-        fprintf( out, "\tlocal:\n\t\t*;\n};\n" );
-      }
-      break;
 
-    default:  /* LIST */
+        if ( len > (int)( sizeof ( temp ) - 1 ) )
+          len = sizeof ( temp ) - 1;
+
+        memcpy( temp, dll_name, len );
+        temp[len] = 0;
+
+        dll_name = (const char*)temp;
+      }
+
       for ( nn = 0; nn < num_names; nn++ )
-        fprintf( out, "%s\n", the_names[nn].name );
+        fprintf( out, "++_%s.%s.%s\n",
+                      the_names[nn].name, dll_name, the_names[nn].name );
+    }
+
+    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 );
+
+    break;
+
+  case OUTPUT_NETWARE_IMP:
+    if ( dll_name )
+      fprintf( out, "  (%s)\n", dll_name );
+
+    for ( nn = 0; nn < num_names - 1; nn++ )
+      fprintf( out, "  %s,\n", the_names[nn].name );
+    fprintf( out, "  %s\n", the_names[num_names - 1].name );
+
+    break;
+
+  case OUTPUT_GNU_VERMAP:
+    fprintf( out, "{\n\tglobal:\n" );
+
+    for ( nn = 0; nn < num_names; nn++ )
+      fprintf( out, "\t\t%s;\n", the_names[nn].name );
+
+    fprintf( out, "\tlocal:\n\t\t*;\n};\n" );
+
+    break;
+
+  default:  /* LIST */
+    for ( nn = 0; nn < num_names; nn++ )
+      fprintf( out, "%s\n", the_names[nn].name );
+
+    break;
   }
 }
 
 
-
-
 /* states of the line parser */
 
 typedef enum  State_
@@ -226,89 +249,96 @@
 
 } State;
 
+
 static int
-read_header_file( FILE*  file, int  verbose )
+read_header_file( FILE*  file,
+                  int    verbose )
 {
   static char  buff[LINEBUFF_SIZE + 1];
   State        state = STATE_START;
 
+
   while ( !feof( file ) )
   {
     char*  p;
 
+
     if ( !fgets( buff, LINEBUFF_SIZE, file ) )
       break;
 
     p = buff;
 
-    while ( *p && (*p == ' ' || *p == '\\') )  /* skip leading whitespace */
+    /* skip leading whitespace */
+    while ( *p && ( *p == ' ' || *p == '\\' ) )
       p++;
 
-    if ( *p == '\n' || *p == '\r' )  /* skip empty lines */
+    /* skip empty lines */
+    if ( *p == '\n' || *p == '\r' )
       continue;
 
     switch ( state )
     {
-      case STATE_START:
-        {
-          if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
-            break;
-
-          p += 10;
-          for (;;)
-          {
-            if ( *p == 0 || *p == '\n' || *p == '\r' )
-              goto NextLine;
-
-            if ( *p == ')' )
-            {
-              p++;
-              break;
-            }
-
-            p++;
-          }
-
-          state = STATE_TYPE;
-
-         /* sometimes, the name is just after the FT_EXPORT(...), so
-          * skip whitespace, and fall-through if we find an alphanumeric
-          * character
-          */
-          while ( *p == ' ' || *p == '\t' )
-            p++;
-
-          if ( !isalpha(*p) )
-            break;
-        }
-        /* fall-through */
-
-      case STATE_TYPE:
-        {
-          char*   name = p;
-
-          while ( isalnum(*p) || *p == '_' )
-            p++;
-
-          if ( p > name )
-          {
-            if ( verbose )
-              fprintf( stderr, ">>> %.*s\n", (int)(p - name), name );
-
-            names_add( name, p );
-          }
-
-          state = STATE_START;
-        }
+    case STATE_START:
+      if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
         break;
 
-      default:
-        ;
+      p += 10;
+      for (;;)
+      {
+        if ( *p == 0 || *p == '\n' || *p == '\r' )
+          goto NextLine;
+
+        if ( *p == ')' )
+        {
+          p++;
+          break;
+        }
+
+        p++;
+      }
+
+      state = STATE_TYPE;
+
+      /*
+       * Sometimes, the name is just after `FT_EXPORT(...)', so skip
+       * whitespace and fall-through if we find an alphanumeric character.
+       */
+      while ( *p == ' ' || *p == '\t' )
+        p++;
+
+      if ( !isalpha( *p ) )
+        break;
+
+      /* fall-through */
+
+    case STATE_TYPE:
+      {
+        char*   name = p;
+
+
+        while ( isalnum( *p ) || *p == '_' )
+          p++;
+
+        if ( p > name )
+        {
+          if ( verbose )
+            fprintf( stderr, ">>> %.*s\n", (int)( p - name ), name );
+
+          names_add( name, p );
+        }
+
+        state = STATE_START;
+      }
+
+      break;
+
+    default:
+      ;
     }
 
-  NextLine:
+NextLine:
     ;
-  }
+  } /* end of while loop */
 
   return 0;
 }
@@ -318,143 +348,159 @@
 usage( void )
 {
   static const char* const  format =
-   "%s %s: extract FreeType API names from header files\n\n"
-   "this program is used to extract the list of public FreeType API\n"
-   "functions. It receives the list of header files as argument and\n"
-   "generates a sorted list of unique identifiers\n\n"
-
-   "usage: %s header1 [options] [header2 ...]\n\n"
-
-   "options:   -      : parse the content of stdin, ignore arguments\n"
-   "           -v     : verbose mode, output sent to standard error\n"
-   "           -oFILE : write output to FILE instead of standard output\n"
-   "           -dNAME : indicate DLL file name, 'freetype.dll' by default\n"
-   "           -w     : output .DEF file for Visual C++ and Mingw\n"
-   "           -wB    : output .DEF file for Borland C++\n"
-   "           -wW    : output Watcom Linker Response File\n"
-   "           -wN    : output NetWare Import File\n"
-   "           -wL    : output version map for GNU or Solaris linker\n"
-   "\n";
+    "%s %s: extract FreeType API names from header files\n"
+    "\n"
+    "This program extracts the list of public FreeType API functions.\n"
+    "It receives a list of header files as an argument and\n"
+    "generates a sorted list of unique identifiers in various formats.\n"
+    "\n"
+    "usage: %s header1 [options] [header2 ...]\n"
+    "\n"
+    "options:   -       parse the contents of stdin, ignore arguments\n"
+    "           -v      verbose mode, output sent to standard error\n"
+    "           -oFILE  write output to FILE instead of standard output\n"
+    "           -dNAME  indicate DLL file name, 'freetype.dll' by default\n"
+    "           -w      output .DEF file for Visual C++ and Mingw\n"
+    "           -wB     output .DEF file for Borland C++\n"
+    "           -wW     output Watcom Linker Response File\n"
+    "           -wV     output OpenVMS Linker Options File\n"
+    "           -wN     output NetWare Import File\n"
+    "           -wL     output version map for GNU or Solaris linker\n"
+    "\n";
 
   fprintf( stderr,
            format,
            PROGRAM_NAME,
            PROGRAM_VERSION,
-           PROGRAM_NAME
-           );
-  exit(1);
+           PROGRAM_NAME );
+
+  exit( 1 );
 }
 
 
-int  main( int argc, const char* const*  argv )
+int
+main( int                 argc,
+      const char* const*  argv )
 {
-  int           from_stdin = 0;
-  int           verbose = 0;
-  OutputFormat  format = OUTPUT_LIST;  /* the default */
-  FILE*         out    = stdout;
+  int           from_stdin   = 0;
+  int           verbose      = 0;
+  OutputFormat  format       = OUTPUT_LIST;  /* the default */
+  FILE*         out          = stdout;
   const char*   library_name = NULL;
 
+
   if ( argc < 2 )
     usage();
 
-  /* '-' used as a single argument means read source file from stdin */
+  /* `-' used as a single argument means read source file from stdin */
   while ( argc > 1 && argv[1][0] == '-' )
   {
     const char*  arg = argv[1];
 
+
     switch ( arg[1] )
     {
-      case 'v':
-        verbose = 1;
+    case 'v':
+      verbose = 1;
+
+      break;
+
+    case 'o':
+      if ( arg[2] == 0 )
+      {
+        if ( argc < 2 )
+          usage();
+
+        arg = argv[2];
+        argv++;
+        argc--;
+      }
+      else
+        arg += 2;
+
+      out = fopen( arg, "wt" );
+      if ( !out )
+      {
+        fprintf( stderr, "could not open '%s' for writing\n", arg );
+        exit( 3 );
+      }
+
+      break;
+
+    case 'd':
+      if ( arg[2] == 0 )
+      {
+        if ( argc < 2 )
+          usage();
+
+        arg = argv[2];
+        argv++;
+        argc--;
+      }
+      else
+        arg += 2;
+
+      library_name = arg;
+
+      break;
+
+    case 'w':
+      format = OUTPUT_WINDOWS_DEF;
+
+      switch ( arg[2] )
+      {
+      case 'B':
+        format = OUTPUT_BORLAND_DEF;
         break;
 
-      case 'o':
-        if ( arg[2] == 0 )
-        {
-          if ( argc < 2 )
-            usage();
-
-          arg = argv[2];
-          argv++;
-          argc--;
-        }
-        else
-          arg += 2;
-
-        out = fopen( arg, "wt" );
-        if ( !out )
-        {
-          fprintf( stderr, "could not open '%s' for writing\n", argv[2] );
-          exit(3);
-        }
+      case 'W':
+        format = OUTPUT_WATCOM_LBC;
         break;
 
-      case 'd':
-        if ( arg[2] == 0 )
-        {
-          if ( argc < 2 )
-            usage();
-
-          arg = argv[2];
-          argv++;
-          argc--;
-        }
-        else
-          arg += 2;
-
-        library_name = arg;
+      case 'V':
+        format = OUTPUT_VMS_OPT;
         break;
 
-      case 'w':
-        format = OUTPUT_WINDOWS_DEF;
-        switch ( arg[2] )
-        {
-          case 'B':
-            format = OUTPUT_BORLAND_DEF;
-            break;
+      case 'N':
+        format = OUTPUT_NETWARE_IMP;
+        break;
 
-          case 'W':
-            format = OUTPUT_WATCOM_LBC;
-            break;
-
-          case 'N':
-            format = OUTPUT_NETWARE_IMP;
-            break;
-
-          case 'L':
-            format = OUTPUT_GNU_VERMAP;
-            break;
-
-          case 0:
-            break;
-
-          default:
-            usage();
-        }
+      case 'L':
+        format = OUTPUT_GNU_VERMAP;
         break;
 
       case 0:
-        from_stdin = 1;
         break;
 
       default:
         usage();
+      }
+
+      break;
+
+    case 0:
+      from_stdin = 1;
+
+      break;
+
+    default:
+      usage();
     }
 
     argc--;
     argv++;
-  }
+
+  } /* end of while loop */
 
   if ( from_stdin )
-  {
     read_header_file( stdin, verbose );
-  }
   else
   {
     for ( --argc, argv++; argc > 0; argc--, argv++ )
     {
       FILE*  file = fopen( argv[0], "rb" );
 
+
       if ( !file )
         fprintf( stderr, "unable to open '%s'\n", argv[0] );
       else
@@ -469,7 +515,7 @@
   }
 
   if ( num_names == 0 )
-    panic( "could not find exported functions !!\n" );
+    panic( "could not find exported functions\n" );
 
   names_sort();
   names_dump( out, format, library_name );
@@ -479,3 +525,6 @@
 
   return 0;
 }
+
+
+/* END */
diff --git a/src/tools/chktrcmp.py b/src/tools/chktrcmp.py
index 4c40bda..d072a87 100755
--- a/src/tools/chktrcmp.py
+++ b/src/tools/chktrcmp.py
@@ -1,114 +1,119 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Check trace components in FreeType 2 source.
-# Author: suzuki toshiya, 2009, 2013
+# Author: suzuki toshiya, 2009, 2013, 2020
 #
 # This code is explicitly into the public domain.
 
-
 import sys
 import os
 import re
 
-SRC_FILE_LIST   = []
-USED_COMPONENT  = {}
+SRC_FILE_LIST = []
+USED_COMPONENT = {}
 KNOWN_COMPONENT = {}
 
-SRC_FILE_DIRS   = [ "src" ]
-TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ]
+SRC_FILE_DIRS = ["src"]
+TRACE_DEF_FILES = ["include/freetype/internal/fttrace.h"]
+
+
+def usage():
+    print("Usage: %s [option]" % sys.argv[0])
+    print("Search used-but-defined and defined-but-not-used trace_XXX macros")
+    print("")
+    print("  --help:")
+    print("        Show this help")
+    print("")
+    print("  --src-dirs=dir1:dir2:...")
+    print("        Specify the directories of C source files to be checked")
+    print("        Default is %s" % ":".join(SRC_FILE_DIRS))
+    print("")
+    print("  --def-files=file1:file2:...")
+    print("        Specify the header files including FT_TRACE_DEF()")
+    print("        Default is %s" % ":".join(TRACE_DEF_FILES))
+    print("")
 
 
 # --------------------------------------------------------------
 # Parse command line options
 #
-
-for i in range( 1, len( sys.argv ) ):
-  if sys.argv[i].startswith( "--help" ):
-    print "Usage: %s [option]" % sys.argv[0]
-    print "Search used-but-defined and defined-but-not-used trace_XXX macros"
-    print ""
-    print "  --help:"
-    print "        Show this help"
-    print ""
-    print "  --src-dirs=dir1:dir2:..."
-    print "        Specify the directories of C source files to be checked"
-    print "        Default is %s" % ":".join( SRC_FILE_DIRS )
-    print ""
-    print "  --def-files=file1:file2:..."
-    print "        Specify the header files including FT_TRACE_DEF()"
-    print "        Default is %s" % ":".join( TRACE_DEF_FILES )
-    print ""
-    exit(0)
-  if sys.argv[i].startswith( "--src-dirs=" ):
-    SRC_FILE_DIRS = sys.argv[i].replace( "--src-dirs=", "", 1 ).split( ":" )
-  elif sys.argv[i].startswith( "--def-files=" ):
-    TRACE_DEF_FILES = sys.argv[i].replace( "--def-files=", "", 1 ).split( ":" )
-
+for i in range(1, len(sys.argv)):
+    if sys.argv[i].startswith("--help"):
+        usage()
+        exit(0)
+    if sys.argv[i].startswith("--src-dirs="):
+        SRC_FILE_DIRS = sys.argv[i].replace("--src-dirs=", "", 1).split(":")
+    elif sys.argv[i].startswith("--def-files="):
+        TRACE_DEF_FILES = sys.argv[i].replace("--def-files=", "", 1).split(":")
 
 # --------------------------------------------------------------
 # Scan C source and header files using trace macros.
 #
 
-c_pathname_pat = re.compile( '^.*\.[ch]$', re.IGNORECASE )
-trace_use_pat  = re.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' )
+c_pathname_pat = re.compile('^.*\.[ch]$', re.IGNORECASE)
+trace_use_pat = re.compile('^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+')
 
 for d in SRC_FILE_DIRS:
-  for ( p, dlst, flst ) in os.walk( d ):
-    for f in flst:
-      if c_pathname_pat.match( f ) != None:
-        src_pathname = os.path.join( p, f )
+    for (p, dlst, flst) in os.walk(d):
+        for f in flst:
+            if c_pathname_pat.match(f) is not None:
+                src_pathname = os.path.join(p, f)
 
-        line_num = 0
-        for src_line in open( src_pathname, 'r' ):
-          line_num = line_num + 1
-          src_line = src_line.strip()
-          if trace_use_pat.match( src_line ) != None:
-            component_name = trace_use_pat.sub( '', src_line )
-            if component_name in USED_COMPONENT:
-              USED_COMPONENT[component_name].append( "%s:%d" % ( src_pathname, line_num ) )
-            else:
-              USED_COMPONENT[component_name] = [ "%s:%d" % ( src_pathname, line_num ) ]
-
+                line_num = 0
+                for src_line in open(src_pathname, 'r'):
+                    line_num = line_num + 1
+                    src_line = src_line.strip()
+                    if trace_use_pat.match(src_line) is not None:
+                        component_name = trace_use_pat.sub('', src_line)
+                        if component_name in USED_COMPONENT:
+                            USED_COMPONENT[component_name]\
+                                .append("%s:%d" % (src_pathname, line_num))
+                        else:
+                            USED_COMPONENT[component_name] =\
+                                ["%s:%d" % (src_pathname, line_num)]
 
 # --------------------------------------------------------------
 # Scan header file(s) defining trace macros.
 #
 
-trace_def_pat_opn = re.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' )
-trace_def_pat_cls = re.compile( '[ \t\)].*$' )
+trace_def_pat_opn = re.compile('^.*FT_TRACE_DEF[ \t]*\([ \t]*')
+trace_def_pat_cls = re.compile('[ \t\)].*$')
 
 for f in TRACE_DEF_FILES:
-  line_num = 0
-  for hdr_line in open( f, 'r' ):
-    line_num = line_num + 1
-    hdr_line = hdr_line.strip()
-    if trace_def_pat_opn.match( hdr_line ) != None:
-      component_name = trace_def_pat_opn.sub( '', hdr_line )
-      component_name = trace_def_pat_cls.sub( '', component_name )
-      if component_name in KNOWN_COMPONENT:
-        print "trace component %s is defined twice, see %s and fttrace.h:%d" % \
-          ( component_name, KNOWN_COMPONENT[component_name], line_num )
-      else:
-        KNOWN_COMPONENT[component_name] = "%s:%d" % \
-          ( os.path.basename( f ), line_num )
-
+    line_num = 0
+    for hdr_line in open(f, 'r'):
+        line_num = line_num + 1
+        hdr_line = hdr_line.strip()
+        if trace_def_pat_opn.match(hdr_line) is not None:
+            component_name = trace_def_pat_opn.sub('', hdr_line)
+            component_name = trace_def_pat_cls.sub('', component_name)
+            if component_name in KNOWN_COMPONENT:
+                print("trace component %s is defined twice,"
+                      " see %s and fttrace.h:%d" %
+                      (component_name, KNOWN_COMPONENT[component_name],
+                       line_num))
+            else:
+                KNOWN_COMPONENT[component_name] =\
+                    "%s:%d" % (os.path.basename(f), line_num)
 
 # --------------------------------------------------------------
 # Compare the used and defined trace macros.
 #
 
-print "# Trace component used in the implementations but not defined in fttrace.h."
-cmpnt = USED_COMPONENT.keys()
+print("# Trace component used in the implementations but not defined in "
+      "fttrace.h.")
+cmpnt = list(USED_COMPONENT.keys())
 cmpnt.sort()
 for c in cmpnt:
-  if c not in KNOWN_COMPONENT:
-    print "Trace component %s (used in %s) is not defined." % ( c, ", ".join( USED_COMPONENT[c] ) )
+    if c not in KNOWN_COMPONENT:
+        print("Trace component %s (used in %s) is not defined." %
+              (c, ", ".join(USED_COMPONENT[c])))
 
-print "# Trace component is defined but not used in the implementations."
-cmpnt = KNOWN_COMPONENT.keys()
+print("# Trace component is defined but not used in the implementations.")
+cmpnt = list(KNOWN_COMPONENT.keys())
 cmpnt.sort()
 for c in cmpnt:
-  if c not in USED_COMPONENT:
-    if c != "any":
-      print "Trace component %s (defined in %s) is not used." % ( c, KNOWN_COMPONENT[c] )
-
+    if c not in USED_COMPONENT:
+        if c != "any":
+            print("Trace component %s (defined in %s) is not used." %
+                  (c, KNOWN_COMPONENT[c]))
diff --git a/src/tools/cordic.py b/src/tools/cordic.py
index 6742c90..6511429 100644
--- a/src/tools/cordic.py
+++ b/src/tools/cordic.py
@@ -1,33 +1,32 @@
+#!/usr/bin/env python3
+
 # compute arctangent table for CORDIC computations in fttrigon.c
-import sys, math
+import math
 
-#units  = 64*65536.0   # don't change !!
-units  = 180 * 2**16
-scale  = units/math.pi
+# units  = 64*65536.0   # don't change !!
+units = 180 * 2 ** 16
+scale = units / math.pi
 shrink = 1.0
-comma  = ""
+angles2 = []
 
-print ""
-print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units"
+print("")
+print("table of arctan( 1/2^n ) for PI = " + repr(units / 65536.0) + " units")
 
-for n in range(1,32):
+for n in range(1, 32):
 
-    x = 0.5**n                      # tangent value
+    x = 0.5 ** n  # tangent value
 
-    angle  = math.atan(x)           # arctangent
-    angle2 = round(angle*scale)     # arctangent in FT_Angle units
+    angle = math.atan(x)  # arctangent
+    angle2 = round(angle * scale)  # arctangent in FT_Angle units
 
     if angle2 <= 0:
         break
 
-    sys.stdout.write( comma + repr( int(angle2) ) )
-    comma = ", "
+    angles2.append(repr(int(angle2)))
+    shrink /= math.sqrt(1 + x * x)
 
-    shrink /= math.sqrt( 1 + x*x )
-
-print
-print "shrink factor    = " + repr( shrink )
-print "shrink factor 2  = " + repr( int( shrink * (2**32) ) )
-print "expansion factor = " + repr( 1/shrink )
-print ""
-
+print(", ".join(angles2))
+print("shrink factor    = " + repr(shrink))
+print("shrink factor 2  = " + repr(int(shrink * (2 ** 32))))
+print("expansion factor = " + repr(1 / shrink))
+print("")
diff --git a/src/tools/docmaker/.gitignore b/src/tools/docmaker/.gitignore
deleted file mode 100644
index 0d20b64..0000000
--- a/src/tools/docmaker/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.pyc
diff --git a/src/tools/docmaker/content.py b/src/tools/docmaker/content.py
deleted file mode 100644
index 198780a..0000000
--- a/src/tools/docmaker/content.py
+++ /dev/null
@@ -1,672 +0,0 @@
-#
-#  content.py
-#
-#    Parse comment blocks to build content blocks (library file).
-#
-#  Copyright 2002-2018 by
-#  David Turner.
-#
-#  This file is part of the FreeType project, and may only be used,
-#  modified, and distributed under the terms of the FreeType project
-#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
-#  this file you indicate that you have read the license and
-#  understand and accept it fully.
-
-#
-# This file contains routines to parse documentation comment blocks,
-# building more structured objects out of them.
-#
-
-
-from sources import *
-from utils   import *
-
-import string, re
-
-
-#
-# Regular expressions to detect code sequences.  `Code sequences' are simply
-# code fragments embedded in '{' and '}', as demonstrated in the following
-# example.
-#
-#   {
-#     x = y + z;
-#     if ( zookoo == 2 )
-#     {
-#       foobar();
-#     }
-#   }
-#
-# Note that the indentation of the first opening brace and the last closing
-# brace must be exactly the same.  The code sequence itself should have a
-# larger indentation than the surrounding braces.
-#
-re_code_start = re.compile( r"(\s*){\s*$" )
-re_code_end   = re.compile( r"(\s*)}\s*$" )
-
-
-#
-# A regular expression to isolate identifiers from other text.  Two syntax
-# forms are supported:
-#
-#   <name>
-#   <name>[<id>]
-#
-# where both `<name>' and `<id>' consist of alphanumeric characters, `_',
-# and `-'.  Use `<id>' if there are multiple, valid `<name>' entries; in the
-# index, `<id>' will be appended in parentheses.
-#
-# For example,
-#
-#   stem_darkening[autofit]
-#
-# becomes `stem_darkening (autofit)' in the index.
-#
-re_identifier = re.compile( r"""
-                              ((?:\w|-)+
-                               (?:\[(?:\w|-)+\])?)
-                            """, re.VERBOSE )
-
-
-#
-# We collect macro names ending in `_H' (group 1), as defined in
-# `freetype/config/ftheader.h'.  While outputting the object data, we use
-# this info together with the object's file location (group 2) to emit the
-# appropriate header file macro and its associated file name before the
-# object itself.
-#
-# Example:
-#
-#   #define FT_FREETYPE_H <freetype.h>
-#
-re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' )
-
-
-################################################################
-##
-##  DOC CODE CLASS
-##
-##  The `DocCode' class is used to store source code lines.
-##
-##  `self.lines' contains a set of source code lines that will be dumped as
-##  HTML in a <PRE> tag.
-##
-##  The object is filled line by line by the parser; it strips the leading
-##  `margin' space from each input line before storing it in `self.lines'.
-##
-class  DocCode:
-
-    def  __init__( self, margin, lines ):
-        self.lines = []
-        self.words = None
-
-        # remove margin spaces
-        for l in lines:
-            if string.strip( l[:margin] ) == "":
-                l = l[margin:]
-            self.lines.append( l )
-
-    def  dump( self, prefix = "", width = 60 ):
-        lines = self.dump_lines( 0, width )
-        for l in lines:
-            print( prefix + l )
-
-    def  dump_lines( self, margin = 0, width = 60 ):
-        result = []
-        for l in self.lines:
-            result.append( " " * margin + l )
-        return result
-
-
-
-################################################################
-##
-##  DOC PARA CLASS
-##
-##  `Normal' text paragraphs are stored in the `DocPara' class.
-##
-##  `self.words' contains the list of words that make up the paragraph.
-##
-class  DocPara:
-
-    def  __init__( self, lines ):
-        self.lines = None
-        self.words = []
-        for l in lines:
-            l = string.strip( l )
-            self.words.extend( string.split( l ) )
-
-    def  dump( self, prefix = "", width = 60 ):
-        lines = self.dump_lines( 0, width )
-        for l in lines:
-            print( prefix + l )
-
-    def  dump_lines( self, margin = 0, width = 60 ):
-        cur    = ""  # current line
-        col    = 0   # current width
-        result = []
-
-        for word in self.words:
-            ln = len( word )
-            if col > 0:
-                ln = ln + 1
-
-            if col + ln > width:
-                result.append( " " * margin + cur )
-                cur = word
-                col = len( word )
-            else:
-                if col > 0:
-                    cur = cur + " "
-                cur = cur + word
-                col = col + ln
-
-        if col > 0:
-            result.append( " " * margin + cur )
-
-        return result
-
-
-################################################################
-##
-##  DOC FIELD CLASS
-##
-##  The `DocField' class stores a list containing either `DocPara' or
-##  `DocCode' objects.  Each DocField object also has an optional `name'
-##  that is used when the object corresponds to a field or value definition.
-##
-class  DocField:
-
-    def  __init__( self, name, lines ):
-        self.name  = name  # can be `None' for normal paragraphs/sources
-        self.items = []    # list of items
-
-        mode_none  = 0     # start parsing mode
-        mode_code  = 1     # parsing code sequences
-        mode_para  = 3     # parsing normal paragraph
-
-        margin     = -1    # current code sequence indentation
-        cur_lines  = []
-
-        # analyze the markup lines to check whether they contain paragraphs,
-        # code sequences, or fields definitions
-        #
-        start = 0
-        mode  = mode_none
-
-        for l in lines:
-            # are we parsing a code sequence?
-            if mode == mode_code:
-                m = re_code_end.match( l )
-                if m and len( m.group( 1 ) ) <= margin:
-                    # that's it, we finished the code sequence
-                    code = DocCode( 0, cur_lines )
-                    self.items.append( code )
-                    margin    = -1
-                    cur_lines = []
-                    mode      = mode_none
-                else:
-                    # otherwise continue the code sequence
-                    cur_lines.append( l[margin:] )
-            else:
-                # start of code sequence?
-                m = re_code_start.match( l )
-                if m:
-                    # save current lines
-                    if cur_lines:
-                        para = DocPara( cur_lines )
-                        self.items.append( para )
-                        cur_lines = []
-
-                    # switch to code extraction mode
-                    margin = len( m.group( 1 ) )
-                    mode   = mode_code
-                else:
-                    if not string.split( l ) and cur_lines:
-                        # if the line is empty, we end the current paragraph,
-                        # if any
-                        para = DocPara( cur_lines )
-                        self.items.append( para )
-                        cur_lines = []
-                    else:
-                        # otherwise, simply add the line to the current
-                        # paragraph
-                        cur_lines.append( l )
-
-        if mode == mode_code:
-            # unexpected end of code sequence
-            code = DocCode( margin, cur_lines )
-            self.items.append( code )
-        elif cur_lines:
-            para = DocPara( cur_lines )
-            self.items.append( para )
-
-    def  dump( self, prefix = "" ):
-        if self.field:
-            print( prefix + self.field + " ::" )
-            prefix = prefix + "----"
-
-        first = 1
-        for p in self.items:
-            if not first:
-                print( "" )
-            p.dump( prefix )
-            first = 0
-
-    def  dump_lines( self, margin = 0, width = 60 ):
-        result = []
-        nl     = None
-
-        for p in self.items:
-            if nl:
-                result.append( "" )
-
-            result.extend( p.dump_lines( margin, width ) )
-            nl = 1
-
-        return result
-
-
-#
-# A regular expression to detect field definitions.
-#
-# Examples:
-#
-#   foo     ::
-#   foo.bar ::
-#
-re_field = re.compile( r"""
-                         \s*
-                           (
-                             \w*
-                           |
-                             \w (\w | \.)* \w
-                           )
-                         \s* ::
-                       """, re.VERBOSE )
-
-
-################################################################
-##
-##  DOC MARKUP CLASS
-##
-class  DocMarkup:
-
-    def  __init__( self, tag, lines ):
-        self.tag    = string.lower( tag )
-        self.fields = []
-
-        cur_lines = []
-        field     = None
-        mode      = 0
-
-        for l in lines:
-            m = re_field.match( l )
-            if m:
-                # We detected the start of a new field definition.
-
-                # first, save the current one
-                if cur_lines:
-                    f = DocField( field, cur_lines )
-                    self.fields.append( f )
-                    cur_lines = []
-                    field     = None
-
-                field     = m.group( 1 )   # record field name
-                ln        = len( m.group( 0 ) )
-                l         = " " * ln + l[ln:]
-                cur_lines = [l]
-            else:
-                cur_lines.append( l )
-
-        if field or cur_lines:
-            f = DocField( field, cur_lines )
-            self.fields.append( f )
-
-    def  get_name( self ):
-        try:
-            return self.fields[0].items[0].words[0]
-        except:
-            return None
-
-    def  dump( self, margin ):
-        print( " " * margin + "<" + self.tag + ">" )
-        for f in self.fields:
-            f.dump( "  " )
-        print( " " * margin + "</" + self.tag + ">" )
-
-
-################################################################
-##
-##  DOC CHAPTER CLASS
-##
-class  DocChapter:
-
-    def  __init__( self, block ):
-        self.block    = block
-        self.sections = []
-        if block:
-            self.name  = block.name
-            self.title = block.get_markup_words( "title" )
-            self.order = block.get_markup_words( "sections" )
-        else:
-            self.name  = "Other"
-            self.title = string.split( "Miscellaneous" )
-            self.order = []
-
-
-################################################################
-##
-##  DOC SECTION CLASS
-##
-class  DocSection:
-
-    def  __init__( self, name = "Other" ):
-        self.name        = name
-        self.blocks      = {}
-        self.block_names = []  # ordered block names in section
-        self.defs        = []
-        self.abstract    = ""
-        self.description = ""
-        self.order       = []
-        self.title       = "ERROR"
-        self.chapter     = None
-
-    def  add_def( self, block ):
-        self.defs.append( block )
-
-    def  add_block( self, block ):
-        self.block_names.append( block.name )
-        self.blocks[block.name] = block
-
-    def  process( self ):
-        # look up one block that contains a valid section description
-        for block in self.defs:
-            title = block.get_markup_text( "title" )
-            if title:
-                self.title       = title
-                self.abstract    = block.get_markup_words( "abstract" )
-                self.description = block.get_markup_items( "description" )
-                self.order       = block.get_markup_words_all( "order" )
-                return
-
-    def  reorder( self ):
-        self.block_names = sort_order_list( self.block_names, self.order )
-
-
-################################################################
-##
-##  CONTENT PROCESSOR CLASS
-##
-class  ContentProcessor:
-
-    def  __init__( self ):
-        """Initialize a block content processor."""
-        self.reset()
-
-        self.sections = {}    # dictionary of documentation sections
-        self.section  = None  # current documentation section
-
-        self.chapters = []    # list of chapters
-
-        self.headers  = {}    # dictionary of header macros
-
-    def  set_section( self, section_name ):
-        """Set current section during parsing."""
-        if not section_name in self.sections:
-            section = DocSection( section_name )
-            self.sections[section_name] = section
-            self.section                = section
-        else:
-            self.section = self.sections[section_name]
-
-    def  add_chapter( self, block ):
-        chapter = DocChapter( block )
-        self.chapters.append( chapter )
-
-    def  reset( self ):
-        """Reset the content processor for a new block."""
-        self.markups      = []
-        self.markup       = None
-        self.markup_lines = []
-
-    def  add_markup( self ):
-        """Add a new markup section."""
-        if self.markup and self.markup_lines:
-
-            # get rid of last line of markup if it's empty
-            marks = self.markup_lines
-            if len( marks ) > 0 and not string.strip( marks[-1] ):
-                self.markup_lines = marks[:-1]
-
-            m = DocMarkup( self.markup, self.markup_lines )
-
-            self.markups.append( m )
-
-            self.markup       = None
-            self.markup_lines = []
-
-    def  process_content( self, content ):
-        """Process a block content and return a list of DocMarkup objects
-           corresponding to it."""
-        markup       = None
-        markup_lines = []
-        first        = 1
-
-        margin  = -1
-        in_code = 0
-
-        for line in content:
-            if in_code:
-                m = re_code_end.match( line )
-                if m and len( m.group( 1 ) ) <= margin:
-                    in_code = 0
-                    margin  = -1
-            else:
-                m = re_code_start.match( line )
-                if m:
-                    in_code = 1
-                    margin  = len( m.group( 1 ) )
-
-            found = None
-
-            if not in_code:
-                for t in re_markup_tags:
-                    m = t.match( line )
-                    if m:
-                        found  = string.lower( m.group( 1 ) )
-                        prefix = len( m.group( 0 ) )
-                        # remove markup from line
-                        line   = " " * prefix + line[prefix:]
-                        break
-
-            # is it the start of a new markup section ?
-            if found:
-                first = 0
-                self.add_markup()  # add current markup content
-                self.markup = found
-                if len( string.strip( line ) ) > 0:
-                    self.markup_lines.append( line )
-            elif first == 0:
-                self.markup_lines.append( line )
-
-        self.add_markup()
-
-        return self.markups
-
-    def  parse_sources( self, source_processor ):
-        blocks = source_processor.blocks
-        count  = len( blocks )
-
-        for n in range( count ):
-            source = blocks[n]
-            if source.content:
-                # this is a documentation comment, we need to catch
-                # all following normal blocks in the "follow" list
-                #
-                follow = []
-                m = n + 1
-                while m < count and not blocks[m].content:
-                    follow.append( blocks[m] )
-                    m = m + 1
-
-                doc_block = DocBlock( source, follow, self )
-
-    def  finish( self ):
-        # process all sections to extract their abstract, description
-        # and ordered list of items
-        #
-        for sec in self.sections.values():
-            sec.process()
-
-        # process chapters to check that all sections are correctly
-        # listed there
-        for chap in self.chapters:
-            for sec in chap.order:
-                if sec in self.sections:
-                    section = self.sections[sec]
-                    section.chapter = chap
-                    section.reorder()
-                    chap.sections.append( section )
-                else:
-                    sys.stderr.write( "WARNING: chapter '" +          \
-                        chap.name + "' in " + chap.block.location() + \
-                        " lists unknown section '" + sec + "'\n" )
-
-        # check that all sections are in a chapter
-        #
-        others = []
-        for sec in self.sections.values():
-            if not sec.chapter:
-                sec.reorder()
-                others.append( sec )
-
-        # create a new special chapter for all remaining sections
-        # when necessary
-        #
-        if others:
-            chap = DocChapter( None )
-            chap.sections = others
-            self.chapters.append( chap )
-
-
-################################################################
-##
-##  DOC BLOCK CLASS
-##
-class  DocBlock:
-
-    def  __init__( self, source, follow, processor ):
-        processor.reset()
-
-        self.source  = source
-        self.code    = []
-        self.type    = "ERRTYPE"
-        self.name    = "ERRNAME"
-        self.section = processor.section
-        self.markups = processor.process_content( source.content )
-
-        # compute block type from first markup tag
-        try:
-            self.type = self.markups[0].tag
-        except:
-            pass
-
-        # compute block name from first markup paragraph
-        try:
-            markup = self.markups[0]
-            para   = markup.fields[0].items[0]
-            name   = para.words[0]
-            m = re_identifier.match( name )
-            if m:
-                name = m.group( 1 )
-            self.name = name
-        except:
-            pass
-
-        if self.type == "section":
-            # detect new section starts
-            processor.set_section( self.name )
-            processor.section.add_def( self )
-        elif self.type == "chapter":
-            # detect new chapter
-            processor.add_chapter( self )
-        else:
-            processor.section.add_block( self )
-
-        # now, compute the source lines relevant to this documentation
-        # block. We keep normal comments in for obvious reasons (??)
-        source = []
-        for b in follow:
-            if b.format:
-                break
-            for l in b.lines:
-                # collect header macro definitions
-                m = re_header_macro.match( l )
-                if m:
-                    processor.headers[m.group( 2 )] = m.group( 1 );
-
-                # we use "/* */" as a separator
-                if re_source_sep.match( l ):
-                    break
-                source.append( l )
-
-        # now strip the leading and trailing empty lines from the sources
-        start = 0
-        end   = len( source ) - 1
-
-        while start < end and not string.strip( source[start] ):
-            start = start + 1
-
-        while start < end and not string.strip( source[end] ):
-            end = end - 1
-
-        if start == end and not string.strip( source[start] ):
-            self.code = []
-        else:
-            self.code = source[start:end + 1]
-
-    def  location( self ):
-        return self.source.location()
-
-    def  get_markup( self, tag_name ):
-        """Return the DocMarkup corresponding to a given tag in a block."""
-        for m in self.markups:
-            if m.tag == string.lower( tag_name ):
-                return m
-        return None
-
-    def  get_markup_words( self, tag_name ):
-        try:
-            m = self.get_markup( tag_name )
-            return m.fields[0].items[0].words
-        except:
-            return []
-
-    def  get_markup_words_all( self, tag_name ):
-        try:
-            m = self.get_markup( tag_name )
-            words = []
-            for item in m.fields[0].items:
-                # We honour empty lines in an `<Order>' section element by
-                # adding the sentinel `/empty/'.  The formatter should then
-                # convert it to an appropriate representation in the
-                # `section_enter' function.
-                words += item.words
-                words.append( "/empty/" )
-            return words
-        except:
-            return []
-
-    def  get_markup_text( self, tag_name ):
-        result = self.get_markup_words( tag_name )
-        return string.join( result )
-
-    def  get_markup_items( self, tag_name ):
-        try:
-            m = self.get_markup( tag_name )
-            return m.fields[0].items
-        except:
-            return None
-
-# eof
diff --git a/src/tools/docmaker/docbeauty.py b/src/tools/docmaker/docbeauty.py
deleted file mode 100644
index 0b021fa..0000000
--- a/src/tools/docmaker/docbeauty.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env python
-#
-#  DocBeauty (c) 2003, 2004, 2008 David Turner <david@freetype.org>
-#
-# This program is used to beautify the documentation comments used
-# in the FreeType 2 public headers.
-#
-
-from sources import *
-from content import *
-from utils   import *
-
-import sys, os, string, getopt
-
-
-content_processor = ContentProcessor()
-
-
-def  beautify_block( block ):
-    if block.content:
-        content_processor.reset()
-
-        markups = content_processor.process_content( block.content )
-        text    = []
-        first   = 1
-
-        for markup in markups:
-            text.extend( markup.beautify( first ) )
-            first = 0
-
-        # now beautify the documentation "borders" themselves
-        lines = [" /*************************************************************************"]
-        for l in text:
-            lines.append( "  *" + l )
-        lines.append( "  */" )
-
-        block.lines = lines
-
-
-def  usage():
-    print( "\nDocBeauty 0.1 Usage information\n" )
-    print( "  docbeauty [options] file1 [file2 ...]\n" )
-    print( "using the following options:\n" )
-    print( "  -h : print this page" )
-    print( "  -b : backup original files with the 'orig' extension" )
-    print( "" )
-    print( "  --backup : same as -b" )
-
-
-def  main( argv ):
-    """main program loop"""
-
-    global output_dir
-
-    try:
-        opts, args = getopt.getopt( sys.argv[1:], \
-                                    "hb",         \
-                                    ["help", "backup"] )
-    except getopt.GetoptError:
-        usage()
-        sys.exit( 2 )
-
-    if args == []:
-        usage()
-        sys.exit( 1 )
-
-    # process options
-    #
-    output_dir = None
-    do_backup  = None
-
-    for opt in opts:
-        if opt[0] in ( "-h", "--help" ):
-            usage()
-            sys.exit( 0 )
-
-        if opt[0] in ( "-b", "--backup" ):
-            do_backup = 1
-
-    # create context and processor
-    source_processor = SourceProcessor()
-
-    # retrieve the list of files to process
-    file_list = make_file_list( args )
-    for filename in file_list:
-        source_processor.parse_file( filename )
-
-        for block in source_processor.blocks:
-            beautify_block( block )
-
-        new_name = filename + ".new"
-        ok       = None
-
-        try:
-            file = open( new_name, "wt" )
-            for block in source_processor.blocks:
-                for line in block.lines:
-                    file.write( line )
-                    file.write( "\n" )
-            file.close()
-        except:
-            ok = 0
-
-
-# if called from the command line
-#
-if __name__ == '__main__':
-    main( sys.argv )
-
-
-# eof
diff --git a/src/tools/docmaker/docmaker.py b/src/tools/docmaker/docmaker.py
deleted file mode 100644
index eb49afb..0000000
--- a/src/tools/docmaker/docmaker.py
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-#
-#  docmaker.py
-#
-#    Convert source code markup to HTML documentation.
-#
-#  Copyright 2002-2018 by
-#  David Turner.
-#
-#  This file is part of the FreeType project, and may only be used,
-#  modified, and distributed under the terms of the FreeType project
-#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
-#  this file you indicate that you have read the license and
-#  understand and accept it fully.
-
-#
-# This program is a re-write of the original DocMaker tool used to generate
-# the API Reference of the FreeType font rendering engine by converting
-# in-source comments into structured HTML.
-#
-# This new version is capable of outputting XML data as well as accepting
-# more liberal formatting options.  It also uses regular expression matching
-# and substitution to speed up operation significantly.
-#
-
-from sources   import *
-from content   import *
-from utils     import *
-from formatter import *
-from tohtml    import *
-
-import utils
-
-import sys, glob, getopt
-
-
-def  usage():
-    print( "\nDocMaker Usage information\n" )
-    print( "  docmaker [options] file1 [file2 ...]\n" )
-    print( "using the following options:\n" )
-    print( "  -h : print this page" )
-    print( "  -t : set project title, as in '-t \"My Project\"'" )
-    print( "  -o : set output directory, as in '-o mydir'" )
-    print( "  -p : set documentation prefix, as in '-p ft2'" )
-    print( "" )
-    print( "  --title  : same as -t, as in '--title=\"My Project\"'" )
-    print( "  --output : same as -o, as in '--output=mydir'" )
-    print( "  --prefix : same as -p, as in '--prefix=ft2'" )
-
-
-def  main( argv ):
-    """Main program loop."""
-
-    global output_dir
-
-    try:
-        opts, args = getopt.getopt( sys.argv[1:],
-                                    "ht:o:p:",
-                                    ["help", "title=", "output=", "prefix="] )
-    except getopt.GetoptError:
-        usage()
-        sys.exit( 2 )
-
-    if args == []:
-        usage()
-        sys.exit( 1 )
-
-    # process options
-    project_title  = "Project"
-    project_prefix = None
-    output_dir     = None
-
-    for opt in opts:
-        if opt[0] in ( "-h", "--help" ):
-            usage()
-            sys.exit( 0 )
-
-        if opt[0] in ( "-t", "--title" ):
-            project_title = opt[1]
-
-        if opt[0] in ( "-o", "--output" ):
-            utils.output_dir = opt[1]
-
-        if opt[0] in ( "-p", "--prefix" ):
-            project_prefix = opt[1]
-
-    check_output()
-
-    # create context and processor
-    source_processor  = SourceProcessor()
-    content_processor = ContentProcessor()
-
-    # retrieve the list of files to process
-    file_list = make_file_list( args )
-    for filename in file_list:
-        source_processor.parse_file( filename )
-        content_processor.parse_sources( source_processor )
-
-    # process sections
-    content_processor.finish()
-
-    formatter = HtmlFormatter( content_processor,
-                               project_title,
-                               project_prefix )
-
-    formatter.toc_dump()
-    formatter.index_dump()
-    formatter.section_dump_all()
-
-
-# if called from the command line
-if __name__ == '__main__':
-    main( sys.argv )
-
-# eof
diff --git a/src/tools/docmaker/formatter.py b/src/tools/docmaker/formatter.py
deleted file mode 100644
index 2708fd4..0000000
--- a/src/tools/docmaker/formatter.py
+++ /dev/null
@@ -1,228 +0,0 @@
-#
-#  formatter.py
-#
-#    Convert parsed content blocks to a structured document (library file).
-#
-#  Copyright 2002-2018 by
-#  David Turner.
-#
-#  This file is part of the FreeType project, and may only be used,
-#  modified, and distributed under the terms of the FreeType project
-#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
-#  this file you indicate that you have read the license and
-#  understand and accept it fully.
-
-#
-# This is the base Formatter class.  Its purpose is to convert a content
-# processor's data into specific documents (i.e., table of contents, global
-# index, and individual API reference indices).
-#
-# You need to sub-class it to output anything sensible.  For example, the
-# file `tohtml.py' contains the definition of the `HtmlFormatter' sub-class
-# to output HTML.
-#
-
-
-from sources import *
-from content import *
-from utils   import *
-
-
-################################################################
-##
-##  FORMATTER CLASS
-##
-class  Formatter:
-
-    def  __init__( self, processor ):
-        self.processor   = processor
-        self.identifiers = {}
-        self.chapters    = processor.chapters
-        self.sections    = processor.sections.values()
-        self.block_index = []
-
-        # store all blocks in a dictionary
-        self.blocks = []
-        for section in self.sections:
-            for block in section.blocks.values():
-                self.add_identifier( block.name, block )
-
-                # add enumeration values to the index, since this is useful
-                for markup in block.markups:
-                    if markup.tag == 'values':
-                        for field in markup.fields:
-                            self.add_identifier( field.name, block )
-
-        self.block_index = self.identifiers.keys()
-        self.block_index.sort( key = index_key )
-
-        # also add section names to dictionary (without making them appear
-        # in the index)
-        for section in self.sections:
-            self.add_identifier( section.name, section )
-
-    def  add_identifier( self, name, block ):
-        if name in self.identifiers:
-            # duplicate name!
-            sys.stderr.write( "WARNING: duplicate definition for"
-                              + " '" + name + "' "
-                              + "in " + block.location() + ", "
-                              + "previous definition in "
-                              + self.identifiers[name].location()
-                              + "\n" )
-        else:
-            self.identifiers[name] = block
-
-    #
-    # formatting the table of contents
-    #
-    def  toc_enter( self ):
-        pass
-
-    def  toc_chapter_enter( self, chapter ):
-        pass
-
-    def  toc_section_enter( self, section ):
-        pass
-
-    def  toc_section_exit( self, section ):
-        pass
-
-    def  toc_chapter_exit( self, chapter ):
-        pass
-
-    def  toc_index( self, index_filename ):
-        pass
-
-    def  toc_exit( self ):
-        pass
-
-    def  toc_dump( self, toc_filename = None, index_filename = None ):
-        output = None
-        if toc_filename:
-            output = open_output( toc_filename )
-
-        self.toc_enter()
-
-        for chap in self.processor.chapters:
-
-            self.toc_chapter_enter( chap )
-
-            for section in chap.sections:
-                self.toc_section_enter( section )
-                self.toc_section_exit( section )
-
-            self.toc_chapter_exit( chap )
-
-        self.toc_index( index_filename )
-
-        self.toc_exit()
-
-        if output:
-            close_output( output )
-
-    #
-    # formatting the index
-    #
-    def  index_enter( self ):
-        pass
-
-    def  index_name_enter( self, name ):
-        pass
-
-    def  index_name_exit( self, name ):
-        pass
-
-    def  index_exit( self ):
-        pass
-
-    def  index_dump( self, index_filename = None ):
-        output = None
-        if index_filename:
-            output = open_output( index_filename )
-
-        self.index_enter()
-
-        for name in self.block_index:
-            self.index_name_enter( name )
-            self.index_name_exit( name )
-
-        self.index_exit()
-
-        if output:
-            close_output( output )
-
-    #
-    # formatting a section
-    #
-    def  section_enter( self, section ):
-        pass
-
-    def  block_enter( self, block ):
-        pass
-
-    def  markup_enter( self, markup, block = None ):
-        pass
-
-    def  field_enter( self, field, markup = None, block = None ):
-        pass
-
-    def  field_exit( self, field, markup = None, block = None ):
-        pass
-
-    def  markup_exit( self, markup, block = None ):
-        pass
-
-    def  block_exit( self, block ):
-        pass
-
-    def  section_exit( self, section ):
-        pass
-
-    def  section_dump( self, section, section_filename = None ):
-        output = None
-        if section_filename:
-            output = open_output( section_filename )
-
-        self.section_enter( section )
-
-        for name in section.block_names:
-            skip_entry = 0
-            try:
-                block = self.identifiers[name]
-                # `block_names' can contain field names also,
-                # which we filter out
-                for markup in block.markups:
-                    if markup.tag == 'values':
-                        for field in markup.fields:
-                            if field.name == name:
-                                skip_entry = 1
-            except:
-                skip_entry = 1   # this happens e.g. for `/empty/' entries
-
-            if skip_entry:
-              continue
-
-            self.block_enter( block )
-
-            for markup in block.markups[1:]:   # always ignore first markup!
-                self.markup_enter( markup, block )
-
-                for field in markup.fields:
-                    self.field_enter( field, markup, block )
-                    self.field_exit( field, markup, block )
-
-                self.markup_exit( markup, block )
-
-            self.block_exit( block )
-
-        self.section_exit( section )
-
-        if output:
-            close_output( output )
-
-    def  section_dump_all( self ):
-        for section in self.sections:
-            self.section_dump( section )
-
-# eof
diff --git a/src/tools/docmaker/sources.py b/src/tools/docmaker/sources.py
deleted file mode 100644
index e3b95e0..0000000
--- a/src/tools/docmaker/sources.py
+++ /dev/null
@@ -1,410 +0,0 @@
-#
-#  sources.py
-#
-#    Convert source code comments to multi-line blocks (library file).
-#
-#  Copyright 2002-2018 by
-#  David Turner.
-#
-#  This file is part of the FreeType project, and may only be used,
-#  modified, and distributed under the terms of the FreeType project
-#  license, LICENSE.TXT.  By continuing to use, modify, or distribute
-#  this file you indicate that you have read the license and
-#  understand and accept it fully.
-
-#
-# This library file contains definitions of classes needed to decompose C
-# source code files into a series of multi-line `blocks'.  There are two
-# kinds of blocks.
-#
-#   - Normal blocks, which contain source code or ordinary comments.
-#
-#   - Documentation blocks, which have restricted formatting, and whose text
-#     always start with a documentation markup tag like `<Function>',
-#     `<Type>', etc.
-#
-# The routines to process the content of documentation blocks are contained
-# in file `content.py'; the classes and methods found here only deal with
-# text parsing and basic documentation block extraction.
-#
-
-
-import fileinput, re, string
-
-
-################################################################
-##
-##  SOURCE BLOCK FORMAT CLASS
-##
-##  A simple class containing compiled regular expressions to detect
-##  potential documentation format block comments within C source code.
-##
-##  The `column' pattern must contain a group to `unbox' the content of
-##  documentation comment blocks.
-##
-##  Later on, paragraphs are converted to long lines, which simplifies the
-##  regular expressions that act upon the text.
-##
-class  SourceBlockFormat:
-
-    def  __init__( self, id, start, column, end ):
-        """Create a block pattern, used to recognize special documentation
-           blocks."""
-        self.id     = id
-        self.start  = re.compile( start, re.VERBOSE )
-        self.column = re.compile( column, re.VERBOSE )
-        self.end    = re.compile( end, re.VERBOSE )
-
-
-#
-# Format 1 documentation comment blocks.
-#
-#    /************************************/ (at least 2 asterisks)
-#    /*                                  */
-#    /*                                  */
-#    /*                                  */
-#    /************************************/ (at least 2 asterisks)
-#
-start = r'''
-  \s*      # any number of whitespace
-  /\*{2,}/ # followed by '/' and at least two asterisks then '/'
-  \s*$     # probably followed by whitespace
-'''
-
-column = r'''
-  \s*      # any number of whitespace
-  /\*{1}   # followed by '/' and precisely one asterisk
-  ([^*].*) # followed by anything (group 1)
-  \*{1}/   # followed by one asterisk and a '/'
-  \s*$     # probably followed by whitespace
-'''
-
-re_source_block_format1 = SourceBlockFormat( 1, start, column, start )
-
-
-#
-# Format 2 documentation comment blocks.
-#
-#    /************************************ (at least 2 asterisks)
-#     *
-#     *                                    (1 asterisk)
-#     *
-#     */                                   (1 or more asterisks)
-#
-start = r'''
-  \s*     # any number of whitespace
-  /\*{2,} # followed by '/' and at least two asterisks
-  \s*$    # probably followed by whitespace
-'''
-
-column = r'''
-  \s*           # any number of whitespace
-  \*{1}(?![*/]) # followed by precisely one asterisk not followed by `/'
-  (.*)          # then anything (group1)
-'''
-
-end = r'''
-  \s*  # any number of whitespace
-  \*+/ # followed by at least one asterisk, then '/'
-'''
-
-re_source_block_format2 = SourceBlockFormat( 2, start, column, end )
-
-
-#
-# The list of supported documentation block formats.  We could add new ones
-# quite easily.
-#
-re_source_block_formats = [re_source_block_format1, re_source_block_format2]
-
-
-#
-# The following regular expressions correspond to markup tags within the
-# documentation comment blocks.  They are equivalent despite their different
-# syntax.
-#
-# A markup tag consists of letters or character `-', to be found in group 1.
-#
-# Notice that a markup tag _must_ begin a new paragraph.
-#
-re_markup_tag1 = re.compile( r'''\s*<((?:\w|-)*)>''' )  # <xxxx> format
-re_markup_tag2 = re.compile( r'''\s*@((?:\w|-)*):''' )  # @xxxx: format
-
-#
-# The list of supported markup tags.  We could add new ones quite easily.
-#
-re_markup_tags = [re_markup_tag1, re_markup_tag2]
-
-
-#
-# A regular expression to detect a cross reference, after markup tags have
-# been stripped off.
-#
-# Two syntax forms are supported:
-#
-#   @<name>
-#   @<name>[<id>]
-#
-# where both `<name>' and `<id>' consist of alphanumeric characters, `_',
-# and `-'.  Use `<id>' if there are multiple, valid `<name>' entries.
-#
-# Example: @foo[bar]
-#
-re_crossref = re.compile( r"""
-                            @
-                            (?P<name>(?:\w|-)+
-                                     (?:\[(?:\w|-)+\])?)
-                            (?P<rest>.*)
-                          """, re.VERBOSE )
-
-#
-# Two regular expressions to detect italic and bold markup, respectively.
-# Group 1 is the markup, group 2 the rest of the line.
-#
-# Note that the markup is limited to words consisting of letters, digits,
-# the characters `_' and `-', or an apostrophe (but not as the first
-# character).
-#
-re_italic = re.compile( r"_((?:\w|-)(?:\w|'|-)*)_(.*)" )     #  _italic_
-re_bold   = re.compile( r"\*((?:\w|-)(?:\w|'|-)*)\*(.*)" )   #  *bold*
-
-#
-# This regular expression code to identify an URL has been taken from
-#
-#   https://mail.python.org/pipermail/tutor/2002-September/017228.html
-#
-# (with slight modifications).
-#
-urls = r'(?:https?|telnet|gopher|file|wais|ftp)'
-ltrs = r'\w'
-gunk = r'/#~:.?+=&%@!\-'
-punc = r'.:?\-'
-any  = "%(ltrs)s%(gunk)s%(punc)s" % { 'ltrs' : ltrs,
-                                      'gunk' : gunk,
-                                      'punc' : punc }
-url  = r"""
-         (
-           \b                    # start at word boundary
-           %(urls)s :            # need resource and a colon
-           [%(any)s] +?          # followed by one or more of any valid
-                                 # character, but be conservative and
-                                 # take only what you need to...
-           (?=                   # [look-ahead non-consumptive assertion]
-             [%(punc)s]*         # either 0 or more punctuation
-             (?:                 # [non-grouping parentheses]
-               [^%(any)s] | $    # followed by a non-url char
-                                 # or end of the string
-             )
-           )
-         )
-        """ % {'urls' : urls,
-               'any'  : any,
-               'punc' : punc }
-
-re_url = re.compile( url, re.VERBOSE | re.MULTILINE )
-
-#
-# A regular expression that stops collection of comments for the current
-# block.
-#
-re_source_sep = re.compile( r'\s*/\*\s*\*/' )   #  /* */
-
-#
-# A regular expression to find possible C identifiers while outputting
-# source code verbatim, covering things like `*foo' or `(bar'.  Group 1 is
-# the prefix, group 2 the identifier -- since we scan lines from left to
-# right, sequentially splitting the source code into prefix and identifier
-# is fully sufficient for our purposes.
-#
-re_source_crossref = re.compile( r'(\W*)(\w*)' )
-
-#
-# A regular expression that matches a list of reserved C source keywords.
-#
-re_source_keywords = re.compile( '''\\b ( typedef   |
-                                          struct    |
-                                          enum      |
-                                          union     |
-                                          const     |
-                                          char      |
-                                          int       |
-                                          short     |
-                                          long      |
-                                          void      |
-                                          signed    |
-                                          unsigned  |
-                                          \#include |
-                                          \#define  |
-                                          \#undef   |
-                                          \#if      |
-                                          \#ifdef   |
-                                          \#ifndef  |
-                                          \#else    |
-                                          \#endif   ) \\b''', re.VERBOSE )
-
-
-################################################################
-##
-##  SOURCE BLOCK CLASS
-##
-##  There are two important fields in a `SourceBlock' object.
-##
-##    self.lines
-##      A list of text lines for the corresponding block.
-##
-##    self.content
-##      For documentation comment blocks only, this is the block content
-##      that has been `unboxed' from its decoration.  This is `None' for all
-##      other blocks (i.e., sources or ordinary comments with no starting
-##      markup tag)
-##
-class  SourceBlock:
-
-    def  __init__( self, processor, filename, lineno, lines ):
-        self.processor = processor
-        self.filename  = filename
-        self.lineno    = lineno
-        self.lines     = lines[:]
-        self.format    = processor.format
-        self.content   = []
-
-        if self.format == None:
-            return
-
-        words = []
-
-        # extract comment lines
-        lines = []
-
-        for line0 in self.lines:
-            m = self.format.column.match( line0 )
-            if m:
-                lines.append( m.group( 1 ) )
-
-        # now, look for a markup tag
-        for l in lines:
-            l = string.strip( l )
-            if len( l ) > 0:
-                for tag in re_markup_tags:
-                    if tag.match( l ):
-                        self.content = lines
-                        return
-
-    def  location( self ):
-        return "(" + self.filename + ":" + repr( self.lineno ) + ")"
-
-    # debugging only -- not used in normal operations
-    def  dump( self ):
-        if self.content:
-            print( "{{{content start---" )
-            for l in self.content:
-                print( l )
-            print( "---content end}}}" )
-            return
-
-        fmt = ""
-        if self.format:
-            fmt = repr( self.format.id ) + " "
-
-        for line in self.lines:
-            print( line )
-
-
-################################################################
-##
-##  SOURCE PROCESSOR CLASS
-##
-##  The `SourceProcessor' is in charge of reading a C source file and
-##  decomposing it into a series of different `SourceBlock' objects.
-##
-##  A SourceBlock object consists of the following data.
-##
-##    - A documentation comment block using one of the layouts above.  Its
-##      exact format will be discussed later.
-##
-##    - Normal sources lines, including comments.
-##
-##
-class  SourceProcessor:
-
-    def  __init__( self ):
-        """Initialize a source processor."""
-        self.blocks   = []
-        self.filename = None
-        self.format   = None
-        self.lines    = []
-
-    def  reset( self ):
-        """Reset a block processor and clean up all its blocks."""
-        self.blocks = []
-        self.format = None
-
-    def  parse_file( self, filename ):
-        """Parse a C source file and add its blocks to the processor's
-           list."""
-        self.reset()
-
-        self.filename = filename
-
-        fileinput.close()
-        self.format = None
-        self.lineno = 0
-        self.lines  = []
-
-        for line in fileinput.input( filename ):
-            # strip trailing newlines, important on Windows machines!
-            if line[-1] == '\012':
-                line = line[0:-1]
-
-            if self.format == None:
-                self.process_normal_line( line )
-            else:
-                if self.format.end.match( line ):
-                    # A normal block end.  Add it to `lines' and create a
-                    # new block
-                    self.lines.append( line )
-                    self.add_block_lines()
-                elif self.format.column.match( line ):
-                    # A normal column line.  Add it to `lines'.
-                    self.lines.append( line )
-                else:
-                    # An unexpected block end.  Create a new block, but
-                    # don't process the line.
-                    self.add_block_lines()
-
-                    # we need to process the line again
-                    self.process_normal_line( line )
-
-        # record the last lines
-        self.add_block_lines()
-
-    def  process_normal_line( self, line ):
-        """Process a normal line and check whether it is the start of a new
-           block."""
-        for f in re_source_block_formats:
-            if f.start.match( line ):
-                self.add_block_lines()
-                self.format = f
-                self.lineno = fileinput.filelineno()
-
-        self.lines.append( line )
-
-    def  add_block_lines( self ):
-        """Add the current accumulated lines and create a new block."""
-        if self.lines != []:
-            block = SourceBlock( self,
-                                 self.filename,
-                                 self.lineno,
-                                 self.lines )
-
-            self.blocks.append( block )
-            self.format = None
-            self.lines  = []
-
-    # debugging only, not used in normal operations
-    def  dump( self ):
-        """Print all blocks in a processor."""
-        for b in self.blocks:
-            b.dump()
-
-# eof
diff --git a/src/tools/docmaker/tohtml.py b/src/tools/docmaker/tohtml.py
deleted file mode 100644
index 97a5459..0000000
--- a/src/tools/docmaker/tohtml.py
+++ /dev/null
@@ -1,726 +0,0 @@
-#
-#  tohtml.py
-#
-#    A sub-class container of the `Formatter' class to produce HTML.
-#
-#  Copyright 2002-2018 by
-#  David Turner.
-#
-#  This file is part of the FreeType project, and may only be used,
-#  modified, and distributed under the terms of the FreeType project
-#  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.
-
-# The parent class is contained in file `formatter.py'.
-
-
-from sources import *
-from content import *
-from formatter import *
-
-import time
-
-
-# The following strings define the HTML header used by all generated pages.
-html_header_1 = """\
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"https://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<title>\
-"""
-
-html_header_2 = """\
- API Reference</title>
-<style type="text/css">
-  a:link { color: #0000EF; }
-  a:visited { color: #51188E; }
-  a:hover { color: #FF0000; }
-
-  body { font-family: Verdana, Geneva, Arial, Helvetica, serif;
-         color: #000000;
-         background: #FFFFFF;
-         width: 87%;
-         margin: auto; }
-
-  div.section { width: 75%;
-                margin: auto; }
-  div.section hr { margin: 4ex 0 1ex 0; }
-  div.section h4 { background-color: #EEEEFF;
-                   font-size: medium;
-                   font-style: oblique;
-                   font-weight: bold;
-                   margin: 3ex 0 1.5ex 9%;
-                   padding: 0.3ex 0 0.3ex 1%; }
-  div.section p { margin: 1.5ex 0 1.5ex 10%; }
-  div.section pre { margin: 3ex 0 3ex 9%;
-                    background-color: #D6E8FF;
-                    padding: 2ex 0 2ex 1%; }
-  div.section table.fields { width: 90%;
-                             margin: 1.5ex 0 1.5ex 10%; }
-  div.section table.toc { width: 95%;
-                          margin: 1.5ex 0 1.5ex 5%; }
-  div.timestamp { text-align: center;
-                  font-size: 69%;
-                  margin: 1.5ex 0 1.5ex 0; }
-
-  h1 { text-align: center; }
-  h3 { font-size: medium;
-       margin: 4ex 0 1.5ex 0; }
-
-  p { text-align: justify; }
-
-  pre.colored { color: blue; }
-
-  span.keyword { font-family: monospace;
-                 text-align: left;
-                 white-space: pre;
-                 color: darkblue; }
-
-  table.fields td.val { font-weight: bold;
-                        text-align: right;
-                        width: 30%;
-                        vertical-align: baseline;
-                        padding: 1ex 1em 1ex 0; }
-  table.fields td.desc { vertical-align: baseline;
-                         padding: 1ex 0 1ex 1em; }
-  table.fields td.desc p:first-child { margin: 0; }
-  table.fields td.desc p { margin: 1.5ex 0 0 0; }
-  table.index { margin: 6ex auto 6ex auto;
-                border: 0;
-                border-collapse: separate;
-                border-spacing: 1em 0.3ex; }
-  table.index tr { padding: 0; }
-  table.index td { padding: 0; }
-  table.index-toc-link { width: 100%;
-                         border: 0;
-                         border-spacing: 0;
-                         margin: 1ex 0 1ex 0; }
-  table.index-toc-link td.left { padding: 0 0.5em 0 0.5em;
-                                 font-size: 83%;
-                                 text-align: left; }
-  table.index-toc-link td.middle { padding: 0 0.5em 0 0.5em;
-                                   font-size: 83%;
-                                   text-align: center; }
-  table.index-toc-link td.right { padding: 0 0.5em 0 0.5em;
-                                  font-size: 83%;
-                                  text-align: right; }
-  table.synopsis { margin: 6ex auto 6ex auto;
-                   border: 0;
-                   border-collapse: separate;
-                   border-spacing: 2em 0.6ex; }
-  table.synopsis tr { padding: 0; }
-  table.synopsis td { padding: 0; }
-  table.toc td.link { width: 30%;
-                      text-align: right;
-                      vertical-align: baseline;
-                      padding: 1ex 1em 1ex 0; }
-  table.toc td.desc { vertical-align: baseline;
-                      padding: 1ex 0 1ex 1em;
-                      text-align: left; }
-  table.toc td.desc p:first-child { margin: 0;
-                                    text-align: left; }
-  table.toc td.desc p { margin: 1.5ex 0 0 0;
-                        text-align: left; }
-
-</style>
-</head>
-<body>
-"""
-
-html_header_3l = """
-<table class="index-toc-link"><tr><td class="left">[<a href="\
-"""
-
-html_header_3r = """
-<table class="index-toc-link"><tr><td class="right">[<a href="\
-"""
-
-html_header_4 = """\
-">Index</a>]</td><td class="right">[<a href="\
-"""
-
-html_header_5t = """\
-">TOC</a>]</td></tr></table>
-<h1>\
-"""
-
-html_header_5i = """\
-">Index</a>]</td></tr></table>
-<h1>\
-"""
-
-html_header_6 = """\
- API Reference</h1>
-"""
-
-
-# The HTML footer used by all generated pages.
-html_footer = """\
-</body>
-</html>\
-"""
-
-# The header and footer used for each section.
-section_title_header1 = '<h1 id="'
-section_title_header2 = '">'
-section_title_footer = "</h1>"
-
-# The header and footer used for code segments.
-code_header = '<pre class="colored">'
-code_footer = '</pre>'
-
-# Paragraph header and footer.
-para_header = "<p>"
-para_footer = "</p>"
-
-# Block header and footer.
-block_header        = '<div class="section">'
-block_footer_start  = """\
-<hr>
-<table class="index-toc-link"><tr><td class="left">[<a href="\
-"""
-block_footer_middle = """\
-">Index</a>]</td>\
-<td class="middle">[<a href="#">Top</a>]</td>\
-<td class="right">[<a href="\
-"""
-block_footer_end    = """\
-">TOC</a>]</td></tr></table></div>
-"""
-
-# Description header/footer.
-description_header = ""
-description_footer = ""
-
-# Marker header/inter/footer combination.
-marker_header = "<h4>"
-marker_inter  = "</h4>"
-marker_footer = ""
-
-# Header location header/footer.
-header_location_header = "<p>"
-header_location_footer = "</p>"
-
-# Source code extracts header/footer.
-source_header = "<pre>"
-source_footer = "</pre>"
-
-# Chapter header/inter/footer.
-chapter_header = """\
-<div class="section">
-<h2>\
-"""
-chapter_inter  = '</h2>'
-chapter_footer = '</div>'
-
-# Index footer.
-index_footer_start = """\
-<hr>
-<table class="index-toc-link"><tr><td class="right">[<a href="\
-"""
-index_footer_end = """\
-">TOC</a>]</td></tr></table>
-"""
-
-# TOC footer.
-toc_footer_start = """\
-<hr>
-<table class="index-toc-link"><tr><td class="left">[<a href="\
-"""
-toc_footer_end = """\
-">Index</a>]</td></tr></table>
-"""
-
-
-# Source language keyword coloration and styling.
-keyword_prefix = '<span class="keyword">'
-keyword_suffix = '</span>'
-
-section_synopsis_header = '<h2>Synopsis</h2>'
-section_synopsis_footer = ''
-
-
-# Translate a single line of source to HTML.  This converts `<', `>', and
-# `&' into `&lt;',`&gt;', and `&amp;'.
-#
-def  html_quote( line ):
-    result = string.replace( line,   "&", "&amp;" )
-    result = string.replace( result, "<", "&lt;"  )
-    result = string.replace( result, ">", "&gt;"  )
-    return result
-
-
-################################################################
-##
-##  HTML FORMATTER CLASS
-##
-class  HtmlFormatter( Formatter ):
-
-    def  __init__( self, processor, project_title, file_prefix ):
-        Formatter.__init__( self, processor )
-
-        global html_header_1
-        global html_header_2
-        global html_header_3l, html_header_3r
-        global html_header_4
-        global html_header_5t, html_header_5i
-        global html_header_6
-        global html_footer
-
-        if file_prefix:
-            file_prefix = file_prefix + "-"
-        else:
-            file_prefix = ""
-
-        self.headers       = processor.headers
-        self.project_title = project_title
-        self.file_prefix   = file_prefix
-        self.html_header   = (
-          html_header_1 + project_title
-          + html_header_2
-          + html_header_3l + file_prefix + "index.html"
-          + html_header_4 + file_prefix + "toc.html"
-          + html_header_5t + project_title
-          + html_header_6 )
-        self.html_index_header = (
-          html_header_1 + project_title
-          + html_header_2
-          + html_header_3r + file_prefix + "toc.html"
-          + html_header_5t + project_title
-          + html_header_6 )
-        self.html_toc_header = (
-          html_header_1 + project_title
-          + html_header_2
-          + html_header_3l + file_prefix + "index.html"
-          + html_header_5i + project_title
-          + html_header_6 )
-        self.html_footer = (
-          '<div class="timestamp">generated on '
-          + time.asctime( time.localtime( time.time() ) )
-          + "</div>" + html_footer )
-
-        self.columns = 3
-
-    def  make_section_url( self, section ):
-        return self.file_prefix + section.name + ".html"
-
-    def  make_block_url( self, block, name = None ):
-        if name == None:
-            name = block.name
-
-        try:
-            section_url = self.make_section_url( block.section )
-        except:
-            # we already have a section
-            section_url = self.make_section_url( block )
-
-        return section_url + "#" + name
-
-    def  make_html_word( self, word ):
-        """Analyze a simple word to detect cross-references and markup."""
-        # handle cross-references
-        m = re_crossref.match( word )
-        if m:
-            try:
-                name = m.group( 'name' )
-                rest = m.group( 'rest' )
-                block = self.identifiers[name]
-                url   = self.make_block_url( block )
-                # display `foo[bar]' as `foo'
-                name = re.sub( r'\[.*\]', '', name )
-                # normalize url, following RFC 3986
-                url = string.replace( url, "[", "(" )
-                url = string.replace( url, "]", ")" )
-
-                try:
-                    # for sections, display title
-                    url = ( '&lsquo;<a href="' + url + '">'
-                            + block.title + '</a>&rsquo;'
-                            + rest )
-                except:
-                    url = ( '<a href="' + url + '">'
-                            + name + '</a>'
-                            + rest )
-
-                return url
-            except:
-                # we detected a cross-reference to an unknown item
-                sys.stderr.write( "WARNING: undefined cross reference"
-                                  + " '" + name + "'.\n" )
-                return '?' + name + '?' + rest
-
-        # handle markup for italic and bold
-        m = re_italic.match( word )
-        if m:
-            name = m.group( 1 )
-            rest = m.group( 2 )
-            return '<i>' + name + '</i>' + rest
-
-        m = re_bold.match( word )
-        if m:
-            name = m.group( 1 )
-            rest = m.group( 2 )
-            return '<b>' + name + '</b>' + rest
-
-        return html_quote( word )
-
-    def  make_html_para( self, words ):
-        """Convert words of a paragraph into tagged HTML text.  Also handle
-           cross references."""
-        line = ""
-        if words:
-            line = self.make_html_word( words[0] )
-            for word in words[1:]:
-                line = line + " " + self.make_html_word( word )
-            # handle hyperlinks
-            line = re_url.sub( r'<a href="\1">\1</a>', line )
-            # convert `...' quotations into real left and right single quotes
-            line = re.sub( r"(^|\W)`(.*?)'(\W|$)",
-                           r'\1&lsquo;\2&rsquo;\3',
-                           line )
-            # convert tilde into non-breakable space
-            line = string.replace( line, "~", "&nbsp;" )
-
-        return para_header + line + para_footer
-
-    def  make_html_code( self, lines ):
-        """Convert a code sequence to HTML."""
-        line = code_header + '\n'
-        for l in lines:
-            line = line + html_quote( l ).rstrip() + '\n'
-
-        return line + code_footer
-
-    def  make_html_items( self, items ):
-        """Convert a field's content into HTML."""
-        lines = []
-        for item in items:
-            if item.lines:
-                lines.append( self.make_html_code( item.lines ) )
-            else:
-                lines.append( self.make_html_para( item.words ) )
-
-        return string.join( lines, '\n' )
-
-    def  print_html_items( self, items ):
-        print( self.make_html_items( items ) )
-
-    def  print_html_field( self, field ):
-        if field.name:
-            print( '<table><tr valign="top"><td><b>'
-                   + field.name
-                   + "</b></td><td>" )
-
-        print( self.make_html_items( field.items ) )
-
-        if field.name:
-            print( "</td></tr></table>" )
-
-    def  html_source_quote( self, line, block_name = None ):
-        result = ""
-        while line:
-            m = re_source_crossref.match( line )
-            if m:
-                name   = m.group( 2 )
-                prefix = html_quote( m.group( 1 ) )
-                length = len( m.group( 0 ) )
-
-                if name == block_name:
-                    # this is the current block name, if any
-                    result = result + prefix + '<b>' + name + '</b>'
-                elif re_source_keywords.match( name ):
-                    # this is a C keyword
-                    result = ( result + prefix
-                               + keyword_prefix + name + keyword_suffix )
-                elif name in self.identifiers:
-                    # this is a known identifier
-                    block = self.identifiers[name]
-                    id = block.name
-
-                    # link to a field ID if possible
-                    try:
-                      for markup in block.markups:
-                          if markup.tag == 'values':
-                              for field in markup.fields:
-                                  if field.name:
-                                      id = name
-
-                      result = ( result + prefix
-                                 + '<a href="'
-                                 + self.make_block_url( block, id )
-                                 + '">' + name + '</a>' )
-                    except:
-                      # sections don't have `markups'; however, we don't
-                      # want references to sections here anyway
-                      result = result + html_quote( line[:length] )
-
-                else:
-                    result = result + html_quote( line[:length] )
-
-                line = line[length:]
-            else:
-                result = result + html_quote( line )
-                line   = []
-
-        return result
-
-    def  print_html_field_list( self, fields ):
-        print( '<table class="fields">' )
-        for field in fields:
-            print( '<tr><td class="val" id="' + field.name + '">'
-                   + field.name
-                   + '</td><td class="desc">' )
-            self.print_html_items( field.items )
-            print( "</td></tr>" )
-        print( "</table>" )
-
-    def  print_html_markup( self, markup ):
-        table_fields = []
-        for field in markup.fields:
-            if field.name:
-                # We begin a new series of field or value definitions.  We
-                # record them in the `table_fields' list before outputting
-                # all of them as a single table.
-                table_fields.append( field )
-            else:
-                if table_fields:
-                    self.print_html_field_list( table_fields )
-                    table_fields = []
-
-                self.print_html_items( field.items )
-
-        if table_fields:
-            self.print_html_field_list( table_fields )
-
-    #
-    # formatting the index
-    #
-    def  index_enter( self ):
-        print( self.html_index_header )
-        self.index_items = {}
-
-    def  index_name_enter( self, name ):
-        block = self.identifiers[name]
-        url   = self.make_block_url( block )
-        self.index_items[name] = url
-
-    def  index_exit( self ):
-        # `block_index' already contains the sorted list of index names
-        count = len( self.block_index )
-        rows  = ( count + self.columns - 1 ) // self.columns
-
-        print( '<table class="index">' )
-        for r in range( rows ):
-            line = "<tr>"
-            for c in range( self.columns ):
-                i = r + c * rows
-                if i < count:
-                    bname = self.block_index[r + c * rows]
-                    url   = self.index_items[bname]
-                    # display `foo[bar]' as `foo (bar)'
-                    bname = string.replace( bname, "[", " (" )
-                    bname = string.replace( bname, "]", ")"  )
-                    # normalize url, following RFC 3986
-                    url = string.replace( url, "[", "(" )
-                    url = string.replace( url, "]", ")" )
-                    line  = ( line + '<td><a href="' + url + '">'
-                              + bname + '</a></td>' )
-                else:
-                    line = line + '<td></td>'
-            line = line + "</tr>"
-            print( line )
-
-        print( "</table>" )
-
-        print( index_footer_start
-               + self.file_prefix + "toc.html"
-               + index_footer_end )
-
-        print( self.html_footer )
-
-        self.index_items = {}
-
-    def  index_dump( self, index_filename = None ):
-        if index_filename == None:
-            index_filename = self.file_prefix + "index.html"
-
-        Formatter.index_dump( self, index_filename )
-
-    #
-    # formatting the table of contents
-    #
-    def  toc_enter( self ):
-        print( self.html_toc_header )
-        print( "<h1>Table of Contents</h1>" )
-
-    def  toc_chapter_enter( self, chapter ):
-        print( chapter_header + string.join( chapter.title ) + chapter_inter )
-        print( '<table class="toc">' )
-
-    def  toc_section_enter( self, section ):
-        print( '<tr><td class="link">'
-               + '<a href="' + self.make_section_url( section ) + '">'
-               + section.title + '</a></td><td class="desc">' )
-        print( self.make_html_para( section.abstract ) )
-
-    def  toc_section_exit( self, section ):
-        print( "</td></tr>" )
-
-    def  toc_chapter_exit( self, chapter ):
-        print( "</table>" )
-        print( chapter_footer )
-
-    def  toc_index( self, index_filename ):
-        print( chapter_header
-               + '<a href="' + index_filename + '">Global Index</a>'
-               + chapter_inter + chapter_footer )
-
-    def  toc_exit( self ):
-        print( toc_footer_start
-               + self.file_prefix + "index.html"
-               + toc_footer_end )
-
-        print( self.html_footer )
-
-    def  toc_dump( self, toc_filename = None, index_filename = None ):
-        if toc_filename == None:
-            toc_filename = self.file_prefix + "toc.html"
-
-        if index_filename == None:
-            index_filename = self.file_prefix + "index.html"
-
-        Formatter.toc_dump( self, toc_filename, index_filename )
-
-    #
-    # formatting sections
-    #
-    def  section_enter( self, section ):
-        print( self.html_header )
-
-        print( section_title_header1 + section.name + section_title_header2
-               + section.title
-               + section_title_footer )
-
-        maxwidth = 0
-        for b in section.blocks.values():
-            if len( b.name ) > maxwidth:
-                maxwidth = len( b.name )
-
-        width = 70  # XXX magic number
-        if maxwidth > 0:
-            # print section synopsis
-            print( section_synopsis_header )
-            print( '<table class="synopsis">' )
-
-            columns = width // maxwidth
-            if columns < 1:
-                columns = 1
-
-            count = len( section.block_names )
-            # don't handle last entry if it is empty
-            if section.block_names[-1] == "/empty/":
-                count -= 1
-            rows  = ( count + columns - 1 ) // columns
-
-            for r in range( rows ):
-                line = "<tr>"
-                for c in range( columns ):
-                    i = r + c * rows
-                    line = line + '<td>'
-                    if i < count:
-                        name = section.block_names[i]
-                        if name == "/empty/":
-                            # it can happen that a complete row is empty, and
-                            # without a proper `filler' the browser might
-                            # collapse the row to a much smaller height (or
-                            # even omit it completely)
-                            line = line + "&nbsp;"
-                        else:
-                            url = name
-                            # display `foo[bar]' as `foo'
-                            name = re.sub( r'\[.*\]', '', name )
-                            # normalize url, following RFC 3986
-                            url = string.replace( url, "[", "(" )
-                            url = string.replace( url, "]", ")" )
-                            line = ( line + '<a href="#' + url + '">'
-                                     + name + '</a>' )
-
-                    line = line + '</td>'
-                line = line + "</tr>"
-                print( line )
-
-            print( "</table>" )
-            print( section_synopsis_footer )
-
-        print( description_header )
-        print( self.make_html_items( section.description ) )
-        print( description_footer )
-
-    def  block_enter( self, block ):
-        print( block_header )
-
-        # place html anchor if needed
-        if block.name:
-            url = block.name
-            # display `foo[bar]' as `foo'
-            name = re.sub( r'\[.*\]', '', block.name )
-            # normalize url, following RFC 3986
-            url = string.replace( url, "[", "(" )
-            url = string.replace( url, "]", ")" )
-            print( '<h3 id="' + url + '">' + name + '</h3>' )
-
-        # dump the block C source lines now
-        if block.code:
-            header = ''
-            for f in self.headers.keys():
-                header_filename = os.path.normpath(block.source.filename)
-                if header_filename.find( os.path.normpath( f ) ) >= 0:
-                    header = self.headers[f] + ' (' + f + ')'
-                    break
-
-#           if not header:
-#               sys.stderr.write(
-#                 "WARNING: No header macro for"
-#                 + " '" + block.source.filename + "'.\n" )
-
-            if header:
-                print( header_location_header
-                       + 'Defined in ' + header + '.'
-                       + header_location_footer )
-
-            print( source_header )
-            for l in block.code:
-                print( self.html_source_quote( l, block.name ) )
-            print( source_footer )
-
-    def  markup_enter( self, markup, block ):
-        if markup.tag == "description":
-            print( description_header )
-        else:
-            print( marker_header + markup.tag + marker_inter )
-
-        self.print_html_markup( markup )
-
-    def  markup_exit( self, markup, block ):
-        if markup.tag == "description":
-            print( description_footer )
-        else:
-            print( marker_footer )
-
-    def  block_exit( self, block ):
-        print( block_footer_start + self.file_prefix + "index.html"
-               + block_footer_middle + self.file_prefix + "toc.html"
-               + block_footer_end )
-
-    def  section_exit( self, section ):
-        print( html_footer )
-
-    def  section_dump_all( self ):
-        for section in self.sections:
-            self.section_dump( section,
-                               self.file_prefix + section.name + '.html' )
-
-# eof
diff --git a/src/tools/docmaker/utils.py b/src/tools/docmaker/utils.py
deleted file mode 100644
index f40f167..0000000
--- a/src/tools/docmaker/utils.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-#  utils.py
-#
-#    Auxiliary functions for the `docmaker' tool (library file).
-#
-#  Copyright 2002-2018 by
-#  David Turner.
-#
-#  This file is part of the FreeType project, and may only be used,
-#  modified, and distributed under the terms of the FreeType project
-#  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.
-
-
-import string, sys, os, glob, itertools
-
-
-# current output directory
-#
-output_dir = None
-
-
-# A function that generates a sorting key.  We want lexicographical order
-# (primary key) except that capital letters are sorted before lowercase
-# ones (secondary key).
-#
-# The primary key is implemented by lowercasing the input.  The secondary
-# key is simply the original data appended, character by character.  For
-# example, the sort key for `FT_x' is `fFtT__xx', while the sort key for
-# `ft_X' is `fftt__xX'.  Since ASCII codes of uppercase letters are
-# numerically smaller than the codes of lowercase letters, `fFtT__xx' gets
-# sorted before `fftt__xX'.
-#
-def  index_key( s ):
-    return string.join( itertools.chain( *zip( s.lower(), s ) ) )
-
-
-# Sort `input_list', placing the elements of `order_list' in front.
-#
-def  sort_order_list( input_list, order_list ):
-    new_list = order_list[:]
-    for id in input_list:
-        if not id in order_list:
-            new_list.append( id )
-    return new_list
-
-
-# Divert standard output to a given project documentation file.  Use
-# `output_dir' to determine the filename location if necessary and save the
-# old stdout handle in a tuple that is returned by this function.
-#
-def  open_output( filename ):
-    global output_dir
-
-    if output_dir and output_dir != "":
-        filename = output_dir + os.sep + filename
-
-    old_stdout = sys.stdout
-    new_file   = open( filename, "w" )
-    sys.stdout = new_file
-
-    return ( new_file, old_stdout )
-
-
-# Close the output that was returned by `open_output'.
-#
-def  close_output( output ):
-    output[0].close()
-    sys.stdout = output[1]
-
-
-# Check output directory.
-#
-def  check_output():
-    global output_dir
-    if output_dir:
-        if output_dir != "":
-            if not os.path.isdir( output_dir ):
-                sys.stderr.write( "argument"
-                                  + " '" + output_dir + "' "
-                                  + "is not a valid directory\n" )
-                sys.exit( 2 )
-        else:
-            output_dir = None
-
-
-def  file_exists( pathname ):
-    """Check that a given file exists."""
-    result = 1
-    try:
-        file = open( pathname, "r" )
-        file.close()
-    except:
-        result = None
-        sys.stderr.write( pathname + " couldn't be accessed\n" )
-
-    return result
-
-
-def  make_file_list( args = None ):
-    """Build a list of input files from command-line arguments."""
-    file_list = []
-    # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' )
-
-    if not args:
-        args = sys.argv[1:]
-
-    for pathname in args:
-        if string.find( pathname, '*' ) >= 0:
-            newpath = glob.glob( pathname )
-            newpath.sort()  # sort files -- this is important because
-                            # of the order of files
-        else:
-            newpath = [pathname]
-
-        file_list.extend( newpath )
-
-    if len( file_list ) == 0:
-        file_list = None
-    else:
-        # now filter the file list to remove non-existing ones
-        file_list = filter( file_exists, file_list )
-
-    return file_list
-
-# eof
diff --git a/src/tools/ftrandom/ftrandom.c b/src/tools/ftrandom/ftrandom.c
index ab5cfc9..4f912cd 100644
--- a/src/tools/ftrandom/ftrandom.c
+++ b/src/tools/ftrandom/ftrandom.c
@@ -29,7 +29,7 @@
 /* This file is now part of the FreeType library */
 
 
-#define _XOPEN_SOURCE 500 /* for `kill', `strdup', `random', and `srandom' */
+#define _XOPEN_SOURCE 600 /* for `kill', `strdup', `random', and `srandom' */
 
 
 #include <stdio.h>
@@ -45,8 +45,8 @@
 #include <time.h>
 
 #include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_OUTLINE_H
+#include <freetype/freetype.h>
+#include <freetype/ftoutln.h>
 
 #define true     1
 #define false    0
diff --git a/src/tools/glnames.py b/src/tools/glnames.py
index e88f710..41509db 100644
--- a/src/tools/glnames.py
+++ b/src/tools/glnames.py
@@ -1,12 +1,9 @@
-#!/usr/bin/env python
-#
+#!/usr/bin/env python3
 
 #
 # FreeType 2 glyph name builder
 #
-
-
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -16,8 +13,7 @@
 # fully.
 
 
-"""\
-
+"""
 usage: %s <output-file>
 
   This python script generates the glyph names tables defined in the
@@ -26,9 +22,9 @@
   Its single argument is the name of the header file to be created.
 """
 
-
-import sys, string, struct, re, os.path
-
+import os.path
+import struct
+import sys
 
 # This table lists the glyphs according to the Macintosh specification.
 # It is used by the TrueType Postscript names table.
@@ -39,379 +35,371 @@
 #
 # for the official list.
 #
-mac_standard_names = \
-[
-  # 0
-  ".notdef", ".null", "nonmarkingreturn", "space", "exclam",
-  "quotedbl", "numbersign", "dollar", "percent", "ampersand",
+mac_standard_names = [
+    # 0
+    ".notdef", ".null", "nonmarkingreturn", "space", "exclam",
+    "quotedbl", "numbersign", "dollar", "percent", "ampersand",
 
-  # 10
-  "quotesingle", "parenleft", "parenright", "asterisk", "plus",
-  "comma", "hyphen", "period", "slash", "zero",
+    # 10
+    "quotesingle", "parenleft", "parenright", "asterisk", "plus",
+    "comma", "hyphen", "period", "slash", "zero",
 
-  # 20
-  "one", "two", "three", "four", "five",
-  "six", "seven", "eight", "nine", "colon",
+    # 20
+    "one", "two", "three", "four", "five",
+    "six", "seven", "eight", "nine", "colon",
 
-  # 30
-  "semicolon", "less", "equal", "greater", "question",
-  "at", "A", "B", "C", "D",
+    # 30
+    "semicolon", "less", "equal", "greater", "question",
+    "at", "A", "B", "C", "D",
 
-  # 40
-  "E", "F", "G", "H", "I",
-  "J", "K", "L", "M", "N",
+    # 40
+    "E", "F", "G", "H", "I",
+    "J", "K", "L", "M", "N",
 
-  # 50
-  "O", "P", "Q", "R", "S",
-  "T", "U", "V", "W", "X",
+    # 50
+    "O", "P", "Q", "R", "S",
+    "T", "U", "V", "W", "X",
 
-  # 60
-  "Y", "Z", "bracketleft", "backslash", "bracketright",
-  "asciicircum", "underscore", "grave", "a", "b",
+    # 60
+    "Y", "Z", "bracketleft", "backslash", "bracketright",
+    "asciicircum", "underscore", "grave", "a", "b",
 
-  # 70
-  "c", "d", "e", "f", "g",
-  "h", "i", "j", "k", "l",
+    # 70
+    "c", "d", "e", "f", "g",
+    "h", "i", "j", "k", "l",
 
-  # 80
-  "m", "n", "o", "p", "q",
-  "r", "s", "t", "u", "v",
+    # 80
+    "m", "n", "o", "p", "q",
+    "r", "s", "t", "u", "v",
 
-  # 90
-  "w", "x", "y", "z", "braceleft",
-  "bar", "braceright", "asciitilde", "Adieresis", "Aring",
+    # 90
+    "w", "x", "y", "z", "braceleft",
+    "bar", "braceright", "asciitilde", "Adieresis", "Aring",
 
-  # 100
-  "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",
-  "aacute", "agrave", "acircumflex", "adieresis", "atilde",
+    # 100
+    "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",
+    "aacute", "agrave", "acircumflex", "adieresis", "atilde",
 
-  # 110
-  "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
-  "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
+    # 110
+    "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
+    "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
 
-  # 120
-  "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",
-  "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",
+    # 120
+    "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",
+    "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",
 
-  # 130
-  "dagger", "degree", "cent", "sterling", "section",
-  "bullet", "paragraph", "germandbls", "registered", "copyright",
+    # 130
+    "dagger", "degree", "cent", "sterling", "section",
+    "bullet", "paragraph", "germandbls", "registered", "copyright",
 
-  # 140
-  "trademark", "acute", "dieresis", "notequal", "AE",
-  "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
+    # 140
+    "trademark", "acute", "dieresis", "notequal", "AE",
+    "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
 
-  # 150
-  "yen", "mu", "partialdiff", "summation", "product",
-  "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
+    # 150
+    "yen", "mu", "partialdiff", "summation", "product",
+    "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
 
-  # 160
-  "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
-  "radical", "florin", "approxequal", "Delta", "guillemotleft",
+    # 160
+    "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
+    "radical", "florin", "approxequal", "Delta", "guillemotleft",
 
-  # 170
-  "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
-  "Otilde", "OE", "oe", "endash", "emdash",
+    # 170
+    "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
+    "Otilde", "OE", "oe", "endash", "emdash",
 
-  # 180
-  "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
-  "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
+    # 180
+    "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
+    "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
 
-  # 190
-  "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
-  "periodcentered", "quotesinglbase", "quotedblbase", "perthousand",
+    # 190
+    "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
+    "periodcentered", "quotesinglbase", "quotedblbase", "perthousand",
     "Acircumflex",
 
-  # 200
-  "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
-  "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
+    # 200
+    "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
+    "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
 
-  # 210
-  "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",
-  "dotlessi", "circumflex", "tilde", "macron", "breve",
+    # 210
+    "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",
+    "dotlessi", "circumflex", "tilde", "macron", "breve",
 
-  # 220
-  "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",
-  "caron", "Lslash", "lslash", "Scaron", "scaron",
+    # 220
+    "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",
+    "caron", "Lslash", "lslash", "Scaron", "scaron",
 
-  # 230
-  "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
-  "Yacute", "yacute", "Thorn", "thorn", "minus",
+    # 230
+    "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
+    "Yacute", "yacute", "Thorn", "thorn", "minus",
 
-  # 240
-  "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
-  "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
+    # 240
+    "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
+    "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
 
-  # 250
-  "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute",
-  "Ccaron", "ccaron", "dcroat"
+    # 250
+    "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute",
+    "Ccaron", "ccaron", "dcroat"
 ]
 
-
 # The list of standard `SID' glyph names.  For the official list,
 # see Annex A of document at
 #
-#   https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf  .
+#   https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
 #
-sid_standard_names = \
-[
-  # 0
-  ".notdef", "space", "exclam", "quotedbl", "numbersign",
-  "dollar", "percent", "ampersand", "quoteright", "parenleft",
+sid_standard_names = [
+    # 0
+    ".notdef", "space", "exclam", "quotedbl", "numbersign",
+    "dollar", "percent", "ampersand", "quoteright", "parenleft",
 
-  # 10
-  "parenright", "asterisk", "plus", "comma", "hyphen",
-  "period", "slash", "zero", "one", "two",
+    # 10
+    "parenright", "asterisk", "plus", "comma", "hyphen",
+    "period", "slash", "zero", "one", "two",
 
-  # 20
-  "three", "four", "five", "six", "seven",
-  "eight", "nine", "colon", "semicolon", "less",
+    # 20
+    "three", "four", "five", "six", "seven",
+    "eight", "nine", "colon", "semicolon", "less",
 
-  # 30
-  "equal", "greater", "question", "at", "A",
-  "B", "C", "D", "E", "F",
+    # 30
+    "equal", "greater", "question", "at", "A",
+    "B", "C", "D", "E", "F",
 
-  # 40
-  "G", "H", "I", "J", "K",
-  "L", "M", "N", "O", "P",
+    # 40
+    "G", "H", "I", "J", "K",
+    "L", "M", "N", "O", "P",
 
-  # 50
-  "Q", "R", "S", "T", "U",
-  "V", "W", "X", "Y", "Z",
+    # 50
+    "Q", "R", "S", "T", "U",
+    "V", "W", "X", "Y", "Z",
 
-  # 60
-  "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
-  "quoteleft", "a", "b", "c", "d",
+    # 60
+    "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
+    "quoteleft", "a", "b", "c", "d",
 
-  # 70
-  "e", "f", "g", "h", "i",
-  "j", "k", "l", "m", "n",
+    # 70
+    "e", "f", "g", "h", "i",
+    "j", "k", "l", "m", "n",
 
-  # 80
-  "o", "p", "q", "r", "s",
-  "t", "u", "v", "w", "x",
+    # 80
+    "o", "p", "q", "r", "s",
+    "t", "u", "v", "w", "x",
 
-  # 90
-  "y", "z", "braceleft", "bar", "braceright",
-  "asciitilde", "exclamdown", "cent", "sterling", "fraction",
+    # 90
+    "y", "z", "braceleft", "bar", "braceright",
+    "asciitilde", "exclamdown", "cent", "sterling", "fraction",
 
-  # 100
-  "yen", "florin", "section", "currency", "quotesingle",
-  "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi",
+    # 100
+    "yen", "florin", "section", "currency", "quotesingle",
+    "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi",
 
-  # 110
-  "fl", "endash", "dagger", "daggerdbl", "periodcentered",
-  "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
+    # 110
+    "fl", "endash", "dagger", "daggerdbl", "periodcentered",
+    "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
 
-  # 120
-  "guillemotright", "ellipsis", "perthousand", "questiondown", "grave",
-  "acute", "circumflex", "tilde", "macron", "breve",
+    # 120
+    "guillemotright", "ellipsis", "perthousand", "questiondown", "grave",
+    "acute", "circumflex", "tilde", "macron", "breve",
 
-  # 130
-  "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
-  "ogonek", "caron", "emdash", "AE", "ordfeminine",
+    # 130
+    "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
+    "ogonek", "caron", "emdash", "AE", "ordfeminine",
 
-  # 140
-  "Lslash", "Oslash", "OE", "ordmasculine", "ae",
-  "dotlessi", "lslash", "oslash", "oe", "germandbls",
+    # 140
+    "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+    "dotlessi", "lslash", "oslash", "oe", "germandbls",
 
-  # 150
-  "onesuperior", "logicalnot", "mu", "trademark", "Eth",
-  "onehalf", "plusminus", "Thorn", "onequarter", "divide",
+    # 150
+    "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+    "onehalf", "plusminus", "Thorn", "onequarter", "divide",
 
-  # 160
-  "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
-  "registered", "minus", "eth", "multiply", "threesuperior",
+    # 160
+    "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
+    "registered", "minus", "eth", "multiply", "threesuperior",
 
-  # 170
-  "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
-  "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
+    # 170
+    "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
+    "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
 
-  # 180
-  "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
-  "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
+    # 180
+    "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+    "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
 
-  # 190
-  "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
-  "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+    # 190
+    "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
+    "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
 
-  # 200
-  "aacute", "acircumflex", "adieresis", "agrave", "aring",
-  "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
+    # 200
+    "aacute", "acircumflex", "adieresis", "agrave", "aring",
+    "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
 
-  # 210
-  "egrave", "iacute", "icircumflex", "idieresis", "igrave",
-  "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
+    # 210
+    "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+    "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
 
-  # 220
-  "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
-  "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+    # 220
+    "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
+    "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
 
-  # 230
-  "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+    # 230
+    "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
     "Acutesmall",
-  "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+    "parenleftsuperior", "parenrightsuperior", "twodotenleader",
     "onedotenleader", "zerooldstyle",
 
-  # 240
-  "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
+    # 240
+    "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
     "fiveoldstyle",
-  "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
+    "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
     "commasuperior",
 
-  # 250
-  "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+    # 250
+    "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
     "bsuperior",
-  "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
+    "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
 
-  # 260
-  "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
-  "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+    # 260
+    "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+    "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
 
-  # 270
-  "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
+    # 270
+    "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
     "Asmall",
-  "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
+    "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
 
-  # 280
-  "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
-  "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+    # 280
+    "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
+    "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
 
-  # 290
-  "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
-  "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
+    # 290
+    "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+    "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
 
-  # 300
-  "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
-  "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
+    # 300
+    "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
+    "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
     "Dieresissmall",
 
-  # 310
-  "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
-  "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
+    # 310
+    "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+    "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
     "questiondownsmall",
 
-  # 320
-  "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
-  "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
+    # 320
+    "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
+    "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
     "sixsuperior",
 
-  # 330
-  "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+    # 330
+    "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
     "oneinferior",
-  "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
+    "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
     "sixinferior",
 
-  # 340
-  "seveninferior", "eightinferior", "nineinferior", "centinferior",
+    # 340
+    "seveninferior", "eightinferior", "nineinferior", "centinferior",
     "dollarinferior",
-  "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
+    "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
     "Acircumflexsmall",
 
-  # 350
-  "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
-  "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+    # 350
+    "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+    "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
     "Igravesmall",
 
-  # 360
-  "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
+    # 360
+    "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
     "Ntildesmall",
-  "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
+    "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
     "Odieresissmall",
 
-  # 370
-  "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
+    # 370
+    "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
     "Ucircumflexsmall",
-  "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
+    "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
     "001.000",
 
-  # 380
-  "001.001", "001.002", "001.003", "Black", "Bold",
-  "Book", "Light", "Medium", "Regular", "Roman",
+    # 380
+    "001.001", "001.002", "001.003", "Black", "Bold",
+    "Book", "Light", "Medium", "Regular", "Roman",
 
-  # 390
-  "Semibold"
+    # 390
+    "Semibold"
 ]
 
-
 # This table maps character codes of the Adobe Standard Type 1
 # encoding to glyph indices in the sid_standard_names table.
 #
-t1_standard_encoding = \
-[
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   1,   2,   3,   4,   5,   6,   7,   8,
-    9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
+t1_standard_encoding = [
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1,   2,   3,   4,   5,   6,   7,   8,
+      9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
 
-   19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
-   29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
-   39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-   49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
-   59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
+     19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
+     29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
+     39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+     49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
+     59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
 
-   69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
-   79,  80,  81,  82,  83,  84,  85,  86,  87,  88,
-   89,  90,  91,  92,  93,  94,  95,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
+     79,  80,  81,  82,  83,  84,  85,  86,  87,  88,
+     89,  90,  91,  92,  93,  94,  95,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,  96,  97,  98,  99, 100, 101, 102, 103, 104,
-  105, 106, 107, 108, 109, 110,   0, 111, 112, 113,
-  114,   0, 115, 116, 117, 118, 119, 120, 121, 122,
-    0, 123,   0, 124, 125, 126, 127, 128, 129, 130,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,  96,  97,  98,  99, 100, 101, 102, 103, 104,
+    105, 106, 107, 108, 109, 110,   0, 111, 112, 113,
+    114,   0, 115, 116, 117, 118, 119, 120, 121, 122,
+      0, 123,   0, 124, 125, 126, 127, 128, 129, 130,
 
-  131,   0, 132, 133,   0, 134, 135, 136, 137,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0, 138,   0, 139,   0,   0,
-    0,   0, 140, 141, 142, 143,   0,   0,   0,   0,
-    0, 144,   0,   0,   0, 145,   0,   0, 146, 147,
+    131,   0, 132, 133,   0, 134, 135, 136, 137,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0, 138,   0, 139,   0,   0,
+      0,   0, 140, 141, 142, 143,   0,   0,   0,   0,
+      0, 144,   0,   0,   0, 145,   0,   0, 146, 147,
 
-  148, 149,   0,   0,   0,   0
+    148, 149,   0,   0,   0, 0
 ]
 
-
 # This table maps character codes of the Adobe Expert Type 1
 # encoding to glyph indices in the sid_standard_names table.
 #
-t1_expert_encoding = \
-[
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   1, 229, 230,   0, 231, 232, 233, 234,
-  235, 236, 237, 238,  13,  14,  15,  99, 239, 240,
+t1_expert_encoding = [
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1, 229, 230,   0, 231, 232, 233, 234,
+    235, 236, 237, 238,  13,  14,  15,  99, 239, 240,
 
-  241, 242, 243, 244, 245, 246, 247, 248,  27,  28,
-  249, 250, 251, 252,   0, 253, 254, 255, 256, 257,
-    0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
-    0,   0, 263, 264, 265,   0, 266, 109, 110, 267,
-  268, 269,   0, 270, 271, 272, 273, 274, 275, 276,
+    241, 242, 243, 244, 245, 246, 247, 248,  27,  28,
+    249, 250, 251, 252,   0, 253, 254, 255, 256, 257,
+      0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
+      0,   0, 263, 264, 265,   0, 266, 109, 110, 267,
+    268, 269,   0, 270, 271, 272, 273, 274, 275, 276,
 
-  277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
-  287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
-  297, 298, 299, 300, 301, 302, 303,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+    287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+    297, 298, 299, 300, 301, 302, 303,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 
-    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-    0, 304, 305, 306,   0,   0, 307, 308, 309, 310,
-  311,   0, 312,   0,   0, 313,   0,   0, 314, 315,
-    0,   0, 316, 317, 318,   0,   0,   0, 158, 155,
-  163, 319, 320, 321, 322, 323, 324, 325,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0, 304, 305, 306,   0,   0, 307, 308, 309, 310,
+    311,   0, 312,   0,   0, 313,   0,   0, 314, 315,
+      0,   0, 316, 317, 318,   0,   0,   0, 158, 155,
+    163, 319, 320, 321, 322, 323, 324, 325,   0,   0,
 
-  326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
-  333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
-  343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
-  353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
-  363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
+    326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+    333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+    343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+    353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+    363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
 
-  373, 374, 375, 376, 377, 378
+    373, 374, 375, 376, 377, 378
 ]
 
-
 # This data has been taken literally from the files `glyphlist.txt'
 # and `zapfdingbats.txt' version 2.0, Sept 2002.  It is available from
 #
@@ -4906,81 +4894,81 @@
 # string table management
 #
 class StringTable:
-  def __init__( self, name_list, master_table_name ):
-    self.names        = name_list
-    self.master_table = master_table_name
-    self.indices      = {}
-    index             = 0
+    def __init__(self, name_list, master_table_name):
+        self.names = name_list
+        self.master_table = master_table_name
+        self.indices = {}
+        index = 0
 
-    for name in name_list:
-      self.indices[name] = index
-      index += len( name ) + 1
+        for name in name_list:
+            self.indices[name] = index
+            index += len(name) + 1
 
-    self.total = index
+        self.total = index
 
-  def dump( self, file ):
-    write = file.write
-    write( "#ifndef  DEFINE_PS_TABLES_DATA\n" )
-    write( "#ifdef  __cplusplus\n" )
-    write( '  extern "C"\n' )
-    write( "#else\n" )
-    write( "  extern\n" )
-    write( "#endif\n" )
-    write( "#endif\n" )
-    write( "  const char  " + self.master_table +
-           "[" + repr( self.total ) + "]\n" )
-    write( "#ifdef  DEFINE_PS_TABLES_DATA\n" )
-    write( "  =\n" )
-    write( "  {\n" )
+    def dump(self, file):
+        write = file.write
+        write("#ifndef  DEFINE_PS_TABLES_DATA\n")
+        write("#ifdef  __cplusplus\n")
+        write('  extern "C"\n')
+        write("#else\n")
+        write("  extern\n")
+        write("#endif\n")
+        write("#endif\n")
+        write("  const char  " + self.master_table +
+              "[" + repr(self.total) + "]\n")
+        write("#ifdef  DEFINE_PS_TABLES_DATA\n")
+        write("  =\n")
+        write("  {\n")
 
-    line = ""
-    for name in self.names:
-      line += "    '"
-      line += string.join( ( re.findall( ".", name ) ), "','" )
-      line += "', 0,\n"
+        line = ""
+        for name in self.names:
+            line += "    '"
+            line += "','".join(list(name))
+            line += "', 0,\n"
 
-    write( line )
-    write( "  }\n" )
-    write( "#endif /* DEFINE_PS_TABLES_DATA */\n" )
-    write( "  ;\n\n\n" )
+        write(line)
+        write("  }\n")
+        write("#endif /* DEFINE_PS_TABLES_DATA */\n")
+        write("  ;\n\n\n")
 
-  def dump_sublist( self, file, table_name, macro_name, sublist ):
-    write = file.write
-    write( "#define " + macro_name + "  " + repr( len( sublist ) ) + "\n\n" )
+    def dump_sublist(self, file, table_name, macro_name, sublist):
+        write = file.write
+        write("#define " + macro_name + "  " + repr(len(sublist)) + "\n\n")
 
-    write( "  /* Values are offsets into the `" +
-           self.master_table + "' table */\n\n" )
-    write( "#ifndef  DEFINE_PS_TABLES_DATA\n" )
-    write( "#ifdef  __cplusplus\n" )
-    write( '  extern "C"\n' )
-    write( "#else\n" )
-    write( "  extern\n" )
-    write( "#endif\n" )
-    write( "#endif\n" )
-    write( "  const short  " + table_name +
-           "[" + macro_name + "]\n" )
-    write( "#ifdef  DEFINE_PS_TABLES_DATA\n" )
-    write( "  =\n" )
-    write( "  {\n" )
+        write("  /* Values are offsets into the `" +
+              self.master_table + "' table */\n\n")
+        write("#ifndef  DEFINE_PS_TABLES_DATA\n")
+        write("#ifdef  __cplusplus\n")
+        write('  extern "C"\n')
+        write("#else\n")
+        write("  extern\n")
+        write("#endif\n")
+        write("#endif\n")
+        write("  const short  " + table_name +
+              "[" + macro_name + "]\n")
+        write("#ifdef  DEFINE_PS_TABLES_DATA\n")
+        write("  =\n")
+        write("  {\n")
 
-    line  = "    "
-    comma = ""
-    col   = 0
+        line = "    "
+        comma = ""
+        col = 0
 
-    for name in sublist:
-      line += comma
-      line += "%4d" % self.indices[name]
-      col  += 1
-      comma = ","
-      if col == 14:
-        col   = 0
-        comma = ",\n    "
+        for name in sublist:
+            line += comma
+            line += "%4d" % self.indices[name]
+            col += 1
+            comma = ","
+            if col == 14:
+                col = 0
+                comma = ",\n    "
 
-    write( line )
-    write( "\n" )
-    write( "  }\n" )
-    write( "#endif /* DEFINE_PS_TABLES_DATA */\n" )
-    write( "  ;\n\n\n" )
+        write(line)
+        write("\n")
+        write("  }\n")
+        write("#endif /* DEFINE_PS_TABLES_DATA */\n")
+        write("  ;\n\n\n")
 
 
 # We now store the Adobe Glyph List in compressed form.  The list is put
@@ -5059,307 +5047,312 @@
 # The root node has first letter = 0, and no value.
 #
 class StringNode:
-  def __init__( self, letter, value ):
-    self.letter   = letter
-    self.value    = value
-    self.children = {}
+    def __init__(self, letter, value):
+        self.letter = letter
+        self.value = value
+        self.children = {}
 
-  def __cmp__( self, other ):
-    return ord( self.letter[0] ) - ord( other.letter[0] )
+    def __cmp__(self, other):
+        return ord(self.letter[0]) - ord(other.letter[0])
 
-  def add( self, word, value ):
-    if len( word ) == 0:
-      self.value = value
-      return
+    def __lt__(self, other):
+        return self.letter[0] < other.letter[0]
 
-    letter = word[0]
-    word   = word[1:]
+    def add(self, word, value):
+        if len(word) == 0:
+            self.value = value
+            return
 
-    if self.children.has_key( letter ):
-      child = self.children[letter]
-    else:
-      child = StringNode( letter, 0 )
-      self.children[letter] = child
+        letter = word[0]
+        word = word[1:]
 
-    child.add( word, value )
+        if letter in self.children:
+            child = self.children[letter]
+        else:
+            child = StringNode(letter, 0)
+            self.children[letter] = child
 
-  def optimize( self ):
-    # optimize all children first
-    children      = self.children.values()
-    self.children = {}
+        child.add(word, value)
 
-    for child in children:
-      self.children[child.letter[0]] = child.optimize()
+    def optimize(self):
+        # optimize all children first
+        children = list(self.children.values())
+        self.children = {}
 
-    # don't optimize if there's a value,
-    # if we don't have any child or if we
-    # have more than one child
-    if ( self.value != 0 ) or ( not children ) or len( children ) > 1:
-      return self
+        for child in children:
+            self.children[child.letter[0]] = child.optimize()
 
-    child = children[0]
+        # don't optimize if there's a value,
+        # if we don't have any child or if we
+        # have more than one child
+        if (self.value != 0) or (not children) or len(children) > 1:
+            return self
 
-    self.letter  += child.letter
-    self.value    = child.value
-    self.children = child.children
+        child = children[0]
 
-    return self
+        self.letter += child.letter
+        self.value = child.value
+        self.children = child.children
 
-  def dump_debug( self, write, margin ):
-    # this is used during debugging
-    line = margin + "+-"
-    if len( self.letter ) == 0:
-      line += "<NOLETTER>"
-    else:
-      line += self.letter
+        return self
 
-    if self.value:
-      line += " => " + repr( self.value )
+    def dump_debug(self, write, margin):
+        # this is used during debugging
+        line = margin + "+-"
+        if len(self.letter) == 0:
+            line += "<NOLETTER>"
+        else:
+            line += self.letter
 
-    write( line + "\n" )
+        if self.value:
+            line += " => " + repr(self.value)
 
-    if self.children:
-      margin += "| "
-      for child in self.children.values():
-        child.dump_debug( write, margin )
+        write(line + "\n")
 
-  def locate( self, index ):
-    self.index = index
-    if len( self.letter ) > 0:
-      index += len( self.letter ) + 1
-    else:
-      index += 2
+        if self.children:
+            margin += "| "
+            for child in self.children.values():
+                child.dump_debug(write, margin)
 
-    if self.value != 0:
-      index += 2
+    def locate(self, index):
+        self.index = index
+        if len(self.letter) > 0:
+            index += len(self.letter) + 1
+        else:
+            index += 2
 
-    children = self.children.values()
-    children.sort()
+        if self.value != 0:
+            index += 2
 
-    index += 2 * len( children )
-    for child in children:
-      index = child.locate( index )
+        children = list(self.children.values())
+        children.sort()
 
-    return index
+        index += 2 * len(children)
+        for child in children:
+            index = child.locate(index)
 
-  def store( self, storage ):
-    # write the letters
-    l = len( self.letter )
-    if l == 0:
-      storage += struct.pack( "B", 0 )
-    else:
-      for n in range( l ):
-        val = ord( self.letter[n] )
-        if n < l - 1:
-          val += 128
-        storage += struct.pack( "B", val )
+        return index
 
-    # write the count
-    children = self.children.values()
-    children.sort()
+    def store(self, storage):
+        # write the letters
+        length = len(self.letter)
+        if length == 0:
+            storage += struct.pack("B", 0)
+        else:
+            for n in range(length):
+                val = ord(self.letter[n])
+                if n < length - 1:
+                    val += 128
+                storage += struct.pack("B", val)
 
-    count = len( children )
+        # write the count
+        children = list(self.children.values())
+        children.sort()
 
-    if self.value != 0:
-      storage += struct.pack( "!BH", count + 128, self.value )
-    else:
-      storage += struct.pack( "B", count )
+        count = len(children)
 
-    for child in children:
-      storage += struct.pack( "!H", child.index )
+        if self.value != 0:
+            storage += struct.pack("!BH", count + 128, self.value)
+        else:
+            storage += struct.pack("B", count)
 
-    for child in children:
-      storage = child.store( storage )
+        for child in children:
+            storage += struct.pack("!H", child.index)
 
-    return storage
+        for child in children:
+            storage = child.store(storage)
+
+        return storage
 
 
 def adobe_glyph_values():
-  """return the list of glyph names and their unicode values"""
+    """return the list of glyph names and their unicode values"""
 
-  lines  = string.split( adobe_glyph_list, '\n' )
-  glyphs = []
-  values = []
+    lines = adobe_glyph_list.split("\n")
+    glyphs = []
+    values = []
 
-  for line in lines:
-    if line:
-      fields = string.split( line, ';' )
-#     print fields[1] + ' - ' + fields[0]
-      subfields = string.split( fields[1], ' ' )
-      if len( subfields ) == 1:
-        glyphs.append( fields[0] )
-        values.append( fields[1] )
+    for line in lines:
+        if line:
+            fields = line.split(';')
+            #     print fields[1] + ' - ' + fields[0]
+            subfields = fields[1].split(' ')
+            if len(subfields) == 1:
+                glyphs.append(fields[0])
+                values.append(fields[1])
 
-  return glyphs, values
+    return glyphs, values
 
 
-def filter_glyph_names( alist, filter ):
-  """filter `alist' by taking _out_ all glyph names that are in `filter'"""
+def filter_glyph_names(alist, filter):
+    """filter `alist' by taking _out_ all glyph names that are in `filter'"""
 
-  count  = 0
-  extras = []
+    count = 0
+    extras = []
 
-  for name in alist:
-    try:
-      filtered_index = filter.index( name )
-    except:
-      extras.append( name )
+    for name in alist:
+        try:
+            filtered_index = filter.index(name)
+        except:
+            extras.append(name)
 
-  return extras
+    return extras
 
 
-def dump_encoding( file, encoding_name, encoding_list ):
-  """dump a given encoding"""
+def dump_encoding(file, encoding_name, encoding_list):
+    """dump a given encoding"""
 
-  write = file.write
-  write( "  /* the following are indices into the SID name table */\n" )
-  write( "#ifndef  DEFINE_PS_TABLES_DATA\n" )
-  write( "#ifdef  __cplusplus\n" )
-  write( '  extern "C"\n' )
-  write( "#else\n" )
-  write( "  extern\n" )
-  write( "#endif\n" )
-  write( "#endif\n" )
-  write( "  const unsigned short  " + encoding_name +
-         "[" + repr( len( encoding_list ) ) + "]\n" )
-  write( "#ifdef  DEFINE_PS_TABLES_DATA\n" )
-  write( "  =\n" )
-  write( "  {\n" )
+    write = file.write
+    write("  /* the following are indices into the SID name table */\n")
+    write("#ifndef  DEFINE_PS_TABLES_DATA\n")
+    write("#ifdef  __cplusplus\n")
+    write('  extern "C"\n')
+    write("#else\n")
+    write("  extern\n")
+    write("#endif\n")
+    write("#endif\n")
+    write("  const unsigned short  " + encoding_name +
+          "[" + repr(len(encoding_list)) + "]\n")
+    write("#ifdef  DEFINE_PS_TABLES_DATA\n")
+    write("  =\n")
+    write("  {\n")
 
-  line  = "    "
-  comma = ""
-  col   = 0
-  for value in encoding_list:
-    line += comma
-    line += "%3d" % value
-    comma = ","
-    col  += 1
-    if col == 16:
-      col = 0
-      comma = ",\n    "
+    line = "    "
+    comma = ""
+    col = 0
+    for value in encoding_list:
+        line += comma
+        line += "%3d" % value
+        comma = ","
+        col += 1
+        if col == 16:
+            col = 0
+            comma = ",\n    "
 
-  write( line )
-  write( "\n" )
-  write( "  }\n" )
-  write( "#endif /* DEFINE_PS_TABLES_DATA */\n" )
-  write( "  ;\n\n\n" )
+    write(line)
+    write("\n")
+    write("  }\n")
+    write("#endif /* DEFINE_PS_TABLES_DATA */\n")
+    write("  ;\n\n\n")
 
 
-def dump_array( the_array, write, array_name ):
-  """dumps a given encoding"""
+def dump_array(the_array, write, array_name):
+    """dumps a given encoding"""
 
-  write( "#ifndef  DEFINE_PS_TABLES_DATA\n" )
-  write( "#ifdef  __cplusplus\n" )
-  write( '  extern "C"\n' )
-  write( "#else\n" )
-  write( "  extern\n" )
-  write( "#endif\n" )
-  write( "#endif\n" )
-  write( "  const unsigned char  " + array_name +
-         "[" + repr( len( the_array ) ) + "L]\n" )
-  write( "#ifdef  DEFINE_PS_TABLES_DATA\n" )
-  write( "  =\n" )
-  write( "  {\n" )
+    write("#ifndef  DEFINE_PS_TABLES_DATA\n")
+    write("#ifdef  __cplusplus\n")
+    write('  extern "C"\n')
+    write("#else\n")
+    write("  extern\n")
+    write("#endif\n")
+    write("#endif\n")
+    write("  const unsigned char  " + array_name +
+          "[" + repr(len(the_array)) + "L]\n")
+    write("#ifdef  DEFINE_PS_TABLES_DATA\n")
+    write("  =\n")
+    write("  {\n")
 
-  line  = ""
-  comma = "    "
-  col   = 0
+    line = ""
+    comma = "    "
+    col = 0
 
-  for value in the_array:
-    line += comma
-    line += "%3d" % ord( value )
-    comma = ","
-    col  += 1
+    for value in the_array:
+        line += comma
+        line += "%3d" % value
+        comma = ","
+        col += 1
 
-    if col == 16:
-      col   = 0
-      comma = ",\n    "
+        if col == 16:
+            col = 0
+            comma = ",\n    "
 
-    if len( line ) > 1024:
-      write( line )
-      line = ""
+        if len(line) > 1024:
+            write(line)
+            line = ""
 
-  write( line )
-  write( "\n" )
-  write( "  }\n" )
-  write( "#endif /* DEFINE_PS_TABLES_DATA */\n" )
-  write( "  ;\n\n\n" )
+    write(line)
+    write("\n")
+    write("  }\n")
+    write("#endif /* DEFINE_PS_TABLES_DATA */\n")
+    write("  ;\n\n\n")
 
 
 def main():
-  """main program body"""
+    """main program body"""
 
-  if len( sys.argv ) != 2:
-    print __doc__ % sys.argv[0]
-    sys.exit( 1 )
+    if len(sys.argv) != 2:
+        print(__doc__ % sys.argv[0])
+        sys.exit(1)
 
-  file  = open( sys.argv[1], "wb" )
-  write = file.write
+    file = open(sys.argv[1], "w")
+    write = file.write
 
-  count_sid = len( sid_standard_names )
+    count_sid = len(sid_standard_names)
 
-  # `mac_extras' contains the list of glyph names in the Macintosh standard
-  # encoding which are not in the SID Standard Names.
-  #
-  mac_extras = filter_glyph_names( mac_standard_names, sid_standard_names )
+    # `mac_extras' contains the list of glyph names in the Macintosh standard
+    # encoding which are not in the SID Standard Names.
+    #
+    mac_extras = filter_glyph_names(mac_standard_names, sid_standard_names)
 
-  # `base_list' contains the names of our final glyph names table.
-  # It consists of the `mac_extras' glyph names, followed by the SID
-  # standard names.
-  #
-  mac_extras_count = len( mac_extras )
-  base_list        = mac_extras + sid_standard_names
+    # `base_list' contains the names of our final glyph names table.
+    # It consists of the `mac_extras' glyph names, followed by the SID
+    # standard names.
+    #
+    mac_extras_count = len(mac_extras)
+    base_list = mac_extras + sid_standard_names
 
-  write( "/****************************************************************************\n" )
-  write( " *\n" )
+    write("/*\n")
+    write(" *\n")
+    write(" * %-71s\n" % os.path.basename(sys.argv[1]))
+    write(" *\n")
+    write(" *   PostScript glyph names.\n")
+    write(" *\n")
+    write(" * Copyright 2005-2022 by\n")
+    write(" * David Turner, Robert Wilhelm, and Werner Lemberg.\n")
+    write(" *\n")
+    write(" * This file is part of the FreeType project, and may only be "
+          "used,\n")
+    write(" * modified, and distributed under the terms of the FreeType "
+          "project\n")
+    write(" * license, LICENSE.TXT.  By continuing to use, modify, or "
+          "distribute\n")
+    write(" * this file you indicate that you have read the license and\n")
+    write(" * understand and accept it fully.\n")
+    write(" *\n")
+    write(" */\n")
+    write("\n")
+    write("\n")
+    write("  /* This file has been generated automatically -- do not edit! */"
+          "\n")
+    write("\n")
+    write("\n")
 
-  write( " * %-71s\n" % os.path.basename( sys.argv[1] ) )
+    # dump final glyph list (mac extras + sid standard names)
+    #
+    st = StringTable(base_list, "ft_standard_glyph_names")
 
-  write( " *\n" )
-  write( " *   PostScript glyph names.\n" )
-  write( " *\n" )
-  write( " * Copyright 2005-2018 by\n" )
-  write( " * David Turner, Robert Wilhelm, and Werner Lemberg.\n" )
-  write( " *\n" )
-  write( " * This file is part of the FreeType project, and may only be used,\n" )
-  write( " * modified, and distributed under the terms of the FreeType project\n" )
-  write( " * license, LICENSE.TXT.  By continuing to use, modify, or distribute\n" )
-  write( " * this file you indicate that you have read the license and\n" )
-  write( " * understand and accept it fully.\n" )
-  write( " *\n" )
-  write( " */\n" )
-  write( "\n" )
-  write( "\n" )
-  write( "  /* This file has been generated automatically -- do not edit! */\n" )
-  write( "\n" )
-  write( "\n" )
+    st.dump(file)
+    st.dump_sublist(file, "ft_mac_names",
+                    "FT_NUM_MAC_NAMES", mac_standard_names)
+    st.dump_sublist(file, "ft_sid_names",
+                    "FT_NUM_SID_NAMES", sid_standard_names)
 
-  # dump final glyph list (mac extras + sid standard names)
-  #
-  st = StringTable( base_list, "ft_standard_glyph_names" )
+    dump_encoding(file, "t1_standard_encoding", t1_standard_encoding)
+    dump_encoding(file, "t1_expert_encoding", t1_expert_encoding)
 
-  st.dump( file )
-  st.dump_sublist( file, "ft_mac_names",
-                   "FT_NUM_MAC_NAMES", mac_standard_names )
-  st.dump_sublist( file, "ft_sid_names",
-                   "FT_NUM_SID_NAMES", sid_standard_names )
+    # dump the AGL in its compressed form
+    #
+    agl_glyphs, agl_values = adobe_glyph_values()
+    dictionary = StringNode("", 0)
 
-  dump_encoding( file, "t1_standard_encoding", t1_standard_encoding )
-  dump_encoding( file, "t1_expert_encoding", t1_expert_encoding )
+    for g in range(len(agl_glyphs)):
+        dictionary.add(agl_glyphs[g], eval("0x" + agl_values[g]))
 
-  # dump the AGL in its compressed form
-  #
-  agl_glyphs, agl_values = adobe_glyph_values()
-  dict = StringNode( "", 0 )
+    dictionary = dictionary.optimize()
+    dict_len = dictionary.locate(0)
+    dict_array = dictionary.store(b"")
 
-  for g in range( len( agl_glyphs ) ):
-    dict.add( agl_glyphs[g], eval( "0x" + agl_values[g] ) )
-
-  dict       = dict.optimize()
-  dict_len   = dict.locate( 0 )
-  dict_array = dict.store( "" )
-
-  write( """\
+    write("""\
   /*
    * This table is a compressed version of the Adobe Glyph List (AGL),
    * optimized for efficient searching.  It has been generated by the
@@ -5371,13 +5364,13 @@
 
 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
 
-""" )
+""")
 
-  dump_array( dict_array, write, "ft_adobe_glyph_list" )
+    dump_array(dict_array, write, "ft_adobe_glyph_list")
 
-  # write the lookup routine now
-  #
-  write( """\
+    # write the lookup routine now
+    #
+    write("""\
 #ifdef  DEFINE_PS_TABLES
   /*
    * This function searches the compressed table efficiently.
@@ -5477,64 +5470,64 @@
 
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
-""" )
+""")
 
-  if 0:  # generate unit test, or don't
-    #
-    # now write the unit test to check that everything works OK
-    #
-    write( "#ifdef TEST\n\n" )
+    if 0:  # generate unit test, or don't
+        #
+        # now write the unit test to check that everything works OK
+        #
+        write("#ifdef TEST\n\n")
 
-    write( "static const char* const  the_names[] = {\n" )
-    for name in agl_glyphs:
-      write( '  "' + name + '",\n' )
-    write( "  0\n};\n" )
+        write("static const char* const  the_names[] = {\n")
+        for name in agl_glyphs:
+            write('  "' + name + '",\n')
+        write("  0\n};\n")
 
-    write( "static const unsigned long  the_values[] = {\n" )
-    for val in agl_values:
-      write( '  0x' + val + ',\n' )
-    write( "  0\n};\n" )
+        write("static const unsigned long  the_values[] = {\n")
+        for val in agl_values:
+            write('  0x' + val + ',\n')
+        write("  0\n};\n")
 
-    write( """
+        write("""
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
-  int
-  main( void )
+int
+main( void )
+{
+int                   result = 0;
+const char* const*    names  = the_names;
+const unsigned long*  values = the_values;
+
+
+for ( ; *names; names++, values++ )
+{
+  const char*    name      = *names;
+  unsigned long  reference = *values;
+  unsigned long  value;
+
+
+  value = ft_get_adobe_glyph_index( name, name + strlen( name ) );
+  if ( value != reference )
   {
-    int                   result = 0;
-    const char* const*    names  = the_names;
-    const unsigned long*  values = the_values;
-
-
-    for ( ; *names; names++, values++ )
-    {
-      const char*    name      = *names;
-      unsigned long  reference = *values;
-      unsigned long  value;
-
-
-      value = ft_get_adobe_glyph_index( name, name + strlen( name ) );
-      if ( value != reference )
-      {
-        result = 1;
-        fprintf( stderr, "name '%s' => %04x instead of %04x\\n",
-                         name, value, reference );
-      }
-    }
-
-    return result;
+    result = 1;
+    fprintf( stderr, "name '%s' => %04x instead of %04x\\n",
+                     name, value, reference );
   }
-""" )
+}
 
-    write( "#endif /* TEST */\n" )
+return result;
+}
+""")
 
-  write("\n/* END */\n")
+        write("#endif /* TEST */\n")
+
+    write("\n/* END */\n")
 
 
 # Now run the main routine
 #
 main()
 
-
 # END
diff --git a/src/tools/make_distribution_archives.py b/src/tools/make_distribution_archives.py
new file mode 100755
index 0000000..f29eb12
--- /dev/null
+++ b/src/tools/make_distribution_archives.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python3
+"""Generate distribution archives for a given FreeType 2 release."""
+
+from __future__ import print_function
+
+import argparse
+import atexit
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+_TOP_DIR = os.path.abspath(os.path.join(__file__, "..", "..", ".."))
+_SCRIPT_DIR = os.path.dirname(os.path.join(_TOP_DIR, "builds", "meson", ""))
+
+
+def get_cmd_output(cmd, cwd=None):
+    """Run a command and return its output as a string."""
+    if cwd is not None:
+        out = subprocess.check_output(cmd, cwd=cwd)
+    else:
+        out = subprocess.check_output(cmd)
+    return out.decode("utf-8").rstrip()
+
+
+def is_git_dir_clean(git_dir):
+    """Return True iff |git_dir| is a git directory in clean state."""
+    out = get_cmd_output(["git", "status", "--porcelain"], cwd=git_dir)
+    return len(out) == 0
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    parser.add_argument(
+        "--source_dir", default=_TOP_DIR, help="Source directory path."
+    )
+
+    parser.add_argument(
+        "--version",
+        help=(
+            "Specify alternate FreeType version (it is otherwise extracted"
+            " from current sources by default)."
+        ),
+    )
+
+    parser.add_argument(
+        "--gnu-config-dir",
+        help=(
+            "Path of input directory containing recent `config.guess` and"
+            " `config.sub` files from GNU config."
+        ),
+    )
+
+    parser.add_argument(
+        "--build-dir",
+        help="Specify build directory. Only used for debugging this script.",
+    )
+
+    parser.add_argument(
+        "--ignore-clean-check",
+        action="store_true",
+        help=(
+            "Do not check for a clean source git repository. Only used for"
+            " debugging this script."
+        ),
+    )
+
+    parser.add_argument(
+        "output_dir", help="Output directory for generated archives."
+    )
+
+    args = parser.parse_args()
+
+    git_dir = args.source_dir if args.source_dir else _TOP_DIR
+    if not args.ignore_clean_check and not is_git_dir_clean(git_dir):
+        sys.stderr.write(
+            "ERROR: Your git repository is not in a clean state: %s\n"
+            % git_dir
+        )
+        return 1
+
+    if args.version:
+        version = args.version
+    else:
+        # Extract FreeType version from sources.
+        version = get_cmd_output(
+            [
+                sys.executable,
+                os.path.join(_SCRIPT_DIR, "extract_freetype_version.py"),
+                os.path.join(_TOP_DIR, "include", "freetype", "freetype.h"),
+            ]
+        )
+
+    # Determine the build directory. This will be a temporary file that is
+    # cleaned up on script exit by default, unless --build-dir=DIR is used,
+    # in which case we only create and empty the directory, but never remove
+    # its content on exit.
+    if args.build_dir:
+        build_dir = args.build_dir
+        if not os.path.exists(build_dir):
+            os.makedirs(build_dir)
+        else:
+            # Remove anything from the build directory, if any.
+            for item in os.listdir(build_dir):
+                file_path = os.path.join(build_dir, item)
+                if os.path.isdir(file_path):
+                    shutil.rmtree(file_path)
+                else:
+                    os.unlink(file_path)
+    else:
+        # Create a temporary directory, and ensure it is removed on exit.
+        build_dir = tempfile.mkdtemp(prefix="freetype-dist-")
+
+        def clean_build_dir():
+            shutil.rmtree(build_dir)
+
+        atexit.register(clean_build_dir)
+
+    # Copy all source files known to git into $BUILD_DIR/freetype-$VERSION
+    # with the exception of .gitignore and .mailmap files.
+    source_files = [
+        f
+        for f in get_cmd_output(["git", "ls-files"], cwd=git_dir).split("\n")
+        if os.path.basename(f) not in (".gitignore", ".mailmap")
+    ]
+
+    freetype_dir = "freetype-" + version
+    tmp_src_dir = os.path.join(build_dir, freetype_dir)
+    os.makedirs(tmp_src_dir)
+
+    for src in source_files:
+        dst = os.path.join(tmp_src_dir, src)
+        dst_dir = os.path.dirname(dst)
+        if not os.path.exists(dst_dir):
+            os.makedirs(dst_dir)
+        shutil.copy(os.path.join(git_dir, src), dst)
+
+    # Run autogen.sh in directory.
+    subprocess.check_call(["/bin/sh", "autogen.sh"], cwd=tmp_src_dir)
+    shutil.rmtree(
+        os.path.join(tmp_src_dir, "builds", "unix", "autom4te.cache")
+    )
+
+    # Copy config.guess and config.sub if possible!
+    if args.gnu_config_dir:
+        for f in ("config.guess", "config.sub"):
+            shutil.copy(
+                os.path.join(args.gnu_config_dir, f),
+                os.path.join(tmp_src_dir, "builds", "unix", f),
+            )
+
+    # Generate reference documentation under docs/
+    subprocess.check_call(
+        [
+            sys.executable,
+            os.path.join(_SCRIPT_DIR, "generate_reference_docs.py"),
+            "--input-dir",
+            tmp_src_dir,
+            "--version",
+            version,
+            "--output-dir",
+            os.path.join(tmp_src_dir, "docs"),
+        ]
+    )
+
+    shutil.rmtree(os.path.join(tmp_src_dir, "docs", "markdown"))
+    os.unlink(os.path.join(tmp_src_dir, "docs", "mkdocs.yml"))
+
+    # Generate our archives
+    freetype_tar = freetype_dir + ".tar"
+
+    subprocess.check_call(
+        ["tar", "-H", "ustar", "-chf", freetype_tar, freetype_dir],
+        cwd=build_dir,
+    )
+
+    subprocess.check_call(
+        ["gzip", "-9", "--keep", freetype_tar], cwd=build_dir
+    )
+
+    subprocess.check_call(["xz", "--keep", freetype_tar], cwd=build_dir)
+
+    ftwinversion = "ft" + "".join(version.split("."))
+    subprocess.check_call(
+        ["zip", "-qlr9", ftwinversion + ".zip", freetype_dir], cwd=build_dir
+    )
+
+    # Copy file to output directory now.
+    if not os.path.exists(args.output_dir):
+        os.makedirs(args.output_dir)
+
+    for f in (
+        freetype_tar + ".gz",
+        freetype_tar + ".xz",
+        ftwinversion + ".zip",
+    ):
+        shutil.copy(
+            os.path.join(build_dir, f), os.path.join(args.output_dir, f)
+        )
+
+    # Done!
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/src/tools/no-copyright b/src/tools/no-copyright
index d639aa4..e171b76 100644
--- a/src/tools/no-copyright
+++ b/src/tools/no-copyright
@@ -1,14 +1,12 @@
 # Files that don't get a copyright, or which are taken from elsewhere.
 #
-# All lines in this file are patterns, including the comment lines; this
-# means that e.g. `FTL.TXT' matches all files that have this string in
-# the file name (including the path relative to the current directory,
-# always starting with `./').
+# All lines in this file are patterns (relative to the top-level directory),
+# including the comment lines; this means that e.g. `FTL.TXT' matches all
+# files that have this string in the file name (including the path relative
+# to the current directory, always starting with `./').
 #
 # Don't put empty lines into this file!
 #
-.gitignore
-#
 builds/unix/pkg.m4
 #
 docs/FTL.TXT
@@ -44,6 +42,7 @@
 src/pcf/rules.mk
 #
 src/gzip/adler32.c
+src/gzip/ftzconf.c
 src/gzip/infblock.c
 src/gzip/infblock.h
 src/gzip/infcodes.c
@@ -62,4 +61,6 @@
 src/tools/apinames.c
 src/tools/ftrandom/ftrandom.c
 #
+subprojects/dlg
+#
 # EOF
diff --git a/src/tools/test_afm.c b/src/tools/test_afm.c
index 8de619b..a4b2268 100644
--- a/src/tools/test_afm.c
+++ b/src/tools/test_afm.c
@@ -2,10 +2,9 @@
  * gcc -DFT2_BUILD_LIBRARY -I../../include -o test_afm test_afm.c \
  *     -L../../objs/.libs -lfreetype -lz -static
  */
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psaux.h>
 
   void dump_fontinfo( AFM_FontInfo  fi )
   {
diff --git a/src/tools/test_bbox.c b/src/tools/test_bbox.c
index 64b82c3..d9fd932 100644
--- a/src/tools/test_bbox.c
+++ b/src/tools/test_bbox.c
@@ -1,6 +1,5 @@
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_BBOX_H
+#include <freetype/freetype.h>
+#include <freetype/ftbbox.h>
 
 
 #include <time.h>    /* for clock() */
diff --git a/src/tools/test_trig.c b/src/tools/test_trig.c
index 99ac1cf..4f3410a 100644
--- a/src/tools/test_trig.c
+++ b/src/tools/test_trig.c
@@ -1,6 +1,5 @@
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TRIGONOMETRY_H
+#include <freetype/freetype.h>
+#include <freetype/fttrigon.h>
 
 #include <math.h>
 #include <stdio.h>
diff --git a/src/tools/update-copyright b/src/tools/update-copyright
index 4a8bf9b..674823c 100755
--- a/src/tools/update-copyright
+++ b/src/tools/update-copyright
@@ -4,10 +4,10 @@
 # taking care of exceptions stored in file `no-copyright'.
 
 topdir=`git rev-parse --show-toplevel`
-toolsdir=$topdir/src/tools
+toolsdir=`dirname $0`
 
 git ls-files --full-name $topdir        \
-| sed 's|^|../../|'                     \
+| sed "s|^|$topdir/|"                   \
 | grep -vFf $toolsdir/no-copyright      \
 | xargs $toolsdir/update-copyright-year
 
diff --git a/src/tools/update-copyright-year b/src/tools/update-copyright-year
index 934f11c..b0b60fb 100755
--- a/src/tools/update-copyright-year
+++ b/src/tools/update-copyright-year
@@ -2,7 +2,7 @@
   & eval 'exec perl -wS -i "$0" $argv:q'
     if 0;
 
-# Copyright 2015-2018 by
+# Copyright (C) 2015-2023 by
 # Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -28,20 +28,20 @@
 #
 # or
 #
-#   /* Copyright 2000,  2001, 2004-2007 by    */
-#   /* foobar                                 */
+#   /* Copyright (c) 2000,  2001, 2004-2007 by    */
+#   /* foobar                                     */
 #
 # and replaces them uniformly with
 #
-#   Copyright 2000-2015
+#   Copyright (C) 2000-2021
 #   foobar
 #
 # and
 #
-#   /* Copyright 2000-2015 by                 */
-#   /* foobar                                 */
+#   /* Copyright (C) 2000-2021 by                 */
+#   /* foobar                                     */
 #
-# (assuming that the current year is 2015).  As can be seen, the line length
+# (assuming that the current year is 2021).  As can be seen, the line length
 # is retained if there is non-whitespace after the word `by' on the same
 # line.
 
@@ -67,7 +67,8 @@
     s {
         (?<begin>.*)
         Copyright
-        (?<space1>\ +)
+        (?<space1>(\ +
+                   | \ +\(C\)\ +))
         (?<first>[12][0-9][0-9][0-9])
         (?<middle>.+)
         (?<last>[12][0-9][0-9][0-9])
@@ -78,14 +79,15 @@
       }
       {
         # Fill line to the same length (if appropriate); we skip the middle
-        # part but insert two spaces and `-'.
-        my $space = length($+{space1}) - 1
-                    + length($+{middle}) - 1
-                    + length($+{space2}) - 1
-                    + length($+{space3});
+        # part but insert `(C)', three spaces, and `-'.
+        my $space = length($+{space1})
+                    + length($+{middle})
+                    + length($+{space2})
+                    + length($+{space3})
+                    - (length("(C)") + 3 + 1);
 
         print "$+{begin}";
-        print "Copyright\ $+{first}-$year\ by";
+        print "Copyright\ (C)\ $+{first}-$year\ by";
         print ' ' x $space if length($+{end});
         print "$+{end}\n";
         $replaced = 1;
@@ -95,7 +97,8 @@
     s {
         (?<begin>.*)
         Copyright
-        (?<space1>\ +)
+        (?<space1>(\ +
+                   | \ +\(C\)\ +))
         (?<first>[12][0-9][0-9][0-9])
         (?<space2>\ +)
         by
@@ -103,19 +106,38 @@
         (?<end>.*)
       }
       {
-        # Fill line to the same length (if appropriate); we insert two
-        # spaces, a `-', and the current year.
-        my $space = length($+{space1}) - 1
-                    + length($+{space2}) - 1
-                    + length($+{space3})
-                    - (length($year) + 1);
+        if ($+{first} < $year)
+        {
+          # Fill line to the same length (if appropriate); we insert three
+          # spaces, the string `(C)', a `-', and the current year.
+          my $space = length($+{space1})
+                      + length($+{space2})
+                      + length($+{space3})
+                      - (length($year) + length("(C)") + 3 + 1);
 
-        print "$+{begin}";
-        print "Copyright $+{first}-$year by";
-        # If $space is negative this inserts nothing.
-        print ' ' x $space if length($+{end});
-        print "$+{end}\n";
-        $replaced = 1;
+          print "$+{begin}";
+          print "Copyright\ (C)\ $+{first}-$year\ by";
+          # If $space is negative this inserts nothing.
+          print ' ' x $space if length($+{end});
+          print "$+{end}\n";
+          $replaced = 1;
+        }
+        else
+        {
+          # Fill line to the same length (if appropriate); we insert three
+          # spaces and the string `(C)'.
+          my $space = length($+{space1})
+                      + length($+{space2})
+                      + length($+{space3})
+                      - (length("(C)") + 3);
+
+          print "$+{begin}";
+          print "Copyright\ (C)\ $+{first}\ by";
+          # If $space is negative this inserts nothing.
+          print ' ' x $space if length($+{end});
+          print "$+{end}\n";
+          $replaced = 1;
+        }
       }ex
     ||
     # Otherwise print line unaltered.
diff --git a/src/truetype/Jamfile b/src/truetype/Jamfile
deleted file mode 100644
index e321fba..0000000
--- a/src/truetype/Jamfile
+++ /dev/null
@@ -1,37 +0,0 @@
-# FreeType 2 src/truetype Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) truetype ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = ttdriver
-               ttgload
-               ttgxvar
-               ttinterp
-               ttobjs
-               ttpic
-               ttpload
-               ttsubpix
-               ;
-  }
-  else
-  {
-    _sources = truetype ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/truetype Jamfile
diff --git a/src/truetype/module.mk b/src/truetype/module.mk
index 16bc9c8..5d44ac1 100644
--- a/src/truetype/module.mk
+++ b/src/truetype/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/truetype/rules.mk b/src/truetype/rules.mk
index e1547ed..23f6f00 100644
--- a/src/truetype/rules.mk
+++ b/src/truetype/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
index dd64db8..c5faa96 100644
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -4,7 +4,7 @@
  *
  *   FreeType TrueType driver component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "ttdriver.c"   /* driver interface    */
 #include "ttgload.c"    /* glyph loader        */
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index eac736c..4bea63e 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
  *
  *   TrueType font driver implementation (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,22 +16,21 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H
-#include FT_SERVICE_FONT_FORMAT_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/internal/services/svfntfmt.h>
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#include FT_MULTIPLE_MASTERS_H
-#include FT_SERVICE_MULTIPLE_MASTERS_H
-#include FT_SERVICE_METRICS_VARIATIONS_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/services/svmm.h>
+#include <freetype/internal/services/svmetric.h>
 #endif
 
-#include FT_SERVICE_TRUETYPE_ENGINE_H
-#include FT_SERVICE_TRUETYPE_GLYF_H
-#include FT_SERVICE_PROPERTIES_H
-#include FT_DRIVER_H
+#include <freetype/internal/services/svtteng.h>
+#include <freetype/internal/services/svttglyf.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/ftdriver.h>
 
 #include "ttdriver.h"
 #include "ttgload.h"
@@ -51,7 +50,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttdriver
+#define FT_COMPONENT  ttdriver
 
 
   /*
@@ -109,7 +108,7 @@
       return error;
     }
 
-    FT_TRACE0(( "tt_property_set: missing property `%s'\n",
+    FT_TRACE2(( "tt_property_set: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
@@ -136,7 +135,7 @@
       return error;
     }
 
-    FT_TRACE0(( "tt_property_get: missing property `%s'\n",
+    FT_TRACE2(( "tt_property_get: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
   }
@@ -355,7 +354,16 @@
 
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
-    FT_Request_Metrics( size->face, req );
+    {
+      FT_Error  err = FT_Request_Metrics( size->face, req );
+
+
+      if ( err )
+      {
+        error = err;
+        goto Exit;
+      }
+    }
 
     if ( FT_IS_SCALABLE( size->face ) )
     {
@@ -383,6 +391,7 @@
 #endif
     }
 
+  Exit:
     return error;
   }
 
@@ -498,17 +507,34 @@
   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_Get_Var_Blend_Func) tt_get_var_blend,       /* get_var_blend  */
-    (FT_Done_Blend_Func)    tt_done_blend           /* done_blend     */
+    (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                */
   )
 
   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h
index 45e25b6..757a66f 100644
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
  *
  *   High-level TrueType driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define TTDRIVER_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/truetype/tterrors.h b/src/truetype/tterrors.h
index a14dee3..008ee99 100644
--- a/src/truetype/tterrors.h
+++ b/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
  *
  *   TrueType error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef TTERRORS_H_
 #define TTERRORS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  TT_Err_
 #define FT_ERR_BASE    FT_Mod_Err_TrueType
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* TTERRORS_H_ */
 
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 9e98f11..d33bdad 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
  *
  *   TrueType Glyph Loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,15 +17,15 @@
 
 
 #include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_OUTLINE_H
-#include FT_DRIVER_H
-#include FT_LIST_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 <freetype/ftlist.h>
 
 #include "ttgload.h"
 #include "ttpload.h"
@@ -45,7 +45,22 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttgload
+#define FT_COMPONENT  ttgload
+
+
+  /**************************************************************************
+   *
+   * Simple glyph flags.
+   */
+#define ON_CURVE_POINT  0x01  /* same value as FT_CURVE_TAG_ON            */
+#define X_SHORT_VECTOR  0x02
+#define Y_SHORT_VECTOR  0x04
+#define REPEAT_FLAG     0x08
+#define X_POSITIVE      0x10  /* two meanings depending on X_SHORT_VECTOR */
+#define SAME_X          0x10
+#define Y_POSITIVE      0x20  /* two meanings depending on Y_SHORT_VECTOR */
+#define SAME_Y          0x20
+#define OVERLAP_SIMPLE  0x40  /* retained as FT_OUTLINE_OVERLAP           */
 
 
   /**************************************************************************
@@ -62,11 +77,20 @@
 #define WE_HAVE_A_2X2              0x0080
 #define WE_HAVE_INSTR              0x0100
 #define USE_MY_METRICS             0x0200
-#define OVERLAP_COMPOUND           0x0400
+#define OVERLAP_COMPOUND           0x0400  /* retained as FT_OUTLINE_OVERLAP */
 #define SCALED_COMPONENT_OFFSET    0x0800
 #define UNSCALED_COMPONENT_OFFSET  0x1000
 
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#define IS_DEFAULT_INSTANCE( _face )             \
+          ( !( FT_IS_NAMED_INSTANCE( _face ) ||  \
+               FT_IS_VARIATION( _face )      ) )
+#else
+#define IS_DEFAULT_INSTANCE( _face )  1
+#endif
+
+
   /**************************************************************************
    *
    * Return the horizontal metrics in font units for a given glyph.
@@ -113,6 +137,11 @@
                                 face->horizontal.Descender );
     }
 
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( !face->vertical_info )
+      FT_TRACE5(( "  [vertical metrics missing, computing values]\n" ));
+#endif
+
     FT_TRACE5(( "  advance height (font units): %d\n", *ah ));
     FT_TRACE5(( "  top side bearing (font units): %d\n", *tsb ));
   }
@@ -168,10 +197,17 @@
     }
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
-    if ( !loader->linear_def )
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    /* With the incremental interface, these values are set by  */
+    /* a call to `tt_get_metrics_incremental'.                  */
+    if ( face->root.internal->incremental_interface == NULL )
+#endif
     {
-      loader->linear_def = 1;
-      loader->linear     = advance_width;
+      if ( !loader->linear_def )
+      {
+        loader->linear_def = 1;
+        loader->linear     = advance_width;
+      }
     }
 
     return FT_Err_Ok;
@@ -181,8 +217,8 @@
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 
   static void
-  tt_get_metrics_incr_overrides( TT_Loader  loader,
-                                 FT_UInt    glyph_index )
+  tt_get_metrics_incremental( TT_Loader  loader,
+                              FT_UInt    glyph_index )
   {
     TT_Face  face = loader->face;
 
@@ -267,12 +303,9 @@
     FT_Error   error;
     FT_Stream  stream = loader->stream;
 
-    /* for non-debug mode */
     FT_UNUSED( glyph_index );
 
 
-    FT_TRACE4(( "Glyph %ld\n", glyph_index ));
-
     /* the following line sets the `error' variable through macros! */
     if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
       return error;
@@ -312,9 +345,9 @@
     loader->bbox.yMax = FT_NEXT_SHORT( p );
 
     FT_TRACE5(( "  # of contours: %d\n", loader->n_contours ));
-    FT_TRACE5(( "  xMin: %4d  xMax: %4d\n", loader->bbox.xMin,
+    FT_TRACE5(( "  xMin: %4ld  xMax: %4ld\n", loader->bbox.xMin,
                                             loader->bbox.xMax ));
-    FT_TRACE5(( "  yMin: %4d  yMax: %4d\n", loader->bbox.yMin,
+    FT_TRACE5(( "  yMin: %4ld  yMax: %4ld\n", loader->bbox.yMin,
                                             loader->bbox.yMax ));
     loader->cursor = p;
 
@@ -337,7 +370,7 @@
     FT_Byte         *flag, *flag_limit;
     FT_Byte         c, count;
     FT_Vector       *vec, *vec_limit;
-    FT_Pos          x;
+    FT_Pos          x, y;
     FT_Short        *cont, *cont_limit, prev_cont;
     FT_Int          xy_size = 0;
 
@@ -425,7 +458,7 @@
                           (void*)&load->exec->glyphIns,
                           n_ins );
 
-      load->exec->glyphSize = (FT_UShort)tmp;
+      load->exec->glyphSize = (FT_UInt)tmp;
       if ( error )
         return error;
 
@@ -454,7 +487,7 @@
         goto Invalid_Outline;
 
       *flag++ = c = FT_NEXT_BYTE( p );
-      if ( c & 8 )
+      if ( c & REPEAT_FLAG )
       {
         if ( p + 1 > limit )
           goto Invalid_Outline;
@@ -468,6 +501,10 @@
       }
     }
 
+    /* retain the overlap flag */
+    if ( n_points && outline->tags[0] & OVERLAP_SIMPLE )
+      gloader->base.outline.flags |= FT_OUTLINE_OVERLAP;
+
     /* reading the X coordinates */
 
     vec       = outline->points;
@@ -480,31 +517,29 @@
 
     for ( ; vec < vec_limit; vec++, flag++ )
     {
-      FT_Pos   y = 0;
-      FT_Byte  f = *flag;
+      FT_Pos   delta = 0;
+      FT_Byte  f     = *flag;
 
 
-      if ( f & 2 )
+      if ( f & X_SHORT_VECTOR )
       {
         if ( p + 1 > limit )
           goto Invalid_Outline;
 
-        y = (FT_Pos)FT_NEXT_BYTE( p );
-        if ( ( f & 16 ) == 0 )
-          y = -y;
+        delta = (FT_Pos)FT_NEXT_BYTE( p );
+        if ( !( f & X_POSITIVE ) )
+          delta = -delta;
       }
-      else if ( ( f & 16 ) == 0 )
+      else if ( !( f & SAME_X ) )
       {
         if ( p + 2 > limit )
           goto Invalid_Outline;
 
-        y = (FT_Pos)FT_NEXT_SHORT( p );
+        delta = (FT_Pos)FT_NEXT_SHORT( p );
       }
 
-      x     += y;
+      x     += delta;
       vec->x = x;
-      /* the cast is for stupid compilers */
-      *flag  = (FT_Byte)( f & ~( 2 | 16 ) );
     }
 
     /* reading the Y coordinates */
@@ -512,35 +547,36 @@
     vec       = gloader->current.outline.points;
     vec_limit = vec + n_points;
     flag      = (FT_Byte*)outline->tags;
-    x         = 0;
+    y         = 0;
 
     for ( ; vec < vec_limit; vec++, flag++ )
     {
-      FT_Pos   y = 0;
-      FT_Byte  f = *flag;
+      FT_Pos   delta = 0;
+      FT_Byte  f     = *flag;
 
 
-      if ( f & 4 )
+      if ( f & Y_SHORT_VECTOR )
       {
         if ( p + 1 > limit )
           goto Invalid_Outline;
 
-        y = (FT_Pos)FT_NEXT_BYTE( p );
-        if ( ( f & 32 ) == 0 )
-          y = -y;
+        delta = (FT_Pos)FT_NEXT_BYTE( p );
+        if ( !( f & Y_POSITIVE ) )
+          delta = -delta;
       }
-      else if ( ( f & 32 ) == 0 )
+      else if ( !( f & SAME_Y ) )
       {
         if ( p + 2 > limit )
           goto Invalid_Outline;
 
-        y = (FT_Pos)FT_NEXT_SHORT( p );
+        delta = (FT_Pos)FT_NEXT_SHORT( p );
       }
 
-      x     += y;
-      vec->y = x;
+      y     += delta;
+      vec->y = y;
+
       /* the cast is for stupid compilers */
-      *flag  = (FT_Byte)( f & FT_CURVE_TAG_ON );
+      *flag  = (FT_Byte)( f & ON_CURVE_POINT );
     }
 
     outline->n_points   = (FT_Short)n_points;
@@ -701,18 +737,20 @@
 
         if ( subglyph->flags & WE_HAVE_A_SCALE )
           FT_TRACE7(( "      scaling: %f\n",
-                      subglyph->transform.xx / 65536.0 ));
+                      (double)subglyph->transform.xx / 65536 ));
         else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
           FT_TRACE7(( "      scaling: x=%f, y=%f\n",
-                      subglyph->transform.xx / 65536.0,
-                      subglyph->transform.yy / 65536.0 ));
+                      (double)subglyph->transform.xx / 65536,
+                      (double)subglyph->transform.yy / 65536 ));
         else if ( subglyph->flags & WE_HAVE_A_2X2 )
-          FT_TRACE7(( "      scaling: xx=%f, yx=%f\n"
-                      "               xy=%f, yy=%f\n",
-                      subglyph->transform.xx / 65536.0,
-                      subglyph->transform.yx / 65536.0,
-                      subglyph->transform.xy / 65536.0,
-                      subglyph->transform.yy / 65536.0 ));
+        {
+          FT_TRACE7(( "      scaling: xx=%f, yx=%f\n",
+                      (double)subglyph->transform.xx / 65536,
+                      (double)subglyph->transform.yx / 65536 ));
+          FT_TRACE7(( "               xy=%f, yy=%f\n",
+                      (double)subglyph->transform.xy / 65536,
+                      (double)subglyph->transform.yy / 65536 ));
+        }
 
         subglyph++;
       }
@@ -763,7 +801,7 @@
                    FT_UInt       start_point,
                    FT_UInt       start_contour )
   {
-    zone->n_points    = (FT_UShort)load->outline.n_points -
+    zone->n_points    = (FT_UShort)load->outline.n_points + 4 -
                           (FT_UShort)start_point;
     zone->n_contours  = load->outline.n_contours -
                           (FT_Short)start_contour;
@@ -805,15 +843,9 @@
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    if ( loader->glyph->control_len > 0xFFFFL )
-    {
-      FT_TRACE1(( "TT_Hint_Glyph: too long instructions" ));
-      FT_TRACE1(( " (0x%lx byte) is truncated\n",
-                  loader->glyph->control_len ));
-    }
     n_ins = loader->glyph->control_len;
 
-    /* save original point position in org */
+    /* save original point positions in `org' array */
     if ( n_ins > 0 )
       FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
 
@@ -922,6 +954,11 @@
     FT_Outline*     outline;
     FT_Int          n_points;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    FT_Memory   memory    = loader->face->root.memory;
+    FT_Vector*  unrounded = NULL;
+#endif
+
 
     outline  = &gloader->current.outline;
     n_points = outline->n_points;
@@ -933,35 +970,21 @@
     outline->points[n_points + 2] = loader->pp3;
     outline->points[n_points + 3] = loader->pp4;
 
-    outline->tags[n_points    ] = 0;
-    outline->tags[n_points + 1] = 0;
-    outline->tags[n_points + 2] = 0;
-    outline->tags[n_points + 3] = 0;
-
     n_points += 4;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-    if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
-         FT_IS_VARIATION( FT_FACE( loader->face ) )      )
+    if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
     {
+      if ( FT_NEW_ARRAY( unrounded, n_points ) )
+        goto Exit;
+
       /* Deltas apply to the unscaled data. */
-      error = TT_Vary_Apply_Glyph_Deltas( loader->face,
-                                          loader->glyph_index,
+      error = TT_Vary_Apply_Glyph_Deltas( loader,
                                           outline,
-                                          (FT_UInt)n_points );
-
-      /* recalculate linear horizontal and vertical advances */
-      /* if we don't have HVAR and VVAR, respectively        */
-      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
-        loader->linear = outline->points[n_points - 3].x -
-                         outline->points[n_points - 4].x;
-      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
-        loader->vadvance = outline->points[n_points - 1].x -
-                           outline->points[n_points - 2].x;
-
+                                          unrounded );
       if ( error )
-        return error;
+        goto Exit;
     }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -971,7 +994,7 @@
       tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
 
       FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
-                     loader->zone.n_points + 4 );
+                     loader->zone.n_points );
     }
 
     {
@@ -1016,10 +1039,23 @@
           /* compensate for any scaling by de/emboldening; */
           /* the amount was determined via experimentation */
           if ( x_scale_factor != 1000 && ppem > 11 )
+          {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+            FT_Vector*  orig_points = outline->points;
+
+
+            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
+              outline->points = unrounded;
+#endif
             FT_Outline_EmboldenXY( outline,
                                    FT_MulFix( 1280 * ppem,
                                               1000 - x_scale_factor ),
                                    0 );
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
+              outline->points = orig_points;
+#endif
+          }
           do_scale = TRUE;
         }
       }
@@ -1040,17 +1076,40 @@
 
       if ( do_scale )
       {
-        for ( ; vec < limit; vec++ )
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
         {
-          vec->x = FT_MulFix( vec->x, x_scale );
-          vec->y = FT_MulFix( vec->y, y_scale );
+          FT_Vector*  u = unrounded;
+
+
+          for ( ; vec < limit; vec++, u++ )
+          {
+            vec->x = ADD_LONG( FT_MulFix( u->x, x_scale ), 32 ) >> 6;
+            vec->y = ADD_LONG( FT_MulFix( u->y, y_scale ), 32 ) >> 6;
+          }
+        }
+        else
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+        {
+          for ( ; vec < limit; vec++ )
+          {
+            vec->x = FT_MulFix( vec->x, x_scale );
+            vec->y = FT_MulFix( vec->y, y_scale );
+          }
         }
       }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-      /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
-      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
-           !IS_HINTED( loader->load_flags )                                 )
+      /* if we have a HVAR table, `pp1' and/or `pp2' */
+      /* are already adjusted but unscaled           */
+      if ( ( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) &&
+           IS_HINTED( loader->load_flags )                                 )
+      {
+        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
+        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
+        /* pp1.y and pp2.y are always zero */
+      }
+      else
 #endif
       {
         loader->pp1 = outline->points[n_points - 4];
@@ -1058,9 +1117,17 @@
       }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-      /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
-      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
-           !IS_HINTED( loader->load_flags )                                 )
+      /* if we have a VVAR table, `pp3' and/or `pp4' */
+      /* are already adjusted but unscaled           */
+      if ( ( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) &&
+           IS_HINTED( loader->load_flags )                                 )
+      {
+        loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
+        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
+        loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
+        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
+      }
+      else
 #endif
       {
         loader->pp3 = outline->points[n_points - 2];
@@ -1069,11 +1136,12 @@
     }
 
     if ( IS_HINTED( loader->load_flags ) )
-    {
-      loader->zone.n_points += 4;
-
       error = TT_Hint_Glyph( loader, 0 );
-    }
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  Exit:
+    FT_FREE( unrounded );
+#endif
 
     return error;
   }
@@ -1136,8 +1204,8 @@
       p1 = gloader->base.outline.points + k;
       p2 = gloader->base.outline.points + l;
 
-      x = p1->x - p2->x;
-      y = p1->y - p2->y;
+      x = SUB_LONG( p1->x, p2->x );
+      y = SUB_LONG( p1->y, p2->y );
     }
     else
     {
@@ -1281,11 +1349,6 @@
     outline->points[outline->n_points + 2] = loader->pp3;
     outline->points[outline->n_points + 3] = loader->pp4;
 
-    outline->tags[outline->n_points    ] = 0;
-    outline->tags[outline->n_points + 1] = 0;
-    outline->tags[outline->n_points + 2] = 0;
-    outline->tags[outline->n_points + 3] = 0;
-
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     {
@@ -1300,7 +1363,7 @@
            FT_READ_USHORT( n_ins )           )
         return error;
 
-      FT_TRACE5(( "  Instructions size = %d\n", n_ins ));
+      FT_TRACE5(( "  Instructions size = %hu\n", n_ins ));
 
       /* check it */
       max_ins = loader->face->max_profile.maxSizeOfInstructions;
@@ -1308,10 +1371,10 @@
       {
         /* don't trust `maxSizeOfInstructions'; */
         /* only do a rough safety check         */
-        if ( (FT_Int)n_ins > loader->byte_len )
+        if ( n_ins > loader->byte_len )
         {
           FT_TRACE1(( "TT_Process_Composite_Glyph:"
-                      " too many instructions (%d) for glyph with length %d\n",
+                      " too many instructions (%hu) for glyph with length %u\n",
                       n_ins, loader->byte_len ));
           return FT_THROW( Too_Many_Hints );
         }
@@ -1344,11 +1407,9 @@
 
     /* Some points are likely touched during execution of  */
     /* instructions on components.  So let's untouch them. */
-    for ( i = 0; i < loader->zone.n_points; i++ )
+    for ( i = 0; i < loader->zone.n_points - 4U; i++ )
       loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
 
-    loader->zone.n_points += 4;
-
     return TT_Hint_Glyph( loader, 1 );
   }
 
@@ -1468,7 +1529,7 @@
     }
 #endif
 
-    use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
+    use_aw_2 = FT_BOOL( subpixel_hinting && grayscale );
 
     loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
     loader->pp1.y = 0;
@@ -1520,12 +1581,13 @@
                        FT_UInt    recurse_count,
                        FT_Bool    header_only )
   {
-    FT_Error        error        = FT_Err_Ok;
+    FT_Error        error   = FT_Err_Ok;
     FT_Fixed        x_scale, y_scale;
     FT_ULong        offset;
-    TT_Face         face         = loader->face;
-    FT_GlyphLoader  gloader      = loader->gloader;
-    FT_Bool         opened_frame = 0;
+    TT_Face         face    = loader->face;
+    FT_GlyphLoader  gloader = loader->gloader;
+
+    FT_Bool  opened_frame = 0;
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     FT_StreamRec    inc_stream;
@@ -1558,16 +1620,16 @@
 
     loader->glyph_index = glyph_index;
 
-    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
-    {
-      x_scale = loader->size->metrics->x_scale;
-      y_scale = loader->size->metrics->y_scale;
-    }
-    else
+    if ( loader->load_flags & FT_LOAD_NO_SCALE )
     {
       x_scale = 0x10000L;
       y_scale = 0x10000L;
     }
+    else
+    {
+      x_scale = loader->size->metrics->x_scale;
+      y_scale = loader->size->metrics->y_scale;
+    }
 
     /* Set `offset' to the start of the glyph relative to the start of */
     /* the `glyf' table, and `byte_len' to the length of the glyph in  */
@@ -1593,7 +1655,7 @@
       FT_ZERO( &inc_stream );
       FT_Stream_OpenMemory( &inc_stream,
                             glyph_data.pointer,
-                            (FT_ULong)glyph_data.length );
+                            glyph_data.length );
 
       loader->stream = &inc_stream;
     }
@@ -1601,8 +1663,7 @@
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
-      offset = tt_face_get_location( face, glyph_index,
-                                     (FT_UInt*)&loader->byte_len );
+      offset = tt_face_get_location( face, glyph_index, &loader->byte_len );
 
     if ( loader->byte_len > 0 )
     {
@@ -1621,49 +1682,45 @@
 
       error = face->access_glyph_frame( loader, glyph_index,
                                         face->glyf_offset + offset,
-                                        (FT_UInt)loader->byte_len );
+                                        loader->byte_len );
       if ( error )
         goto Exit;
 
-      opened_frame = 1;
-
       /* read glyph header first */
       error = face->read_glyph_header( loader );
-      if ( error )
-        goto Exit;
 
-      /* the metrics must be computed after loading the glyph header */
-      /* since we need the glyph's `yMax' value in case the vertical */
-      /* metrics must be emulated                                    */
-      error = tt_get_metrics( loader, glyph_index );
-      if ( error )
-        goto Exit;
+      face->forget_glyph_frame( loader );
 
-      if ( header_only )
+      if ( error )
         goto Exit;
     }
 
+    /* a space glyph */
     if ( loader->byte_len == 0 || loader->n_contours == 0 )
     {
       loader->bbox.xMin = 0;
       loader->bbox.xMax = 0;
       loader->bbox.yMin = 0;
       loader->bbox.yMax = 0;
+    }
 
-      error = tt_get_metrics( loader, glyph_index );
-      if ( error )
-        goto Exit;
+    /* the metrics must be computed after loading the glyph header */
+    /* since we need the glyph's `yMax' value in case the vertical */
+    /* metrics must be emulated                                    */
+    error = tt_get_metrics( loader, glyph_index );
+    if ( error )
+      goto Exit;
 
-      if ( header_only )
-        goto Exit;
+    if ( header_only )
+      goto Exit;
 
-      /* must initialize points before (possibly) overriding */
-      /* glyph metrics from the incremental interface        */
+    if ( loader->byte_len == 0 || loader->n_contours == 0 )
+    {
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+      tt_get_metrics_incremental( loader, glyph_index );
+#endif
       tt_loader_set_pp( loader );
 
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
-      tt_get_metrics_incr_overrides( loader, glyph_index );
-#endif
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
@@ -1673,52 +1730,29 @@
         /* a small outline structure with four elements for */
         /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
         FT_Vector   points[4];
-        char        tags[4]     = { 1, 1, 1, 1 };
-        short       contours[4] = { 0, 1, 2, 3 };
         FT_Outline  outline;
 
+        /* unrounded values */
+        FT_Vector  unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
 
-        points[0].x = loader->pp1.x;
-        points[0].y = loader->pp1.y;
-        points[1].x = loader->pp2.x;
-        points[1].y = loader->pp2.y;
 
-        points[2].x = loader->pp3.x;
-        points[2].y = loader->pp3.y;
-        points[3].x = loader->pp4.x;
-        points[3].y = loader->pp4.y;
+        points[0] = loader->pp1;
+        points[1] = loader->pp2;
+        points[2] = loader->pp3;
+        points[3] = loader->pp4;
 
-        outline.n_points   = 4;
-        outline.n_contours = 4;
+        outline.n_points   = 0;
+        outline.n_contours = 0;
         outline.points     = points;
-        outline.tags       = tags;
-        outline.contours   = contours;
+        outline.tags       = NULL;
+        outline.contours   = NULL;
 
         /* this must be done before scaling */
-        error = TT_Vary_Apply_Glyph_Deltas( loader->face,
-                                            glyph_index,
+        error = TT_Vary_Apply_Glyph_Deltas( loader,
                                             &outline,
-                                            (FT_UInt)outline.n_points );
+                                            unrounded );
         if ( error )
           goto Exit;
-
-        loader->pp1.x = points[0].x;
-        loader->pp1.y = points[0].y;
-        loader->pp2.x = points[1].x;
-        loader->pp2.y = points[1].y;
-
-        loader->pp3.x = points[2].x;
-        loader->pp3.y = points[2].y;
-        loader->pp4.x = points[3].x;
-        loader->pp4.y = points[3].y;
-
-
-        /* recalculate linear horizontal and vertical advances */
-        /* if we don't have HVAR and VVAR, respectively        */
-        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
-          loader->linear = loader->pp2.x - loader->pp1.x;
-        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
-          loader->vadvance = loader->pp4.x - loader->pp3.x;
       }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1741,18 +1775,26 @@
       goto Exit;
     }
 
-    /* must initialize phantom points before (possibly) overriding */
-    /* glyph metrics from the incremental interface                */
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    tt_get_metrics_incremental( loader, glyph_index );
+#endif
     tt_loader_set_pp( loader );
 
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
-    tt_get_metrics_incr_overrides( loader, glyph_index );
-#endif
 
     /***********************************************************************/
     /***********************************************************************/
     /***********************************************************************/
 
+    /* we now open a frame again, right after the glyph header */
+    /* (which consists of 10 bytes)                            */
+    error = face->access_glyph_frame( loader, glyph_index,
+                                      face->glyf_offset + offset + 10,
+                                      loader->byte_len - 10 );
+    if ( error )
+      goto Exit;
+
+    opened_frame = 1;
+
     /* if it is a simple glyph, load it */
 
     if ( loader->n_contours > 0 )
@@ -1798,11 +1840,10 @@
        * pointers with a width of at least 32 bits.
        */
 
-
       /* clear the nodes filled by sibling chains */
       node = ft_list_get_node_at( &loader->composites, recurse_count );
       for ( node2 = node; node2; node2 = node2->next )
-        node2->data = (void*)FT_ULONG_MAX;
+        node2->data = (void*)-1;
 
       /* check whether we already have a composite glyph with this index */
       if ( FT_List_Find( &loader->composites,
@@ -1819,7 +1860,7 @@
 
       else
       {
-        if ( FT_NEW( node ) )
+        if ( FT_QNEW( node ) )
           goto Exit;
         node->data = FT_UINT_TO_POINTER( glyph_index );
         FT_List_Add( &loader->composites, node );
@@ -1849,25 +1890,26 @@
         FT_SubGlyph  subglyph;
 
         FT_Outline  outline;
-        FT_Vector*  points   = NULL;
-        char*       tags     = NULL;
-        short*      contours = NULL;
+        FT_Vector*  points    = NULL;
+        char*       tags      = NULL;
+        short*      contours  = NULL;
+        FT_Vector*  unrounded = NULL;
 
 
         limit = (short)gloader->current.num_subglyphs;
 
         /* construct an outline structure for              */
         /* communication with `TT_Vary_Apply_Glyph_Deltas' */
-        outline.n_points   = (short)( gloader->current.num_subglyphs + 4 );
-        outline.n_contours = outline.n_points;
+        outline.n_contours = outline.n_points = limit;
 
         outline.points   = NULL;
         outline.tags     = NULL;
         outline.contours = NULL;
 
-        if ( FT_NEW_ARRAY( points, outline.n_points )   ||
-             FT_NEW_ARRAY( tags, outline.n_points )     ||
-             FT_NEW_ARRAY( contours, outline.n_points ) )
+        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 ) )
           goto Exit1;
 
         subglyph = gloader->current.subglyphs;
@@ -1883,28 +1925,10 @@
           contours[i] = i;
         }
 
-        points[i].x = loader->pp1.x;
-        points[i].y = loader->pp1.y;
-        tags[i]     = 1;
-        contours[i] = i;
-
-        i++;
-        points[i].x = loader->pp2.x;
-        points[i].y = loader->pp2.y;
-        tags[i]     = 1;
-        contours[i] = i;
-
-        i++;
-        points[i].x = loader->pp3.x;
-        points[i].y = loader->pp3.y;
-        tags[i]     = 1;
-        contours[i] = i;
-
-        i++;
-        points[i].x = loader->pp4.x;
-        points[i].y = loader->pp4.y;
-        tags[i]     = 1;
-        contours[i] = i;
+        points[i++] = loader->pp1;
+        points[i++] = loader->pp2;
+        points[i++] = loader->pp3;
+        points[i  ] = loader->pp4;
 
         outline.points   = points;
         outline.tags     = tags;
@@ -1912,11 +1936,9 @@
 
         /* this call provides additional offsets */
         /* for each component's translation      */
-        if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
-                             face,
-                             glyph_index,
-                             &outline,
-                             (FT_UInt)outline.n_points ) ) )
+        if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( loader,
+                                                       &outline,
+                                                       unrounded ) ) )
           goto Exit1;
 
         subglyph = gloader->current.subglyphs;
@@ -1930,27 +1952,11 @@
           }
         }
 
-        loader->pp1.x = points[i + 0].x;
-        loader->pp1.y = points[i + 0].y;
-        loader->pp2.x = points[i + 1].x;
-        loader->pp2.y = points[i + 1].y;
-
-        loader->pp3.x = points[i + 2].x;
-        loader->pp3.y = points[i + 2].y;
-        loader->pp4.x = points[i + 3].x;
-        loader->pp4.y = points[i + 3].y;
-
-        /* recalculate linear horizontal and vertical advances */
-        /* if we don't have HVAR and VVAR, respectively        */
-        if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
-          loader->linear = loader->pp2.x - loader->pp1.x;
-        if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
-          loader->vadvance = loader->pp4.x - loader->pp3.x;
-
       Exit1:
         FT_FREE( outline.points );
         FT_FREE( outline.tags );
         FT_FREE( outline.contours );
+        FT_FREE( unrounded );
 
         if ( error )
           goto Exit;
@@ -1996,7 +2002,7 @@
         FT_UInt      num_base_subgs = gloader->base.num_subglyphs;
 
         FT_Stream    old_stream     = loader->stream;
-        FT_Int       old_byte_len   = loader->byte_len;
+        FT_UInt      old_byte_len   = loader->byte_len;
 
 
         FT_GlyphLoader_Add( gloader );
@@ -2010,7 +2016,7 @@
           FT_Int  linear_vadvance;
 
 
-          /* Each time we call load_truetype_glyph in this loop, the   */
+          /* Each time we call `load_truetype_glyph' in this loop, the */
           /* value of `gloader.base.subglyphs' can change due to table */
           /* reallocations.  We thus need to recompute the subglyph    */
           /* pointer on each iteration.                                */
@@ -2053,12 +2059,14 @@
           if ( num_points == num_base_points )
             continue;
 
-          /* gloader->base.outline consists of three parts:               */
-          /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
-          /*                                                              */
-          /* (1): exists from the beginning                               */
-          /* (2): components that have been loaded so far                 */
-          /* (3): the newly loaded component                              */
+          /* gloader->base.outline consists of three parts:           */
+          /*                                                          */
+          /* 0 ----> start_point ----> num_base_points ----> n_points */
+          /*    (1)               (2)                   (3)           */
+          /*                                                          */
+          /* (1) points that exist from the beginning                 */
+          /* (2) component points that have been loaded so far        */
+          /* (3) points of the newly loaded component                 */
           error = TT_Process_Composite_Component( loader,
                                                   subglyph,
                                                   start_point,
@@ -2074,6 +2082,7 @@
         loader->ins_pos = ins_pos;
         if ( IS_HINTED( loader->load_flags ) &&
 #ifdef TT_USE_BYTECODE_INTERPRETER
+             subglyph                        &&
              subglyph->flags & WE_HAVE_INSTR &&
 #endif
              num_points > start_point )
@@ -2085,6 +2094,11 @@
             goto Exit;
         }
       }
+
+      /* retain the overlap flag */
+      if ( gloader->base.num_subglyphs                         &&
+           gloader->base.subglyphs[0].flags & OVERLAP_COMPOUND )
+        gloader->base.outline.flags |= FT_OUTLINE_OVERLAP;
     }
 
     /***********************************************************************/
@@ -2113,16 +2127,11 @@
   compute_glyph_metrics( TT_Loader  loader,
                          FT_UInt    glyph_index )
   {
-    TT_Face    face   = loader->face;
-#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
-    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-#endif
-
+    TT_Face       face  = loader->face;
+    TT_Size       size  = loader->size;
+    TT_GlyphSlot  glyph = loader->glyph;
     FT_BBox       bbox;
     FT_Fixed      y_scale;
-    TT_GlyphSlot  glyph = loader->glyph;
-    TT_Size       size  = loader->size;
 
 
     y_scale = 0x10000L;
@@ -2140,53 +2149,10 @@
 
     glyph->metrics.horiBearingX = bbox.xMin;
     glyph->metrics.horiBearingY = bbox.yMax;
-    glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;
-
-    /* Adjust advance width to the value contained in the hdmx table   */
-    /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
-    /* mode of the v40 interpreter is active.  See `ttinterp.h' for    */
-    /* details on backward compatibility mode.                         */
-    if (
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-         !( driver->interpreter_version == TT_INTERPRETER_VERSION_40  &&
-            ( loader->exec && loader->exec->backward_compatibility  ) ) &&
-#endif
-         !face->postscript.isFixedPitch                                 &&
-         IS_HINTED( loader->load_flags )                                &&
-         !( loader->load_flags & FT_LOAD_COMPUTE_METRICS )              )
-    {
-      FT_Byte*  widthp;
-
-
-      widthp = tt_face_get_device_metrics( face,
-                                           size->metrics->x_ppem,
-                                           glyph_index );
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-      {
-        FT_Bool  ignore_x_mode;
-
-
-        ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
-                                 FT_RENDER_MODE_MONO );
-
-        if ( widthp                                                   &&
-             ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
-                !ignore_x_mode                                      ||
-                SPH_OPTION_BITMAP_WIDTHS                            ) )
-          glyph->metrics.horiAdvance = *widthp * 64;
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-      {
-        if ( widthp )
-          glyph->metrics.horiAdvance = *widthp * 64;
-      }
-    }
+    if ( loader->widthp )
+      glyph->metrics.horiAdvance = loader->widthp[glyph_index] * 64;
+    else
+      glyph->metrics.horiAdvance = SUB_LONG( loader->pp2.x, loader->pp1.x );
 
     /* set glyph dimensions */
     glyph->metrics.width  = SUB_LONG( bbox.xMax, bbox.xMin );
@@ -2204,13 +2170,14 @@
       if ( face->vertical_info                   &&
            face->vertical.number_Of_VMetrics > 0 )
       {
-        top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
+        top = (FT_Short)FT_DivFix( SUB_LONG( loader->pp3.y, bbox.yMax ),
                                    y_scale );
 
         if ( loader->pp3.y <= loader->pp4.y )
           advance = 0;
         else
-          advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
+          advance = (FT_UShort)FT_DivFix( SUB_LONG( loader->pp3.y,
+                                                    loader->pp4.y ),
                                           y_scale );
       }
       else
@@ -2302,17 +2269,13 @@
                    FT_UInt       glyph_index,
                    FT_Int32      load_flags )
   {
-    TT_Face             face;
-    SFNT_Service        sfnt;
-    FT_Stream           stream;
+    TT_Face             face   = (TT_Face)glyph->face;
+    SFNT_Service        sfnt   = (SFNT_Service)face->sfnt;
+    FT_Stream           stream = face->root.stream;
     FT_Error            error;
     TT_SBit_MetricsRec  sbit_metrics;
 
 
-    face   = (TT_Face)glyph->face;
-    sfnt   = (SFNT_Service)face->sfnt;
-    stream = face->root.stream;
-
     error = sfnt->load_sbit_image( face,
                                    size->strike_index,
                                    glyph_index,
@@ -2363,22 +2326,19 @@
                   FT_Int32      load_flags,
                   FT_Bool       glyf_table_only )
   {
-    TT_Face    face;
-    FT_Stream  stream;
+    TT_Face    face   = (TT_Face)glyph->face;
+    FT_Stream  stream = face->root.stream;
 
 #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
-    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
+    TT_Driver  driver   = (TT_Driver)FT_FACE_DRIVER( glyph->face );
 #endif
 #endif
 
 
-    face   = (TT_Face)glyph->face;
-    stream = face->root.stream;
-
     FT_ZERO( loader );
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
@@ -2597,14 +2557,12 @@
 
       if ( reexecute )
       {
-        FT_UInt  i;
-
-
-        for ( i = 0; i < size->cvt_size; i++ )
-          size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
         error = tt_size_run_prep( size, pedantic );
         if ( error )
           return error;
+        error = TT_Load_Context( exec, face, size );
+        if ( error )
+          return error;
       }
 
       /* check whether the cvt program has disabled hinting */
@@ -2620,12 +2578,58 @@
       /* 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 = 0;
-#endif
+        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
+       * when
+       *
+       * 1) we have a `tricky' font that heavily relies on the interpreter to
+       *    render glyphs correctly, for example DFKai-SB, or
+       * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested.
+       *
+       * In those cases, backward compatibility needs to be turned off to get
+       * correct rendering.  The rendering is then completely up to the
+       * font's programming.
+       *
+       */
+      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+           subpixel_hinting_lean                                    &&
+           !FT_IS_TRICKY( glyph->face )                             )
+        exec->backward_compatibility = !( exec->GS.instruct_control & 4 );
+      else
+        exec->backward_compatibility = FALSE;
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
 
       exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
       loader->exec = exec;
       loader->instructions = exec->glyphIns;
+
+      /* Use the hdmx table if any unless FT_LOAD_COMPUTE_METRICS */
+      /* is set or backward compatibility mode of the v38 or v40  */
+      /* interpreters is active.  See `ttinterp.h' for details on */
+      /* backward compatibility mode.                             */
+      if ( IS_HINTED( loader->load_flags )                                &&
+           !( loader->load_flags & FT_LOAD_COMPUTE_METRICS )              &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+           !( 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;
+      }
+      else
+        loader->widthp = NULL;
     }
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
@@ -2673,11 +2677,12 @@
    *   A function used to load a single glyph within a given glyph slot,
    *   for a given size.
    *
-   * @Input:
+   * @InOut:
    *   glyph ::
    *     A handle to a target slot object where the glyph
    *     will be loaded.
    *
+   * @Input:
    *   size ::
    *     A handle to the source face size at which the glyph
    *     must be scaled/loaded.
@@ -2701,16 +2706,10 @@
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
   {
+    TT_Face       face = (TT_Face)glyph->face;
     FT_Error      error;
     TT_LoaderRec  loader;
 
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#define IS_DEFAULT_INSTANCE  ( !( FT_IS_NAMED_INSTANCE( glyph->face ) ||  \
-                                  FT_IS_VARIATION( glyph->face )      ) )
-#else
-#define IS_DEFAULT_INSTANCE  1
-#endif
-
 
     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
 
@@ -2719,7 +2718,7 @@
     /* try to load embedded bitmap (if any) */
     if ( size->strike_index != 0xFFFFFFFFUL      &&
          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
-         IS_DEFAULT_INSTANCE                     )
+         IS_DEFAULT_INSTANCE( glyph->face )      )
     {
       FT_Fixed  x_scale = size->root.metrics.x_scale;
       FT_Fixed  y_scale = size->root.metrics.y_scale;
@@ -2732,8 +2731,6 @@
         /* if we have a bitmap-only font, return an empty glyph            */
         if ( !FT_IS_SCALABLE( glyph->face ) )
         {
-          TT_Face  face = (TT_Face)glyph->face;
-
           FT_Short  left_bearing = 0;
           FT_Short  top_bearing  = 0;
 
@@ -2789,7 +2786,8 @@
       }
       else
       {
-        if ( FT_IS_SCALABLE( glyph->face ) )
+        if ( FT_IS_SCALABLE( glyph->face ) ||
+             FT_HAS_SBIX( glyph->face )    )
         {
           /* for the bbox we need the header only */
           (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
@@ -2798,6 +2796,35 @@
           glyph->linearHoriAdvance = loader.linear;
           glyph->linearVertAdvance = loader.vadvance;
 
+          /* Bitmaps from the 'sbix' table need special treatment:  */
+          /* if there is a glyph contour, the bitmap origin must be */
+          /* shifted to be relative to the lower left corner of the */
+          /* glyph bounding box, also taking the left-side bearing  */
+          /* (or top bearing) into account.                         */
+          if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX &&
+               loader.n_contours > 0                            )
+          {
+            FT_Int  bitmap_left;
+            FT_Int  bitmap_top;
+
+
+            if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
+            {
+              /* This is a guess, since Apple's CoreText engine doesn't */
+              /* really do vertical typesetting.                        */
+              bitmap_left = loader.bbox.xMin;
+              bitmap_top  = loader.top_bearing;
+            }
+            else
+            {
+              bitmap_left = loader.left_bearing;
+              bitmap_top  = loader.bbox.yMin;
+            }
+
+            glyph->bitmap_left += FT_MulFix( bitmap_left, x_scale ) >> 6;
+            glyph->bitmap_top  += FT_MulFix( bitmap_top,  y_scale ) >> 6;
+          }
+
           /* sanity checks: if `xxxAdvance' in the sbit metric */
           /* structure isn't set, use `linearXXXAdvance'      */
           if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
@@ -2812,6 +2839,12 @@
       }
     }
 
+    if ( load_flags & FT_LOAD_SBITS_ONLY )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
     /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
@@ -2821,16 +2854,77 @@
       goto Exit;
     }
 
-    if ( load_flags & FT_LOAD_SBITS_ONLY )
+#ifdef FT_CONFIG_OPTION_SVG
+
+    /* check for OT-SVG */
+    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
+    {
+      SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+
+
+      FT_TRACE3(( "Trying to load SVG glyph\n" ));
+
+      error = sfnt->load_svg_doc( glyph, glyph_index );
+      if ( !error )
+      {
+        FT_Fixed  x_scale = size->root.metrics.x_scale;
+        FT_Fixed  y_scale = size->root.metrics.y_scale;
+
+        FT_Short   leftBearing;
+        FT_Short   topBearing;
+        FT_UShort  advanceX;
+        FT_UShort  advanceY;
+
+
+        FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
+
+        glyph->format = FT_GLYPH_FORMAT_SVG;
+
+        sfnt->get_metrics( face,
+                           FALSE,
+                           glyph_index,
+                           &leftBearing,
+                           &advanceX );
+        sfnt->get_metrics( face,
+                           TRUE,
+                           glyph_index,
+                           &topBearing,
+                           &advanceY );
+
+        glyph->linearHoriAdvance = advanceX;
+        glyph->linearVertAdvance = advanceY;
+
+        glyph->metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
+        glyph->metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
+
+        return error;
+      }
+
+      FT_TRACE3(( "Failed to load SVG glyph\n" ));
+    }
+
+    /* return immediately if we only want SVG glyphs */
+    if ( load_flags & FT_LOAD_SVG_ONLY )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
 
+#endif /* FT_CONFIG_OPTION_SVG */
+
     error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
     if ( error )
       goto Exit;
 
+    /* done if we are only interested in the `hdmx` advance */
+    if ( load_flags & FT_LOAD_ADVANCE_ONLY         &&
+         !( load_flags & FT_LOAD_VERTICAL_LAYOUT ) &&
+         loader.widthp                             )
+    {
+      glyph->metrics.horiAdvance = loader.widthp[glyph_index] * 64;
+      goto Done;
+    }
+
     glyph->format        = FT_GLYPH_FORMAT_OUTLINE;
     glyph->num_subglyphs = 0;
     glyph->outline.flags = 0;
@@ -2894,8 +2988,6 @@
       error = compute_glyph_metrics( &loader, glyph_index );
     }
 
-    tt_loader_done( &loader );
-
     /* Set the `high precision' bit flag.                           */
     /* This is _critical_ to get correct output for monochrome      */
     /* TrueType glyphs at all sizes using the bytecode interpreter. */
@@ -2904,6 +2996,16 @@
          size->metrics->y_ppem < 24         )
       glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
 
+    FT_TRACE1(( "  subglyphs = %u, contours = %hd, points = %hd,"
+                " flags = 0x%.3x\n",
+                loader.gloader->base.num_subglyphs,
+                glyph->outline.n_contours,
+                glyph->outline.n_points,
+                glyph->outline.flags ));
+
+  Done:
+    tt_loader_done( &loader );
+
   Exit:
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( error )
diff --git a/src/truetype/ttgload.h b/src/truetype/ttgload.h
index c117728..f18637d 100644
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
  *
  *   TrueType Glyph Loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define TTGLOAD_H_
 
 
-#include <ft2build.h>
 #include "ttobjs.h"
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 3df50d6..60a0095 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
  *
  *   TrueType GX Font Variation loader
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -40,14 +40,15 @@
 
 
 #include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_TRUETYPE_IDS_H
-#include FT_MULTIPLE_MASTERS_H
-#include FT_LIST_H
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/tttags.h>
+#include <freetype/ttnameid.h>
+#include <freetype/ftmm.h>
+#include <freetype/ftlist.h>
 
 #include "ttpload.h"
 #include "ttgxvar.h"
@@ -68,14 +69,16 @@
 
 
   /* some macros we need */
-#define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
-
-#define FT_fdot14ToFixed( x )                \
-        ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
-#define FT_intToFixed( i )                    \
-        ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
-#define FT_fixedToInt( x )                                   \
-        ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
+#define FT_fdot14ToFixed( x )                  \
+          ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
+#define FT_intToFixed( i )                      \
+          ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
+#define FT_fdot6ToFixed( i )                    \
+          ( (FT_Fixed)( (FT_ULong)(i) << 10 ) )
+#define FT_fixedToInt( x )                          \
+          ( (FT_Short)( ( (x) + 0x8000U ) >> 16 ) )
+#define FT_fixedToFdot6( x )                    \
+          ( (FT_Pos)( ( (x) + 0x200 ) >> 10 ) )
 
 
   /**************************************************************************
@@ -85,7 +88,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttgxvar
+#define FT_COMPONENT  ttgxvar
 
 
   /*************************************************************************/
@@ -149,9 +152,7 @@
     FT_UInt    i, j;
     FT_UShort  first;
     FT_Memory  memory = stream->memory;
-    FT_Error   error  = FT_Err_Ok;
-
-    FT_UNUSED( error );
+    FT_Error   error;
 
 
     *point_cnt = 0;
@@ -176,7 +177,7 @@
     /* in the nested loops below we increase `i' twice; */
     /* it is faster to simply allocate one more slot    */
     /* than to add another test within the loop         */
-    if ( FT_NEW_ARRAY( points, n + 1 ) )
+    if ( FT_QNEW_ARRAY( points, n + 1 ) )
       return NULL;
 
     *point_cnt = n;
@@ -262,55 +263,78 @@
     FT_Fixed  *deltas = NULL;
     FT_UInt    runcnt, cnt;
     FT_UInt    i, j;
+    FT_UInt    bytes_used;
     FT_Memory  memory = stream->memory;
-    FT_Error   error  = FT_Err_Ok;
-
-    FT_UNUSED( error );
+    FT_Error   error;
 
 
-    if ( delta_cnt > size )
-    {
-      FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" ));
-      return NULL;
-    }
-
-    if ( FT_NEW_ARRAY( deltas, delta_cnt ) )
+    if ( FT_QNEW_ARRAY( deltas, delta_cnt ) )
       return NULL;
 
-    i = 0;
-    while ( i < delta_cnt )
+    i          = 0;
+    bytes_used = 0;
+
+    while ( i < delta_cnt && bytes_used < size )
     {
       runcnt = FT_GET_BYTE();
       cnt    = runcnt & GX_DT_DELTA_RUN_COUNT_MASK;
 
+      bytes_used++;
+
       if ( runcnt & GX_DT_DELTAS_ARE_ZERO )
       {
-        /* `runcnt' zeroes get added */
+        /* `cnt` + 1 zeroes get added */
         for ( j = 0; j <= cnt && i < delta_cnt; j++ )
           deltas[i++] = 0;
       }
       else if ( runcnt & GX_DT_DELTAS_ARE_WORDS )
       {
-        /* `runcnt' shorts from the stack */
+        /* `cnt` + 1 shorts from the stack */
+        bytes_used += 2 * ( cnt + 1 );
+        if ( bytes_used > size )
+        {
+          FT_TRACE1(( "ft_var_readpackeddeltas:"
+                      " number of short deltas too large\n" ));
+          goto Fail;
+        }
+
         for ( j = 0; j <= cnt && i < delta_cnt; j++ )
           deltas[i++] = FT_intToFixed( FT_GET_SHORT() );
       }
       else
       {
-        /* `runcnt' signed bytes from the stack */
+        /* `cnt` + 1 signed bytes from the stack */
+        bytes_used += cnt + 1;
+        if ( bytes_used > size )
+        {
+          FT_TRACE1(( "ft_var_readpackeddeltas:"
+                      " number of byte deltas too large\n" ));
+          goto Fail;
+        }
+
         for ( j = 0; j <= cnt && i < delta_cnt; j++ )
           deltas[i++] = FT_intToFixed( FT_GET_CHAR() );
       }
 
       if ( j <= cnt )
       {
-        /* bad format */
-        FT_FREE( deltas );
-        return NULL;
+        FT_TRACE1(( "ft_var_readpackeddeltas:"
+                    " number of deltas too large\n" ));
+        goto Fail;
       }
     }
 
+    if ( i < delta_cnt )
+    {
+      FT_TRACE1(( "ft_var_readpackeddeltas: not enough deltas\n" ));
+      goto Fail;
+    }
+
     return deltas;
+
+  Fail:
+    FT_FREE( deltas );
+    return NULL;
   }
 
 
@@ -330,17 +354,24 @@
   static void
   ft_var_load_avar( TT_Face  face )
   {
-    FT_Stream       stream = FT_FACE_STREAM( face );
-    FT_Memory       memory = stream->memory;
+    FT_Error   error;
+    FT_Stream  stream = FT_FACE_STREAM( face );
+    FT_Memory  memory = stream->memory;
+    FT_Int     i, j;
+
     GX_Blend        blend  = face->blend;
     GX_AVarSegment  segment;
-    FT_Error        error = FT_Err_Ok;
-    FT_Long         version;
-    FT_Long         axisCount;
-    FT_Int          i, j;
-    FT_ULong        table_len;
+    GX_AVarTable    table;
 
-    FT_UNUSED( error );
+    FT_Long   version;
+    FT_Long   axisCount;
+    FT_ULong  table_len;
+
+#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
+    FT_ULong  table_offset;
+    FT_ULong  store_offset;
+    FT_ULong  axisMap_offset;
+#endif
 
 
     FT_TRACE2(( "AVAR " ));
@@ -353,13 +384,21 @@
       return;
     }
 
+#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
+    table_offset = FT_STREAM_POS();
+#endif
+
     if ( FT_FRAME_ENTER( table_len ) )
       return;
 
     version   = FT_GET_LONG();
     axisCount = FT_GET_LONG();
 
-    if ( version != 0x00010000L )
+    if ( version != 0x00010000L
+#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
+         && version != 0x00020000L
+#endif
+       )
     {
       FT_TRACE2(( "bad table version\n" ));
       goto Exit;
@@ -369,55 +408,91 @@
 
     if ( axisCount != (FT_Long)blend->mmvar->num_axis )
     {
-      FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `fvar'\n"
-                  "                  table are different\n" ));
+      FT_TRACE2(( "ft_var_load_avar:"
+                  " number of axes in `avar' and `fvar'\n" ));
+      FT_TRACE2(( "                  table are different\n" ));
       goto Exit;
     }
 
-    if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) )
+    if ( FT_NEW( blend->avar_table ) )
+      goto Exit;
+    table = blend->avar_table;
+
+    if ( FT_QNEW_ARRAY( table->avar_segment, axisCount ) )
       goto Exit;
 
-    segment = &blend->avar_segment[0];
+    segment = &table->avar_segment[0];
     for ( i = 0; i < axisCount; i++, segment++ )
     {
       FT_TRACE5(( "  axis %d:\n", i ));
 
       segment->pairCount = FT_GET_USHORT();
-      if ( (FT_ULong)segment->pairCount * 4 > table_len                ||
-           FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
+      if ( (FT_ULong)segment->pairCount * 4 > table_len                 ||
+           FT_QNEW_ARRAY( segment->correspondence, segment->pairCount ) )
       {
         /* Failure.  Free everything we have done so far.  We must do */
         /* it right now since loading the `avar' table is optional.   */
 
         for ( j = i - 1; j >= 0; j-- )
-          FT_FREE( blend->avar_segment[j].correspondence );
+          FT_FREE( table->avar_segment[j].correspondence );
 
-        FT_FREE( blend->avar_segment );
-        blend->avar_segment = NULL;
+        FT_FREE( table->avar_segment );
         goto Exit;
       }
 
       for ( j = 0; j < segment->pairCount; j++ )
       {
-        /* convert to Fixed */
-        segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4;
-        segment->correspondence[j].toCoord   = FT_GET_SHORT() * 4;
+        segment->correspondence[j].fromCoord =
+          FT_fdot14ToFixed( FT_GET_SHORT() );
+        segment->correspondence[j].toCoord =
+          FT_fdot14ToFixed( FT_GET_SHORT() );
 
         FT_TRACE5(( "    mapping %.5f to %.5f\n",
-                    segment->correspondence[j].fromCoord / 65536.0,
-                    segment->correspondence[j].toCoord / 65536.0 ));
+                    (double)segment->correspondence[j].fromCoord / 65536,
+                    (double)segment->correspondence[j].toCoord / 65536 ));
       }
 
       FT_TRACE5(( "\n" ));
     }
 
+#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
+    if ( version < 0x00020000L )
+      goto Exit;
+
+    axisMap_offset = FT_GET_ULONG();
+    store_offset   = FT_GET_ULONG();
+
+    if ( store_offset )
+    {
+      error = tt_var_load_item_variation_store(
+                face,
+                table_offset + store_offset,
+                &table->itemStore );
+      if ( error )
+        goto Exit;
+    }
+
+    if ( axisMap_offset )
+    {
+      error = tt_var_load_delta_set_index_mapping(
+                face,
+                table_offset + axisMap_offset,
+                &table->axisMap,
+                &table->itemStore,
+                table_len );
+      if ( error )
+        goto Exit;
+    }
+#endif
+
+
   Exit:
     FT_FRAME_EXIT();
   }
 
 
-  static FT_Error
-  ft_var_load_item_variation_store( TT_Face          face,
+  FT_LOCAL_DEF( FT_Error )
+  tt_var_load_item_variation_store( TT_Face          face,
                                     FT_ULong         offset,
                                     GX_ItemVarStore  itemStore )
   {
@@ -427,12 +502,15 @@
     FT_Error   error;
     FT_UShort  format;
     FT_ULong   region_offset;
-    FT_UInt    i, j, k;
-    FT_UInt    shortDeltaCount;
 
-    GX_Blend        blend = face->blend;
-    GX_ItemVarData  varData;
+    FT_UInt    data_count;
+    FT_UShort  axis_count;
+    FT_UInt    region_count;
 
+    FT_UInt  i, j, k;
+    FT_Bool  long_words;
+
+    GX_Blend   blend           = face->blend;
     FT_ULong*  dataOffsetArray = NULL;
 
 
@@ -442,31 +520,31 @@
 
     if ( format != 1 )
     {
-      FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n",
+      FT_TRACE2(( "tt_var_load_item_variation_store: bad store format %d\n",
                   format ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
 
     /* read top level fields */
-    if ( FT_READ_ULONG( region_offset )         ||
-         FT_READ_USHORT( itemStore->dataCount ) )
+    if ( FT_READ_ULONG( region_offset ) ||
+         FT_READ_USHORT( data_count )   )
       goto Exit;
 
     /* we need at least one entry in `itemStore->varData' */
-    if ( !itemStore->dataCount )
+    if ( !data_count )
     {
-      FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" ));
+      FT_TRACE2(( "tt_var_load_item_variation_store: missing varData\n" ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
 
     /* make temporary copy of item variation data offsets; */
     /* we will parse region list first, then come back     */
-    if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
+    if ( FT_QNEW_ARRAY( dataOffsetArray, data_count ) )
       goto Exit;
 
-    for ( i = 0; i < itemStore->dataCount; i++ )
+    for ( i = 0; i < data_count; i++ )
     {
       if ( FT_READ_ULONG( dataOffsetArray[i] ) )
         goto Exit;
@@ -476,30 +554,40 @@
     if ( FT_STREAM_SEEK( offset + region_offset ) )
       goto Exit;
 
-    if ( FT_READ_USHORT( itemStore->axisCount )   ||
-         FT_READ_USHORT( itemStore->regionCount ) )
+    if ( FT_READ_USHORT( axis_count )   ||
+         FT_READ_USHORT( region_count ) )
       goto Exit;
 
-    if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
+    if ( axis_count != (FT_Long)blend->mmvar->num_axis )
     {
-      FT_TRACE2(( "ft_var_load_item_variation_store:"
-                  " number of axes in item variation store\n"
-                  "                                 "
+      FT_TRACE2(( "tt_var_load_item_variation_store:"
+                  " number of axes in item variation store\n" ));
+      FT_TRACE2(( "                                 "
                   " and `fvar' table are different\n" ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
+    itemStore->axisCount = axis_count;
 
-    if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) )
+    /* new constraint in OpenType 1.8.4 */
+    if ( region_count >= 32768U )
+    {
+      FT_TRACE2(( "tt_var_load_item_variation_store:"
+                  " too many variation region tables\n" ));
+      error = FT_THROW( Invalid_Table );
       goto Exit;
+    }
+
+    if ( FT_NEW_ARRAY( itemStore->varRegionList, region_count ) )
+      goto Exit;
+    itemStore->regionCount = region_count;
 
     for ( i = 0; i < itemStore->regionCount; i++ )
     {
       GX_AxisCoords  axisCoords;
 
 
-      if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList,
-                         itemStore->axisCount ) )
+      if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, axis_count ) )
         goto Exit;
 
       axisCoords = itemStore->varRegionList[i].axisList;
@@ -523,44 +611,53 @@
     /* end of region list parse */
 
     /* use dataOffsetArray now to parse varData items */
-    if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
+    if ( FT_NEW_ARRAY( itemStore->varData, data_count ) )
       goto Exit;
+    itemStore->dataCount = data_count;
 
-    for ( i = 0; i < itemStore->dataCount; i++ )
+    for ( i = 0; i < data_count; i++ )
     {
-      varData = &itemStore->varData[i];
+      GX_ItemVarData  varData = &itemStore->varData[i];
+
+      FT_UInt  item_count;
+      FT_UInt  word_delta_count;
+      FT_UInt  region_idx_count;
+
 
       if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
         goto Exit;
 
-      if ( FT_READ_USHORT( varData->itemCount )      ||
-           FT_READ_USHORT( shortDeltaCount )         ||
-           FT_READ_USHORT( varData->regionIdxCount ) )
+      if ( FT_READ_USHORT( item_count )       ||
+           FT_READ_USHORT( word_delta_count ) ||
+           FT_READ_USHORT( region_idx_count ) )
         goto Exit;
 
+      long_words        = !!( word_delta_count & 0x8000 );
+      word_delta_count &= 0x7FFF;
+
       /* check some data consistency */
-      if ( shortDeltaCount > varData->regionIdxCount )
+      if ( word_delta_count > region_idx_count )
       {
         FT_TRACE2(( "bad short count %d or region count %d\n",
-                    shortDeltaCount,
-                    varData->regionIdxCount ));
+                    word_delta_count,
+                    region_idx_count ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
 
-      if ( varData->regionIdxCount > itemStore->regionCount )
+      if ( region_idx_count > itemStore->regionCount )
       {
         FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n",
-                    varData->regionIdxCount,
+                    region_idx_count,
                     i ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
 
       /* parse region indices */
-      if ( FT_NEW_ARRAY( varData->regionIndices,
-                         varData->regionIdxCount ) )
+      if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) )
         goto Exit;
+      varData->regionIdxCount = region_idx_count;
 
       for ( j = 0; j < varData->regionIdxCount; j++ )
       {
@@ -576,41 +673,35 @@
         }
       }
 
-      /* Parse delta set.                                                */
-      /*                                                                 */
-      /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes   */
-      /* each; on output, deltas are expanded to `regionIdxCount' shorts */
-      /* each.                                                           */
-      if ( FT_NEW_ARRAY( varData->deltaSet,
-                         varData->regionIdxCount * varData->itemCount ) )
+      /* 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;
 
-      /* the delta set is stored as a 2-dimensional array of shorts; */
-      /* sign-extend signed bytes to signed shorts                   */
-      for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
+      for ( j = 0; j < item_count * region_idx_count; )
       {
-        for ( k = 0; k < shortDeltaCount; k++, j++ )
+        if ( long_words )
         {
-          /* read the short deltas */
-          FT_Short  delta;
-
-
-          if ( FT_READ_SHORT( delta ) )
-            goto Exit;
-
-          varData->deltaSet[j] = delta;
+          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;
         }
-
-        for ( ; k < varData->regionIdxCount; k++, j++ )
+        else
         {
-          /* read the (signed) byte deltas */
-          FT_Char  delta;
-
-
-          if ( FT_READ_CHAR( delta ) )
-            goto Exit;
-
-          varData->deltaSet[j] = delta;
+          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;
         }
       }
     }
@@ -622,41 +713,70 @@
   }
 
 
-  static FT_Error
-  ft_var_load_delta_set_index_mapping( TT_Face            face,
+  FT_LOCAL_DEF( FT_Error )
+  tt_var_load_delta_set_index_mapping( TT_Face            face,
                                        FT_ULong           offset,
                                        GX_DeltaSetIdxMap  map,
-                                       GX_ItemVarStore    itemStore )
+                                       GX_ItemVarStore    itemStore,
+                                       FT_ULong           table_len )
   {
     FT_Stream  stream = FT_FACE_STREAM( face );
     FT_Memory  memory = stream->memory;
 
-    FT_Error   error;
+    FT_Error  error;
 
-    FT_UShort  format;
-    FT_UInt    entrySize;
-    FT_UInt    innerBitCount;
-    FT_UInt    innerIndexMask;
-    FT_UInt    i, j;
+    FT_Byte   format;
+    FT_Byte   entryFormat;
+    FT_UInt   entrySize;
+    FT_UInt   innerBitCount;
+    FT_UInt   innerIndexMask;
+    FT_ULong  i;
+    FT_UInt   j;
 
 
-    if ( FT_STREAM_SEEK( offset )        ||
-         FT_READ_USHORT( format )        ||
-         FT_READ_USHORT( map->mapCount ) )
+    if ( FT_STREAM_SEEK( offset )    ||
+         FT_READ_BYTE( format )      ||
+         FT_READ_BYTE( entryFormat ) )
       goto Exit;
 
-    if ( format & 0xFFC0 )
+    if ( format == 0 )
+    {
+      if ( FT_READ_USHORT( map->mapCount ) )
+        goto Exit;
+    }
+    else if ( format == 1 ) /* new in OpenType 1.9 */
+    {
+      if ( FT_READ_ULONG( map->mapCount ) )
+        goto Exit;
+    }
+    else
     {
       FT_TRACE2(( "bad map format %d\n", format ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
 
+    if ( entryFormat & 0xC0 )
+    {
+      FT_TRACE2(( "bad entry format %d\n", format ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
     /* bytes per entry: 1, 2, 3, or 4 */
-    entrySize      = ( ( format & 0x0030 ) >> 4 ) + 1;
-    innerBitCount  = ( format & 0x000F ) + 1;
+    entrySize      = ( ( entryFormat & 0x30 ) >> 4 ) + 1;
+    innerBitCount  = ( entryFormat & 0x0F ) + 1;
     innerIndexMask = ( 1 << innerBitCount ) - 1;
 
+    /* rough sanity check */
+    if ( map->mapCount * entrySize > table_len )
+    {
+      FT_TRACE1(( "tt_var_load_delta_set_index_mapping:"
+                  " invalid number of delta-set index mappings\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
     if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) )
       goto Exit;
 
@@ -681,11 +801,21 @@
         mapData = ( mapData << 8 ) | data;
       }
 
+      /* new in OpenType 1.8.4 */
+      if ( mapData == 0xFFFFFFFFUL )
+      {
+        /* no variation data for this item */
+        map->outerIndex[i] = 0xFFFFU;
+        map->innerIndex[i] = 0xFFFFU;
+
+        continue;
+      }
+
       outerIndex = mapData >> innerBitCount;
 
       if ( outerIndex >= itemStore->dataCount )
       {
-        FT_TRACE2(( "outerIndex[%d] == %d out of range\n",
+        FT_TRACE2(( "outerIndex[%ld] == %d out of range\n",
                     i,
                     outerIndex ));
         error = FT_THROW( Invalid_Table );
@@ -698,7 +828,7 @@
 
       if ( innerIndex >= itemStore->varData[outerIndex].itemCount )
       {
-        FT_TRACE2(( "innerIndex[%d] == %d out of range\n",
+        FT_TRACE2(( "innerIndex[%ld] == %d out of range\n",
                     i,
                     innerIndex ));
         error = FT_THROW( Invalid_Table );
@@ -810,7 +940,7 @@
       table = blend->hvar_table;
     }
 
-    error = ft_var_load_item_variation_store(
+    error = tt_var_load_item_variation_store(
               face,
               table_offset + store_offset,
               &table->itemStore );
@@ -819,11 +949,12 @@
 
     if ( widthMap_offset )
     {
-      error = ft_var_load_delta_set_index_mapping(
+      error = tt_var_load_delta_set_index_mapping(
                 face,
                 table_offset + widthMap_offset,
                 &table->widthMap,
-                &table->itemStore );
+                &table->itemStore,
+                table_len );
       if ( error )
         goto Exit;
     }
@@ -860,31 +991,52 @@
   }
 
 
-  static FT_Int
-  ft_var_get_item_delta( TT_Face          face,
+  FT_LOCAL_DEF( FT_ItemVarDelta )
+  tt_var_get_item_delta( TT_Face          face,
                          GX_ItemVarStore  itemStore,
                          FT_UInt          outerIndex,
                          FT_UInt          innerIndex )
   {
-    GX_ItemVarData  varData;
-    FT_Short*       deltaSet;
+    FT_Stream  stream = FT_FACE_STREAM( face );
+    FT_Memory  memory = stream->memory;
+    FT_Error   error  = FT_Err_Ok;
 
-    FT_UInt   master, j;
-    FT_Fixed  netAdjustment = 0;     /* accumulated adjustment */
-    FT_Fixed  scaledDelta;
-    FT_Fixed  delta;
+    GX_ItemVarData    varData;
+    FT_ItemVarDelta*  deltaSet;
 
+    FT_UInt          master, j;
+    FT_Fixed*        scalars = NULL;
+    FT_ItemVarDelta  returnValue;
+
+
+    if ( !face->blend || !face->blend->normalizedcoords )
+      return 0;
+
+    /* OpenType 1.8.4+: No variation data for this item */
+    /* as indices have special value 0xFFFF.            */
+    if ( outerIndex == 0xFFFF && innerIndex == 0xFFFF )
+      return 0;
 
     /* See pseudo code from `Font Variations Overview' */
     /* in the OpenType specification.                  */
 
+    if ( outerIndex >= itemStore->dataCount )
+      return 0; /* Out of range. */
+
     varData  = &itemStore->varData[outerIndex];
-    deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex];
+    deltaSet = FT_OFFSET( varData->deltaSet,
+                          varData->regionIdxCount * innerIndex );
+
+    if ( innerIndex >= varData->itemCount )
+      return 0; /* Out of range. */
+
+    if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
+      return 0;
 
     /* outer loop steps through master designs to be blended */
     for ( master = 0; master < varData->regionIdxCount; master++ )
     {
-      FT_Fixed  scalar      = FT_FIXED_ONE;
+      FT_Fixed  scalar      = 0x10000L;
       FT_UInt   regionIndex = varData->regionIndices[master];
 
       GX_AxisCoords  axis = itemStore->varRegionList[regionIndex].axisList;
@@ -893,59 +1045,70 @@
       /* inner loop steps through axes in this region */
       for ( j = 0; j < itemStore->axisCount; j++, axis++ )
       {
-        FT_Fixed  axisScalar;
-
-
         /* compute the scalar contribution of this axis; */
         /* ignore invalid ranges                         */
         if ( axis->startCoord > axis->peakCoord ||
              axis->peakCoord > axis->endCoord   )
-          axisScalar = FT_FIXED_ONE;
+          continue;
 
         else if ( axis->startCoord < 0 &&
                   axis->endCoord > 0   &&
                   axis->peakCoord != 0 )
-          axisScalar = FT_FIXED_ONE;
+          continue;
 
         /* peak of 0 means ignore this axis */
         else if ( axis->peakCoord == 0 )
-          axisScalar = FT_FIXED_ONE;
+          continue;
+
+        else if ( face->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   )
-          axisScalar = 0;
-
-        /* calculate a proportional factor */
-        else
+        else if ( face->blend->normalizedcoords[j] <= axis->startCoord ||
+                  face->blend->normalizedcoords[j] >= axis->endCoord   )
         {
-          if ( face->blend->normalizedcoords[j] == axis->peakCoord )
-            axisScalar = FT_FIXED_ONE;
-          else if ( face->blend->normalizedcoords[j] < axis->peakCoord )
-            axisScalar =
-              FT_DivFix( face->blend->normalizedcoords[j] - axis->startCoord,
-                         axis->peakCoord - axis->startCoord );
-          else
-            axisScalar =
-              FT_DivFix( axis->endCoord - face->blend->normalizedcoords[j],
-                         axis->endCoord - axis->peakCoord );
+          scalar = 0;
+          break;
         }
 
-        /* take product of all the axis scalars */
-        scalar = FT_MulFix( scalar, axisScalar );
+        /* cumulative product of all the axis scalars */
+        else if ( face->blend->normalizedcoords[j] < axis->peakCoord )
+          scalar =
+            FT_MulDiv( scalar,
+                       face->blend->normalizedcoords[j] - axis->startCoord,
+                       axis->peakCoord - axis->startCoord );
+        else
+          scalar =
+            FT_MulDiv( scalar,
+                       axis->endCoord - face->blend->normalizedcoords[j],
+                       axis->endCoord - axis->peakCoord );
 
       } /* per-axis loop */
 
-      /* get the scaled delta for this region */
-      delta       = FT_intToFixed( deltaSet[master] );
-      scaledDelta = FT_MulFix( scalar, delta );
-
-      /* accumulate the adjustments from each region */
-      netAdjustment = netAdjustment + scaledDelta;
+      scalars[master] = scalar;
 
     } /* per-region loop */
 
-    return FT_fixedToInt( netAdjustment );
+
+    /* Compute the scaled delta for this region.
+     *
+     * From: https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables:
+     *
+     *   `Fixed` is a 32-bit (16.16) type and, in the general case, requires
+     *   32-bit deltas.  As described above, the `DeltaSet` record can
+     *   accommodate deltas that are, logically, either 16-bit or 32-bit.
+     *   When scaled deltas are applied to `Fixed` values, the `Fixed` value
+     *   is treated like a 32-bit integer.
+     *
+     * `FT_MulAddFix` internally uses 64-bit precision; it thus can handle
+     * deltas ranging from small 8-bit to large 32-bit values that are
+     * applied to 16.16 `FT_Fixed` / OpenType `Fixed` values.
+     */
+    returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
+
+    FT_FREE( scalars );
+
+    return returnValue;
   }
 
 
@@ -1038,35 +1201,27 @@
     }
     else
     {
-      GX_ItemVarData  varData;
-
-
       /* no widthMap data */
       outerIndex = 0;
       innerIndex = gindex;
-
-      varData = &table->itemStore.varData[outerIndex];
-      if ( gindex >= varData->itemCount )
-      {
-        FT_TRACE2(( "gindex %d out of range\n", gindex ));
-        error = FT_THROW( Invalid_Argument );
-        goto Exit;
-      }
     }
 
-    delta = ft_var_get_item_delta( face,
+    delta = tt_var_get_item_delta( face,
                                    &table->itemStore,
                                    outerIndex,
                                    innerIndex );
 
-    FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n",
-                vertical ? "vertical height" : "horizontal width",
-                *avalue,
-                delta,
-                delta == 1 ? "" : "s",
-                vertical ? "VVAR" : "HVAR" ));
+    if ( delta )
+    {
+      FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n",
+                  vertical ? "vertical height" : "horizontal width",
+                  *avalue,
+                  delta,
+                  delta == 1 ? "" : "s",
+                  vertical ? "VVAR" : "HVAR" ));
 
-    *avalue += delta;
+      *avalue = ADD_INT( *avalue, delta );
+    }
 
   Exit:
     return error;
@@ -1233,7 +1388,7 @@
 
     records_offset = FT_STREAM_POS();
 
-    error = ft_var_load_item_variation_store(
+    error = tt_var_load_item_variation_store(
               face,
               table_offset + store_offset,
               &blend->mvar_table->itemStore );
@@ -1249,7 +1404,7 @@
       return;
 
     value     = blend->mvar_table->values;
-    limit     = value + blend->mvar_table->valueCount;
+    limit     = FT_OFFSET( value, blend->mvar_table->valueCount );
     itemStore = &blend->mvar_table->itemStore;
 
     for ( ; value < limit; value++ )
@@ -1258,6 +1413,13 @@
       value->outerIndex = FT_GET_USHORT();
       value->innerIndex = FT_GET_USHORT();
 
+      /* new in OpenType 1.8.4 */
+      if ( value->outerIndex == 0xFFFFU && value->innerIndex == 0xFFFFU )
+      {
+        /* no variation data for this item */
+        continue;
+      }
+
       if ( value->outerIndex >= itemStore->dataCount                  ||
            value->innerIndex >= itemStore->varData[value->outerIndex]
                                                   .itemCount          )
@@ -1275,7 +1437,7 @@
     FT_TRACE2(( "loaded\n" ));
 
     value = blend->mvar_table->values;
-    limit = value + blend->mvar_table->valueCount;
+    limit = FT_OFFSET( value, blend->mvar_table->valueCount );
 
     /* save original values of the data MVAR is going to modify */
     for ( ; value < limit; value++ )
@@ -1331,13 +1493,16 @@
   {
     GX_Blend  blend = face->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 ) )
       return;
 
     value = blend->mvar_table->values;
-    limit = value + blend->mvar_table->valueCount;
+    limit = FT_OFFSET( value, blend->mvar_table->valueCount );
 
     for ( ; value < limit; value++ )
     {
@@ -1345,12 +1510,12 @@
       FT_Int     delta;
 
 
-      delta = ft_var_get_item_delta( face,
+      delta = tt_var_get_item_delta( face,
                                      &blend->mvar_table->itemStore,
                                      value->outerIndex,
                                      value->innerIndex );
 
-      if ( p )
+      if ( p && delta )
       {
         FT_TRACE5(( "value %c%c%c%c (%d unit%s) adjusted by %d unit%s (MVAR)\n",
                     (FT_Char)( value->tag >> 24 ),
@@ -1365,6 +1530,14 @@
         /* since we handle both signed and unsigned values as FT_Short, */
         /* ensure proper overflow arithmetic                            */
         *p = (FT_Short)( value->unmodified + (FT_Short)delta );
+
+        /* Treat hasc, hdsc and hlgp specially, see below. */
+        if ( value->tag == MVAR_TAG_HASC )
+          mvar_hasc_delta = (FT_Short)delta;
+        else if ( value->tag == MVAR_TAG_HDSC )
+          mvar_hdsc_delta = (FT_Short)delta;
+        else if ( value->tag == MVAR_TAG_HLGP )
+          mvar_hlgp_delta = (FT_Short)delta;
       }
     }
 
@@ -1372,25 +1545,40 @@
     {
       FT_Face  root = &face->root;
 
+      /*
+       * Apply the deltas of hasc, hdsc and hlgp to the FT_Face's ascender,
+       * descender and height attributes, no matter how they were originally
+       * computed.
+       *
+       * (Code that ignores those and accesses the font's metrics values
+       * directly is already served by the delta application code above.)
+       *
+       * The MVAR table supports variations for both typo and win metrics.
+       * According to Behdad Esfahbod, the thinking of the working group was
+       * that no one uses win metrics anymore for setting line metrics (the
+       * specification even calls these metrics "horizontal clipping
+       * ascent/descent", probably for their role on the Windows platform in
+       * computing clipping boxes), and new fonts should use typo metrics, so
+       * typo deltas should be applied to whatever sfnt_load_face decided the
+       * line metrics should be.
+       *
+       * Before, the following led to different line metrics between default
+       * outline and instances, visible when e.g. the default outlines were
+       * used as the regular face and instances for everything else:
+       *
+       * 1. sfnt_load_face applied the hhea metrics by default.
+       * 2. This code later applied the typo metrics by default, regardless of
+       *    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;
 
-      if ( face->os2.version != 0xFFFFU )
-      {
-        if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
-        {
-          root->ascender  = face->os2.sTypoAscender;
-          root->descender = face->os2.sTypoDescender;
 
-          root->height = root->ascender - root->descender +
-                         face->os2.sTypoLineGap;
-        }
-        else
-        {
-          root->ascender  =  (FT_Short)face->os2.usWinAscent;
-          root->descender = -(FT_Short)face->os2.usWinDescent;
-
-          root->height = root->ascender - root->descender;
-        }
-      }
+      root->ascender  = root->ascender + mvar_hasc_delta;
+      root->descender = root->descender + mvar_hdsc_delta;
+      root->height    = root->ascender - root->descender +
+                        current_line_gap + mvar_hlgp_delta;
 
       root->underline_position  = face->postscript.underlinePosition -
                                   face->postscript.underlineThickness / 2;
@@ -1445,6 +1633,7 @@
     FT_ULong      table_len;
     FT_ULong      gvar_start;
     FT_ULong      offsetToData;
+    FT_ULong      offsets_len;
     GX_GVar_Head  gvar_head;
 
     static const FT_Frame_Field  gvar_fields[] =
@@ -1489,8 +1678,9 @@
 
     if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
     {
-      FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n"
-                  "                  table are different\n" ));
+      FT_TRACE1(( "ft_var_load_gvar:"
+                  " number of axes in `gvar' and `cvar'\n" ));
+      FT_TRACE1(( "                  table are different\n" ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
@@ -1505,9 +1695,13 @@
       goto Exit;
     }
 
-    /* rough sanity check: offsets can be either 2 or 4 bytes */
-    if ( (FT_ULong)gvar_head.glyphCount *
-           ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len )
+    /* offsets can be either 2 or 4 bytes                  */
+    /* (one more offset than glyphs, to mark size of last) */
+    offsets_len = ( gvar_head.glyphCount + 1 ) *
+                  ( ( gvar_head.flags & 1 ) ? 4L : 2L );
+
+    /* rough sanity check */
+    if (offsets_len > table_len )
     {
       FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" ));
       error = FT_THROW( Invalid_Table );
@@ -1516,66 +1710,116 @@
 
     FT_TRACE2(( "loaded\n" ));
 
-    blend->gvar_size   = table_len;
-    blend->tuplecount  = gvar_head.globalCoordCount;
-    blend->gv_glyphcnt = gvar_head.glyphCount;
-    offsetToData       = gvar_start + gvar_head.offsetToData;
+    blend->gvar_size = table_len;
+    offsetToData     = gvar_start + gvar_head.offsetToData;
 
     FT_TRACE5(( "gvar: there %s %d shared coordinate%s:\n",
-                blend->tuplecount == 1 ? "is" : "are",
-                blend->tuplecount,
-                blend->tuplecount == 1 ? "" : "s" ));
+                gvar_head.globalCoordCount == 1 ? "is" : "are",
+                gvar_head.globalCoordCount,
+                gvar_head.globalCoordCount == 1 ? "" : "s" ));
 
-    if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
+    if ( FT_FRAME_ENTER( offsets_len ) )
       goto Exit;
 
+    /* offsets (one more offset than glyphs, to mark size of last) */
+    if ( FT_QNEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) )
+      goto Fail2;
+
     if ( gvar_head.flags & 1 )
     {
-      /* long offsets (one more offset than glyphs, to mark size of last) */
-      if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
-        goto Exit;
+      FT_ULong  limit      = gvar_start + table_len;
+      FT_ULong  max_offset = 0;
 
-      for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+
+      for ( i = 0; i <= gvar_head.glyphCount; i++ )
+      {
         blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
 
-      FT_FRAME_EXIT();
+        if ( max_offset <= blend->glyphoffsets[i] )
+          max_offset = blend->glyphoffsets[i];
+        else
+        {
+          FT_TRACE2(( "ft_var_load_gvar:"
+                      " glyph variation data offset %d not monotonic\n",
+                      i ));
+          blend->glyphoffsets[i] = max_offset;
+        }
+
+        /* use `<', not `<=' */
+        if ( limit < blend->glyphoffsets[i] )
+        {
+          FT_TRACE2(( "ft_var_load_gvar:"
+                      " glyph variation data offset %d out of range\n",
+                      i ));
+          blend->glyphoffsets[i] = limit;
+        }
+      }
     }
     else
     {
-      /* short offsets (one more offset than glyphs, to mark size of last) */
-      if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
-        goto Exit;
+      FT_ULong  limit      = gvar_start + table_len;
+      FT_ULong  max_offset = 0;
 
-      for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+
+      for ( i = 0; i <= gvar_head.glyphCount; i++ )
+      {
         blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
-                                               /* XXX: Undocumented: `*2'! */
 
-      FT_FRAME_EXIT();
+        if ( max_offset <= blend->glyphoffsets[i] )
+          max_offset = blend->glyphoffsets[i];
+        else
+        {
+          FT_TRACE2(( "ft_var_load_gvar:"
+                      " glyph variation data offset %d not monotonic\n",
+                      i ));
+          blend->glyphoffsets[i] = max_offset;
+        }
+
+        /* use `<', not `<=' */
+        if ( limit < blend->glyphoffsets[i] )
+        {
+          FT_TRACE2(( "ft_var_load_gvar:"
+                      " glyph variation data offset %d out of range\n",
+                      i ));
+          blend->glyphoffsets[i] = limit;
+        }
+      }
     }
 
-    if ( blend->tuplecount != 0 )
+    blend->gv_glyphcnt = gvar_head.glyphCount;
+
+    FT_FRAME_EXIT();
+
+    if ( gvar_head.globalCoordCount != 0 )
     {
-      if ( FT_NEW_ARRAY( blend->tuplecoords,
-                         gvar_head.axisCount * blend->tuplecount ) )
-        goto Exit;
+      if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) ||
+           FT_FRAME_ENTER( gvar_head.globalCoordCount *
+                           gvar_head.axisCount * 2L )             )
+      {
+        FT_TRACE2(( "ft_var_load_gvar:"
+                    " glyph variation shared tuples missing\n" ));
+        goto Fail;
+      }
 
-      if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )         ||
-           FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
-        goto Exit;
+      if ( FT_QNEW_ARRAY( blend->tuplecoords,
+                          gvar_head.axisCount * gvar_head.globalCoordCount ) )
+        goto Fail2;
 
-      for ( i = 0; i < blend->tuplecount; i++ )
+      for ( i = 0; i < gvar_head.globalCoordCount; i++ )
       {
         FT_TRACE5(( "  [ " ));
         for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
         {
           blend->tuplecoords[i * gvar_head.axisCount + j] =
-            FT_GET_SHORT() * 4;                 /* convert to FT_Fixed */
+            FT_fdot14ToFixed( FT_GET_SHORT() );
           FT_TRACE5(( "%.5f ",
-            blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
+            (double)blend->tuplecoords[i * gvar_head.axisCount + j] / 65536 ));
         }
         FT_TRACE5(( "]\n" ));
       }
 
+      blend->tuplecount = gvar_head.globalCoordCount;
+
       FT_TRACE5(( "\n" ));
 
       FT_FRAME_EXIT();
@@ -1583,6 +1827,14 @@
 
   Exit:
     return error;
+
+  Fail2:
+    FT_FRAME_EXIT();
+
+  Fail:
+    FT_FREE( blend->glyphoffsets );
+    blend->gv_glyphcnt = 0;
+    goto Exit;
   }
 
 
@@ -1631,13 +1883,8 @@
 
     for ( i = 0; i < blend->num_axis; i++ )
     {
-      FT_TRACE6(( "    axis coordinate %d (%.5f):\n",
-                  i, blend->normalizedcoords[i] / 65536.0 ));
-      if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
-        FT_TRACE6(( "      intermediate coordinates %d (%.5f, %.5f):\n",
-                    i,
-                    im_start_coords[i] / 65536.0,
-                    im_end_coords[i] / 65536.0 ));
+      FT_TRACE6(( "    axis %d coordinate %.5f:\n",
+                  i, (double)blend->normalizedcoords[i] / 65536 ));
 
       /* It's not clear why (for intermediate tuples) we don't need     */
       /* to check against start/end -- the documentation says we don't. */
@@ -1646,7 +1893,7 @@
 
       if ( tuple_coords[i] == 0 )
       {
-        FT_TRACE6(( "      tuple coordinate is zero, ignored\n", i ));
+        FT_TRACE6(( "      tuple coordinate is zero, ignore\n" ));
         continue;
       }
 
@@ -1659,8 +1906,8 @@
 
       if ( blend->normalizedcoords[i] == tuple_coords[i] )
       {
-        FT_TRACE6(( "      tuple coordinate value %.5f fits perfectly\n",
-                    tuple_coords[i] / 65536.0 ));
+        FT_TRACE6(( "      tuple coordinate %.5f fits perfectly\n",
+                    (double)tuple_coords[i] / 65536 ));
         /* `apply' does not change */
         continue;
       }
@@ -1672,14 +1919,14 @@
         if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) ||
              blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) )
         {
-          FT_TRACE6(( "      tuple coordinate value %.5f is exceeded, stop\n",
-                      tuple_coords[i] / 65536.0 ));
+          FT_TRACE6(( "      tuple coordinate %.5f is exceeded, stop\n",
+                      (double)tuple_coords[i] / 65536 ));
           apply = 0;
           break;
         }
 
-        FT_TRACE6(( "      tuple coordinate value %.5f fits\n",
-                    tuple_coords[i] / 65536.0 ));
+        FT_TRACE6(( "      tuple coordinate %.5f fits\n",
+                    (double)tuple_coords[i] / 65536 ));
         apply = FT_MulDiv( apply,
                            blend->normalizedcoords[i],
                            tuple_coords[i] );
@@ -1688,40 +1935,32 @@
       {
         /* intermediate tuple */
 
-        if ( blend->normalizedcoords[i] < im_start_coords[i] ||
-             blend->normalizedcoords[i] > im_end_coords[i]   )
+        if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
+             blend->normalizedcoords[i] >= im_end_coords[i]   )
         {
-          FT_TRACE6(( "      intermediate tuple range [%.5f;%.5f] is exceeded,"
+          FT_TRACE6(( "      intermediate tuple range ]%.5f;%.5f[ is exceeded,"
                       " stop\n",
-                      im_start_coords[i] / 65536.0,
-                      im_end_coords[i] / 65536.0 ));
+                      (double)im_start_coords[i] / 65536,
+                      (double)im_end_coords[i] / 65536 ));
           apply = 0;
           break;
         }
 
-        else if ( blend->normalizedcoords[i] < tuple_coords[i] )
-        {
-          FT_TRACE6(( "      intermediate tuple range [%.5f;%.5f] fits\n",
-                      im_start_coords[i] / 65536.0,
-                      im_end_coords[i] / 65536.0 ));
+        FT_TRACE6(( "      intermediate tuple range ]%.5f;%.5f[ fits\n",
+                    (double)im_start_coords[i] / 65536,
+                    (double)im_end_coords[i] / 65536 ));
+        if ( blend->normalizedcoords[i] < tuple_coords[i] )
           apply = FT_MulDiv( apply,
                              blend->normalizedcoords[i] - im_start_coords[i],
                              tuple_coords[i] - im_start_coords[i] );
-        }
-
         else
-        {
-          FT_TRACE6(( "      intermediate tuple range [%.5f;%.5f] fits\n",
-                      im_start_coords[i] / 65536.0,
-                      im_end_coords[i] / 65536.0 ));
           apply = FT_MulDiv( apply,
                              im_end_coords[i] - blend->normalizedcoords[i],
                              im_end_coords[i] - tuple_coords[i] );
-        }
       }
     }
 
-    FT_TRACE6(( "    apply factor is %.5f\n", apply / 65536.0 ));
+    FT_TRACE6(( "    apply factor is %.5f\n", (double)apply / 65536 ));
 
     return apply;
   }
@@ -1735,12 +1974,18 @@
                         FT_Fixed*  coords,
                         FT_Fixed*  normalized )
   {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = face->root.memory;
+    FT_UInt    i, j;
+
     GX_Blend        blend;
     FT_MM_Var*      mmvar;
-    FT_UInt         i, j;
     FT_Var_Axis*    a;
     GX_AVarSegment  av;
 
+    FT_Fixed*  new_normalized = NULL;
+    FT_Fixed*  old_normalized;
+
 
     blend = face->blend;
     mmvar = blend->mmvar;
@@ -1763,28 +2008,25 @@
       FT_Fixed  coord = coords[i];
 
 
-      FT_TRACE5(( "    %d: %.5f\n", i, coord / 65536.0 ));
+      FT_TRACE5(( "    %d: %.5f\n", i, (double)coord / 65536 ));
       if ( coord > a->maximum || coord < a->minimum )
       {
-        FT_TRACE1((
-          "ft_var_to_normalized: design coordinate %.5f\n"
-          "                      is out of range [%.5f;%.5f]; clamping\n",
-          coord / 65536.0,
-          a->minimum / 65536.0,
-          a->maximum / 65536.0 ));
-
-        if ( coord > a->maximum )
-          coord = a->maximum;
-        else
-          coord = a->minimum;
+        FT_TRACE1(( "ft_var_to_normalized: design coordinate %.5f\n",
+                    (double)coord / 65536 ));
+        FT_TRACE1(( "                      is out of range [%.5f;%.5f];"
+                    " clamping\n",
+                    (double)a->minimum / 65536,
+                    (double)a->maximum / 65536 ));
       }
 
-      if ( coord < a->def )
-        normalized[i] = -FT_DivFix( SUB_LONG( coord, a->def ),
-                                    SUB_LONG( a->minimum, a->def ) );
-      else if ( coord > a->def )
-        normalized[i] = FT_DivFix( SUB_LONG( coord, a->def ),
+      if ( coord > a->def )
+        normalized[i] = coord >= a->maximum ?  0x10000L :
+                        FT_DivFix( SUB_LONG( coord, a->def ),
                                    SUB_LONG( a->maximum, a->def ) );
+      else if ( coord < a->def )
+        normalized[i] = coord <= a->minimum ? -0x10000L :
+                        FT_DivFix( SUB_LONG( coord, a->def ),
+                                   SUB_LONG( a->def, a->minimum ) );
       else
         normalized[i] = 0;
     }
@@ -1794,31 +2036,92 @@
     for ( ; i < mmvar->num_axis; i++ )
       normalized[i] = 0;
 
-    if ( blend->avar_segment )
+    if ( blend->avar_table )
     {
+      GX_AVarTable  table = blend->avar_table;
+
+
       FT_TRACE5(( "normalized design coordinates"
                   " before applying `avar' data:\n" ));
 
-      av = blend->avar_segment;
-      for ( i = 0; i < mmvar->num_axis; i++, av++ )
+      if ( table->avar_segment )
       {
-        for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
-        {
-          if ( normalized[i] < av->correspondence[j].fromCoord )
-          {
-            FT_TRACE5(( "  %.5f\n", normalized[i] / 65536.0 ));
+        av = table->avar_segment;
 
-            normalized[i] =
-              FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
-                         av->correspondence[j].toCoord -
-                           av->correspondence[j - 1].toCoord,
-                         av->correspondence[j].fromCoord -
-                           av->correspondence[j - 1].fromCoord ) +
-              av->correspondence[j - 1].toCoord;
-            break;
+        for ( i = 0; i < mmvar->num_axis; i++, av++ )
+        {
+          for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
+          {
+            if ( normalized[i] < av->correspondence[j].fromCoord )
+            {
+              FT_TRACE5(( "  %.5f\n", (double)normalized[i] / 65536 ));
+
+              normalized[i] =
+                FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
+                           av->correspondence[j].toCoord -
+                             av->correspondence[j - 1].toCoord,
+                           av->correspondence[j].fromCoord -
+                             av->correspondence[j - 1].fromCoord ) +
+                av->correspondence[j - 1].toCoord;
+              break;
+            }
           }
         }
       }
+
+      if ( table->itemStore.varData )
+      {
+        if ( FT_QNEW_ARRAY( new_normalized, mmvar->num_axis ) )
+          return;
+
+        /* Install our half-normalized coordinates for the next */
+        /* Item Variation Store to work with.                   */
+        old_normalized                = face->blend->normalizedcoords;
+        face->blend->normalizedcoords = normalized;
+
+        for ( i = 0; i < mmvar->num_axis; i++ )
+        {
+          FT_Fixed  v          = normalized[i];
+          FT_UInt   innerIndex = i;
+          FT_UInt   outerIndex = 0;
+          FT_Int    delta;
+
+
+          if ( table->axisMap.innerIndex )
+          {
+            FT_UInt  idx = i;
+
+
+            if ( idx >= table->axisMap.mapCount )
+              idx = table->axisMap.mapCount - 1;
+
+            outerIndex = table->axisMap.outerIndex[idx];
+            innerIndex = table->axisMap.innerIndex[idx];
+          }
+
+          delta = tt_var_get_item_delta( face,
+                                         &table->itemStore,
+                                         outerIndex,
+                                         innerIndex );
+
+	  v += delta << 2;
+
+	  /* Clamp value range. */
+	  v = v >=  0x10000L ?  0x10000 : v;
+	  v = v <= -0x10000L ? -0x10000 : v;
+
+          new_normalized[i] = v;
+        }
+
+        for ( i = 0; i < mmvar->num_axis; i++ )
+        {
+          normalized[i] = new_normalized[i];
+        }
+
+        face->blend->normalizedcoords = old_normalized;
+
+        FT_FREE( new_normalized );
+      }
     }
   }
 
@@ -1855,9 +2158,9 @@
     for ( ; i < num_coords; i++ )
       design[i] = 0;
 
-    if ( blend->avar_segment )
+    if ( blend->avar_table && blend->avar_table->avar_segment )
     {
-      GX_AVarSegment  av = blend->avar_segment;
+      GX_AVarSegment  av = blend->avar_table->avar_segment;
 
 
       FT_TRACE5(( "design coordinates"
@@ -1877,7 +2180,7 @@
                            av->correspondence[j - 1].toCoord ) +
               av->correspondence[j - 1].fromCoord;
 
-            FT_TRACE5(( "  %.5f\n", design[i] / 65536.0 ));
+            FT_TRACE5(( "  %.5f\n", (double)design[i] / 65536 ));
             break;
           }
         }
@@ -1974,7 +2277,7 @@
     FT_Var_Axis*         a;
     FT_Fixed*            c;
     FT_Var_Named_Style*  ns;
-    GX_FVar_Head         fvar_head;
+    GX_FVar_Head         fvar_head  = { 0, 0, 0, 0, 0, 0 };
     FT_Bool              usePsName  = 0;
     FT_UInt              num_instances;
     FT_UInt              num_axes;
@@ -2022,6 +2325,11 @@
       FT_FRAME_END
     };
 
+    /* `num_instances` holds the number of all named instances including  */
+    /* 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;
 
     /* read the font data and set up the internal representation */
     /* if not already done                                       */
@@ -2032,20 +2340,6 @@
     {
       FT_TRACE2(( "FVAR " ));
 
-      /* both `fvar' and `gvar' must be present */
-      if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar,
-                                           stream, &table_len ) ) )
-      {
-        /* CFF2 is an alternate to gvar here */
-        if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2,
-                                             stream, &table_len ) ) )
-        {
-          FT_TRACE1(( "\n"
-                      "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" ));
-          goto Exit;
-        }
-      }
-
       if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar,
                                            stream, &table_len ) ) )
       {
@@ -2060,6 +2354,17 @@
       if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) )
         goto Exit;
 
+      /* If `num_instances` is larger, synthetization of the default  */
+      /* instance is required.  If `num_instances` is smaller,        */
+      /* however, the value has been reset to 0 in `sfnt_init_face`   */
+      /* (in `sfobjs.c`); in this case we have underallocated `mmvar` */
+      /* structs.                                                     */
+      if ( num_instances < fvar_head.instanceCount )
+      {
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
       usePsName = FT_BOOL( fvar_head.instanceSize ==
                            6 + 4 * fvar_head.axisCount );
 
@@ -2078,17 +2383,12 @@
     else
       num_axes = face->blend->num_axis;
 
-    /* `num_instances' holds the number of all named instances, */
-    /* including the default instance which might be missing    */
-    /* in fvar's table of named instances                       */
-    num_instances = (FT_UInt)face->root.style_flags >> 16;
-
     /* prepare storage area for MM data; this cannot overflow   */
     /* 32-bit arithmetic because of the size limits used in the */
     /* `fvar' table validity check in `sfnt_init_face'          */
 
     /* the various `*_size' variables, which we also use as     */
-    /* offsets into the `mmlen' array, must be multiples of the */
+    /* offsets into the `mmvar' array, must be multiples of the */
     /* pointer size (except the last one); without such an      */
     /* alignment there might be runtime errors due to           */
     /* misaligned addresses                                     */
@@ -2210,9 +2510,9 @@
                     "  %10.5f  %10.5f  %10.5f  0x%04X%s\n",
                     i,
                     a->name,
-                    a->minimum / 65536.0,
-                    a->def / 65536.0,
-                    a->maximum / 65536.0,
+                    (double)a->minimum / 65536,
+                    (double)a->def / 65536,
+                    (double)a->maximum / 65536,
                     *axis_flags,
                     invalid ? " (invalid, disabled)" : "" ));
 #endif
@@ -2413,6 +2713,8 @@
           a->name = (char*)"OpticalSize";
         else if ( a->tag == TTAG_slnt )
           a->name = (char*)"Slant";
+        else if ( a->tag == TTAG_ital )
+          a->name = (char*)"Italic";
 
         next_name += 5;
         a++;
@@ -2469,17 +2771,17 @@
       num_coords = mmvar->num_axis;
     }
 
-    FT_TRACE5(( "TT_Set_MM_Blend:\n"
-                "  normalized design coordinates:\n" ));
+    FT_TRACE5(( "TT_Set_MM_Blend:\n" ));
+    FT_TRACE5(( "  normalized design coordinates:\n" ));
 
     for ( i = 0; i < num_coords; i++ )
     {
-      FT_TRACE5(( "    %.5f\n", coords[i] / 65536.0 ));
+      FT_TRACE5(( "    %.5f\n", (double)coords[i] / 65536 ));
       if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
       {
-        FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n"
-                    "                 is out of range [-1;1]\n",
-                    coords[i] / 65536.0 ));
+        FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n",
+                    (double)coords[i] / 65536 ));
+        FT_TRACE1(( "                 is out of range [-1;1]\n" ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
@@ -2488,8 +2790,16 @@
     FT_TRACE5(( "\n" ));
 
     if ( !face->is_cff2 && !blend->glyphoffsets )
-      if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) )
+    {
+      /* While a missing 'gvar' table is acceptable, for example for */
+      /* fonts that only vary metrics information or 'COLR' v1       */
+      /* `PaintVar*` tables, an incorrect SFNT table offset or size  */
+      /* for 'gvar', or an inconsistent 'gvar' table is not.         */
+      error = ft_var_load_gvar( face );
+      if ( error != FT_Err_Table_Missing && error != FT_Err_Ok )
         goto Exit;
+      error = FT_Err_Ok;
+    }
 
     if ( !blend->coords )
     {
@@ -2577,9 +2887,10 @@
     }
 
     blend->num_axis = mmvar->num_axis;
-    FT_MEM_COPY( blend->normalizedcoords,
-                 coords,
-                 num_coords * sizeof ( FT_Fixed ) );
+    if ( coords )
+      FT_MEM_COPY( blend->normalizedcoords,
+                   coords,
+                   num_coords * sizeof ( FT_Fixed ) );
 
     if ( set_design_coords )
       ft_var_to_design( face,
@@ -2597,7 +2908,6 @@
         /* The cvt table has been loaded already; every time we change the */
         /* blend we may need to reload and remodify the cvt table.         */
         FT_FREE( face->cvt );
-        face->cvt = NULL;
 
         error = tt_face_load_cvt( face, face->root.stream );
         break;
@@ -2616,7 +2926,6 @@
 
     /* enforce recomputation of the PostScript name; */
     FT_FREE( face->postscript_name );
-    face->postscript_name = NULL;
 
   Exit:
     return error;
@@ -2877,8 +3186,8 @@
     if ( !face->blend->avar_loaded )
       ft_var_load_avar( face );
 
-    FT_TRACE5(( "TT_Set_Var_Design:\n"
-                "  normalized design coordinates:\n" ));
+    FT_TRACE5(( "TT_Set_Var_Design:\n" ));
+    FT_TRACE5(( "  normalized design coordinates:\n" ));
     ft_var_to_normalized( face, num_coords, blend->coords, normalized );
 
     error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 );
@@ -2998,7 +3307,7 @@
   TT_Set_Named_Instance( TT_Face  face,
                          FT_UInt  instance_index )
   {
-    FT_Error    error = FT_ERR( Invalid_Argument );
+    FT_Error    error;
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
 
@@ -3018,9 +3327,12 @@
 
     /* `instance_index' starts with value 1, thus `>' */
     if ( instance_index > num_instances )
+    {
+      error = FT_ERR( Invalid_Argument );
       goto Exit;
+    }
 
-    if ( instance_index > 0 && mmvar->namedstyle )
+    if ( instance_index > 0 )
     {
       FT_Memory     memory = face->root.memory;
       SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
@@ -3046,7 +3358,12 @@
                                  mmvar->num_axis,
                                  named_style->coords );
       if ( error )
+      {
+        /* internal error code -1 means `no change' */
+        if ( error == -1 )
+          error = FT_Err_Ok;
         goto Exit;
+      }
     }
     else
       error = TT_Set_Var_Design( face, 0, NULL );
@@ -3069,6 +3386,26 @@
   /*************************************************************************/
 
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
+  static FT_Error
+  tt_cvt_ready_iterator( FT_ListNode  node,
+                         void*        user )
+  {
+    TT_Size  size = (TT_Size)node->data;
+
+    FT_UNUSED( user );
+
+
+    size->cvt_ready = -1;
+
+    return FT_Err_Ok;
+  }
+
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
+
+
   /**************************************************************************
    *
    * @Function:
@@ -3096,9 +3433,13 @@
   tt_face_vary_cvt( TT_Face    face,
                     FT_Stream  stream )
   {
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
     FT_Error   error;
     FT_Memory  memory = stream->memory;
 
+    FT_Face  root = &face->root;
+
     FT_ULong  table_start;
     FT_ULong  table_len;
 
@@ -3129,16 +3470,16 @@
 
     if ( !blend )
     {
-      FT_TRACE2(( "\n"
-                  "tt_face_vary_cvt: no blend specified\n" ));
+      FT_TRACE2(( "\n" ));
+      FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
       error = FT_Err_Ok;
       goto Exit;
     }
 
     if ( !face->cvt )
     {
-      FT_TRACE2(( "\n"
-                  "tt_face_vary_cvt: no `cvt ' table\n" ));
+      FT_TRACE2(( "\n" ));
+      FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
       error = FT_Err_Ok;
       goto Exit;
     }
@@ -3205,14 +3546,14 @@
     }
 
     FT_TRACE5(( "cvar: there %s %d tuple%s:\n",
-                ( tupleCount & 0xFFF ) == 1 ? "is" : "are",
-                tupleCount & 0xFFF,
-                ( tupleCount & 0xFFF ) == 1 ? "" : "s" ));
+                ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "is" : "are",
+                tupleCount & GX_TC_TUPLE_COUNT_MASK,
+                ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" ));
 
     if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) )
       goto FExit;
 
-    for ( i = 0; i < ( tupleCount & 0xFFF ); i++ )
+    for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
     {
       FT_UInt   tupleDataSize;
       FT_UInt   tupleIndex;
@@ -3227,8 +3568,7 @@
       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          tuple_coords[j] = FT_GET_SHORT() * 4;  /* convert from        */
-                                                 /* short frac to fixed */
+          tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
       {
@@ -3236,20 +3576,32 @@
                     " invalid tuple index\n" ));
 
         error = FT_THROW( Invalid_Table );
-        goto Exit;
+        goto FExit;
       }
       else
+      {
+        if ( !blend->tuplecoords )
+        {
+          FT_TRACE2(( "tt_face_vary_cvt:"
+                      " no valid tuple coordinates available\n" ));
+
+          error = FT_THROW( Invalid_Table );
+          goto FExit;
+        }
+
         FT_MEM_COPY(
           tuple_coords,
-          &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis],
+          blend->tuplecoords +
+            ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
           blend->num_axis * sizeof ( FT_Fixed ) );
+      }
 
       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          im_start_coords[j] = FT_GET_SHORT() * 4;
+          im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
         for ( j = 0; j < blend->num_axis; j++ )
-          im_end_coords[j] = FT_GET_SHORT() * 4;
+          im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
 
       apply = ft_var_apply_tuple( blend,
@@ -3277,6 +3629,7 @@
       }
       else
       {
+        localpoints = NULL;
         points      = sharedpoints;
         point_count = spoint_count;
       }
@@ -3286,9 +3639,7 @@
                                         point_count == 0 ? face->cvt_size
                                                          : point_count );
 
-      if ( !points                                                        ||
-           !deltas                                                        ||
-           ( localpoints == ALL_POINTS && point_count != face->cvt_size ) )
+      if ( !points || !deltas )
         ; /* failure, ignore it */
 
       else if ( localpoints == ALL_POINTS )
@@ -3314,10 +3665,10 @@
           {
             FT_TRACE7(( "      %d: %f -> %f\n",
                         j,
-                        ( FT_intToFixed( face->cvt[j] ) +
-                          old_cvt_delta ) / 65536.0,
-                        ( FT_intToFixed( face->cvt[j] ) +
-                          cvt_deltas[j] ) / 65536.0 ));
+                        (double)( FT_fdot6ToFixed( face->cvt[j] ) +
+                                    old_cvt_delta ) / 65536,
+                        (double)( FT_fdot6ToFixed( face->cvt[j] ) +
+                                    cvt_deltas[j] ) / 65536 ));
             count++;
           }
 #endif
@@ -3356,10 +3707,10 @@
           {
             FT_TRACE7(( "      %d: %f -> %f\n",
                         pindex,
-                        ( FT_intToFixed( face->cvt[pindex] ) +
-                          old_cvt_delta ) / 65536.0,
-                        ( FT_intToFixed( face->cvt[pindex] ) +
-                          cvt_deltas[pindex] ) / 65536.0 ));
+                        (double)( FT_fdot6ToFixed( face->cvt[pindex] ) +
+                                    old_cvt_delta ) / 65536,
+                        (double)( FT_fdot6ToFixed( face->cvt[pindex] ) +
+                                    cvt_deltas[pindex] ) / 65536 ));
             count++;
           }
 #endif
@@ -3383,7 +3734,7 @@
     FT_TRACE5(( "\n" ));
 
     for ( i = 0; i < face->cvt_size; i++ )
-      face->cvt[i] += FT_fixedToInt( cvt_deltas[i] );
+      face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] );
 
   FExit:
     FT_FRAME_EXIT();
@@ -3396,7 +3747,23 @@
     FT_FREE( im_end_coords );
     FT_FREE( cvt_deltas );
 
+    /* iterate over all FT_Size objects and set `cvt_ready' to -1 */
+    /* to trigger rescaling of all CVT values                     */
+    FT_List_Iterate( &root->sizes_list,
+                     tt_cvt_ready_iterator,
+                     NULL );
+
     return error;
+
+#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
+    FT_UNUSED( face );
+    FT_UNUSED( stream );
+
+    return FT_Err_Ok;
+
+#endif /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
   }
 
 
@@ -3440,9 +3807,8 @@
   /* between `p1' and `p2', using `ref1' and `ref2' as the reference */
   /* point indices.                                                  */
 
-  /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */
-  /* `Ins_IUP'                                                     */
-
+  /* modeled after `af_iup_interp', `_iup_worker_interpolate', and   */
+  /* `Ins_IUP' with spec differences in handling ill-defined cases.  */
   static void
   tt_delta_interpolate( int         p1,
                         int         p2,
@@ -3609,33 +3975,32 @@
    * @Description:
    *   Apply the appropriate deltas to the current glyph.
    *
-   * @Input:
-   *   face ::
-   *     A handle to the target face object.
-   *
-   *   glyph_index ::
-   *     The index of the glyph being modified.
-   *
-   *   n_points ::
-   *     The number of the points in the glyph, including
-   *     phantom points.
-   *
    * @InOut:
+   *   loader ::
+   *     A handle to the loader object.
+   *
    *   outline ::
-   *     The outline to change.
+   *     The outline to change, with appended phantom points.
+   *
+   * @Output:
+   *   unrounded ::
+   *     An array with `n_points' elements that is filled with unrounded
+   *     point coordinates (in 26.6 format).
    *
    * @Return:
    *   FreeType error code.  0 means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
-                              FT_UInt      glyph_index,
+  TT_Vary_Apply_Glyph_Deltas( TT_Loader    loader,
                               FT_Outline*  outline,
-                              FT_UInt      n_points )
+                              FT_Vector*   unrounded )
   {
     FT_Error   error;
-    FT_Stream  stream = face->root.stream;
-    FT_Memory  memory = stream->memory;
+    TT_Face    face        = loader->face;
+    FT_Stream  stream      = face->root.stream;
+    FT_Memory  memory      = stream->memory;
+    FT_UInt    glyph_index = loader->glyph_index;
+    FT_UInt    n_points    = (FT_UInt)outline->n_points + 4;
 
     FT_Vector*  points_org = NULL;  /* coordinates in 16.16 format */
     FT_Vector*  points_out = NULL;  /* coordinates in 16.16 format */
@@ -3645,6 +4010,7 @@
 
     FT_UInt   tupleCount;
     FT_ULong  offsetToData;
+    FT_ULong  dataSize;
 
     FT_ULong  here;
     FT_UInt   i, j;
@@ -3671,12 +4037,18 @@
     if ( !face->doblend || !blend )
       return FT_THROW( Invalid_Argument );
 
+    for ( i = 0; i < n_points; i++ )
+    {
+      unrounded[i].x = INT_TO_F26DOT6( outline->points[i].x );
+      unrounded[i].y = INT_TO_F26DOT6( outline->points[i].y );
+    }
+
     if ( glyph_index >= blend->gv_glyphcnt      ||
          blend->glyphoffsets[glyph_index] ==
            blend->glyphoffsets[glyph_index + 1] )
     {
       FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
-                  " no variation data for this glyph\n" ));
+                  " no variation data for glyph %d\n", glyph_index ));
       return FT_Err_Ok;
     }
 
@@ -3685,9 +4057,11 @@
          FT_NEW_ARRAY( has_delta, n_points )  )
       goto Fail1;
 
-    if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] )   ||
-         FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] -
-                           blend->glyphoffsets[glyph_index] ) )
+    dataSize = blend->glyphoffsets[glyph_index + 1] -
+                 blend->glyphoffsets[glyph_index];
+
+    if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
+         FT_FRAME_ENTER( dataSize )                         )
       goto Fail1;
 
     glyph_start = FT_Stream_FTell( stream );
@@ -3703,8 +4077,8 @@
     offsetToData = FT_GET_USHORT();
 
     /* rough sanity test */
-    if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 >
-           blend->gvar_size )
+    if ( offsetToData > dataSize                                ||
+         ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > dataSize )
     {
       FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
                   " invalid glyph variation array header\n" ));
@@ -3759,8 +4133,7 @@
       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          tuple_coords[j] = FT_GET_SHORT() * 4;   /* convert from        */
-                                                  /* short frac to fixed */
+          tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
       {
@@ -3773,15 +4146,16 @@
       else
         FT_MEM_COPY(
           tuple_coords,
-          &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis],
+          blend->tuplecoords +
+            ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
           blend->num_axis * sizeof ( FT_Fixed ) );
 
       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          im_start_coords[j] = FT_GET_SHORT() * 4;
+          im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
         for ( j = 0; j < blend->num_axis; j++ )
-          im_end_coords[j] = FT_GET_SHORT() * 4;
+          im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
 
       apply = ft_var_apply_tuple( blend,
@@ -3844,50 +4218,22 @@
           FT_Fixed  point_delta_y = FT_MulFix( deltas_y[j], apply );
 
 
-          if ( j < n_points - 4 )
-          {
-            point_deltas_x[j] = old_point_delta_x + point_delta_x;
-            point_deltas_y[j] = old_point_delta_y + point_delta_y;
-          }
-          else
-          {
-            /* To avoid double adjustment of advance width or height, */
-            /* adjust phantom points only if there is no HVAR or VVAR */
-            /* support, respectively.                                 */
-            if ( j == ( n_points - 4 )        &&
-                 !( face->variation_support &
-                    TT_FACE_FLAG_VAR_LSB    ) )
-              point_deltas_x[j] = old_point_delta_x + point_delta_x;
-
-            else if ( j == ( n_points - 3 )          &&
-                      !( face->variation_support   &
-                         TT_FACE_FLAG_VAR_HADVANCE ) )
-              point_deltas_x[j] = old_point_delta_x + point_delta_x;
-
-            else if ( j == ( n_points - 2 )        &&
-                      !( face->variation_support &
-                         TT_FACE_FLAG_VAR_TSB    ) )
-              point_deltas_y[j] = old_point_delta_y + point_delta_y;
-
-            else if ( j == ( n_points - 1 )          &&
-                      !( face->variation_support   &
-                         TT_FACE_FLAG_VAR_VADVANCE ) )
-              point_deltas_y[j] = old_point_delta_y + point_delta_y;
-          }
+          point_deltas_x[j] = old_point_delta_x + point_delta_x;
+          point_deltas_y[j] = old_point_delta_y + point_delta_y;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
           if ( point_delta_x || point_delta_y )
           {
             FT_TRACE7(( "      %d: (%f, %f) -> (%f, %f)\n",
                         j,
-                        ( FT_intToFixed( outline->points[j].x ) +
-                          old_point_delta_x ) / 65536.0,
-                        ( FT_intToFixed( outline->points[j].y ) +
-                          old_point_delta_y ) / 65536.0,
-                        ( FT_intToFixed( outline->points[j].x ) +
-                          point_deltas_x[j] ) / 65536.0,
-                        ( FT_intToFixed( outline->points[j].y ) +
-                          point_deltas_y[j] ) / 65536.0 ));
+                        (double)( FT_intToFixed( outline->points[j].x ) +
+                                    old_point_delta_x ) / 65536,
+                        (double)( FT_intToFixed( outline->points[j].y ) +
+                                    old_point_delta_y ) / 65536,
+                        (double)( FT_intToFixed( outline->points[j].x ) +
+                                    point_deltas_x[j] ) / 65536,
+                        (double)( FT_intToFixed( outline->points[j].y ) +
+                                    point_deltas_y[j] ) / 65536 ));
             count++;
           }
 #endif
@@ -3946,50 +4292,22 @@
           FT_Pos  point_delta_y = points_out[j].y - points_org[j].y;
 
 
-          if ( j < n_points - 4 )
-          {
-            point_deltas_x[j] = old_point_delta_x + point_delta_x;
-            point_deltas_y[j] = old_point_delta_y + point_delta_y;
-          }
-          else
-          {
-            /* To avoid double adjustment of advance width or height, */
-            /* adjust phantom points only if there is no HVAR or VVAR */
-            /* support, respectively.                                 */
-            if ( j == ( n_points - 4 )        &&
-                 !( face->variation_support &
-                    TT_FACE_FLAG_VAR_LSB    ) )
-              point_deltas_x[j] = old_point_delta_x + point_delta_x;
-
-            else if ( j == ( n_points - 3 )          &&
-                      !( face->variation_support   &
-                         TT_FACE_FLAG_VAR_HADVANCE ) )
-              point_deltas_x[j] = old_point_delta_x + point_delta_x;
-
-            else if ( j == ( n_points - 2 )        &&
-                      !( face->variation_support &
-                         TT_FACE_FLAG_VAR_TSB    ) )
-              point_deltas_y[j] = old_point_delta_y + point_delta_y;
-
-            else if ( j == ( n_points - 1 )          &&
-                      !( face->variation_support   &
-                         TT_FACE_FLAG_VAR_VADVANCE ) )
-              point_deltas_y[j] = old_point_delta_y + point_delta_y;
-          }
+          point_deltas_x[j] = old_point_delta_x + point_delta_x;
+          point_deltas_y[j] = old_point_delta_y + point_delta_y;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
           if ( point_delta_x || point_delta_y )
           {
             FT_TRACE7(( "      %d: (%f, %f) -> (%f, %f)\n",
                         j,
-                        ( FT_intToFixed( outline->points[j].x ) +
-                          old_point_delta_x ) / 65536.0,
-                        ( FT_intToFixed( outline->points[j].y ) +
-                          old_point_delta_y ) / 65536.0,
-                        ( FT_intToFixed( outline->points[j].x ) +
-                          point_deltas_x[j] ) / 65536.0,
-                        ( FT_intToFixed( outline->points[j].y ) +
-                          point_deltas_y[j] ) / 65536.0 ));
+                        (double)( FT_intToFixed( outline->points[j].x ) +
+                                    old_point_delta_x ) / 65536,
+                        (double)( FT_intToFixed( outline->points[j].y ) +
+                                    old_point_delta_y ) / 65536,
+                        (double)( FT_intToFixed( outline->points[j].x ) +
+                                    point_deltas_x[j] ) / 65536,
+                        (double)( FT_intToFixed( outline->points[j].y ) +
+                                    point_deltas_y[j] ) / 65536 ));
             count++;
           }
 #endif
@@ -4013,12 +4331,51 @@
 
     FT_TRACE5(( "\n" ));
 
+    /* To avoid double adjustment of advance width or height, */
+    /* do not move phantom points if there is HVAR or VVAR    */
+    /* support, respectively.                                 */
+    if ( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE )
+    {
+      point_deltas_x[n_points - 4] = 0;
+      point_deltas_y[n_points - 4] = 0;
+      point_deltas_x[n_points - 3] = 0;
+      point_deltas_y[n_points - 3] = 0;
+    }
+    if ( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE )
+    {
+      point_deltas_x[n_points - 2] = 0;
+      point_deltas_y[n_points - 2] = 0;
+      point_deltas_x[n_points - 1] = 0;
+      point_deltas_y[n_points - 1] = 0;
+    }
+
     for ( i = 0; i < n_points; i++ )
     {
+      unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] );
+      unrounded[i].y += FT_fixedToFdot6( point_deltas_y[i] );
+
       outline->points[i].x += FT_fixedToInt( point_deltas_x[i] );
       outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
     }
 
+    /* To avoid double adjustment of advance width or height, */
+    /* adjust phantom points only if there is no HVAR or VVAR */
+    /* support, respectively.                                 */
+    if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
+    {
+      loader->pp1      = outline->points[n_points - 4];
+      loader->pp2      = outline->points[n_points - 3];
+      loader->linear   = FT_PIX_ROUND( unrounded[n_points - 3].x -
+                                       unrounded[n_points - 4].x ) / 64;
+    }
+    if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+    {
+      loader->pp3      = outline->points[n_points - 2];
+      loader->pp4      = outline->points[n_points - 1];
+      loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].y -
+                                       unrounded[n_points - 2].y ) / 64;
+    }
+
   Fail3:
     FT_FREE( point_deltas_x );
     FT_FREE( point_deltas_y );
@@ -4083,8 +4440,8 @@
   }
 
 
-  static void
-  ft_var_done_item_variation_store( TT_Face          face,
+  FT_LOCAL_DEF( void )
+  tt_var_done_item_variation_store( TT_Face          face,
                                     GX_ItemVarStore  itemStore )
   {
     FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -4112,6 +4469,18 @@
   }
 
 
+  FT_LOCAL_DEF( void )
+  tt_var_done_delta_set_index_map( TT_Face            face,
+                                   GX_DeltaSetIdxMap  deltaSetIdxMap )
+  {
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+
+
+    FT_FREE( deltaSetIdxMap->innerIndex );
+    FT_FREE( deltaSetIdxMap->outerIndex );
+  }
+
+
   /**************************************************************************
    *
    * @Function:
@@ -4140,36 +4509,47 @@
       FT_FREE( blend->normalized_stylecoords );
       FT_FREE( blend->mmvar );
 
-      if ( blend->avar_segment )
+      if ( blend->avar_table )
       {
-        for ( i = 0; i < num_axes; i++ )
-          FT_FREE( blend->avar_segment[i].correspondence );
-        FT_FREE( blend->avar_segment );
+        if ( blend->avar_table->avar_segment )
+        {
+          for ( i = 0; i < num_axes; i++ )
+            FT_FREE( blend->avar_table->avar_segment[i].correspondence );
+          FT_FREE( blend->avar_table->avar_segment );
+        }
+
+        tt_var_done_item_variation_store( face,
+                                          &blend->avar_table->itemStore );
+
+        tt_var_done_delta_set_index_map( face,
+                                         &blend->avar_table->axisMap );
+
+        FT_FREE( blend->avar_table );
       }
 
       if ( blend->hvar_table )
       {
-        ft_var_done_item_variation_store( face,
+        tt_var_done_item_variation_store( face,
                                           &blend->hvar_table->itemStore );
 
-        FT_FREE( blend->hvar_table->widthMap.innerIndex );
-        FT_FREE( blend->hvar_table->widthMap.outerIndex );
+        tt_var_done_delta_set_index_map( face,
+                                         &blend->hvar_table->widthMap );
         FT_FREE( blend->hvar_table );
       }
 
       if ( blend->vvar_table )
       {
-        ft_var_done_item_variation_store( face,
+        tt_var_done_item_variation_store( face,
                                           &blend->vvar_table->itemStore );
 
-        FT_FREE( blend->vvar_table->widthMap.innerIndex );
-        FT_FREE( blend->vvar_table->widthMap.outerIndex );
+        tt_var_done_delta_set_index_map( face,
+                                         &blend->vvar_table->widthMap );
         FT_FREE( blend->vvar_table );
       }
 
       if ( blend->mvar_table )
       {
-        ft_var_done_item_variation_store( face,
+        tt_var_done_item_variation_store( face,
                                           &blend->mvar_table->itemStore );
 
         FT_FREE( blend->mvar_table->values );
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index bdc09d1..4fec980 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -4,7 +4,7 @@
  *
  *   TrueType GX Font Variation loader (specification)
  *
- * Copyright 2004-2018 by
+ * Copyright (C) 2004-2023 by
  * David Turner, Robert Wilhelm, Werner Lemberg and George Williams.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,7 @@
 #define TTGXVAR_H_
 
 
-#include <ft2build.h>
+#include <freetype/internal/ftmmtypes.h>
 #include "ttobjs.h"
 
 
@@ -63,55 +63,21 @@
   } GX_AVarSegmentRec, *GX_AVarSegment;
 
 
-  typedef struct  GX_ItemVarDataRec_
+  /**************************************************************************
+   *
+   * @Struct:
+   *   GX_AVarTableRec
+   *
+   * @Description:
+   *   Data from the `avar' table.
+   */
+  typedef struct  GX_AVarTableRec_
   {
-    FT_UInt    itemCount;      /* number of delta sets per item         */
-    FT_UInt    regionIdxCount; /* number of region indices in this data */
-    FT_UInt*   regionIndices;  /* array of `regionCount' indices;       */
-                               /* these index `varRegionList'           */
-    FT_Short*  deltaSet;       /* array of `itemCount' deltas           */
-                               /* use `innerIndex' for this array       */
+    GX_AVarSegment        avar_segment;   /* avar_segment[num_axis] */
+    GX_ItemVarStoreRec    itemStore;      /* Item Variation Store   */
+    GX_DeltaSetIdxMapRec  axisMap;        /* Axis Mapping           */
 
-  } GX_ItemVarDataRec, *GX_ItemVarData;
-
-
-  /* contribution of one axis to a region */
-  typedef struct  GX_AxisCoordsRec_
-  {
-    FT_Fixed  startCoord;
-    FT_Fixed  peakCoord;      /* zero means no effect (factor = 1) */
-    FT_Fixed  endCoord;
-
-  } GX_AxisCoordsRec, *GX_AxisCoords;
-
-
-  typedef struct  GX_VarRegionRec_
-  {
-    GX_AxisCoords  axisList;               /* array of axisCount records */
-
-  } GX_VarRegionRec, *GX_VarRegion;
-
-
-  /* item variation store */
-  typedef struct  GX_ItemVarStoreRec_
-  {
-    FT_UInt         dataCount;
-    GX_ItemVarData  varData;            /* array of dataCount records;     */
-                                        /* use `outerIndex' for this array */
-    FT_UShort     axisCount;
-    FT_UInt       regionCount;          /* total number of regions defined */
-    GX_VarRegion  varRegionList;
-
-  } GX_ItemVarStoreRec, *GX_ItemVarStore;
-
-
-  typedef struct  GX_DeltaSetIdxMapRec_
-  {
-    FT_UInt   mapCount;
-    FT_UInt*  outerIndex;             /* indices to item var data */
-    FT_UInt*  innerIndex;             /* indices to delta set     */
-
-  } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
+  } GX_AVarTableRec, *GX_AVarTable;
 
 
   /**************************************************************************
@@ -246,7 +212,7 @@
    *     A Boolean; if set, FreeType tried to load (and parse) the `avar'
    *     table.
    *
-   *   avar_segment ::
+   *   avar_table ::
    *     Data from the `avar' table.
    *
    *   hvar_loaded ::
@@ -311,7 +277,7 @@
                       /* normalized_stylecoords[num_namedstyles][num_axis] */
 
     FT_Bool         avar_loaded;
-    GX_AVarSegment  avar_segment;                /* avar_segment[num_axis] */
+    GX_AVarTable    avar_table;
 
     FT_Bool         hvar_loaded;
     FT_Bool         hvar_checked;
@@ -377,6 +343,7 @@
 #define TTAG_wdth  FT_MAKE_TAG( 'w', 'd', 't', 'h' )
 #define TTAG_opsz  FT_MAKE_TAG( 'o', 'p', 's', 'z' )
 #define TTAG_slnt  FT_MAKE_TAG( 's', 'l', 'n', 't' )
+#define TTAG_ital  FT_MAKE_TAG( 'i', 't', 'a', 'l' )
 
 
   FT_LOCAL( FT_Error )
@@ -413,10 +380,9 @@
 
 
   FT_LOCAL( FT_Error )
-  TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
-                              FT_UInt      glyph_index,
+  TT_Vary_Apply_Glyph_Deltas( TT_Loader    loader,
                               FT_Outline*  outline,
-                              FT_UInt      n_points );
+                              FT_Vector*   unrounded );
 
   FT_LOCAL( FT_Error )
   tt_hadvance_adjust( TT_Face  face,
@@ -431,6 +397,34 @@
   FT_LOCAL( void )
   tt_apply_mvar( TT_Face  face );
 
+
+  FT_LOCAL( FT_Error )
+  tt_var_load_item_variation_store( TT_Face          face,
+                                    FT_ULong         offset,
+                                    GX_ItemVarStore  itemStore );
+
+  FT_LOCAL( FT_Error )
+  tt_var_load_delta_set_index_mapping( TT_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,
+                         GX_ItemVarStore  itemStore,
+                         FT_UInt          outerIndex,
+                         FT_UInt          innerIndex );
+
+  FT_LOCAL( void )
+  tt_var_done_item_variation_store( TT_Face          face,
+                                    GX_ItemVarStore  itemStore );
+
+  FT_LOCAL( void )
+  tt_var_done_delta_set_index_map( TT_Face            face,
+                                   GX_DeltaSetIdxMap  deltaSetIdxMap );
+
+
   FT_LOCAL( FT_Error )
   tt_get_var_blend( TT_Face      face,
                     FT_UInt     *num_coords,
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 35aa399..4fcfaa3 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
  *
  *   TrueType bytecode interpreter (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,13 +20,12 @@
 /* issues; many thanks!                                                */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_TRIGONOMETRY_H
-#include FT_SYSTEM_H
-#include FT_DRIVER_H
-#include FT_MULTIPLE_MASTERS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/fttrigon.h>
+#include <freetype/ftsystem.h>
+#include <freetype/ftdriver.h>
+#include <freetype/ftmm.h>
 
 #include "ttinterp.h"
 #include "tterrors.h"
@@ -46,7 +45,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttinterp
+#define FT_COMPONENT  ttinterp
 
 
 #define NO_SUBPIXEL_HINTING                                                  \
@@ -252,6 +251,14 @@
     FT_FREE( exec->stack );
     exec->stackSize = 0;
 
+    /* free glyf cvt working area */
+    FT_FREE( exec->glyfCvt );
+    exec->glyfCvtSize = 0;
+
+    /* free glyf storage working area */
+    FT_FREE( exec->glyfStorage );
+    exec->glyfStoreSize = 0;
+
     /* free call stack */
     FT_FREE( exec->callStack );
     exec->callSize = 0;
@@ -271,64 +278,6 @@
   /**************************************************************************
    *
    * @Function:
-   *   Init_Context
-   *
-   * @Description:
-   *   Initializes a context object.
-   *
-   * @Input:
-   *   memory ::
-   *     A handle to the parent memory object.
-   *
-   * @InOut:
-   *   exec ::
-   *     A handle to the target execution context.
-   *
-   * @Return:
-   *   FreeType error code.  0 means success.
-   */
-  static FT_Error
-  Init_Context( TT_ExecContext  exec,
-                FT_Memory       memory )
-  {
-    FT_Error  error;
-
-
-    FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec ));
-
-    exec->memory   = memory;
-    exec->callSize = 32;
-
-    if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) )
-      goto Fail_Memory;
-
-    /* all values in the context are set to 0 already, but this is */
-    /* here as a remainder                                         */
-    exec->maxPoints   = 0;
-    exec->maxContours = 0;
-
-    exec->stackSize = 0;
-    exec->glyphSize = 0;
-
-    exec->stack    = NULL;
-    exec->glyphIns = NULL;
-
-    exec->face = NULL;
-    exec->size = NULL;
-
-    return FT_Err_Ok;
-
-  Fail_Memory:
-    FT_ERROR(( "Init_Context: not enough memory for %p\n", exec ));
-    TT_Done_Context( exec );
-
-    return error;
- }
-
-
-  /**************************************************************************
-   *
-   * @Function:
    *   Update_Max
    *
    * @Description:
@@ -368,7 +317,7 @@
 
     if ( *size < new_max )
     {
-      if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
+      if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
         return error;
       *size = new_max;
     }
@@ -401,6 +350,8 @@
    *
    * @Note:
    *   Only the glyph loader and debugger should call this function.
+   *
+   *   Note that not all members of `TT_ExecContext` get initialized.
    */
   FT_LOCAL_DEF( FT_Error )
   TT_Load_Context( TT_ExecContext  exec,
@@ -465,13 +416,13 @@
     if ( error )
       return error;
 
-    tmp = exec->glyphSize;
+    tmp = (FT_ULong)exec->glyphSize;
     error = Update_Max( exec->memory,
                         &tmp,
                         sizeof ( FT_Byte ),
                         (void*)&exec->glyphIns,
                         maxp->maxSizeOfInstructions );
-    exec->glyphSize = (FT_UShort)tmp;
+    exec->glyphSize = (FT_UInt)tmp;
     if ( error )
       return error;
 
@@ -537,14 +488,6 @@
    *   Executes one or more instructions in the execution context.
    *
    * @Input:
-   *   debug ::
-   *     A Boolean flag.  If set, the function sets some internal
-   *     variables and returns immediately, otherwise TT_RunIns()
-   *     is called.
-   *
-   *     This is commented out currently.
-   *
-   * @Input:
    *   exec ::
    *     A handle to the target execution context.
    *
@@ -618,19 +561,19 @@
 
     memory = driver->root.root.memory;
 
-    /* allocate object */
+    /* allocate object and zero everything inside */
     if ( FT_NEW( exec ) )
       goto Fail;
 
-    /* initialize it; in case of error this deallocates `exec' too */
-    error = Init_Context( exec, memory );
-    if ( error )
-      goto Fail;
+    /* create callStack here, other allocations delayed */
+    exec->memory   = memory;
+    exec->callSize = 32;
 
-    return exec;
+    if ( FT_QNEW_ARRAY( exec->callStack, exec->callSize ) )
+      FT_FREE( exec );
 
   Fail:
-    return NULL;
+    return exec;
   }
 
 
@@ -662,23 +605,25 @@
     /* opcodes are gathered in groups of 16 */
     /* please keep the spaces as they are   */
 
-    /*  SVTCA  y  */  PACK( 0, 0 ),
-    /*  SVTCA  x  */  PACK( 0, 0 ),
-    /*  SPvTCA y  */  PACK( 0, 0 ),
-    /*  SPvTCA x  */  PACK( 0, 0 ),
-    /*  SFvTCA y  */  PACK( 0, 0 ),
-    /*  SFvTCA x  */  PACK( 0, 0 ),
-    /*  SPvTL //  */  PACK( 2, 0 ),
-    /*  SPvTL +   */  PACK( 2, 0 ),
-    /*  SFvTL //  */  PACK( 2, 0 ),
-    /*  SFvTL +   */  PACK( 2, 0 ),
-    /*  SPvFS     */  PACK( 2, 0 ),
-    /*  SFvFS     */  PACK( 2, 0 ),
-    /*  GPv       */  PACK( 0, 2 ),
-    /*  GFv       */  PACK( 0, 2 ),
-    /*  SFvTPv    */  PACK( 0, 0 ),
+    /* 0x00 */
+    /*  SVTCA[0]  */  PACK( 0, 0 ),
+    /*  SVTCA[1]  */  PACK( 0, 0 ),
+    /*  SPVTCA[0] */  PACK( 0, 0 ),
+    /*  SPVTCA[1] */  PACK( 0, 0 ),
+    /*  SFVTCA[0] */  PACK( 0, 0 ),
+    /*  SFVTCA[1] */  PACK( 0, 0 ),
+    /*  SPVTL[0]  */  PACK( 2, 0 ),
+    /*  SPVTL[1]  */  PACK( 2, 0 ),
+    /*  SFVTL[0]  */  PACK( 2, 0 ),
+    /*  SFVTL[1]  */  PACK( 2, 0 ),
+    /*  SPVFS     */  PACK( 2, 0 ),
+    /*  SFVFS     */  PACK( 2, 0 ),
+    /*  GPV       */  PACK( 0, 2 ),
+    /*  GFV       */  PACK( 0, 2 ),
+    /*  SFVTPV    */  PACK( 0, 0 ),
     /*  ISECT     */  PACK( 5, 0 ),
 
+    /* 0x10 */
     /*  SRP0      */  PACK( 1, 0 ),
     /*  SRP1      */  PACK( 1, 0 ),
     /*  SRP2      */  PACK( 1, 0 ),
@@ -692,10 +637,11 @@
     /*  SMD       */  PACK( 1, 0 ),
     /*  ELSE      */  PACK( 0, 0 ),
     /*  JMPR      */  PACK( 1, 0 ),
-    /*  SCvTCi    */  PACK( 1, 0 ),
-    /*  SSwCi     */  PACK( 1, 0 ),
+    /*  SCVTCI    */  PACK( 1, 0 ),
+    /*  SSWCI     */  PACK( 1, 0 ),
     /*  SSW       */  PACK( 1, 0 ),
 
+    /* 0x20 */
     /*  DUP       */  PACK( 1, 2 ),
     /*  POP       */  PACK( 1, 0 ),
     /*  CLEAR     */  PACK( 0, 0 ),
@@ -703,7 +649,7 @@
     /*  DEPTH     */  PACK( 0, 1 ),
     /*  CINDEX    */  PACK( 1, 1 ),
     /*  MINDEX    */  PACK( 1, 0 ),
-    /*  AlignPTS  */  PACK( 2, 0 ),
+    /*  ALIGNPTS  */  PACK( 2, 0 ),
     /*  INS_$28   */  PACK( 0, 0 ),
     /*  UTP       */  PACK( 1, 0 ),
     /*  LOOPCALL  */  PACK( 2, 0 ),
@@ -713,6 +659,7 @@
     /*  MDAP[0]   */  PACK( 1, 0 ),
     /*  MDAP[1]   */  PACK( 1, 0 ),
 
+    /* 0x30 */
     /*  IUP[0]    */  PACK( 0, 0 ),
     /*  IUP[1]    */  PACK( 0, 0 ),
     /*  SHP[0]    */  PACK( 0, 0 ), /* loops */
@@ -725,17 +672,18 @@
     /*  IP        */  PACK( 0, 0 ), /* loops */
     /*  MSIRP[0]  */  PACK( 2, 0 ),
     /*  MSIRP[1]  */  PACK( 2, 0 ),
-    /*  AlignRP   */  PACK( 0, 0 ), /* loops */
+    /*  ALIGNRP   */  PACK( 0, 0 ), /* loops */
     /*  RTDG      */  PACK( 0, 0 ),
     /*  MIAP[0]   */  PACK( 2, 0 ),
     /*  MIAP[1]   */  PACK( 2, 0 ),
 
-    /*  NPushB    */  PACK( 0, 0 ),
-    /*  NPushW    */  PACK( 0, 0 ),
+    /* 0x40 */
+    /*  NPUSHB    */  PACK( 0, 0 ),
+    /*  NPUSHW    */  PACK( 0, 0 ),
     /*  WS        */  PACK( 2, 0 ),
     /*  RS        */  PACK( 1, 1 ),
-    /*  WCvtP     */  PACK( 2, 0 ),
-    /*  RCvt      */  PACK( 1, 1 ),
+    /*  WCVTP     */  PACK( 2, 0 ),
+    /*  RCVT      */  PACK( 1, 1 ),
     /*  GC[0]     */  PACK( 1, 1 ),
     /*  GC[1]     */  PACK( 1, 1 ),
     /*  SCFS      */  PACK( 2, 0 ),
@@ -743,10 +691,11 @@
     /*  MD[1]     */  PACK( 2, 1 ),
     /*  MPPEM     */  PACK( 0, 1 ),
     /*  MPS       */  PACK( 0, 1 ),
-    /*  FlipON    */  PACK( 0, 0 ),
-    /*  FlipOFF   */  PACK( 0, 0 ),
+    /*  FLIPON    */  PACK( 0, 0 ),
+    /*  FLIPOFF   */  PACK( 0, 0 ),
     /*  DEBUG     */  PACK( 1, 0 ),
 
+    /* 0x50 */
     /*  LT        */  PACK( 2, 1 ),
     /*  LTEQ      */  PACK( 2, 1 ),
     /*  GT        */  PACK( 2, 1 ),
@@ -760,10 +709,11 @@
     /*  AND       */  PACK( 2, 1 ),
     /*  OR        */  PACK( 2, 1 ),
     /*  NOT       */  PACK( 1, 1 ),
-    /*  DeltaP1   */  PACK( 1, 0 ),
+    /*  DELTAP1   */  PACK( 1, 0 ),
     /*  SDB       */  PACK( 1, 0 ),
     /*  SDS       */  PACK( 1, 0 ),
 
+    /* 0x60 */
     /*  ADD       */  PACK( 2, 1 ),
     /*  SUB       */  PACK( 2, 1 ),
     /*  DIV       */  PACK( 2, 1 ),
@@ -781,14 +731,15 @@
     /*  NROUND[2] */  PACK( 1, 1 ),
     /*  NROUND[3] */  PACK( 1, 1 ),
 
-    /*  WCvtF     */  PACK( 2, 0 ),
-    /*  DeltaP2   */  PACK( 1, 0 ),
-    /*  DeltaP3   */  PACK( 1, 0 ),
-    /*  DeltaCn[0] */ PACK( 1, 0 ),
-    /*  DeltaCn[1] */ PACK( 1, 0 ),
-    /*  DeltaCn[2] */ PACK( 1, 0 ),
+    /* 0x70 */
+    /*  WCVTF     */  PACK( 2, 0 ),
+    /*  DELTAP2   */  PACK( 1, 0 ),
+    /*  DELTAP3   */  PACK( 1, 0 ),
+    /*  DELTAC1   */  PACK( 1, 0 ),
+    /*  DELTAC2   */  PACK( 1, 0 ),
+    /*  DELTAC3   */  PACK( 1, 0 ),
     /*  SROUND    */  PACK( 1, 0 ),
-    /*  S45Round  */  PACK( 1, 0 ),
+    /*  S45ROUND  */  PACK( 1, 0 ),
     /*  JROT      */  PACK( 2, 0 ),
     /*  JROF      */  PACK( 2, 0 ),
     /*  ROFF      */  PACK( 0, 0 ),
@@ -798,23 +749,25 @@
     /*  SANGW     */  PACK( 1, 0 ),
     /*  AA        */  PACK( 1, 0 ),
 
-    /*  FlipPT    */  PACK( 0, 0 ), /* loops */
-    /*  FlipRgON  */  PACK( 2, 0 ),
-    /*  FlipRgOFF */  PACK( 2, 0 ),
+    /* 0x80 */
+    /*  FLIPPT    */  PACK( 0, 0 ), /* loops */
+    /*  FLIPRGON  */  PACK( 2, 0 ),
+    /*  FLIPRGOFF */  PACK( 2, 0 ),
     /*  INS_$83   */  PACK( 0, 0 ),
     /*  INS_$84   */  PACK( 0, 0 ),
-    /*  ScanCTRL  */  PACK( 1, 0 ),
-    /*  SDPvTL[0] */  PACK( 2, 0 ),
-    /*  SDPvTL[1] */  PACK( 2, 0 ),
-    /*  GetINFO   */  PACK( 1, 1 ),
+    /*  SCANCTRL  */  PACK( 1, 0 ),
+    /*  SDPVTL[0] */  PACK( 2, 0 ),
+    /*  SDPVTL[1] */  PACK( 2, 0 ),
+    /*  GETINFO   */  PACK( 1, 1 ),
     /*  IDEF      */  PACK( 1, 0 ),
     /*  ROLL      */  PACK( 3, 3 ),
     /*  MAX       */  PACK( 2, 1 ),
     /*  MIN       */  PACK( 2, 1 ),
-    /*  ScanTYPE  */  PACK( 1, 0 ),
-    /*  InstCTRL  */  PACK( 2, 0 ),
+    /*  SCANTYPE  */  PACK( 1, 0 ),
+    /*  INSTCTRL  */  PACK( 2, 0 ),
     /*  INS_$8F   */  PACK( 0, 0 ),
 
+    /* 0x90 */
     /*  INS_$90  */   PACK( 0, 0 ),
     /*  GETVAR   */   PACK( 0, 0 ), /* will be handled specially */
     /*  GETDATA  */   PACK( 0, 1 ),
@@ -832,6 +785,7 @@
     /*  INS_$9E  */   PACK( 0, 0 ),
     /*  INS_$9F  */   PACK( 0, 0 ),
 
+    /* 0xA0 */
     /*  INS_$A0  */   PACK( 0, 0 ),
     /*  INS_$A1  */   PACK( 0, 0 ),
     /*  INS_$A2  */   PACK( 0, 0 ),
@@ -849,23 +803,25 @@
     /*  INS_$AE  */   PACK( 0, 0 ),
     /*  INS_$AF  */   PACK( 0, 0 ),
 
-    /*  PushB[0]  */  PACK( 0, 1 ),
-    /*  PushB[1]  */  PACK( 0, 2 ),
-    /*  PushB[2]  */  PACK( 0, 3 ),
-    /*  PushB[3]  */  PACK( 0, 4 ),
-    /*  PushB[4]  */  PACK( 0, 5 ),
-    /*  PushB[5]  */  PACK( 0, 6 ),
-    /*  PushB[6]  */  PACK( 0, 7 ),
-    /*  PushB[7]  */  PACK( 0, 8 ),
-    /*  PushW[0]  */  PACK( 0, 1 ),
-    /*  PushW[1]  */  PACK( 0, 2 ),
-    /*  PushW[2]  */  PACK( 0, 3 ),
-    /*  PushW[3]  */  PACK( 0, 4 ),
-    /*  PushW[4]  */  PACK( 0, 5 ),
-    /*  PushW[5]  */  PACK( 0, 6 ),
-    /*  PushW[6]  */  PACK( 0, 7 ),
-    /*  PushW[7]  */  PACK( 0, 8 ),
+    /* 0xB0 */
+    /*  PUSHB[0]  */  PACK( 0, 1 ),
+    /*  PUSHB[1]  */  PACK( 0, 2 ),
+    /*  PUSHB[2]  */  PACK( 0, 3 ),
+    /*  PUSHB[3]  */  PACK( 0, 4 ),
+    /*  PUSHB[4]  */  PACK( 0, 5 ),
+    /*  PUSHB[5]  */  PACK( 0, 6 ),
+    /*  PUSHB[6]  */  PACK( 0, 7 ),
+    /*  PUSHB[7]  */  PACK( 0, 8 ),
+    /*  PUSHW[0]  */  PACK( 0, 1 ),
+    /*  PUSHW[1]  */  PACK( 0, 2 ),
+    /*  PUSHW[2]  */  PACK( 0, 3 ),
+    /*  PUSHW[3]  */  PACK( 0, 4 ),
+    /*  PUSHW[4]  */  PACK( 0, 5 ),
+    /*  PUSHW[5]  */  PACK( 0, 6 ),
+    /*  PUSHW[6]  */  PACK( 0, 7 ),
+    /*  PUSHW[7]  */  PACK( 0, 8 ),
 
+    /* 0xC0 */
     /*  MDRP[00]  */  PACK( 1, 0 ),
     /*  MDRP[01]  */  PACK( 1, 0 ),
     /*  MDRP[02]  */  PACK( 1, 0 ),
@@ -883,6 +839,7 @@
     /*  MDRP[14]  */  PACK( 1, 0 ),
     /*  MDRP[15]  */  PACK( 1, 0 ),
 
+    /* 0xD0 */
     /*  MDRP[16]  */  PACK( 1, 0 ),
     /*  MDRP[17]  */  PACK( 1, 0 ),
     /*  MDRP[18]  */  PACK( 1, 0 ),
@@ -900,6 +857,7 @@
     /*  MDRP[30]  */  PACK( 1, 0 ),
     /*  MDRP[31]  */  PACK( 1, 0 ),
 
+    /* 0xE0 */
     /*  MIRP[00]  */  PACK( 2, 0 ),
     /*  MIRP[01]  */  PACK( 2, 0 ),
     /*  MIRP[02]  */  PACK( 2, 0 ),
@@ -917,6 +875,7 @@
     /*  MIRP[14]  */  PACK( 2, 0 ),
     /*  MIRP[15]  */  PACK( 2, 0 ),
 
+    /* 0xF0 */
     /*  MIRP[16]  */  PACK( 2, 0 ),
     /*  MIRP[17]  */  PACK( 2, 0 ),
     /*  MIRP[18]  */  PACK( 2, 0 ),
@@ -945,23 +904,25 @@
   static
   const char*  const opcode_name[256] =
   {
-    "7 SVTCA y",
-    "7 SVTCA x",
-    "8 SPvTCA y",
-    "8 SPvTCA x",
-    "8 SFvTCA y",
-    "8 SFvTCA x",
-    "8 SPvTL ||",
-    "7 SPvTL +",
-    "8 SFvTL ||",
-    "7 SFvTL +",
-    "5 SPvFS",
-    "5 SFvFS",
-    "3 GPv",
-    "3 GFv",
-    "6 SFvTPv",
+    /* 0x00 */
+    "8 SVTCA[y]",
+    "8 SVTCA[x]",
+    "9 SPVTCA[y]",
+    "9 SPVTCA[x]",
+    "9 SFVTCA[y]",
+    "9 SFVTCA[x]",
+    "9 SPVTL[||]",
+    "8 SPVTL[+]",
+    "9 SFVTL[||]",
+    "8 SFVTL[+]",
+    "5 SPVFS",
+    "5 SFVFS",
+    "3 GPV",
+    "3 GFV",
+    "6 SFVTPV",
     "5 ISECT",
 
+    /* 0x10 */
     "4 SRP0",
     "4 SRP1",
     "4 SRP2",
@@ -975,10 +936,11 @@
     "3 SMD",
     "4 ELSE",
     "4 JMPR",
-    "6 SCvTCi",
-    "5 SSwCi",
+    "6 SCVTCI",
+    "5 SSWCI",
     "3 SSW",
 
+    /* 0x20 */
     "3 DUP",
     "3 POP",
     "5 CLEAR",
@@ -986,50 +948,53 @@
     "5 DEPTH",
     "6 CINDEX",
     "6 MINDEX",
-    "8 AlignPTS",
+    "8 ALIGNPTS",
     "7 INS_$28",
     "3 UTP",
     "8 LOOPCALL",
     "4 CALL",
     "4 FDEF",
     "4 ENDF",
-    "7 MDAP[0]",
-    "7 MDAP[1]",
+    "6 MDAP[]",
+    "9 MDAP[rnd]",
 
-    "6 IUP[0]",
-    "6 IUP[1]",
-    "6 SHP[0]",
-    "6 SHP[1]",
-    "6 SHC[0]",
-    "6 SHC[1]",
-    "6 SHZ[0]",
-    "6 SHZ[1]",
+    /* 0x30 */
+    "6 IUP[y]",
+    "6 IUP[x]",
+    "8 SHP[rp2]",
+    "8 SHP[rp1]",
+    "8 SHC[rp2]",
+    "8 SHC[rp1]",
+    "8 SHZ[rp2]",
+    "8 SHZ[rp1]",
     "5 SHPIX",
     "2 IP",
-    "8 MSIRP[0]",
-    "8 MSIRP[1]",
-    "7 AlignRP",
+    "7 MSIRP[]",
+    "A MSIRP[rp0]",
+    "7 ALIGNRP",
     "4 RTDG",
-    "7 MIAP[0]",
-    "7 MIAP[1]",
+    "6 MIAP[]",
+    "9 MIAP[rnd]",
 
-    "6 NPushB",
-    "6 NPushW",
+    /* 0x40 */
+    "6 NPUSHB",
+    "6 NPUSHW",
     "2 WS",
     "2 RS",
-    "5 WCvtP",
-    "4 RCvt",
-    "5 GC[0]",
-    "5 GC[1]",
+    "5 WCVTP",
+    "4 RCVT",
+    "8 GC[curr]",
+    "8 GC[orig]",
     "4 SCFS",
-    "5 MD[0]",
-    "5 MD[1]",
+    "8 MD[curr]",
+    "8 MD[orig]",
     "5 MPPEM",
     "3 MPS",
-    "6 FlipON",
-    "7 FlipOFF",
+    "6 FLIPON",
+    "7 FLIPOFF",
     "5 DEBUG",
 
+    /* 0x50 */
     "2 LT",
     "4 LTEQ",
     "2 GT",
@@ -1043,10 +1008,11 @@
     "3 AND",
     "2 OR",
     "3 NOT",
-    "7 DeltaP1",
+    "7 DELTAP1",
     "3 SDB",
     "3 SDS",
 
+    /* 0x60 */
     "3 ADD",
     "3 SUB",
     "3 DIV",
@@ -1055,23 +1021,24 @@
     "3 NEG",
     "5 FLOOR",
     "7 CEILING",
-    "8 ROUND[0]",
-    "8 ROUND[1]",
-    "8 ROUND[2]",
-    "8 ROUND[3]",
-    "9 NROUND[0]",
-    "9 NROUND[1]",
-    "9 NROUND[2]",
-    "9 NROUND[3]",
+    "8 ROUND[G]",
+    "8 ROUND[B]",
+    "8 ROUND[W]",
+    "7 ROUND[]",
+    "9 NROUND[G]",
+    "9 NROUND[B]",
+    "9 NROUND[W]",
+    "8 NROUND[]",
 
-    "5 WCvtF",
-    "7 DeltaP2",
-    "7 DeltaP3",
-    "A DeltaCn[0]",
-    "A DeltaCn[1]",
-    "A DeltaCn[2]",
+    /* 0x70 */
+    "5 WCVTF",
+    "7 DELTAP2",
+    "7 DELTAP3",
+    "7 DELTAC1",
+    "7 DELTAC2",
+    "7 DELTAC3",
     "6 SROUND",
-    "8 S45Round",
+    "8 S45ROUND",
     "4 JROT",
     "4 JROF",
     "4 ROFF",
@@ -1081,26 +1048,28 @@
     "5 SANGW",
     "2 AA",
 
-    "6 FlipPT",
-    "8 FlipRgON",
-    "9 FlipRgOFF",
+    /* 0x80 */
+    "6 FLIPPT",
+    "8 FLIPRGON",
+    "9 FLIPRGOFF",
     "7 INS_$83",
     "7 INS_$84",
-    "8 ScanCTRL",
-    "9 SDPvTL[0]",
-    "9 SDPvTL[1]",
-    "7 GetINFO",
+    "8 SCANCTRL",
+    "A SDPVTL[||]",
+    "9 SDPVTL[+]",
+    "7 GETINFO",
     "4 IDEF",
     "4 ROLL",
     "3 MAX",
     "3 MIN",
-    "8 ScanTYPE",
-    "8 InstCTRL",
+    "8 SCANTYPE",
+    "8 INSTCTRL",
     "7 INS_$8F",
 
+    /* 0x90 */
     "7 INS_$90",
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    "6 GETVAR",
+    "C GETVARIATION",
     "7 GETDATA",
 #else
     "7 INS_$91",
@@ -1120,6 +1089,7 @@
     "7 INS_$9E",
     "7 INS_$9F",
 
+    /* 0xA0 */
     "7 INS_$A0",
     "7 INS_$A1",
     "7 INS_$A2",
@@ -1137,90 +1107,95 @@
     "7 INS_$AE",
     "7 INS_$AF",
 
-    "8 PushB[0]",
-    "8 PushB[1]",
-    "8 PushB[2]",
-    "8 PushB[3]",
-    "8 PushB[4]",
-    "8 PushB[5]",
-    "8 PushB[6]",
-    "8 PushB[7]",
-    "8 PushW[0]",
-    "8 PushW[1]",
-    "8 PushW[2]",
-    "8 PushW[3]",
-    "8 PushW[4]",
-    "8 PushW[5]",
-    "8 PushW[6]",
-    "8 PushW[7]",
+    /* 0xB0 */
+    "8 PUSHB[0]",
+    "8 PUSHB[1]",
+    "8 PUSHB[2]",
+    "8 PUSHB[3]",
+    "8 PUSHB[4]",
+    "8 PUSHB[5]",
+    "8 PUSHB[6]",
+    "8 PUSHB[7]",
+    "8 PUSHW[0]",
+    "8 PUSHW[1]",
+    "8 PUSHW[2]",
+    "8 PUSHW[3]",
+    "8 PUSHW[4]",
+    "8 PUSHW[5]",
+    "8 PUSHW[6]",
+    "8 PUSHW[7]",
 
+    /* 0xC0 */
     "7 MDRP[G]",
     "7 MDRP[B]",
     "7 MDRP[W]",
-    "7 MDRP[?]",
+    "6 MDRP[]",
     "8 MDRP[rG]",
     "8 MDRP[rB]",
     "8 MDRP[rW]",
-    "8 MDRP[r?]",
+    "7 MDRP[r]",
     "8 MDRP[mG]",
     "8 MDRP[mB]",
     "8 MDRP[mW]",
-    "8 MDRP[m?]",
+    "7 MDRP[m]",
     "9 MDRP[mrG]",
     "9 MDRP[mrB]",
     "9 MDRP[mrW]",
-    "9 MDRP[mr?]",
+    "8 MDRP[mr]",
 
+    /* 0xD0 */
     "8 MDRP[pG]",
     "8 MDRP[pB]",
     "8 MDRP[pW]",
-    "8 MDRP[p?]",
+    "7 MDRP[p]",
     "9 MDRP[prG]",
     "9 MDRP[prB]",
     "9 MDRP[prW]",
-    "9 MDRP[pr?]",
+    "8 MDRP[pr]",
     "9 MDRP[pmG]",
     "9 MDRP[pmB]",
     "9 MDRP[pmW]",
-    "9 MDRP[pm?]",
+    "8 MDRP[pm]",
     "A MDRP[pmrG]",
     "A MDRP[pmrB]",
     "A MDRP[pmrW]",
-    "A MDRP[pmr?]",
+    "9 MDRP[pmr]",
 
+    /* 0xE0 */
     "7 MIRP[G]",
     "7 MIRP[B]",
     "7 MIRP[W]",
-    "7 MIRP[?]",
+    "6 MIRP[]",
     "8 MIRP[rG]",
     "8 MIRP[rB]",
     "8 MIRP[rW]",
-    "8 MIRP[r?]",
+    "7 MIRP[r]",
     "8 MIRP[mG]",
     "8 MIRP[mB]",
     "8 MIRP[mW]",
-    "8 MIRP[m?]",
+    "7 MIRP[m]",
     "9 MIRP[mrG]",
     "9 MIRP[mrB]",
     "9 MIRP[mrW]",
-    "9 MIRP[mr?]",
+    "8 MIRP[mr]",
 
+    /* 0xF0 */
     "8 MIRP[pG]",
     "8 MIRP[pB]",
     "8 MIRP[pW]",
-    "8 MIRP[p?]",
+    "7 MIRP[p]",
     "9 MIRP[prG]",
     "9 MIRP[prB]",
     "9 MIRP[prW]",
-    "9 MIRP[pr?]",
+    "8 MIRP[pr]",
     "9 MIRP[pmG]",
     "9 MIRP[pmB]",
     "9 MIRP[pmW]",
-    "9 MIRP[pm?]",
+    "8 MIRP[pm]",
     "A MIRP[pmrG]",
     "A MIRP[pmrB]",
     "A MIRP[pmrW]",
-    "A MIRP[pmr?]"
+    "9 MIRP[pmr]"
   };
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
@@ -1549,11 +1524,35 @@
   }
 
 
+  static void
+  Modify_CVT_Check( TT_ExecContext  exc )
+  {
+    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 )
+        return;
+
+      FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
+      exc->cvt = exc->glyfCvt;
+    }
+  }
+
+
   FT_CALLBACK_DEF( void )
   Write_CVT( TT_ExecContext  exc,
              FT_ULong        idx,
              FT_F26Dot6      value )
   {
+    Modify_CVT_Check( exc );
+    if ( exc->error )
+      return;
+
     exc->cvt[idx] = value;
   }
 
@@ -1563,6 +1562,10 @@
                        FT_ULong        idx,
                        FT_F26Dot6      value )
   {
+    Modify_CVT_Check( exc );
+    if ( exc->error )
+      return;
+
     exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
   }
 
@@ -1572,7 +1575,11 @@
             FT_ULong        idx,
             FT_F26Dot6      value )
   {
-    exc->cvt[idx] += value;
+    Modify_CVT_Check( exc );
+    if ( exc->error )
+      return;
+
+    exc->cvt[idx] = ADD_LONG( exc->cvt[idx], value );
   }
 
 
@@ -1581,7 +1588,12 @@
                       FT_ULong        idx,
                       FT_F26Dot6      value )
   {
-    exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
+    Modify_CVT_Check( exc );
+    if ( exc->error )
+      return;
+
+    exc->cvt[idx] = ADD_LONG( exc->cvt[idx],
+                              FT_DivFix( value, Current_Ratio( exc ) ) );
   }
 
 
@@ -1669,6 +1681,32 @@
   }
 
 
+  /*
+   *
+   * Apple's TrueType specification at
+   *
+   *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#order
+   *
+   * gives the following order of operations in instructions that move
+   * points.
+   *
+   *   - check single width cut-in (MIRP, MDRP)
+   *
+   *   - check control value cut-in (MIRP, MIAP)
+   *
+   *   - apply engine compensation (MIRP, MDRP)
+   *
+   *   - round distance (MIRP, MDRP) or value (MIAP, MDAP)
+   *
+   *   - check minimum distance (MIRP,MDRP)
+   *
+   *   - move point (MIRP, MDRP, MIAP, MSIRP, MDAP)
+   *
+   * For rounding instructions, engine compensation happens before rounding.
+   *
+   */
+
+
   /**************************************************************************
    *
    * @Function:
@@ -1893,7 +1931,6 @@
     zone->org[point].y = ADD_LONG( zone->org[point].y, distance );
   }
 
-
   /**************************************************************************
    *
    * @Function:
@@ -1906,27 +1943,20 @@
    *   distance ::
    *     The distance (not) to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   The compensated distance.
-   *
-   * @Note:
-   *   The TrueType specification says very few about the relationship
-   *   between rounding and engine compensation.  However, it seems from
-   *   the description of super round that we should add the compensation
-   *   before rounding.
    */
   static FT_F26Dot6
   Round_None( TT_ExecContext  exc,
               FT_F26Dot6      distance,
-              FT_F26Dot6      compensation )
+              FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
-    FT_UNUSED( exc );
-
 
     if ( distance >= 0 )
     {
@@ -1956,8 +1986,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -1965,12 +1995,11 @@
   static FT_F26Dot6
   Round_To_Grid( TT_ExecContext  exc,
                  FT_F26Dot6      distance,
-                 FT_F26Dot6      compensation )
+                 FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
-    FT_UNUSED( exc );
-
 
     if ( distance >= 0 )
     {
@@ -2002,8 +2031,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -2011,12 +2040,11 @@
   static FT_F26Dot6
   Round_To_Half_Grid( TT_ExecContext  exc,
                       FT_F26Dot6      distance,
-                      FT_F26Dot6      compensation )
+                      FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
-    FT_UNUSED( exc );
-
 
     if ( distance >= 0 )
     {
@@ -2050,8 +2078,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -2059,12 +2087,11 @@
   static FT_F26Dot6
   Round_Down_To_Grid( TT_ExecContext  exc,
                       FT_F26Dot6      distance,
-                      FT_F26Dot6      compensation )
+                      FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
-    FT_UNUSED( exc );
-
 
     if ( distance >= 0 )
     {
@@ -2095,8 +2122,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -2104,12 +2131,11 @@
   static FT_F26Dot6
   Round_Up_To_Grid( TT_ExecContext  exc,
                     FT_F26Dot6      distance,
-                    FT_F26Dot6      compensation )
+                    FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
-    FT_UNUSED( exc );
-
 
     if ( distance >= 0 )
     {
@@ -2141,8 +2167,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -2150,12 +2176,11 @@
   static FT_F26Dot6
   Round_To_Double_Grid( TT_ExecContext  exc,
                         FT_F26Dot6      distance,
-                        FT_F26Dot6      compensation )
+                        FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
-    FT_UNUSED( exc );
-
 
     if ( distance >= 0 )
     {
@@ -2187,8 +2212,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -2202,8 +2227,9 @@
   static FT_F26Dot6
   Round_Super( TT_ExecContext  exc,
                FT_F26Dot6      distance,
-               FT_F26Dot6      compensation )
+               FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
 
@@ -2242,8 +2268,8 @@
    *   distance ::
    *     The distance to round.
    *
-   *   compensation ::
-   *     The engine compensation.
+   *   color ::
+   *     The engine compensation color.
    *
    * @Return:
    *   Rounded distance.
@@ -2255,8 +2281,9 @@
   static FT_F26Dot6
   Round_Super_45( TT_ExecContext  exc,
                   FT_F26Dot6      distance,
-                  FT_F26Dot6      compensation )
+                  FT_Int          color )
   {
+    FT_F26Dot6  compensation = exc->tt_metrics.compensations[color];
     FT_F26Dot6  val;
 
 
@@ -2855,7 +2882,7 @@
   Ins_ODD( TT_ExecContext  exc,
            FT_Long*        args )
   {
-    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
+    args[0] = ( ( exc->func_round( exc, args[0], 3 ) & 127 ) == 64 );
   }
 
 
@@ -2869,7 +2896,7 @@
   Ins_EVEN( TT_ExecContext  exc,
             FT_Long*        args )
   {
-    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
+    args[0] = ( ( exc->func_round( exc, args[0], 3 ) & 127 ) == 0 );
   }
 
 
@@ -3086,7 +3113,28 @@
         ARRAY_BOUND_ERROR;
     }
     else
+    {
+      if ( exc->iniRange == tt_coderange_glyph &&
+           exc->storage != exc->glyfStorage    )
+      {
+        FT_ULong  tmp = (FT_ULong)exc->glyfStoreSize;
+
+
+        exc->error = Update_Max( exc->memory,
+                                 &tmp,
+                                 sizeof ( FT_Long ),
+                                 (void*)&exc->glyfStorage,
+                                 exc->storeSize );
+        exc->glyfStoreSize = (FT_UShort)tmp;
+        if ( exc->error )
+          return;
+
+        FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
+        exc->storage = exc->glyfStorage;
+      }
+
       exc->storage[I] = args[1];
+    }
   }
 
 
@@ -3199,10 +3247,7 @@
   Ins_ROUND( TT_ExecContext  exc,
              FT_Long*        args )
   {
-    args[0] = exc->func_round(
-                exc,
-                args[0],
-                exc->tt_metrics.compensations[exc->opcode - 0x68] );
+    args[0] = exc->func_round( exc, args[0], exc->opcode & 3 );
   }
 
 
@@ -3216,10 +3261,7 @@
   Ins_NROUND( TT_ExecContext  exc,
               FT_Long*        args )
   {
-    args[0] = Round_None(
-                exc,
-                args[0],
-                exc->tt_metrics.compensations[exc->opcode - 0x6C] );
+    args[0] = Round_None( exc, args[0], exc->opcode & 3 );
   }
 
 
@@ -3492,7 +3534,7 @@
       return;
     }
 
-    exc->IP += args[0];
+    exc->IP = ADD_LONG( exc->IP, args[0] );
     if ( exc->IP < 0                                             ||
          ( exc->callTop > 0                                    &&
            exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )
@@ -3664,7 +3706,7 @@
 
 
     /* FDEF is only allowed in `prep' or `fpgm' */
-    if ( exc->curRange == tt_coderange_glyph )
+    if ( exc->iniRange == tt_coderange_glyph )
     {
       exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
       return;
@@ -3674,7 +3716,7 @@
     /* We will then parse the current table.                       */
 
     rec   = exc->FDefs;
-    limit = rec + exc->numFDefs;
+    limit = FT_OFFSET( rec, exc->numFDefs );
     n     = (FT_ULong)args[0];
 
     for ( ; rec < limit; rec++ )
@@ -3738,7 +3780,7 @@
 
             if ( opcode_pointer[i] == opcode_size[i] )
             {
-              FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
+              FT_TRACE6(( "sph: Function %d, opcode ptrn: %ld, %s %s\n",
                           i, n,
                           exc->face->root.family_name,
                           exc->face->root.style_name ));
@@ -3921,6 +3963,9 @@
     if ( BOUNDSL( F, exc->maxFunc + 1 ) )
       goto Fail;
 
+    if ( !exc->FDefs )
+      goto Fail;
+
     /* Except for some old Apple fonts, all functions in a TrueType */
     /* font are defined in increasing order, starting from 0.  This */
     /* means that we normally have                                  */
@@ -4018,7 +4063,7 @@
     /*                                                              */
     /* If this isn't true, we need to look up the function table.   */
 
-    def = exc->FDefs + F;
+    def = FT_OFFSET( exc->FDefs, F );
     if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
     {
       /* look up the FDefs table */
@@ -4026,7 +4071,7 @@
 
 
       def   = exc->FDefs;
-      limit = def + exc->numFDefs;
+      limit = FT_OFFSET( def, exc->numFDefs );
 
       while ( def < limit && def->opc != F )
         def++;
@@ -4097,7 +4142,7 @@
 
 
     /* we enable IDEF only in `prep' or `fpgm' */
-    if ( exc->curRange == tt_coderange_glyph )
+    if ( exc->iniRange == tt_coderange_glyph )
     {
       exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
       return;
@@ -4106,7 +4151,7 @@
     /*  First of all, look for the same function in our table */
 
     def   = exc->IDefs;
-    limit = def + exc->numIDefs;
+    limit = FT_OFFSET( def, exc->numIDefs );
 
     for ( ; def < limit; def++ )
       if ( def->opc == (FT_ULong)args[0] )
@@ -4326,7 +4371,7 @@
 
     if ( ( opcode & 1 ) != 0 )
     {
-      C = B;   /* counter clockwise rotation */
+      C = B;   /* counter-clockwise rotation */
       B = A;
       A = NEG_LONG( C );
     }
@@ -4955,9 +5000,9 @@
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          &&
-         FT_ABS( D ) == 64           )
+    if ( SUBPIXEL_HINTING_INFINALITY         &&
+         exc->ignore_x_mode                  &&
+         ( D < 0 ? NEG_LONG( D ) : D ) == 64 )
       D += 1;
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
@@ -5014,7 +5059,7 @@
 
     if ( ( opcode & 1 ) != 0 )
     {
-      C = B;   /* counter clockwise rotation */
+      C = B;   /* counter-clockwise rotation */
       B = A;
       A = NEG_LONG( C );
     }
@@ -5038,7 +5083,7 @@
 
     if ( ( opcode & 1 ) != 0 )
     {
-      C = B;   /* counter clockwise rotation */
+      C = B;   /* counter-clockwise rotation */
       B = A;
       A = NEG_LONG( C );
     }
@@ -5212,16 +5257,21 @@
       }
     }
 
-    exc->GS.instruct_control &= ~(FT_Byte)Kf;
-    exc->GS.instruct_control |= (FT_Byte)L;
+    /* INSTCTRL should only be used in the CVT program */
+    if ( exc->iniRange == tt_coderange_cvt )
+    {
+      exc->GS.instruct_control &= ~(FT_Byte)Kf;
+      exc->GS.instruct_control |= (FT_Byte)L;
+    }
 
-    if ( K == 3 )
+    /* 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 );
+        exc->ignore_x_mode = !FT_BOOL( L == 4 );
 #endif
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
@@ -5232,6 +5282,8 @@
         exc->backward_compatibility = !FT_BOOL( L == 4 );
 #endif
     }
+    else if ( exc->pedantic_hinting )
+      exc->error = FT_THROW( Invalid_Reference );
   }
 
 
@@ -5686,9 +5738,6 @@
   {
     FT_F26Dot6  dx, dy;
     FT_UShort   point;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    FT_Int      B1, B2;
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     FT_Bool     in_twilight = FT_BOOL( exc->GS.gep0 == 0 ||
                                        exc->GS.gep1 == 0 ||
@@ -5723,8 +5772,12 @@
       }
       else
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( 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:   */
@@ -5733,72 +5786,57 @@
         /*   - the glyph is specifically set to allow SHPIX moves        */
         /*   - the move is on a previously Y-touched point               */
 
-        if ( exc->ignore_x_mode )
+        /* save point for later comparison */
+        B1 = exc->zp2.cur[point].y;
+
+        if ( exc->face->sph_compatibility_mode )
         {
-          /* save point for later comparison */
+          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 )
-            B1 = exc->zp2.cur[point].y;
-          else
-            B1 = exc->zp2.cur[point].x;
-
-          if ( !exc->face->sph_compatibility_mode &&
-               exc->GS.freeVector.y != 0          )
           {
-            Move_Zp2_Point( exc, point, dx, dy, TRUE );
+            B2 = exc->zp2.cur[point].y;
 
-            /* save new point */
-            if ( exc->GS.freeVector.y != 0 )
-            {
-              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 );
-            }
+            /* 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->face->sph_compatibility_mode )
-          {
-            if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
-            {
-              dx = FT_PIX_ROUND( B1 + dx ) - B1;
-              dy = FT_PIX_ROUND( B1 + dy ) - B1;
-            }
-
-            /* skip post-iup deltas */
-            if ( 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->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
-            Move_Zp2_Point( exc, point, dx, dy, TRUE );
         }
-        else
+        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
@@ -5846,22 +5884,8 @@
   {
     FT_UShort   point = 0;
     FT_F26Dot6  distance;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    FT_F26Dot6  control_value_cutin = 0;
-    FT_F26Dot6  delta;
 
 
-    if ( SUBPIXEL_HINTING_INFINALITY )
-    {
-      control_value_cutin = exc->GS.control_value_cutin;
-
-      if ( exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        control_value_cutin = 0;
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     point = (FT_UShort)args[0];
 
     if ( BOUNDS( point,       exc->zp1.n_points ) ||
@@ -5884,16 +5908,25 @@
     distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    delta = SUB_LONG( distance, args[1] );
-    if ( delta < 0 )
-      delta = NEG_LONG( delta );
-
     /* subpixel hinting - make MSIRP respect CVT cut-in; */
-    if ( SUBPIXEL_HINTING_INFINALITY  &&
-         exc->ignore_x_mode           &&
-         exc->GS.freeVector.x != 0    &&
-         delta >= control_value_cutin )
-      distance = args[1];
+    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,
@@ -5940,18 +5973,10 @@
       if ( SUBPIXEL_HINTING_INFINALITY &&
            exc->ignore_x_mode          &&
            exc->GS.freeVector.x != 0   )
-        distance = SUB_LONG(
-                     Round_None( exc,
-                                 cur_dist,
-                                 exc->tt_metrics.compensations[0] ),
-                     cur_dist );
+        distance = SUB_LONG( Round_None( exc, cur_dist, 3 ), cur_dist );
       else
 #endif
-        distance = SUB_LONG(
-                     exc->func_round( exc,
-                                      cur_dist,
-                                      exc->tt_metrics.compensations[0] ),
-                     cur_dist );
+        distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist );
     }
     else
       distance = 0;
@@ -5977,21 +6002,10 @@
     FT_UShort   point;
     FT_F26Dot6  distance;
     FT_F26Dot6  org_dist;
-    FT_F26Dot6  control_value_cutin;
 
 
-    control_value_cutin = exc->GS.control_value_cutin;
-    cvtEntry            = (FT_ULong)args[1];
-    point               = (FT_UShort)args[0];
-
-#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 */
+    cvtEntry = (FT_ULong)args[1];
+    point    = (FT_UShort)args[0];
 
     if ( BOUNDS( point,     exc->zp0.n_points ) ||
          BOUNDSL( cvtEntry, exc->cvtSize )      )
@@ -6035,7 +6049,7 @@
         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->GS.freeVector.y );
       exc->zp0.cur[point]   = exc->zp0.org[point];
     }
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
@@ -6051,9 +6065,19 @@
 
     if ( ( exc->opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
     {
+      FT_F26Dot6  control_value_cutin = exc->GS.control_value_cutin;
       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 );
@@ -6065,14 +6089,10 @@
       if ( SUBPIXEL_HINTING_INFINALITY &&
            exc->ignore_x_mode          &&
            exc->GS.freeVector.x != 0   )
-        distance = Round_None( exc,
-                               distance,
-                               exc->tt_metrics.compensations[0] );
+        distance = Round_None( exc, distance, 3 );
       else
 #endif
-        distance = exc->func_round( exc,
-                                    distance,
-                                    exc->tt_metrics.compensations[0] );
+        distance = exc->func_round( exc, distance, 3 );
     }
 
     exc->func_move( exc, &exc->zp0, point, SUB_LONG( distance, org_dist ) );
@@ -6094,19 +6114,9 @@
             FT_Long*        args )
   {
     FT_UShort   point = 0;
-    FT_F26Dot6  org_dist, distance, minimum_distance;
+    FT_F26Dot6  org_dist, distance;
 
 
-    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 */
-
     point = (FT_UShort)args[0];
 
     if ( BOUNDS( point,       exc->zp1.n_points ) ||
@@ -6179,27 +6189,29 @@
       if ( SUBPIXEL_HINTING_INFINALITY &&
            exc->ignore_x_mode          &&
            exc->GS.freeVector.x != 0   )
-        distance = Round_None(
-                     exc,
-                     org_dist,
-                     exc->tt_metrics.compensations[exc->opcode & 3] );
+        distance = Round_None( exc, org_dist, exc->opcode & 3 );
       else
 #endif
-        distance = exc->func_round(
-                     exc,
-                     org_dist,
-                     exc->tt_metrics.compensations[exc->opcode & 3] );
+        distance = exc->func_round( exc, org_dist, exc->opcode & 3 );
     }
     else
-      distance = Round_None(
-                   exc,
-                   org_dist,
-                   exc->tt_metrics.compensations[exc->opcode & 3] );
+      distance = Round_None( exc, org_dist, exc->opcode & 3 );
 
     /* minimum distance flag */
 
     if ( ( exc->opcode & 8 ) != 0 )
     {
+      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 )
@@ -6243,30 +6255,13 @@
     FT_F26Dot6  cvt_dist,
                 distance,
                 cur_dist,
-                org_dist,
-                control_value_cutin,
-                minimum_distance;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    FT_Int      B1           = 0; /* pacify compiler */
-    FT_Int      B2           = 0;
-    FT_Bool     reverse_move = FALSE;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+                org_dist;
 
     FT_F26Dot6  delta;
 
 
-    minimum_distance    = exc->GS.minimum_distance;
-    control_value_cutin = exc->GS.control_value_cutin;
-    point               = (FT_UShort)args[0];
-    cvtEntry            = (FT_ULong)( ADD_LONG( args[1], 1 ) );
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                        &&
-         exc->ignore_x_mode                                 &&
-         exc->GS.freeVector.x != 0                          &&
-         !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-      control_value_cutin = minimum_distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+    point    = (FT_UShort)args[0];
+    cvtEntry = (FT_ULong)( ADD_LONG( args[1], 1 ) );
 
     /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
 
@@ -6302,12 +6297,14 @@
     /* twilight points (confirmed by Greg Hitchcock)   */
     if ( exc->GS.gep1 == 0 )
     {
-      exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
-                              TT_MulFix14( cvt_dist,
-                                           exc->GS.freeVector.x );
-      exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
-                              TT_MulFix14( cvt_dist,
-                                           exc->GS.freeVector.y );
+      exc->zp1.org[point].x = ADD_LONG(
+                                exc->zp0.org[exc->GS.rp0].x,
+                                TT_MulFix14( cvt_dist,
+                                             exc->GS.freeVector.x ) );
+      exc->zp1.org[point].y = ADD_LONG(
+                                exc->zp0.org[exc->GS.rp0].y,
+                                TT_MulFix14( cvt_dist,
+                                             exc->GS.freeVector.y ) );
       exc->zp1.cur[point]   = exc->zp1.org[point];
     }
 
@@ -6319,22 +6316,9 @@
     if ( exc->GS.auto_flip )
     {
       if ( ( org_dist ^ cvt_dist ) < 0 )
-        cvt_dist = -cvt_dist;
+        cvt_dist = NEG_LONG( cvt_dist );
     }
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                               &&
-         exc->ignore_x_mode                                        &&
-         exc->GS.freeVector.y != 0                                 &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
-    {
-      if ( cur_dist < -64 )
-        cvt_dist -= 16;
-      else if ( cur_dist > 64 && cur_dist < 84 )
-        cvt_dist += 32;
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* control value cut-in and round */
 
     if ( ( exc->opcode & 4 ) != 0 )
@@ -6344,6 +6328,9 @@
 
       if ( exc->GS.gep0 == exc->GS.gep1 )
       {
+        FT_F26Dot6  control_value_cutin = exc->GS.control_value_cutin;
+
+
         /* XXX: According to Greg Hitchcock, the following wording is */
         /*      the right one:                                        */
         /*                                                            */
@@ -6364,10 +6351,7 @@
           cvt_dist = org_dist;
       }
 
-      distance = exc->func_round(
-                   exc,
-                   cvt_dist,
-                   exc->tt_metrics.compensations[exc->opcode & 3] );
+      distance = exc->func_round( exc, cvt_dist, exc->opcode & 3 );
     }
     else
     {
@@ -6378,6 +6362,22 @@
            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 );
@@ -6387,16 +6387,24 @@
       }
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
-      distance = Round_None(
-                   exc,
-                   cvt_dist,
-                   exc->tt_metrics.compensations[exc->opcode & 3] );
+      distance = Round_None( exc, cvt_dist, exc->opcode & 3 );
     }
 
     /* minimum distance test */
 
     if ( ( exc->opcode & 8 ) != 0 )
     {
+      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 )
@@ -6410,60 +6418,51 @@
     }
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( 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->ignore_x_mode                                          &&
-           exc->GS.freeVector.y != 0                                   &&
-           ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+      if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
         distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
 
-      if ( exc->ignore_x_mode                                      &&
-           exc->GS.freeVector.y != 0                               &&
-           ( exc->opcode & 16 ) == 0                               &&
+      if ( ( exc->opcode & 16 ) == 0                               &&
            ( exc->opcode & 8 ) == 0                                &&
            ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
         distance += 64;
-    }
-#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 ) );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY )
-    {
       B2 = exc->zp1.cur[point].y;
 
       /* Reverse move if necessary */
-      if ( exc->ignore_x_mode )
-      {
-        if ( exc->face->sph_compatibility_mode &&
-             exc->GS.freeVector.y != 0         &&
+      if ( ( exc->face->sph_compatibility_mode &&
              ( B1 & 63 ) == 0                  &&
-             ( B2 & 63 ) != 0                  )
-          reverse_move = TRUE;
-
-        if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-             exc->GS.freeVector.y != 0                                  &&
-             ( B2 & 63 ) != 0                                           &&
-             ( B1 & 63 ) != 0                                           )
-          reverse_move = TRUE;
-      }
-
-      if ( reverse_move )
+             ( 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 ) );
+
   Fail:
     exc->GS.rp1 = exc->GS.rp0;
 
@@ -6872,7 +6871,7 @@
 
 
   static void
-  _iup_worker_shift( IUP_Worker  worker,
+  iup_worker_shift_( IUP_Worker  worker,
                      FT_UInt     p1,
                      FT_UInt     p2,
                      FT_UInt     p )
@@ -6894,7 +6893,7 @@
 
 
   static void
-  _iup_worker_interpolate( IUP_Worker  worker,
+  iup_worker_interpolate_( IUP_Worker  worker,
                            FT_UInt     p1,
                            FT_UInt     p2,
                            FT_UInt     ref1,
@@ -7088,7 +7087,7 @@
         {
           if ( ( exc->pts.tags[point] & mask ) != 0 )
           {
-            _iup_worker_interpolate( &V,
+            iup_worker_interpolate_( &V,
                                      cur_touched + 1,
                                      point - 1,
                                      cur_touched,
@@ -7100,17 +7099,17 @@
         }
 
         if ( cur_touched == first_touched )
-          _iup_worker_shift( &V, first_point, end_point, cur_touched );
+          iup_worker_shift_( &V, first_point, end_point, cur_touched );
         else
         {
-          _iup_worker_interpolate( &V,
+          iup_worker_interpolate_( &V,
                                    (FT_UShort)( cur_touched + 1 ),
                                    end_point,
                                    cur_touched,
                                    first_touched );
 
           if ( first_touched > 0 )
-            _iup_worker_interpolate( &V,
+            iup_worker_interpolate_( &V,
                                      first_point,
                                      first_touched - 1,
                                      cur_touched,
@@ -7136,10 +7135,9 @@
     FT_UShort  A;
     FT_ULong   C, P;
     FT_Long    B;
+
+
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    FT_UShort  B1, B2;
-
-
     if ( SUBPIXEL_HINTING_INFINALITY                              &&
          exc->ignore_x_mode                                       &&
          exc->iup_called                                          &&
@@ -7220,6 +7218,9 @@
             /* 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;
 
@@ -7671,7 +7672,7 @@
   Ins_UNKNOWN( TT_ExecContext  exc )
   {
     TT_DefRecord*  def   = exc->IDefs;
-    TT_DefRecord*  limit = def + exc->numIDefs;
+    TT_DefRecord*  limit = FT_OFFSET( def, exc->numIDefs );
 
 
     for ( ; def < limit; def++ )
@@ -7758,35 +7759,6 @@
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    exc->iup_called = FALSE;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    /*
-     * Toggle backward compatibility according to what font wants, except
-     * when
-     *
-     * 1) we have a `tricky' font that heavily relies on the interpreter to
-     *    render glyphs correctly, for example DFKai-SB, or
-     * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested.
-     *
-     * In those cases, backward compatibility needs to be turned off to get
-     * correct rendering.  The rendering is then completely up to the
-     * font's programming.
-     *
-     */
-    if ( SUBPIXEL_HINTING_MINIMAL          &&
-         exc->subpixel_hinting_lean        &&
-         !FT_IS_TRICKY( &exc->face->root ) )
-      exc->backward_compatibility = !( exc->GS.instruct_control & 4 );
-    else
-      exc->backward_compatibility = FALSE;
-
-    exc->iupx_called = FALSE;
-    exc->iupy_called = FALSE;
-#endif
-
     /* We restrict the number of twilight points to a reasonable,     */
     /* heuristic value to avoid slow execution of malformed bytecode. */
     num_twilight_points = FT_MAX( 30,
@@ -7796,8 +7768,8 @@
       if ( num_twilight_points > 0xFFFFU )
         num_twilight_points = 0xFFFFU;
 
-      FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n"
-                  "           from %d to the more reasonable value %d\n",
+      FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" ));
+      FT_TRACE5(( "           from %d to the more reasonable value %ld\n",
                   exc->twilight.n_points,
                   num_twilight_points ));
       exc->twilight.n_points = (FT_UShort)num_twilight_points;
@@ -7823,7 +7795,7 @@
                                   FT_MAX( 50,
                                           exc->cvtSize / 10 );
     else
-      exc->loopcall_counter_max = 300 + 8 * exc->cvtSize;
+      exc->loopcall_counter_max = 300 + 22 * exc->cvtSize;
 
     /* as a protection against an unreasonable number of CVT entries  */
     /* we assume at most 100 control values per glyph for the counter */
@@ -7832,11 +7804,11 @@
       exc->loopcall_counter_max = 100 * (FT_ULong)exc->face->root.num_glyphs;
 
     FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL"
-                " to %d\n", exc->loopcall_counter_max ));
+                " to %ld\n", exc->loopcall_counter_max ));
 
     exc->neg_jump_counter_max = exc->loopcall_counter_max;
     FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps"
-                " to %d\n", exc->neg_jump_counter_max ));
+                " to %ld\n", exc->neg_jump_counter_max ));
 
     /* set PPEM and CVT functions */
     exc->tt_metrics.ratio = 0;
@@ -7857,14 +7829,26 @@
       exc->func_move_cvt  = Move_CVT;
     }
 
+    exc->iniRange    = exc->curRange;
+
     Compute_Funcs( exc );
     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;
+#endif
+
     do
     {
       exc->opcode = exc->code[exc->IP];
 
 #ifdef FT_DEBUG_LEVEL_TRACE
+      if ( ft_trace_levels[trace_ttinterp] >= 6 )
       {
         FT_Long  cnt = FT_MIN( 8, exc->top );
         FT_Long  n;
@@ -7873,14 +7857,14 @@
         /* if tracing level is 7, show current code position */
         /* and the first few stack elements also             */
         FT_TRACE6(( "  " ));
-        FT_TRACE7(( "%06d ", exc->IP ));
-        FT_TRACE6(( opcode_name[exc->opcode] + 2 ));
+        FT_TRACE7(( "%06ld ", exc->IP ));
+        FT_TRACE6(( "%s", opcode_name[exc->opcode] + 2 ));
         FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A'
                               ? 2
                               : 12 - ( *opcode_name[exc->opcode] - '0' ),
                               "#" ));
         for ( n = 1; n <= cnt; n++ )
-          FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
+          FT_TRACE7(( " %ld", exc->stack[exc->top - n] ));
         FT_TRACE6(( "\n" ));
       }
 #endif /* FT_DEBUG_LEVEL_TRACE */
@@ -8523,7 +8507,7 @@
         case FT_ERR( Invalid_Opcode ):
           {
             TT_DefRecord*  def   = exc->IDefs;
-            TT_DefRecord*  limit = def + exc->numIDefs;
+            TT_DefRecord*  limit = FT_OFFSET( def, exc->numIDefs );
 
 
             for ( ; def < limit; def++ )
@@ -8582,7 +8566,10 @@
       /* increment instruction counter and check if we didn't */
       /* run this program for too long (e.g. infinite loops). */
       if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES )
-        return FT_THROW( Execution_Too_Long );
+      {
+        exc->error = FT_THROW( Execution_Too_Long );
+        goto LErrorLabel_;
+      }
 
     LSuiteLabel_:
       if ( exc->IP >= exc->codeSize )
@@ -8598,9 +8585,10 @@
     } while ( !exc->instruction_trap );
 
   LNo_Error_:
-    FT_TRACE4(( "  %d instruction%s executed\n",
+    FT_TRACE4(( "  %ld instruction%s executed\n",
                 ins_counter,
                 ins_counter == 1 ? "" : "s" ));
+
     return FT_Err_Ok;
 
   LErrorCodeOverflow_:
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 172cdd0..c54c053 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
  *
  *   TrueType bytecode interpreter (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,7 +19,6 @@
 #ifndef TTINTERP_H_
 #define TTINTERP_H_
 
-#include <ft2build.h>
 #include "ttobjs.h"
 
 
@@ -52,7 +51,7 @@
   typedef FT_F26Dot6
   (*TT_Round_Func)( TT_ExecContext  exc,
                     FT_F26Dot6      distance,
-                    FT_F26Dot6      compensation );
+                    FT_Int          color );
 
   /* Point displacement along the freedom vector routine */
   typedef void
@@ -145,37 +144,41 @@
    *
    * The main structure for the interpreter which collects all necessary
    * variables and states.
+   *
+   * Members that are initialized by `TT_Load_Context` are marked with '!'.
+   * Members that are initialized by `TT_Run_Context` are marked with '@'.
    */
   typedef struct  TT_ExecContextRec_
   {
-    TT_Face            face;
-    TT_Size            size;
+    TT_Face            face;       /* ! */
+    TT_Size            size;       /* ! */
     FT_Memory          memory;
 
     /* instructions state */
 
     FT_Error           error;      /* last execution error */
 
-    FT_Long            top;        /* top of exec. stack   */
+    FT_Long            top;        /* @ top of exec. stack */
 
-    FT_Long            stackSize;  /* size of exec. stack  */
-    FT_Long*           stack;      /* current exec. stack  */
+    FT_Long            stackSize;  /* ! size of exec. stack */
+    FT_Long*           stack;      /* ! current exec. stack */
 
     FT_Long            args;
-    FT_Long            new_top;    /* new top after exec.  */
+    FT_Long            new_top;    /* new top after exec. */
 
-    TT_GlyphZoneRec    zp0,        /* zone records */
-                       zp1,
-                       zp2,
-                       pts,
-                       twilight;
+    TT_GlyphZoneRec    zp0,        /* @! zone records */
+                       zp1,        /* @!              */
+                       zp2,        /* @!              */
+                       pts,        /*  !              */
+                       twilight;   /*  !              */
 
-    FT_Long            pointSize;  /* in 26.6 format */
-    FT_Size_Metrics    metrics;
-    TT_Size_Metrics    tt_metrics; /* size metrics */
+    FT_Long            pointSize;  /* ! in 26.6 format */
+    FT_Size_Metrics    metrics;    /* !                */
+    TT_Size_Metrics    tt_metrics; /* ! size metrics   */
 
-    TT_GraphicsState   GS;         /* current graphics state */
+    TT_GraphicsState   GS;         /* !@ current graphics state */
 
+    FT_Int             iniRange;  /* initial code range number   */
     FT_Int             curRange;  /* current code range number   */
     FT_Byte*           code;      /* current code range          */
     FT_Long            IP;        /* current instruction pointer */
@@ -186,43 +189,47 @@
 
     FT_Bool            step_ins;  /* true if the interpreter must */
                                   /* increment IP after ins. exec */
-    FT_ULong           cvtSize;
-    FT_Long*           cvt;
+    FT_ULong           cvtSize;   /* ! */
+    FT_Long*           cvt;       /* ! */
+    FT_ULong           glyfCvtSize;
+    FT_Long*           glyfCvt;   /* cvt working copy for glyph */
 
-    FT_UInt            glyphSize; /* glyph instructions buffer size */
-    FT_Byte*           glyphIns;  /* glyph instructions buffer */
+    FT_UInt            glyphSize; /* ! glyph instructions buffer size */
+    FT_Byte*           glyphIns;  /* ! glyph instructions buffer      */
 
-    FT_UInt            numFDefs;  /* number of function defs         */
-    FT_UInt            maxFDefs;  /* maximum number of function defs */
-    TT_DefArray        FDefs;     /* table of FDefs entries          */
+    FT_UInt            numFDefs;  /* ! number of function defs         */
+    FT_UInt            maxFDefs;  /* ! maximum number of function defs */
+    TT_DefArray        FDefs;     /*   table of FDefs entries          */
 
-    FT_UInt            numIDefs;  /* number of instruction defs */
-    FT_UInt            maxIDefs;  /* maximum number of ins defs */
-    TT_DefArray        IDefs;     /* table of IDefs entries     */
+    FT_UInt            numIDefs;  /* ! number of instruction defs */
+    FT_UInt            maxIDefs;  /* ! maximum number of ins defs */
+    TT_DefArray        IDefs;     /*   table of IDefs entries     */
 
-    FT_UInt            maxFunc;   /* maximum function index     */
-    FT_UInt            maxIns;    /* maximum instruction index  */
+    FT_UInt            maxFunc;   /* ! maximum function index    */
+    FT_UInt            maxIns;    /* ! maximum instruction index */
 
-    FT_Int             callTop,    /* top of call stack during execution */
-                       callSize;   /* size of call stack */
-    TT_CallStack       callStack;  /* call stack */
+    FT_Int             callTop,    /* @ top of call stack during execution */
+                       callSize;   /*   size of call stack                 */
+    TT_CallStack       callStack;  /*   call stack                         */
 
     FT_UShort          maxPoints;    /* capacity of this context's `pts' */
     FT_Short           maxContours;  /* record, expressed in points and  */
                                      /* contours.                        */
 
-    TT_CodeRangeTable  codeRangeTable;  /* table of valid code ranges */
-                                        /* useful for the debugger   */
+    TT_CodeRangeTable  codeRangeTable;  /* ! table of valid code ranges */
+                                        /*   useful for the debugger    */
 
-    FT_UShort          storeSize;  /* size of current storage */
-    FT_Long*           storage;    /* storage area            */
+    FT_UShort          storeSize;    /* ! size of current storage */
+    FT_Long*           storage;      /* ! storage area            */
+    FT_UShort          glyfStoreSize;
+    FT_Long*           glyfStorage;  /* storage working copy for glyph */
 
     FT_F26Dot6         period;     /* values used for the */
     FT_F26Dot6         phase;      /* `SuperRounding'     */
     FT_F26Dot6         threshold;
 
-    FT_Bool            instruction_trap; /* If `True', the interpreter will */
-                                         /* exit after each instruction     */
+    FT_Bool            instruction_trap; /* ! If `True', the interpreter   */
+                                         /*   exits after each instruction */
 
     TT_GraphicsState   default_GS;       /* graphics state resulting from   */
                                          /* the prep program                */
@@ -239,7 +246,7 @@
                        func_dualproj,  /* current dual proj. function */
                        func_freeProj;  /* current freedom proj. func  */
 
-    TT_Move_Func       func_move;      /* current point move function */
+    TT_Move_Func       func_move;      /* current point move function     */
     TT_Move_Func       func_move_orig; /* move original position function */
 
     TT_Cur_Ppem_Func   func_cur_ppem;  /* get current proj. ppem value  */
@@ -352,7 +359,7 @@
      *     https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
      *
      * [3] Beat Stamm describes it in more detail:
-     *     http://www.beatstamm.com/typography/RTRCh4.htm#Sec12
+     *     http://rastertragedy.com/RTRCh4.htm#Sec12.
      *
      * [4] The list of `native ClearType' fonts is small at the time of this
      *     writing; I found the following on a Windows 10 Update 1511
@@ -470,16 +477,15 @@
    *   TT_New_Context
    *
    * @Description:
-   *   Queries the face context for a given font.  Note that there is
-   *   now a _single_ execution context in the TrueType driver which is
-   *   shared among faces.
+   *   Create a `TT_ExecContext`.  Note that there is now an execution
+   *   context per `TT_Size` that is not shared among faces.
    *
    * @Input:
-   *   face ::
-   *     A handle to the source face object.
+   *   driver ::
+   *     A handle to the driver, used for memory allocation.
    *
    * @Return:
-   *   A handle to the execution context.  Initialized for `face'.
+   *   A handle to a new empty execution context.
    *
    * @Note:
    *   Only the glyph loader and debugger should call this function.
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index df6c72a..4a8873f 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
  *
  *   Objects manager (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_INTERNAL_SFNT_H
-#include FT_DRIVER_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
+#include <freetype/internal/sfnt.h>
+#include <freetype/ftdriver.h>
 
 #include "ttgload.h"
 #include "ttpload.h"
@@ -43,7 +42,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttobjs
+#define FT_COMPONENT  ttobjs
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
@@ -141,18 +140,42 @@
 
     return error;
   }
-#endif /* TT_USE_BYTECODE_INTERPRETER */
+
+
+  /*
+   * Fonts embedded in PDFs are made unique by prepending randomization
+   * prefixes to their names: as defined in Section 5.5.3, 'Font Subsets',
+   * of the PDF Reference, they consist of 6 uppercase letters followed by
+   * the `+` sign.  For safety, we do not skip prefixes violating this rule.
+   */
+
+  static const FT_String*
+  tt_skip_pdffont_random_tag( const FT_String*  name )
+  {
+    unsigned int  i;
+
+
+    if ( ft_strlen( name ) < 8 || name[6] != '+' )
+      return name;
+
+    for ( i = 0; i < 6; i++ )
+      if ( !ft_isupper( name[i] ) )
+        return name;
+
+    FT_TRACE7(( "name without randomization tag: %s\n", name + 7 ));
+    return name + 7;
+  }
 
 
   /* Compare the face with a list of well-known `tricky' fonts. */
   /* This list shall be expanded as we find more of them.       */
 
   static FT_Bool
-  tt_check_trickyness_family( FT_String*  name )
+  tt_check_trickyness_family( const FT_String*  name )
   {
 
 #define TRICK_NAMES_MAX_CHARACTERS  19
-#define TRICK_NAMES_COUNT           26
+#define TRICK_NAMES_COUNT           20
 
     static const char trick_names[TRICK_NAMES_COUNT]
                                  [TRICK_NAMES_MAX_CHARACTERS + 1] =
@@ -172,22 +195,28 @@
       "DFGirl-W6-WIN-BF",   /* dftt-h6.ttf; version 1.00, 1993 */
       "DFGothic-EB",        /* DynaLab Inc. 1992-1995 */
       "DFGyoSho-Lt",        /* DynaLab Inc. 1992-1995 */
-      "DFHei-Md-HK-BF",     /* maybe DynaLab Inc. */
+      "DFHei",              /* DynaLab Inc. 1992-1995 [DFHei-Bd-WIN-HK-BF] */
+                            /* covers "DFHei-Md-HK-BF", maybe DynaLab Inc. */
+
       "DFHSGothic-W5",      /* DynaLab Inc. 1992-1995 */
       "DFHSMincho-W3",      /* DynaLab Inc. 1992-1995 */
       "DFHSMincho-W7",      /* DynaLab Inc. 1992-1995 */
       "DFKaiSho-SB",        /* dfkaisb.ttf */
-      "DFKaiShu",
-      "DFKaiShu-Md-HK-BF",  /* maybe DynaLab Inc. */
+      "DFKaiShu",           /* covers "DFKaiShu-Md-HK-BF", maybe DynaLab Inc. */
       "DFKai-SB",           /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */
-      "DFMing-Bd-HK-BF",    /* maybe DynaLab Inc. */
+
+      "DFMing",             /* DynaLab Inc. 1992-1995 [DFMing-Md-WIN-HK-BF] */
+                            /* covers "DFMing-Bd-HK-BF", maybe DynaLab Inc. */
+
       "DLC",                /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */
                             /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */
-      "DLCHayMedium",       /* dftt-b5.ttf; version 1.00, 1993 */
-      "DLCHayBold",         /* dftt-b7.ttf; version 1.00, 1993 */
-      "DLCKaiMedium",       /* dftt-k5.ttf; version 1.00, 1992 */
-      "DLCLiShu",           /* dftt-l5.ttf; version 1.00, 1992 */
-      "DLCRoundBold",       /* dftt-r7.ttf; version 1.00, 1993 */
+                            /* covers following */
+                            /* "DLCHayMedium", dftt-b5.ttf; version 1.00, 1993 */
+                            /* "DLCHayBold",   dftt-b7.ttf; version 1.00, 1993 */
+                            /* "DLCKaiMedium", dftt-k5.ttf; version 1.00, 1992 */
+                            /* "DLCLiShu",     dftt-l5.ttf; version 1.00, 1992 */
+                            /* "DLCRoundBold", dftt-r7.ttf; version 1.00, 1993 */
+
       "HuaTianKaiTi?",      /* htkt2.ttf */
       "HuaTianSongTi?",     /* htst3.ttf */
       "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */
@@ -200,10 +229,12 @@
     };
 
     int  nn;
+    const FT_String*  name_without_tag;
 
 
+    name_without_tag = tt_skip_pdffont_random_tag( name );
     for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
-      if ( ft_strstr( name, trick_names[nn] ) )
+      if ( ft_strstr( name_without_tag, trick_names[nn] ) )
         return TRUE;
 
     return FALSE;
@@ -278,7 +309,7 @@
   tt_check_trickyness_sfnt_ids( TT_Face  face )
   {
 #define TRICK_SFNT_IDS_PER_FACE   3
-#define TRICK_SFNT_IDS_NUM_FACES  29
+#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] = {
@@ -431,6 +462,16 @@
         { 0x00170003UL, 0x00000060UL }, /* cvt  */
         { 0xDBB4306EUL, 0x000058AAUL }, /* fpgm */
         { 0xD643482AUL, 0x00000035UL }  /* prep */
+      },
+        { /* DFHei-Bd-WIN-HK-BF, issue #1087 */
+        { 0x1269EB58UL, 0x00000350UL }, /* cvt  */
+        { 0x5CD5957AUL, 0x00006A4EUL }, /* fpgm */
+        { 0xF758323AUL, 0x00000380UL }  /* prep */
+      },
+        { /* DFMing-Md-WIN-HK-BF, issue #1087 */
+        { 0x122FEB0BUL, 0x00000350UL }, /* cvt  */
+        { 0x7F10919AUL, 0x000070A9UL }, /* fpgm */
+        { 0x7CD7E7B7UL, 0x0000025CUL }  /* prep */
       }
     };
 
@@ -511,17 +552,27 @@
     /* For first, check the face name for quick check. */
     if ( face->family_name                               &&
          tt_check_trickyness_family( face->family_name ) )
+    {
+      FT_TRACE3(( "found as a tricky font"
+                  " by its family name: %s\n", face->family_name ));
       return TRUE;
+    }
 
     /* Type42 fonts may lack `name' tables, we thus try to identify */
     /* tricky fonts by checking the checksums of Type42-persistent  */
     /* sfnt tables (`cvt', `fpgm', and `prep').                     */
     if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
+    {
+      FT_TRACE3(( "found as a tricky font"
+                  " by its cvt/fpgm/prep table checksum\n" ));
       return TRUE;
+    }
 
     return FALSE;
   }
 
+#endif /* TT_USE_BYTECODE_INTERPRETER */
+
 
   /* Check whether `.notdef' is the only glyph in the `loca' table. */
   static FT_Bool
@@ -667,14 +718,17 @@
     if ( error )
       goto Exit;
 
+#ifdef TT_USE_BYTECODE_INTERPRETER
     if ( tt_check_trickyness( ttface ) )
       ttface->face_flags |= FT_FACE_FLAG_TRICKY;
+#endif
 
     error = tt_face_load_hdmx( face, stream );
     if ( error )
       goto Exit;
 
-    if ( FT_IS_SCALABLE( ttface ) )
+    if ( FT_IS_SCALABLE( ttface ) ||
+         FT_HAS_SBIX( ttface )    )
     {
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       if ( !ttface->internal->incremental_interface )
@@ -713,8 +767,8 @@
              tt_check_single_notdef( ttface ) )
         {
           FT_TRACE5(( "tt_face_init:"
-                      " Only the `.notdef' glyph has an outline.\n"
-                      "             "
+                      " Only the `.notdef' glyph has an outline.\n" ));
+          FT_TRACE5(( "             "
                       " Resetting scalable flag to FALSE.\n" ));
 
           ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
@@ -937,7 +991,22 @@
     TT_Face         face = (TT_Face)size->root.face;
     TT_ExecContext  exec;
     FT_Error        error;
+    FT_UInt         i;
 
+    /* unscaled CVT values are already stored in 26.6 format */
+    FT_Fixed  scale = size->ttmetrics.scale >> 6;
+
+
+    /* Scale the cvt values to the new ppem.            */
+    /* By default, we use the y ppem value for scaling. */
+    FT_TRACE6(( "CVT values:\n" ));
+    for ( i = 0; i < size->cvt_size; i++ )
+    {
+      size->cvt[i] = FT_MulFix( face->cvt[i], scale );
+      FT_TRACE6(( "  %3d: %f (%f)\n",
+                  i, (double)face->cvt[i] / 64, (double)size->cvt[i] / 64 ));
+    }
+    FT_TRACE6(( "\n" ));
 
     exec = size->context;
 
@@ -1094,11 +1163,17 @@
       tt_metrics->rotated   = FALSE;
       tt_metrics->stretched = FALSE;
 
-      /* set default engine compensation */
-      tt_metrics->compensations[0] = 0;   /* gray     */
-      tt_metrics->compensations[1] = 0;   /* black    */
-      tt_metrics->compensations[2] = 0;   /* white    */
-      tt_metrics->compensations[3] = 0;   /* reserved */
+      /* Set default engine compensation.  Value 3 is not described */
+      /* in the OpenType specification (as of Mai 2019), but Greg   */
+      /* says that MS handles it the same as `gray'.                */
+      /*                                                            */
+      /* The Apple specification says that the compensation for     */
+      /* `gray' is always zero.  FreeType doesn't do any            */
+      /* compensation at all.                                       */
+      tt_metrics->compensations[0] = 0;   /* gray  */
+      tt_metrics->compensations[1] = 0;   /* black */
+      tt_metrics->compensations[2] = 0;   /* white */
+      tt_metrics->compensations[3] = 0;   /* zero  */
     }
 
     /* allocate function defs, instruction defs, cvt, and storage area */
@@ -1170,17 +1245,11 @@
     /* rescale CVT when needed */
     if ( size->cvt_ready < 0 )
     {
-      FT_UInt  i;
-      TT_Face  face = (TT_Face)size->root.face;
+      FT_UShort  i;
 
 
-      /* Scale the cvt values to the new ppem.          */
-      /* We use by default the y ppem to scale the CVT. */
-      for ( i = 0; i < size->cvt_size; i++ )
-        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
-
       /* all twilight points are originally zero */
-      for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
+      for ( i = 0; i < size->twilight.n_points; i++ )
       {
         size->twilight.org[i].x = 0;
         size->twilight.org[i].y = 0;
@@ -1189,7 +1258,7 @@
       }
 
       /* clear storage area */
-      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
+      for ( i = 0; i < size->storage_size; i++ )
         size->storage[i] = 0;
 
       size->GS = tt_default_graphics_state;
@@ -1367,6 +1436,8 @@
       size->ttmetrics.y_ratio = 0x10000L;
     }
 
+    size->widthp = tt_face_get_device_metrics( face, size_metrics->x_ppem, 0 );
+
     size->metrics = size_metrics;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index dcff3f7..bc6fbe7 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
  *
  *   Objects manager (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define TTOBJS_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/tttypes.h>
 
 
 FT_BEGIN_HEADER
@@ -283,6 +282,8 @@
 
     TT_Size_Metrics    ttmetrics;
 
+    FT_Byte*           widthp;          /* glyph widths from the hdmx table */
+
     FT_ULong           strike_index;      /* 0xFFFFFFFF to indicate invalid */
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index f7935cf..e08bf30 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
  *
  *   TrueType-specific tables loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_TAGS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/tttags.h>
 
 #include "ttpload.h"
 
@@ -38,7 +37,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_ttpload
+#define FT_COMPONENT  ttpload
 
 
   /**************************************************************************
@@ -99,36 +98,23 @@
       goto Exit;
     }
 
-    if ( face->header.Index_To_Loc_Format != 0 )
-    {
-      shift = 2;
+    shift = face->header.Index_To_Loc_Format != 0 ? 2 : 1;
 
-      if ( table_len >= 0x40000L )
-      {
-        FT_TRACE2(( "table too large\n" ));
-        table_len = 0x3FFFFL;
-      }
-      face->num_locations = table_len >> shift;
-    }
-    else
+    if ( table_len > 0x10000UL << shift )
     {
-      shift = 1;
-
-      if ( table_len >= 0x20000L )
-      {
-        FT_TRACE2(( "table too large\n" ));
-        table_len = 0x1FFFFL;
-      }
-      face->num_locations = table_len >> shift;
+      FT_TRACE2(( "table too large\n" ));
+      table_len = 0x10000UL << shift;
     }
 
+    face->num_locations = table_len >> shift;
+
     if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 )
     {
-      FT_TRACE2(( "glyph count mismatch!  loca: %d, maxp: %d\n",
+      FT_TRACE2(( "glyph count mismatch!  loca: %ld, maxp: %ld\n",
                   face->num_locations - 1, face->root.num_glyphs ));
 
       /* we only handle the case where `maxp' gives a larger value */
-      if ( face->num_locations <= (FT_ULong)face->root.num_glyphs )
+      if ( face->num_locations < (FT_ULong)face->root.num_glyphs + 1 )
       {
         FT_ULong  new_loca_len =
                     ( (FT_ULong)face->root.num_glyphs + 1 ) << shift;
@@ -165,7 +151,7 @@
           face->num_locations = (FT_ULong)face->root.num_glyphs + 1;
           table_len           = new_loca_len;
 
-          FT_TRACE2(( "adjusting num_locations to %d\n",
+          FT_TRACE2(( "adjusting num_locations to %ld\n",
                       face->num_locations ));
         }
         else
@@ -173,7 +159,7 @@
           face->root.num_glyphs = face->num_locations
                                     ? (FT_Long)face->num_locations - 1 : 0;
 
-          FT_TRACE2(( "adjusting num_glyphs to %d\n",
+          FT_TRACE2(( "adjusting num_glyphs to %ld\n",
                       face->root.num_glyphs ));
         }
       }
@@ -238,10 +224,11 @@
     if ( pos1 > face->glyf_len )
     {
       FT_TRACE1(( "tt_face_get_location:"
-                  " too large offset (0x%08lx) found for glyph index %ld,\n"
-                  "                     "
+                  " too large offset (0x%08lx) found for glyph index %d,\n",
+                  pos1, gindex ));
+      FT_TRACE1(( "                     "
                   " exceeding the end of `glyf' table (0x%08lx)\n",
-                  pos1, gindex, face->glyf_len ));
+                  face->glyf_len ));
       *asize = 0;
       return 0;
     }
@@ -252,19 +239,21 @@
       if ( gindex == face->num_locations - 2 )
       {
         FT_TRACE1(( "tt_face_get_location:"
-                    " too large size (%ld bytes) found for glyph index %ld,\n"
-                    "                     "
+                    " 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",
-                    pos2 - pos1, gindex, face->glyf_len - pos1 ));
+                    face->glyf_len - pos1 ));
         pos2 = face->glyf_len;
       }
       else
       {
         FT_TRACE1(( "tt_face_get_location:"
-                    " too large offset (0x%08lx) found for glyph index %ld,\n"
-                    "                     "
+                    " too large offset (0x%08lx) found for glyph index %d,\n",
+                    pos2, gindex + 1 ));
+        FT_TRACE1(( "                     "
                     " exceeding the end of `glyf' table (0x%08lx)\n",
-                    pos2, gindex + 1, face->glyf_len ));
+                    face->glyf_len ));
         *asize = 0;
         return 0;
       }
@@ -345,19 +334,19 @@
 
     face->cvt_size = table_len / 2;
 
-    if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
+    if ( FT_QNEW_ARRAY( face->cvt, face->cvt_size ) )
       goto Exit;
 
     if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
       goto Exit;
 
     {
-      FT_Short*  cur   = face->cvt;
-      FT_Short*  limit = cur + face->cvt_size;
+      FT_Int32*  cur   = face->cvt;
+      FT_Int32*  limit = cur + face->cvt_size;
 
 
       for ( ; cur < limit; cur++ )
-        *cur = FT_GET_SHORT();
+        *cur = FT_GET_SHORT() * 64;
     }
 
     FT_FRAME_EXIT();
@@ -429,7 +418,7 @@
       if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
         goto Exit;
 
-      FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
+      FT_TRACE2(( "loaded, %12ld bytes\n", face->font_program_size ));
     }
 
   Exit:
@@ -492,7 +481,7 @@
       if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
         goto Exit;
 
-      FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
+      FT_TRACE2(( "loaded, %12ld bytes\n", face->cvt_program_size ));
     }
 
   Exit:
@@ -509,6 +498,14 @@
   }
 
 
+  FT_COMPARE_DEF( int )
+  compare_ppem( const void*  a,
+                const void*  b )
+  {
+    return **(FT_Byte**)a - **(FT_Byte**)b;
+  }
+
+
   /**************************************************************************
    *
    * @Function:
@@ -558,12 +555,6 @@
     num_records = FT_NEXT_USHORT( p );
     record_size = FT_NEXT_ULONG( p );
 
-    /* The maximum number of bytes in an hdmx device record is the */
-    /* maximum number of glyphs + 2; this is 0xFFFF + 2, thus      */
-    /* explaining why `record_size' is a long (which we read as    */
-    /* unsigned long for convenience).  In practice, two bytes are */
-    /* sufficient to hold the size value.                          */
-    /*                                                             */
     /* There are at least two fonts, HANNOM-A and HANNOM-B version */
     /* 2.0 (2005), which get this wrong: The upper two bytes of    */
     /* the size value are set to 0xFF instead of 0x00.  We catch   */
@@ -572,32 +563,46 @@
     if ( record_size >= 0xFFFF0000UL )
       record_size &= 0xFFFFU;
 
+    FT_TRACE2(( "Hdmx " ));
+
     /* The limit for `num_records' is a heuristic value. */
-    if ( num_records > 255              ||
-         ( num_records > 0            &&
-           ( record_size > 0x10001L ||
-             record_size < 4        ) ) )
+    if ( num_records > 255 || num_records == 0 )
     {
-      error = FT_THROW( Invalid_File_Format );
+      FT_TRACE2(( "with unreasonable %u records rejected\n", num_records ));
       goto Fail;
     }
 
-    if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
+    /* Out-of-spec tables are rejected.  The record size must be */
+    /* equal to the number of glyphs + 2 + 32-bit padding.       */
+    if ( (FT_Long)record_size != ( ( face->root.num_glyphs + 2 + 3 ) & ~3 ) )
+    {
+      FT_TRACE2(( "with record size off by %ld bytes rejected\n",
+                  (FT_Long)record_size -
+                    ( ( face->root.num_glyphs + 2 + 3 ) & ~3 ) ));
+      goto Fail;
+    }
+
+    if ( FT_QNEW_ARRAY( face->hdmx_records, num_records ) )
       goto Fail;
 
     for ( nn = 0; nn < num_records; nn++ )
     {
       if ( p + record_size > limit )
         break;
-
-      face->hdmx_record_sizes[nn] = p[0];
-      p                          += record_size;
+      face->hdmx_records[nn] = p;
+      p                     += record_size;
     }
 
+    /* The records must be already sorted by ppem but it does not */
+    /* hurt to make sure so that the binary search works later.   */
+    ft_qsort( face->hdmx_records, nn, sizeof ( FT_Byte* ), compare_ppem );
+
     face->hdmx_record_count = nn;
     face->hdmx_table_size   = table_size;
     face->hdmx_record_size  = record_size;
 
+    FT_TRACE2(( "%ux%lu loaded\n", num_records, record_size ));
+
   Exit:
     return error;
 
@@ -615,7 +620,7 @@
     FT_Memory  memory = stream->memory;
 
 
-    FT_FREE( face->hdmx_record_sizes );
+    FT_FREE( face->hdmx_records );
     FT_FRAME_RELEASE( face->hdmx_table );
   }
 
@@ -623,27 +628,34 @@
   /**************************************************************************
    *
    * Return the advance width table for a given pixel size if it is found
-   * in the font's `hdmx' table (if any).
+   * in the font's `hdmx' table (if any).  The records must be sorted for
+   * the binary search to work properly.
    */
   FT_LOCAL_DEF( FT_Byte* )
   tt_face_get_device_metrics( TT_Face  face,
                               FT_UInt  ppem,
                               FT_UInt  gindex )
   {
-    FT_UInt   nn;
-    FT_Byte*  result      = NULL;
-    FT_ULong  record_size = face->hdmx_record_size;
-    FT_Byte*  record      = face->hdmx_table + 8;
+    FT_UInt   min    = 0;
+    FT_UInt   max    = face->hdmx_record_count;
+    FT_UInt   mid;
+    FT_Byte*  result = NULL;
 
 
-    for ( nn = 0; nn < face->hdmx_record_count; nn++ )
-      if ( face->hdmx_record_sizes[nn] == ppem )
+    while ( min < max )
+    {
+      mid = ( min + max ) >> 1;
+
+      if ( face->hdmx_records[mid][0] > ppem )
+        max = mid;
+      else if ( face->hdmx_records[mid][0] < ppem )
+        min = mid + 1;
+      else
       {
-        gindex += 2;
-        if ( gindex < record_size )
-          result = record + nn * record_size + gindex;
+        result = face->hdmx_records[mid] + 2 + gindex;
         break;
       }
+    }
 
     return result;
   }
diff --git a/src/truetype/ttpload.h b/src/truetype/ttpload.h
index eef2695..939e02f 100644
--- a/src/truetype/ttpload.h
+++ b/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
  *
  *   TrueType-specific tables loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define TTPLOAD_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_TRUETYPE_TYPES_H
+#include <freetype/internal/tttypes.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
index 70e94e2..d811bee 100644
--- a/src/truetype/ttsubpix.c
+++ b/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
  *
  *   TrueType Subpixel Hinting.
  *
- * Copyright 2010-2018 by
+ * 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,
@@ -15,14 +15,13 @@
  *
  */
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_OUTLINE_H
-#include FT_DRIVER_H
+#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"
 
@@ -316,7 +315,7 @@
   static const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules
                               [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
   {
-    /* fix vwxyz thinness*/
+    /* fix vwxyz thinness */
     { "Consolas", 0, "", 0 },
     /* Fix thin middle stems */
     { "Core MS Legacy Fonts", 0, "Regular", 0 },
@@ -892,12 +891,12 @@
 #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;
+    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;
+    loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x
 
 
   FT_LOCAL_DEF( void )
diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h
index 2e10ea3..62af4c2 100644
--- a/src/truetype/ttsubpix.h
+++ b/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
  *
  *   TrueType Subpixel Hinting.
  *
- * Copyright 2010-2018 by
+ * 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,
@@ -19,7 +19,6 @@
 #ifndef TTSUBPIX_H_
 #define TTSUBPIX_H_
 
-#include <ft2build.h>
 #include "ttobjs.h"
 #include "ttinterp.h"
 
diff --git a/src/type1/Jamfile b/src/type1/Jamfile
deleted file mode 100644
index b94b7d0..0000000
--- a/src/type1/Jamfile
+++ /dev/null
@@ -1,35 +0,0 @@
-# FreeType 2 src/type1 Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) type1 ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = t1afm
-               t1driver
-               t1gload
-               t1load
-               t1objs
-               t1parse
-               ;
-  }
-  else
-  {
-    _sources = type1 ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/type1 Jamfile
diff --git a/src/type1/module.mk b/src/type1/module.mk
index 3fea5cc..33bceff 100644
--- a/src/type1/module.mk
+++ b/src/type1/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/type1/rules.mk b/src/type1/rules.mk
index cb1a142..efe744b 100644
--- a/src/type1/rules.mk
+++ b/src/type1/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/type1/t1afm.c b/src/type1/t1afm.c
index 0cbef3b..787aa92 100644
--- a/src/type1/t1afm.c
+++ b/src/type1/t1afm.c
@@ -4,7 +4,7 @@
  *
  *   AFM support for Type 1 fonts (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,11 +16,10 @@
  */
 
 
-#include <ft2build.h>
 #include "t1afm.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psaux.h>
 #include "t1errors.h"
 
 
@@ -33,7 +32,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1afm
+#define FT_COMPONENT  t1afm
 
 
   FT_LOCAL_DEF( void )
@@ -84,7 +83,7 @@
 
 
   /* compare two kerning pairs */
-  FT_CALLBACK_DEF( int )
+  FT_COMPARE_DEF( int )
   compare_kern_pairs( const void*  a,
                       const void*  b )
   {
@@ -179,7 +178,6 @@
     /* temporarily.  If we find no PostScript charmap, then just use    */
     /* the default and hope it is the right one.                        */
     oldcharmap = t1_face->charmap;
-    charmap    = NULL;
 
     for ( n = 0; n < t1_face->num_charmaps; n++ )
     {
@@ -187,9 +185,7 @@
       /* check against PostScript pseudo platform */
       if ( charmap->platform_id == 7 )
       {
-        error = FT_Set_Charmap( t1_face, charmap );
-        if ( error )
-          goto Exit;
+        t1_face->charmap = charmap;
         break;
       }
     }
@@ -204,16 +200,13 @@
       kp->index1 = FT_Get_Char_Index( t1_face, p[0] );
       kp->index2 = FT_Get_Char_Index( t1_face, p[1] );
 
-      kp->x = (FT_Int)FT_PEEK_SHORT_LE(p + 2);
+      kp->x = (FT_Int)FT_PEEK_SHORT_LE( p + 2 );
       kp->y = 0;
 
       kp++;
     }
 
-    if ( oldcharmap )
-      error = FT_Set_Charmap( t1_face, oldcharmap );
-    if ( error )
-      goto Exit;
+    t1_face->charmap = oldcharmap;
 
     /* now, sort the kern pairs according to their glyph indices */
     ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ),
@@ -303,9 +296,14 @@
       t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16;
       t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16;
 
-      /* no `U' suffix here to 0x8000! */
-      t1_face->ascender  = (FT_Short)( ( fi->Ascender  + 0x8000 ) >> 16 );
-      t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );
+      /* 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 );
+      }
 
       if ( fi->NumKernPair )
       {
diff --git a/src/type1/t1afm.h b/src/type1/t1afm.h
index d92b78f..e0d5aa5 100644
--- a/src/type1/t1afm.h
+++ b/src/type1/t1afm.h
@@ -4,7 +4,7 @@
  *
  *   AFM support for Type 1 fonts (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,9 +19,8 @@
 #ifndef T1AFM_H_
 #define T1AFM_H_
 
-#include <ft2build.h>
 #include "t1objs.h"
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/internal/t1types.h>
 
 FT_BEGIN_HEADER
 
diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
index 4d46e3e..ded3b26 100644
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -4,7 +4,7 @@
  *
  *   Type 1 driver interface (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,7 +16,6 @@
  */
 
 
-#include <ft2build.h>
 #include "t1driver.h"
 #include "t1gload.h"
 #include "t1load.h"
@@ -27,20 +26,20 @@
 #include "t1afm.h"
 #endif
 
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_HASH_H
-#include FT_INTERNAL_POSTSCRIPT_PROPS_H
-#include FT_DRIVER_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/fthash.h>
+#include <freetype/internal/ftpsprop.h>
+#include <freetype/ftdriver.h>
 
-#include FT_SERVICE_MULTIPLE_MASTERS_H
-#include FT_SERVICE_GLYPH_DICT_H
-#include FT_SERVICE_FONT_FORMAT_H
-#include FT_SERVICE_POSTSCRIPT_NAME_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
-#include FT_SERVICE_PROPERTIES_H
-#include FT_SERVICE_KERNING_H
+#include <freetype/internal/services/svmm.h>
+#include <freetype/internal/services/svgldict.h>
+#include <freetype/internal/services/svfntfmt.h>
+#include <freetype/internal/services/svpostnm.h>
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/services/svpsinfo.h>
+#include <freetype/internal/services/svprop.h>
+#include <freetype/internal/services/svkern.h>
 
 
   /**************************************************************************
@@ -50,7 +49,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1driver
+#define FT_COMPONENT  t1driver
 
   /*
    * GLYPH DICT SERVICE
@@ -70,8 +69,8 @@
 
 
   static FT_UInt
-  t1_get_name_index( T1_Face     face,
-                     FT_String*  glyph_name )
+  t1_get_name_index( T1_Face           face,
+                     const FT_String*  glyph_name )
   {
     FT_Int  i;
 
@@ -122,17 +121,30 @@
 #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_Get_Var_Blend_Func) NULL,                  /* get_var_blend  */
-    (FT_Done_Blend_Func)    T1_Done_Blend          /* done_blend     */
+    (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                */
   };
 #endif
 
diff --git a/src/type1/t1driver.h b/src/type1/t1driver.h
index 2dae4bd..ee7fcf4 100644
--- a/src/type1/t1driver.h
+++ b/src/type1/t1driver.h
@@ -4,7 +4,7 @@
  *
  *   High-level Type 1 driver interface (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define T1DRIVER_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type1/t1errors.h b/src/type1/t1errors.h
index 312f456..2fbd1e5 100644
--- a/src/type1/t1errors.h
+++ b/src/type1/t1errors.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef T1ERRORS_H_
 #define T1ERRORS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  T1_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Type1
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* T1ERRORS_H_ */
 
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
index 87c2a0f..a32a464 100644
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -4,7 +4,7 @@
  *
  *   Type 1 Glyph Loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,15 +16,14 @@
  */
 
 
-#include <ft2build.h>
 #include "t1gload.h"
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_OUTLINE_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_CFF_TYPES_H
-#include FT_DRIVER_H
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/ftoutln.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/internal/cfftypes.h>
+#include <freetype/ftdriver.h>
 
 #include "t1errors.h"
 
@@ -36,7 +35,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1gload
+#define FT_COMPONENT  t1gload
 
 
   static FT_Error
@@ -80,7 +79,7 @@
     /* For ordinary fonts get the character data stored in the face record. */
     {
       char_string->pointer = type1->charstrings[glyph_index];
-      char_string->length  = (FT_Int)type1->charstrings_len[glyph_index];
+      char_string->length  = type1->charstrings_len[glyph_index];
     }
 
     if ( !error )
@@ -265,7 +264,7 @@
     }
 
     FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n",
-                *max_advance / 65536.0 ));
+                (double)*max_advance / 65536 ));
 
     psaux->t1_decoder_funcs->done( &decoder );
 
@@ -334,7 +333,7 @@
       else
         advances[nn] = 0;
 
-      FT_TRACE5(( "  idx %d: advance width %d font unit%s\n",
+      FT_TRACE5(( "  idx %d: advance width %ld font unit%s\n",
                   first + nn,
                   advances[nn],
                   advances[nn] == 1 ? "" : "s" ));
@@ -402,9 +401,9 @@
     t1glyph->outline.n_points   = 0;
     t1glyph->outline.n_contours = 0;
 
-    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
-                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
-    scaled  = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 );
+    hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) &&
+                       !( load_flags & FT_LOAD_NO_HINTING ) );
+    scaled  = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) );
 
     glyph->hint     = hinting;
     glyph->scaled   = scaled;
@@ -416,7 +415,7 @@
                                  t1glyph,
                                  (FT_Byte**)type1->glyph_names,
                                  face->blend,
-                                 FT_BOOL( hinting ),
+                                 hinting,
                                  FT_LOAD_TARGET_MODE( load_flags ),
                                  T1_Parse_Glyph );
     if ( error )
@@ -424,8 +423,7 @@
 
     must_finish_decoder = TRUE;
 
-    decoder.builder.no_recurse = FT_BOOL(
-                                   ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
+    decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
 
     decoder.num_subrs     = type1->num_subrs;
     decoder.subrs         = type1->subrs;
@@ -546,7 +544,7 @@
 
 
           /* First of all, scale the points, if we are not hinting */
-          if ( !hinting || ! decoder.builder.hints_funcs )
+          if ( !hinting || !decoder.builder.hints_funcs )
             for ( n = cur->n_points; n > 0; n--, vec++ )
             {
               vec->x = FT_MulFix( vec->x, x_scale );
diff --git a/src/type1/t1gload.h b/src/type1/t1gload.h
index 12ba234..c064847 100644
--- a/src/type1/t1gload.h
+++ b/src/type1/t1gload.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 Glyph Loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,7 +20,6 @@
 #define T1GLOAD_H_
 
 
-#include <ft2build.h>
 #include "t1objs.h"
 
 
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index a443571..5a1afd8 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -4,7 +4,7 @@
  *
  *   Type 1 font loader (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -61,19 +61,19 @@
 
 
 #include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_MULTIPLE_MASTERS_H
-#include FT_INTERNAL_TYPE1_TYPES_H
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_HASH_H
+#include <freetype/ftmm.h>
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/fthash.h>
 
 #include "t1load.h"
 #include "t1errors.h"
 
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-#define IS_INCREMENTAL  (FT_Bool)( face->root.internal->incremental_interface != 0 )
+#define IS_INCREMENTAL  FT_BOOL( face->root.internal->incremental_interface )
 #else
 #define IS_INCREMENTAL  0
 #endif
@@ -86,7 +86,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1load
+#define FT_COMPONENT  t1load
 
 
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
@@ -117,6 +117,9 @@
         goto Exit;
 
       blend->num_default_design_vector = 0;
+      blend->weight_vector             = NULL;
+      blend->default_weight_vector     = NULL;
+      blend->design_pos[0]             = NULL;
 
       face->blend = blend;
     }
@@ -130,14 +133,11 @@
 
 
         /* allocate the blend `private' and `font_info' dictionaries */
-        if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs     ) ||
-             FT_NEW_ARRAY( blend->privates  [1], num_designs     ) ||
-             FT_NEW_ARRAY( blend->bboxes    [1], num_designs     ) ||
-             FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
+        if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) ||
+             FT_NEW_ARRAY( blend->privates  [1], num_designs ) ||
+             FT_NEW_ARRAY( blend->bboxes    [1], num_designs ) )
           goto Exit;
 
-        blend->default_weight_vector = blend->weight_vector + num_designs;
-
         blend->font_infos[0] = &face->type1.font_info;
         blend->privates  [0] = &face->type1.private_dict;
         blend->bboxes    [0] = &face->type1.font_bbox;
@@ -164,21 +164,6 @@
       blend->num_axis = num_axis;
     }
 
-    /* allocate the blend design pos table if needed */
-    num_designs = blend->num_designs;
-    num_axis    = blend->num_axis;
-    if ( num_designs && num_axis && blend->design_pos[0] == 0 )
-    {
-      FT_UInt  n;
-
-
-      if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )
-        goto Exit;
-
-      for ( n = 1; n < num_designs; n++ )
-        blend->design_pos[n] = blend->design_pos[0] + num_axis * n;
-    }
-
   Exit:
     return error;
 
@@ -309,31 +294,55 @@
     FT_UInt          i;
     FT_Fixed         axiscoords[T1_MAX_MM_AXIS];
     PS_Blend         blend = face->blend;
+    FT_UShort*       axis_flags;
+
+    FT_Offset  mmvar_size;
+    FT_Offset  axis_flags_size;
+    FT_Offset  axis_size;
 
 
     error = T1_Get_Multi_Master( face, &mmaster );
     if ( error )
       goto Exit;
-    if ( FT_ALLOC( mmvar,
-                   sizeof ( FT_MM_Var ) +
-                     mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
+
+    /* the various `*_size' variables, which we also use as     */
+    /* offsets into the `mmvar' array, must be multiples of the */
+    /* pointer size (except the last one); without such an      */
+    /* alignment there might be runtime errors due to           */
+    /* misaligned addresses                                     */
+#undef  ALIGN_SIZE
+#define ALIGN_SIZE( n ) \
+          ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
+
+    mmvar_size      = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
+    axis_flags_size = ALIGN_SIZE( mmaster.num_axis *
+                                  sizeof ( FT_UShort ) );
+    axis_size       = mmaster.num_axis * sizeof ( FT_Var_Axis );
+
+    if ( FT_ALLOC( mmvar, mmvar_size +
+                          axis_flags_size +
+                          axis_size ) )
       goto Exit;
 
     mmvar->num_axis        = mmaster.num_axis;
     mmvar->num_designs     = mmaster.num_designs;
     mmvar->num_namedstyles = 0;                           /* Not supported */
-    mmvar->axis            = (FT_Var_Axis*)&mmvar[1];
-                                      /* Point to axes after MM_Var struct */
-    mmvar->namedstyle      = NULL;
+
+    /* while axis flags are meaningless here, we have to provide the array */
+    /* 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;
+
+    mmvar->axis       = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
+    mmvar->namedstyle = NULL;
 
     for ( i = 0; i < mmaster.num_axis; i++ )
     {
       mmvar->axis[i].name    = mmaster.axis[i].name;
       mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum );
       mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
-      mmvar->axis[i].def     = ( mmvar->axis[i].minimum +
-                                   mmvar->axis[i].maximum ) / 2;
-                            /* Does not apply.  But this value is in range */
       mmvar->axis[i].strid   = ~0U;                      /* Does not apply */
       mmvar->axis[i].tag     = ~0U;                      /* Does not apply */
 
@@ -346,6 +355,10 @@
         mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
       else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
         mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
+      else if ( ft_strcmp( mmvar->axis[i].name, "Slant" ) == 0 )
+        mmvar->axis[i].tag = FT_MAKE_TAG( 's', 'l', 'n', 't' );
+      else if ( ft_strcmp( mmvar->axis[i].name, "Italic" ) == 0 )
+        mmvar->axis[i].tag = FT_MAKE_TAG( 'i', 't', 'a', 'l' );
     }
 
     mm_weights_unmap( blend->default_weight_vector,
@@ -384,24 +397,31 @@
     for ( n = 0; n < blend->num_designs; n++ )
     {
       FT_Fixed  result = 0x10000L;  /* 1.0 fixed */
+      FT_Fixed  factor;
 
 
       for ( m = 0; m < blend->num_axis; m++ )
       {
-        FT_Fixed  factor;
-
-
-        /* get current blend axis position;                  */
         /* use a default value if we don't have a coordinate */
-        factor = m < num_coords ? coords[m] : 0x8000;
-        if ( factor < 0 )
-          factor = 0;
-        if ( factor > 0x10000L )
-          factor = 0x10000L;
+        if ( m >= num_coords )
+        {
+          result >>= 1;
+          continue;
+        }
 
+        /* get current blend axis position */
+        factor = coords[m];
         if ( ( n & ( 1 << m ) ) == 0 )
           factor = 0x10000L - factor;
 
+        if ( factor <= 0 )
+        {
+          result = 0;
+          break;
+        }
+        else if ( factor >= 0x10000L )
+          continue;
+
         result = FT_MulFix( result, factor );
       }
 
@@ -474,13 +494,82 @@
 
 
   FT_LOCAL_DEF( FT_Error )
+  T1_Set_MM_WeightVector( T1_Face    face,
+                          FT_UInt    len,
+                          FT_Fixed*  weightvector )
+  {
+    PS_Blend  blend = face->blend;
+    FT_UInt   i, n;
+
+
+    if ( !blend )
+     return FT_THROW( Invalid_Argument );
+
+    if ( !len && !weightvector )
+    {
+      for ( i = 0; i < blend->num_designs; i++ )
+        blend->weight_vector[i] = blend->default_weight_vector[i];
+    }
+    else
+    {
+      if ( !weightvector )
+        return FT_THROW( Invalid_Argument );
+
+      n = len < blend->num_designs ? len : blend->num_designs;
+
+      for ( i = 0; i < n; i++ )
+        blend->weight_vector[i] = weightvector[i];
+
+      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;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  T1_Get_MM_WeightVector( T1_Face    face,
+                          FT_UInt*   len,
+                          FT_Fixed*  weightvector )
+  {
+    PS_Blend  blend = face->blend;
+    FT_UInt   i;
+
+
+    if ( !blend )
+      return FT_THROW( Invalid_Argument );
+
+    if ( *len < blend->num_designs )
+    {
+      *len = blend->num_designs;
+      return FT_THROW( Invalid_Argument );
+    }
+
+    for ( i = 0; i < blend->num_designs; i++ )
+      weightvector[i] = blend->weight_vector[i];
+    for ( ; i < *len; i++ )
+      weightvector[i] = (FT_Fixed)0;
+
+    *len = blend->num_designs;
+
+    return FT_Err_Ok;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
   T1_Set_MM_Design( T1_Face   face,
                     FT_UInt   num_coords,
                     FT_Long*  coords )
   {
     FT_Error  error;
     PS_Blend  blend = face->blend;
-    FT_UInt   n, p;
+    FT_UInt   n;
     FT_Fixed  final_blends[T1_MAX_MM_DESIGNS];
 
 
@@ -499,7 +588,7 @@
       PS_DesignMap  map     = blend->design_map + n;
       FT_Long*      designs = map->design_points;
       FT_Fixed*     blends  = map->blend_points;
-      FT_Int        before  = -1, after = -1;
+      FT_Int        p, before  = -1, after = -1;
 
 
       /* use a default value if we don't have a coordinate */
@@ -508,7 +597,7 @@
       else
         design = ( designs[map->num_points - 1] - designs[0] ) / 2;
 
-      for ( p = 0; p < (FT_UInt)map->num_points; p++ )
+      for ( p = 0; p < (FT_Int)map->num_points; p++ )
       {
         FT_Long  p_design = designs[p];
 
@@ -522,11 +611,11 @@
 
         if ( design < p_design )
         {
-          after = (FT_Int)p;
+          after = p;
           break;
         }
 
-        before = (FT_Int)p;
+        before = p;
       }
 
       /* now interpolate if necessary */
@@ -751,7 +840,7 @@
         FT_FREE( name );
       }
 
-      if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
+      if ( FT_QALLOC( blend->axis_names[n], len + 1 ) )
         goto Exit;
 
       name = (FT_Byte*)blend->axis_names[n];
@@ -772,12 +861,14 @@
   {
     T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
     FT_Int       num_designs;
-    FT_Int       num_axis;
-    T1_Parser    parser = &loader->parser;
+    FT_Int       num_axis = 0; /* make compiler happy */
+    T1_Parser    parser   = &loader->parser;
+    FT_Memory    memory   = face->root.memory;
+    FT_Error     error    = FT_Err_Ok;
+    FT_Fixed*    design_pos[T1_MAX_MM_DESIGNS];
 
-    FT_Error     error = FT_Err_Ok;
-    PS_Blend     blend;
 
+    design_pos[0] = NULL;
 
     /* get the array of design tokens -- compute number of designs */
     T1_ToTokenArray( parser, design_tokens,
@@ -799,12 +890,10 @@
     {
       FT_Byte*  old_cursor = parser->root.cursor;
       FT_Byte*  old_limit  = parser->root.limit;
-      FT_Int    n;
+      FT_Int    n, nn;
+      PS_Blend  blend;
 
 
-      blend    = face->blend;
-      num_axis = 0;  /* make compiler happy */
-
       FT_TRACE4(( " [" ));
 
       for ( n = 0; n < num_designs; n++ )
@@ -837,7 +926,13 @@
                                      (FT_UInt)num_axis );
           if ( error )
             goto Exit;
-          blend = face->blend;
+
+          /* allocate a blend design pos table */
+          if ( FT_QNEW_ARRAY( design_pos[0], num_designs * num_axis ) )
+            goto Exit;
+
+          for ( nn = 1; nn < num_designs; nn++ )
+            design_pos[nn] = design_pos[0] + num_axis * nn;
         }
         else if ( n_axis != num_axis )
         {
@@ -855,8 +950,8 @@
 
           parser->root.cursor = token2->start;
           parser->root.limit  = token2->limit;
-          blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
-          FT_TRACE4(( " %f", (double)blend->design_pos[n][axis] / 65536 ));
+          design_pos[n][axis] = T1_ToFixed( parser, 0 );
+          FT_TRACE4(( " %f", (double)design_pos[n][axis] / 65536 ));
         }
         FT_TRACE4(( "]" )) ;
       }
@@ -865,9 +960,21 @@
 
       loader->parser.root.cursor = old_cursor;
       loader->parser.root.limit  = old_limit;
+
+      /* a valid BlendDesignPosition has been parsed */
+      blend = face->blend;
+      if ( blend->design_pos[0] )
+        FT_FREE( blend->design_pos[0] );
+
+      for ( n = 0; n < num_designs; n++ )
+      {
+        blend->design_pos[n] = design_pos[n];
+        design_pos[n]        = NULL;
+      }
     }
 
   Exit:
+    FT_FREE( design_pos[0] );
     loader->parser.root.error = error;
   }
 
@@ -944,7 +1051,7 @@
       }
 
       /* allocate design map data */
-      if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )
+      if ( FT_QNEW_ARRAY( map->design_points, num_points * 2 ) )
         goto Exit;
       map->blend_points = map->design_points + num_points;
       map->num_points   = (FT_Byte)num_points;
@@ -963,7 +1070,7 @@
         map->design_points[p] = T1_ToInt( parser );
         map->blend_points [p] = T1_ToFixed( parser, 0 );
 
-        FT_TRACE4(( " [%d %f]",
+        FT_TRACE4(( " [%ld %f]",
                     map->design_points[p],
                     (double)map->blend_points[p] / 65536 ));
       }
@@ -988,6 +1095,7 @@
     T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
     FT_Int       num_designs;
     FT_Error     error  = FT_Err_Ok;
+    FT_Memory    memory = face->root.memory;
     T1_Parser    parser = &loader->parser;
     PS_Blend     blend  = face->blend;
     T1_Token     token;
@@ -1022,13 +1130,19 @@
     else if ( blend->num_designs != (FT_UInt)num_designs )
     {
       FT_ERROR(( "parse_weight_vector:"
-                 " /BlendDesignPosition and /WeightVector have\n"
-                 "                    "
+                 " /BlendDesignPosition and /WeightVector have\n" ));
+      FT_ERROR(( "                    "
                  " different number of elements\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
+    if ( !blend->weight_vector )
+      if ( FT_QNEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
+        goto Exit;
+
+    blend->default_weight_vector = blend->weight_vector + num_designs;
+
     old_cursor = parser->root.cursor;
     old_limit  = parser->root.limit;
 
@@ -1062,16 +1176,22 @@
   parse_buildchar( T1_Face    face,
                    T1_Loader  loader )
   {
-    FT_UInt  i;
-
-
     face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
                                                     0, NULL, 0 );
-    FT_TRACE4(( " [" ));
-    for ( i = 0; i < face->len_buildchar; i++ )
-      FT_TRACE4(( " 0" ));
 
-    FT_TRACE4(( "]\n" ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+    {
+      FT_UInt  i;
+
+
+      FT_TRACE4(( " [" ));
+      for ( i = 0; i < face->len_buildchar; i++ )
+        FT_TRACE4(( " 0" ));
+
+      FT_TRACE4(( "]\n" ));
+    }
+#endif
+
     return;
   }
 
@@ -1201,9 +1321,9 @@
     else
     {
       FT_TRACE1(( "t1_load_keyword: ignoring keyword `%s'"
-                  " which is not valid at this point\n"
-                  "                 (probably due to missing keywords)\n",
+                  " which is not valid at this point\n",
                  field->ident ));
+      FT_TRACE1(( "                 (probably due to missing keywords)\n" ));
       error = FT_Err_Ok;
     }
 
@@ -1414,8 +1534,8 @@
 
       /* we use a T1_Table to store our charnames */
       loader->num_chars = encode->num_chars = array_size;
-      if ( FT_NEW_ARRAY( encode->char_index, array_size )     ||
-           FT_NEW_ARRAY( encode->char_name,  array_size )     ||
+      if ( FT_QNEW_ARRAY( encode->char_index, array_size )    ||
+           FT_QNEW_ARRAY( encode->char_name,  array_size )    ||
            FT_SET_ERROR( psaux->ps_table_funcs->init(
                            char_table, array_size, memory ) ) )
       {
@@ -1425,12 +1545,7 @@
 
       /* We need to `zero' out encoding_table.elements */
       for ( n = 0; n < array_size; n++ )
-      {
-        char*  notdef = (char *)".notdef";
-
-
-        (void)T1_Add_Table( char_table, n, notdef, 8 );
-      }
+        (void)T1_Add_Table( char_table, n, ".notdef", 8 );
 
       /* Now we need to read records of the form                */
       /*                                                        */
@@ -1654,14 +1769,14 @@
        */
 
       FT_TRACE0(( "parse_subrs: adjusting number of subroutines"
-                  " (from %d to %d)\n",
+                  " (from %d to %ld)\n",
                   num_subrs,
                   ( parser->root.limit - parser->root.cursor ) >> 3 ));
       num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
 
       if ( !loader->subrs_hash )
       {
-        if ( FT_NEW( loader->subrs_hash ) )
+        if ( FT_QNEW( loader->subrs_hash ) )
           goto Fail;
 
         error = ft_hash_num_init( loader->subrs_hash, memory );
@@ -1757,7 +1872,7 @@
         }
 
         /* t1_decrypt() shouldn't write to base -- make temporary copy */
-        if ( FT_ALLOC( temp, size ) )
+        if ( FT_QALLOC( temp, size ) )
           goto Fail;
         FT_MEM_COPY( temp, base, size );
         psaux->t1_decrypt( temp, size, 4330 );
@@ -1825,7 +1940,7 @@
     if ( num_glyphs > ( limit - cur ) >> 3 )
     {
       FT_TRACE0(( "parse_charstrings: adjusting number of glyphs"
-                  " (from %d to %d)\n",
+                  " (from %d to %ld)\n",
                   num_glyphs, ( limit - cur ) >> 3 ));
       num_glyphs = ( limit - cur ) >> 3;
     }
@@ -1946,9 +2061,9 @@
         name_table->elements[n][len] = '\0';
 
         /* record index of /.notdef */
-        if ( *cur == '.'                                              &&
+        if ( *cur == '.'                                                &&
              ft_strcmp( ".notdef",
-                        (const char*)(name_table->elements[n]) ) == 0 )
+                        (const char*)( name_table->elements[n] ) ) == 0 )
         {
           notdef_index = n;
           notdef_found = 1;
@@ -1967,7 +2082,7 @@
           }
 
           /* t1_decrypt() shouldn't write to base -- make temporary copy */
-          if ( FT_ALLOC( temp, size ) )
+          if ( FT_QALLOC( temp, size ) )
             goto Fail;
           FT_MEM_COPY( temp, base, size );
           psaux->t1_decrypt( temp, size, 4330 );
@@ -2065,7 +2180,6 @@
 
       /* 0 333 hsbw endchar */
       FT_Byte  notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
-      char*    notdef_name    = (char *)".notdef";
 
 
       error = T1_Add_Table( swap_table, 0,
@@ -2080,7 +2194,7 @@
       if ( error )
         goto Fail;
 
-      error = T1_Add_Table( name_table, 0, notdef_name, 8 );
+      error = T1_Add_Table( name_table, 0, ".notdef", 8 );
       if ( error )
         goto Fail;
 
@@ -2221,8 +2335,8 @@
       /* in valid Type 1 fonts we don't see `RD' or `-|' directly */
       /* since those tokens are handled by parse_subrs and        */
       /* parse_charstrings                                        */
-      else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&
-                have_integer )
+      else if ( *cur == 'R' && cur + 6 < limit && *( cur + 1 ) == 'D' &&
+                have_integer                                          )
       {
         FT_ULong  s;
         FT_Byte*  b;
@@ -2234,8 +2348,8 @@
         have_integer = 0;
       }
 
-      else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&
-                have_integer )
+      else if ( *cur == '-' && cur + 6 < limit && *( cur + 1 ) == '|' &&
+                have_integer                                          )
       {
         FT_ULong  s;
         FT_Byte*  b;
@@ -2478,7 +2592,15 @@
          ( !face->blend->num_designs || !face->blend->num_axis ) )
       T1_Done_Blend( face );
 
-    /* another safety check */
+    /* the font may have no valid WeightVector */
+    if ( face->blend && !face->blend->weight_vector )
+      T1_Done_Blend( face );
+
+    /* the font may have no valid BlendDesignPositions */
+    if ( face->blend && !face->blend->design_pos[0] )
+      T1_Done_Blend( face );
+
+    /* the font may have no valid BlendDesignMap */
     if ( face->blend )
     {
       FT_UInt  i;
@@ -2551,8 +2673,7 @@
     /* we must now build type1.encoding when we have a custom array */
     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
     {
-      FT_Int    charcode, idx, min_char, max_char;
-      FT_Byte*  glyph_name;
+      FT_Int  charcode, idx, min_char, max_char;
 
 
       /* OK, we do the following: for each element in the encoding  */
@@ -2566,27 +2687,27 @@
       charcode = 0;
       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
       {
-        FT_Byte*  char_name;
+        const FT_String*  char_name =
+              (const FT_String*)loader.encoding_table.elements[charcode];
 
 
         type1->encoding.char_index[charcode] = 0;
-        type1->encoding.char_name [charcode] = (char *)".notdef";
+        type1->encoding.char_name [charcode] = ".notdef";
 
-        char_name = loader.encoding_table.elements[charcode];
         if ( char_name )
           for ( idx = 0; idx < type1->num_glyphs; idx++ )
           {
-            glyph_name = (FT_Byte*)type1->glyph_names[idx];
-            if ( ft_strcmp( (const char*)char_name,
-                            (const char*)glyph_name ) == 0 )
+            const FT_String*  glyph_name = type1->glyph_names[idx];
+
+
+            if ( ft_strcmp( char_name, glyph_name ) == 0 )
             {
               type1->encoding.char_index[charcode] = (FT_UShort)idx;
-              type1->encoding.char_name [charcode] = (char*)glyph_name;
+              type1->encoding.char_name [charcode] = glyph_name;
 
               /* Change min/max encoded char only if glyph name is */
               /* not /.notdef                                      */
-              if ( ft_strcmp( (const char*)".notdef",
-                              (const char*)glyph_name ) != 0 )
+              if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
               {
                 if ( charcode < min_char )
                   min_char = charcode;
diff --git a/src/type1/t1load.h b/src/type1/t1load.h
index 43d5db5..f8511cc 100644
--- a/src/type1/t1load.h
+++ b/src/type1/t1load.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 font loader (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,10 +20,9 @@
 #define T1LOAD_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_MULTIPLE_MASTERS_H
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psaux.h>
+#include <freetype/ftmm.h>
 
 #include "t1parse.h"
 
@@ -106,6 +105,16 @@
   FT_LOCAL( void )
   T1_Done_Blend( T1_Face  face );
 
+  FT_LOCAL( FT_Error )
+  T1_Set_MM_WeightVector( T1_Face    face,
+                          FT_UInt    len,
+                          FT_Fixed*  weightvector );
+
+  FT_LOCAL( FT_Error )
+  T1_Get_MM_WeightVector( T1_Face    face,
+                          FT_UInt*   len,
+                          FT_Fixed*  weightvector );
+
 #endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */
 
 
diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c
index 05f02d5..1bb2f15 100644
--- a/src/type1/t1objs.c
+++ b/src/type1/t1objs.c
@@ -4,7 +4,7 @@
  *
  *   Type 1 objects manager (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,11 @@
  */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_CALC_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_TRUETYPE_IDS_H
-#include FT_DRIVER_H
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/ttnameid.h>
+#include <freetype/ftdriver.h>
 
 #include "t1gload.h"
 #include "t1load.h"
@@ -32,8 +31,8 @@
 #include "t1afm.h"
 #endif
 
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/psaux.h>
 
 
   /**************************************************************************
@@ -43,7 +42,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1objs
+#define FT_COMPONENT  t1objs
 
 
   /**************************************************************************
@@ -117,11 +116,15 @@
   T1_Size_Request( FT_Size          t1size,     /* T1_Size */
                    FT_Size_Request  req )
   {
+    FT_Error  error;
+
     T1_Size            size  = (T1_Size)t1size;
     PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );
 
 
-    FT_Request_Metrics( size->root.face, req );
+    error = FT_Request_Metrics( size->root.face, req );
+    if ( error )
+      goto Exit;
 
     if ( funcs )
       funcs->set_scale( (PSH_Globals)t1size->internal->module_data,
@@ -129,7 +132,8 @@
                         size->root.metrics.y_scale,
                         0, 0 );
 
-    return FT_Err_Ok;
+  Exit:
+    return error;
   }
 
 
@@ -142,7 +146,9 @@
   FT_LOCAL_DEF( void )
   T1_GlyphSlot_Done( FT_GlyphSlot  slot )
   {
-    slot->internal->glyph_hints = NULL;
+    /* `slot->internal` might be NULL in out-of-memory situations. */
+    if ( slot->internal )
+      slot->internal->glyph_hints = NULL;
   }
 
 
@@ -218,7 +224,6 @@
     {
       FT_FREE( face->buildchar );
 
-      face->buildchar     = NULL;
       face->len_buildchar = 0;
     }
 
@@ -347,8 +352,8 @@
     if ( error )
       goto Exit;
 
-    FT_TRACE2(( "T1_Face_Init: %08p (index %d)\n",
-                face,
+    FT_TRACE2(( "T1_Face_Init: %p (index %d)\n",
+                (void *)face,
                 face_index ));
 
     /* if we just wanted to check the format, leave successfully now */
@@ -526,7 +531,8 @@
 
         error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
         if ( error                                      &&
-             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
+             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
+             FT_ERR_NEQ( error, Unimplemented_Feature ) )
           goto Exit;
         error = FT_Err_Ok;
 
@@ -598,11 +604,7 @@
 
 
     /* set default property values, cf. `ftt1drv.h' */
-#ifdef T1_CONFIG_OPTION_OLD_ENGINE
-    driver->hinting_engine = FT_HINTING_FREETYPE;
-#else
     driver->hinting_engine = FT_HINTING_ADOBE;
-#endif
 
     driver->no_stem_darkening = TRUE;
 
diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h
index 86fecd9..03847b2 100644
--- a/src/type1/t1objs.h
+++ b/src/type1/t1objs.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 objects manager (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,9 +21,9 @@
 
 
 #include <ft2build.h>
-#include FT_INTERNAL_OBJECTS_H
+#include <freetype/internal/ftobjs.h>
 #include FT_CONFIG_CONFIG_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/internal/t1types.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type1/t1parse.c b/src/type1/t1parse.c
index 9214831..6dec6c1 100644
--- a/src/type1/t1parse.c
+++ b/src/type1/t1parse.c
@@ -4,7 +4,7 @@
  *
  *   Type 1 parser (body).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -33,10 +33,9 @@
    */
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psaux.h>
 
 #include "t1parse.h"
 
@@ -50,7 +49,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1parse
+#define FT_COMPONENT  t1parse
 
 
   /*************************************************************************/
@@ -222,7 +221,7 @@
     else
     {
       /* read segment in memory -- this is clumsy, but so does the format */
-      if ( FT_ALLOC( parser->base_dict, size )       ||
+      if ( FT_QALLOC( parser->base_dict, size )      ||
            FT_STREAM_READ( parser->base_dict, size ) )
         goto Exit;
       parser->base_len = size;
@@ -303,8 +302,8 @@
         goto Fail;
       }
 
-      if ( FT_STREAM_SEEK( start_pos )                           ||
-           FT_ALLOC( parser->private_dict, parser->private_len ) )
+      if ( FT_STREAM_SEEK( start_pos )                            ||
+           FT_QALLOC( parser->private_dict, parser->private_len ) )
         goto Fail;
 
       parser->private_len = 0;
@@ -331,50 +330,25 @@
       /* the private dict.  Otherwise, simply overwrite into the base  */
       /* dictionary block in the heap.                                 */
 
-      /* first of all, look at the `eexec' keyword */
+      /* First look for the `eexec' keyword. Ensure `eexec' is real -- */
+      /* it could be in a comment or string (as e.g. in u003043t.gsf   */
+      /* from ghostscript).                                            */
       FT_Byte*    cur   = parser->base_dict;
       FT_Byte*    limit = cur + parser->base_len;
       FT_Pointer  pos_lf;
       FT_Bool     test_cr;
 
 
-    Again:
-      for (;;)
-      {
-        if ( cur[0] == 'e'   &&
-             cur + 9 < limit )      /* 9 = 5 letters for `eexec' + */
-                                    /* whitespace + 4 chars        */
-        {
-          if ( cur[1] == 'e' &&
-               cur[2] == 'x' &&
-               cur[3] == 'e' &&
-               cur[4] == 'c' )
-            break;
-        }
-        cur++;
-        if ( cur >= limit )
-        {
-          FT_ERROR(( "T1_Get_Private_Dict:"
-                     " could not find `eexec' keyword\n" ));
-          error = FT_THROW( Invalid_File_Format );
-          goto Exit;
-        }
-      }
-
-      /* check whether `eexec' was real -- it could be in a comment */
-      /* or string (as e.g. in u003043t.gsf from ghostscript)       */
-
       parser->root.cursor = parser->base_dict;
-      /* set limit to `eexec' + whitespace + 4 characters */
-      parser->root.limit  = cur + 10;
+      parser->root.limit  = parser->base_dict + parser->base_len;
 
       cur   = parser->root.cursor;
       limit = parser->root.limit;
 
       while ( cur < limit )
       {
-        if ( cur[0] == 'e'   &&
-             cur + 5 < limit )
+        /* 9 = 5 letters for `eexec' + whitespace + 4 chars */
+        if ( cur[0] == 'e' && cur + 9 < limit )
         {
           if ( cur[1] == 'e' &&
                cur[2] == 'x' &&
@@ -390,21 +364,9 @@
         cur = parser->root.cursor;
       }
 
-      /* we haven't found the correct `eexec'; go back and continue */
-      /* searching                                                  */
-
-      cur   = limit;
-      limit = parser->base_dict + parser->base_len;
-
-      if ( cur >= limit )
-      {
-        FT_ERROR(( "T1_Get_Private_Dict:"
-                   " premature end in private dictionary\n" ));
-        error = FT_THROW( Invalid_File_Format );
-        goto Exit;
-      }
-
-      goto Again;
+      FT_ERROR(( "T1_Get_Private_Dict: could not find `eexec' keyword\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
 
       /* now determine where to write the _encrypted_ binary private  */
       /* dictionary.  We overwrite the base dictionary for disk-based */
@@ -451,7 +413,7 @@
       if ( parser->in_memory )
       {
         /* note that we allocate one more byte to put a terminating `0' */
-        if ( FT_ALLOC( parser->private_dict, size + 1 ) )
+        if ( FT_QALLOC( parser->private_dict, size + 1 ) )
           goto Fail;
         parser->private_len = size;
       }
diff --git a/src/type1/t1parse.h b/src/type1/t1parse.h
index 5659f4a..0d9a286 100644
--- a/src/type1/t1parse.h
+++ b/src/type1/t1parse.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 parser (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,9 +20,8 @@
 #define T1PARSE_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_TYPE1_TYPES_H
-#include FT_INTERNAL_STREAM_H
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/ftstream.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type1/t1tokens.h b/src/type1/t1tokens.h
index 45fc50d..40f3609 100644
--- a/src/type1/t1tokens.h
+++ b/src/type1/t1tokens.h
@@ -4,7 +4,7 @@
  *
  *   Type 1 tokenizer (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
diff --git a/src/type1/type1.c b/src/type1/type1.c
index c2d7922..d9bd8ca 100644
--- a/src/type1/type1.c
+++ b/src/type1/type1.c
@@ -4,7 +4,7 @@
  *
  *   FreeType Type 1 driver component (body only).
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "t1afm.c"
 #include "t1driver.c"
diff --git a/src/type42/Jamfile b/src/type42/Jamfile
deleted file mode 100644
index b98de05..0000000
--- a/src/type42/Jamfile
+++ /dev/null
@@ -1,32 +0,0 @@
-# FreeType 2 src/type42 Jamfile
-#
-# Copyright 2002-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) type42 ;
-
-{
-  local  _sources ;
-
-  if $(FT2_MULTI)
-  {
-    _sources = t42drivr
-               t42objs
-               t42parse
-               ;
-  }
-  else
-  {
-    _sources = type42 ;
-  }
-
-  Library  $(FT2_LIB) : $(_sources).c ;
-}
-
-# end of src/type42 Jamfile
diff --git a/src/type42/module.mk b/src/type42/module.mk
index 3d4732b..d98b123 100644
--- a/src/type42/module.mk
+++ b/src/type42/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/type42/rules.mk b/src/type42/rules.mk
index 9325d38..41cb358 100644
--- a/src/type42/rules.mk
+++ b/src/type42/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2002-2018 by
+# Copyright (C) 2002-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/type42/t42drivr.c b/src/type42/t42drivr.c
index 1036503..ce1528e 100644
--- a/src/type42/t42drivr.c
+++ b/src/type42/t42drivr.c
@@ -4,7 +4,7 @@
  *
  *   High-level Type 42 driver interface (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -39,15 +39,15 @@
 #include "t42drivr.h"
 #include "t42objs.h"
 #include "t42error.h"
-#include FT_INTERNAL_DEBUG_H
+#include <freetype/internal/ftdebug.h>
 
-#include FT_SERVICE_FONT_FORMAT_H
-#include FT_SERVICE_GLYPH_DICT_H
-#include FT_SERVICE_POSTSCRIPT_NAME_H
-#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include <freetype/internal/services/svfntfmt.h>
+#include <freetype/internal/services/svgldict.h>
+#include <freetype/internal/services/svpostnm.h>
+#include <freetype/internal/services/svpsinfo.h>
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t42
+#define FT_COMPONENT  t42
 
 
   /*
@@ -69,8 +69,8 @@
 
 
   static FT_UInt
-  t42_get_name_index( T42_Face    face,
-                      FT_String*  glyph_name )
+  t42_get_name_index( T42_Face          face,
+                      const FT_String*  glyph_name )
   {
     FT_Int  i;
 
@@ -150,22 +150,13 @@
   }
 
 
-  static FT_Error
-  t42_ps_get_font_private( FT_Face         face,
-                           PS_PrivateRec*  afont_private )
-  {
-    *afont_private = ((T42_Face)face)->type1.private_dict;
-
-    return FT_Err_Ok;
-  }
-
-
   static const FT_Service_PsInfoRec  t42_service_ps_info =
   {
     (PS_GetFontInfoFunc)   t42_ps_get_font_info,    /* ps_get_font_info    */
     (PS_GetFontExtraFunc)  t42_ps_get_font_extra,   /* ps_get_font_extra   */
     (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names,  /* ps_has_glyph_names  */
-    (PS_GetFontPrivateFunc)t42_ps_get_font_private, /* ps_get_font_private */
+    /* Type42 fonts don't have a Private dict */
+    (PS_GetFontPrivateFunc)NULL,                    /* ps_get_font_private */
     /* not implemented */
     (PS_GetFontValueFunc)  NULL                     /* ps_get_font_value   */
   };
diff --git a/src/type42/t42drivr.h b/src/type42/t42drivr.h
index ef50ad9..ec7da18 100644
--- a/src/type42/t42drivr.h
+++ b/src/type42/t42drivr.h
@@ -4,7 +4,7 @@
  *
  *   High-level Type 42 driver interface (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,8 +20,7 @@
 #define T42DRIVR_H_
 
 
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type42/t42error.h b/src/type42/t42error.h
index 95f9e69..dcea9c4 100644
--- a/src/type42/t42error.h
+++ b/src/type42/t42error.h
@@ -4,7 +4,7 @@
  *
  *   Type 42 error codes (specification only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -25,7 +25,7 @@
 #ifndef T42ERROR_H_
 #define T42ERROR_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -33,7 +33,7 @@
 #define FT_ERR_PREFIX  T42_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Type42
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* T42ERROR_H_ */
 
diff --git a/src/type42/t42objs.c b/src/type42/t42objs.c
index 0325cad..bf4028e 100644
--- a/src/type42/t42objs.c
+++ b/src/type42/t42objs.c
@@ -4,7 +4,7 @@
  *
  *   Type 42 objects manager (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,13 +19,13 @@
 #include "t42objs.h"
 #include "t42parse.h"
 #include "t42error.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_LIST_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/ftlist.h>
+#include <freetype/ttnameid.h>
 
 
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t42
+#define FT_COMPONENT  t42
 
 
   static FT_Error
@@ -44,14 +44,8 @@
 
     parser = &loader.parser;
 
-    if ( FT_ALLOC( face->ttf_data, 12 ) )
-      goto Exit;
-
-    /* while parsing the font we always update `face->ttf_size' so that */
-    /* even in case of buggy data (which might lead to premature end of */
-    /* scanning without causing an error) the call to `FT_Open_Face' in */
-    /* `T42_Face_Init' passes the correct size                          */
-    face->ttf_size = 12;
+    face->ttf_data = NULL;
+    face->ttf_size = 0;
 
     error = t42_parser_init( parser,
                              face->root.stream,
@@ -98,8 +92,7 @@
     /* we must now build type1.encoding when we have a custom array */
     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
     {
-      FT_Int    charcode, idx, min_char, max_char;
-      FT_Byte*  glyph_name;
+      FT_Int  charcode, idx, min_char, max_char;
 
 
       /* OK, we do the following: for each element in the encoding   */
@@ -114,27 +107,27 @@
       charcode = 0;
       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
       {
-        FT_Byte*  char_name;
+        const FT_String*  char_name =
+              (const FT_String*)loader.encoding_table.elements[charcode];
 
 
         type1->encoding.char_index[charcode] = 0;
-        type1->encoding.char_name [charcode] = (char *)".notdef";
+        type1->encoding.char_name [charcode] = ".notdef";
 
-        char_name = loader.encoding_table.elements[charcode];
         if ( char_name )
           for ( idx = 0; idx < type1->num_glyphs; idx++ )
           {
-            glyph_name = (FT_Byte*)type1->glyph_names[idx];
-            if ( ft_strcmp( (const char*)char_name,
-                            (const char*)glyph_name ) == 0 )
+            const FT_String*  glyph_name = type1->glyph_names[idx];
+
+
+            if ( ft_strcmp( char_name, glyph_name ) == 0 )
             {
               type1->encoding.char_index[charcode] = (FT_UShort)idx;
-              type1->encoding.char_name [charcode] = (char*)glyph_name;
+              type1->encoding.char_name [charcode] = glyph_name;
 
               /* Change min/max encoded char only if glyph name is */
               /* not /.notdef                                      */
-              if ( ft_strcmp( (const char*)".notdef",
-                              (const char*)glyph_name ) != 0 )
+              if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
               {
                 if ( charcode < min_char )
                   min_char = charcode;
@@ -153,6 +146,11 @@
 
   Exit:
     t42_loader_done( &loader );
+    if ( error )
+    {
+      FT_FREE( face->ttf_data );
+      face->ttf_size = 0;
+    }
     return error;
   }
 
@@ -354,7 +352,8 @@
 
         error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
         if ( error                                      &&
-             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
+             FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
+             FT_ERR_NEQ( error, Unimplemented_Feature ) )
           goto Exit;
         error = FT_Err_Ok;
 
@@ -510,7 +509,8 @@
 
 
     error = FT_New_Size( t42face->ttf_face, &ttsize );
-    t42size->ttsize = ttsize;
+    if ( !error )
+      t42size->ttsize = ttsize;
 
     FT_Activate_Size( ttsize );
 
@@ -582,6 +582,7 @@
     FT_Face        face    = t42slot->face;
     T42_Face       t42face = (T42_Face)face;
     FT_GlyphSlot   ttslot;
+    FT_Memory      memory  = face->memory;
     FT_Error       error   = FT_Err_Ok;
 
 
@@ -593,9 +594,15 @@
     else
     {
       error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot );
-      slot->ttslot = ttslot;
+      if ( !error )
+        slot->ttslot = ttslot;
     }
 
+    /* share the loader so that the autohinter can see it */
+    FT_GlyphLoader_Done( slot->ttslot->internal->loader );
+    FT_FREE( slot->ttslot->internal );
+    slot->ttslot->internal = t42slot->internal;
+
     return error;
   }
 
@@ -606,6 +613,8 @@
     T42_GlyphSlot  slot = (T42_GlyphSlot)t42slot;
 
 
+    /* do not destroy the inherited internal structure just yet */
+    slot->ttslot->internal = NULL;
     FT_Done_GlyphSlot( slot->ttslot );
   }
 
diff --git a/src/type42/t42objs.h b/src/type42/t42objs.h
index 332a43c..33e6215 100644
--- a/src/type42/t42objs.h
+++ b/src/type42/t42objs.h
@@ -4,7 +4,7 @@
  *
  *   Type 42 objects manager (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -19,15 +19,14 @@
 #ifndef T42OBJS_H_
 #define T42OBJS_H_
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TYPE1_TABLES_H
-#include FT_INTERNAL_TYPE1_TYPES_H
+#include <freetype/freetype.h>
+#include <freetype/t1tables.h>
+#include <freetype/internal/t1types.h>
 #include "t42types.h"
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DRIVER_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdrv.h>
+#include <freetype/internal/services/svpscmap.h>
+#include <freetype/internal/pshints.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type42/t42parse.c b/src/type42/t42parse.c
index edd27a8..6d765c8 100644
--- a/src/type42/t42parse.c
+++ b/src/type42/t42parse.c
@@ -4,7 +4,7 @@
  *
  *   Type 42 font parser (body).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -18,9 +18,9 @@
 
 #include "t42parse.h"
 #include "t42error.h"
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psaux.h>
 
 
   /**************************************************************************
@@ -30,7 +30,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t42
+#define FT_COMPONENT  t42
 
 
   static void
@@ -92,7 +92,7 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_BBOX
 
-    T1_FIELD_BBOX("FontBBox", xMin, 0 )
+    T1_FIELD_BBOX( "FontBBox", xMin, 0 )
 
     T1_FIELD_CALLBACK( "FontMatrix",  t42_parse_font_matrix, 0 )
     T1_FIELD_CALLBACK( "Encoding",    t42_parse_encoding,    0 )
@@ -197,7 +197,7 @@
     else
     {
       /* read segment in memory */
-      if ( FT_ALLOC( parser->base_dict, size )       ||
+      if ( FT_QALLOC( parser->base_dict, size )      ||
            FT_STREAM_READ( parser->base_dict, size ) )
         goto Exit;
 
@@ -226,7 +226,8 @@
     if ( !parser->in_memory )
       FT_FREE( parser->base_dict );
 
-    parser->root.funcs.done( &parser->root );
+    if ( parser->root.funcs.done )
+      parser->root.funcs.done( &parser->root );
   }
 
 
@@ -362,8 +363,8 @@
 
       /* we use a T1_Table to store our charnames */
       loader->num_chars = encode->num_chars = count;
-      if ( FT_NEW_ARRAY( encode->char_index, count )     ||
-           FT_NEW_ARRAY( encode->char_name,  count )     ||
+      if ( FT_QNEW_ARRAY( encode->char_index, count )    ||
+           FT_QNEW_ARRAY( encode->char_name,  count )    ||
            FT_SET_ERROR( psaux->ps_table_funcs->init(
                            char_table, count, memory ) ) )
       {
@@ -373,12 +374,7 @@
 
       /* We need to `zero' out encoding_table.elements */
       for ( n = 0; n < count; n++ )
-      {
-        char*  notdef = (char *)".notdef";
-
-
-        (void)T1_Add_Table( char_table, n, notdef, 8 );
-      }
+        (void)T1_Add_Table( char_table, n, ".notdef", 8 );
 
       /* Now we need to read records of the form                */
       /*                                                        */
@@ -542,7 +538,8 @@
     FT_Byte*    limit  = parser->root.limit;
     FT_Error    error;
     FT_Int      num_tables = 0;
-    FT_Long     count;
+    FT_Long     ttf_count;
+    FT_Long     ttf_reserved;
 
     FT_ULong    n, string_size, old_string_size, real_size;
     FT_Byte*    string_buf = NULL;
@@ -550,6 +547,9 @@
 
     T42_Load_Status  status;
 
+    /** There should only be one sfnts array, but free any previous. */
+    FT_FREE( face->ttf_data );
+    face->ttf_size = 0;
 
     /* The format is                                */
     /*                                              */
@@ -578,7 +578,13 @@
     status          = BEFORE_START;
     string_size     = 0;
     old_string_size = 0;
-    count           = 0;
+    ttf_count       = 0;
+    ttf_reserved    = 12;
+    if ( FT_QALLOC( face->ttf_data, ttf_reserved ) )
+      goto Fail;
+
+    FT_TRACE2(( "\n" ));
+    FT_TRACE2(( "t42_parse_sfnts:\n" ));
 
     while ( parser->root.cursor < limit )
     {
@@ -590,11 +596,20 @@
       if ( *cur == ']' )
       {
         parser->root.cursor++;
+        face->ttf_size = ttf_count;
         goto Exit;
       }
 
       else if ( *cur == '<' )
       {
+        if ( string_buf && !allocated )
+        {
+          FT_ERROR(( "t42_parse_sfnts: "
+                     "can't handle mixed binary and hex strings\n" ));
+          error = FT_THROW( Invalid_File_Format );
+          goto Fail;
+        }
+
         T1_Skip_PS_Token( parser );
         if ( parser->root.error )
           goto Exit;
@@ -607,7 +622,7 @@
           error = FT_THROW( Invalid_File_Format );
           goto Fail;
         }
-        if ( FT_REALLOC( string_buf, old_string_size, string_size ) )
+        if ( FT_QREALLOC( string_buf, old_string_size, string_size ) )
           goto Fail;
 
         allocated = 1;
@@ -676,6 +691,9 @@
         goto Fail;
       }
 
+      FT_TRACE2(( "  PS string size %5lu bytes, offset 0x%08lx (%lu)\n",
+                  string_size, ttf_count, ttf_count ));
+
       /* The whole TTF is now loaded into `string_buf'.  We are */
       /* checking its contents while copying it to `ttf_data'.  */
 
@@ -687,50 +705,64 @@
         {
         case BEFORE_START:
           /* load offset table, 12 bytes */
-          if ( count < 12 )
+          if ( ttf_count < 12 )
           {
-            face->ttf_data[count++] = string_buf[n];
+            face->ttf_data[ttf_count++] = string_buf[n];
             continue;
           }
           else
           {
-            num_tables     = 16 * face->ttf_data[4] + face->ttf_data[5];
-            status         = BEFORE_TABLE_DIR;
-            face->ttf_size = 12 + 16 * num_tables;
+            FT_Long ttf_reserved_prev = ttf_reserved;
 
-            if ( (FT_Long)size < face->ttf_size )
+
+            num_tables   = 16 * face->ttf_data[4] + face->ttf_data[5];
+            status       = BEFORE_TABLE_DIR;
+            ttf_reserved = 12 + 16 * num_tables;
+
+            FT_TRACE2(( "  SFNT directory contains %d tables\n",
+                        num_tables ));
+
+            if ( (FT_Long)size < ttf_reserved )
             {
               FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
               error = FT_THROW( Invalid_File_Format );
               goto Fail;
             }
 
-            if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) )
+            if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev,
+                              ttf_reserved ) )
               goto Fail;
           }
-          /* fall through */
+          FALL_THROUGH;
 
         case BEFORE_TABLE_DIR:
           /* the offset table is read; read the table directory */
-          if ( count < face->ttf_size )
+          if ( ttf_count < ttf_reserved )
           {
-            face->ttf_data[count++] = string_buf[n];
+            face->ttf_data[ttf_count++] = string_buf[n];
             continue;
           }
           else
           {
             int       i;
             FT_ULong  len;
+            FT_Long ttf_reserved_prev = ttf_reserved;
 
 
+            FT_TRACE2(( "\n" ));
+            FT_TRACE2(( "  table    length\n" ));
+            FT_TRACE2(( "  ------------------------------\n" ));
+
             for ( i = 0; i < num_tables; i++ )
             {
               FT_Byte*  p = face->ttf_data + 12 + 16 * i + 12;
 
 
               len = FT_PEEK_ULONG( p );
+              FT_TRACE2(( "   %4i  0x%08lx (%lu)\n", i, len, len ));
+
               if ( len > size                               ||
-                   face->ttf_size > (FT_Long)( size - len ) )
+                   ttf_reserved > (FT_Long)( size - len ) )
               {
                 FT_ERROR(( "t42_parse_sfnts:"
                            " invalid data in sfnts array\n" ));
@@ -739,26 +771,31 @@
               }
 
               /* Pad to a 4-byte boundary length */
-              face->ttf_size += (FT_Long)( ( len + 3 ) & ~3U );
+              ttf_reserved += (FT_Long)( ( len + 3 ) & ~3U );
             }
+            ttf_reserved += 1;
 
             status = OTHER_TABLES;
 
-            if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
-                             face->ttf_size + 1 ) )
+            FT_TRACE2(( "\n" ));
+            FT_TRACE2(( "  allocating %ld bytes\n", ttf_reserved ));
+            FT_TRACE2(( "\n" ));
+
+            if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev,
+                              ttf_reserved ) )
               goto Fail;
           }
-          /* fall through */
+          FALL_THROUGH;
 
         case OTHER_TABLES:
           /* all other tables are just copied */
-          if ( count >= face->ttf_size )
+          if ( ttf_count >= ttf_reserved )
           {
             FT_ERROR(( "t42_parse_sfnts: too much binary data\n" ));
             error = FT_THROW( Invalid_File_Format );
             goto Fail;
           }
-          face->ttf_data[count++] = string_buf[n];
+          face->ttf_data[ttf_count++] = string_buf[n];
         }
       }
 
@@ -772,6 +809,11 @@
     parser->root.error = error;
 
   Exit:
+    if ( parser->root.error )
+    {
+      FT_FREE( face->ttf_data );
+      face->ttf_size = 0;
+    }
     if ( allocated )
       FT_FREE( string_buf );
   }
@@ -822,7 +864,7 @@
       if ( loader->num_glyphs > ( limit - parser->root.cursor ) >> 2 )
       {
         FT_TRACE0(( "t42_parse_charstrings: adjusting number of glyphs"
-                    " (from %d to %d)\n",
+                    " (from %d to %ld)\n",
                     loader->num_glyphs,
                     ( limit - parser->root.cursor ) >> 2 ));
         loader->num_glyphs = ( limit - parser->root.cursor ) >> 2;
@@ -966,9 +1008,9 @@
         name_table->elements[n][len] = '\0';
 
         /* record index of /.notdef */
-        if ( *cur == '.'                                              &&
+        if ( *cur == '.'                                                &&
              ft_strcmp( ".notdef",
-                        (const char*)(name_table->elements[n]) ) == 0 )
+                        (const char*)( name_table->elements[n] ) ) == 0 )
         {
           notdef_index = n;
           notdef_found = 1;
@@ -1013,8 +1055,7 @@
     }
 
     /* if /.notdef does not occupy index 0, do our magic. */
-    if ( ft_strcmp( (const char*)".notdef",
-                    (const char*)name_table->elements[0] ) )
+    if ( ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )
     {
       /* Swap glyph in index 0 with /.notdef glyph.  First, add index 0  */
       /* name and code entries to swap_table.  Then place notdef_index   */
diff --git a/src/type42/t42parse.h b/src/type42/t42parse.h
index d9b9a69..5741c54 100644
--- a/src/type42/t42parse.h
+++ b/src/type42/t42parse.h
@@ -4,7 +4,7 @@
  *
  *   Type 42 font parser (specification).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -21,7 +21,7 @@
 
 
 #include "t42objs.h"
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/internal/psaux.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type42/t42types.h b/src/type42/t42types.h
index 7d0230e..0bfe14e 100644
--- a/src/type42/t42types.h
+++ b/src/type42/t42types.h
@@ -4,7 +4,7 @@
  *
  *   Type 42 font data types (specification only).
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * Roberto Alameda.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -20,11 +20,10 @@
 #define T42TYPES_H_
 
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_TYPE1_TABLES_H
-#include FT_INTERNAL_TYPE1_TYPES_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include <freetype/freetype.h>
+#include <freetype/t1tables.h>
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/pshints.h>
 
 
 FT_BEGIN_HEADER
diff --git a/src/type42/type42.c b/src/type42/type42.c
index 187c5ed..8d2302c 100644
--- a/src/type42/type42.c
+++ b/src/type42/type42.c
@@ -4,7 +4,7 @@
  *
  *   FreeType Type 42 driver component.
  *
- * Copyright 2002-2018 by
+ * Copyright (C) 2002-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -17,7 +17,6 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
 
 #include "t42drivr.c"
 #include "t42objs.c"
diff --git a/src/winfonts/Jamfile b/src/winfonts/Jamfile
deleted file mode 100644
index 4385e3b..0000000
--- a/src/winfonts/Jamfile
+++ /dev/null
@@ -1,16 +0,0 @@
-# FreeType 2 src/winfonts Jamfile
-#
-# Copyright 2001-2018 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.
-
-SubDir  FT2_TOP $(FT2_SRC_DIR) winfonts ;
-
-Library  $(FT2_LIB) : winfnt.c ;
-
-# end of src/winfonts Jamfile
diff --git a/src/winfonts/fnterrs.h b/src/winfonts/fnterrs.h
index 08fceb0..dafdb07 100644
--- a/src/winfonts/fnterrs.h
+++ b/src/winfonts/fnterrs.h
@@ -4,7 +4,7 @@
  *
  *   Win FNT/FON error codes (specification only).
  *
- * Copyright 2001-2018 by
+ * Copyright (C) 2001-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -26,7 +26,7 @@
 #ifndef FNTERRS_H_
 #define FNTERRS_H_
 
-#include FT_MODULE_ERRORS_H
+#include <freetype/ftmoderr.h>
 
 #undef FTERRORS_H_
 
@@ -34,7 +34,7 @@
 #define FT_ERR_PREFIX  FNT_Err_
 #define FT_ERR_BASE    FT_Mod_Err_Winfonts
 
-#include FT_ERRORS_H
+#include <freetype/fterrors.h>
 
 #endif /* FNTERRS_H_ */
 
diff --git a/src/winfonts/module.mk b/src/winfonts/module.mk
index 13f9077..78a2900 100644
--- a/src/winfonts/module.mk
+++ b/src/winfonts/module.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/winfonts/rules.mk b/src/winfonts/rules.mk
index d694d1a..b39c519 100644
--- a/src/winfonts/rules.mk
+++ b/src/winfonts/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2018 by
+# Copyright (C) 1996-2023 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c
index 70fc827..fa73ae4 100644
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -4,7 +4,7 @@
  *
  *   FreeType font driver for Windows FNT/FON files
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  * Copyright 2003 Huw D M Davies for Codeweavers
  * Copyright 2007 Dmitry Timoshkov for Codeweavers
@@ -18,17 +18,16 @@
  */
 
 
-#include <ft2build.h>
-#include FT_WINFONTS_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_TRUETYPE_IDS_H
+#include <freetype/ftwinfnt.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/ttnameid.h>
 
 #include "winfnt.h"
 #include "fnterrs.h"
-#include FT_SERVICE_WINFNT_H
-#include FT_SERVICE_FONT_FORMAT_H
+#include <freetype/internal/services/svwinfnt.h>
+#include <freetype/internal/services/svfntfmt.h>
 
   /**************************************************************************
    *
@@ -37,7 +36,7 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_winfnt
+#define FT_COMPONENT  winfnt
 
 
   static const FT_Frame_Field  winmz_header_fields[] =
@@ -218,7 +217,11 @@
     /* first of all, read the FNT header */
     if ( FT_STREAM_SEEK( font->offset )                        ||
          FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) )
+    {
+      FT_TRACE2(( "  not a Windows FNT file\n" ));
+      error = FT_THROW( Unknown_File_Format );
       goto Exit;
+    }
 
     /* check header */
     if ( header->version != 0x200 &&
@@ -285,7 +288,10 @@
     /* does it begin with an MZ header? */
     if ( FT_STREAM_SEEK( 0 )                                      ||
          FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) )
+    {
+      error = FT_ERR( Unknown_File_Format );
       goto Exit;
+    }
 
     error = FT_ERR( Unknown_File_Format );
     if ( mz_header.magic == WINFNT_MZ_MAGIC )
@@ -331,7 +337,7 @@
         {
           FT_TRACE2(( "invalid alignment shift count for resource data\n" ));
           error = FT_THROW( Invalid_File_Format );
-          goto Exit;
+          goto Exit1;
         }
 
 
@@ -346,6 +352,10 @@
 
           count = FT_GET_USHORT_LE();
 
+          FT_TRACE2(( type_id == 0x8007U ? "RT_FONTDIR count %hu\n" :
+                      type_id == 0x8008U ? "RT_FONT count %hu\n" : "",
+                                           count ));
+
           if ( type_id == 0x8008U )
           {
             font_count  = count;
@@ -421,12 +431,12 @@
           goto Exit;
 
         FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, "
-                    "size_of_optional_header %02x\n"
-                    "magic32 %02x, rsrc_virtual_address %04lx, "
-                    "rsrc_size %04lx\n",
+                    "size_of_optional_header %02x\n",
                     pe32_header.magic, pe32_header.machine,
                     pe32_header.number_of_sections,
-                    pe32_header.size_of_optional_header,
+                    pe32_header.size_of_optional_header ));
+        FT_TRACE2(( "magic32 %02x, rsrc_virtual_address %04lx, "
+                    "rsrc_size %04lx\n",
                     pe32_header.magic32, pe32_header.rsrc_virtual_address,
                     pe32_header.rsrc_size ));
 
@@ -479,7 +489,7 @@
                                       &dir_entry1 )                )
             goto Exit;
 
-          if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )
+          if ( !( dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )
           {
             error = FT_THROW( Invalid_File_Format );
             goto Exit;
@@ -503,7 +513,7 @@
                                         &dir_entry2 )                )
               goto Exit;
 
-            if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )
+            if ( !( dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )
             {
               error = FT_THROW( Invalid_File_Format );
               goto Exit;
@@ -597,6 +607,10 @@
 
   Exit:
     return error;
+
+  Exit1:
+    FT_FRAME_EXIT();
+    goto Exit;
   }
 
 
@@ -790,7 +804,7 @@
         root->style_flags |= FT_STYLE_FLAG_BOLD;
 
       /* set up the `fixed_sizes' array */
-      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
+      if ( FT_QNEW( root->available_sizes ) )
         goto Fail;
 
       root->num_fixed_sizes = 1;
@@ -882,10 +896,10 @@
       }
       family_size = font->header.file_size - font->header.face_name_offset;
       /* Some broken fonts don't delimit the face name with a final */
-      /* NULL byte -- the frame is erroneously one byte too small.  */
+      /* null byte -- the frame is erroneously one byte too small.  */
       /* We thus allocate one more byte, setting it explicitly to   */
       /* zero.                                                      */
-      if ( FT_ALLOC( font->family_name, family_size + 1 ) )
+      if ( FT_QALLOC( font->family_name, family_size + 1 ) )
         goto Fail;
 
       FT_MEM_COPY( font->family_name,
@@ -894,9 +908,10 @@
 
       font->family_name[family_size] = '\0';
 
-      if ( FT_REALLOC( font->family_name,
-                       family_size,
-                       ft_strlen( font->family_name ) + 1 ) )
+      /* shrink it to the actual length */
+      if ( FT_QREALLOC( font->family_name,
+                        family_size + 1,
+                        ft_strlen( font->family_name ) + 1 ) )
         goto Fail;
 
       root->family_name = font->family_name;
@@ -1091,7 +1106,7 @@
 
       /* note: since glyphs are stored in columns and not in rows we */
       /*       can't use ft_glyphslot_set_bitmap                     */
-      if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, pitch ) )
+      if ( FT_QALLOC_MULT( bitmap->buffer, bitmap->rows, pitch ) )
         goto Exit;
 
       column = (FT_Byte*)bitmap->buffer;
diff --git a/src/winfonts/winfnt.h b/src/winfonts/winfnt.h
index 0161939..2f75b9e 100644
--- a/src/winfonts/winfnt.h
+++ b/src/winfonts/winfnt.h
@@ -4,7 +4,7 @@
  *
  *   FreeType font driver for Windows FNT/FON files
  *
- * Copyright 1996-2018 by
+ * Copyright (C) 1996-2023 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  * Copyright 2007 Dmitry Timoshkov for Codeweavers
  *
@@ -21,9 +21,8 @@
 #define WINFNT_H_
 
 
-#include <ft2build.h>
-#include FT_WINFONTS_H
-#include FT_INTERNAL_DRIVER_H
+#include <freetype/ftwinfnt.h>
+#include <freetype/internal/ftdrv.h>
 
 
 FT_BEGIN_HEADER
@@ -150,9 +149,6 @@
     FT_FaceRec     root;
     FNT_Font       font;
 
-    FT_CharMap     charmap_handle;
-    FT_CharMapRec  charmap;  /* a single charmap per face */
-
   } FNT_FaceRec, *FNT_Face;
 
 
diff --git a/subprojects/harfbuzz.wrap b/subprojects/harfbuzz.wrap
new file mode 100644
index 0000000..341be63
--- /dev/null
+++ b/subprojects/harfbuzz.wrap
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = harfbuzz-5.2.0
+source_url = https://github.com/harfbuzz/harfbuzz/releases/download/5.2.0/harfbuzz-5.2.0.tar.xz
+source_filename = harfbuzz-5.2.0.tar.xz
+source_hash = 735a94917b47936575acb4d4fa7e7986522f8a89527e4635721474dee2bc942c
+wrapdb_version = 5.2.0-1
+
+[provide]
+harfbuzz = libharfbuzz_dep
+harfbuzz-icu = libharfbuzz_icu_dep
+harfbuzz-subset = libharfbuzz_subset_dep
+harfbuzz-gobject = libharfbuzz_gobject_dep
diff --git a/subprojects/libpng.wrap b/subprojects/libpng.wrap
new file mode 100644
index 0000000..12ba5b1
--- /dev/null
+++ b/subprojects/libpng.wrap
@@ -0,0 +1,12 @@
+[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
+
+[provide]
+libpng = libpng_dep
diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap
new file mode 100644
index 0000000..23af071
--- /dev/null
+++ b/subprojects/zlib.wrap
@@ -0,0 +1,12 @@
+[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
+
+[provide]
+zlib = zlib_dep
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..0d0b99a
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,22 @@
+# Unit and regression tests for the FreeType library
+
+## Quick Start
+
+### Download test fonts
+
+Run the `tests/scripts/download-fonts.py` script, which will
+download test fonts to the `tests/data/` directory first.
+
+### Build the test programs
+
+The tests are only built with the Meson build system, and
+are disabled by default, enable the 'tests' option to compile
+them, as in:
+
+  meson setup out -Dtests=enabled
+  meson compile -C out
+
+### Run the test programs
+
+  meson test -C out
+
diff --git a/tests/issue-1063/main.c b/tests/issue-1063/main.c
new file mode 100644
index 0000000..fd5404e
--- /dev/null
+++ b/tests/issue-1063/main.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+
+#include <freetype/freetype.h>
+#include <ft2build.h>
+
+
+int
+main( void )
+{
+  FT_Library  library;
+  FT_Face     face = NULL;
+
+  /*
+   * We assume that `FREETYPE_TESTS_DATA_DIR` was set by `meson test`.
+   * Otherwise we default to `../tests/data`.
+   *
+   * TODO (David): Rewrite this to pass the test directory through the
+   * command-line.
+   */
+  const char*  testdata_dir = getenv( "FREETYPE_TESTS_DATA_DIR" );
+  char         filepath[FILENAME_MAX];
+
+
+  snprintf( filepath, sizeof( filepath ), "%s/%s",
+            testdata_dir ? testdata_dir : "../tests/data",
+            "As.I.Lay.Dying.ttf" );
+
+  FT_Init_FreeType( &library );
+  if ( FT_New_Face( library, filepath, 0, &face ) != 0 )
+  {
+    fprintf( stderr, "Could not open file: %s\n", filepath );
+    return 1;
+  }
+
+  for ( FT_ULong  i = 59; i < 171; i++ )
+  {
+    FT_UInt   gid  = FT_Get_Char_Index( face, i );
+    FT_Error  code = FT_Load_Glyph( face, gid, FT_LOAD_DEFAULT );
+
+
+    if ( code )
+      printf( "unknown %d for char %lu, gid %u\n", code, i, gid );
+  }
+
+  return 0;
+}
+
+/* EOF */
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 0000000..527998f
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,14 @@
+test_issue_1063 = executable('issue-1063',
+  files([ 'issue-1063/main.c' ]),
+  dependencies: freetype_dep,
+)
+
+test_env = ['FREETYPE_TESTS_DATA_DIR='
+            + join_paths(meson.current_source_dir(), 'data')]
+
+test('issue-1063',
+  test_issue_1063,
+  env: test_env,
+  suite: 'regression')
+
+# EOF
diff --git a/tests/scripts/download-test-fonts.py b/tests/scripts/download-test-fonts.py
new file mode 100755
index 0000000..52b742e
--- /dev/null
+++ b/tests/scripts/download-test-fonts.py
@@ -0,0 +1,302 @@
+#!/usr/bin/env python3
+
+"""Download test fonts used by the FreeType regression test programs.  These
+will be copied to $FREETYPE/tests/data/ by default."""
+
+import argparse
+import collections
+import hashlib
+import io
+import os
+import requests
+import sys
+import zipfile
+
+from typing import Callable, List, Optional, Tuple
+
+# The list of download items describing the font files to install.  Each
+# download item is a dictionary with one of the following schemas:
+#
+# - File item:
+#
+#      file_url
+#        Type: URL string.
+#        Required: Yes.
+#        Description: URL to download the file from.
+#
+#      install_name
+#        Type: file name string
+#        Required: No
+#        Description: Installation name for the font file, only provided if
+#          it must be different from the original URL's basename.
+#
+#      hex_digest
+#        Type: hexadecimal string
+#        Required: No
+#        Description: Digest of the input font file.
+#
+# - Zip items:
+#
+#   These items correspond to one or more font files that are embedded in a
+#   remote zip archive.  Each entry has the following fields:
+#
+#      zip_url
+#        Type: URL string.
+#        Required: Yes.
+#        Description: URL to download the zip archive from.
+#
+#      zip_files
+#        Type: List of file entries (see below)
+#        Required: Yes
+#        Description: A list of entries describing a single font file to be
+#          extracted from the archive
+#
+# Apart from that, some schemas are used for dictionaries used inside
+# download items:
+#
+# - File entries:
+#
+#   These are dictionaries describing a single font file to extract from an
+#   archive.
+#
+#      filename
+#        Type: file path string
+#        Required: Yes
+#        Description: Path of source file, relative to the archive's
+#          top-level directory.
+#
+#      install_name
+#        Type: file name string
+#        Required: No
+#        Description: Installation name for the font file; only provided if
+#          it must be different from the original filename value.
+#
+#      hex_digest
+#        Type: hexadecimal string
+#        Required: No
+#        Description: Digest of the input source file
+#
+_DOWNLOAD_ITEMS = [
+    {
+        "zip_url": "https://github.com/python-pillow/Pillow/files/6622147/As.I.Lay.Dying.zip",
+        "zip_files": [
+            {
+                "filename": "As I Lay Dying.ttf",
+                "install_name": "As.I.Lay.Dying.ttf",
+                "hex_digest": "ef146bbc2673b387",
+            },
+        ],
+    },
+]
+
+
+def digest_data(data: bytes):
+    """Compute the digest of a given input byte string, which are the first
+    8 bytes of its sha256 hash."""
+    m = hashlib.sha256()
+    m.update(data)
+    return m.digest()[:8]
+
+
+def check_existing(path: str, hex_digest: str):
+    """Return True if |path| exists and matches |hex_digest|."""
+    if not os.path.exists(path) or hex_digest is None:
+        return False
+
+    with open(path, "rb") as f:
+        existing_content = f.read()
+
+    return bytes.fromhex(hex_digest) == digest_data(existing_content)
+
+
+def install_file(content: bytes, dest_path: str):
+    """Write a byte string to a given destination file.
+
+    Args:
+      content: Input data, as a byte string
+      dest_path: Installation path
+    """
+    parent_path = os.path.dirname(dest_path)
+    if not os.path.exists(parent_path):
+        os.makedirs(parent_path)
+
+    with open(dest_path, "wb") as f:
+        f.write(content)
+
+
+def download_file(url: str, expected_digest: Optional[bytes] = None):
+    """Download a file from a given URL.
+
+    Args:
+      url: Input URL
+      expected_digest: Optional digest of the file
+        as a byte string
+    Returns:
+      URL content as binary string.
+    """
+    r = requests.get(url, allow_redirects=True)
+    content = r.content
+    if expected_digest is not None:
+        digest = digest_data(r.content)
+        if digest != expected_digest:
+            raise ValueError(
+                "%s has invalid digest %s (expected %s)"
+                % (url, digest.hex(), expected_digest.hex())
+            )
+
+    return content
+
+
+def extract_file_from_zip_archive(
+    archive: zipfile.ZipFile,
+    archive_name: str,
+    filepath: str,
+    expected_digest: Optional[bytes] = None,
+):
+    """Extract a file from a given zipfile.ZipFile archive.
+
+    Args:
+      archive: Input ZipFile objec.
+      archive_name: Archive name or URL, only used to generate a
+        human-readable error message.
+
+      filepath: Input filepath in archive.
+      expected_digest: Optional digest for the file.
+    Returns:
+      A new File instance corresponding to the extract file.
+    Raises:
+      ValueError if expected_digest is not None and does not match the
+      extracted file.
+    """
+    file = archive.open(filepath)
+    if expected_digest is not None:
+        digest = digest_data(archive.open(filepath).read())
+        if digest != expected_digest:
+            raise ValueError(
+                "%s in zip archive at %s has invalid digest %s (expected %s)"
+                % (filepath, archive_name, digest.hex(), expected_digest.hex())
+            )
+    return file.read()
+
+
+def _get_and_install_file(
+    install_path: str,
+    hex_digest: Optional[str],
+    force_download: bool,
+    get_content: Callable[[], bytes],
+) -> bool:
+    if not force_download and hex_digest is not None \
+      and os.path.exists(install_path):
+        with open(install_path, "rb") as f:
+            content: bytes = f.read()
+        if bytes.fromhex(hex_digest) == digest_data(content):
+            return False
+
+    content = get_content()
+    install_file(content, install_path)
+    return True
+
+
+def download_and_install_item(
+    item: dict, install_dir: str, force_download: bool
+) -> List[Tuple[str, bool]]:
+    """Download and install one item.
+
+    Args:
+      item: Download item as a dictionary, see above for schema.
+      install_dir: Installation directory.
+      force_download: Set to True to force download and installation, even
+        if the font file is already installed with the right content.
+
+    Returns:
+      A list of (install_name, status) tuples, where 'install_name' is the
+      file's installation name under 'install_dir', and 'status' is a
+      boolean that is True to indicate that the file was downloaded and
+      installed, or False to indicate that the file is already installed
+      with the right content.
+    """
+    if "file_url" in item:
+        file_url = item["file_url"]
+        install_name = item.get("install_name", os.path.basename(file_url))
+        install_path = os.path.join(install_dir, install_name)
+        hex_digest = item.get("hex_digest")
+
+        def get_content():
+            return download_file(file_url, hex_digest)
+
+        status = _get_and_install_file(
+            install_path, hex_digest, force_download, get_content
+        )
+        return [(install_name, status)]
+
+    if "zip_url" in item:
+        # One or more files from a zip archive.
+        archive_url = item["zip_url"]
+        archive = zipfile.ZipFile(io.BytesIO(download_file(archive_url)))
+
+        result = []
+        for f in item["zip_files"]:
+            filename = f["filename"]
+            install_name = f.get("install_name", filename)
+            hex_digest = f.get("hex_digest")
+
+            def get_content():
+                return extract_file_from_zip_archive(
+                    archive,
+                    archive_url,
+                    filename,
+                    bytes.fromhex(hex_digest) if hex_digest else None,
+                )
+
+            status = _get_and_install_file(
+                os.path.join(install_dir, install_name),
+                hex_digest,
+                force_download,
+                get_content,
+            )
+            result.append((install_name, status))
+
+        return result
+
+    else:
+        raise ValueError("Unknown download item schema: %s" % item)
+
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+
+    # Assume this script is under tests/scripts/ and tests/data/
+    # is the default installation directory.
+    install_dir = os.path.normpath(
+        os.path.join(os.path.dirname(__file__), "..", "data")
+    )
+
+    parser.add_argument(
+        "--force",
+        action="store_true",
+        default=False,
+        help="Force download and installation of font files",
+    )
+
+    parser.add_argument(
+        "--install-dir",
+        default=install_dir,
+        help="Specify installation directory [%s]" % install_dir,
+    )
+
+    args = parser.parse_args()
+
+    for item in _DOWNLOAD_ITEMS:
+        for install_name, status in download_and_install_item(
+            item, args.install_dir, args.force
+        ):
+            print("%s %s" % (install_name,
+                             "INSTALLED" if status else "UP-TO-DATE"))
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
+
+# EOF
diff --git a/version.sed b/version.sed
deleted file mode 100644
index c281ff5..0000000
--- a/version.sed
+++ /dev/null
@@ -1,5 +0,0 @@
-#! /usr/bin/sed -nf
-
-s/^#define  *FREETYPE_MAJOR  *\([^ ][^ ]*\).*$/freetype_major="\1" ;/p
-s/^#define  *FREETYPE_MINOR  *\([^ ][^ ]*\).*$/freetype_minor=".\1" ;/p
-s/^#define  *FREETYPE_PATCH  *\([^ ][^ ]*\).*$/freetype_patch=".\1" ;/p
diff --git a/vms_make.com b/vms_make.com
index 7b8a49b..a1ccb65 100644
--- a/vms_make.com
+++ b/vms_make.com
@@ -1,6 +1,6 @@
 $! make FreeType 2 under OpenVMS
 $!
-$! Copyright 2003-2018 by
+$! Copyright (C) 2003-2023 by
 $! David Turner, Robert Wilhelm, and Werner Lemberg.
 $!
 $! This file is part of the FreeType project, and may only be used, modified,
@@ -47,13 +47,13 @@
 $! Setup variables holding "config" information
 $!
 $ Make    = ""
-$ ccopt   = "/name=as_is/float=ieee"
+$ ccopt   = "/name=(as_is,short)/float=ieee"
 $ lopts   = ""
 $ dnsrl   = ""
 $ aconf_in_file = "config.hin"
 $ name    = "Freetype2"
-$ mapfile =  name + ".map"
-$ optfile =  name + ".opt"
+$ mapfile = name + ".map"
+$ optfile = name + ".opt"
 $ s_case  = false
 $ liblist = ""
 $!
@@ -113,7 +113,14 @@
 $ If f$getsyi("HW_MODEL") .gt. 1024
 $ Then
 $   write sys$output "Creating freetype2shr.exe"
-$   call anal_obj_axp 'optfile' _link.opt
+$   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
@@ -157,7 +164,7 @@
 #
 
 
-# Copyright 2001 by
+# 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,
@@ -172,15 +179,16 @@
 
 
 all :
-        define freetype [--.include]
-        define psaux [-.psaux]
+        define config [--.include.freetype.config]
+        define internal [--.include.freetype.internal]
         define autofit [-.autofit]
-        define autohint [-.autohint]
         define base [-.base]
         define cache [-.cache]
         define cff [-.cff]
         define cid [-.cid]
+        define freetype [--.include.freetype]
         define pcf [-.pcf]
+        define psaux [-.psaux]
         define psnames [-.psnames]
         define raster [-.raster]
         define sfnt [-.sfnt]
@@ -191,9 +199,7 @@
         if f$search("lib.dir") .eqs. "" then create/directory [.lib]
         set default [.builds.vms]
         $(MMS)$(MMSQUALIFIERS)
-#        set default [--.src.autofit]
-#        $(MMS)$(MMSQUALIFIERS)
-        set default [--.src.autohint]
+        set default [--.src.autofit]
         $(MMS)$(MMSQUALIFIERS)
         set default [-.base]
         $(MMS)$(MMSQUALIFIERS)
@@ -205,8 +211,12 @@
         $(MMS)$(MMSQUALIFIERS)
         set default [-.cid]
         $(MMS)$(MMSQUALIFIERS)
+        set default [-.gxvalid]
+        $(MMS)$(MMSQUALIFIERS)
         set default [-.gzip]
         $(MMS)$(MMSQUALIFIERS)
+        set default [-.bzip2]
+        $(MMS)$(MMSQUALIFIERS)
         set default [-.lzw]
         $(MMS)$(MMSQUALIFIERS)
         set default [-.otvalid]
@@ -250,7 +260,7 @@
 #
 
 
-# Copyright 2001 by
+# 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,
@@ -260,7 +270,7 @@
 # fully.
 
 
-CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([],[--.include],[--.src.base])
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
 
 OBJS=ftsystem.obj
 
@@ -282,7 +292,7 @@
 #
 
 
-# Copyright 2002 by
+# Copyright 2002-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -293,39 +303,7 @@
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.autofit])
 
-OBJS=afangles.obj,afhints.obj,aflatin.obj
-
-all : $(OBJS)
-        library [--.lib]freetype.olb $(OBJS)
-
-# EOF
-$ eod
-$ close out
-$ write sys$output "... [.src.autohint] directory"
-$ create [.src.autohint]descrip.mms
-$ open/append out [.src.autohint]descrip.mms
-$ copy sys$input: out
-$ deck
-#
-# FreeType 2 auto-hinter module compilation rules for VMS
-#
-
-
-# Copyright 2001, 2002 Catharon Productions Inc.
-#
-# This file is part of the Catharon Typography Project and shall only
-# be used, modified, and distributed under the terms of the Catharon
-# Open Source License that should come with this file under the name
-# `CatharonLicense.txt'.  By continuing to use, modify, or distribute
-# this file you indicate that you have read the license and
-# understand and accept it fully.
-#
-# Note that this license is compatible with the FreeType license.
-
-
-CFLAGS=$(COMP_FLAGS)$(DEBUG)/incl=([--.include],[--.src.autohint])
-
-OBJS=autohint.obj
+OBJS=autofit.obj
 
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
@@ -343,7 +321,7 @@
 #
 
 
-# Copyright 2001, 2003 by
+# 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,
@@ -355,9 +333,22 @@
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base])
 
-OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,\
-     fttype1.obj,ftpfr.obj,ftstroke.obj,ftwinfnt.obj,ftbbox.obj,\
-     ftbitmap.obj,ftgasp.obj
+OBJS=ftbase.obj,\
+     ftbbox.obj,\
+     ftbdf.obj,\
+     ftbitmap.obj,\
+     ftcid.obj,\
+     ftdebug.obj,\
+     ftfstype.obj,\
+     ftgasp.obj,\
+     ftglyph.obj,\
+     ftinit.obj,\
+     ftmm.obj,\
+     ftpfr.obj,\
+     ftstroke.obj,\
+     ftsynth.obj,\
+     fttype1.obj,\
+     ftwinfnt.obj
 
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
@@ -375,7 +366,7 @@
 #
 
 
-# Copyright 2002 by
+# Copyright 2002-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -405,7 +396,7 @@
 #
 
 
-# Copyright 2001, 2002, 2003, 2004 by
+# 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,
@@ -415,16 +406,13 @@
 # fully.
 
 
-CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cache])
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cache])/nowarn
 
 OBJS=ftcache.obj
 
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
 
-ftcache.obj : ftcache.c ftcbasic.c ftccache.c ftccmap.c ftcglyph.c ftcimage.c \
-              ftcmanag.c ftcmru.c ftcsbits.c
-
 # EOF
 $ eod
 $ close out
@@ -438,7 +426,7 @@
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -468,7 +456,7 @@
 #
 
 
-# Copyright 2001 by
+# 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,
@@ -488,6 +476,36 @@
 # EOF
 $ eod
 $ close out
+$ write sys$output "... [.src.gxvalid] directory"
+$ create [.src.gxvalid]descrip.mms
+$ open/append out [.src.gxvalid]descrip.mms
+$ copy sys$input: out
+$ deck
+#
+# FreeType 2 TrueTypeGX/AAT validation driver configuration rules for VMS
+#
+
+
+# Copyright 2004-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.gxvalid])
+
+OBJS=gxvalid.obj
+
+all : $(OBJS)
+        library [--.lib]freetype.olb $(OBJS)
+
+# EOF
+$ eod
+$ close out
 $ write sys$output "... [.src.gzip] directory"
 $ create [.src.gzip]descrip.mms
 $ open/append out [.src.gzip]descrip.mms
@@ -498,7 +516,7 @@
 #
 
 
-# Copyright 2002 by
+# Copyright 2002-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -522,6 +540,42 @@
 # EOF
 $ eod
 $ close out
+$ write sys$output "... [.src.bzip2] directory"
+$ create [.src.bzip2]descrip.mms
+$ open/append out [.src.bzip2]descrip.mms
+$ copy sys$input: out
+$ deck
+#
+# FreeType 2 BZIP2 support compilation rules for VMS
+#
+
+
+# Copyright 2010-2019 by
+# Joel Klinghed.
+#
+# based on `src/lzw/rules.mk'
+#
+# 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.
+$EOD
+$ if libincs .nes. "" then write out "LIBINCS = ", libincs - ",", ","
+$ write out "COMP_FLAGS = ", ccopt
+$ copy sys$input: out
+$ deck
+
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.bzip2])
+
+OBJS=ftbzip2.obj
+
+all : $(OBJS)
+        library [--.lib]freetype.olb $(OBJS)
+
+# EOF
+$ eod
+$ close out
 $ write sys$output "... [.src.lzw] directory"
 $ create [.src.lzw]descrip.mms
 $ open/append out [.src.lzw]descrip.mms
@@ -532,7 +586,7 @@
 #
 
 
-# Copyright 2004 by
+# Copyright 2004-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -556,38 +610,6 @@
 # EOF
 $ eod
 $ close out
-$ write sys$output "... [.src.otlayout] directory"
-$ create [.src.otlayout]descrip.mms
-$ open/append out [.src.otlayout]descrip.mms
-$ copy sys$input: out
-$ deck
-#
-# FreeType 2 OT layout compilation rules for VMS
-#
-
-
-# Copyright 2004 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.otlayout])
-
-OBJS=otlbase.obj,otlcommn.obj,otlgdef.obj,otlgpos.obj,otlgsub.obj,\
-     otljstf.obj,otlparse.obj
-
-all : $(OBJS)
-        library [--.lib]freetype.olb $(OBJS)
-
-
-# EOF
-$ eod
-$ close out
 $ write sys$output "... [.src.otvalid] directory"
 $ create [.src.otvalid]descrip.mms
 $ open/append out [.src.otvalid]descrip.mms
@@ -598,7 +620,7 @@
 #
 
 
-# Copyright 2004 by
+# Copyright 2004-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -670,7 +692,7 @@
 #
 
 
-# Copyright 2002 by
+# Copyright 2002-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -700,7 +722,7 @@
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -730,7 +752,7 @@
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -756,11 +778,11 @@
 $ copy sys$input: out
 $ deck
 #
-# FreeType 2 PSNames driver compilation rules for VMS
+# FreeType 2 psnames driver compilation rules for VMS
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -790,7 +812,7 @@
 #
 
 
-# Copyright 2001 by
+# 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,
@@ -820,7 +842,7 @@
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -850,7 +872,7 @@
 #
 
 
-# Copyright 2001 by
+# 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,
@@ -880,7 +902,7 @@
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -910,7 +932,7 @@
 #
 
 
-# Copyright 1996-2000, 2002 by
+# 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,
@@ -927,8 +949,6 @@
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
 
-type1.obj : type1.c t1parse.c t1load.c t1objs.c t1driver.c t1gload.c t1afm.c
-
 # EOF
 $ eod
 $ close out
@@ -942,7 +962,7 @@
 #
 
 
-# Copyright 2002 by
+# Copyright 2002-2019 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -972,7 +992,7 @@
 #
 
 
-# Copyright 2001, 2002 by
+# 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,
@@ -1103,7 +1123,7 @@
 $!
 $! Init symbols used to hold CPP definitions and include path
 $!
-$ libdefs = ""
+$ libdefs = "FT2_BUILD_LIBRARY,FT_CONFIG_OPTION_OLD_INTERNALS,"
 $ libincs = ""
 $!
 $! Open data file with location of libraries