summaryrefslogtreecommitdiffstats
path: root/testing/freetype-infinality/upstream-2014.10.08.patch
diff options
context:
space:
mode:
Diffstat (limited to 'testing/freetype-infinality/upstream-2014.10.08.patch')
-rw-r--r--testing/freetype-infinality/upstream-2014.10.08.patch6990
1 files changed, 6990 insertions, 0 deletions
diff --git a/testing/freetype-infinality/upstream-2014.10.08.patch b/testing/freetype-infinality/upstream-2014.10.08.patch
new file mode 100644
index 000000000..a51911886
--- /dev/null
+++ b/testing/freetype-infinality/upstream-2014.10.08.patch
@@ -0,0 +1,6990 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index a4e583d..df77d96 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -16,11 +16,16 @@
+ #
+ # cmake CMakeLists.txt
+ #
+-# to create a Makefile that builds a static version of the library. For a
+-# dynamic library, use
++# to create a Makefile that builds a static version of the library.
++#
++# For a dynamic library, use
+ #
+ # cmake CMakeLists.txt -DBUILD_SHARED_LIBS:BOOL=true
+ #
++# For a framework on OS X, use
++#
++# cmake CMakeLists.txt -DBUILD_FRAMEWORK:BOOL=true -G Xcode
++#
+ # instead. Please refer to the cmake manual for further options, in
+ # particular, how to modify compilation and linking parameters.
+ #
+@@ -39,6 +44,14 @@ cmake_minimum_required(VERSION 2.6)
+
+ project(freetype)
+
++if (BUILD_FRAMEWORK)
++ if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
++ message(FATAL_ERROR "You should use Xcode generator with BUILD_FRAMEWORK enabled")
++ endif ()
++ set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
++ set(BUILD_SHARED_LIBS ON)
++endif ()
++
+ set(VERSION_MAJOR "2")
+ set(VERSION_MINOR "5")
+ set(VERSION_PATCH "3")
+@@ -51,22 +64,27 @@ add_definitions(-DFT2_BUILD_LIBRARY)
+ include_directories("${PROJECT_SOURCE_DIR}/include")
+
+ # Create the configuration file
+-message(STATUS "Creating directory, ${PROJECT_BINARY_DIR}/include.")
+-file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include)
++message(STATUS "Creating directory, ${PROJECT_BINARY_DIR}/include/freetype2.")
++file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/freetype2)
+
+ # For the auto-generated ftconfig.h file
+-include_directories("${PROJECT_BINARY_DIR}/include")
+-message(STATUS "Creating ${PROJECT_BINARY_DIR}/include/ftconfig.h.")
++include_directories(BEFORE "${PROJECT_BINARY_DIR}/include/freetype2")
++message(STATUS "Creating ${PROJECT_BINARY_DIR}/include/freetype2/ftconfig.h.")
+ execute_process(
+ COMMAND sed -e "s/FT_CONFIG_OPTIONS_H/<ftoption.h>/" -e "s/FT_CONFIG_STANDARD_LIBRARY_H/<ftstdlib.h>/" -e "s?/undef ?#undef ?"
+ INPUT_FILE ${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.in
+- OUTPUT_FILE ${PROJECT_BINARY_DIR}/include/ftconfig.h
++ OUTPUT_FILE ${PROJECT_BINARY_DIR}/include/freetype2/ftconfig.h
+ )
+
++file(GLOB PUBLIC_HEADERS "include/*.h")
++file(GLOB PUBLIC_CONFIG_HEADERS "include/config/*.h")
++file(GLOB PRIVATE_HEADERS "include/internal/*.h")
++
+ set(BASE_SRCS
+ src/autofit/autofit.c
+ src/base/ftadvanc.c
+ src/base/ftbbox.c
++ src/base/ftbdf.c
+ src/base/ftbitmap.c
+ src/base/ftcalc.c
+ src/base/ftcid.c
+@@ -125,7 +143,31 @@ include_directories("src/raster")
+ include_directories("src/psaux")
+ include_directories("src/psnames")
+
+-add_library(freetype ${BASE_SRCS})
++if (BUILD_FRAMEWORK)
++ set(BASE_SRCS
++ ${BASE_SRCS}
++ builds/mac/freetype-Info.plist
++ )
++endif ()
++
++add_library(freetype
++ ${PUBLIC_HEADERS}
++ ${PUBLIC_CONFIG_HEADERS}
++ ${PRIVATE_HEADERS}
++ ${BASE_SRCS}
++)
++
++if (BUILD_FRAMEWORK)
++ set_property(SOURCE ${PUBLIC_CONFIG_HEADERS}
++ PROPERTY MACOSX_PACKAGE_LOCATION Headers/config
++ )
++ set_target_properties(freetype PROPERTIES
++ FRAMEWORK TRUE
++ MACOSX_FRAMEWORK_INFO_PLIST builds/mac/freetype-Info.plist
++ PUBLIC_HEADER "${PUBLIC_HEADERS}"
++ XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
++ )
++endif ()
+
+ # Installations
+ # Note the trailing slash in the argument to the `DIRECTORY' directive
+@@ -137,6 +179,7 @@ install(TARGETS freetype
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
++ FRAMEWORK DESTINATION Library/Frameworks
+ )
+
+ # Packaging
+diff --git a/ChangeLog b/ChangeLog
+index ea1eb4a..4e17454 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,703 @@
++2014-10-02 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Significant optimization of `ft_div64by32'
++
++ We shift as many bits as we can into the high register, perform
++ 32-bit division with modulo there, then work through the remaining
++ bits with long division. This optimization is especially noticeable
++ for smaller dividends that barely use the high register.
++
++ * src/base/ftcalc.c (ft_div64by32): Updated.
++
++2014-10-02 Dave Arnold <darnold@adobe.com>
++
++ [cff] Fix Savannah bug #43271.
++
++ * src/cff/cf2font.c (cf2_computeDarkening): Change overflow
++ detection to use logarithms and clamp `scaledStem'.
++
++2014-10-01 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/base/ftcalc.c: Remove miscellaneous type casts.
++
++2014-10-01 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Use more common `FT_MSB' implementation with masks.
++
++ * src/base/ftcalc.c (FT_MSB): Updated.
++
++2014-09-30 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Clean up.
++
++ * src/base/ftcalc.c (FT_MOVE_SIGN): New macro for frequently used
++ code.
++
++2014-09-25 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Avoid unnecessary long division.
++
++ This applies to `FT_MulDiv' but not to `FT_DivFix', where overflows or
++ lack thereof are predicted accurately.
++
++ * src/base/ftcalc.c (ft_div64by32): Improve readability.
++ (FT_MulDiv, FT_MulDiv_No_Round) [!FT_LONG64]: Use straight division
++ when multiplication stayed within 32 bits.
++
++2014-09-24 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Minor clean-ups.
++
++ * src/autofit/afhints.c (AF_FLAGS): Remove obsolete values.
++
++ * src/autofit/afhints.c (af_glyph_hints_dump_points,
++ af_glyph_hints_align_strong_points): Updated.
++
++ * src/autofit/aflatin.c (af_latin_hints_link_segments,
++ af_latin_hints_compute_segments), src/autofit/afcjk.c
++ (af_cjk_hints_link_segments), src/autofit/aflatin2.c
++ (af_latin2_hints_link_segments, af_latin2_hints_compute_segments):
++ There are no longer fake segments since more than 10 years...
++
++2014-09-22 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Minor code streamlining.
++
++ * src/autofit/afhints.c (af_axis_hints_new_edge): Remove redundant
++ initialization.
++
++2014-09-19 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/base/ftcalc.c: Harmonize code.
++
++2014-09-15 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Tighten the overflow check in `FT_MulDiv'.
++
++ * src/base/ftcalc.c (FT_MulDiv) [!FT_LONG64]: Updated.
++
++2014-09-08 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ Fix Savannah bug #43153.
++
++ * src/psaux/psconv.c (PS_Conv_ToFixed): Add protection against
++ overflow in `divider'.
++
++2014-09-03 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Tighten the overflow check in `FT_DivFix'.
++
++ This fixes a 13-year old bug. The original overflow check should have
++ been updated when rounding was introduced into this function
++ (c2cd00443b).
++
++ * src/base/ftcalc.c (FT_DivFix) [!FT_LONG64]: Updated.
++ * include/freetype.h (FT_DivFix): Updated documentation.
++
++2014-09-03 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Tighten the overflow check in `FT_MulFix'.
++
++ * src/base/ftcalc.c (FT_MulFix) [!FT_LONG64]: Updated.
++
++2014-09-02 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [truetype] Shortcut ppem calculations for square pixels.
++
++ * src/truetype/ttinterp.h (TT_ExecContextRec): New field
++ `cur_ppem_func' with a function pointer.
++ * src/truetype/ttinterp.c (TT_RunIns): Initialize `cur_ppem_func'
++ depending on the pixel geometry to either...
++ (Current_Ppem_Stretched): ... this for stretched pixels.
++ (Current_Ppem): ... or this for square pixels.
++ (DO_MPPEM, DO_MPS, Ins_DELTAP, Ins_DELTAC): Use `cur_ppem_func'.
++
++2014-08-31 Behdad Esfahbod <behdad@behdad.org>
++
++ Don't use `register' keyword. Fixes compiler warnings.
++
++ * src/base/ftcalc.c (FT_Add64) [!FT_LONG64]: Do it.
++ * src/gzip/inftrees.c (huft_build): Ditto.
++ * src/truetype/ttinterp.c (TT_MulFix14_arm): Ditto.
++
++2014-08-24 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [truetype] Optimize DELTAP and DELTAC.
++
++ * src/truetype/ttinterp.c (Ins_DELTAP, Ins_DELTAC): Move ppem
++ calculations outside of the loop.
++
++2014-08-21 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ Fix Savannah bug #43033.
++
++ * include/config/ftconfig.h, builds/unix/ftconfig.in,
++ builds/vms/ftconfig.h [FT_LONG64]: Do not disable the macro when
++ 64-bit type is `long'.
++
++2014-08-20 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Small optimization of `FT_MulFix'.
++
++ * src/base/ftcalc.c (FT_MulFix): Loosen up the condition for direct
++ 32-bit calculations.
++
++2014-08-19 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Use unsigned calculation in `FT_MulDiv'.
++
++ * src/base/ftcalc.c (FT_MulDiv): Updated to expand 32-bit range.
++
++2014-08-18 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Remove truncation in `FT_DivFix'.
++
++ * src/base/ftcalc.c (FT_DivFix): Updated.
++
++2014-08-14 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ Minor refactoring.
++
++ * src/base/ftcalc.c (FT_MulDiv, FT_MulDiv_No_Round): Updated.
++
++2014-08-14 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ Turn FT_MSB into a macro when using gcc builtins.
++
++ * src/base/ftcalc.c, include/internal/ftcalc.h: Updated.
++
++2014-08-12 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Avoid undefined FT_MSB in `BBox_Cubic_Check'.
++
++ * src/base/ftbbox.c (BBox_Cubic_Check): Update.
++ (update_cubic_max): Repalce with...
++ (cubic_peak): ... this, which now handles upscaling.
++
++2014-08-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Handle collapsed outlines to avoid undefined FT_MSB.
++
++ * src/base/ftoutln.c (FT_Outline_Get_Orientation): Update.
++
++2014-08-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Restore FT_MulFix inlining.
++
++ * include/freetype.h (FT_MulFix): Unconditionally defined.
++
++ * src/base/ftcalc.c [FT_MULFIX_ASSEMBLER]: Move code from here...
++
++ * include/internal/ftcalc.h [FT_MULFIX_ASSEMBLER]: ... to here,
++ which conditionally replaces the function with an inline version
++ through the macro.
++
++2014-08-08 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/base/ftbitmap.c (ft_gray_for_premultiplied_srgb_bgra): Refactor.
++
++2014-07-26 Werner Lemberg <wl@gnu.org>
++
++ [cff] Fix typo.
++
++ * src/cff/cf2hints.c (cf2_glyphpath_computeOffset): Use correct
++ offsets in third quadrant.
++
++ Reported by maks <maksqwe1@ukr.net>.
++
++2014-07-17 Werner Lemberg <wl@gnu.org>
++
++ Fix Savannah bug #42788.
++
++ * src/pfr/pfrobjs.c: Include `ftcalc.h'.
++
++2014-07-16 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ Replace `ft_highpow2' function.
++
++ * src/pfr/pfrobjs.c (pfr_face_get_kerning): Use `FT_MSB' instead of
++ `ft_highpow2'.
++
++ * src/base/ftutil.c, include/internal/ftobjs.h (ft_highpow2): Remove
++ it.
++
++2014-07-15 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/base/ftcalc.c (FT_MSB): Utilize gcc builtins.
++
++2014-07-15 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Move assembler code back in the source file.
++
++ FT_MulFix assembler used to reside in ftcalc.c before f47d263f1b.
++
++ * include/config/ftconfig.h, builds/unix/ftconfig.in,
++ builds/vms/ftconfig.h [FT_MULFIX_ASSEMBLER]: Move code from here...
++
++ * src/base/ftcalc.c [FT_MULFIX_ASSEMBLER]: ... to here.
++
++2014-07-14 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Further clean up color bitmap conversion.
++
++ * src/base/ftbitmap.c (ft_gray_for_premultiplied_srgb_bgra): Stop
++ using FT_MulFix and FT_DivFix since all calculations fit into 32 bits.
++
++2014-07-13 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Improve handling of buggy `prep' tables.
++
++ In case of an error in the `prep' table, no longer try to execute it
++ again and again. This makes FreeType handle endless loops in buggy
++ fonts much faster.
++
++ * src/truetype/ttobjs.h (TT_SizeRec): The fields `bytecode_ready'
++ and `cvt_ready' are now negative if not initialized yet, otherwise
++ they indicate the error code of the last run.
++
++ * src/truetype/ttobjs.c (tt_size_run_fpgm, tt_size_run_prep,
++ tt_size_done_bytecode, tt_size_init_bytecode,
++ tt_size_ready_bytecode, tt_size_init, tt_size_done, tt_size_reset):
++ Updated.
++
++ * src/truetype/ttgload.c (tt_loader_init): Updated.
++ * src/truetype/ttinterp.c (TT_RunIns): Force reexecution of `fpgm'
++ and `prep' only if we are in the `glyf' table.
++
++2014-07-12 Werner Lemberg <wl@gnu.org>
++
++ * builds/vms/ftconfig.h: Synchronize.
++ Problem reported by Alexei.
++
++2014-07-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Clean up bitmap conversion.
++
++ * src/base/ftbitmap.c (ft_gray_for_premultiplied_srgb_bgra): Use
++ appropriate FT_DivFix and remove superfluous upscaling.
++
++2014-07-04 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [base] Small optimization of the ancient code.
++
++ * src/base/ftcalc.c (FT_MulDiv, FT_MulDiv_No_Round): Loosen up the
++ condition for direct 32-bit calculations.
++
++2014-06-27 Werner Lemberg <wl@gnu.org>
++
++ Fix Apple standard glyph names.
++
++ * src/sfnt/ttpost.c (tt_post_default_names): Synchronize with
++ `tools/glnames.py'
++
++ Problem reported by Adam Twardoch <adam@fontlab.com>.
++
++2014-06-17 Werner Lemberg <wl@gnu.org>
++
++ Partially revert commit from 2014-06-13.
++
++ * src/autofit/aflatin.c (af_latin_metrics_init_blues): Move
++ declaration of `p_first' and `p_last' out of the loop.
++
++2014-06-17 Werner Lemberg <wl@gnu.org>
++
++ * builds/unix/freetype2.m4: s/AC_PATH_PROG/AC_PATH_TOOL/.
++
++ This simplifies cross-compiling.
++
++2014-06-13 Werner Lemberg <wl@gnu.org>
++
++ Fix more compiler warnings.
++ Reported by Wojciech Mamrak <wmamrak@gmail.com>.
++
++ * src/autofit/afglobal.c (af_face_globals_compute_style_coverage):
++ Make integer constant unsigned.
++
++ * src/sfnt/ttsbit.c (tt_face_load_strike_metrics)
++ <TT_SBIT_TABLE_TYPE_SBIX>: Fix types.
++ (tt_sbit_decoder_load_compound, tt_face_load_sbix_image): Add proper
++ casts.
++
++2014-06-13 Werner Lemberg <wl@gnu.org>
++
++ Fix compiler warnings.
++ Reported by Wojciech Mamrak <wmamrak@gmail.com>.
++
++ * src/autofit/afglobal.c (af_face_globals_compute_style_coverage),
++ src/autofit/afmodule.c (af_property_set): Fix `signed' vs.
++ `unsigned' issues.
++
++ * src/autofit/aflatin.c (af_latin_metrics_init_blues): Make compiler
++ happy.
++
++ * src/base/ftlcdfil.c (_ft_lcd_filter_fir): Use only four elements
++ for `fir'.
++ Fix `signed' vs. `unsigned' issues.
++
++ * src/sfnt/sfobjs.c (WRITE_BYTE): Removed, unused.
++ (WRITE_USHORT, WRITE_ULONG): Add proper casts.
++
++ * src/truetype/ttgload.c (TT_Get_VMetrics): Add proper casts.
++
++ * src/truetype/ttinterp.c (Ins_DELTAP): Add proper casts for `B1'
++ and `B2'.
++
++2014-05-16 Alexey Petruchik <alexey.petruchik@gmail.com>
++
++ [cmake] Add option to build OS X framework.
++
++ * CMakeLists.txt: Update accordingly.
++
++ * builds/mac/freetype-Info.plist: New file.
++
++2014-05-13 Pavel Koshevoy <pkoshevoy@gmail.com>
++
++ * CMakeLists.txt (BASE_SRCS): Add missing `ftbdf.c'.
++
++2014-05-11 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Fix variable initializations.
++
++ * src/autofit/afhints.c (af_glyph_hints_reload): Assign default
++ values to `in_dir' and `out_dir' for all points.
++
++2014-05-11 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Fix crash with font `CabinSketch-Bold.ttf'.
++
++ Problem reported by Ralf S. Engelschall <rse@engelschall.com>.
++
++ * src/autofit/afhints.c (af_glyph_hints_reload): Fix threshold for
++ finding first non-near point.
++ Properly initialize non-near point deltas.
++
++2014-05-01 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Add blue-zone support for Devanagari.
++
++ This essentially moves the Devanagari script from the `Indic' hinter
++ to the `Latin' hinter. Thanks to Girish Dalvi
++ <girish.dalvi@gmail.com> for guidance with blue zone characters!
++
++ * src/autofit/afblue.dat: Add blue zone data for Devanagari.
++
++ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
++
++ * src/autofit/afscript.h: Add Devanagari standard characters and
++ move data out of AF_CONFIG_OPTION_INDIC block.
++
++ * src/autofit/afranges.c: Move Devanagari data out of
++ AF_CONFIG_OPTION_INDIC block.
++ Move U+20B9, (new) Rupee sign, from Latin to Devanagari.
++
++ * src/autofit/afstyles.h: Update Devanagari data; in particular, use
++ AF_WRITING_SYSTEM_LATIN.
++
++2014-05-01 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Fix handling of neutral blue zones in stems.
++
++ * src/autofit/afhints.h (AF_Edge_Flags): New value
++ `AF_EDGE_NEUTRAL'.
++
++ * src/autofit/aflatin.c (af_latin_hints_compute_blue_edges): Trace
++ neutral blue zones with AF_EDGE_NEUTRAL.
++ (af_latin_hint_edges): Skip neutral blue zones if necessary.
++
++2014-04-28 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Introduce neutral blue zones to the latin module.
++
++ Such blue zones match either the top or the bottom of a contour. We
++ need them for scripts where accent-like elements directly touch the
++ base character (for example, some vowel signs in Devanagari, cf.
++ U+0913 or U+0914).
++
++ * src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_NEUTRAL): New
++ property.
++
++ * src/autofit/afblue.h: Regenerated.
++
++ * src/autofit/aflatin.h (AF_LATIN_IS_NEUTRAL_BLUE): New macro.
++ (AF_LATIN_BLUE_NEUTRAL): New enumeration value.
++
++ * src/autofit/aflatin.c (af_latin_metrics_init_blues,
++ af_latin_hints_compute_blue_edges): Handle neutral blue zones.
++
++2014-04-25 Werner Lemberg <wl@gnu.org>
++
++ * src/autofit/hbshim.c: Partially revert commit from 2014-04-17.
++
++ Using input glyph coverage data is simply wrong.
++
++ Problem reported by Nikolaus Waxweiler <madigens@gmail.com> and
++ Mantas Mikulėnas <grawity@gmail.com>.
++
++2014-04-23 Werner Lemberg <wl@gnu.org>
++
++ * src/raster/ftraster.c (Vertical_Sweep_Span): Use drop-out mode.
++
++ This spot has been missed while introducing support for various
++ drop-out modes years ago (including no drop-out mode, which this
++ commit fixes).
++
++ Problem reported by Patrick Thomas <pthomas505@gmail.com>.
++
++2014-04-22 Werner Lemberg <wl@gnu.org>
++
++ * src/sfnt/pngshim.c (error_callback): s/longjmp/ft_longjmp/.
++
++2014-04-20 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Fix Savannah bug #42148.
++
++ The adaptation of the cjk auto-hinter module to blue stringsets in
++ 2013-08-25 had three severe bugs. Mea culpa.
++
++ 1. Contrary to the latin auto-hinter, characters for reference and
++ overshoot values of a blue zone are specified separately. Due to
++ the screwed-up change it didn't work at all.
++
++ 2. A boolean comparison was erroneously replaced with a cast,
++ causing invalid results with the `^' operator later on. The
++ visual artifact caused by this problem is the topic of the bug
++ report.
++
++ 3. Two flag values were inverted, causing incorrect assignment of
++ reference and overshoot values.
++
++ * src/autofit/afblue.dat: Fix CJK bluestrings, introducing a new
++ syntax to have both reference and overshoot characters in a single
++ string. This is error #1.
++ Add extensive comments.
++
++ * src/autofit/afblue.hin (AF_BLUE_PROPERTY_CJK_FILL): Removed, no
++ longer used.
++ (AF_BLUE_PROPERTY_CJK_TOP, AF_BLUE_PROPERTY_CJK_HORIZ): Fix values.
++ This is error #3.
++
++ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
++
++ * src/autofit/afcjk.c (af_cjk_metrics_init_blues): Correct error #1.
++ Use character `|' to separate characters for reference and overshoot
++ values.
++ Improve tracing messages, synchronizing them with the latin
++ auto-hinter.
++ (af_cjk_hints_compute_blue_edges): Fix value of `is_top_right_blue'.
++ This is error #2.
++ (af_cjk_align_linked_edge): Add tracing message.
++
++ * src/autofit/afcjk.h (AF_CJK_IS_FILLED_BLUE): Removed, no longer
++ used.
++
++2014-04-17 Werner Lemberg <wl@gnu.org>
++
++ [autofit] More coverage fixes for complex scripts.
++
++ * src/autofit/hbshim.c (af_get_coverage): Merge input glyph coverage
++ of GSUB lookups into output coverage. Otherwise, ligatures are not
++ handled properly.
++ Don't check blue zone characters for default coverage.
++
++2014-04-17 Werner Lemberg <wl@gnu.org>
++
++ Make `FT_Get_SubGlyph_Info' actually work.
++
++ * src/base/ftobjs.c (FT_Get_SubGlyph_Info): Return FT_Err_Ok
++ if there is no error.
++
++2014-04-15 Werner Lemberg <wl@gnu.org>
++
++ [afblue.pl]: Minor improvements.
++
++ * src/tools/afblue.pl: Allow whitespace before comments.
++ Ignore whitespace in strings.
++
++2014-04-14 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Improve coverage handling.
++
++ * src/autofit/hbshim.c (af_get_coverage): Don't exclude glyphs
++ appearing in the GPOS table if we are processing the default
++ coverage.
++
++2014-04-13 David Weber <weber.aulendorf@googlemail.com>
++
++ [smooth] Fix stand-alone compilation.
++
++ * src/smooth/ftgrays.c (FT_BEGIN_STMNT, FT_END_STMNT): Define.
++
++2014-04-12 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Redesign the recognition algorithm of strong points.
++
++ In particular, local extrema without horizontal or vertical segments
++ are better recognized:
++
++ + A + D
++ \ /
++ \ /
++ \ /
++ \ /
++ \ + C
++ \ /
++ B +/
++
++ If the distances AB and CD are large, point B wasn't previously
++ detected as an extremum since the `ft_corner_is_flat' function
++ `swallowed' BC regardless of its direction, tagging point B as weak.
++ The next iteration started at B and made `ft_corner_is_flat' swallow
++ point C, tagging it as weak also, et voilà.
++
++ To improve that, another pass gets now performed before calling
++ `ft_corner_is_flat' to improve the `topology' of an outline: A
++ sequence of non-horizontal or non-vertical vectors that point into
++ the same quadrant are handled as a single, large vector.
++
++ Additionally, distances of near points are now accumulated, which
++ makes the auto-hinter handle them as if they were prepended to the
++ next non-near vector.
++
++ This generally improves the auto-hinter's rendering results.
++
++ * src/autofit/afhints.c (af_glyph_hints_reload): Implement it.
++
++ * src/autofit/afhints.h (AF_FLAGS): Remove no longer used flag
++ `AF_FLAG_NEAR'.
++
++2014-04-05 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Improve scoring algorithm for identifying stems.
++
++ Problem reported by Karsten Lücke <karsten.luecke@kltf.de>.
++
++ The new algorithm takes care of the width of stems: If the distance
++ between two segments is larger than the largest stem width, the
++ demerits quickly increase for larger distances. This improves
++ hinting of slanted fonts (especially if the inner parts of serifs
++ have non-horizontal `shoulders'), avoiding false stem links.
++
++ * src/autofit/aflatin.c (af_latin_hints_link_segments): Use largest
++ stem width (if available) to compute better demerits for distances
++ between stems.
++ (af_latin_hints_detect_features): Pass stem width array and array
++ size.
++ (af_latin_metrics_init_widths): Updated to use original algorithm.
++ (af_latin_hints_apply): Updated to use new algorithm.
++
++ * src/autofit/aflatin.h: Updated.
++ * src/autofit/afcjk.c: Updated.
++
++2014-04-03 Werner Lemberg <wl@gnu.org>
++
++ Don't require `gzip' module for `sfnt'.
++
++ Reported by Preet <prismatic.project@gmail.com>.
++
++ * src/sfnt/sfobjs.c (woff_open_font): Guard use of
++ FT_Gzip_Uncompress with FT_CONFIG_OPTION_USE_ZLIB.
++
++2014-03-27 Werner Lemberg <wl@gnu.org>
++
++ Fix Savannah bug #38235.
++
++ Work around a bug in pkg-config version 0.28 and earlier: If a
++ variable value gets surrounded by doublequotes (in particular values
++ for the `prefix' variable), the prefix override mechanism fails.
++
++ * builds/unix/freetype2.in: Don't use doublequotes.
++ * builds/unix/unix-def.in (freetype.pc): Escape spaces in directory
++ names with backslashes.
++
++2014-03-24 Werner Lemberg <wl@gnu.org>
++
++ Fix Savannah bug #41946.
++
++ Based on a patch from Marek Kašík <mkasik@redhat.com>.
++
++ * builds/unix/configure.raw (LIBS_CONFIG): Remove.
++ * builds/unix/freetype-config.in (libs): Hard-code value.
++ * builds/unix/unix-def.in: Updated.
++
++2014-03-22 Werner Lemberg <wl@gnu.org>
++
++ Another revert for the change from 2014-03-18.
++
++ Problem reported by Nikolaus Waxweiler <madigens@gmail.com>.
++
++ * src/base/ftcalc.c (FT_MulFix): Ensure that an `FT_MulFix' symbol
++ gets always exported.
++
++2014-03-20 Werner Lemberg <wl@gnu.org>
++
++ CMakeLists.txt: Another fix for include directories.
++
++ Problem reported by Taylor Holberton <taylorcholberton@gmail.com>.
++
++2014-03-19 Werner Lemberg <wl@gnu.org>
++
++ CMakeLists.txt: Fix include directories.
++
++ Problem reported by Taylor Holberton <taylorcholberton@gmail.com>.
++
++2014-03-19 Werner Lemberg <wl@gnu.org>
++
++ Partially revert last commit.
++
++ Found by Alexei.
++
++ * src/autofit/aflatin.c (af_latin_metrics_init_blues): Initializing
++ those variables is plain wrong, since we are in a loop.
++
++2014-03-18 Sean McBride <sean@rogue-research.com>
++ Werner Lemberg <wl@gnu.org>
++
++ Fix clang warnings.
++
++ * src/autofit/aflatin.c (af_latin_metrics_init_blues): Initialize
++ some variables.
++
++ * src/base/ftcalc.c (FT_MulFix): Only use code if
++ `FT_MULFIX_INLINED' is not defined.
++
++ * src/bdf/bdfdrivr.c (bdf_cmap_class), src/cache/ftcbasic.c
++ (ftc_basic_image_family_class, ftc_basic_image_cache_class,
++ ftc_basic_sbit_family_class, ftc_basic_sbit_cache_class),
++ src/cache/ftccmap.c (ftc_cmap_cache_class), src/cache/ftcmanag.c
++ (ftc_size_list_class, ftc_face_list_class), src/pcf/pcfdrivr.c
++ (pcf_cmap_class), src/pfr/pfrdrivr.c (pfr_metrics_service_rec): Make
++ function static.
++
++ * src/type1/t1driver.c (t1_ps_get_font_value): Remove redundant
++ code.
++
++2014-03-17 Werner Lemberg <wl@gnu.org>
++
++ Fix Savannah bug #41869.
++
++ This works around a problem with HarfBuzz (<= 0.9.26), which doesn't
++ validate glyph indices returned by
++ `hb_ot_layout_lookup_collect_glyphs'.
++
++ * src/autofit/hbshim.c (af_get_coverage): Guard `idx'.
++
++ * docs/CHANGES: Updated.
++
++2014-03-14 Werner Lemberg <wl@gnu.org>
++
++ * builds/unix/configure.raw: Don't show error messages of `which'.
++
++2014-03-09 Alan Coopersmith <alan.coopersmith@oracle.com>
++
++ Fix cppcheck 1.64 warning.
++
++ * src/autofit/afglobal.c (af_face_globals_new): Catch NULL pointer
++ dereference in case of error.
++
++2014-03-09 Sean McBride <sean@rogue-research.com>
++
++ * src/sfnt/ttcmap.c (tt_face_build_cmaps): Remove clang warning.
++
+ 2014-03-06 Werner Lemberg <wl@gnu.org>
+
+ * Version 2.5.3 released.
+diff --git a/builds/mac/freetype-Info.plist b/builds/mac/freetype-Info.plist
+new file mode 100644
+index 0000000..b3d114d
+--- /dev/null
++++ b/builds/mac/freetype-Info.plist
+@@ -0,0 +1,36 @@
++<?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">
++
++<plist version="1.0">
++
++<dict>
++ <key>CFBundleDevelopmentRegion</key>
++ <string>English</string>
++
++ <key>CFBundleExecutable</key>
++ <string>FreeType</string>
++
++ <key>CFBundleGetInfoString</key>
++ <string>FreeType ${PROJECT_VERSION}</string>
++
++ <key>CFBundleInfoDictionaryVersion</key>
++ <string>6.0</string>
++
++ <key>CFBundleName</key>
++ <string>FreeType</string>
++
++ <key>CFBundlePackageType</key>
++ <string>FMWK</string>
++
++ <key>CFBundleShortVersionString</key>
++ <string>${PROJECT_VERSION}</string>
++
++ <key>CFBundleSignature</key>
++ <string>????</string>
++
++ <key>CFBundleVersion</key>
++ <string>${PROJECT_VERSION}</string>
++</dict>
++
++</plist>
+diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw
+index dd7e576..8a17ffe 100644
+--- a/builds/unix/configure.raw
++++ b/builds/unix/configure.raw
+@@ -437,7 +437,7 @@ if test x"$with_png" = xyes -o x"$with_png" = xauto; then
+ else
+ # fall back to config script.
+ AC_MSG_CHECKING([for libpng-config])
+- if which libpng-config > /dev/null; then
++ if which libpng-config > /dev/null 2>&1; then
+ LIBPNG_CFLAGS=`libpng-config --cflags`
+ LIBPNG_LIBS=`libpng-config --ldflags`
+ libpng_libpriv=`libpng-config --static --ldflags`
+@@ -656,7 +656,7 @@ else
+ fi
+
+
+-# Whether to use FileManager which is deprecated since Mac OS X 10.4.
++# Whether to use FileManager, which is deprecated since Mac OS X 10.4.
+
+ AC_ARG_WITH([fsspec],
+ AS_HELP_STRING([--with-fsspec],
+@@ -765,7 +765,7 @@ elif test x$with_old_mac_fonts = xyes -a x$with_fsref != x; then
+ fi
+
+
+-# Whether to use QuickDraw API in ToolBox which is deprecated since
++# Whether to use QuickDraw API in ToolBox, which is deprecated since
+ # Mac OS X 10.4.
+
+ AC_ARG_WITH([quickdraw-toolbox],
+@@ -807,7 +807,7 @@ elif test x$with_old_mac_fonts = xyes -a x$with_quickdraw_toolbox != x; then
+ fi
+
+
+-# Whether to use QuickDraw API in Carbon which is deprecated since
++# Whether to use QuickDraw API in Carbon, which is deprecated since
+ # Mac OS X 10.4.
+
+ AC_ARG_WITH([quickdraw-carbon],
+@@ -937,21 +937,6 @@ LIBS_PRIVATE=`echo "$LIBS_PRIVATE" \
+ -e 's/ *$//' \
+ -e 's/ */ /g'`
+
+-LIBS_CONFIG="-lfreetype \
+- $ZLIB_LIBS \
+- $BZIP2_LIBS \
+- $LIBPNG_LIBS \
+- $HARFBUZZ_LIBS \
+- $ft2_extra_libs"
+-# remove -L/usr/lib and -L/usr/lib64 since `freetype-config' adds them later
+-# on if necessary; also beautify
+-LIBS_CONFIG=`echo "$LIBS_CONFIG" \
+- | sed -e 's|-L */usr/lib64/* | |g' \
+- -e 's|-L */usr/lib/* | |g' \
+- -e 's/^ *//' \
+- -e 's/ *$//' \
+- -e 's/ */ /g'`
+-
+ LIBSSTATIC_CONFIG="-lfreetype \
+ $zlib_libstaticconf \
+ $bzip2_libstaticconf \
+@@ -971,7 +956,6 @@ LIBSSTATIC_CONFIG=`echo "$LIBSSTATIC_CONFIG" \
+ AC_SUBST([ftmac_c])
+ AC_SUBST([REQUIRES_PRIVATE])
+ AC_SUBST([LIBS_PRIVATE])
+-AC_SUBST([LIBS_CONFIG])
+ AC_SUBST([LIBSSTATIC_CONFIG])
+
+ AC_SUBST([hardcode_libdir_flag_spec])
+diff --git a/builds/unix/freetype-config.in b/builds/unix/freetype-config.in
+index 41c3a88..ebc311f 100644
+--- a/builds/unix/freetype-config.in
++++ b/builds/unix/freetype-config.in
+@@ -142,7 +142,7 @@ if test "$echo_cflags" = "yes" ; then
+ fi
+
+ if test "$echo_libs" = "yes" ; then
+- libs="%LIBS_CONFIG%"
++ libs="-lfreetype"
+ staticlibs="%LIBSSTATIC_CONFIG%"
+ if test "$show_static" = "yes" ; then
+ libs="$staticlibs"
+diff --git a/builds/unix/freetype2.in b/builds/unix/freetype2.in
+index 6e7fb10..a488d96 100644
+--- a/builds/unix/freetype2.in
++++ b/builds/unix/freetype2.in
+@@ -1,7 +1,7 @@
+-prefix="%prefix%"
+-exec_prefix="%exec_prefix%"
+-libdir="%libdir%"
+-includedir="%includedir%/freetype2"
++prefix=%prefix%
++exec_prefix=%exec_prefix%
++libdir=%libdir%
++includedir=%includedir%/freetype2
+
+ Name: FreeType 2
+ URL: http://freetype.org
+diff --git a/builds/unix/freetype2.m4 b/builds/unix/freetype2.m4
+index 3d0ecb3..3a806d9 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
+ #
+-# Copyright 2001, 2003, 2007, 2009 by
++# Copyright 2001, 2003, 2007, 2009, 2014 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 @@
+ # generated by Autoconf, under the same distribution terms as the rest of
+ # that program.
+ #
+-# serial 3
++# serial 4
+
+ # AC_CHECK_FT2([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+ # Test for FreeType 2, and define FT2_CFLAGS and FT2_LIBS.
+@@ -61,7 +61,7 @@ AC_DEFUN([AC_CHECK_FT2],
+ fi
+
+ if test "x$FT2_CONFIG" = x ; then
+- AC_PATH_PROG([FT2_CONFIG], [freetype-config], [no])
++ AC_PATH_TOOL([FT2_CONFIG], [freetype-config], [no])
+ fi
+
+ min_ft_version=m4_if([$1], [], [7.0.1], [$1])
+diff --git a/builds/unix/ftconfig.in b/builds/unix/ftconfig.in
+index 2cf6708..e66f3ea 100644
+--- a/builds/unix/ftconfig.in
++++ b/builds/unix/ftconfig.in
+@@ -296,7 +296,16 @@ FT_BEGIN_HEADER
+ #define FT_INT64 long
+ #define FT_UINT64 unsigned long
+
+-#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
++ /*************************************************************************/
++ /* */
++ /* A 64-bit data type may create compilation problems if you compile */
++ /* in strict ANSI mode. To avoid them, we disable other 64-bit data */
++ /* types if __STDC__ is defined. You can however ignore this rule */
++ /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
++ /* */
++#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
++
++#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
+
+ /* this compiler provides the __int64 type */
+ #define FT_LONG64
+@@ -330,30 +339,9 @@ FT_BEGIN_HEADER
+ #define FT_INT64 long long int
+ #define FT_UINT64 unsigned long long int
+
+-#endif /* FT_SIZEOF_LONG == 8 */
+-
+-
+- /*************************************************************************/
+- /* */
+- /* A 64-bit data type will create compilation problems if you compile */
+- /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */
+- /* is defined. You can however ignore this rule by defining the */
+- /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
+- /* */
+-#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )
+-
+-#ifdef __STDC__
+-
+- /* Undefine the 64-bit macros in strict ANSI compilation mode. */
+- /* Since `#undef' doesn't survive in configuration header files */
+- /* we use the postprocessing facility of AC_CONFIG_HEADERS to */
+- /* replace the leading `/' with `#'. */
+-/undef FT_LONG64
+-/undef FT_INT64
+-
+-#endif /* __STDC__ */
++#endif /* _MSC_VER */
+
+-#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
++#endif /* FT_SIZEOF_LONG == 8 */
+
+ #ifdef FT_LONG64
+ typedef FT_INT64 FT_Int64;
+@@ -366,219 +354,6 @@ FT_BEGIN_HEADER
+ #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT
+
+
+-#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
+- /* Provide assembler fragments for performance-critical functions. */
+- /* These must be defined `static __inline__' with GCC. */
+-
+-#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
+-
+- /* documentation is in freetype.h */
+-
+- static __inline FT_Int32
+- FT_MulFix_arm( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 t, t2;
+-
+-
+- __asm
+- {
+- smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
+- mov a, t, asr #31 /* a = (hi >> 31) */
+- add a, a, #0x8000 /* a += 0x8000 */
+- adds t2, t2, a /* t2 += a */
+- adc t, t, #0 /* t += carry */
+- mov a, t2, lsr #16 /* a = t2 >> 16 */
+- orr a, a, t, lsl #16 /* a |= t << 16 */
+- }
+- return a;
+- }
+-
+-#endif /* __CC_ARM || __ARMCC__ */
+-
+-
+-#ifdef __GNUC__
+-
+-#if defined( __arm__ ) && \
+- ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
+- !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
+-
+- /* documentation is in freetype.h */
+-
+- static __inline__ FT_Int32
+- FT_MulFix_arm( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 t, t2;
+-
+-
+- __asm__ __volatile__ (
+- "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
+- "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
+-#if defined( __clang__ ) && defined( __thumb2__ )
+- "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
+-#else
+- "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
+-#endif
+- "adds %1, %1, %0\n\t" /* %1 += %0 */
+- "adc %2, %2, #0\n\t" /* %2 += carry */
+- "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
+- "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
+- : "=r"(a), "=&r"(t2), "=&r"(t)
+- : "r"(a), "r"(b)
+- : "cc" );
+- return a;
+- }
+-
+-#endif /* __arm__ && */
+- /* ( __thumb2__ || !__thumb__ ) && */
+- /* !( __CC_ARM || __ARMCC__ ) */
+-
+-
+-#if defined( __i386__ )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
+-
+- /* documentation is in freetype.h */
+-
+- static __inline__ FT_Int32
+- FT_MulFix_i386( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 result;
+-
+-
+- __asm__ __volatile__ (
+- "imul %%edx\n"
+- "movl %%edx, %%ecx\n"
+- "sarl $31, %%ecx\n"
+- "addl $0x8000, %%ecx\n"
+- "addl %%ecx, %%eax\n"
+- "adcl $0, %%edx\n"
+- "shrl $16, %%eax\n"
+- "shll $16, %%edx\n"
+- "addl %%edx, %%eax\n"
+- : "=a"(result), "=d"(b)
+- : "a"(a), "d"(b)
+- : "%ecx", "cc" );
+- return result;
+- }
+-
+-#endif /* i386 */
+-
+-#endif /* __GNUC__ */
+-
+-
+-#ifdef _MSC_VER /* Visual C++ */
+-
+-#ifdef _M_IX86
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
+-
+- /* documentation is in freetype.h */
+-
+- static __inline FT_Int32
+- FT_MulFix_i386( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 result;
+-
+- __asm
+- {
+- mov eax, a
+- mov edx, b
+- imul edx
+- mov ecx, edx
+- sar ecx, 31
+- add ecx, 8000h
+- add eax, ecx
+- adc edx, 0
+- shr eax, 16
+- shl edx, 16
+- add eax, edx
+- mov result, eax
+- }
+- return result;
+- }
+-
+-#endif /* _M_IX86 */
+-
+-#endif /* _MSC_VER */
+-
+-
+-#if defined( __GNUC__ ) && defined( __x86_64__ )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64
+-
+- static __inline__ FT_Int32
+- FT_MulFix_x86_64( FT_Int32 a,
+- FT_Int32 b )
+- {
+- /* Temporarily disable the warning that C90 doesn't support */
+- /* `long long'. */
+-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wlong-long"
+-#endif
+-
+-#if 1
+- /* Technically not an assembly fragment, but GCC does a really good */
+- /* job at inlining it and generating good machine code for it. */
+- long long ret, tmp;
+-
+-
+- ret = (long long)a * b;
+- tmp = ret >> 63;
+- ret += 0x8000 + tmp;
+-
+- return (FT_Int32)( ret >> 16 );
+-#else
+-
+- /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */
+- /* code from the lines below. The main issue is that `wide_a' is not */
+- /* properly initialized by sign-extending `a'. Instead, the generated */
+- /* machine code assumes that the register that contains `a' on input */
+- /* can be used directly as a 64-bit value, which is wrong most of the */
+- /* time. */
+- long long wide_a = (long long)a;
+- long long wide_b = (long long)b;
+- long long result;
+-
+-
+- __asm__ __volatile__ (
+- "imul %2, %1\n"
+- "mov %1, %0\n"
+- "sar $63, %0\n"
+- "lea 0x8000(%1, %0), %0\n"
+- "sar $16, %0\n"
+- : "=&r"(result), "=&r"(wide_a)
+- : "r"(wide_b)
+- : "cc" );
+-
+- return (FT_Int32)result;
+-#endif
+-
+-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+-#pragma GCC diagnostic pop
+-#endif
+- }
+-
+-#endif /* __GNUC__ && __x86_64__ */
+-
+-#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
+-
+-
+-#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
+-#ifdef FT_MULFIX_ASSEMBLER
+-#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER
+-#endif
+-#endif
+-
+-
+ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+
+ #define FT_LOCAL( x ) static x
+diff --git a/builds/unix/unix-def.in b/builds/unix/unix-def.in
+index 35ea9c8..4c06a05 100644
+--- a/builds/unix/unix-def.in
++++ b/builds/unix/unix-def.in
+@@ -64,7 +64,6 @@ version_info := @version_info@
+ #
+ REQUIRES_PRIVATE := @REQUIRES_PRIVATE@
+ LIBS_PRIVATE := @LIBS_PRIVATE@
+-LIBS_CONFIG := @LIBS_CONFIG@
+ LIBSSTATIC_CONFIG := @LIBSSTATIC_CONFIG@
+ build_libtool_libs := @build_libtool_libs@
+ ft_version := @ft_version@
+@@ -102,8 +101,7 @@ NO_OUTPUT := 2> /dev/null
+
+ $(OBJ_BUILD)/freetype-config: $(TOP_DIR)/builds/unix/freetype-config.in
+ rm -f $@ $@.tmp
+- sed -e 's|%LIBS_CONFIG%|$(LIBS_CONFIG)|' \
+- -e 's|%LIBSSTATIC_CONFIG%|$(LIBSSTATIC_CONFIG)|' \
++ sed -e 's|%LIBSSTATIC_CONFIG%|$(LIBSSTATIC_CONFIG)|' \
+ -e 's|%build_libtool_libs%|$(build_libtool_libs)|' \
+ -e 's|%exec_prefix%|$(exec_prefix)|' \
+ -e 's|%ft_version%|$(ft_version)|' \
+@@ -116,16 +114,29 @@ $(OBJ_BUILD)/freetype-config: $(TOP_DIR)/builds/unix/freetype-config.in
+ chmod a-w $@.tmp
+ mv $@.tmp $@
+
++# To support directory names with spaces (as might easily happen on Windows
++# platforms), the right solution would be to surround the pkg-variables in
++# `freetype2.pc' with double quotes. However, doing so ironically disables
++# the prefix override mechanism especially written for Windows. This is a
++# bug in pkg-config version 0.28 and earlier.
++#
++# For this reason, we escape spaces with backslashes.
++
++exec_prefix_x := $(subst $(space),\\$(space),$(exec_prefix))
++includedir_x := $(subst $(space),\\$(space),$(includedir))
++libdir_x := $(subst $(space),\\$(space),$(libdir))
++prefix_x := $(subst $(space),\\$(space),$(prefix))
++
+ $(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)|' \
++ -e 's|%exec_prefix%|$(exec_prefix_x)|' \
+ -e 's|%ft_version%|$(ft_version)|' \
+- -e 's|%includedir%|$(includedir)|' \
+- -e 's|%libdir%|$(libdir)|' \
+- -e 's|%prefix%|$(prefix)|' \
++ -e 's|%includedir%|$(includedir_x)|' \
++ -e 's|%libdir%|$(libdir_x)|' \
++ -e 's|%prefix%|$(prefix_x)|' \
+ $< \
+ > $@.tmp
+ chmod a-w $@.tmp
+diff --git a/builds/vms/ftconfig.h b/builds/vms/ftconfig.h
+index 3fb8f84..b309651 100644
+--- a/builds/vms/ftconfig.h
++++ b/builds/vms/ftconfig.h
+@@ -4,7 +4,7 @@
+ /* */
+ /* VMS-specific configuration file (specification only). */
+ /* */
+-/* Copyright 1996-2004, 2006-2008, 2011, 2013 by */
++/* Copyright 1996-2004, 2006-2008, 2011, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -239,7 +239,16 @@ FT_BEGIN_HEADER
+ #define FT_INT64 long
+ #define FT_UINT64 unsigned long
+
+-#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
++ /*************************************************************************/
++ /* */
++ /* A 64-bit data type may create compilation problems if you compile */
++ /* in strict ANSI mode. To avoid them, we disable other 64-bit data */
++ /* types if __STDC__ is defined. You can however ignore this rule */
++ /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
++ /* */
++#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
++
++#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
+
+ /* this compiler provides the __int64 type */
+ #define FT_LONG64
+@@ -273,27 +282,9 @@ FT_BEGIN_HEADER
+ #define FT_INT64 long long int
+ #define FT_UINT64 unsigned long long int
+
+-#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+-
+-
+- /*************************************************************************/
+- /* */
+- /* A 64-bit data type will create compilation problems if you compile */
+- /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */
+- /* is defined. You can however ignore this rule by defining the */
+- /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
+- /* */
+-#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )
+-
+-#ifdef __STDC__
+-
+- /* undefine the 64-bit macros in strict ANSI compilation mode */
+-#undef FT_LONG64
+-#undef FT_INT64
+-
+-#endif /* __STDC__ */
++#endif /* _MSC_VER */
+
+-#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
++#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+
+ #ifdef FT_LONG64
+ typedef FT_INT64 FT_Int64;
+@@ -306,215 +297,6 @@ FT_BEGIN_HEADER
+ #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT
+
+
+-#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
+- /* Provide assembler fragments for performance-critical functions. */
+- /* These must be defined `static __inline__' with GCC. */
+-
+-#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
+-
+- /* documentation is in freetype.h */
+-
+- static __inline FT_Int32
+- FT_MulFix_arm( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 t, t2;
+-
+-
+- __asm
+- {
+- smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
+- mov a, t, asr #31 /* a = (hi >> 31) */
+- add a, a, #0x8000 /* a += 0x8000 */
+- adds t2, t2, a /* t2 += a */
+- adc t, t, #0 /* t += carry */
+- mov a, t2, lsr #16 /* a = t2 >> 16 */
+- orr a, a, t, lsl #16 /* a |= t << 16 */
+- }
+- return a;
+- }
+-
+-#endif /* __CC_ARM || __ARMCC__ */
+-
+-
+-#ifdef __GNUC__
+-
+-#if defined( __arm__ ) && \
+- ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
+- !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
+-
+- /* documentation is in freetype.h */
+-
+- static __inline__ FT_Int32
+- FT_MulFix_arm( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 t, t2;
+-
+-
+- __asm__ __volatile__ (
+- "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
+- "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
+- "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
+- "adds %1, %1, %0\n\t" /* %1 += %0 */
+- "adc %2, %2, #0\n\t" /* %2 += carry */
+- "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
+- "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
+- : "=r"(a), "=&r"(t2), "=&r"(t)
+- : "r"(a), "r"(b)
+- : "cc" );
+- return a;
+- }
+-
+-#endif /* __arm__ && */
+- /* ( __thumb2__ || !__thumb__ ) && */
+- /* !( __CC_ARM || __ARMCC__ ) */
+-
+-
+-#if defined( __i386__ )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
+-
+- /* documentation is in freetype.h */
+-
+- static __inline__ FT_Int32
+- FT_MulFix_i386( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 result;
+-
+-
+- __asm__ __volatile__ (
+- "imul %%edx\n"
+- "movl %%edx, %%ecx\n"
+- "sarl $31, %%ecx\n"
+- "addl $0x8000, %%ecx\n"
+- "addl %%ecx, %%eax\n"
+- "adcl $0, %%edx\n"
+- "shrl $16, %%eax\n"
+- "shll $16, %%edx\n"
+- "addl %%edx, %%eax\n"
+- : "=a"(result), "=d"(b)
+- : "a"(a), "d"(b)
+- : "%ecx", "cc" );
+- return result;
+- }
+-
+-#endif /* i386 */
+-
+-#endif /* __GNUC__ */
+-
+-
+-#ifdef _MSC_VER /* Visual C++ */
+-
+-#ifdef _M_IX86
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
+-
+- /* documentation is in freetype.h */
+-
+- static __inline FT_Int32
+- FT_MulFix_i386( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 result;
+-
+- __asm
+- {
+- mov eax, a
+- mov edx, b
+- imul edx
+- mov ecx, edx
+- sar ecx, 31
+- add ecx, 8000h
+- add eax, ecx
+- adc edx, 0
+- shr eax, 16
+- shl edx, 16
+- add eax, edx
+- mov result, eax
+- }
+- return result;
+- }
+-
+-#endif /* _M_IX86 */
+-
+-#endif /* _MSC_VER */
+-
+-
+-#if defined( __GNUC__ ) && defined( __x86_64__ )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64
+-
+- static __inline__ FT_Int32
+- FT_MulFix_x86_64( FT_Int32 a,
+- FT_Int32 b )
+- {
+- /* Temporarily disable the warning that C90 doesn't support */
+- /* `long long'. */
+-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wlong-long"
+-#endif
+-
+-#if 1
+- /* Technically not an assembly fragment, but GCC does a really good */
+- /* job at inlining it and generating good machine code for it. */
+- long long ret, tmp;
+-
+-
+- ret = (long long)a * b;
+- tmp = ret >> 63;
+- ret += 0x8000 + tmp;
+-
+- return (FT_Int32)( ret >> 16 );
+-#else
+-
+- /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */
+- /* code from the lines below. The main issue is that `wide_a' is not */
+- /* properly initialized by sign-extending `a'. Instead, the generated */
+- /* machine code assumes that the register that contains `a' on input */
+- /* can be used directly as a 64-bit value, which is wrong most of the */
+- /* time. */
+- long long wide_a = (long long)a;
+- long long wide_b = (long long)b;
+- long long result;
+-
+-
+- __asm__ __volatile__ (
+- "imul %2, %1\n"
+- "mov %1, %0\n"
+- "sar $63, %0\n"
+- "lea 0x8000(%1, %0), %0\n"
+- "sar $16, %0\n"
+- : "=&r"(result), "=&r"(wide_a)
+- : "r"(wide_b)
+- : "cc" );
+-
+- return (FT_Int32)result;
+-#endif
+-
+-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+-#pragma GCC diagnostic pop
+-#endif
+- }
+-
+-#endif /* __GNUC__ && __x86_64__ */
+-
+-#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
+-
+-
+-#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
+-#ifdef FT_MULFIX_ASSEMBLER
+-#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER
+-#endif
+-#endif
+-
+-
+ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+
+ #define FT_LOCAL( x ) static x
+diff --git a/docs/CHANGES b/docs/CHANGES
+index 803f02d..51b829c 100644
+--- a/docs/CHANGES
++++ b/docs/CHANGES
+@@ -1,11 +1,40 @@
+
++CHANGES BETWEEN 2.5.3 and 2.5.4
++
++ I. IMPORTANT BUG FIXES
++
++ - The new auto-hinter code using HarfBuzz crashed for some invalid
++ fonts.
++
++
++ II. IMPORTANT CHANGES
++
++ - Full auto-hinter support of the Devanagari script.
++
++
++ III. MISCELLANEOUS
++
++ - Improvements to the auto-hinter's algorithm to recognize stems
++ and local extrema.
++
++ - Function `FT_Get_SubGlyph_Info' always returned an error even in
++ case of success.
++
++ - Version 2.5.1 introduced major bugs in the cjk part of the
++ auto-hinter, which are now fixed.
++
++ - `cmake' now supports a build of FreeType as an OS X framework.
++
++
++======================================================================
++
+ CHANGES BETWEEN 2.5.2 and 2.5.3
+
+ I. IMPORTANT BUG FIXES
+
+- - A vulnerability was identified and fixed in the new CFF driver
+- (cf. http://savannah.nongnu.org/bugs/?41697; it doesn't have a
+- CVE number yet). All users should upgrade.
++ - A vulnerability (CVE-2014-2240) was identified and fixed in the
++ new CFF driver (cf. http://savannah.nongnu.org/bugs/?41697).
++ All users should upgrade.
+
+ - More bug fixes related to correct positioning of composite
+ glyphs.
+@@ -261,6 +290,9 @@ CHANGES BETWEEN 2.4.12 and 2.5
+ it accepts a new command line option `-H' to select the hinting
+ engine.
+
++ - `ftdump's verbose option has been renamed to `-V'. For all demo
++ programs, `-v' now shows version information.
++
+ - Another round of TrueType subpixel hinting fixes.
+
+ - The `apinames' tool can now create an import file for NetWare.
+diff --git a/include/config/ftconfig.h b/include/config/ftconfig.h
+index d98a311..22d70fd 100644
+--- a/include/config/ftconfig.h
++++ b/include/config/ftconfig.h
+@@ -266,7 +266,16 @@ FT_BEGIN_HEADER
+ #define FT_INT64 long
+ #define FT_UINT64 unsigned long
+
+-#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
++ /*************************************************************************/
++ /* */
++ /* A 64-bit data type may create compilation problems if you compile */
++ /* in strict ANSI mode. To avoid them, we disable other 64-bit data */
++ /* types if __STDC__ is defined. You can however ignore this rule */
++ /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
++ /* */
++#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
++
++#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
+
+ /* this compiler provides the __int64 type */
+ #define FT_LONG64
+@@ -300,27 +309,9 @@ FT_BEGIN_HEADER
+ #define FT_INT64 long long int
+ #define FT_UINT64 unsigned long long int
+
+-#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+-
+-
+- /*************************************************************************/
+- /* */
+- /* A 64-bit data type will create compilation problems if you compile */
+- /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */
+- /* is defined. You can however ignore this rule by defining the */
+- /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */
+- /* */
+-#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )
+-
+-#ifdef __STDC__
+-
+- /* undefine the 64-bit macros in strict ANSI compilation mode */
+-#undef FT_LONG64
+-#undef FT_INT64
+-
+-#endif /* __STDC__ */
++#endif /* _MSC_VER */
+
+-#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
++#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+
+ #ifdef FT_LONG64
+ typedef FT_INT64 FT_Int64;
+@@ -333,219 +324,6 @@ FT_BEGIN_HEADER
+ #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT
+
+
+-#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
+- /* Provide assembler fragments for performance-critical functions. */
+- /* These must be defined `static __inline__' with GCC. */
+-
+-#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
+-
+- /* documentation is in freetype.h */
+-
+- static __inline FT_Int32
+- FT_MulFix_arm( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 t, t2;
+-
+-
+- __asm
+- {
+- smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
+- mov a, t, asr #31 /* a = (hi >> 31) */
+- add a, a, #0x8000 /* a += 0x8000 */
+- adds t2, t2, a /* t2 += a */
+- adc t, t, #0 /* t += carry */
+- mov a, t2, lsr #16 /* a = t2 >> 16 */
+- orr a, a, t, lsl #16 /* a |= t << 16 */
+- }
+- return a;
+- }
+-
+-#endif /* __CC_ARM || __ARMCC__ */
+-
+-
+-#ifdef __GNUC__
+-
+-#if defined( __arm__ ) && \
+- ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
+- !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
+-
+- /* documentation is in freetype.h */
+-
+- static __inline__ FT_Int32
+- FT_MulFix_arm( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 t, t2;
+-
+-
+- __asm__ __volatile__ (
+- "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
+- "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
+-#if defined( __clang__ ) && defined( __thumb2__ )
+- "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
+-#else
+- "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
+-#endif
+- "adds %1, %1, %0\n\t" /* %1 += %0 */
+- "adc %2, %2, #0\n\t" /* %2 += carry */
+- "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
+- "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
+- : "=r"(a), "=&r"(t2), "=&r"(t)
+- : "r"(a), "r"(b)
+- : "cc" );
+- return a;
+- }
+-
+-#endif /* __arm__ && */
+- /* ( __thumb2__ || !__thumb__ ) && */
+- /* !( __CC_ARM || __ARMCC__ ) */
+-
+-
+-#if defined( __i386__ )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
+-
+- /* documentation is in freetype.h */
+-
+- static __inline__ FT_Int32
+- FT_MulFix_i386( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 result;
+-
+-
+- __asm__ __volatile__ (
+- "imul %%edx\n"
+- "movl %%edx, %%ecx\n"
+- "sarl $31, %%ecx\n"
+- "addl $0x8000, %%ecx\n"
+- "addl %%ecx, %%eax\n"
+- "adcl $0, %%edx\n"
+- "shrl $16, %%eax\n"
+- "shll $16, %%edx\n"
+- "addl %%edx, %%eax\n"
+- : "=a"(result), "=d"(b)
+- : "a"(a), "d"(b)
+- : "%ecx", "cc" );
+- return result;
+- }
+-
+-#endif /* i386 */
+-
+-#endif /* __GNUC__ */
+-
+-
+-#ifdef _MSC_VER /* Visual C++ */
+-
+-#ifdef _M_IX86
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
+-
+- /* documentation is in freetype.h */
+-
+- static __inline FT_Int32
+- FT_MulFix_i386( FT_Int32 a,
+- FT_Int32 b )
+- {
+- register FT_Int32 result;
+-
+- __asm
+- {
+- mov eax, a
+- mov edx, b
+- imul edx
+- mov ecx, edx
+- sar ecx, 31
+- add ecx, 8000h
+- add eax, ecx
+- adc edx, 0
+- shr eax, 16
+- shl edx, 16
+- add eax, edx
+- mov result, eax
+- }
+- return result;
+- }
+-
+-#endif /* _M_IX86 */
+-
+-#endif /* _MSC_VER */
+-
+-
+-#if defined( __GNUC__ ) && defined( __x86_64__ )
+-
+-#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64
+-
+- static __inline__ FT_Int32
+- FT_MulFix_x86_64( FT_Int32 a,
+- FT_Int32 b )
+- {
+- /* Temporarily disable the warning that C90 doesn't support */
+- /* `long long'. */
+-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wlong-long"
+-#endif
+-
+-#if 1
+- /* Technically not an assembly fragment, but GCC does a really good */
+- /* job at inlining it and generating good machine code for it. */
+- long long ret, tmp;
+-
+-
+- ret = (long long)a * b;
+- tmp = ret >> 63;
+- ret += 0x8000 + tmp;
+-
+- return (FT_Int32)( ret >> 16 );
+-#else
+-
+- /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */
+- /* code from the lines below. The main issue is that `wide_a' is not */
+- /* properly initialized by sign-extending `a'. Instead, the generated */
+- /* machine code assumes that the register that contains `a' on input */
+- /* can be used directly as a 64-bit value, which is wrong most of the */
+- /* time. */
+- long long wide_a = (long long)a;
+- long long wide_b = (long long)b;
+- long long result;
+-
+-
+- __asm__ __volatile__ (
+- "imul %2, %1\n"
+- "mov %1, %0\n"
+- "sar $63, %0\n"
+- "lea 0x8000(%1, %0), %0\n"
+- "sar $16, %0\n"
+- : "=&r"(result), "=&r"(wide_a)
+- : "r"(wide_b)
+- : "cc" );
+-
+- return (FT_Int32)result;
+-#endif
+-
+-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+-#pragma GCC diagnostic pop
+-#endif
+- }
+-
+-#endif /* __GNUC__ && __x86_64__ */
+-
+-#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
+-
+-
+-#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
+-#ifdef FT_MULFIX_ASSEMBLER
+-#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER
+-#endif
+-#endif
+-
+-
+ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+
+ #define FT_LOCAL( x ) static x
+diff --git a/include/freetype.h b/include/freetype.h
+index fb62b62..6a31502 100644
+--- a/include/freetype.h
++++ b/include/freetype.h
+@@ -1592,7 +1592,6 @@ FT_BEGIN_HEADER
+ /* This field is only valid for the composite */
+ /* glyph format that should normally only be */
+ /* loaded with the @FT_LOAD_NO_RECURSE flag. */
+- /* For now this is internal to FreeType. */
+ /* */
+ /* subglyphs :: An array of subglyph descriptors for */
+ /* composite glyphs. There are `num_subglyphs' */
+@@ -2560,14 +2559,11 @@ FT_BEGIN_HEADER
+ * Ignored. Deprecated.
+ *
+ * FT_LOAD_NO_RECURSE ::
+- * This flag is only used internally. It merely indicates that the
+- * font driver should not load composite glyphs recursively. Instead,
+- * it should set the `num_subglyph' and `subglyphs' values of the
+- * glyph slot accordingly, and set `glyph->format' to
+- * @FT_GLYPH_FORMAT_COMPOSITE.
+- *
+- * The description of sub-glyphs is not available to client
+- * applications for now.
++ * Indicate that the font driver should not load composite glyphs
++ * recursively. Instead, it should set the `num_subglyph' and
++ * `subglyphs' values of the glyph slot accordingly, and set
++ * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of
++ * subglyphs can then be accessed with @FT_Get_SubGlyph_Info.
+ *
+ * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM.
+ *
+@@ -3065,9 +3061,8 @@ FT_BEGIN_HEADER
+ /* glyph index~0 always corresponds to the `missing glyph' (called */
+ /* `.notdef'). */
+ /* */
+- /* This function is not compiled within the library if the config */
+- /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */
+- /* `ftoptions.h'. */
++ /* This function always returns an error if the config macro */
++ /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FT_Get_Glyph_Name( FT_Face face,
+@@ -3767,12 +3762,6 @@ FT_BEGIN_HEADER
+ FT_Long c );
+
+
+- /* */
+-
+- /* The following #if 0 ... #endif is for the documentation formatter, */
+- /* hiding the internal `FT_MULFIX_INLINED' macro. */
+-
+-#if 0
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+@@ -3806,17 +3795,6 @@ FT_BEGIN_HEADER
+ FT_MulFix( FT_Long a,
+ FT_Long b );
+
+- /* */
+-#endif
+-
+-#ifdef FT_MULFIX_INLINED
+-#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b )
+-#else
+- FT_EXPORT( FT_Long )
+- FT_MulFix( FT_Long a,
+- FT_Long b );
+-#endif
+-
+
+ /*************************************************************************/
+ /* */
+@@ -3829,18 +3807,12 @@ FT_BEGIN_HEADER
+ /* used to divide a given value by a 16.16 fixed-point factor. */
+ /* */
+ /* <Input> */
+- /* a :: The first multiplier. */
+- /* b :: The second multiplier. Use a 16.16 factor here whenever */
+- /* possible (see note below). */
++ /* a :: The numerator. */
++ /* b :: The denominator. Use a 16.16 factor here. */
+ /* */
+ /* <Return> */
+ /* The result of `(a*0x10000)/b'. */
+ /* */
+- /* <Note> */
+- /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */
+- /* 32~bits, then the division is computed directly. Otherwise, we */
+- /* use a specialized version of @FT_MulDiv. */
+- /* */
+ FT_EXPORT( FT_Long )
+ FT_DivFix( FT_Long a,
+ FT_Long b );
+diff --git a/include/fterrdef.h b/include/fterrdef.h
+index 76c7b9e..99b2fad 100644
+--- a/include/fterrdef.h
++++ b/include/fterrdef.h
+@@ -31,218 +31,218 @@
+
+ /* generic errors */
+
+- FT_NOERRORDEF_( Ok, 0x00, \
++ FT_NOERRORDEF_( Ok, 0x00,
+ "no error" )
+
+- FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \
++ FT_ERRORDEF_( Cannot_Open_Resource, 0x01,
+ "cannot open resource" )
+- FT_ERRORDEF_( Unknown_File_Format, 0x02, \
++ FT_ERRORDEF_( Unknown_File_Format, 0x02,
+ "unknown file format" )
+- FT_ERRORDEF_( Invalid_File_Format, 0x03, \
++ FT_ERRORDEF_( Invalid_File_Format, 0x03,
+ "broken file" )
+- FT_ERRORDEF_( Invalid_Version, 0x04, \
++ FT_ERRORDEF_( Invalid_Version, 0x04,
+ "invalid FreeType version" )
+- FT_ERRORDEF_( Lower_Module_Version, 0x05, \
++ FT_ERRORDEF_( Lower_Module_Version, 0x05,
+ "module version is too low" )
+- FT_ERRORDEF_( Invalid_Argument, 0x06, \
++ FT_ERRORDEF_( Invalid_Argument, 0x06,
+ "invalid argument" )
+- FT_ERRORDEF_( Unimplemented_Feature, 0x07, \
++ FT_ERRORDEF_( Unimplemented_Feature, 0x07,
+ "unimplemented feature" )
+- FT_ERRORDEF_( Invalid_Table, 0x08, \
++ FT_ERRORDEF_( Invalid_Table, 0x08,
+ "broken table" )
+- FT_ERRORDEF_( Invalid_Offset, 0x09, \
++ FT_ERRORDEF_( Invalid_Offset, 0x09,
+ "broken offset within table" )
+- FT_ERRORDEF_( Array_Too_Large, 0x0A, \
++ FT_ERRORDEF_( Array_Too_Large, 0x0A,
+ "array allocation size too large" )
+- FT_ERRORDEF_( Missing_Module, 0x0B, \
++ FT_ERRORDEF_( Missing_Module, 0x0B,
+ "missing module" )
+- FT_ERRORDEF_( Missing_Property, 0x0C, \
++ FT_ERRORDEF_( Missing_Property, 0x0C,
+ "missing property" )
+
+ /* glyph/character errors */
+
+- FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \
++ FT_ERRORDEF_( Invalid_Glyph_Index, 0x10,
+ "invalid glyph index" )
+- FT_ERRORDEF_( Invalid_Character_Code, 0x11, \
++ FT_ERRORDEF_( Invalid_Character_Code, 0x11,
+ "invalid character code" )
+- FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \
++ FT_ERRORDEF_( Invalid_Glyph_Format, 0x12,
+ "unsupported glyph image format" )
+- FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \
++ FT_ERRORDEF_( Cannot_Render_Glyph, 0x13,
+ "cannot render this glyph format" )
+- FT_ERRORDEF_( Invalid_Outline, 0x14, \
++ FT_ERRORDEF_( Invalid_Outline, 0x14,
+ "invalid outline" )
+- FT_ERRORDEF_( Invalid_Composite, 0x15, \
++ FT_ERRORDEF_( Invalid_Composite, 0x15,
+ "invalid composite glyph" )
+- FT_ERRORDEF_( Too_Many_Hints, 0x16, \
++ FT_ERRORDEF_( Too_Many_Hints, 0x16,
+ "too many hints" )
+- FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \
++ FT_ERRORDEF_( Invalid_Pixel_Size, 0x17,
+ "invalid pixel size" )
+
+ /* handle errors */
+
+- FT_ERRORDEF_( Invalid_Handle, 0x20, \
++ FT_ERRORDEF_( Invalid_Handle, 0x20,
+ "invalid object handle" )
+- FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \
++ FT_ERRORDEF_( Invalid_Library_Handle, 0x21,
+ "invalid library handle" )
+- FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \
++ FT_ERRORDEF_( Invalid_Driver_Handle, 0x22,
+ "invalid module handle" )
+- FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \
++ FT_ERRORDEF_( Invalid_Face_Handle, 0x23,
+ "invalid face handle" )
+- FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \
++ FT_ERRORDEF_( Invalid_Size_Handle, 0x24,
+ "invalid size handle" )
+- FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \
++ FT_ERRORDEF_( Invalid_Slot_Handle, 0x25,
+ "invalid glyph slot handle" )
+- FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \
++ FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26,
+ "invalid charmap handle" )
+- FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \
++ FT_ERRORDEF_( Invalid_Cache_Handle, 0x27,
+ "invalid cache manager handle" )
+- FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \
++ FT_ERRORDEF_( Invalid_Stream_Handle, 0x28,
+ "invalid stream handle" )
+
+ /* driver errors */
+
+- FT_ERRORDEF_( Too_Many_Drivers, 0x30, \
++ FT_ERRORDEF_( Too_Many_Drivers, 0x30,
+ "too many modules" )
+- FT_ERRORDEF_( Too_Many_Extensions, 0x31, \
++ FT_ERRORDEF_( Too_Many_Extensions, 0x31,
+ "too many extensions" )
+
+ /* memory errors */
+
+- FT_ERRORDEF_( Out_Of_Memory, 0x40, \
++ FT_ERRORDEF_( Out_Of_Memory, 0x40,
+ "out of memory" )
+- FT_ERRORDEF_( Unlisted_Object, 0x41, \
++ FT_ERRORDEF_( Unlisted_Object, 0x41,
+ "unlisted object" )
+
+ /* stream errors */
+
+- FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \
++ FT_ERRORDEF_( Cannot_Open_Stream, 0x51,
+ "cannot open stream" )
+- FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \
++ FT_ERRORDEF_( Invalid_Stream_Seek, 0x52,
+ "invalid stream seek" )
+- FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \
++ FT_ERRORDEF_( Invalid_Stream_Skip, 0x53,
+ "invalid stream skip" )
+- FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \
++ FT_ERRORDEF_( Invalid_Stream_Read, 0x54,
+ "invalid stream read" )
+- FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \
++ FT_ERRORDEF_( Invalid_Stream_Operation, 0x55,
+ "invalid stream operation" )
+- FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \
++ FT_ERRORDEF_( Invalid_Frame_Operation, 0x56,
+ "invalid frame operation" )
+- FT_ERRORDEF_( Nested_Frame_Access, 0x57, \
++ FT_ERRORDEF_( Nested_Frame_Access, 0x57,
+ "nested frame access" )
+- FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \
++ FT_ERRORDEF_( Invalid_Frame_Read, 0x58,
+ "invalid frame read" )
+
+ /* raster errors */
+
+- FT_ERRORDEF_( Raster_Uninitialized, 0x60, \
++ FT_ERRORDEF_( Raster_Uninitialized, 0x60,
+ "raster uninitialized" )
+- FT_ERRORDEF_( Raster_Corrupted, 0x61, \
++ FT_ERRORDEF_( Raster_Corrupted, 0x61,
+ "raster corrupted" )
+- FT_ERRORDEF_( Raster_Overflow, 0x62, \
++ FT_ERRORDEF_( Raster_Overflow, 0x62,
+ "raster overflow" )
+- FT_ERRORDEF_( Raster_Negative_Height, 0x63, \
++ FT_ERRORDEF_( Raster_Negative_Height, 0x63,
+ "negative height while rastering" )
+
+ /* cache errors */
+
+- FT_ERRORDEF_( Too_Many_Caches, 0x70, \
++ FT_ERRORDEF_( Too_Many_Caches, 0x70,
+ "too many registered caches" )
+
+ /* TrueType and SFNT errors */
+
+- FT_ERRORDEF_( Invalid_Opcode, 0x80, \
++ FT_ERRORDEF_( Invalid_Opcode, 0x80,
+ "invalid opcode" )
+- FT_ERRORDEF_( Too_Few_Arguments, 0x81, \
++ FT_ERRORDEF_( Too_Few_Arguments, 0x81,
+ "too few arguments" )
+- FT_ERRORDEF_( Stack_Overflow, 0x82, \
++ FT_ERRORDEF_( Stack_Overflow, 0x82,
+ "stack overflow" )
+- FT_ERRORDEF_( Code_Overflow, 0x83, \
++ FT_ERRORDEF_( Code_Overflow, 0x83,
+ "code overflow" )
+- FT_ERRORDEF_( Bad_Argument, 0x84, \
++ FT_ERRORDEF_( Bad_Argument, 0x84,
+ "bad argument" )
+- FT_ERRORDEF_( Divide_By_Zero, 0x85, \
++ FT_ERRORDEF_( Divide_By_Zero, 0x85,
+ "division by zero" )
+- FT_ERRORDEF_( Invalid_Reference, 0x86, \
++ FT_ERRORDEF_( Invalid_Reference, 0x86,
+ "invalid reference" )
+- FT_ERRORDEF_( Debug_OpCode, 0x87, \
++ FT_ERRORDEF_( Debug_OpCode, 0x87,
+ "found debug opcode" )
+- FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \
++ FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88,
+ "found ENDF opcode in execution stream" )
+- FT_ERRORDEF_( Nested_DEFS, 0x89, \
++ FT_ERRORDEF_( Nested_DEFS, 0x89,
+ "nested DEFS" )
+- FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \
++ FT_ERRORDEF_( Invalid_CodeRange, 0x8A,
+ "invalid code range" )
+- FT_ERRORDEF_( Execution_Too_Long, 0x8B, \
++ FT_ERRORDEF_( Execution_Too_Long, 0x8B,
+ "execution context too long" )
+- FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \
++ FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C,
+ "too many function definitions" )
+- FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \
++ FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D,
+ "too many instruction definitions" )
+- FT_ERRORDEF_( Table_Missing, 0x8E, \
++ FT_ERRORDEF_( Table_Missing, 0x8E,
+ "SFNT font table missing" )
+- FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \
++ FT_ERRORDEF_( Horiz_Header_Missing, 0x8F,
+ "horizontal header (hhea) table missing" )
+- FT_ERRORDEF_( Locations_Missing, 0x90, \
++ FT_ERRORDEF_( Locations_Missing, 0x90,
+ "locations (loca) table missing" )
+- FT_ERRORDEF_( Name_Table_Missing, 0x91, \
++ FT_ERRORDEF_( Name_Table_Missing, 0x91,
+ "name table missing" )
+- FT_ERRORDEF_( CMap_Table_Missing, 0x92, \
++ FT_ERRORDEF_( CMap_Table_Missing, 0x92,
+ "character map (cmap) table missing" )
+- FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \
++ FT_ERRORDEF_( Hmtx_Table_Missing, 0x93,
+ "horizontal metrics (hmtx) table missing" )
+- FT_ERRORDEF_( Post_Table_Missing, 0x94, \
++ FT_ERRORDEF_( Post_Table_Missing, 0x94,
+ "PostScript (post) table missing" )
+- FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \
++ FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95,
+ "invalid horizontal metrics" )
+- FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \
++ FT_ERRORDEF_( Invalid_CharMap_Format, 0x96,
+ "invalid character map (cmap) format" )
+- FT_ERRORDEF_( Invalid_PPem, 0x97, \
++ FT_ERRORDEF_( Invalid_PPem, 0x97,
+ "invalid ppem value" )
+- FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \
++ FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98,
+ "invalid vertical metrics" )
+- FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \
++ FT_ERRORDEF_( Could_Not_Find_Context, 0x99,
+ "could not find context" )
+- FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \
++ FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A,
+ "invalid PostScript (post) table format" )
+- FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \
++ FT_ERRORDEF_( Invalid_Post_Table, 0x9B,
+ "invalid PostScript (post) table" )
+
+ /* CFF, CID, and Type 1 errors */
+
+- FT_ERRORDEF_( Syntax_Error, 0xA0, \
++ FT_ERRORDEF_( Syntax_Error, 0xA0,
+ "opcode syntax error" )
+- FT_ERRORDEF_( Stack_Underflow, 0xA1, \
++ FT_ERRORDEF_( Stack_Underflow, 0xA1,
+ "argument stack underflow" )
+- FT_ERRORDEF_( Ignore, 0xA2, \
++ FT_ERRORDEF_( Ignore, 0xA2,
+ "ignore" )
+- FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, \
++ FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3,
+ "no Unicode glyph name found" )
+- FT_ERRORDEF_( Glyph_Too_Big, 0xA4, \
++ FT_ERRORDEF_( Glyph_Too_Big, 0xA4,
+ "glyph to big for hinting" )
+
+ /* BDF errors */
+
+- FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \
++ FT_ERRORDEF_( Missing_Startfont_Field, 0xB0,
+ "`STARTFONT' field missing" )
+- FT_ERRORDEF_( Missing_Font_Field, 0xB1, \
++ FT_ERRORDEF_( Missing_Font_Field, 0xB1,
+ "`FONT' field missing" )
+- FT_ERRORDEF_( Missing_Size_Field, 0xB2, \
++ FT_ERRORDEF_( Missing_Size_Field, 0xB2,
+ "`SIZE' field missing" )
+- FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, \
++ FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3,
+ "`FONTBOUNDINGBOX' field missing" )
+- FT_ERRORDEF_( Missing_Chars_Field, 0xB4, \
++ FT_ERRORDEF_( Missing_Chars_Field, 0xB4,
+ "`CHARS' field missing" )
+- FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, \
++ FT_ERRORDEF_( Missing_Startchar_Field, 0xB5,
+ "`STARTCHAR' field missing" )
+- FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, \
++ FT_ERRORDEF_( Missing_Encoding_Field, 0xB6,
+ "`ENCODING' field missing" )
+- FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, \
++ FT_ERRORDEF_( Missing_Bbx_Field, 0xB7,
+ "`BBX' field missing" )
+- FT_ERRORDEF_( Bbx_Too_Big, 0xB8, \
++ FT_ERRORDEF_( Bbx_Too_Big, 0xB8,
+ "`BBX' too big" )
+- FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, \
++ FT_ERRORDEF_( Corrupted_Font_Header, 0xB9,
+ "Font header corrupted or missing fields" )
+- FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, \
++ FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA,
+ "Font glyphs corrupted or missing fields" )
+
+
+diff --git a/include/fttrigon.h b/include/fttrigon.h
+index 65143cb..9c7b543 100644
+--- a/include/fttrigon.h
++++ b/include/fttrigon.h
+@@ -237,7 +237,7 @@ FT_BEGIN_HEADER
+ *
+ * @input:
+ * angle ::
+- * The address of angle.
++ * The input angle.
+ *
+ */
+ FT_EXPORT( void )
+@@ -259,7 +259,7 @@ FT_BEGIN_HEADER
+ *
+ * @input:
+ * angle ::
+- * The address of angle.
++ * The input angle.
+ *
+ */
+ FT_EXPORT( void )
+diff --git a/include/internal/ftcalc.h b/include/internal/ftcalc.h
+index 03bd68e..95165bf 100644
+--- a/include/internal/ftcalc.h
++++ b/include/internal/ftcalc.h
+@@ -4,7 +4,7 @@
+ /* */
+ /* Arithmetic computations (specification). */
+ /* */
+-/* Copyright 1996-2006, 2008, 2009, 2012-2013 by */
++/* Copyright 1996-2006, 2008, 2009, 2012-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -27,36 +27,223 @@
+ FT_BEGIN_HEADER
+
+
+-#if 0
+-
+ /*************************************************************************/
+ /* */
+- /* <Function> */
+- /* FT_SqrtFixed */
+- /* */
+- /* <Description> */
+- /* Computes the square root of a 16.16 fixed-point value. */
+- /* */
+- /* <Input> */
+- /* x :: The value to compute the root for. */
+- /* */
+- /* <Return> */
+- /* The result of `sqrt(x)'. */
+- /* */
+- /* <Note> */
+- /* This function is not very fast. */
++ /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */
+ /* */
+- FT_BASE( FT_Int32 )
+- FT_SqrtFixed( FT_Int32 x );
++ /*************************************************************************/
+
+-#endif /* 0 */
++#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
++ /* Provide assembler fragments for performance-critical functions. */
++ /* These must be defined `static __inline__' with GCC. */
+
++#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */
+
+- /*************************************************************************/
+- /* */
+- /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */
+- /* */
+- /*************************************************************************/
++#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
++
++ /* documentation is in freetype.h */
++
++ static __inline FT_Int32
++ FT_MulFix_arm( FT_Int32 a,
++ FT_Int32 b )
++ {
++ register FT_Int32 t, t2;
++
++
++ __asm
++ {
++ smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
++ mov a, t, asr #31 /* a = (hi >> 31) */
++ add a, a, #0x8000 /* a += 0x8000 */
++ adds t2, t2, a /* t2 += a */
++ adc t, t, #0 /* t += carry */
++ mov a, t2, lsr #16 /* a = t2 >> 16 */
++ orr a, a, t, lsl #16 /* a |= t << 16 */
++ }
++ return a;
++ }
++
++#endif /* __CC_ARM || __ARMCC__ */
++
++
++#ifdef __GNUC__
++
++#if defined( __arm__ ) && \
++ ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
++ !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
++
++#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
++
++ /* documentation is in freetype.h */
++
++ static __inline__ FT_Int32
++ FT_MulFix_arm( FT_Int32 a,
++ FT_Int32 b )
++ {
++ register FT_Int32 t, t2;
++
++
++ __asm__ __volatile__ (
++ "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
++ "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
++#if defined( __clang__ ) && defined( __thumb2__ )
++ "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
++#else
++ "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
++#endif
++ "adds %1, %1, %0\n\t" /* %1 += %0 */
++ "adc %2, %2, #0\n\t" /* %2 += carry */
++ "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
++ "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
++ : "=r"(a), "=&r"(t2), "=&r"(t)
++ : "r"(a), "r"(b)
++ : "cc" );
++ return a;
++ }
++
++#endif /* __arm__ && */
++ /* ( __thumb2__ || !__thumb__ ) && */
++ /* !( __CC_ARM || __ARMCC__ ) */
++
++
++#if defined( __i386__ )
++
++#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
++
++ /* documentation is in freetype.h */
++
++ static __inline__ FT_Int32
++ FT_MulFix_i386( FT_Int32 a,
++ FT_Int32 b )
++ {
++ register FT_Int32 result;
++
++
++ __asm__ __volatile__ (
++ "imul %%edx\n"
++ "movl %%edx, %%ecx\n"
++ "sarl $31, %%ecx\n"
++ "addl $0x8000, %%ecx\n"
++ "addl %%ecx, %%eax\n"
++ "adcl $0, %%edx\n"
++ "shrl $16, %%eax\n"
++ "shll $16, %%edx\n"
++ "addl %%edx, %%eax\n"
++ : "=a"(result), "=d"(b)
++ : "a"(a), "d"(b)
++ : "%ecx", "cc" );
++ return result;
++ }
++
++#endif /* i386 */
++
++#endif /* __GNUC__ */
++
++
++#ifdef _MSC_VER /* Visual C++ */
++
++#ifdef _M_IX86
++
++#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
++
++ /* documentation is in freetype.h */
++
++ static __inline FT_Int32
++ FT_MulFix_i386( FT_Int32 a,
++ FT_Int32 b )
++ {
++ register FT_Int32 result;
++
++ __asm
++ {
++ mov eax, a
++ mov edx, b
++ imul edx
++ mov ecx, edx
++ sar ecx, 31
++ add ecx, 8000h
++ add eax, ecx
++ adc edx, 0
++ shr eax, 16
++ shl edx, 16
++ add eax, edx
++ mov result, eax
++ }
++ return result;
++ }
++
++#endif /* _M_IX86 */
++
++#endif /* _MSC_VER */
++
++
++#if defined( __GNUC__ ) && defined( __x86_64__ )
++
++#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64
++
++ static __inline__ FT_Int32
++ FT_MulFix_x86_64( FT_Int32 a,
++ FT_Int32 b )
++ {
++ /* Temporarily disable the warning that C90 doesn't support */
++ /* `long long'. */
++#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wlong-long"
++#endif
++
++#if 1
++ /* Technically not an assembly fragment, but GCC does a really good */
++ /* job at inlining it and generating good machine code for it. */
++ long long ret, tmp;
++
++
++ ret = (long long)a * b;
++ tmp = ret >> 63;
++ ret += 0x8000 + tmp;
++
++ return (FT_Int32)( ret >> 16 );
++#else
++
++ /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */
++ /* code from the lines below. The main issue is that `wide_a' is not */
++ /* properly initialized by sign-extending `a'. Instead, the generated */
++ /* machine code assumes that the register that contains `a' on input */
++ /* can be used directly as a 64-bit value, which is wrong most of the */
++ /* time. */
++ long long wide_a = (long long)a;
++ long long wide_b = (long long)b;
++ long long result;
++
++
++ __asm__ __volatile__ (
++ "imul %2, %1\n"
++ "mov %1, %0\n"
++ "sar $63, %0\n"
++ "lea 0x8000(%1, %0), %0\n"
++ "sar $16, %0\n"
++ : "=&r"(result), "=&r"(wide_a)
++ : "r"(wide_b)
++ : "cc" );
++
++ return (FT_Int32)result;
++#endif
++
++#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
++#pragma GCC diagnostic pop
++#endif
++ }
++
++#endif /* __GNUC__ && __x86_64__ */
++
++#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
++
++
++#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
++#ifdef FT_MULFIX_ASSEMBLER
++#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( a, b )
++#endif
++#endif
+
+
+ /*************************************************************************/
+@@ -139,9 +326,32 @@ FT_BEGIN_HEADER
+ /*
+ * Return the most significant bit index.
+ */
++
++#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
++#if defined( __GNUC__ )
++#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) )
++
++#if FT_SIZEOF_INT == 4
++
++#define FT_MSB( x ) ( 31 - __builtin_clz( x ) )
++
++#elif FT_SIZEOF_LONG == 4
++
++#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) )
++
++#endif
++
++#endif
++#endif /* __GNUC__ */
++#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
++
++#ifndef FT_MSB
++
+ FT_BASE( FT_Int )
+ FT_MSB( FT_UInt32 z );
+
++#endif
++
+
+ /*
+ * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
+@@ -152,6 +362,31 @@ FT_BEGIN_HEADER
+ FT_Fixed y );
+
+
++#if 0
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* FT_SqrtFixed */
++ /* */
++ /* <Description> */
++ /* Computes the square root of a 16.16 fixed-point value. */
++ /* */
++ /* <Input> */
++ /* x :: The value to compute the root for. */
++ /* */
++ /* <Return> */
++ /* The result of `sqrt(x)'. */
++ /* */
++ /* <Note> */
++ /* This function is not very fast. */
++ /* */
++ FT_BASE( FT_Int32 )
++ FT_SqrtFixed( FT_Int32 x );
++
++#endif /* 0 */
++
++
+ #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 )
+ #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 )
+ #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 )
+diff --git a/include/internal/ftobjs.h b/include/internal/ftobjs.h
+index 701c850..faa37f8 100644
+--- a/include/internal/ftobjs.h
++++ b/include/internal/ftobjs.h
+@@ -83,14 +83,6 @@ FT_BEGIN_HEADER
+
+
+ /*
+- * Return the highest power of 2 that is <= value; this correspond to
+- * the highest bit in a given 32-bit value.
+- */
+- FT_BASE( FT_UInt32 )
+- ft_highpow2( FT_UInt32 value );
+-
+-
+- /*
+ * character classification functions -- since these are used to parse
+ * font files, we must not use those in <ctypes.h> which are
+ * locale-dependent
+diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c
+index 6e214c8..f3526bf 100644
+--- a/src/autofit/afblue.c
++++ b/src/autofit/afblue.c
+@@ -26,15 +26,21 @@
+ af_blue_strings[] =
+ {
+ /* */
+- 'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S', /* THEZOCQS */
++ '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕПЗОСЭ */
+ '\0',
+- 'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S', /* HEZLOCUS */
++ '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕШЗОСЭ */
+ '\0',
+- 'f', 'i', 'j', 'k', 'd', 'b', 'h', /* fijkdbh */
++ '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81', /* хпншезос */
+ '\0',
+- 'x', 'z', 'r', 'o', 'e', 's', 'c', /* xzroesc */
++ '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84', /* руф */
+ '\0',
+- 'p', 'q', 'g', 'j', 'y', /* pqgjy */
++ '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */
++ '\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',
++ '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */
++ '\0',
++ '\xE0', '\xA5', '\x81', '\xE0', '\xA5', '\x83', /* ु ृ */
+ '\0',
+ '\xCE', '\x93', '\xCE', '\x92', '\xCE', '\x95', '\xCE', '\x96', '\xCE', '\x98', '\xCE', '\x9F', '\xCE', '\xA9', /* ΓΒΕΖΘΟΩ */
+ '\0',
+@@ -46,26 +52,27 @@
+ '\0',
+ '\xCE', '\xB2', '\xCE', '\xB3', '\xCE', '\xB7', '\xCE', '\xBC', '\xCF', '\x81', '\xCF', '\x86', '\xCF', '\x87', '\xCF', '\x88', /* βγημρφχψ */
+ '\0',
+- '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕПЗОСЭ */
++ '\xD7', '\x91', '\xD7', '\x93', '\xD7', '\x94', '\xD7', '\x97', '\xD7', '\x9A', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', /* בדהחךכםס */
+ '\0',
+- '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕШЗОСЭ */
++ '\xD7', '\x91', '\xD7', '\x98', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', '\xD7', '\xA6', /* בטכםסצ */
+ '\0',
+- '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81', /* хпншезос */
++ '\xD7', '\xA7', '\xD7', '\x9A', '\xD7', '\x9F', '\xD7', '\xA3', '\xD7', '\xA5', /* קךןףץ */
+ '\0',
+- '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84', /* руф */
++ 'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S', /* THEZOCQS */
+ '\0',
+- '\xD7', '\x91', '\xD7', '\x93', '\xD7', '\x94', '\xD7', '\x97', '\xD7', '\x9A', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', /* בדהחךכםס */
++ 'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S', /* HEZLOCUS */
+ '\0',
+- '\xD7', '\x91', '\xD7', '\x98', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', '\xD7', '\xA6', /* בטכםסצ */
++ 'f', 'i', 'j', 'k', 'd', 'b', 'h', /* fijkdbh */
+ '\0',
+- '\xD7', '\xA7', '\xD7', '\x9A', '\xD7', '\x9F', '\xD7', '\xA3', '\xD7', '\xA5', /* קךןףץ */
++ 'x', 'z', 'r', 'o', 'e', 's', 'c', /* xzroesc */
++ '\0',
++ 'p', 'q', 'g', 'j', 'y', /* pqgjy */
+ #ifdef AF_CONFIG_OPTION_CJK
+ '\0',
+ '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0', /* 他们你來們到和地 */
+ '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', '\xE5', '\xB8', '\xAD', '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x83', /* 对對就席我时時會 */
+ '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\x83', '\xBD', '\xE8', '\x88', '\xB0', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99', /* 来為能舰說说这這 */
+- '\xE9', '\xBD', '\x8A', /* 齊 */
+- '\0',
++ '\xE9', '\xBD', '\x8A', '|', /* 齊 | */
+ '\xE5', '\x86', '\x9B', '\xE5', '\x90', '\x8C', '\xE5', '\xB7', '\xB2', '\xE6', '\x84', '\xBF', '\xE6', '\x97', '\xA2', '\xE6', '\x98', '\x9F', '\xE6', '\x98', '\xAF', '\xE6', '\x99', '\xAF', /* 军同已愿既星是景 */
+ '\xE6', '\xB0', '\x91', '\xE7', '\x85', '\xA7', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\xA8', '\xE7', '\xBD', '\xAE', '\xE8', '\xA6', '\x81', /* 民照现現理用置要 */
+ '\xE8', '\xBB', '\x8D', '\xE9', '\x82', '\xA3', '\xE9', '\x85', '\x8D', '\xE9', '\x87', '\x8C', '\xE9', '\x96', '\x8B', '\xE9', '\x9B', '\xB7', '\xE9', '\x9C', '\xB2', '\xE9', '\x9D', '\xA2', /* 軍那配里開雷露面 */
+@@ -74,8 +81,7 @@
+ '\xE4', '\xB8', '\xAA', '\xE4', '\xB8', '\xBA', '\xE4', '\xBA', '\xBA', '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xA5', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', /* 个为人他以们你來 */
+ '\xE5', '\x80', '\x8B', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\xA4', '\xA7', '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', /* 個們到和大对對就 */
+ '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x89', '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\xA6', '\x81', '\xE8', '\xAA', '\xAA', /* 我时時有来為要說 */
+- '\xE8', '\xAF', '\xB4', /* 说 */
+- '\0',
++ '\xE8', '\xAF', '\xB4', '|', /* 说 | */
+ '\xE4', '\xB8', '\xBB', '\xE4', '\xBA', '\x9B', '\xE5', '\x9B', '\xA0', '\xE5', '\xAE', '\x83', '\xE6', '\x83', '\xB3', '\xE6', '\x84', '\x8F', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\x9F', /* 主些因它想意理生 */
+ '\xE7', '\x95', '\xB6', '\xE7', '\x9C', '\x8B', '\xE7', '\x9D', '\x80', '\xE7', '\xBD', '\xAE', '\xE8', '\x80', '\x85', '\xE8', '\x87', '\xAA', '\xE8', '\x91', '\x97', '\xE8', '\xA3', '\xA1', /* 當看着置者自著裡 */
+ '\xE8', '\xBF', '\x87', '\xE8', '\xBF', '\x98', '\xE8', '\xBF', '\x9B', '\xE9', '\x80', '\xB2', '\xE9', '\x81', '\x8E', '\xE9', '\x81', '\x93', '\xE9', '\x82', '\x84', '\xE9', '\x87', '\x8C', /* 过还进進過道還里 */
+@@ -85,8 +91,7 @@
+ '\xE4', '\xBA', '\x9B', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0', /* 些们你來們到和地 */
+ '\xE5', '\xA5', '\xB9', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE5', '\xB0', '\xB1', '\xE5', '\xB9', '\xB4', '\xE5', '\xBE', '\x97', '\xE6', '\x83', '\x85', '\xE6', '\x9C', '\x80', /* 她将將就年得情最 */
+ '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE7', '\x90', '\x86', '\xE8', '\x83', '\xBD', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99', /* 样樣理能說说这這 */
+- '\xE9', '\x80', '\x9A', /* 通 */
+- '\0',
++ '\xE9', '\x80', '\x9A', '|', /* 通 | */
+ '\xE5', '\x8D', '\xB3', '\xE5', '\x90', '\x97', '\xE5', '\x90', '\xA7', '\xE5', '\x90', '\xAC', '\xE5', '\x91', '\xA2', '\xE5', '\x93', '\x81', '\xE5', '\x93', '\x8D', '\xE5', '\x97', '\x8E', /* 即吗吧听呢品响嗎 */
+ '\xE5', '\xB8', '\x88', '\xE5', '\xB8', '\xAB', '\xE6', '\x94', '\xB6', '\xE6', '\x96', '\xAD', '\xE6', '\x96', '\xB7', '\xE6', '\x98', '\x8E', '\xE7', '\x9C', '\xBC', '\xE9', '\x96', '\x93', /* 师師收断斷明眼間 */
+ '\xE9', '\x97', '\xB4', '\xE9', '\x99', '\x85', '\xE9', '\x99', '\x88', '\xE9', '\x99', '\x90', '\xE9', '\x99', '\xA4', '\xE9', '\x99', '\xB3', '\xE9', '\x9A', '\x8F', '\xE9', '\x9A', '\x9B', /* 间际陈限除陳随際 */
+@@ -95,8 +100,7 @@
+ '\xE4', '\xBA', '\x8B', '\xE5', '\x89', '\x8D', '\xE5', '\xAD', '\xB8', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE6', '\x83', '\x85', '\xE6', '\x83', '\xB3', '\xE6', '\x88', '\x96', /* 事前學将將情想或 */
+ '\xE6', '\x94', '\xBF', '\xE6', '\x96', '\xAF', '\xE6', '\x96', '\xB0', '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE6', '\xB0', '\x91', '\xE6', '\xB2', '\x92', '\xE6', '\xB2', '\xA1', /* 政斯新样樣民沒没 */
+ '\xE7', '\x84', '\xB6', '\xE7', '\x89', '\xB9', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x83', '\xE7', '\xAC', '\xAC', '\xE7', '\xB6', '\x93', '\xE8', '\xB0', '\x81', /* 然特现現球第經谁 */
+- '\xE8', '\xB5', '\xB7', /* 起 */
+- '\0',
++ '\xE8', '\xB5', '\xB7', '|', /* 起 | */
+ '\xE4', '\xBE', '\x8B', '\xE5', '\x88', '\xA5', '\xE5', '\x88', '\xAB', '\xE5', '\x88', '\xB6', '\xE5', '\x8A', '\xA8', '\xE5', '\x8B', '\x95', '\xE5', '\x90', '\x97', '\xE5', '\x97', '\x8E', /* 例別别制动動吗嗎 */
+ '\xE5', '\xA2', '\x9E', '\xE6', '\x8C', '\x87', '\xE6', '\x98', '\x8E', '\xE6', '\x9C', '\x9D', '\xE6', '\x9C', '\x9F', '\xE6', '\x9E', '\x84', '\xE7', '\x89', '\xA9', '\xE7', '\xA1', '\xAE', /* 增指明朝期构物确 */
+ '\xE7', '\xA7', '\x8D', '\xE8', '\xAA', '\xBF', '\xE8', '\xB0', '\x83', '\xE8', '\xB2', '\xBB', '\xE8', '\xB4', '\xB9', '\xE9', '\x82', '\xA3', '\xE9', '\x83', '\xBD', '\xE9', '\x96', '\x93', /* 种調调費费那都間 */
+@@ -113,14 +117,21 @@
+ af_blue_stringsets[] =
+ {
+ /* */
+- { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+- { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 },
+- { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+- { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
+- AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+- { AF_BLUE_STRING_LATIN_SMALL, 0 },
+- { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 },
+- { AF_BLUE_STRING_MAX, 0 },
++ { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
++ { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 },
++ { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
++ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
++ { AF_BLUE_STRING_CYRILLIC_SMALL, 0 },
++ { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 },
++ { AF_BLUE_STRING_MAX, 0 },
++ { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
++ { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP },
++ { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
++ AF_BLUE_PROPERTY_LATIN_NEUTRAL |
++ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
++ { AF_BLUE_STRING_DEVANAGARI_BASE, 0 },
++ { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 },
++ { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 },
+ { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+@@ -129,35 +140,28 @@
+ { AF_BLUE_STRING_GREEK_SMALL, 0 },
+ { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
+- { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+- { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 },
+- { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
+- AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
+- { AF_BLUE_STRING_CYRILLIC_SMALL, 0 },
+- { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 },
+- { AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_LONG },
+ { AF_BLUE_STRING_HEBREW_BOTTOM, 0 },
+ { AF_BLUE_STRING_HEBREW_DESCENDER, 0 },
+ { AF_BLUE_STRING_MAX, 0 },
++ { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
++ { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 },
++ { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
++ { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
++ AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
++ { AF_BLUE_STRING_LATIN_SMALL, 0 },
++ { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 },
++ { AF_BLUE_STRING_MAX, 0 },
+ #ifdef AF_CONFIG_OPTION_CJK
+- { AF_BLUE_STRING_CJK_TOP_FILL, AF_BLUE_PROPERTY_CJK_TOP |
+- AF_BLUE_PROPERTY_CJK_FILL },
+- { AF_BLUE_STRING_CJK_TOP_UNFILL, AF_BLUE_PROPERTY_CJK_TOP },
+- { AF_BLUE_STRING_CJK_BOTTOM_FILL, AF_BLUE_PROPERTY_CJK_FILL },
+- { AF_BLUE_STRING_CJK_BOTTOM_UNFILL, 0 },
++ { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP },
++ { AF_BLUE_STRING_CJK_BOTTOM, 0 },
+ #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
+- { AF_BLUE_STRING_CJK_LEFT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ |
+- AF_BLUE_PROPERTY_CJK_FILL },
+- { AF_BLUE_STRING_CJK_LEFT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ },
+- { AF_BLUE_STRING_CJK_RIGHT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ |
+- AF_BLUE_PROPERTY_CJK_RIGHT |
+- AF_BLUE_PROPERTY_CJK_FILL },
+- { AF_BLUE_STRING_CJK_RIGHT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ |
+- AF_BLUE_PROPERTY_CJK_RIGHT },
++ { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ },
++ { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ |
++ AF_BLUE_PROPERTY_CJK_RIGHT },
+ #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
+- { AF_BLUE_STRING_MAX, 0 },
++ { AF_BLUE_STRING_MAX, 0 },
+ #endif /* AF_CONFIG_OPTION_CJK */
+
+ };
+diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
+index d488f3f..74a472d 100644
+--- a/src/autofit/afblue.dat
++++ b/src/autofit/afblue.dat
+@@ -2,7 +2,7 @@
+ //
+ // Auto-fitter data for blue strings.
+ //
+-// Copyright 2013 by
++// Copyright 2013, 2014 by
+ // David Turner, Robert Wilhelm, and Werner Lemberg.
+ //
+ // This file is part of the FreeType project, and may only be used,
+@@ -34,11 +34,11 @@
+ // using C syntax. There can be only one string per line, thus the
+ // starting and ending double quote must be the first and last character
+ // in the line, respectively, ignoring whitespace before and after the
+-// string. If there are multiple strings (in multiple lines), they are
+-// concatenated to a single string. In the output, a string gets
+-// represented as a series of singles bytes, followed by a zero byte. The
+-// enumeration values simply hold byte offsets to the start of the
+-// corresponding strings.
++// string. Space characters within the string are ignored too. If there
++// are multiple strings (in multiple lines), they are concatenated to a
++// single string. In the output, a string gets represented as a series of
++// singles bytes, followed by a zero byte. The enumeration values simply
++// hold byte offsets to the start of the corresponding strings.
+ //
+ // - Data blocks enclosed in balanced braces, which get copied verbatim and
+ // which can span multiple lines. The opening brace of a block must be
+@@ -63,18 +63,32 @@
+ // characters, not bytes.
+
+
++// The blue zone string data, to be used in the blue stringsets below.
++
+ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
+
+- AF_BLUE_STRING_LATIN_CAPITAL_TOP
+- "THEZOCQS"
+- AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM
+- "HEZLOCUS"
+- AF_BLUE_STRING_LATIN_SMALL_F_TOP
+- "fijkdbh"
+- AF_BLUE_STRING_LATIN_SMALL
+- "xzroesc"
+- AF_BLUE_STRING_LATIN_SMALL_DESCENDER
+- "pqgjy"
++ AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP
++ "БВЕПЗОСЭ"
++ AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM
++ "БВЕШЗОСЭ"
++ AF_BLUE_STRING_CYRILLIC_SMALL
++ "хпншезос"
++ AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER
++ "руф"
++
++ // we separate the letters with spaces to avoid ligatures;
++ // this is just for convenience to simplify reading
++ AF_BLUE_STRING_DEVANAGARI_BASE
++ "क म अ आ थ ध भ श"
++ AF_BLUE_STRING_DEVANAGARI_TOP
++ "ई ऐ ओ औ ि ी ो ौ"
++ // note that some fonts have extreme variation in the height of the
++ // round head elements; for this reason we also define the `base'
++ // blue zone, which must be always present
++ AF_BLUE_STRING_DEVANAGARI_HEAD
++ "क म अ आ थ ध भ श"
++ AF_BLUE_STRING_DEVANAGARI_BOTTOM
++ "ु ृ"
+
+ AF_BLUE_STRING_GREEK_CAPITAL_TOP
+ "ΓΒΕΖΘΟΩ"
+@@ -87,15 +101,6 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
+ AF_BLUE_STRING_GREEK_SMALL_DESCENDER
+ "βγημρφχψ"
+
+- AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP
+- "БВЕПЗОСЭ"
+- AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM
+- "БВЕШЗОСЭ"
+- AF_BLUE_STRING_CYRILLIC_SMALL
+- "хпншезос"
+- AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER
+- "руф"
+-
+ AF_BLUE_STRING_HEBREW_TOP
+ "בדהחךכםס"
+ AF_BLUE_STRING_HEBREW_BOTTOM
+@@ -103,24 +108,33 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
+ AF_BLUE_STRING_HEBREW_DESCENDER
+ "קךןףץ"
+
++ AF_BLUE_STRING_LATIN_CAPITAL_TOP
++ "THEZOCQS"
++ AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM
++ "HEZLOCUS"
++ AF_BLUE_STRING_LATIN_SMALL_F_TOP
++ "fijkdbh"
++ AF_BLUE_STRING_LATIN_SMALL
++ "xzroesc"
++ AF_BLUE_STRING_LATIN_SMALL_DESCENDER
++ "pqgjy"
++
+ #ifdef AF_CONFIG_OPTION_CJK
+
+- AF_BLUE_STRING_CJK_TOP_FILL
++ AF_BLUE_STRING_CJK_TOP
+ "他们你來們到和地"
+ "对對就席我时時會"
+ "来為能舰說说这這"
+- "齊"
+- AF_BLUE_STRING_CJK_TOP_UNFILL
++ "齊 |"
+ "军同已愿既星是景"
+ "民照现現理用置要"
+ "軍那配里開雷露面"
+ "顾"
+- AF_BLUE_STRING_CJK_BOTTOM_FILL
++ AF_BLUE_STRING_CJK_BOTTOM
+ "个为人他以们你來"
+ "個們到和大对對就"
+ "我时時有来為要說"
+- "说"
+- AF_BLUE_STRING_CJK_BOTTOM_UNFILL
++ "说 |"
+ "主些因它想意理生"
+ "當看着置者自著裡"
+ "过还进進過道還里"
+@@ -128,22 +142,20 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
+
+ #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
+
+- AF_BLUE_STRING_CJK_LEFT_FILL
++ AF_BLUE_STRING_CJK_LEFT
+ "些们你來們到和地"
+ "她将將就年得情最"
+ "样樣理能說说这這"
+- "通"
+- AF_BLUE_STRING_CJK_LEFT_UNFILL
++ "通 |"
+ "即吗吧听呢品响嗎"
+ "师師收断斷明眼間"
+ "间际陈限除陳随際"
+ "隨"
+- AF_BLUE_STRING_CJK_RIGHT_FILL
++ AF_BLUE_STRING_CJK_RIGHT
+ "事前學将將情想或"
+ "政斯新样樣民沒没"
+ "然特现現球第經谁"
+- "起"
+- AF_BLUE_STRING_CJK_RIGHT_UNFILL
++ "起 |"
+ "例別别制动動吗嗎"
+ "增指明朝期构物确"
+ "种調调費费那都間"
+@@ -154,17 +166,118 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
+ #endif /* AF_CONFIG_OPTION_CJK */
+
+
++// The blue zone stringsets, as used in the script styles, cf. `afstyles.h'.
++//
++// The AF_BLUE_PROPERTY_XXX flags are defined in `afblue.h'; here some
++// explanations.
++//
++// A blue zone in general is defined by a reference and an overshoot line.
++// During the hinting process, all coordinate values between those two lines
++// are set equal to the reference value, provided that the blue zone is not
++// wider than 0.75 pixels (otherwise the blue zone gets ignored). All
++// entries must have `AF_BLUE_STRING_MAX' as the final line.
++//
++// During the glyph analysis, edges are sorted from bottom to top, and then
++// sequentially checked, edge by edge, against the blue zones in the order
++// given below.
++//
++//
++// latin auto-hinter
++// -----------------
++//
++// Characters in a blue string are automatically classified as having a flat
++// (reference) or a round (overshoot) extremum. The blue zone is then set
++// up by the mean values of all flat extrema and all round extrema,
++// respectively. Only horizontal blue zones (i.e., adjusting vertical
++// coordinate values) are supported.
++//
++// For the latin auto-hinter, the overshoot should be larger than the
++// reference for top zones, and vice versa for bottom zones.
++//
++// LATIN_TOP
++// Take the maximum flat and round coordinate values of the blue string
++// characters for computing the blue zone's reference and overshoot
++// values.
++//
++// If not set, take the minimum values.
++//
++// LATIN_NEUTRAL
++// Ignore round extrema and define the blue zone with flat values only.
++// Both top and bottom of contours can match. This is useful for
++// scripts like Devanagari where vowel signs attach to the base
++// character and are implemented as components of composite glyphs.
++//
++// If not set, both round and flat extrema are taken into account.
++// Additionally, only the top or the bottom of a contour can match,
++// depending on the LATIN_TOP flag.
++//
++// Neutral blue zones should always follow non-neutral blue zones.
++//
++// LATIN_X_HEIGHT
++// Scale all glyphs vertically from the corresponding script to make the
++// reference line of this blue zone align on the grid. The scaling
++// takes place before all other blue zones get aligned to the grid.
++// Only one blue character string of a script style can have this flag.
++//
++// LATIN_LONG
++// Apply an additional constraint for blue zone values: Don't
++// necessarily use the extremum as-is but a segment of the topmost (or
++// bottommost) contour that is longer than a heuristic threshold, and
++// which is not too far away vertically from the real extremum. This
++// ensures that small bumps in the outline are ignored (for example, the
++// `vertical serifs' found in many Hebrew glyph designs).
++//
++// The segment must be at least EM/25 font units long, and the distance
++// to the extremum must be smaller than EM/4.
++//
++//
++// cjk auto-hinter
++// ---------------
++//
++// Characters in a blue string are *not* automatically classified. Instead,
++// first come the characters used for the overshoot value, then the
++// character `|', then the characters used for the reference value. The
++// blue zone is then set up by the mean values of all reference values and
++// all overshoot values, respectively. Both horizontal and vertical blue
++// zones (i.e., adjusting vertical and horizontal coordinate values,
++// respectively) are supported.
++//
++// For the cjk auto-hinter, the overshoot should be smaller than the
++// reference for top zones, and vice versa for bottom zones.
++//
++// CJK_TOP
++// Take the maximum flat and round coordinate values of the blue string
++// characters. If not set, take the minimum values.
++//
++// CJK_RIGHT
++// A synonym for CJK_TOP. If CJK_HORIZ is set, this flag indicates the
++// right blue zone, taking horizontal maximum values.
++//
++// CJK_HORIZ
++// Define a blue zone for horizontal hinting (i.e., vertical blue
++// zones). If not set, this is a blue zone for vertical hinting.
++
++
+ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
+
+- AF_BLUE_STRINGSET_LATN
+- { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+- { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }
+- { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+- { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
+- AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+- { AF_BLUE_STRING_LATIN_SMALL, 0 }
+- { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }
+- { AF_BLUE_STRING_MAX, 0 }
++ AF_BLUE_STRINGSET_CYRL
++ { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
++ { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }
++ { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
++ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
++ { AF_BLUE_STRING_CYRILLIC_SMALL, 0 }
++ { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 }
++ { AF_BLUE_STRING_MAX, 0 }
++
++ AF_BLUE_STRINGSET_DEVA
++ { AF_BLUE_STRING_DEVANAGARI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
++ { AF_BLUE_STRING_DEVANAGARI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }
++ { AF_BLUE_STRING_DEVANAGARI_BASE, AF_BLUE_PROPERTY_LATIN_TOP |
++ AF_BLUE_PROPERTY_LATIN_NEUTRAL |
++ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
++ { AF_BLUE_STRING_DEVANAGARI_BASE, 0 }
++ { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 }
++ { AF_BLUE_STRING_MAX, 0 }
+
+ AF_BLUE_STRINGSET_GREK
+ { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+@@ -176,15 +289,6 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
+ { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
+- AF_BLUE_STRINGSET_CYRL
+- { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+- { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }
+- { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
+- AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
+- { AF_BLUE_STRING_CYRILLIC_SMALL, 0 }
+- { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0 }
+- { AF_BLUE_STRING_MAX, 0 }
+-
+ AF_BLUE_STRINGSET_HEBR
+ { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
+ AF_BLUE_PROPERTY_LATIN_LONG }
+@@ -192,25 +296,27 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
+ { AF_BLUE_STRING_HEBREW_DESCENDER, 0 }
+ { AF_BLUE_STRING_MAX, 0 }
+
++ AF_BLUE_STRINGSET_LATN
++ { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
++ { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }
++ { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
++ { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP |
++ AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
++ { AF_BLUE_STRING_LATIN_SMALL, 0 }
++ { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }
++ { AF_BLUE_STRING_MAX, 0 }
++
+ #ifdef AF_CONFIG_OPTION_CJK
+
+ AF_BLUE_STRINGSET_HANI
+- { AF_BLUE_STRING_CJK_TOP_FILL, AF_BLUE_PROPERTY_CJK_TOP |
+- AF_BLUE_PROPERTY_CJK_FILL }
+- { AF_BLUE_STRING_CJK_TOP_UNFILL, AF_BLUE_PROPERTY_CJK_TOP }
+- { AF_BLUE_STRING_CJK_BOTTOM_FILL, AF_BLUE_PROPERTY_CJK_FILL }
+- { AF_BLUE_STRING_CJK_BOTTOM_UNFILL, 0 }
++ { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP }
++ { AF_BLUE_STRING_CJK_BOTTOM, 0 }
+ #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
+- { AF_BLUE_STRING_CJK_LEFT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ |
+- AF_BLUE_PROPERTY_CJK_FILL }
+- { AF_BLUE_STRING_CJK_LEFT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ }
+- { AF_BLUE_STRING_CJK_RIGHT_FILL, AF_BLUE_PROPERTY_CJK_HORIZ |
+- AF_BLUE_PROPERTY_CJK_RIGHT |
+- AF_BLUE_PROPERTY_CJK_FILL }
+- { AF_BLUE_STRING_CJK_RIGHT_UNFILL, AF_BLUE_PROPERTY_CJK_HORIZ |
+- AF_BLUE_PROPERTY_CJK_RIGHT }
++ { AF_BLUE_STRING_CJK_LEFT, AF_BLUE_PROPERTY_CJK_HORIZ }
++ { AF_BLUE_STRING_CJK_RIGHT, AF_BLUE_PROPERTY_CJK_HORIZ |
++ AF_BLUE_PROPERTY_CJK_RIGHT }
+ #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
+- { AF_BLUE_STRING_MAX, 0 }
++ { AF_BLUE_STRING_MAX, 0 }
+
+ #endif /* AF_CONFIG_OPTION_CJK */
+
+diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
+index 6f336ab..d239e8e 100644
+--- a/src/autofit/afblue.h
++++ b/src/autofit/afblue.h
+@@ -7,7 +7,7 @@
+ /* */
+ /* Auto-fitter data for blue strings (specification). */
+ /* */
+-/* Copyright 2013 by */
++/* Copyright 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -67,42 +67,42 @@ FT_BEGIN_HEADER
+ /* At the bottommost level, we define strings for finding blue zones. */
+
+
+-#define AF_BLUE_STRING_MAX_LEN 25
++#define AF_BLUE_STRING_MAX_LEN 51
+
+ /* The AF_Blue_String enumeration values are offsets into the */
+ /* `af_blue_strings' array. */
+
+ typedef enum AF_Blue_String_
+ {
+- AF_BLUE_STRING_LATIN_CAPITAL_TOP = 0,
+- AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 9,
+- AF_BLUE_STRING_LATIN_SMALL_F_TOP = 18,
+- AF_BLUE_STRING_LATIN_SMALL = 26,
+- AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 34,
+- AF_BLUE_STRING_GREEK_CAPITAL_TOP = 40,
+- AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 55,
+- AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 68,
+- AF_BLUE_STRING_GREEK_SMALL = 81,
+- AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 98,
+- AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 115,
+- AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 132,
+- AF_BLUE_STRING_CYRILLIC_SMALL = 149,
+- AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 166,
+- AF_BLUE_STRING_HEBREW_TOP = 173,
+- AF_BLUE_STRING_HEBREW_BOTTOM = 190,
+- AF_BLUE_STRING_HEBREW_DESCENDER = 203,
+- af_blue_1_1 = 213,
++ AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 0,
++ AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 17,
++ AF_BLUE_STRING_CYRILLIC_SMALL = 34,
++ AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 51,
++ AF_BLUE_STRING_DEVANAGARI_BASE = 58,
++ AF_BLUE_STRING_DEVANAGARI_TOP = 83,
++ AF_BLUE_STRING_DEVANAGARI_HEAD = 108,
++ AF_BLUE_STRING_DEVANAGARI_BOTTOM = 133,
++ AF_BLUE_STRING_GREEK_CAPITAL_TOP = 140,
++ AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 155,
++ AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 168,
++ AF_BLUE_STRING_GREEK_SMALL = 181,
++ AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 198,
++ AF_BLUE_STRING_HEBREW_TOP = 215,
++ AF_BLUE_STRING_HEBREW_BOTTOM = 232,
++ AF_BLUE_STRING_HEBREW_DESCENDER = 245,
++ AF_BLUE_STRING_LATIN_CAPITAL_TOP = 256,
++ AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 265,
++ AF_BLUE_STRING_LATIN_SMALL_F_TOP = 274,
++ AF_BLUE_STRING_LATIN_SMALL = 282,
++ AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 290,
++ af_blue_1_1 = 295,
+ #ifdef AF_CONFIG_OPTION_CJK
+- AF_BLUE_STRING_CJK_TOP_FILL = af_blue_1_1 + 1,
+- AF_BLUE_STRING_CJK_TOP_UNFILL = af_blue_1_1 + 77,
+- AF_BLUE_STRING_CJK_BOTTOM_FILL = af_blue_1_1 + 153,
+- AF_BLUE_STRING_CJK_BOTTOM_UNFILL = af_blue_1_1 + 229,
++ AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
++ AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 153,
+ af_blue_1_1_1 = af_blue_1_1 + 304,
+ #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
+- AF_BLUE_STRING_CJK_LEFT_FILL = af_blue_1_1_1 + 1,
+- AF_BLUE_STRING_CJK_LEFT_UNFILL = af_blue_1_1_1 + 77,
+- AF_BLUE_STRING_CJK_RIGHT_FILL = af_blue_1_1_1 + 153,
+- AF_BLUE_STRING_CJK_RIGHT_UNFILL = af_blue_1_1_1 + 229,
++ AF_BLUE_STRING_CJK_LEFT = af_blue_1_1_1 + 1,
++ AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 153,
+ af_blue_1_1_2 = af_blue_1_1_1 + 304,
+ #else
+ af_blue_1_1_2 = af_blue_1_1_1 + 0,
+@@ -136,33 +136,34 @@ FT_BEGIN_HEADER
+ /* Properties are specific to a writing system. We assume that a given */
+ /* blue string can't be used in more than a single writing system, which */
+ /* is a safe bet. */
+-#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 )
+-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 1 )
+-#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 2 )
++#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 ) /* must have value 1 */
++#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1 << 1 )
++#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 2 )
++#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 3 )
+
+-#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 0 )
+-#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 1 )
+-#define AF_BLUE_PROPERTY_CJK_FILL ( 1 << 2 )
++#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 0 ) /* must have value 1 */
++#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 1 ) /* must have value 2 */
+ #define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP
+
+
+-#define AF_BLUE_STRINGSET_MAX_LEN 9
++#define AF_BLUE_STRINGSET_MAX_LEN 7
+
+ /* The AF_Blue_Stringset enumeration values are offsets into the */
+ /* `af_blue_stringsets' array. */
+
+ typedef enum AF_Blue_Stringset_
+ {
+- AF_BLUE_STRINGSET_LATN = 0,
+- AF_BLUE_STRINGSET_GREK = 7,
+- AF_BLUE_STRINGSET_CYRL = 14,
+- AF_BLUE_STRINGSET_HEBR = 20,
+- af_blue_2_1 = 24,
++ AF_BLUE_STRINGSET_CYRL = 0,
++ AF_BLUE_STRINGSET_DEVA = 6,
++ AF_BLUE_STRINGSET_GREK = 12,
++ AF_BLUE_STRINGSET_HEBR = 19,
++ AF_BLUE_STRINGSET_LATN = 23,
++ af_blue_2_1 = 30,
+ #ifdef AF_CONFIG_OPTION_CJK
+ AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
+- af_blue_2_1_1 = af_blue_2_1 + 4,
++ af_blue_2_1_1 = af_blue_2_1 + 2,
+ #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
+- af_blue_2_1_2 = af_blue_2_1_1 + 4,
++ af_blue_2_1_2 = af_blue_2_1_1 + 2,
+ #else
+ af_blue_2_1_2 = af_blue_2_1_1 + 0,
+ #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
+diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin
+index 4fc9917..0b4b48d 100644
+--- a/src/autofit/afblue.hin
++++ b/src/autofit/afblue.hin
+@@ -4,7 +4,7 @@
+ /* */
+ /* Auto-fitter data for blue strings (specification). */
+ /* */
+-/* Copyright 2013 by */
++/* Copyright 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -96,13 +96,13 @@ FT_BEGIN_HEADER
+ /* Properties are specific to a writing system. We assume that a given */
+ /* blue string can't be used in more than a single writing system, which */
+ /* is a safe bet. */
+-#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 )
+-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 1 )
+-#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 2 )
++#define AF_BLUE_PROPERTY_LATIN_TOP ( 1 << 0 ) /* must have value 1 */
++#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1 << 1 )
++#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1 << 2 )
++#define AF_BLUE_PROPERTY_LATIN_LONG ( 1 << 3 )
+
+-#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 0 )
+-#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 1 )
+-#define AF_BLUE_PROPERTY_CJK_FILL ( 1 << 2 )
++#define AF_BLUE_PROPERTY_CJK_TOP ( 1 << 0 ) /* must have value 1 */
++#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1 << 1 ) /* must have value 2 */
+ #define AF_BLUE_PROPERTY_CJK_RIGHT AF_BLUE_PROPERTY_CJK_TOP
+
+
+diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
+index 3a65fc5..048e0e7 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-2013 by */
++/* Copyright 2006-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -178,6 +178,8 @@
+ goto Exit;
+
+ af_latin_hints_link_segments( hints,
++ 0,
++ NULL,
+ (AF_Dimension)dim );
+
+ seg = axhints->segments;
+@@ -261,6 +263,8 @@
+ FT_Int num_fills;
+ FT_Int num_flats;
+
++ FT_Bool fill;
++
+ AF_CJKBlue blue;
+ FT_Error error;
+ AF_CJKAxis axis;
+@@ -271,22 +275,6 @@
+ AF_Blue_Stringset bss = sc->blue_stringset;
+ const AF_Blue_StringRec* bs = &af_blue_stringsets[bss];
+
+-#ifdef FT_DEBUG_LEVEL_TRACE
+- FT_String* cjk_blue_name[4] =
+- {
+- (FT_String*)"bottom", /* -- , -- */
+- (FT_String*)"top", /* -- , TOP */
+- (FT_String*)"left", /* HORIZ, -- */
+- (FT_String*)"right" /* HORIZ, TOP */
+- };
+-
+- FT_String* cjk_blue_type_name[2] =
+- {
+- (FT_String*)"unfilled", /* -- */
+- (FT_String*)"filled" /* FILL */
+- };
+-#endif
+-
+
+ /* we walk over the blue character strings as specified in the */
+ /* style's entry in the `af_blue_stringset' array, computing its */
+@@ -308,15 +296,29 @@
+ else
+ axis = &metrics->axis[AF_DIMENSION_VERT];
+
+- FT_TRACE5(( "blue zone %d:\n", axis->blue_count ));
++#ifdef FT_DEBUG_LEVEL_TRACE
++ {
++ FT_String* cjk_blue_name[4] =
++ {
++ (FT_String*)"bottom", /* -- , -- */
++ (FT_String*)"top", /* -- , TOP */
++ (FT_String*)"left", /* HORIZ, -- */
++ (FT_String*)"right" /* HORIZ, TOP */
++ };
++
++
++ FT_TRACE5(( "blue zone %d (%s):\n",
++ axis->blue_count,
++ cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) |
++ AF_CJK_IS_TOP_BLUE( bs ) ] ));
++ }
++#endif /* FT_DEBUG_LEVEL_TRACE */
+
+ num_fills = 0;
+ num_flats = 0;
+
+- FT_TRACE5(( " cjk blue %s/%s\n",
+- cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) |
+- AF_CJK_IS_TOP_BLUE( bs ) ],
+- cjk_blue_type_name[!!AF_CJK_IS_FILLED_BLUE( bs )] ));
++ fill = 1; /* start with characters that define fill values */
++ FT_TRACE5(( " [overshoot values]\n" ));
+
+ while ( *p )
+ {
+@@ -330,6 +332,14 @@
+
+ GET_UTF8_CHAR( ch, p );
+
++ /* switch to characters that define flat values */
++ if ( ch == '|' )
++ {
++ fill = 0;
++ FT_TRACE5(( " [reference values]\n" ));
++ continue;
++ }
++
+ /* load the character in the face -- skip unknown or empty ones */
+ af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset );
+ if ( glyph_index == 0 )
+@@ -417,7 +427,7 @@
+ FT_TRACE5(( " U+%04lX: best_pos = %5ld\n", ch, best_pos ));
+ }
+
+- if ( AF_CJK_IS_FILLED_BLUE( bs ) )
++ if ( fill )
+ fills[num_fills++] = best_pos;
+ else
+ flats[num_flats++] = best_pos;
+@@ -429,15 +439,15 @@
+ * we couldn't find a single glyph to compute this blue zone,
+ * we will simply ignore it then
+ */
+- FT_TRACE5(( " empty\n" ));
++ FT_TRACE5(( " empty\n" ));
+ continue;
+ }
+
+- /* we have computed the contents of the `fill' and `flats' tables, */
+- /* now determine the reference position of the blue zone -- */
+- /* we simply take the median value after a simple sort */
+- af_sort_pos( num_flats, flats );
++ /* we have computed the contents of the `fill' 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_fills, fills );
++ af_sort_pos( num_flats, flats );
+
+ blue = &axis->blues[axis->blue_count];
+ blue_ref = &blue->ref.org;
+@@ -476,7 +486,7 @@
+ *blue_ref =
+ *blue_shoot = ( shoot + ref ) / 2;
+
+- FT_TRACE5(( " [overshoot smaller than reference,"
++ FT_TRACE5(( " [reference smaller than overshoot,"
+ " taking mean value]\n" ));
+ }
+ }
+@@ -755,10 +765,6 @@
+ /* now compare each segment to the others */
+ for ( seg1 = segments; seg1 < segment_limit; seg1++ )
+ {
+- /* the fake segments are for metrics hinting only */
+- if ( seg1->first == seg1->last )
+- continue;
+-
+ if ( seg1->dir != major_dir )
+ continue;
+
+@@ -1018,10 +1024,11 @@
+
+ edge->first = seg;
+ edge->last = seg;
++ edge->dir = seg->dir;
+ edge->fpos = seg->pos;
+- edge->opos = edge->pos = FT_MulFix( seg->pos, scale );
++ edge->opos = FT_MulFix( seg->pos, scale );
++ edge->pos = edge->opos;
+ seg->edge_next = seg;
+- edge->dir = seg->dir;
+ }
+ else
+ {
+@@ -1230,8 +1237,10 @@
+ /* zone, check for left edges */
+ /* */
+ /* of course, that's for TrueType */
+- is_top_right_blue = FT_BOOL( blue->flags & AF_CJK_BLUE_TOP );
+- is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
++ is_top_right_blue =
++ (FT_Byte)( ( blue->flags & AF_CJK_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 */
+@@ -1528,6 +1537,12 @@
+
+
+ stem_edge->pos = base_edge->pos + fitted_width;
++
++ FT_TRACE5(( " CJKLINK: edge %d @%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 ));
+ }
+
+
+diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
+index a260b09..4dd4f39 100644
+--- a/src/autofit/afcjk.h
++++ b/src/autofit/afcjk.h
+@@ -4,7 +4,7 @@
+ /* */
+ /* Auto-fitter hinting routines for CJK writing system (specification). */
+ /* */
+-/* Copyright 2006, 2007, 2011-2013 by */
++/* Copyright 2006, 2007, 2011-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -50,8 +50,6 @@ FT_BEGIN_HEADER
+ ( (b)->properties & AF_BLUE_PROPERTY_CJK_TOP )
+ #define AF_CJK_IS_HORIZ_BLUE( b ) \
+ ( (b)->properties & AF_BLUE_PROPERTY_CJK_HORIZ )
+-#define AF_CJK_IS_FILLED_BLUE( b ) \
+- ( (b)->properties & AF_BLUE_PROPERTY_CJK_FILL )
+ #define AF_CJK_IS_RIGHT_BLUE AF_CJK_IS_TOP_BLUE
+
+ #define AF_CJK_MAX_WIDTHS 16
+diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
+index 7aa2e11..a54c20c 100644
+--- a/src/autofit/afglobal.c
++++ b/src/autofit/afglobal.c
+@@ -138,7 +138,7 @@
+ FT_Byte* gstyles = globals->glyph_styles;
+ FT_UInt ss;
+ FT_UInt i;
+- FT_UInt dflt = -1;
++ FT_UInt dflt = ~0U; /* a non-valid value */
+
+
+ /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */
+@@ -176,7 +176,8 @@
+ */
+ if ( style_class->coverage == AF_COVERAGE_DEFAULT )
+ {
+- if ( style_class->script == globals->module->default_script )
++ if ( (FT_UInt)style_class->script ==
++ globals->module->default_script )
+ dflt = ss;
+
+ for ( range = script_class->script_uni_ranges;
+@@ -332,8 +333,8 @@
+ af_face_globals_free( globals );
+ globals = NULL;
+ }
+-
+- globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX;
++ else
++ globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX;
+
+ Exit:
+ *aglobals = globals;
+diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
+index d2da40e..38d8d69 100644
+--- a/src/autofit/afglobal.h
++++ b/src/autofit/afglobal.h
+@@ -66,16 +66,16 @@ FT_BEGIN_HEADER
+
+ /* index of fallback style in `af_style_classes' */
+ #ifdef AF_CONFIG_OPTION_CJK
+-#define AF_STYLE_FALLBACK AF_STYLE_HANI_DFLT
++#define AF_STYLE_FALLBACK AF_STYLE_HANI_DFLT
+ #else
+-#define AF_STYLE_FALLBACK AF_STYLE_NONE_DFLT
++#define AF_STYLE_FALLBACK AF_STYLE_NONE_DFLT
+ #endif
+ /* default script for OpenType; ignored if HarfBuzz isn't used */
+-#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN
++#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN
+ /* a bit mask indicating an uncovered glyph */
+ #define AF_STYLE_UNASSIGNED 0x7F
+ /* if this flag is set, we have an ASCII digit */
+-#define AF_DIGIT 0x80
++#define AF_DIGIT 0x80
+
+ /* `increase-x-height' property */
+ #define AF_PROP_INCREASE_X_HEIGHT_MIN 6
+diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
+index 270a06b..9fbc541 100644
+--- a/src/autofit/afhints.c
++++ b/src/autofit/afhints.c
+@@ -74,7 +74,8 @@
+ }
+
+
+- /* Get new edge for given axis, direction, and position. */
++ /* Get new edge for given axis, direction, and position, */
++ /* without initializing the edge itself. */
+
+ FT_LOCAL( FT_Error )
+ af_axis_hints_new_edge( AF_AxisHints axis,
+@@ -130,10 +131,6 @@
+
+ axis->num_edges++;
+
+- FT_ZERO( edge );
+- edge->fpos = (FT_Short)fpos;
+- edge->dir = (FT_Char)dir;
+-
+ Exit:
+ *anedge = edge;
+ return error;
+@@ -204,7 +201,7 @@
+
+ for ( point = points; point < limit; point++ )
+ AF_DUMP(( " [ %5d | %5d | %5d | %6.2f | %6.2f"
+- " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
++ " | %5.2f | %5.2f | %c ]\n",
+ point - points,
+ point->fx,
+ point->fy,
+@@ -212,12 +209,7 @@
+ point->oy / 64.0,
+ point->x / 64.0,
+ point->y / 64.0,
+- ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
+- ( point->flags & AF_FLAG_INFLECTION ) ? 'i' : ' ',
+- ( point->flags & AF_FLAG_EXTREMA_X ) ? '<' : ' ',
+- ( point->flags & AF_FLAG_EXTREMA_Y ) ? 'v' : ' ',
+- ( point->flags & AF_FLAG_ROUND_X ) ? '(' : ' ',
+- ( point->flags & AF_FLAG_ROUND_Y ) ? 'u' : ' '));
++ ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' '));
+ AF_DUMP(( "\n" ));
+ }
+ #ifdef __cplusplus
+@@ -651,6 +643,9 @@
+
+ for ( point = points; point < point_limit; point++, vec++, tag++ )
+ {
++ point->in_dir = (FT_Char)AF_DIR_NONE;
++ point->out_dir = (FT_Char)AF_DIR_NONE;
++
+ point->fx = (FT_Short)vec->x;
+ point->fy = (FT_Short)vec->y;
+ point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
+@@ -698,91 +693,186 @@
+ }
+ }
+
+- /* compute directions of in & out vectors */
+ {
+- AF_Point first = points;
+- AF_Point prev = NULL;
+- FT_Pos in_x = 0;
+- FT_Pos in_y = 0;
+- AF_Direction in_dir = AF_DIR_NONE;
+-
+- FT_Pos last_good_in_x = 0;
+- FT_Pos last_good_in_y = 0;
+-
++ /*
++ * Compute directions of `in' and `out' vectors.
++ *
++ * Note that distances between points that are very near to each
++ * other are accumulated. In other words, the auto-hinter
++ * prepends the small vectors between near points to the first
++ * non-near vector. All intermediate points are tagged as
++ * weak; the directions are adjusted also to be equal to the
++ * accumulated one.
++ */
++
++ /* value 20 in `near_limit' is heuristic */
+ FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM;
+ FT_Int near_limit = 20 * units_per_em / 2048;
++ FT_Int near_limit2 = 2 * near_limit - 1;
+
++ AF_Point* contour;
++ AF_Point* contour_limit = hints->contours + hints->num_contours;
+
+- for ( point = points; point < point_limit; point++ )
++
++ for ( contour = hints->contours; contour < contour_limit; contour++ )
+ {
+- AF_Point next;
+- FT_Pos out_x, out_y;
++ AF_Point first = *contour;
++ AF_Point next, prev, curr;
++
++ FT_Pos out_x, out_y;
+
++ FT_Bool is_first;
+
+- if ( point == first )
++
++ /* since the first point of a contour could be part of a */
++ /* series of near points, go backwards to find the first */
++ /* non-near point and adjust `first' */
++
++ point = first;
++ prev = first->prev;
++
++ while ( prev != first )
+ {
+- prev = first->prev;
++ out_x = point->fx - prev->fx;
++ out_y = point->fy - prev->fy;
++
++ /*
++ * We use Taxicab metrics to measure the vector length.
++ *
++ * Note that the accumulated distances so far could have the
++ * opposite direction of the distance measured here. For this
++ * reason we use `near_limit2' for the comparison to get a
++ * non-near point even in the worst case.
++ */
++ if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
++ break;
++
++ point = prev;
++ prev = prev->prev;
++ }
+
+- in_x = first->fx - prev->fx;
+- in_y = first->fy - prev->fy;
++ /* adjust first point */
++ first = point;
+
+- last_good_in_x = in_x;
+- last_good_in_y = in_y;
++ /* now loop over all points of the contour to get */
++ /* `in' and `out' vector directions */
+
+- if ( FT_ABS( in_x ) + FT_ABS( in_y ) < near_limit )
+- {
+- /* search first non-near point to get a good `in_dir' value */
++ curr = first;
+
+- AF_Point point_ = prev;
++ /*
++ * We abuse the `u' and `v' fields to store index deltas to the
++ * next and previous non-near point, respectively.
++ *
++ * To avoid problems with not having non-near points, we point to
++ * `first' by default as the next non-near point.
++ *
++ */
++ curr->u = (FT_Pos)( first - curr );
++ first->v = -curr->u;
+
++ out_x = 0;
++ out_y = 0;
+
+- while ( point_ != first )
+- {
+- AF_Point prev_ = point_->prev;
++ is_first = 1;
+
+- FT_Pos in_x_ = point_->fx - prev_->fx;
+- FT_Pos in_y_ = point_->fy - prev_->fy;
++ for ( point = first;
++ point != first || is_first;
++ point = point->next )
++ {
++ AF_Direction out_dir;
+
+
+- if ( FT_ABS( in_x_ ) + FT_ABS( in_y_ ) >= near_limit )
+- {
+- last_good_in_x = in_x_;
+- last_good_in_y = in_y_;
++ is_first = 0;
+
+- break;
+- }
++ next = point->next;
+
+- point_ = prev_;
+- }
++ out_x += next->fx - point->fx;
++ out_y += next->fy - point->fy;
++
++ if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
++ {
++ next->flags |= AF_FLAG_WEAK_INTERPOLATION;
++ continue;
++ }
++
++ curr->u = (FT_Pos)( next - curr );
++ next->v = -curr->u;
++
++ out_dir = af_direction_compute( out_x, out_y );
++
++ /* adjust directions for all points inbetween; */
++ /* the loop also updates position of `curr' */
++ curr->out_dir = (FT_Char)out_dir;
++ for ( curr = curr->next; curr != next; curr = curr->next )
++ {
++ curr->in_dir = (FT_Char)out_dir;
++ curr->out_dir = (FT_Char)out_dir;
+ }
++ next->in_dir = (FT_Char)out_dir;
+
+- in_dir = af_direction_compute( in_x, in_y );
+- first = prev + 1;
++ curr->u = (FT_Pos)( first - curr );
++ first->v = -curr->u;
++
++ out_x = 0;
++ out_y = 0;
+ }
++ }
+
+- point->in_dir = (FT_Char)in_dir;
++ /*
++ * The next step is to `simplify' an outline's topology so that we
++ * can identify local extrema more reliably: A series of
++ * non-horizontal or non-vertical vectors pointing into the same
++ * quadrant are handled as a single, long vector. From a
++ * topological point of the view, the intermediate points are of no
++ * interest and thus tagged as weak.
++ */
+
+- /* check whether the current point is near to the previous one */
+- /* (value 20 in `near_limit' is heuristic; we use Taxicab */
+- /* metrics for the test) */
++ for ( point = points; point < point_limit; point++ )
++ {
++ if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
++ continue;
+
+- if ( FT_ABS( in_x ) + FT_ABS( in_y ) < near_limit )
+- point->flags |= AF_FLAG_NEAR;
+- else
++ if ( point->in_dir == AF_DIR_NONE &&
++ point->out_dir == AF_DIR_NONE )
+ {
+- last_good_in_x = in_x;
+- last_good_in_y = in_y;
+- }
++ /* check whether both vectors point into the same quadrant */
++
++ FT_Pos in_x, in_y;
++ FT_Pos out_x, out_y;
++
++ AF_Point next_u = point + point->u;
++ AF_Point prev_v = point + point->v;
++
+
+- next = point->next;
+- out_x = next->fx - point->fx;
+- out_y = next->fy - point->fy;
++ in_x = point->fx - prev_v->fx;
++ in_y = point->fy - prev_v->fy;
++
++ out_x = next_u->fx - point->fx;
++ out_y = next_u->fy - point->fy;
++
++ if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
++ {
++ /* yes, so tag current point as weak */
++ /* and update index deltas */
++
++ point->flags |= AF_FLAG_WEAK_INTERPOLATION;
++
++ prev_v->u = (FT_Pos)( next_u - prev_v );
++ next_u->v = -prev_v->u;
++ }
++ }
++ }
+
+- in_dir = af_direction_compute( out_x, out_y );
+- point->out_dir = (FT_Char)in_dir;
++ /*
++ * Finally, check for remaining weak points. Everything else not
++ * collected in edges so far is then implicitly classified as strong
++ * points.
++ */
+
+- /* Check for weak points. The remaining points not collected */
+- /* in edges are then implicitly classified as strong points. */
++ for ( point = points; point < point_limit; point++ )
++ {
++ if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
++ continue;
+
+ if ( point->flags & AF_FLAG_CONTROL )
+ {
+@@ -799,18 +889,25 @@
+ goto Is_Weak_Point;
+ }
+
+- /* test whether `in' and `out' direction is approximately */
+- /* the same (and use the last good `in' vector in case */
+- /* the current point is near to the previous one) */
+- if ( ft_corner_is_flat(
+- point->flags & AF_FLAG_NEAR ? last_good_in_x : in_x,
+- point->flags & AF_FLAG_NEAR ? last_good_in_y : in_y,
+- out_x,
+- out_y ) )
+ {
+- /* current point lies on a straight, diagonal line */
+- /* (more or less) */
+- goto Is_Weak_Point;
++ AF_Point next_u = point + point->u;
++ AF_Point prev_v = point + point->v;
++
++
++ if ( ft_corner_is_flat( point->fx - prev_v->fx,
++ point->fy - prev_v->fy,
++ next_u->fx - point->fx,
++ next_u->fy - point->fy ) )
++ {
++ /* either the `in' or the `out' vector is much more */
++ /* dominant than the other one, so tag current point */
++ /* as weak and update index deltas */
++
++ prev_v->u = (FT_Pos)( next_u - prev_v );
++ next_u->v = -prev_v->u;
++
++ goto Is_Weak_Point;
++ }
+ }
+ }
+ else if ( point->in_dir == -point->out_dir )
+@@ -818,9 +915,6 @@
+ /* current point forms a spike */
+ goto Is_Weak_Point;
+ }
+-
+- in_x = out_x;
+- in_y = out_y;
+ }
+ }
+ }
+@@ -977,8 +1071,7 @@
+ /* if this point is candidate to weak interpolation, we */
+ /* interpolate it after all strong points have been processed */
+
+- if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
+- !( point->flags & AF_FLAG_INFLECTION ) )
++ if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
+ continue;
+
+ if ( dim == AF_DIMENSION_VERT )
+diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
+index 5f1507f..92101de 100644
+--- a/src/autofit/afhints.h
++++ b/src/autofit/afhints.h
+@@ -4,7 +4,7 @@
+ /* */
+ /* Auto-fitter hinting routines (specification). */
+ /* */
+-/* Copyright 2003-2008, 2010-2012 by */
++/* Copyright 2003-2008, 2010-2012, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -72,13 +72,9 @@ FT_BEGIN_HEADER
+ * `af_{cjk,latin,...}_hints_compute_segments' are the functions to
+ * find segments in an outline.
+ *
+- * A segment is a series of consecutive points that are approximately
+- * aligned along a coordinate axis. The analysis to do so is specific
+- * to a writing system.
+- *
+- * A segment must have at least two points, except in the case of
+- * `fake' segments that are generated to hint metrics appropriately,
+- * and which consist of a single point.
++ * A segment is a series of at least two consecutive points that are
++ * approximately aligned along a coordinate axis. The analysis to do
++ * so is specific to a writing system.
+ *
+ *
+ * Edges
+@@ -148,7 +144,7 @@ FT_BEGIN_HEADER
+ * Serifs are detected by `af_{cjk,latin,...}_hint_edges'.
+ *
+ * In comparison to a stem, a serif (as handled by the auto-hinter
+- * module which takes care of the `latin' writing system) has
++ * module that takes care of the `latin' writing system) has
+ *
+ * best segment_1 = segment_2 && best segment_2 != segment_1
+ *
+@@ -178,19 +174,19 @@ FT_BEGIN_HEADER
+ *
+ * Strong Points
+ *
+- * Experience has shown that points which are not part of an edge need
+- * to be interpolated linearly between their two closest edges, even if
+- * these are not part of the contour of those particular points.
+- * Typical candidates for this are
++ * Experience has shown that points not part of an edge need to be
++ * interpolated linearly between their two closest edges, even if these
++ * are not part of the contour of those particular points. Typical
++ * candidates for this are
+ *
+ * - angle points (i.e., points where the `in' and `out' direction
+ * differ greatly)
+ *
+ * - inflection points (i.e., where the `in' and `out' angles are the
+ * same, but the curvature changes sign) [currently, such points
+- * aren't handled in the auto-hinter]
++ * aren't handled specially in the auto-hinter]
+ *
+- * `af_glyph_hints_align_strong_points' is the function which takes
++ * `af_glyph_hints_align_strong_points' is the function that takes
+ * care of such situations; it is equivalent to the TrueType `IP'
+ * hinting instruction.
+ *
+@@ -220,26 +216,12 @@ FT_BEGIN_HEADER
+ AF_FLAG_CUBIC = 1 << 1,
+ AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
+
+- /* point extremum flags */
+- AF_FLAG_EXTREMA_X = 1 << 2,
+- AF_FLAG_EXTREMA_Y = 1 << 3,
+-
+- /* point roundness flags */
+- AF_FLAG_ROUND_X = 1 << 4,
+- AF_FLAG_ROUND_Y = 1 << 5,
+-
+ /* point touch flags */
+- AF_FLAG_TOUCH_X = 1 << 6,
+- AF_FLAG_TOUCH_Y = 1 << 7,
++ AF_FLAG_TOUCH_X = 1 << 2,
++ AF_FLAG_TOUCH_Y = 1 << 3,
+
+ /* candidates for weak interpolation have this flag set */
+- AF_FLAG_WEAK_INTERPOLATION = 1 << 8,
+-
+- /* all inflection points in the outline have this flag set */
+- AF_FLAG_INFLECTION = 1 << 9,
+-
+- /* the current point is very near to another one */
+- AF_FLAG_NEAR = 1 << 10
++ AF_FLAG_WEAK_INTERPOLATION = 1 << 4
+
+ } AF_Flags;
+
+@@ -247,10 +229,11 @@ FT_BEGIN_HEADER
+ /* edge hint flags */
+ typedef enum AF_Edge_Flags_
+ {
+- AF_EDGE_NORMAL = 0,
+- AF_EDGE_ROUND = 1 << 0,
+- AF_EDGE_SERIF = 1 << 1,
+- AF_EDGE_DONE = 1 << 2
++ AF_EDGE_NORMAL = 0,
++ AF_EDGE_ROUND = 1 << 0,
++ AF_EDGE_SERIF = 1 << 1,
++ AF_EDGE_DONE = 1 << 2,
++ AF_EDGE_NEUTRAL = 1 << 3 /* set if edge aligns to a neutral blue zone */
+
+ } AF_Edge_Flags;
+
+diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
+index e3a7742..36a3689 100644
+--- a/src/autofit/aflatin.c
++++ b/src/autofit/aflatin.c
+@@ -171,7 +171,15 @@
+ if ( error )
+ goto Exit;
+
++ /*
++ * We assume that the glyphs selected for the stem width
++ * computation are `featureless' enough so that the linking
++ * algorithm works fine without adjustments of its scoring
++ * function.
++ */
+ af_latin_hints_link_segments( hints,
++ 0,
++ NULL,
+ (AF_Dimension)dim );
+
+ seg = axhints->segments;
+@@ -298,6 +306,14 @@
+ have_flag = 1;
+ }
+
++ if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
++ {
++ if ( have_flag )
++ FT_TRACE5(( ", " ));
++ FT_TRACE5(( "neutral" ));
++ have_flag = 1;
++ }
++
+ if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) )
+ {
+ if ( have_flag )
+@@ -520,6 +536,13 @@
+ FT_Int last;
+ FT_Bool hit;
+
++ /* we intentionally declare these two variables */
++ /* outside of the loop since various compilers emit */
++ /* incorrect warning messages otherwise, talking about */
++ /* `possibly uninitialized variables' */
++ FT_Int p_first = 0; /* make compiler happy */
++ FT_Int p_last = 0;
++
+ FT_Bool left2right;
+
+
+@@ -552,7 +575,6 @@
+ {
+ FT_Bool l2r;
+ FT_Pos d;
+- FT_Int p_first, p_last;
+
+
+ if ( !hit )
+@@ -688,6 +710,13 @@
+ FT_CURVE_TAG( outline.tags[best_segment_last] ) !=
+ FT_CURVE_TAG_ON );
+
++ if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
++ {
++ /* only use flat segments for a neutral blue zone */
++ FT_TRACE5(( " (round, skipped)\n" ));
++ continue;
++ }
++
+ FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
+ }
+
+@@ -758,6 +787,8 @@
+ blue->flags = 0;
+ if ( AF_LATIN_IS_TOP_BLUE( bs ) )
+ blue->flags |= AF_LATIN_BLUE_TOP;
++ if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
++ blue->flags |= AF_LATIN_BLUE_NEUTRAL;
+
+ /*
+ * The following flag is used later to adjust the y and x scales
+@@ -1262,17 +1293,19 @@
+ /* this is the start of a new segment! */
+ segment_dir = (AF_Direction)point->out_dir;
+
+- /* clear all segment fields */
+ error = af_axis_hints_new_segment( axis, memory, &segment );
+ if ( error )
+ goto Exit;
+
+- segment[0] = seg0;
++ /* clear all segment fields */
++ segment[0] = seg0;
++
+ segment->dir = (FT_Char)segment_dir;
+ min_pos = max_pos = point->u;
+ segment->first = point;
+ segment->last = point;
+- on_edge = 1;
++
++ on_edge = 1;
+ }
+
+ point = point->next;
+@@ -1296,9 +1329,6 @@
+ FT_Pos last_v = last->v;
+
+
+- if ( first == last )
+- continue;
+-
+ if ( first_v < last_v )
+ {
+ AF_Point p;
+@@ -1337,31 +1367,44 @@
+ }
+
+
+- /* Link segments to form stems and serifs. */
++ /* Link segments to form stems and serifs. If `width_count' and */
++ /* `widths' are non-zero, use them to fine-tune the scoring function. */
+
+ FT_LOCAL_DEF( void )
+ af_latin_hints_link_segments( AF_GlyphHints hints,
++ FT_UInt width_count,
++ AF_WidthRec* widths,
+ AF_Dimension dim )
+ {
+ AF_AxisHints axis = &hints->axis[dim];
+ AF_Segment segments = axis->segments;
+ AF_Segment segment_limit = segments + axis->num_segments;
+- FT_Pos len_threshold, len_score;
++ FT_Pos len_threshold, len_score, dist_score, max_width;
+ AF_Segment seg1, seg2;
+
+
++ if ( width_count )
++ max_width = widths[width_count - 1].org;
++ else
++ max_width = 0;
++
++ /* a heuristic value to set up a minimum value for overlapping */
+ len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
+ if ( len_threshold == 0 )
+ len_threshold = 1;
+
++ /* a heuristic value to weight lengths */
+ len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
+
++ /* a heuristic value to weight distances (no call to */
++ /* AF_LATIN_CONSTANT needed, since we work on multiples */
++ /* of the stem width) */
++ dist_score = 3000;
++
+ /* now compare each segment to the others */
+ for ( seg1 = segments; seg1 < segment_limit; seg1++ )
+ {
+- /* the fake segments are introduced to hint the metrics -- */
+- /* we must never link them to anything */
+- if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
++ if ( seg1->dir != axis->major_dir )
+ continue;
+
+ /* search for stems having opposite directions, */
+@@ -1375,10 +1418,9 @@
+ if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 )
+ {
+ /* compute distance between the two segments */
+- FT_Pos dist = pos2 - pos1;
+- FT_Pos min = seg1->min_coord;
+- FT_Pos max = seg1->max_coord;
+- FT_Pos len, score;
++ FT_Pos min = seg1->min_coord;
++ FT_Pos max = seg1->max_coord;
++ FT_Pos len;
+
+
+ if ( min < seg2->min_coord )
+@@ -1388,15 +1430,49 @@
+ max = seg2->max_coord;
+
+ /* compute maximum coordinate difference of the two segments */
++ /* (this is, how much they overlap) */
+ len = max - min;
+ if ( len >= len_threshold )
+ {
+- /* small coordinate differences cause a higher score, and */
+- /* segments with a greater distance cause a higher score also */
+- score = dist + len_score / len;
++ /*
++ * The score is the sum of two demerits indicating the
++ * `badness' of a fit, measured along the segments' main axis
++ * and orthogonal to it, respectively.
++ *
++ * o The less overlapping along the main axis, the worse it
++ * is, causing a larger demerit.
++ *
++ * o The nearer the orthogonal distance to a stem width, the
++ * better it is, causing a smaller demerit. For simplicity,
++ * however, we only increase the demerit for values that
++ * exceed the largest stem width.
++ */
++
++ FT_Pos dist = pos2 - pos1;
++
++ FT_Pos dist_demerit, score;
++
++
++ if ( max_width )
++ {
++ /* distance demerits are based on multiples of `max_width'; */
++ /* we scale by 1024 for getting more precision */
++ FT_Pos delta = ( dist << 10 ) / max_width - ( 1 << 10 );
++
++
++ if ( delta > 10000 )
++ dist_demerit = 32000;
++ else if ( delta > 0 )
++ dist_demerit = delta * delta / dist_score;
++ else
++ dist_demerit = 0;
++ }
++ else
++ dist_demerit = dist; /* default if no widths available */
++
++ score = dist_demerit + len_score / len;
+
+ /* and we search for the smallest score */
+- /* of the sum of the two values */
+ if ( score < seg1->score )
+ {
+ seg1->score = score;
+@@ -1728,6 +1804,8 @@
+
+ FT_LOCAL_DEF( FT_Error )
+ af_latin_hints_detect_features( AF_GlyphHints hints,
++ FT_UInt width_count,
++ AF_WidthRec* widths,
+ AF_Dimension dim )
+ {
+ FT_Error error;
+@@ -1736,7 +1814,7 @@
+ error = af_latin_hints_compute_segments( hints, dim );
+ if ( !error )
+ {
+- af_latin_hints_link_segments( hints, dim );
++ af_latin_hints_link_segments( hints, width_count, widths, dim );
+
+ error = af_latin_hints_compute_edges( hints, dim );
+ }
+@@ -1765,8 +1843,9 @@
+ for ( ; edge < edge_limit; edge++ )
+ {
+ FT_UInt bb;
+- AF_Width best_blue = NULL;
+- FT_Pos best_dist; /* initial threshold */
++ AF_Width best_blue = NULL;
++ FT_Bool best_blue_is_neutral = 0;
++ FT_Pos best_dist; /* initial threshold */
+
+
+ /* compute the initial threshold as a fraction of the EM size */
+@@ -1780,24 +1859,26 @@
+ for ( bb = 0; bb < latin->blue_count; bb++ )
+ {
+ AF_LatinBlue blue = latin->blues + bb;
+- FT_Bool is_top_blue, is_major_dir;
++ FT_Bool is_top_blue, is_neutral_blue, is_major_dir;
+
+
+ /* skip inactive blue zones (i.e., those that are too large) */
+ 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 )
++ /* if it is a top zone, check for right edges (against the major */
++ /* direction); if it is a bottom zone, check for left edges (in */
++ /* the major direction) -- this assumes the TrueType convention */
++ /* for the orientation of contours */
++ is_top_blue =
++ (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
++ is_neutral_blue =
++ (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0);
++ is_major_dir =
++ FT_BOOL( edge->dir == axis->major_dir );
++
++ /* neutral blue zones are handled for both directions */
++ if ( is_top_blue ^ is_major_dir || is_neutral_blue )
+ {
+ FT_Pos dist;
+
+@@ -1810,15 +1891,19 @@
+ dist = FT_MulFix( dist, scale );
+ if ( dist < best_dist )
+ {
+- best_dist = dist;
+- best_blue = &blue->ref;
++ best_dist = dist;
++ best_blue = &blue->ref;
++ best_blue_is_neutral = is_neutral_blue;
+ }
+
+ /* now compare it to the overshoot position and check whether */
+ /* the edge is rounded, and whether 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 )
++ /* position of a bottom zone (provided we don't have a */
++ /* neutral blue zone) */
++ if ( edge->flags & AF_EDGE_ROUND &&
++ dist != 0 &&
++ !is_neutral_blue )
+ {
+ FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
+
+@@ -1832,8 +1917,9 @@
+ dist = FT_MulFix( dist, scale );
+ if ( dist < best_dist )
+ {
+- best_dist = dist;
+- best_blue = &blue->shoot;
++ best_dist = dist;
++ best_blue = &blue->shoot;
++ best_blue_is_neutral = is_neutral_blue;
+ }
+ }
+ }
+@@ -1841,7 +1927,11 @@
+ }
+
+ if ( best_blue )
++ {
+ edge->blue_edge = best_blue;
++ if ( best_blue_is_neutral )
++ edge->flags |= AF_EDGE_NEUTRAL;
++ }
+ }
+ }
+
+@@ -2159,7 +2249,7 @@
+
+ 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 - hints->axis[dim].edges, stem_edge->opos / 64.0,
+ stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
+ }
+
+@@ -2226,14 +2316,41 @@
+ if ( edge->flags & AF_EDGE_DONE )
+ continue;
+
+- blue = edge->blue_edge;
+ edge1 = NULL;
+ edge2 = edge->link;
+
++ /*
++ * If a stem contains both a neutral and a non-neutral blue zone,
++ * skip the neutral one. Otherwise, outlines with different
++ * directions might be incorrectly aligned at the same vertical
++ * position.
++ *
++ * If we have two neutral blue zones, skip one of them.
++ *
++ */
++ if ( edge->blue_edge && edge2 && edge2->blue_edge )
++ {
++ FT_Byte neutral = edge->flags & AF_EDGE_NEUTRAL;
++ FT_Byte neutral2 = edge2->flags & AF_EDGE_NEUTRAL;
++
++
++ if ( ( neutral && neutral2 ) || neutral2 )
++ {
++ edge2->blue_edge = NULL;
++ edge2->flags &= ~AF_EDGE_NEUTRAL;
++ }
++ else if ( neutral )
++ {
++ edge->blue_edge = NULL;
++ edge->flags &= ~AF_EDGE_NEUTRAL;
++ }
++ }
++
++ blue = edge->blue_edge;
+ if ( blue )
+ edge1 = edge;
+
+- /* flip edges if the other stem is aligned to a blue zone */
++ /* flip edges if the other edge is aligned to a blue zone */
+ else if ( edge2 && edge2->blue_edge )
+ {
+ blue = edge2->blue_edge;
+@@ -2300,7 +2417,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 %d\n", edge2 - edges ));
+
+ af_latin_align_linked_edge( hints, dim, edge2, edge );
+ edge->flags |= AF_EDGE_DONE;
+@@ -2689,6 +2806,8 @@
+ FT_Error error;
+ int dim;
+
++ AF_LatinAxis axis;
++
+
+ error = af_glyph_hints_reload( hints, outline );
+ if ( error )
+@@ -2702,14 +2821,22 @@
+ if ( AF_HINTS_DO_HORIZONTAL( hints ) )
+ #endif
+ {
+- error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
++ axis = &metrics->axis[AF_DIMENSION_HORZ];
++ error = af_latin_hints_detect_features( hints,
++ axis->width_count,
++ axis->widths,
++ AF_DIMENSION_HORZ );
+ if ( error )
+ goto Exit;
+ }
+
+ if ( AF_HINTS_DO_VERTICAL( hints ) )
+ {
+- error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );
++ axis = &metrics->axis[AF_DIMENSION_VERT];
++ error = af_latin_hints_detect_features( hints,
++ axis->width_count,
++ axis->widths,
++ AF_DIMENSION_VERT );
+ if ( error )
+ goto Exit;
+
+diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
+index a958af3..2c0bfca 100644
+--- a/src/autofit/aflatin.h
++++ b/src/autofit/aflatin.h
+@@ -5,7 +5,7 @@
+ /* Auto-fitter hinting routines for latin writing system */
+ /* (specification). */
+ /* */
+-/* Copyright 2003-2007, 2009, 2011-2013 by */
++/* Copyright 2003-2007, 2009, 2011-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -53,6 +53,8 @@ FT_BEGIN_HEADER
+
+ #define AF_LATIN_IS_TOP_BLUE( b ) \
+ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP )
++#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \
++ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL )
+ #define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \
+ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT )
+ #define AF_LATIN_IS_LONG_BLUE( b ) \
+@@ -63,10 +65,11 @@ FT_BEGIN_HEADER
+
+ enum
+ {
+- AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */
+- AF_LATIN_BLUE_TOP = 1 << 1, /* result of AF_LATIN_IS_TOP_BLUE */
+- AF_LATIN_BLUE_ADJUSTMENT = 1 << 2, /* used for scale adjustment */
+- /* optimization */
++ AF_LATIN_BLUE_ACTIVE = 1 << 0, /* set if zone height is <= 3/4px */
++ AF_LATIN_BLUE_TOP = 1 << 1, /* set if we have a top blue zone */
++ AF_LATIN_BLUE_NEUTRAL = 1 << 2, /* set if we have neutral blue zone */
++ AF_LATIN_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment */
++ /* optimization */
+ AF_LATIN_BLUE_FLAG_MAX
+ };
+
+@@ -169,6 +172,8 @@ FT_BEGIN_HEADER
+
+ FT_LOCAL( void )
+ af_latin_hints_link_segments( AF_GlyphHints hints,
++ FT_UInt width_count,
++ AF_WidthRec* widths,
+ AF_Dimension dim );
+
+ FT_LOCAL( FT_Error )
+@@ -177,6 +182,8 @@ FT_BEGIN_HEADER
+
+ FT_LOCAL( FT_Error )
+ af_latin_hints_detect_features( AF_GlyphHints hints,
++ FT_UInt width_count,
++ AF_WidthRec* widths,
+ AF_Dimension dim );
+
+ /* */
+diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
+index 930fa98..07590b3 100644
+--- a/src/autofit/aflatin2.c
++++ b/src/autofit/aflatin2.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* Auto-fitter hinting routines for latin writing system (body). */
+ /* */
+-/* Copyright 2003-2013 by */
++/* Copyright 2003-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -890,9 +890,6 @@
+ FT_Pos last_v = last->v;
+
+
+- if ( first == last )
+- continue;
+-
+ if ( first_v < last_v )
+ {
+ p = first->prev;
+@@ -984,7 +981,7 @@
+ #ifdef AF_SORT_SEGMENTS
+ for ( seg1 = segments; seg1 < segment_mid; seg1++ )
+ {
+- if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
++ if ( seg1->dir != axis->major_dir )
+ continue;
+
+ for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ )
+@@ -992,9 +989,7 @@
+ /* now compare each segment to the others */
+ for ( seg1 = segments; seg1 < segment_limit; seg1++ )
+ {
+- /* the fake segments are introduced to hint the metrics -- */
+- /* we must never link them to anything */
+- if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
++ if ( seg1->dir != axis->major_dir )
+ continue;
+
+ for ( seg2 = segments; seg2 < segment_limit; seg2++ )
+@@ -1194,9 +1189,10 @@
+
+ edge->first = seg;
+ edge->last = seg;
+- edge->fpos = seg->pos;
+ edge->dir = seg->dir;
+- edge->opos = edge->pos = FT_MulFix( seg->pos, scale );
++ edge->fpos = seg->pos;
++ edge->opos = FT_MulFix( seg->pos, scale );
++ edge->pos = edge->opos;
+ seg->edge_next = seg;
+ }
+ else
+diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
+index 73bf832..181cf55 100644
+--- a/src/autofit/afmodule.c
++++ b/src/autofit/afmodule.c
+@@ -103,8 +103,8 @@
+ AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss];
+
+
+- if ( style_class->script == *fallback_script &&
+- style_class->coverage == AF_COVERAGE_DEFAULT )
++ if ( (FT_UInt)style_class->script == *fallback_script &&
++ style_class->coverage == AF_COVERAGE_DEFAULT )
+ {
+ module->fallback_style = ss;
+ break;
+diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c
+index 3d919b5..139a4c1 100644
+--- a/src/autofit/afranges.c
++++ b/src/autofit/afranges.c
+@@ -21,51 +21,59 @@
+
+ const AF_Script_UniRangeRec af_cyrl_uniranges[] =
+ {
+- AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */
++ AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */
+ AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */
+ AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */
+ AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */
+ AF_UNIRANGE_REC( 0UL, 0UL )
+ };
+
++ const AF_Script_UniRangeRec af_deva_uniranges[] =
++ {
++ AF_UNIRANGE_REC( 0x0900UL, 0x097FUL ), /* Devanagari */
++ AF_UNIRANGE_REC( 0x20B9UL, 0x20B9UL ), /* (new) Rupee sign */
++ AF_UNIRANGE_REC( 0UL, 0UL )
++ };
++
+ const AF_Script_UniRangeRec af_grek_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */
+- AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */
++ AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */
+ AF_UNIRANGE_REC( 0UL, 0UL )
+ };
+
+ const AF_Script_UniRangeRec af_hebr_uniranges[] =
+ {
+- AF_UNIRANGE_REC( 0x0590UL, 0x05FFUL ), /* Hebrew */
++ AF_UNIRANGE_REC( 0x0590UL, 0x05FFUL ), /* Hebrew */
+ AF_UNIRANGE_REC( 0xFB1DUL, 0xFB4FUL ), /* Alphab. Present. Forms (Hebrew) */
+ AF_UNIRANGE_REC( 0UL, 0UL )
+ };
+
+ const AF_Script_UniRangeRec af_latn_uniranges[] =
+ {
+- AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */
+- AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */
+- AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */
+- AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */
+- AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */
+- AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */
+- AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */
+- AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */
+- AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */
++ AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */
++ AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */
++ AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */
++ AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */
++ AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */
++ AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */
++ AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */
++ AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */
++ AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */
+ AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */
+- AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */
+- AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */
+- AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */
+- AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */
+- AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */
+- AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */
+- AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */
+- AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */
+- AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */
+- AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */
+- AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */
+- AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */
++ AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */
++ AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */
++ AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */
++ AF_UNIRANGE_REC( 0x20A0UL, 0x20B8UL ), /* Currency Symbols ... */
++ AF_UNIRANGE_REC( 0x20BAUL, 0x20CFUL ), /* ... except new Rupee sign */
++ AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */
++ AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */
++ AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */
++ AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */
++ AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */
++ AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */
++ AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */
++ AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */
+ AF_UNIRANGE_REC( 0UL, 0UL )
+ };
+
+@@ -82,12 +90,6 @@
+ AF_UNIRANGE_REC( 0UL, 0UL )
+ };
+
+- const AF_Script_UniRangeRec af_deva_uniranges[] =
+- {
+- AF_UNIRANGE_REC( 0x0900UL, 0x097FUL ), /* Devanagari */
+- AF_UNIRANGE_REC( 0UL, 0UL )
+- };
+-
+ const AF_Script_UniRangeRec af_gujr_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x0A80UL, 0x0AFFUL ), /* Gujarati */
+diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
+index ae20932..a418b05 100644
+--- a/src/autofit/afscript.h
++++ b/src/autofit/afscript.h
+@@ -31,6 +31,11 @@
+ HB_SCRIPT_CYRILLIC,
+ 0x43E, 0x41E, 0x0 ) /* оО */
+
++ SCRIPT( deva, DEVA,
++ "Devanagari",
++ HB_SCRIPT_DEVANAGARI,
++ 0x920, 0x935, 0x91F ) /* ठ व ट */
++
+ SCRIPT( grek, GREK,
+ "Greek",
+ HB_SCRIPT_GREEK,
+@@ -58,11 +63,6 @@
+ HB_SCRIPT_BENGALI,
+ 'o', 0x0, 0x0 ) /* XXX */
+
+- SCRIPT( deva, DEVA,
+- "Devanagari",
+- HB_SCRIPT_DEVANAGARI,
+- 'o', 0x0, 0x0 ) /* XXX */
+-
+ SCRIPT( gujr, GUJR,
+ "Gujarati",
+ HB_SCRIPT_GUJARATI,
+diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
+index 429da76..27fdd2e 100644
+--- a/src/autofit/afstyles.h
++++ b/src/autofit/afstyles.h
+@@ -81,7 +81,9 @@
+ DEFAULT )
+
+ META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" )
++
+ META_STYLE_LATIN( grek, GREK, "Greek" )
++
+ STYLE( hebr_dflt, HEBR_DFLT,
+ "Hebrew default style",
+ AF_WRITING_SYSTEM_LATIN,
+@@ -90,6 +92,13 @@
+ AF_COVERAGE_DEFAULT )
+ META_STYLE_LATIN( latn, LATN, "Latin" )
+
++ STYLE( deva_dflt, DEVA_DFLT,
++ "Devanagari default style",
++ AF_WRITING_SYSTEM_LATIN,
++ AF_SCRIPT_DEVA,
++ AF_BLUE_STRINGSET_DEVA,
++ AF_COVERAGE_DEFAULT )
++
+ #ifdef FT_OPTION_AUTOFIT2
+ STYLE( ltn2_dflt, LTN2_DFLT,
+ "Latin 2 default style",
+@@ -119,7 +128,6 @@
+ AF_COVERAGE_DEFAULT )
+
+ STYLE_DEFAULT_INDIC( beng, BENG, "Bengali" )
+- STYLE_DEFAULT_INDIC( deva, DEVA, "Devanagari" )
+ STYLE_DEFAULT_INDIC( gujr, GUJR, "Gujarati" )
+ STYLE_DEFAULT_INDIC( guru, GURU, "Gurmukhi" )
+ STYLE_DEFAULT_INDIC( knda, KNDA, "Kannada" )
+diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c
+index 11fb743..cc04815 100644
+--- a/src/autofit/hbshim.c
++++ b/src/autofit/hbshim.c
+@@ -247,6 +247,7 @@
+ * (this is, not a single character is covered), we skip this coverage.
+ *
+ */
++ if ( style_class->coverage != AF_COVERAGE_DEFAULT )
+ {
+ AF_Blue_Stringset bss = style_class->blue_stringset;
+ const AF_Blue_StringRec* bs = &af_blue_stringsets[bss];
+@@ -328,8 +329,15 @@
+ * out whether a glyph gets shifted vertically, but this is something I
+ * would like to avoid if not really necessary.
+ *
++ * Note that we don't follow this logic for the default coverage.
++ * Complex scripts like Devanagari have mandatory GPOS features to
++ * position many glyph elements, using mark-to-base or mark-to-ligature
++ * tables; the number of glyphs missed due to condition (b) would be far
++ * too large.
++ *
+ */
+- hb_set_subtract( gsub_glyphs, gpos_glyphs );
++ if ( style_class->coverage != AF_COVERAGE_DEFAULT )
++ hb_set_subtract( gsub_glyphs, gpos_glyphs );
+
+ #ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE4(( " glyphs without GPOS data (`*' means already assigned)" ));
+@@ -347,6 +355,12 @@
+ count++;
+ #endif
+
++ /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */
++ /* can be arbitrary: some fonts use fake indices for processing */
++ /* internal to GSUB or GPOS, which is fully valid */
++ if ( idx >= (hb_codepoint_t)globals->glyph_count )
++ continue;
++
+ if ( gstyles[idx] == AF_STYLE_UNASSIGNED )
+ gstyles[idx] = (FT_Byte)style_class->style;
+ #ifdef FT_DEBUG_LEVEL_TRACE
+diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
+index 8d3f383..349cb95 100644
+--- a/src/base/ftbbox.c
++++ b/src/base/ftbbox.c
+@@ -203,15 +203,48 @@
+ /* max :: The address of the current maximum. */
+ /* */
+ static FT_Pos
+- update_cubic_max( FT_Pos q1,
+- FT_Pos q2,
+- FT_Pos q3,
+- FT_Pos q4,
+- FT_Pos max )
++ cubic_peak( FT_Pos q1,
++ FT_Pos q2,
++ FT_Pos q3,
++ FT_Pos q4 )
+ {
+- /* for a cubic segment to possibly reach new maximum, at least */
+- /* one of its off-points must stay above the current value */
+- while ( q2 > max || q3 > max )
++ FT_Pos peak = 0;
++ FT_Int shift;
++
++ /* This function finds a peak of a cubic segment if it is above 0 */
++ /* using iterative bisection of the segment, or returns 0. */
++ /* The fixed-point arithmetic of bisection is inherently stable */
++ /* but may loose accuracy in the two lowest bits. To compensate, */
++ /* we upscale the segment if there is room. Large values may need */
++ /* to be downscaled to avoid overflows during bisection. */
++ /* It is called with either q2 or q3 positive, which is necessary */
++ /* for the peak to exist and avoids undefined FT_MSB. */
++
++ shift = 27 -
++ FT_MSB( FT_ABS( q1 ) | FT_ABS( q2 ) | FT_ABS( q3 ) | FT_ABS( q4 ) );
++
++ if ( shift > 0 )
++ {
++ /* upscaling too much just wastes time */
++ if ( shift > 2 )
++ shift = 2;
++
++ q1 <<= shift;
++ q2 <<= shift;
++ q3 <<= shift;
++ q4 <<= shift;
++ }
++ else
++ {
++ q1 >>= -shift;
++ q2 >>= -shift;
++ q3 >>= -shift;
++ q4 >>= -shift;
++ }
++
++ /* for a peak to exist above 0, the cubic segment must have */
++ /* at least one of its control off-points above 0. */
++ while ( q2 > 0 || q3 > 0 )
+ {
+ /* determine which half contains the maximum and split */
+ if ( q1 + q2 > q3 + q4 ) /* first half */
+@@ -240,17 +273,22 @@
+ /* check whether either end reached the maximum */
+ if ( q1 == q2 && q1 >= q3 )
+ {
+- max = q1;
++ peak = q1;
+ break;
+ }
+ if ( q3 == q4 && q2 <= q4 )
+ {
+- max = q4;
++ peak = q4;
+ break;
+ }
+ }
+
+- return max;
++ if ( shift > 0 )
++ peak >>= shift;
++ else
++ peak <<= -shift;
++
++ return peak;
+ }
+
+
+@@ -262,65 +300,17 @@
+ FT_Pos* min,
+ FT_Pos* max )
+ {
+- FT_Pos nmin, nmax;
+- FT_Int shift;
+-
+-
+ /* This function is only called when a control off-point is outside */
+- /* the bbox that contains all on-points. It finds a local extremum */
+- /* within the segment using iterative bisection of the segment. */
+- /* The fixed-point arithmetic of bisection is inherently stable */
+- /* but may loose accuracy in the two lowest bits. To compensate, */
+- /* we upscale the segment if there is room. Large values may need */
+- /* to be downscaled to avoid overflows during bisection. */
+- /* The control off-point outside the bbox is likely to have the top */
+- /* absolute value among arguments. */
+-
+- shift = 27 - FT_MSB( FT_ABS( p2 ) | FT_ABS( p3 ) );
+-
+- if ( shift > 0 )
+- {
+- /* upscaling too much just wastes time */
+- if ( shift > 2 )
+- shift = 2;
+-
+- p1 <<= shift;
+- p2 <<= shift;
+- p3 <<= shift;
+- p4 <<= shift;
+- nmin = *min << shift;
+- nmax = *max << shift;
+- }
+- else
+- {
+- p1 >>= -shift;
+- p2 >>= -shift;
+- p3 >>= -shift;
+- p4 >>= -shift;
+- nmin = *min >> -shift;
+- nmax = *max >> -shift;
+- }
++ /* the bbox that contains all on-points. So at least one of the */
++ /* conditions below holds and cubic_peak is called with at least one */
++ /* non-zero argument. */
+
+- nmax = update_cubic_max( p1, p2, p3, p4, nmax );
++ if ( p2 > *max || p3 > *max )
++ *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max );
+
+ /* now flip the signs to update the minimum */
+- nmin = -update_cubic_max( -p1, -p2, -p3, -p4, -nmin );
+-
+- if ( shift > 0 )
+- {
+- nmin >>= shift;
+- nmax >>= shift;
+- }
+- else
+- {
+- nmin <<= -shift;
+- nmax <<= -shift;
+- }
+-
+- if ( nmin < *min )
+- *min = nmin;
+- if ( nmax > *max )
+- *max = nmax;
++ if ( p2 < *min || p3 < *min )
++ *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 );
+ }
+
+
+diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
+index 5606745..158a428 100644
+--- a/src/base/ftbitmap.c
++++ b/src/base/ftbitmap.c
+@@ -378,11 +378,8 @@
+ static FT_Byte
+ ft_gray_for_premultiplied_srgb_bgra( const FT_Byte* bgra )
+ {
+- FT_Long a = bgra[3];
+- FT_Long b = bgra[0];
+- FT_Long g = bgra[1];
+- FT_Long r = bgra[2];
+- FT_Long l;
++ FT_UInt a = bgra[3];
++ FT_UInt l;
+
+
+ /* Short-circuit transparent color to avoid div-by-zero. */
+@@ -397,38 +394,30 @@
+ *
+ * http://accessibility.kde.org/hsl-adjusted.php
+ *
+- * We do the computation with integers only.
++ * We do the computation with integers only, applying a gamma of 2.0.
++ * We guarantee 32-bit arithmetic to avoid overflow but the resulting
++ * luminosity fits into 16 bits.
++ *
+ */
+
+- /* Undo premultification, get the number in a 16.16 form. */
+- b = FT_MulDiv( b, 65536, a );
+- g = FT_MulDiv( g, 65536, a );
+- r = FT_MulDiv( r, 65536, a );
+- a = a * 256;
+-
+- /* Apply gamma of 2.0 instead of 2.2. */
+- b = FT_MulFix( b, b );
+- g = FT_MulFix( g, g );
+- r = FT_MulFix( r, r );
+-
+- /* Apply coefficients. */
+- b = FT_MulFix( b, 4731 /* 0.0722 * 65536 */ );
+- g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ );
+- r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ );
+-
+- l = r + g + b;
++ l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
++ 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
++ 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
+
+ /*
+- * Final transparency can be determined this way:
++ * Final transparency can be determined as follows.
+ *
+ * - If alpha is zero, we want 0.
+ * - If alpha is zero and luminosity is zero, we want 255.
+ * - If alpha is zero and luminosity is one, we want 0.
+ *
+- * So the formula is a * (1 - l).
++ * So the formula is a * (1 - l) = a - l * a.
++ *
++ * We still need to undo premultiplication by dividing l by a*a.
++ *
+ */
+
+- return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 );
++ return (FT_Byte)( a - l / a );
+ }
+
+
+diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
+index 6e65583..d0c43e0 100644
+--- a/src/base/ftcalc.c
++++ b/src/base/ftcalc.c
+@@ -39,7 +39,8 @@
+ #include FT_INTERNAL_DEBUG_H
+ #include FT_INTERNAL_OBJECTS_H
+
+-#ifdef FT_MULFIX_INLINED
++
++#ifdef FT_MULFIX_ASSEMBLER
+ #undef FT_MulFix
+ #endif
+
+@@ -67,6 +68,16 @@
+ #define FT_COMPONENT trace_calc
+
+
++ /* transfer sign leaving a positive number */
++#define FT_MOVE_SIGN( x, s ) \
++ FT_BEGIN_STMNT \
++ if ( x < 0 ) \
++ { \
++ x = -x; \
++ s = -s; \
++ } \
++ FT_END_STMNT
++
+ /* The following three functions are available regardless of whether */
+ /* FT_LONG64 is defined. */
+
+@@ -99,6 +110,7 @@
+ : -((-a) & ~0xFFFFL );
+ }
+
++#ifndef FT_MSB
+
+ FT_BASE_DEF ( FT_Int )
+ FT_MSB( FT_UInt32 z )
+@@ -106,27 +118,27 @@
+ FT_Int shift = 0;
+
+ /* determine msb bit index in `shift' */
+- if ( z >= ( 1L << 16 ) )
++ if ( z & 0xFFFF0000U )
+ {
+ z >>= 16;
+ shift += 16;
+ }
+- if ( z >= ( 1L << 8 ) )
++ if ( z & 0x0000FF00U )
+ {
+ z >>= 8;
+ shift += 8;
+ }
+- if ( z >= ( 1L << 4 ) )
++ if ( z & 0x000000F0U )
+ {
+ z >>= 4;
+ shift += 4;
+ }
+- if ( z >= ( 1L << 2 ) )
++ if ( z & 0x0000000CU )
+ {
+ z >>= 2;
+ shift += 2;
+ }
+- if ( z >= ( 1L << 1 ) )
++ if ( z & 0x00000002U )
+ {
+ /* z >>= 1; */
+ shift += 1;
+@@ -135,6 +147,8 @@
+ return shift;
+ }
+
++#endif /* !FT_MSB */
++
+
+ /* documentation is in ftcalc.h */
+
+@@ -162,14 +176,13 @@
+ FT_Long b,
+ FT_Long c )
+ {
+- FT_Int s;
++ FT_Int s = 1;
+ FT_Long d;
+
+
+- s = 1;
+- if ( a < 0 ) { a = -a; s = -1; }
+- if ( b < 0 ) { b = -b; s = -s; }
+- if ( c < 0 ) { c = -c; s = -s; }
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
++ FT_MOVE_SIGN( c, s );
+
+ d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c
+ : 0x7FFFFFFFL );
+@@ -185,14 +198,13 @@
+ FT_Long b,
+ FT_Long c )
+ {
+- FT_Int s;
++ FT_Int s = 1;
+ FT_Long d;
+
+
+- s = 1;
+- if ( a < 0 ) { a = -a; s = -1; }
+- if ( b < 0 ) { b = -b; s = -s; }
+- if ( c < 0 ) { c = -c; s = -s; }
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
++ FT_MOVE_SIGN( c, s );
+
+ d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c
+ : 0x7FFFFFFFL );
+@@ -217,17 +229,8 @@
+ FT_Long c;
+
+
+- if ( a < 0 )
+- {
+- a = -a;
+- s = -1;
+- }
+-
+- if ( b < 0 )
+- {
+- b = -b;
+- s = -s;
+- }
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
+
+ c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 );
+
+@@ -243,30 +246,17 @@
+ FT_DivFix( FT_Long a,
+ FT_Long b )
+ {
+- FT_Int32 s;
+- FT_UInt32 q;
++ FT_Int s = 1;
++ FT_Long q;
+
+
+- s = 1;
+- if ( a < 0 )
+- {
+- a = -a;
+- s = -1;
+- }
+- if ( b < 0 )
+- {
+- b = -b;
+- s = -s;
+- }
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
+
+- if ( b == 0 )
+- /* check for division by 0 */
+- q = 0x7FFFFFFFL;
+- else
+- /* compute result directly */
+- q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b );
++ q = (FT_Long)( b > 0 ? ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b
++ : 0x7FFFFFFFL );
+
+- return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
++ return ( s < 0 ? -q : q );
+ }
+
+
+@@ -314,25 +304,30 @@
+ FT_Int i;
+
+
+- q = 0;
+- r = hi;
+-
+- if ( r >= y )
++ if ( hi >= y )
+ return (FT_UInt32)0x7FFFFFFFL;
+
+- i = 32;
++ /* We shift as many bits as we can into the high register, perform */
++ /* 32-bit division with modulo there, then work through the remaining */
++ /* bits with long division. This optimization is especially noticeable */
++ /* for smaller dividends that barely use the high register. */
++
++ i = 31 - FT_MSB( hi );
++ r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */
++ q = r / y;
++ r -= q * y; /* remainder */
++
++ i = 32 - i; /* bits remaining in low register */
+ do
+ {
+- r <<= 1;
+ q <<= 1;
+- r |= lo >> 31;
++ r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1;
+
+ if ( r >= y )
+ {
+ r -= y;
+ q |= 1;
+ }
+- lo <<= 1;
+ } while ( --i );
+
+ return q;
+@@ -344,7 +339,7 @@
+ FT_Int64* y,
+ FT_Int64 *z )
+ {
+- register FT_UInt32 lo, hi;
++ FT_UInt32 lo, hi;
+
+
+ lo = x->lo + y->lo;
+@@ -355,58 +350,93 @@
+ }
+
+
+- /* documentation is in freetype.h */
+-
+- /* The FT_MulDiv function has been optimized thanks to ideas from */
+- /* Graham Asher. The trick is to optimize computation when everything */
+- /* fits within 32-bits (a rather common case). */
++ /* The FT_MulDiv function has been optimized thanks to ideas from */
++ /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */
++ /* a rather common case when everything fits within 32-bits. */
++ /* */
++ /* We compute 'a*b+c/2', then divide it by 'c' (all positive values). */
++ /* */
++ /* The product of two positive numbers never exceeds the square of */
++ /* its mean values. Therefore, we always avoid the overflow by */
++ /* imposing */
++ /* */
++ /* (a + b) / 2 <= sqrt(X - c/2) , */
+ /* */
+- /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */
++ /* where X = 2^32 - 1, the maximum unsigned 32-bit value, and using */
++ /* unsigned arithmetic. Now we replace `sqrt' with a linear function */
++ /* that is smaller or equal for all values of c in the interval */
++ /* [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the */
++ /* endpoints. Substituting the linear solution and explicit numbers */
++ /* we get */
+ /* */
+- /* 46340 is FLOOR(SQRT(2^31-1)). */
++ /* a + b <= 131071.99 - c / 122291.84 . */
+ /* */
+- /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
++ /* In practice, we should use a faster and even stronger inequality */
+ /* */
+- /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
++ /* a + b <= 131071 - (c >> 16) */
+ /* */
+- /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
++ /* or, alternatively, */
+ /* */
+- /* and 2*0x157F0 = 176096 */
++ /* a + b <= 129894 - (c >> 17) . */
+ /* */
++ /* FT_MulFix, on the other hand, is optimized for a small value of */
++ /* the first argument, when the second argument can be much larger. */
++ /* This can be achieved by scaling the second argument and the limit */
++ /* in the above inequalities. For example, */
++ /* */
++ /* a + (b >> 8) <= (131071 >> 4) */
++ /* */
++ /* covers the practical range of use. The actual test below is a bit */
++ /* tighter to avoid the border case overflows. */
++ /* */
++ /* In the case of FT_DivFix, the exact overflow check */
++ /* */
++ /* a << 16 <= X - c/2 */
++ /* */
++ /* is scaled down by 2^16 and we use */
++ /* */
++ /* a <= 65535 - (c >> 17) . */
++
++ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( FT_Long )
+ FT_MulDiv( FT_Long a,
+ FT_Long b,
+ FT_Long c )
+ {
+- long s;
++ FT_Int s = 1;
+
+
+ /* XXX: this function does not allow 64-bit arguments */
+ if ( a == 0 || b == c )
+ return a;
+
+- s = a; a = FT_ABS( a );
+- s ^= b; b = FT_ABS( b );
+- s ^= c; c = FT_ABS( c );
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
++ FT_MOVE_SIGN( c, s );
+
+- if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 )
+- a = ( a * b + ( c >> 1 ) ) / c;
++ if ( c == 0 )
++ a = 0x7FFFFFFFL;
++
++ else if ( (FT_ULong)a + b <= 129894UL - ( c >> 17 ) )
++ a = ( (FT_ULong)a * b + ( c >> 1 ) ) / c;
+
+- else if ( (FT_Int32)c > 0 )
++ else
+ {
+ FT_Int64 temp, temp2;
+
+
+- ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
++ ft_multo64( a, b, &temp );
+
+ temp2.hi = 0;
+- temp2.lo = (FT_UInt32)(c >> 1);
++ temp2.lo = c >> 1;
++
+ FT_Add64( &temp, &temp2, &temp );
+- a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
++
++ /* last attempt to ditch long division */
++ a = temp.hi == 0 ? temp.lo / c
++ : ft_div64by32( temp.hi, temp.lo, c );
+ }
+- else
+- a = 0x7FFFFFFFL;
+
+ return ( s < 0 ? -a : a );
+ }
+@@ -417,29 +447,33 @@
+ FT_Long b,
+ FT_Long c )
+ {
+- long s;
++ FT_Int s = 1;
+
+
+ if ( a == 0 || b == c )
+ return a;
+
+- s = a; a = FT_ABS( a );
+- s ^= b; b = FT_ABS( b );
+- s ^= c; c = FT_ABS( c );
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
++ FT_MOVE_SIGN( c, s );
+
+- if ( a <= 46340L && b <= 46340L && c > 0 )
+- a = a * b / c;
++ if ( c == 0 )
++ a = 0x7FFFFFFFL;
++
++ else if ( (FT_ULong)a + b <= 131071UL )
++ a = (FT_ULong)a * b / c;
+
+- else if ( (FT_Int32)c > 0 )
++ else
+ {
+ FT_Int64 temp;
+
+
+- ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
+- a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
++ ft_multo64( a, b, &temp );
++
++ /* last attempt to ditch long division */
++ a = temp.hi == 0 ? temp.lo / c
++ : ft_div64by32( temp.hi, temp.lo, c );
+ }
+- else
+- a = 0x7FFFFFFFL;
+
+ return ( s < 0 ? -a : a );
+ }
+@@ -497,7 +531,7 @@
+ ua = (FT_ULong)a;
+ ub = (FT_ULong)b;
+
+- if ( ua <= 2048 && ub <= 1048576L )
++ if ( ua + ( ub >> 8 ) <= 8190UL )
+ ua = ( ua * ub + 0x8000U ) >> 16;
+ else
+ {
+@@ -515,20 +549,20 @@
+
+ #else /* 0 */
+
+- FT_Long s;
++ FT_Int s = 1;
+ FT_ULong ua, ub;
+
+
+ if ( a == 0 || b == 0x10000L )
+ return a;
+
+- s = a; a = FT_ABS( a );
+- s ^= b; b = FT_ABS( b );
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
+
+ ua = (FT_ULong)a;
+ ub = (FT_ULong)b;
+
+- if ( ua <= 2048 && ub <= 1048576L )
++ if ( ua + ( ub >> 8 ) <= 8190UL )
+ ua = ( ua * ub + 0x8000UL ) >> 16;
+ else
+ {
+@@ -552,23 +586,24 @@
+ FT_DivFix( FT_Long a,
+ FT_Long b )
+ {
+- FT_Int32 s;
+- FT_UInt32 q;
++ FT_Int s = 1;
++ FT_Long q;
+
+
+ /* XXX: this function does not allow 64-bit arguments */
+- s = (FT_Int32)a; a = FT_ABS( a );
+- s ^= (FT_Int32)b; b = FT_ABS( b );
+
+- if ( (FT_UInt32)b == 0 )
++ FT_MOVE_SIGN( a, s );
++ FT_MOVE_SIGN( b, s );
++
++ if ( b == 0 )
+ {
+ /* check for division by 0 */
+- q = (FT_UInt32)0x7FFFFFFFL;
++ q = 0x7FFFFFFFL;
+ }
+- else if ( ( a >> 16 ) == 0 )
++ else if ( a <= 65535L - ( b >> 17 ) )
+ {
+ /* compute result directly */
+- q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
++ q = (FT_Long)( ( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / b );
+ }
+ else
+ {
+@@ -576,138 +611,18 @@
+ FT_Int64 temp, temp2;
+
+
+- temp.hi = (FT_Int32)( a >> 16 );
+- temp.lo = (FT_UInt32)a << 16;
++ temp.hi = a >> 16;
++ temp.lo = a << 16;
+ temp2.hi = 0;
+- temp2.lo = (FT_UInt32)( b >> 1 );
+- FT_Add64( &temp, &temp2, &temp );
+- q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b );
+- }
+-
+- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+- }
++ temp2.lo = b >> 1;
+
+-
+-#if 0
+-
+- /* documentation is in ftcalc.h */
+-
+- FT_EXPORT_DEF( void )
+- FT_MulTo64( FT_Int32 x,
+- FT_Int32 y,
+- FT_Int64 *z )
+- {
+- FT_Int32 s;
+-
+-
+- s = x; x = FT_ABS( x );
+- s ^= y; y = FT_ABS( y );
+-
+- ft_multo64( x, y, z );
+-
+- if ( s < 0 )
+- {
+- z->lo = (FT_UInt32)-(FT_Int32)z->lo;
+- z->hi = ~z->hi + !( z->lo );
+- }
+- }
+-
+-
+- /* apparently, the second version of this code is not compiled correctly */
+- /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
+-
+-#if 1
+-
+- FT_EXPORT_DEF( FT_Int32 )
+- FT_Div64by32( FT_Int64* x,
+- FT_Int32 y )
+- {
+- FT_Int32 s;
+- FT_UInt32 q, r, i, lo;
+-
+-
+- s = x->hi;
+- if ( s < 0 )
+- {
+- x->lo = (FT_UInt32)-(FT_Int32)x->lo;
+- x->hi = ~x->hi + !x->lo;
+- }
+- s ^= y; y = FT_ABS( y );
+-
+- /* Shortcut */
+- if ( x->hi == 0 )
+- {
+- if ( y > 0 )
+- q = x->lo / y;
+- else
+- q = 0x7FFFFFFFL;
+-
+- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+- }
+-
+- r = x->hi;
+- lo = x->lo;
+-
+- if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
+- return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
+- /* Return Max/Min Int32 if division overflow. */
+- /* This includes division by zero! */
+- q = 0;
+- for ( i = 0; i < 32; i++ )
+- {
+- r <<= 1;
+- q <<= 1;
+- r |= lo >> 31;
+-
+- if ( r >= (FT_UInt32)y )
+- {
+- r -= y;
+- q |= 1;
+- }
+- lo <<= 1;
+- }
+-
+- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+- }
+-
+-#else /* 0 */
+-
+- FT_EXPORT_DEF( FT_Int32 )
+- FT_Div64by32( FT_Int64* x,
+- FT_Int32 y )
+- {
+- FT_Int32 s;
+- FT_UInt32 q;
+-
+-
+- s = x->hi;
+- if ( s < 0 )
+- {
+- x->lo = (FT_UInt32)-(FT_Int32)x->lo;
+- x->hi = ~x->hi + !x->lo;
+- }
+- s ^= y; y = FT_ABS( y );
+-
+- /* Shortcut */
+- if ( x->hi == 0 )
+- {
+- if ( y > 0 )
+- q = ( x->lo + ( y >> 1 ) ) / y;
+- else
+- q = 0x7FFFFFFFL;
+-
+- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
++ FT_Add64( &temp, &temp2, &temp );
++ q = (FT_Long)ft_div64by32( temp.hi, temp.lo, b );
+ }
+
+- q = ft_div64by32( x->hi, x->lo, y );
+-
+- return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
++ return ( s < 0 ? -q : q );
+ }
+
+-#endif /* 0 */
+-
+-#endif /* 0 */
+-
+
+ #endif /* FT_LONG64 */
+
+diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
+index 852fb32..4aefb68 100644
+--- a/src/base/ftlcdfil.c
++++ b/src/base/ftlcdfil.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */
+ /* */
+-/* Copyright 2006, 2008-2010, 2013 by */
++/* Copyright 2006, 2008-2010, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -46,9 +46,12 @@
+ FT_Byte* line = bitmap->buffer;
+
+
++ /* `fir' and `pix' must be at least 32 bit wide, since the sum of */
++ /* the values in `weights' can exceed 0xFF */
++
+ for ( ; height > 0; height--, line += bitmap->pitch )
+ {
+- FT_UInt fir[5];
++ FT_UInt fir[4]; /* below, `pix' is used as the 5th element */
+ FT_UInt val1, xx;
+
+
+@@ -57,7 +60,6 @@
+ fir[1] = weights[3] * val1;
+ fir[2] = weights[4] * val1;
+ fir[3] = 0;
+- fir[4] = 0;
+
+ val1 = line[1];
+ fir[0] += weights[1] * val1;
+@@ -78,7 +80,7 @@
+ fir[3] = weights[4] * val;
+
+ pix >>= 8;
+- pix |= -( pix >> 8 );
++ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
+ line[xx - 2] = (FT_Byte)pix;
+ }
+
+@@ -87,11 +89,11 @@
+
+
+ pix = fir[0] >> 8;
+- pix |= -( pix >> 8 );
++ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
+ line[xx - 2] = (FT_Byte)pix;
+
+ pix = fir[1] >> 8;
+- pix |= -( pix >> 8 );
++ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
+ line[xx - 1] = (FT_Byte)pix;
+ }
+ }
+@@ -107,7 +109,7 @@
+ for ( ; width > 0; width--, column++ )
+ {
+ FT_Byte* col = column;
+- FT_UInt fir[5];
++ FT_UInt fir[4]; /* below, `pix' is used as the 5th element */
+ FT_UInt val1, yy;
+
+
+@@ -116,7 +118,6 @@
+ fir[1] = weights[3] * val1;
+ fir[2] = weights[4] * val1;
+ fir[3] = 0;
+- fir[4] = 0;
+ col += pitch;
+
+ val1 = col[0];
+@@ -139,7 +140,7 @@
+ fir[3] = weights[4] * val;
+
+ pix >>= 8;
+- pix |= -( pix >> 8 );
++ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
+ col[-2 * pitch] = (FT_Byte)pix;
+ col += pitch;
+ }
+@@ -149,11 +150,11 @@
+
+
+ pix = fir[0] >> 8;
+- pix |= -( pix >> 8 );
++ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
+ col[-2 * pitch] = (FT_Byte)pix;
+
+ pix = fir[1] >> 8;
+- pix |= -( pix >> 8 );
++ pix |= (FT_UInt)-(FT_Int)( pix >> 8 );
+ col[-pitch] = (FT_Byte)pix;
+ }
+ }
+diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
+index 6f32336..cc56105 100644
+--- a/src/base/ftobjs.c
++++ b/src/base/ftobjs.c
+@@ -4881,6 +4881,8 @@
+ *p_arg1 = subg->arg1;
+ *p_arg2 = subg->arg2;
+ *p_transform = subg->transform;
++
++ error = FT_Err_Ok;
+ }
+
+ return error;
+diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
+index 4a39dcd..632b6d2 100644
+--- a/src/base/ftoutln.c
++++ b/src/base/ftoutln.c
+@@ -1045,6 +1045,10 @@
+
+ FT_Outline_Get_CBox( outline, &cbox );
+
++ /* Handle collapsed outlines to avoid undefined FT_MSB. */
++ if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax )
++ return FT_ORIENTATION_NONE;
++
+ xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14;
+ xshift = FT_MAX( xshift, 0 );
+
+diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
+index 4ffdcb7..e3ce8a6 100644
+--- a/src/base/fttrigon.c
++++ b/src/base/fttrigon.c
+@@ -111,6 +111,7 @@
+ #endif /* !FT_LONG64 */
+
+
++ /* undefined and never called for zero vector */
+ static FT_Int
+ ft_trig_prenorm( FT_Vector* vec )
+ {
+diff --git a/src/base/ftutil.c b/src/base/ftutil.c
+index 879d027..9f37189 100644
+--- a/src/base/ftutil.c
++++ b/src/base/ftutil.c
+@@ -411,26 +411,4 @@
+ }
+
+
+- FT_BASE_DEF( FT_UInt32 )
+- ft_highpow2( FT_UInt32 value )
+- {
+- FT_UInt32 value2;
+-
+-
+- /*
+- * We simply clear the lowest bit in each iteration. When
+- * we reach 0, we know that the previous value was our result.
+- */
+- for ( ;; )
+- {
+- value2 = value & (value - 1); /* clear lowest bit */
+- if ( value2 == 0 )
+- break;
+-
+- value = value2;
+- }
+- return value;
+- }
+-
+-
+ /* END */
+diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
+index 5a1c296..d7649ab 100644
+--- a/src/bdf/bdfdrivr.c
++++ b/src/bdf/bdfdrivr.c
+@@ -182,7 +182,7 @@ THE SOFTWARE.
+ }
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FT_CMap_ClassRec bdf_cmap_class =
+ {
+ sizeof ( BDF_CMapRec ),
+diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
+index 84d336d..01be88c 100644
+--- a/src/cache/ftcbasic.c
++++ b/src/cache/ftcbasic.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* The FreeType basic cache interface (body). */
+ /* */
+-/* Copyright 2003-2007, 2009-2011, 2013 by */
++/* Copyright 2003-2007, 2009-2011, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -229,7 +229,7 @@
+ *
+ */
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_IFamilyClassRec ftc_basic_image_family_class =
+ {
+ {
+@@ -243,7 +243,7 @@
+ };
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_GCacheClassRec ftc_basic_image_cache_class =
+ {
+ {
+@@ -415,7 +415,7 @@
+ *
+ */
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_SFamilyClassRec ftc_basic_sbit_family_class =
+ {
+ {
+@@ -430,7 +430,7 @@
+ };
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_GCacheClassRec ftc_basic_sbit_cache_class =
+ {
+ {
+diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c
+index 848349b..b2e9609 100644
+--- a/src/cache/ftccmap.c
++++ b/src/cache/ftccmap.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* FreeType CharMap cache (body) */
+ /* */
+-/* Copyright 2000-2013 by */
++/* Copyright 2000-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -202,7 +202,7 @@
+ /*************************************************************************/
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_CacheClassRec ftc_cmap_cache_class =
+ {
+ ftc_cmap_node_new,
+diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c
+index 4eb2c5b..a65f94d 100644
+--- a/src/cache/ftcmanag.c
++++ b/src/cache/ftcmanag.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* FreeType Cache Manager (body). */
+ /* */
+-/* Copyright 2000-2006, 2008-2010, 2013 by */
++/* Copyright 2000-2006, 2008-2010, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -151,7 +151,7 @@
+ }
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_MruListClassRec ftc_size_list_class =
+ {
+ sizeof ( FTC_SizeNodeRec ),
+@@ -290,7 +290,7 @@
+ }
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FTC_MruListClassRec ftc_face_list_class =
+ {
+ sizeof ( FTC_FaceNodeRec),
+diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
+index 6e99dc2..3d2c22a 100644
+--- a/src/cff/cf2font.c
++++ b/src/cff/cf2font.c
+@@ -105,6 +105,7 @@
+ /* adjusting for emRatio converts darkenAmount to character */
+ /* space (font units). */
+ CF2_Fixed stemWidthPer1000, scaledStem;
++ FT_Int logBase2;
+
+
+ *darkenAmount = 0;
+@@ -131,26 +132,33 @@
+ /* convert from true character space to 1000 unit character space; */
+ /* add synthetic emboldening effect */
+
+- /* we have to assure that the computation of `scaledStem' */
+- /* and `stemWidthPer1000' don't overflow */
++ /* `stemWidthPer1000' will not overflow for a legitimate font */
+
+ stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
+
+- if ( emRatio > CF2_FIXED_ONE &&
+- stemWidthPer1000 <= ( stemWidth + boldenAmount ) )
+- {
+- stemWidthPer1000 = 0; /* to pacify compiler */
+- scaledStem = cf2_intToFixed( x4 );
+- }
++ /* `scaledStem' can easily overflow, so we must clamp its maximum */
++ /* value; the test doesn't need to be precise, but must be */
++ /* conservative. The clamp value (default 2333) where */
++ /* `darkenAmount' is zero is well below the overflow value of */
++ /* 32767. */
++ /* */
++ /* FT_MSB computes the integer part of the base 2 logarithm. The */
++ /* number of bits for the product is 1 or 2 more than the sum of */
++ /* logarithms; remembering that the 16 lowest bits of the fraction */
++ /* are dropped this is correct to within a factor of almost 4. */
++ /* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and */
++ /* is flagged as possible overflow because 0xff.ffff * 0xff.ffff = */
++ /* 0xffff.fe00 is also 23+23. */
++
++ logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) +
++ FT_MSB( (FT_UInt32)ppem );
++
++ if ( logBase2 >= 46 )
++ /* possible overflow */
++ scaledStem = cf2_intToFixed( x4 );
+ else
+- {
+ scaledStem = FT_MulFix( stemWidthPer1000, ppem );
+
+- if ( ppem > CF2_FIXED_ONE &&
+- scaledStem <= stemWidthPer1000 )
+- scaledStem = cf2_intToFixed( x4 );
+- }
+-
+ /* now apply the darkening parameters */
+
+ if ( scaledStem < cf2_intToFixed( x1 ) )
+diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c
+index 5853d77..81049f4 100644
+--- a/src/cff/cf2hints.c
++++ b/src/cff/cf2hints.c
+@@ -1560,7 +1560,7 @@
+ {
+ /* -y */
+ *x = -glyphpath->xOffset;
+- *y = glyphpath->xOffset;
++ *y = glyphpath->yOffset;
+ }
+ else
+ {
+diff --git a/src/gzip/inftrees.c b/src/gzip/inftrees.c
+index ef53652..56f52b1 100644
+--- a/src/gzip/inftrees.c
++++ b/src/gzip/inftrees.c
+@@ -115,16 +115,16 @@ uIntf *v /* working area: values in order of bit length */
+ uInt f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+- register uInt i; /* counter, current code */
+- register uInt j; /* counter */
+- register int k; /* number of bits in current code */
++ uInt i; /* counter, current code */
++ uInt j; /* counter */
++ int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
+- register uIntf *p; /* pointer into c[], b[], or v[] */
++ uIntf *p; /* pointer into c[], b[], or v[] */
+ inflate_huft *q; /* points to current table */
+ struct inflate_huft_s r; /* table entry for structure assignment */
+ inflate_huft *u[BMAX]; /* table stack */
+- register int w; /* bits before this table == (l * h) */
++ int w; /* bits before this table == (l * h) */
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
+ uIntf *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c
+index 748cbca..5183f6f 100644
+--- a/src/pcf/pcfdrivr.c
++++ b/src/pcf/pcfdrivr.c
+@@ -2,7 +2,7 @@
+
+ FreeType font driver for pcf files
+
+- Copyright (C) 2000-2004, 2006-2011, 2013 by
++ 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
+@@ -189,7 +189,7 @@ THE SOFTWARE.
+ }
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FT_CMap_ClassRec pcf_cmap_class =
+ {
+ sizeof ( PCF_CMapRec ),
+diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c
+index 4c43947..188aa0d 100644
+--- a/src/pfr/pfrdrivr.c
++++ b/src/pfr/pfrdrivr.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* FreeType PFR driver interface (body). */
+ /* */
+-/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013 by */
++/* Copyright 2002-2004, 2006, 2008, 2010, 2011, 2013, 2014 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 @@
+ }
+
+
+- FT_CALLBACK_TABLE_DEF
++ static
+ const FT_Service_PfrMetricsRec pfr_metrics_service_rec =
+ {
+ pfr_get_metrics,
+diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
+index 194d2df..0c89242 100644
+--- a/src/pfr/pfrobjs.c
++++ b/src/pfr/pfrobjs.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* FreeType PFR object methods (body). */
+ /* */
+-/* Copyright 2002-2008, 2010-2011, 2013 by */
++/* Copyright 2002-2008, 2010-2011, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -23,6 +23,7 @@
+ #include "pfrsbit.h"
+ #include FT_OUTLINE_H
+ #include FT_INTERNAL_DEBUG_H
++#include FT_INTERNAL_CALC_H
+ #include FT_TRUETYPE_IDS_H
+
+ #include "pfrerror.h"
+@@ -515,7 +516,7 @@
+ {
+ FT_UInt count = item->pair_count;
+ FT_UInt size = item->pair_size;
+- FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count );
++ FT_UInt power = 1 << FT_MSB( count );
+ FT_UInt probe = power * size;
+ FT_UInt extra = count - power;
+ FT_Byte* base = stream->cursor;
+diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
+index d0d8861..7792a62 100644
+--- a/src/psaux/psconv.c
++++ b/src/psaux/psconv.c
+@@ -250,7 +250,8 @@
+ if ( c < 0 || c >= 10 )
+ break;
+
+- if ( decimal < 0xCCCCCCCL )
++ /* only add digit if we don't overflow */
++ if ( divider < 0xCCCCCCCL && decimal < 0xCCCCCCCL )
+ {
+ decimal = decimal * 10 + c;
+
+diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
+index ddecc80..abbecb7 100644
+--- a/src/raster/ftraster.c
++++ b/src/raster/ftraster.c
+@@ -2284,6 +2284,8 @@
+ Long e1, e2;
+ Byte* target;
+
++ Int dropOutControl = left->flags & 7;
++
+ FT_UNUSED( y );
+ FT_UNUSED( left );
+ FT_UNUSED( right );
+@@ -2293,7 +2295,8 @@
+
+ e1 = TRUNC( CEILING( x1 ) );
+
+- if ( x2 - x1 - ras.precision <= ras.precision_jitter )
++ if ( dropOutControl != 2 &&
++ x2 - x1 - ras.precision <= ras.precision_jitter )
+ e2 = e1;
+ else
+ e2 = TRUNC( FLOOR( x2 ) );
+diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
+index 878de1f..9afbe5a 100644
+--- a/src/sfnt/pngshim.c
++++ b/src/sfnt/pngshim.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* PNG Bitmap glyph support. */
+ /* */
+-/* Copyright 2013 by Google, Inc. */
++/* Copyright 2013, 2014 by Google, Inc. */
+ /* Written by Stuart Gill and Behdad Esfahbod. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -129,7 +129,7 @@
+
+ *error = FT_THROW( Out_Of_Memory );
+ #ifdef PNG_SETJMP_SUPPORTED
+- longjmp( png_jmpbuf( png ), 1 );
++ ft_longjmp( png_jmpbuf( png ), 1 );
+ #endif
+ /* if we get here, then we have no choice but to abort ... */
+ }
+diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
+index a31c77c..44aa467 100644
+--- a/src/sfnt/sfobjs.c
++++ b/src/sfnt/sfobjs.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* SFNT object management (base). */
+ /* */
+-/* Copyright 1996-2008, 2010-2013 by */
++/* Copyright 1996-2008, 2010-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -348,29 +348,22 @@
+ }
+
+
+-#define WRITE_BYTE( p, v ) \
+- do \
+- { \
+- *(p)++ = (v) >> 0; \
+- \
++#define WRITE_USHORT( p, v ) \
++ do \
++ { \
++ *(p)++ = (FT_Byte)( (v) >> 8 ); \
++ *(p)++ = (FT_Byte)( (v) >> 0 ); \
++ \
+ } while ( 0 )
+
+-#define WRITE_USHORT( p, v ) \
+- do \
+- { \
+- *(p)++ = (v) >> 8; \
+- *(p)++ = (v) >> 0; \
+- \
+- } while ( 0 )
+-
+-#define WRITE_ULONG( p, v ) \
+- do \
+- { \
+- *(p)++ = (v) >> 24; \
+- *(p)++ = (v) >> 16; \
+- *(p)++ = (v) >> 8; \
+- *(p)++ = (v) >> 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 )
+
+
+@@ -661,6 +654,8 @@
+ }
+ else
+ {
++#ifdef FT_CONFIG_OPTION_USE_ZLIB
++
+ /* Uncompress with zlib. */
+ FT_ULong output_len = table->OrigLength;
+
+@@ -675,6 +670,13 @@
+ 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();
+@@ -717,7 +719,6 @@
+ }
+
+
+-#undef WRITE_BYTE
+ #undef WRITE_USHORT
+ #undef WRITE_ULONG
+
+diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
+index c717f5f..f9acf5d 100644
+--- a/src/sfnt/ttcmap.c
++++ b/src/sfnt/ttcmap.c
+@@ -3473,10 +3473,9 @@
+ /* only recognize format 0 */
+ if ( TT_NEXT_USHORT( p ) != 0 )
+ {
+- p -= 2;
+ FT_ERROR(( "tt_face_build_cmaps:"
+ " unsupported `cmap' table format = %d\n",
+- TT_PEEK_USHORT( p ) ));
++ TT_PEEK_USHORT( p - 2) ));
+ return FT_THROW( Invalid_Table );
+ }
+
+diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
+index 47a85c0..99d8005 100644
+--- a/src/sfnt/ttpost.c
++++ b/src/sfnt/ttpost.c
+@@ -5,7 +5,7 @@
+ /* Postcript name table processing for TrueType and OpenType fonts */
+ /* (body). */
+ /* */
+-/* Copyright 1996-2003, 2006-2010, 2013 by */
++/* Copyright 1996-2003, 2006-2010, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -64,12 +64,12 @@
+
+ #define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] )
+
+- /* the 258 default Mac PS glyph names */
++ /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */
+
+ static const FT_String* const tt_post_default_names[258] =
+ {
+ /* 0 */
+- ".notdef", ".null", "CR", "space", "exclam",
++ ".notdef", ".null", "nonmarkingreturn", "space", "exclam",
+ "quotedbl", "numbersign", "dollar", "percent", "ampersand",
+ /* 10 */
+ "quotesingle", "parenleft", "parenright", "asterisk", "plus",
+@@ -120,7 +120,7 @@
+ "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
+ "radical", "florin", "approxequal", "Delta", "guillemotleft",
+ /* 170 */
+- "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde",
++ "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
+ "Otilde", "OE", "oe", "endash", "emdash",
+ /* 180 */
+ "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
+@@ -144,8 +144,8 @@
+ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
+ "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
+ /* 250 */
+- "Idot", "Scedilla", "scedilla", "Cacute", "cacute",
+- "Ccaron", "ccaron", "dmacron",
++ "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute",
++ "Ccaron", "ccaron", "dcroat",
+ };
+
+
+diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
+index 8ff7b9d..180d559 100644
+--- a/src/sfnt/ttsbit.c
++++ b/src/sfnt/ttsbit.c
+@@ -256,7 +256,8 @@
+ case TT_SBIT_TABLE_TYPE_SBIX:
+ {
+ FT_Stream stream = face->root.stream;
+- FT_UInt offset, ppem, resolution, upem;
++ FT_UInt offset, upem;
++ FT_UShort ppem, resolution;
+ TT_HoriHeader *hori;
+ FT_ULong table_size;
+
+@@ -800,12 +801,12 @@
+ FT_Error error = FT_Err_Ok;
+ FT_UInt num_components, nn;
+
+- FT_Char horiBearingX = decoder->metrics->horiBearingX;
+- FT_Char horiBearingY = decoder->metrics->horiBearingY;
+- FT_Byte horiAdvance = decoder->metrics->horiAdvance;
+- FT_Char vertBearingX = decoder->metrics->vertBearingX;
+- FT_Char vertBearingY = decoder->metrics->vertBearingY;
+- FT_Byte vertAdvance = decoder->metrics->vertAdvance;
++ FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX;
++ FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY;
++ FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance;
++ FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX;
++ FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY;
++ FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance;
+
+
+ if ( p + 2 > limit )
+@@ -1352,10 +1353,11 @@
+
+ tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
+
+- metrics->horiBearingX = originOffsetX;
+- metrics->horiBearingY = -originOffsetY + metrics->height;
+- metrics->horiAdvance = aadvance * face->root.size->metrics.x_ppem /
+- face->header.Units_Per_EM;
++ metrics->horiBearingX = (FT_Short)originOffsetX;
++ metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
++ metrics->horiAdvance = (FT_Short)( aadvance *
++ face->root.size->metrics.x_ppem /
++ face->header.Units_Per_EM );
+ }
+
+ return error;
+diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
+index 425911a..27be966 100644
+--- a/src/smooth/ftgrays.c
++++ b/src/smooth/ftgrays.c
+@@ -98,6 +98,9 @@
+ #define FT_ERR_XCAT( x, y ) x ## y
+ #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y )
+
++#define FT_BEGIN_STMNT do {
++#define FT_END_STMNT } while ( 0 )
++
+
+ /* define this to dump debugging information */
+ /* #define FT_DEBUG_LEVEL_TRACE */
+diff --git a/src/tools/afblue.pl b/src/tools/afblue.pl
+index 58aa2a0..60fe696 100644
+--- a/src/tools/afblue.pl
++++ b/src/tools/afblue.pl
+@@ -63,8 +63,8 @@ my $enum_element_re = qr/ ^ \s* ( [A-Za-z0-9_]+ ) \s* $ /x;
+ # '#' <preprocessor directive> '\n'
+ my $preprocessor_re = qr/ ^ \# /x;
+
+-# '/' '/' <comment> '\n'
+-my $comment_re = qr| ^ // |x;
++# [<ws>] '/' '/' <comment> '\n'
++my $comment_re = qr| ^ \s* // |x;
+
+ # empty line
+ my $whitespace_only_re = qr/ ^ \s* $ /x;
+@@ -159,6 +159,9 @@ sub convert_ascii_chars
+ # A series of ASCII characters in the printable range.
+ my $s = shift;
+
++ # We ignore spaces.
++ $s =~ s/ //g;
++
+ my $count = $s =~ s/\G(.)/'$1', /g;
+ $curr_offset += $count;
+ $curr_elem_size += $count;
+diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
+index 5f676a2..ff2b339 100644
+--- a/src/truetype/ttgload.c
++++ b/src/truetype/ttgload.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* TrueType Glyph Loader (body). */
+ /* */
+-/* Copyright 1996-2013 */
++/* Copyright 1996-2014 */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -99,13 +99,13 @@
+
+ else if ( face->os2.version != 0xFFFFU )
+ {
+- *tsb = face->os2.sTypoAscender - yMax;
++ *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
+ *ah = face->os2.sTypoAscender - face->os2.sTypoDescender;
+ }
+
+ else
+ {
+- *tsb = face->horizontal.Ascender - yMax;
++ *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
+ *ah = face->horizontal.Ascender - face->horizontal.Descender;
+ }
+
+@@ -2120,7 +2120,7 @@
+ FT_Bool reexecute = FALSE;
+
+
+- if ( !size->cvt_ready )
++ if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
+ {
+ FT_Error error = tt_size_ready_bytecode( size, pedantic );
+
+@@ -2128,6 +2128,10 @@
+ if ( error )
+ return error;
+ }
++ else if ( size->bytecode_ready )
++ return size->bytecode_ready;
++ else if ( size->cvt_ready )
++ return size->cvt_ready;
+
+ /* query new execution context */
+ exec = size->debug ? size->context
+@@ -2238,12 +2242,15 @@
+
+ if ( reexecute )
+ {
+- FT_UInt i;
++ FT_UInt i;
++ FT_Error error;
+
+
+ for ( i = 0; i < size->cvt_size; i++ )
+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+- tt_size_run_prep( size, pedantic );
++ error = tt_size_run_prep( size, pedantic );
++ if ( error )
++ return error;
+ }
+
+ /* see whether the cvt program has disabled hinting */
+diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
+index 56e8fa7..7d0248b 100644
+--- a/src/truetype/ttinterp.c
++++ b/src/truetype/ttinterp.c
+@@ -172,6 +172,9 @@
+ #define CUR_Func_round( d, c ) \
+ CUR.func_round( EXEC_ARG_ d, c )
+
++#define CUR_Func_cur_ppem() \
++ CUR.func_cur_ppem( EXEC_ARG )
++
+ #define CUR_Func_read_cvt( index ) \
+ CUR.func_read_cvt( EXEC_ARG_ index )
+
+@@ -184,12 +187,6 @@
+ #define CURRENT_Ratio() \
+ Current_Ratio( EXEC_ARG )
+
+-#define CURRENT_Ppem() \
+- Current_Ppem( EXEC_ARG )
+-
+-#define CUR_Ppem() \
+- Cur_PPEM( EXEC_ARG )
+-
+ #define INS_SxVTL( a, b, c, d ) \
+ Ins_SxVTL( EXEC_ARG_ a, b, c, d )
+
+@@ -1446,7 +1443,7 @@
+ TT_MulFix14_arm( FT_Int32 a,
+ FT_Int b )
+ {
+- register FT_Int32 t, t2;
++ FT_Int32 t, t2;
+
+
+ #if defined( __CC_ARM ) || defined( __ARMCC__ )
+@@ -1706,9 +1703,16 @@
+ }
+
+
+- static FT_Long
++ FT_CALLBACK_DEF( FT_Long )
+ Current_Ppem( EXEC_OP )
+ {
++ return CUR.tt_metrics.ppem;
++ }
++
++
++ FT_CALLBACK_DEF( FT_Long )
++ Current_Ppem_Stretched( EXEC_OP )
++ {
+ return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+ }
+
+@@ -3089,7 +3093,7 @@
+
+
+ #define DO_MPPEM \
+- args[0] = CURRENT_Ppem();
++ args[0] = CUR_Func_cur_ppem();
+
+
+ /* Note: The pointSize should be irrelevant in a given font program; */
+@@ -3102,7 +3106,7 @@
+ #else
+
+ #define DO_MPS \
+- args[0] = CURRENT_Ppem();
++ args[0] = CUR_Func_cur_ppem();
+
+ #endif /* 0 */
+
+@@ -7487,9 +7491,9 @@
+ static void
+ Ins_DELTAP( INS_ARG )
+ {
+- FT_ULong k, nump;
++ FT_ULong nump, k;
+ FT_UShort A;
+- FT_ULong C;
++ FT_ULong C, P;
+ FT_Long B;
+ #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ FT_UShort B1, B2;
+@@ -7523,6 +7527,7 @@
+ }
+ #endif
+
++ P = (FT_ULong)CUR_Func_cur_ppem();
+ nump = (FT_ULong)args[0]; /* some points theoretically may occur more
+ than once, thus UShort isn't enough */
+
+@@ -7567,7 +7572,7 @@
+
+ C += CUR.GS.delta_base;
+
+- if ( CURRENT_Ppem() == (FT_Long)C )
++ if ( P == C )
+ {
+ B = ( (FT_ULong)B & 0xF ) - 8;
+ if ( B >= 0 )
+@@ -7596,9 +7601,9 @@
+ else if ( CUR.ignore_x_mode )
+ {
+ if ( CUR.GS.freeVector.y != 0 )
+- B1 = CUR.zp0.cur[A].y;
++ B1 = (FT_UShort)CUR.zp0.cur[A].y;
+ else
+- B1 = CUR.zp0.cur[A].x;
++ B1 = (FT_UShort)CUR.zp0.cur[A].x;
+
+ #if 0
+ /* Standard Subpixel Hinting: Allow y move. */
+@@ -7615,7 +7620,7 @@
+ !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
+ {
+ /* save the y value of the point now; compare after move */
+- B1 = CUR.zp0.cur[A].y;
++ B1 = (FT_UShort)CUR.zp0.cur[A].y;
+
+ if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+ B = FT_PIX_ROUND( B1 + B ) - B1;
+@@ -7627,7 +7632,7 @@
+ CUR_Func_move( &CUR.zp0, A, B );
+ }
+
+- B2 = CUR.zp0.cur[A].y;
++ B2 = (FT_UShort)CUR.zp0.cur[A].y;
+
+ /* Reverse this move if it results in a disallowed move */
+ if ( CUR.GS.freeVector.y != 0 &&
+@@ -7667,7 +7672,7 @@
+ Ins_DELTAC( INS_ARG )
+ {
+ FT_ULong nump, k;
+- FT_ULong A, C;
++ FT_ULong A, C, P;
+ FT_Long B;
+
+
+@@ -7691,6 +7696,7 @@
+ }
+ #endif
+
++ P = (FT_ULong)CUR_Func_cur_ppem();
+ nump = (FT_ULong)args[0];
+
+ for ( k = 1; k <= nump; k++ )
+@@ -7736,7 +7742,7 @@
+
+ C += CUR.GS.delta_base;
+
+- if ( CURRENT_Ppem() == (FT_Long)C )
++ if ( P == C )
+ {
+ B = ( (FT_ULong)B & 0xF ) - 8;
+ if ( B >= 0 )
+@@ -8269,11 +8275,12 @@
+ CUR.iup_called = FALSE;
+ #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+
+- /* set CVT functions */
++ /* set PPEM and CVT functions */
+ CUR.tt_metrics.ratio = 0;
+ if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
+ {
+ /* non-square pixels, use the stretched routines */
++ CUR.func_cur_ppem = Current_Ppem_Stretched;
+ CUR.func_read_cvt = Read_CVT_Stretched;
+ CUR.func_write_cvt = Write_CVT_Stretched;
+ CUR.func_move_cvt = Move_CVT_Stretched;
+@@ -8281,6 +8288,7 @@
+ else
+ {
+ /* square pixels, use normal routines */
++ CUR.func_cur_ppem = Current_Ppem;
+ CUR.func_read_cvt = Read_CVT;
+ CUR.func_write_cvt = Write_CVT;
+ CUR.func_move_cvt = Move_CVT;
+@@ -9035,10 +9043,13 @@
+ /* If any errors have occurred, function tables may be broken. */
+ /* Force a re-execution of `prep' and `fpgm' tables if no */
+ /* bytecode debugger is run. */
+- if ( CUR.error && !CUR.instruction_trap )
++ if ( CUR.error
++ && !CUR.instruction_trap
++ && CUR.curRange == tt_coderange_glyph )
+ {
+ FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
+- exc->size->cvt_ready = FALSE;
++ exc->size->bytecode_ready = -1;
++ exc->size->cvt_ready = -1;
+ }
+
+ return CUR.error;
+diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
+index 1d8825d..3cfc859 100644
+--- a/src/truetype/ttinterp.h
++++ b/src/truetype/ttinterp.h
+@@ -4,7 +4,7 @@
+ /* */
+ /* TrueType bytecode interpreter (specification). */
+ /* */
+-/* Copyright 1996-2007, 2010, 2012-2013 by */
++/* Copyright 1996-2007, 2010, 2012-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -81,6 +81,10 @@ FT_BEGIN_HEADER
+ (*TT_Project_Func)( EXEC_OP_ FT_Pos dx,
+ FT_Pos dy );
+
++ /* getting current ppem. Take care of non-square pixels if necessary */
++ typedef FT_Long
++ (*TT_Cur_Ppem_Func)( EXEC_OP );
++
+ /* reading a cvt value. Take care of non-square pixels if necessary */
+ typedef FT_F26Dot6
+ (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx );
+@@ -228,11 +232,6 @@ FT_BEGIN_HEADER
+ FT_F26Dot6 phase; /* `SuperRounding' */
+ FT_F26Dot6 threshold;
+
+-#if 0
+- /* this seems to be unused */
+- FT_Int cur_ppem; /* ppem along the current proj vector */
+-#endif
+-
+ FT_Bool instruction_trap; /* If `True', the interpreter will */
+ /* exit after each instruction */
+
+@@ -254,6 +253,8 @@ FT_BEGIN_HEADER
+ TT_Move_Func func_move; /* current point move function */
+ TT_Move_Func func_move_orig; /* move original position function */
+
++ TT_Cur_Ppem_Func func_cur_ppem; /* get current proj. ppem value */
++
+ TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */
+ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */
+ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */
+diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
+index 4adba58..05a121c 100644
+--- a/src/truetype/ttobjs.c
++++ b/src/truetype/ttobjs.c
+@@ -813,6 +813,8 @@
+ else
+ error = FT_Err_Ok;
+
++ size->bytecode_ready = error;
++
+ if ( !error )
+ TT_Save_Context( exec, size );
+
+@@ -884,6 +886,8 @@
+ else
+ error = FT_Err_Ok;
+
++ size->cvt_ready = error;
++
+ /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */
+ /* graphics state variables to be modified by the CVT program. */
+
+@@ -912,10 +916,6 @@
+ return error;
+ }
+
+-#endif /* TT_USE_BYTECODE_INTERPRETER */
+-
+-
+-#ifdef TT_USE_BYTECODE_INTERPRETER
+
+ static void
+ tt_size_done_bytecode( FT_Size ftsize )
+@@ -953,8 +953,8 @@
+ size->max_func = 0;
+ size->max_ins = 0;
+
+- size->bytecode_ready = 0;
+- size->cvt_ready = 0;
++ size->bytecode_ready = -1;
++ size->cvt_ready = -1;
+ }
+
+
+@@ -974,8 +974,8 @@
+ TT_MaxProfile* maxp = &face->max_profile;
+
+
+- size->bytecode_ready = 1;
+- size->cvt_ready = 0;
++ size->bytecode_ready = -1;
++ size->cvt_ready = -1;
+
+ size->max_function_defs = maxp->maxFunctionDefs;
+ size->max_instruction_defs = maxp->maxInstructionDefs;
+@@ -1052,15 +1052,14 @@
+ FT_Error error = FT_Err_Ok;
+
+
+- if ( !size->bytecode_ready )
+- {
++ if ( size->bytecode_ready < 0 )
+ error = tt_size_init_bytecode( (FT_Size)size, pedantic );
+- if ( error )
+- goto Exit;
+- }
++
++ if ( error || size->bytecode_ready )
++ goto Exit;
+
+ /* rescale CVT when needed */
+- if ( !size->cvt_ready )
++ if ( size->cvt_ready < 0 )
+ {
+ FT_UInt i;
+ TT_Face face = (TT_Face)size->root.face;
+@@ -1087,8 +1086,6 @@
+ size->GS = tt_default_graphics_state;
+
+ error = tt_size_run_prep( size, pedantic );
+- if ( !error )
+- size->cvt_ready = 1;
+ }
+
+ Exit:
+@@ -1119,8 +1116,8 @@
+ FT_Error error = FT_Err_Ok;
+
+ #ifdef TT_USE_BYTECODE_INTERPRETER
+- size->bytecode_ready = 0;
+- size->cvt_ready = 0;
++ size->bytecode_ready = -1;
++ size->cvt_ready = -1;
+ #endif
+
+ size->ttmetrics.valid = FALSE;
+@@ -1148,7 +1145,7 @@
+
+
+ #ifdef TT_USE_BYTECODE_INTERPRETER
+- if ( size->bytecode_ready )
++ if ( size->bytecode_ready >= 0 )
+ tt_size_done_bytecode( ttsize );
+ #endif
+
+@@ -1229,7 +1226,7 @@
+ }
+
+ #ifdef TT_USE_BYTECODE_INTERPRETER
+- size->cvt_ready = 0;
++ size->cvt_ready = -1;
+ #endif /* TT_USE_BYTECODE_INTERPRETER */
+
+ if ( !error )
+diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
+index a11dd37..47d50d9 100644
+--- a/src/truetype/ttobjs.h
++++ b/src/truetype/ttobjs.h
+@@ -4,7 +4,7 @@
+ /* */
+ /* Objects manager (specification). */
+ /* */
+-/* Copyright 1996-2009, 2011-2013 by */
++/* Copyright 1996-2009, 2011-2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -333,8 +333,10 @@ FT_BEGIN_HEADER
+ FT_Bool debug;
+ TT_ExecContext context;
+
+- FT_Bool bytecode_ready;
+- FT_Bool cvt_ready;
++ /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */
++ /* otherwise it is the returned error code */
++ FT_Error bytecode_ready;
++ FT_Error cvt_ready;
+
+ #endif /* TT_USE_BYTECODE_INTERPRETER */
+
+diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
+index 28470ad..9871994 100644
+--- a/src/truetype/ttsubpix.c
++++ b/src/truetype/ttsubpix.c
+@@ -956,7 +956,7 @@
+ if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 )
+ {
+ loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
+- loader->exec->size->cvt_ready = FALSE;
++ loader->exec->size->cvt_ready = -1;
+
+ tt_size_ready_bytecode(
+ loader->exec->size,
+@@ -971,7 +971,7 @@
+ SPH_OPTION_SET_RASTERIZER_VERSION )
+ {
+ loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
+- loader->exec->size->cvt_ready = FALSE;
++ loader->exec->size->cvt_ready = -1;
+
+ tt_size_ready_bytecode(
+ loader->exec->size,
+diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
+index 697288d..2602bdb 100644
+--- a/src/type1/t1driver.c
++++ b/src/type1/t1driver.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* Type 1 driver interface (body). */
+ /* */
+-/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 by */
++/* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013, 2014 by */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -557,9 +557,6 @@
+ if ( value && value_len >= retval )
+ *((FT_Long *)value) = type1->font_info.italic_angle;
+ break;
+-
+- default:
+- break;
+ }
+
+ return retval;