Update FreeType to 2.8.1 + 107 CLs
Update FreeType to 94f6d57a (107 CLs past 2.8.1) to match FreeType
bundled with Chrome on other platforms.
A subset of what's new:
- Faster bitmap emoji font loading
- Better variable font support including bug fixes
- New LCD rendering called Harmony (not yet enabled).
In addition, disable unused modules (bdf,pcf,pcr,winfonts,lzw)
to save about 52 KiB and reduce potential risks associated with them.
BUG=None
TEST=emerge-${BOARD} freetype
TEST=cros tryjob -g 758744 chromiumos-sdk amd64-generic-full daisy-full
Change-Id: I056ff78cca872330b0fc2b1d80d03603b36ca877
Reviewed-on: https://chromium-review.googlesource.com/758744
Commit-Ready: Jungshik Shin <jshin@chromium.org>
Tested-by: Jungshik Shin <jshin@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/media-libs/freetype/Manifest b/media-libs/freetype/Manifest
index c7d39804..40fbff3 100644
--- a/media-libs/freetype/Manifest
+++ b/media-libs/freetype/Manifest
@@ -1 +1,3 @@
-DIST freetype-2.8.tar.bz2 1873526 SHA256 a3c603ed84c3c2495f9c9331fe6bba3bb0ee65e06ec331e0a0fb52158291b40b SHA512 3842c34bf6100a8c9b78258146b2ff35e9bb4c993937d3ef09982c1e2552dfd15f8849ddd8a1e84edf08b5a5fb918b68cf7b1584545c5900e22a00bfa1c89ff5 WHIRLPOOL 2fb845ede217b228c39e1e767ea5b21868bd3b02521ca48fe614d78f790c9dab5145cc6feb147725e8e44cd3aa716a14742ef4893b2f54e5b167efe9f4905386
+DIST freetype-2.8.1.tar.bz2 1886443 SHA256 e5435f02e02d2b87bb8e4efdcaa14b1f78c9cf3ab1ed80f94b6382fb6acc7d78 SHA512 ca59e47f0fceeeb9b8032be2671072604d0c79094675df24187829c05e99757d0a48a0f8062d4d688e056f783aa8f6090d732ad116562e94784fccf1339eb823 WHIRLPOOL 4827e36cccf23323be8e5e55edd6692503747e90ff3764a497571c06338c711c0d2071ab06766ccb803152e4b00df4cefbee2768ad3660fbf6430f3622620893
+DIST freetype-doc-2.8.1.tar.bz2 2128376 SHA256 e6251ab44adcb075c7ca4205163c43b6539cbe5265b8a24ec0afa07f8b9213f3 SHA512 386f3e2f123e60e697eb446d667bdcdf184d354a7a9a7bcc42767ea7964cd5a89e5ef42a234838c03e7ce926d3e92d763acb84983afdaf9f6977c028d55f2806 WHIRLPOOL 3197ea90412e32b5086b1f1d1ba80a069e73e021a1289423509ea36e0b13431be28af12666c619b498f5e50e07854e97cdf15383433a7ea0a1211470bca7dd1c
+DIST ft2demos-2.8.1.tar.bz2 228934 SHA256 7e385c34fc91978e4db976cbb9e1cdc4d1ce611046f2a21ceb0737e9a60cefd9 SHA512 f3a3216448df7b9bebb875a69587f31d0548f4b7e1b1bd70b0f06b3c4a43b3f5ca99ac2fcfecb32909b16b32a466fff24d1a6407e5fd6c2145fd64d2a156429a WHIRLPOOL adc29f9e0dce4e897f450b06800dd6a36ba1a64a53972bb15d5bb10e4551334b0267006b257cbde909462c8c00444e8a8e7335e95092add1c90f786fd1b1baf7
diff --git a/media-libs/freetype/files/freetype-2.8.1-94f6d57a4.patch b/media-libs/freetype/files/freetype-2.8.1-94f6d57a4.patch
new file mode 100644
index 0000000..5bfc2f0
--- /dev/null
+++ b/media-libs/freetype/files/freetype-2.8.1-94f6d57a4.patch
@@ -0,0 +1,21489 @@
+Changes between 2.8.1 and 94f6d57a4
+
+This is to match the version of FreeType on other platforms.
+
+diff --git a/ChangeLog.27 b/ChangeLog.27
+new file mode 100644
+index 0000000000..e61d55135e
+--- /dev/null
++++ b/ChangeLog.27
+@@ -0,0 +1,2106 @@
++2016-12-30 Werner Lemberg <wl@gnu.org>
++
++ * Version 2.7.1 released.
++ =========================
++
++
++ Tag sources with `VER-2-7-1'.
++
++ * docs/VERSION.TXT: Add entry for version 2.7.1.
++
++ * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj,
++ builds/windows/vc2005/index.html,
++ builds/windows/vc2008/freetype.vcproj,
++ builds/windows/vc2008/index.html,
++ builds/windows/vc2010/freetype.vcxproj,
++ builds/windows/vc2010/index.html,
++ builds/windows/visualc/freetype.dsp,
++ builds/windows/visualc/freetype.vcproj,
++ builds/windows/visualc/index.html,
++ builds/windows/visualce/freetype.dsp,
++ builds/windows/visualce/freetype.vcproj,
++ builds/windows/visualce/index.html,
++ builds/wince/vc2005-ce/freetype.vcproj,
++ builds/wince/vc2005-ce/index.html,
++ builds/wince/vc2008-ce/freetype.vcproj,
++ builds/wince/vc2008-ce/index.html: s/2.7/2.7.1/, s/27/271/.
++
++ * include/freetype/freetype.h (FREETYPE_PATCH): Set to 1.
++
++ * builds/unix/configure.raw (version_info): Set to 19:0:13.
++ * CMakeLists.txt (VERSION_PATCH): Set to 1.
++
++2016-12-30 Werner Lemberg <wl@gnu.org>
++
++ [ftfuzzer] Replace `rand' with an xorshift algorithm.
++
++ * src/tools/ftfuzzer/ftfuzzer.cc: Don't include `stdlib.h'.
++ (Random): Implement and use a 32bit `xorshift' algorithm.
++
++2016-12-30 Werner Lemberg <wl@gnu.org>
++
++ [ftfuzzer] Restrict number of tested bitmap strikes.
++
++ Malformed fonts often have large values for the number of bitmap
++ strikes, and FreeType doesn't check the validity of all bitmap
++ strikes in advance.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=353
++
++ * src/tools/ftfuzzer/ftfuzzer.cc: Include `stdlib.h' for `rand'.
++ (Random): Small class to provide n randomly selected numbers
++ (without repetition) out of the value set [1,N].
++ (LLVMFuzzerTestOneInput): Use it to test only up to 10 bitmap
++ strikes.
++
++2016-12-29 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Variation font API stability issues.
++
++ Make some functions work before a call to `TT_Set_MM_Blend'.
++
++ * src/truetype/ttgxvar.c (tt_hadvance_adjust): Exit immediately if
++ we don't blend.
++ (TT_Get_MM_Blend, TT_Get_Var_Design): Return default values if we
++ don't blend.
++
++2016-12-29 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttgxvar.c (TT_Get_MM_Var): Check axis data.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=348
++
++2016-12-29 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Tracing fixes.
++
++ * src/truetype/ttgxvar.c (tt_hadvance_adjust): Emit correct
++ information.
++ (TT_Set_Var_Design): Fix typo.
++ (TT_Get_Var_Design): Fix typos.
++
++2016-12-29 Werner Lemberg <wl@gnu.org>
++
++ */*: Use `0.5f' for tracing 16.16 numbers.
++
++2016-12-29 Werner Lemberg <wl@gnu.org>
++
++ [pcf] Protect against gzip bombs.
++
++ Fix suggested by Kostya; reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=345
++
++ * src/pcf/pcfread.c (pcf_read_TOC): Limit number of TOC entries to
++ 1024.
++
++2016-12-28 Werner Lemberg <wl@gnu.org>
++
++ [psnames] Only declare, not define, data in `pstables.h' (#49949).
++
++ Pdfium includes `pstables.h' a second time; moving the definition
++ from `pstables.h' to `psmodule.c' saves more than 60kByte data
++ segment space for this case.
++
++ * src/tools/glnames.py (StringTable::dump,
++ StringTable::dump_sublist, dump_encoding, dump_array): Emit
++ additional code to only define tables if `DEFINE_PS_TABLES' is set.
++
++ * src/psnames/pstables.h: Regenerated.
++ * src/psnames/psmodule.c (DEFINE_PS_TABLES): Define.
++
++2016-12-28 Werner Lemberg <wl@gnu.org>
++
++ [cff] Catch `blend' op in non-variant fonts.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=334
++
++ * src/cff/cf2intrp.c (cf2_interpT2CharString) <cf2_cmdBLEND>: Don't
++ allow `blend' op for non-variant fonts.
++
++2016-12-28 Werner Lemberg <wl@gnu.org>
++
++ [cff] Better check of number of blends.
++
++ * src/cff/cf2intrp.c (cf2_interpT2CharString) <cf2_cmdBLEND>,
++ src/cff/cffparse.c (cff_parse_blend): Compare number of blends with
++ stack size.
++
++2016-12-27 Werner Lemberg <wl@gnu.org>
++
++ Documentation updates.
++
++ * docs/CHANGES: Add missing information.
++
++ * docs/formats.txt: Rewritten and updated.
++
++2016-12-27 Werner Lemberg <wl@gnu.org>
++
++ [truetype, type1] Implement `FT_Get_Var_Design_Coordinates'.
++
++ * src/truetype/ttgxvar.c (TT_Get_Var_Design): Implement.
++ (TT_Set_Var_Design): Fix tracing.
++
++ * src/type1/t1load.c (T1_Get_Var_Design): Implement.
++
++2016-12-24 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttpload.c (tt_face_load_hdmx): Ignore `version'.
++
++ Problem reported by å¼µä¿è <418092625@qq.com>.
++
++2016-12-24 Werner Lemberg <wl@gnu.org>
++
++ * src/sfnt/ttsbit.c (tt_face_load_sbit): Allow more version values.
++
++ Some fonts seem to have the `version' field in the wrong byte order.
++
++ Problem reported by å¼µä¿è <418092625@qq.com>.
++
++2016-12-24 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttpload.c (tt_face_load_loca): Sanitize table length.
++
++ This trivial fix allows us to accept more fonts.
++
++ Problem reported by å¼µä¿è <418092625@qq.com>.
++
++2016-12-24 Werner Lemberg <wl@gnu.org>
++
++ * src/sfnt/sfobjs.c (sfnt_init_face): Fix tracing.
++
++2016-12-22 Werner Lemberg <wl@gnu.org>
++
++ * CMakeLists.txt: Make it work with cmake 2.8.11.2 (#49909).
++
++2016-12-22 Werner Lemberg <wl@gnu.org>
++
++ Ensure used preprocessor symbols are defined (#49790).
++
++ * builds/unix/ftconfig.in, builds/vms/ftconfig.h,
++ include/freetype/config/ftconfig.h: Check `__GNUC__', `__IBMC__',
++ and `__SUNPRO_C' correctly.
++
++2016-12-22 Werner Lemberg <wl@gnu.org>
++
++ * src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Check `count'.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=308
++
++2016-12-22 Werner Lemberg <wl@gnu.org>
++
++ [cff] Protect against invalid `vsindex' and `blend' values.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=305
++
++ * src/cff/cf2intrp.c (cf2_interpT2CharString) <cf2_cmdVSINDEX,
++ cf2_cmdBLEND>: Implement it.
++
++2016-12-22 Werner Lemberg <wl@gnu.org>
++
++ [ftfuzzer] Always use Adobe CFF engine.
++
++ * src/tools/ftfuzzer/ftfuzzer.cc (FT_Global::FT_Global): Implement
++ it.
++
++2016-12-21 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Thinko.
++
++ I should really stop coding late in the evening...
++
++ Thanks again to Ben for checking.
++
++2016-12-21 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Support variation fonts.
++
++ (This ChangeLog entry was added later on.)
++
++ * src/autofit/afglobal.c (af_face_globals_free): Remove useless
++ code.
++
++ * src/base/ftmm.c (FT_Set_MM_Design_Coordinates,
++ * FT_Set_Var_Design_Coordinates, FT_Set_MM_Blend_Coordinates,
++ FT_Set_Var_Blend_Coordinates): Finalize
++ auto-hinter data to enforce recomputation. Note that this is a
++ brute-force method which should be improved.
++
++2016-12-21 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Thinko.
++
++ Don't apply deltas twice for non-phantom points.
++
++ Spotted by Ben Wagner.
++
++2016-12-21 Werner Lemberg <wl@gnu.org>
++
++ [cff, truetype] Another try for #49829.
++
++ * src/cff/cffdrivr.c: Don't include
++ `FT_SERVICE_METRICS_VARIATIONS_H'.
++ (cff_get_advances): Use `ttface->variation_support'.
++
++ * src/truetype/ttdriver.c (tt_get_advances): Use
++ `ttface->variation_support'.
++
++ * src/truetype/ttgload.c (TT_Process_Simple_Glyph,
++ load_truetype_glyph): Use `ttface->variation_support'.
++
++2016-12-21 Werner Lemberg <wl@gnu.org>
++
++ [truetype, sfnt] Introduce font variation flags to `TT_Face'.
++
++ * include/freetype/internal/tttypes.h (TT_FACE_FLAG_VAR_XXX):
++ New macros describing available functionality of various OpenType
++ tables related to font variation.
++ (TT_Face): New fields `variation_support' and `mvar_support',
++ replacing and extending `use_fvar'.
++
++ * src/sfnt/sfobjs.c (sfnt_init_face, sfnt_load_face): Use
++ `variation_support'.
++
++ * src/truetype/ttgxvar.c (ft_var_load_hvar): Set `variation_support'
++ field.
++ (TT_Vary_Apply_Glyph_Deltas): Updated.
++
++2016-12-21 Werner Lemberg <wl@gnu.org>
++
++ [base] Improve sanity check for Mac resources (#49888).
++
++ * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Abort if `rlen' is not
++ positive.
++
++2016-12-20 Werner Lemberg <wl@gnu.org>
++
++ [base] More sanity checks for Mac resources.
++
++ We use
++
++ https://github.com/kreativekorp/ksfl/wiki/Macintosh-Resource-File-Format
++
++ and
++
++ https://developer.apple.com/legacy/library/documentation/mac/pdf/MoreMacintoshToolbox.pdf#page=151
++
++ as references.
++
++ * include/freetype/internal/ftrfork.h (FT_RFork_Ref): Use FT_Short
++ for `res_id'.
++
++ * src/base/ftrfork.c (FT_Raccess_Get_HeaderInfo): Extract map length
++ and use it to improve sanity checks.
++ Follow the specification more closely;in particular, all data types
++ are signed, not unsigned.
++ (FT_Raccess_Get_DataOffsets): Follow the specification more closely;
++ in particular, all data types are signed, not unsigned.
++ Add some sanity checks.
++
++2016-12-20 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Improve logic for getting fast advance widths.
++
++ * src/cff/cffdrivr.c (cff_get_advances), src/truetype/ttdriver.c
++ (tt_get_advances): Use `is_default_instance' for test; this gets
++ recomputed after changing blend coordinates.
++
++2016-12-20 Ben Wagner <bungeman@google.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix linear metrics of GX variation fonts (#49829).
++
++ When asking for an unhinted non-default variations,
++ `linearVertAdvance' is currently the value from the `hmtx' table
++ instead of the actual value after applying the variation. `HVAR'
++ support fixes this, but fonts will exist without that table and will
++ need sane fallback.
++
++ Problem also reported as
++
++ https://bugs.chromium.org/p/skia/issues/detail?id=5917
++
++ * src/truetype/ttgload.c (TT_Process_Simple_Glyph,
++ load_truetype_glyph): Implement linear advance adjustments if `HVAR'
++ or `VVAR' tables are missing.
++
++2016-12-20 Werner Lemberg <wl@gnu.org>
++
++ [cff, truetype] Fast advance width retrieval for fonts with HVAR.
++
++ Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++
++ * src/base/ftadvanc.c (LOAD_ADVANCE_FAST_CHECK): Don't handle MM.
++
++ * src/cff/cffdrivr.c: Include FT_SERVICE_METRICS_VARIATIONS_H.
++ (cff_get_advances): Test for HVAR and VVAR.
++
++ * src/truetype/ttdriver.c (tt_get_advances): Test for HVAR and VVAR.
++
++2016-12-18 Werner Lemberg <wl@gnu.org>
++
++ [base] Fix invalid mac font recursion.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=304
++
++ * src/base/ftobjs.c (FT_Open_Face): Code moved to...
++ (ft_open_face_internal): ... this function.
++ Add a parameter to control whether we try special Mac font handling
++ in case of failure.
++ (FT_Open_Face, FT_New_Face, FT_New_Memory_Face,
++ open_face_from_buffer): Use `ft_open_face_internal'.
++
++2016-12-18 Werner Lemberg <wl@gnu.org>
++
++ * src/cff/cffobjs.c (cff_face_init): Make named instances work.
++
++2016-12-18 Werner Lemberg <wl@gnu.org>
++
++ [truetype, cff] Extend `get_var_blend' function of MM service.
++
++ In particular, we need access to named instance data.
++
++ * include/freetype/internal/services/svmm.h (FT_Get_Var_Blend_Func):
++ Add argument for `FT_MM_Var'.
++
++ * src/cff/cffload.c (cff_get_var_blend): Updated.
++ * src/cff/cffload.h: Updated.
++
++ * src/cff/cf2ft.c (cf2_getNormalizedVector): Updated.
++
++ * src/truetype/ttgxvar.c (tt_get_var_blend): Updated.
++ Accept value `NULL' for arguments.
++ * src/truetype/ttgxvar.h: Updated.
++
++2016-12-18 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Handle `fvar' with zero axes as a non-MM font.
++
++ This is better behaviour than exiting with an error.
++
++ * include/freetype/internal/tttypes.h (TT_Face): Add `use_fvar'
++ field.
++
++ * src/sfnt/sfobjs.c (sfnt_init_face): Compute `use_fvar', also
++ updating the validation code.
++ Use `use_fvar' to compute FT_FACE_FLAG_MULTIPLE_MASTERS.
++
++ * src/truetype/ttgxvar.c (TT_Get_MM_Var): Remove `fvar' validation
++ code.
++
++2016-12-18 Werner Lemberg <wl@gnu.org>
++
++ Minor GX code shuffling.
++
++ * include/freetype/internal/tttypes.h (TT_Face): Move
++ `is_default_instance' into TT_CONFIG_OPTION_GX_VAR_SUPPORT
++ block.
++
++ * src/sfnt/sfobjs.c (sfnt_init_face): Updated.
++ * src/truetype/ttgload.c (IS_DEFAULT_INSTANCE): New macro.
++ (TT_Load_Glyph): Use it.
++
++2016-12-18 Werner Lemberg <wl@gnu.org>
++
++ [cff] Better handling of non-CFF font formats.
++
++ * src/cff/cffload.c (cff_font_load): Pure CFFs don't have a
++ signature, so return `FT_Err_Unknown_File_Format' more often.
++
++2016-12-17 Werner Lemberg <wl@gnu.org>
++
++ * src/cff/cffload.c (cff_build_blend_vector): Remove redundant code.
++
++2016-12-17 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttobjs.c (tt_face_init): Simplify conditional code.
++
++2016-12-17 Werner Lemberg <wl@gnu.org>
++
++ [sfnt, truetype] Various sanitizing fixes.
++
++ * src/sfnt/sfobjs.c (sfnt_init_face): If the axis count in `fvar' is
++ zero, set `num_instances' to zero.
++
++ * src/truetype/ttgxvar.c (TT_Get_MM_Var): Handle `fvar' table with
++ zero axes as invalid.
++
++ * src/truetype/ttobjs.c (tt_face_init): Improve logic of loading
++ `loca', `cvt', `fpgm', and `prep' table.
++
++2016-12-17 Werner Lemberg <wl@gnu.org>
++
++ Improve tracing of `FT_Open_Face'.
++
++ * src/base/ftobjs.c (FT_Open_Face): Return info on number of
++ available faces and numbered instances, or the indices of the
++ requested face and numbered instance.
++
++ * src/sfnt/sfobjs. (sfnt_open_font): Trace number of subfonts.
++
++2016-12-17 Werner Lemberg <wl@gnu.org>
++
++ * src/cff/cffload.c (cff_load_private_dict): Always init `blend'.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=295
++
++2016-12-16 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix `cvar' sanity test.
++
++ Reported by Dave Arnold.
++
++ * src/truetype/ttgxvar.c (tt_face_vary_cvt): Use tuple count mask.
++
++2016-12-16 Werner Lemberg <wl@gnu.org>
++
++ [cff, truetype] Remove compiler warnings; fix `make multi'.
++
++ * src/cff/cf2font.h: Include `cffload.h'.
++
++ * src/cff/cffload.c: Include FT_MULTIPLE_MASTERS_H and
++ FT_SERVICE_MULTIPLE_MASTERS_H.
++ (cff_vstore_load): Eliminate `vsSize'.
++ (cff_load_private_dict): Tag as `FT_LOCAL_DEF'.
++
++ * src/cff/cffload.h: Include `cffobjs.h'.
++ Provide declaration for `cff_load_private_dict'.
++
++ * src/truetype/ttgxvar.c (ft_var_load_hvar): Eliminate
++ `minorVersion' and `map_offset'.
++
++2016-12-16 Werner Lemberg <wl@gnu.org>
++
++ [cff] Fix heap buffer overflow (#49858).
++
++ * src/cff/cffparse.c (cff_parser_run): Add one more stack size
++ check.
++
++2016-12-15 Werner Lemberg <wl@gnu.org>
++
++ Fix clang warnings.
++
++ * src/cff/cffload.c (cff_blend_doBlend): Add cast.
++ (cff_subfont_load): Set `error' correctly.
++
++ * src/sfnt/ttmtx.c (tt_face_get_metrics): Typo.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [cff] Implement CFF2 support (2/2).
++
++ The font variation code. All parts dependent on the GX code in the
++ `truetype' module are guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++ In other words, you can still compile the `cff' module without
++ defining TT_CONFIG_OPTION_GX_VAR_SUPPORT (which brings you CFF2
++ support without font variation).
++
++ * src/cff/cf2font.c (cf2_font_setup): Add support for font
++ variation.
++ * src/cff/cf2font.h (CF2_Font): Add fields for variation data.
++
++ * src/cff/cf2ft.c (cf2_free_instance): Free blend data.
++ (cf2_getVStore, cf2_getNormalizedVector): New functions.
++ * src/cff/cf2ft.h: Updated.
++
++ * src/cff/cf2intrp.c: Include `cffload.h'.
++ (cf2_cmdRESERVED_15, cf2_cmdRESERVED_16): Replace with...
++ (cf2_cmdVSINDEX, cf2_cmdBLEND): ... this new enum values.
++ (cf2_doBlend): New function.
++ (cf2_interpT2CharString): Handle `vsindex' and `blend' opcodes.
++
++ * src/cff/cffload.c (FT_fdot14ToFixed): New macro.
++ (cff_vstore_done, cff_vstore_load): New functions.
++ (cff_blend_clear, cff_blend_doBlend, cff_blend_build_vector,
++ cff_blend_check_vector): New functions.
++ (cff_load_private_dict): Add arguments for blend vector.
++ Handle blend data.
++ (cff_subfont_load, cff_subfont_done): Updated.
++ (cff_font_load): Handle CFF2 variation store data.
++ (cff_font_done): Updated.
++ * src/cff/cffload.h: Include `cffparse.h'.
++ Updated.
++
++ * src/cff/cffobjs.c (cff_face_done): Updated.
++
++ * src/cff/cffparse.c: Include `cffload.h'.
++ (cff_parse_num): Handle internal value 255.
++ (cff_parse_vsindex, cff_parse_blend): New functions.
++ (CFF_FIELD_BLEND): New macro.
++ (cff_parser_run): Updated.
++ * src/cff/cffparse.h (cff_kind_blend): New enum value.
++
++ * src/cff/cfftoken.h: Handle `vstore', `vsindex', and `blend'
++ dictionary values.
++
++ * src/cff/cfftypes.h (CFF_VarData, CFF_AxisCoords, CFF_VarRegion,
++ CFF_VStore, CFF_Blend): New structures.
++ (CFF_FontRecDict): Add `vstore_offset' field.
++ (CFF_Private): Add `vsindex' field.
++ (CFF_SubFont): Add fields for blend data.
++ (CFF_Font): Add `vstore' field.
++
++ * src/truetype/ttgxvar.c (TT_Get_MM_Var): `CFF2' is equal to `gvar',
++ since glyph variation data is directly embedded.
++ (TT_Set_MM_Blend): Don't load `gvar' table for CFF2 fonts.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [cff] Implement CFF2 support (1/2).
++
++ This commit does not contain the blend code for font variation
++ support, which follows in another commit.
++
++ You should ignore whitespace while inspecting this commit.
++
++ * include/freetype/internal/tttypes.h (TT_Face): Add `isCFF2'
++ member.
++
++ * src/cff/cf2font.h (CF2_Font): Add `isCFF2' member.
++
++ * src/cff/cf2ft.c (cf2_decoder_parse_charstrings): Handle `isCFF2'
++ flag.
++ (cf2_getMaxstack): New function.
++ * src/cff/cf2ft.h: Updated.
++
++ * src/cff/cf2intrp.c (cf2_escRESERVED_38): New enum.
++ (cf2_interpT2CharString): Handle CFF2 differences.
++ Add tracing message for errors.
++
++ * src/cff/cffdrivr.c (cff_get_glyph_name, cff_get_name_index):
++ Update for CFF2.
++
++ * src/cff/cffload.c (FT_FIXED_ONE): New macro.
++ (cff_index_init, cff_index_load_offsets, cff_index_access_element,
++ cff_index_get_name, cff_ft_select_get, cff_load_private_dict,
++ cff_subfont_load, cff_font_load): Handle CFF2.
++ * src/cff/cffload.h: Updated.
++
++ * src/cff/cffobjs.c (cff_face_init): Handle CFF2.
++
++ * src/cff/cffparse.c (cff_parse_maxstack): New function.
++ (CFFCODE_TOPDICT, CFFCODE_PRIVATE): Removed
++ * src/cff/cffparse.h (CFF2_MAX_STACK, CFF2_DEFAULT_STACK): New
++ macros.
++ (CFF2_CODE_TOPDICT, CFF2_CODE_FONTDICT, CFF2_CODE_PRIVATE): New
++ macros.
++
++ * src/cff/cfftoken.h: Add fields for CFF2 dictionaries (but no blend
++ stuff).
++
++ * src/cff/cfftypes.h (CFF_Index): Add `hdr_size' field.
++ (CFF_FontRecDict): Add `maxstack' field.
++ (CFF_Private): Add `subfont' field.
++ (CFF_Font): Add `top_dict_length' and `cff2' fields.
++
++ * src/sfnt/sfobjs.c (sfnt_load_face): Handle `CFF2' table.
++
++2016-12-15 Werner Lemberg <wl@gnu.org>
++ Dave Arnold <darnold@adobe.com>
++
++ [truetype] Provide HVAR advance width variation as a service.
++
++ Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++
++ * src/truetype/ttdriver.c (tt_service_metrics_variations): Updated.
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Prevent
++ double adjustment of advance width.
++
++ * src/sfnt/ttmtx.c: Include FT_SERVICE_METRICS_VARIATIONS_H.
++ (tt_face_get_metrics): Apply metrics variations.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [truetype] Provide function to apply `HVAR' advance width variation.
++
++ Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++
++ * src/truetype/ttgxvar.c (tt_hadvance_adjust): New function.
++ * src/truetype/ttgxvar.h: Updated.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [truetype] Add `HVAR' table parsing.
++
++ Note that this is not complete yet; it only handles advance width
++ variation.
++
++ Activation of the code follows in another commit.
++
++ Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++
++ * include/freetype/ftmm.h (FT_Var_Named_Style): Add `psid' member.
++
++ * src/truetype/ttgxvar.h (GX_HVarData, GX_AxisCoords, GX_HVarRegion,
++ GX_HVStore, GX_WidthMap): New auxiliary structures for...
++ (GX_HVarTable): ... HVAR main structure.
++ (GX_BlendRec): Add data for HVAR loading.
++
++ * src/truetype/ttgxvar.c (FT_FIXED_ONE, FT_fdot14ToFixed,
++ FT_intToFixed, FT_fixedToInt): New macros.
++ (ft_var_load_hvar): New function.
++ (TT_Get_MM_Var): Updated.
++ (tt_done_blend): Deallocate HVAR data.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++
++ [cff] Extend number parsing.
++
++ The forthcoming CFF2 support needs a dynamic parsing limit.
++
++ * src/cff/cffparse.c (cff_parse_num, do_fixed, cff_parse_fixed,
++ cff_parse_fixed_scaled, cff_parse_fixed_dynamic): Add argument for
++ parser.
++ (cff_parse_font_matrix, cff_parse_font_bbox, cff_parse_private_dict,
++ cff_parse_multiple_master, cff_parse_cid_ros, cff_parser_run): Updated.
++
++ * src/cff/cffparse.h (cff_parse_num): Export locally.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++
++ [cff] Implement dynamic stack size for Adobe engine.
++
++ This also adds `cf2_stack_setReal' and `cf2_stack_pop', needed for
++ the forthcoming CFF2 support.
++
++ * src/cff/cf2stack.c (cf2_stack_init): Add argument for stack size.
++ (cf2_stack_free): Deallocate stack.
++ (cf2_stack_count, cf2_stack_pushInt, cf2_stack_pushFixed,
++ cf2_stack_popInt, cf2_stack_popFixed, cf2_stack_getReal,
++ cf2_stack_clear): Updated.
++ (cf2_stack_setReal, cf2_stack_pop): New functions.
++
++ * src/cff/cf2stack.h (CF2_Stack): Add `stackSize' member.
++ Update function declarations.
++
++ * src/cff/cf2intrp.c (cf2_interpT2CharString): Updated.
++
++ * src/cff/cffparse.c (cff_parser_init): Add parameter for stack
++ size; return error code.
++ (cff_parser_done): New function.
++ (cff_parser_run): Updated.
++
++ * src/cff/cffparse.h (CFF_Parser): Add `stackSize' member and make
++ `stack' a pointer.
++ Update function declarations.
++
++ * src/cff/cffload.c (cff_load_private_dict, cff_subfont_load):
++ Updated.
++
++2016-12-15 Dave Arnold <darnold@adobe.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [cff] Code shuffling.
++
++ * src/cff/cfftypes.h (CFF_Font): Add `library' and `base_offset'
++ fields.
++
++ * src/cff/cffload.c (cff_subfont_load): Change last argument to
++ `CFF_Font'
++ Split off parsing of private dictionary into...
++ (cff_load_private_dict): ...this new function.
++ (cff_font_load): Updated.
++
++2016-12-14 Werner Lemberg <wl@gnu.org>
++
++ [sfnt, truetype] Add framework for Metrics Variations service.
++
++ No effect yet; service functions will be implemented later on.
++
++ Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++
++ * include/freetype/internal/services/svmetric.h: New file.
++
++ * include/freetype/internal/ftserv.h
++ (FT_SERVICE_METRICS_VARIATIONS_H): New macro.
++
++ * include/freetype/internal/tttypes.h (TT_Face): New field `var'.
++
++ * src/sfnt/sfobjs.c: Include FT_SERVICE_METRICS_VARIATIONS_H.
++ (sfnt_init_face): Initialize `face->var'.
++
++ * src/truetype/ttdriver.c: Include FT_SERVICE_METRICS_VARIATIONS_H.
++ (tt_service_metrics_variations): New service.
++ (tt_services): Updated.
++
++ * src/truetype/ttpic.h: Updated.
++
++2016-12-14 Werner Lemberg <wl@gnu.org>
++
++ [cff] Add Multiple Masters service.
++
++ The code simply uses the MM functions from the `truetype' module.
++
++ Everything is guarded with TT_CONFIG_OPTION_GX_VAR_SUPPORT.
++
++ * include/freetype/internal/tttypes.h (TT_Face): New field `mm'.
++
++ * src/cff/cffdrivr.c: Include FT_SERVICE_MULTIPLE_MASTERS_H.
++ (cff_set_mm_blend, cff_get_mm_blend, cff_get_mm_var,
++ cff_set_var_design, cff_get_var_design): New functions.
++ (cff_service_multi_masters): New service.
++ (cff_services): Updated.
++
++ * src/cff/cffload.c (cff_get_var_blend, cff_done_blend): New
++ functions.
++ * src/cff/cffload.h: Updated.
++
++ * src/cff/cffpic.h (CFF_SERVICE_MULTI_MASTERS_GET): New macro.
++
++ * src/sfnt/sfobjs.c: Include FT_SERVICE_MULTIPLE_MASTERS_H.
++ (sfnt_init_face): Initialize `face->mm'.
++
++2016-12-14 Werner Lemberg <wl@gnu.org>
++
++ Extend functionality of `ft_module_get_service'.
++
++ It can now differentiate between local and global searches.
++
++ * src/base/ftobjs.c (ft_module_get_service): Add `global' argument.
++ (FT_Get_TrueType_Engine_Type): Updated.
++
++ * src/cff/cffdrivr.c (cff_get_ps_name, cff_get_cmap_info): Updated.
++
++ * include/freetype/internal/ftobjs.h: Updated.
++ * include/freetype/internal/ftserv.h (FT_FACE_FIND_GLOBAL_SERVICE):
++ Updated.
++
++2016-12-14 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttgxvar.c (tt_get_var_blend): Fix compiler warning.
++
++2016-12-14 Dave Arnold <darnold@adobe.com>
++ Werner Lemberg <wl@gnu.org>
++
++ [sfnt, cff] Minor preparations.
++
++ * include/freetype/tttags.h (TTAG_CFF2, TTAG_HVAR, TTAG_MVAR,
++ TTAG_VVAR): New SFNT table tags.
++
++ * src/cff/cf2fixed.h (CF2_FIXED_ONE, CF2_FIXED_EPSILON): Add cast.
++
++2016-12-10 Werner Lemberg <wl@gnu.org>
++
++ [truetype, type1] Add `get_var_blend' to MM service.
++
++ For internal use; we want to share code between the forthcoming CFF2
++ support and TrueType.
++
++ * include/freetype/internal/services/svmm.h (FT_Get_Var_Blend_Func):
++ New typedef.
++ (MultiMasters): Add `get_var_blend'.
++ (FT_Service_MultiMasters): Updated.
++
++ * src/truetype/ttgxvar.c (tt_get_var_blend): New function.
++ * src/truetype/ttgxvar.h: Updated.
++
++ * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated.
++ * src/type1/t1driver.c (t1_service_multi_masters): Updated.
++
++2016-12-10 Werner Lemberg <wl@gnu.org>
++
++ [truetype, type1] Add `done_blend' to MM service.
++
++ For internal use; we want to share code between the forthcoming CFF2
++ support and TrueType.
++
++ * include/freetype/internal/services/svmm.h (FT_Done_Blend_Func):
++ New typedef.
++ (MultiMasters): Add `done_blend'.
++ (FT_Service_MultiMasters): Updated.
++
++ * src/truetype/ttgxvar.c (tt_done_blend): Use `TT_Face' as argument.
++ * src/truetype/ttgxvar.h: Updated.
++
++ * src/truetype/ttobjs.c (TT_Face_Done): Updated.
++
++ * src/truetype/ttdriver.c (tt_service_gx_multi_masters): Updated.
++ * src/type1/t1driver.c (t1_service_multi_masters): Updated.
++
++2016-12-09 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Revert change from 2016-12-08.
++
++ I missed the functionality of `ft_module_get_service', which makes
++ the change unnecessary.
++
++2016-12-08 Werner Lemberg <wl@gnu.org>
++
++ Add framework to support services with 8 functions.
++
++ We will need this for CFF variation font support.
++
++ * include/freetype/internal/ftserv.h (FT_DEFINE_SERVICEDESCREC8):
++ New macro.
++
++2016-12-08 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Add `get_glyph_name' and `get_name_index' to SFNT interface.
++
++ CFF2 fonts will need access to those two functions.
++
++ * include/freetype/internal/sfnt.h: Include FT_SERVICE_GLYPH_DICT_H.
++ (SFNT_Interface): Add `get_glyph_name' and `get_name_index' members.
++ (FT_DEFINE_SFNT_INTERFACE): Updated.
++
++ * src/sfnt/sfdriver.c (sfnt_get_glyph_name, sfnt_get_name_index):
++ Fix signatures to exactly correspond to the glyph dict service
++ function typedefs.
++ (sfnt_interface): Updated.
++
++2016-12-06 Dave Arnold <darnold@adobe.com>
++
++ Add `FT_Get_Var_Design_Coordinates' function.
++
++ Note that the low-level functions aren't implemented yet.
++
++ * include/freetype/ftmm.h: Declare.
++
++ * include/freetype/internal/services/svmm.h
++ (FT_Get_Var_Design_Func): New typedef.
++ (MultiMasters): New MM service function `get_var_design'.
++ (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated.
++ Update all callers.
++
++ * src/base/ftmm.c (FT_Get_Var_Design_Coordinates): Implement.
++
++ * src/truetype/ttdriver.c: Updated.
++
++ * src/truetype/ttgxvar.c (TT_Get_Var_Design): New dummy function to
++ handle `get_var_design' service.
++ * src/truetype/ttgxvar.h: Updated.
++
++ * src/type1/t1driver.c: Updated.
++
++ * src/type1/t1load.c (T1_Get_Var_Design): New dump function to
++ handle `get_var_design' service.
++ * src/type1/t1load.h: Updated.
++
++2016-12-06 Werner Lemberg <wl@gnu.org>
++
++ * src/type1/t1load.c (parse_subrs): Fix memory leak.
++
++ The `subrs' keyword might erroneously occur multiple times.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=231
++
++2016-12-01 Werner Lemberg <wl@gnu.org>
++
++ [gzip] Improve building with external zlib (#49673).
++
++ Building FreeType with external zlib 1.2.8 makes msvc 14 stop with
++ the following error.
++
++ ftgzip.c
++ zlib-1.2.8\zlib.h(86): error C2061:
++ syntax error: identifier 'z_const'
++ zlib-1.2.8\zlib.h(94): error C2054:
++ expected '(' to follow 'z_const'
++ zlib-1.2.8\zlib.h(94): error C2085:
++ 'msg': not in formal parameter list
++ ...
++ zlib-1.2.8\zlib.h(877): fatal error C1003:
++ error count exceeds 100; stopping compilation
++
++ The error happens because FreeType keeps an own copy of zlib-1.1.4
++ under `src/gzip'. When building `src/gzip/ftgzip.c' with
++ FT_CONFIG_OPTION_SYSTEM_ZLIB defined, it uses
++
++ #include <zlib.h>
++
++ which correctly finds an external `zlib.h', but `zlib.h' itself has
++ a line
++
++ #include "zconf.h"
++
++ which makes Visual Studio 2015 find `src/gzip/zconf.h' while
++ compiling the files in `src/gzip'.
++
++ * src/gzip/zconf.h: Rename to...
++ * src/gzip/ftzconf.h: ... this.
++ * src/gzip/zlib.h, src/gzip/rules.mk (GZIP_DRV_SRCS): Updated.
++
++2016-12-01 Oleksandr Chekhovskyi <oleksandr.chekhovskyi@gmail.com>
++
++ [autofit] Fix Emscripten crash (patch #9180).
++
++ Function calls through pointers must use a matching signature to
++ work on Emscripten, since such calls are dispatched through lookup
++ tables grouped by signature.
++
++ * src/autofit/aftypes.h (AF_WritingSystem_ApplyHintsFunc): Fix
++ typedef.
++
++2016-11-29 Werner Lemberg <wl@gnu.org>
++
++ [smooth] Revert previous commit. Already fixed with 6ca54c64.
++
++2016-11-29 Werner Lemberg <wl@gnu.org>
++
++ [smooth] Avoid conditional jump on uninitialized value (#49711).
++
++ * src/smooth/ftgrays.c (gray_raster_render): Initialize `worker'.
++
++2016-11-27 Nikolaus Waxweiler <madigens@gmail.com>
++
++ [autofit] Code shuffling.
++
++ Also improve some comments and remove unused code.
++
++ No functional change.
++
++ * src/autofit/afloader.c (af_loader_load_g): Merged with...
++ (af_loader_load_glyph): ...this function.
++ Split off emboldening code into...
++ (af_loader_embolden_glyph_in_slot): ... this function.
++
++2016-11-17 Werner Lemberg <wl@gnu.org>
++
++ Better support of LLP64 systems with gcc (and clang).
++
++ * builds/unix/configure.raw: Call `AC_TYPE_LONG_LONG_INT'.
++
++ * builds/unix/ftconfig.in (FT_LONG64): Enable for LLP64 systems (and
++ suppress warnings) even without `FT_CONFIG_OPTION_FORCE_INT64'.
++
++2016-11-10 Werner Lemberg <wl@gnu.org>
++
++ Fix `lcd_weights' array size.
++
++ * include/freetype/internal/ftobjs.h (FT_LibraryRec): Do it.
++
++ Reported by Nikolaus.
++
++2016-11-06 Werner Lemberg <wl@gnu.org>
++
++ * src/base/ftobjs.c (FT_Render_Glyph_Internal): Fix tracing.
++
++2016-11-06 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Improve FT_LOAD_BITMAP_METRICS_ONLY for `sbix' format.
++
++ It's unavoidable to call the PNG engine, but to get the metrics it
++ is sufficient to read the PNG image's header only.
++
++ * src/sfnt/pngshim.c (Load_SBit_Png): Add argument to control the
++ allocation of the glyph slot.
++ * src/sfnt/pngshim.h: Updated.
++ * src/sfnt/ttsbit.c (tt_sbit_decoder_load_png,
++ tt_face_load_sbix_image, tt_face_load_sbit_image): Updated.
++
++2016-11-06 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Speed up `sbix' lookup.
++
++ This also fixes a bug introduced in 2016-10-01 which prevents
++ display of embedded bitmap fonts that use the `sbix' format.
++
++ * src/sfnt/ttsbit.c (tt_face_load_sbit): Store `sbix' size and
++ offset also in `ebdt_size' and `ebdt_start', respectively. This
++ makes the test for an embedded bitmap data table succeed for this
++ format.
++
++ (tt_face_load_strike_metrics) <TT_SBIT_TABLE_TYPE_SBIX>: Use
++ `ebdt_size' and `ebdt_start'
++ (tt_face_load_sbix_image): Ditto.
++
++2016-11-06 Seigo Nonaka <nona@google.com>
++ Werner Lemberg <wl@gnu.org>
++
++ Introduce a way of quickly retrieving (embedded) bitmap metrics.
++
++ `FT_Load_Glyph' doesn't generate a bitmap for a non-bitmap glyph
++ until the user calls `FT_Render_Glyph'. However, it always
++ allocates memory for bitmaps and copies or decodes the contents of a
++ bitmap glyph, which can be quite slow for PNG data.
++
++ * include/freetype/freetype.h (FT_LOAD_BITMAP_METRICS_ONLY): New
++ macro.
++
++ * src/base/ftobjs.c (FT_Load_Glyph): Unset FT_LOAD_RENDER if
++ FT_LOAD_BITMAP_METRICS_ONLY is used.
++
++ * src/sfnt/ttsbit.c (tt_sbit_decoder_alloc_bitmap,
++ tt_sbit_decoder_load_bitmap): Add argument to control allocation of
++ the glyph slot.
++ (tt_sbit_decoder_load_image, tt_sbit_decoder_load_compound,
++ tt_face_load_sbit_image): Updated.
++
++ * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Quickly exit if
++ `FT_LOAD_BITMAP_METRICS_ONLY' is set.
++
++ * src/pfr/pfrsbit.c, src/pfr/pfrsbit.h (pfr_slot_load_bitmap): Add
++ argument to control allocation of the glyph slot.
++ * src/pfr/pfrobjs (pfr_slot_load): Updated.
++
++ * src/winfonts/winfnt.c (FNT_Load_Glyph): Ditto.
++
++ * docs/CHANGES: Updated.
++
++2016-11-06 Werner Lemberg <wl@gnu.org>
++
++ Synchronize with gnulib (#49448).
++
++ * include/freetype/config/ftconfig.h, builds/unix/ftconfig.in,
++ builds/vms/ftconfig.h (FT_TYPEOF): Update code to use definition in
++ current version of `intprops.h'.
++ Other minor synchronization to reduce code differences between the
++ three files.
++
++2016-11-03 Behdad Esfahbod <behdad@behdad.org>
++
++ [truetype] Clamp variation requests to valid range.
++
++ This is required by OpenType 1.8; it also avoids rounding surprises.
++
++ * src/truetype/ttgxvar.c (TT_Set_Var_Design): Clamp design coordinates
++ outside of the allowed range to always stay within the range instead
++ of producing an error.
++
++2016-10-29 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Remove clang warnings.
++
++ * src/truetype/ttinterp.h (TT_ExecContextRec): Using `FT_ULong' for
++ loop counter handling.
++
++ * src/truetype/ttinterp.c: Updated.
++ (Ins_SCANTYPE): Use signed constant.
++ (TT_RunIns): Ensure `num_twilight_points' is 16bit.
++
++2016-10-27 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix commit from 2014-11-24.
++
++ Problem reported by Hin-Tak Leung <htl10@users.sourceforge.net>.
++
++ * src/truetype/ttpload.c (tt_face_load_hdmx): Fix file checking
++ logic.
++
++2016-10-26 Werner Lemberg <wl@gnu.org>
++
++ Add `FT_Get_{MM,Var}_Blend_Coordinates' functions.
++
++ * include/freetype/ftmm.h: Declare.
++
++ * include/freetype/internal/services/svmm.h (FT_Get_MM_Blend_Func):
++ New typedef.
++ (MultiMasters): New MM service function `get_mm_blend'.
++ (FT_DEFINE_SERVICE_MULTIMASTERSREC): Updated.
++ Update all callers.
++
++ * src/base/ftmm.c (FT_Get_MM_Blend_Coordinates,
++ FT_Get_Var_Blend_Coordinates): Implement.
++
++ * src/truetype/ttdriver.c: Updated.
++
++ * src/truetype/ttgxvar.c (TT_Get_MM_Blend): New function to handle
++ `get_mm_blend' service.
++ * src/truetype/ttgxvar.h: Updated.
++
++ * src/type1/t1driver.c: Updated.
++
++ * src/type1/t1load.c (T1_Get_MM_Blend): New function to handle
++ `get_mm_blend' service.
++ * src/type1/t1load.h: Updated.
++
++ * docs/CHANGES: Document.
++
++2016-10-26 Werner Lemberg <wl@gnu.org>
++
++ * src/type1/t1load.c (parse_subrs): Fix limit check.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=81
++
++2016-10-25 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [cff] Correct cmap format reporting (#24819).
++
++ * src/cff/cffdrivr.c (cff_get_cmap_info): Throw an error on synthetic
++ charmap instead of guessing its format and language.
++
++2016-10-22 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix SCANTYPE instruction (#49394).
++
++ * src/truetype/ttinterp.c (Ins_SCANTYPE): Only use lower 16bits.
++
++2016-10-22 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Improve handling of invalid post 2.5 tables [#49393].
++
++ * src/sfnt/ttpost.c (load_format_25): We need at least a single
++ table entry.
++
++2016-10-14 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix handling of `cvar' table data.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53
++
++ * src/truetype/ttgxvar.c (tt_face_vary_cvt): Ignore invalid CVT
++ indices.
++
++2016-10-11 Werner Lemberg <wl@gnu.org>
++
++ [psaux] Fix handling of invalid flex subrs.
++
++ Problem reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52
++
++ * src/psaux/t1decode.c (t1_decoder_parse_charstrings)
++ <op_callothersubr>: Set `flex_state' after error checking.
++
++2016-10-11 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttgxvar.c (tt_done_blend): Fix deallocation.
++
++2016-10-08 Werner Lemberg <wl@gnu.org>
++
++ * src/cid/cidload.c (cid_face_open): Properly propagate `error'.
++
++2016-10-08 Werner Lemberg <wl@gnu.org>
++
++ [cid] Fix parsing of subr offsets.
++
++ Bug introduced 2016-05-16.
++
++ * src/cid/cidparse.c (cid_parser_new): Fix off-by-one error.
++
++2016-10-01 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Disable bitmap strikes if we don't have a bitmap data table.
++
++ * src/sfnt/ttsbit.c (tt_face_load_sbit): Check whether we have
++ a bitmap data table.
++
++2016-10-01 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Remove impossibility.
++
++ * src/smooth/ftgrays.c (TWorker): Rearrange fields.
++ (gray_convert_glyph): Remove impossible condition and clean up.
++
++2016-09-29 Werner Lemberg <wl@gnu.org>
++
++ [pcf] Enrich family name with foundry name and glyph width info.
++
++ This is a very old patch from openSuSE (from 2006, submitted to
++ FreeType in 2011) that I forgot to apply.
++
++ https://build.opensuse.org/package/view_file/openSUSE:Factory/freetype2/freetype2-bitmap-foundry.patch
++
++ Prepend the foundry name plus a space to the family name. There are
++ many fonts just called `Fixed' which look completely different, and
++ which have nothing to do with each other. When selecting `Fixed' in
++ KDE or Gnome one gets results that appear rather random, the style
++ changes often if one changes the size and one cannot select some
++ fonts at all.
++
++ We also check whether we have `wide' characters; all put together,
++ we get family names like `Sony Fixed' or `Misc Fixed Wide'.
++
++ * src/pcf/pcfread.c (pcf_load_font): Implement it.
++
++ * docs/CHANGES: Document it.
++
++2016-09-29 Werner Lemberg <wl@gnu.org>
++
++ [ftfuzzer] Speed up.
++
++ * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Don't
++ check for embedded bitmaps if we have a non-default instance.
++
++2016-09-29 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Disallow bitmap strikes for non-default instances.
++
++ Also speed up access of default instances if GX variations are
++ active.
++
++ * include/freetype/internal/tttypes.h (TT_FaceRec): Add
++ `is_default_instance' member.
++
++ * src/sfnt/sfobjs.c (sfnt_init_face): Initialize
++ `is_default_instance'.
++
++ * src/truetype/ttgload.c (TT_Process_Simple_Glyph,
++ load_truetype_glyph): Add test for default instance.
++ (TT_Load_Glyph): Load embedded bitmaps for default instance only.
++
++ * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Compute
++ `is_default_instance'.
++
++2016-09-29 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Clean up `TT_Face' structure.
++
++ * include/freetype/internal/tttypes.h (TT_FaceRec): Remove unused
++ fields `horz_metrics' and `vert_metrics'.
++ Update documentation.
++
++ * src/sfnt/sfobjs.c (sfnt_done_face): Updated.
++
++2016-09-28 Werner Lemberg <wl@gnu.org>
++
++ More FT_ZERO usage.
++
++ * src/gxvalid/gxvcommn.c (gxv_ClassTable_validate):
++ s/ft_memset/FT_MEM_ZERO/.
++
++ * src/psaux/t1decode.c (t1_decoder_parse_charstrings):
++ s/ft_memset/FT_ARRAY_ZERO/.
++
++ * src/raster/ftraster.c (FT_ZERO): Define.
++ (ft_black_new): Use it.
++ * src/raster/ftrend1.c (ft_raster1_get_cbox):
++ s/FT_MEM_ZERO/FT_ZERO/.
++
++ * src/smooth/ftgrays.c (FT_ZERO): Define.
++ (gray_raster_new): Use it.
++ * src/smooth/ftsmooth.c (ft_smooth_get_cbox):
++ s/FT_MEM_ZERO/FT_ZERO/.
++
++2016-09-28 Werner Lemberg <wl@gnu.org>
++
++ */*: s/FT_MEM_ZERO/FT_ZERO/ where appropriate.
++
++2016-09-27 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Trace number of executed opcodes.
++
++ * src/truetype/ttinterp.c (TT_RunIns): Implement it.
++
++2016-09-27 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Speed up `TT_Load_Glyph'.
++
++ This avoids additional calls to `tt_face_lookup_table' for the
++ `glyf' table, which can be expensive.
++
++ * include/freetype/internal/tttypes.h (TT_LoaderRec): Move
++ `glyf_offset' field to ...
++ (TT_FaceRec): ... this structure.
++ * src/truetype/ttgload.c (load_truetype_glyph): Updated.
++ (tt_loader_init): Move initialization of `glyf_offset' to ...
++ * src/truetype/ttpload.c (tt_face_load_loca): ... this function.
++
++2016-09-27 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Introduce dynamic limits for some bytecode opcodes.
++
++ This speeds up FreeType's handling of malformed fonts.
++
++ * src/truetype/ttinterp.c (TT_RunIns): Set up limits for the number
++ of twilight points, the total number of negative jumps, and the
++ total number of loops in LOOPCALL opcodes. The values are based on
++ the number of points and entries in the CVT table.
++ (Ins_JMPR): Test negative jump counter.
++ (Ins_LOOPCALL): Test loopcall counter.
++
++ * src/truetype/ttinterp.h (TT_ExecContext): Updated.
++
++ * docs/CHANGES: Updated.
++
++2016-09-25 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Sanitize only last entry of `loca' table.
++
++ Without this patch, a loca sequence like `0 100000 0 100000 ...',
++ where value 100000 is larger than the `glyf' table size, makes
++ FreeType handle the whole `glyf' table as a single glyph again and
++ again, which is certainly invalid (and can be very slow, too).
++
++ * src/truetype/ttpload.c (tt_face_get_location): Implement.
++ Improve tracing messages.
++
++2016-09-25 Werner Lemberg <wl@gnu.org>
++
++ * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Fix typo.
++
++2016-09-24 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Tracing fixes.
++
++ * src/autofit/afmodule.c (af_autofitter_load_glyph): Call dumping
++ functions only if we actually do tracing.
++
++2016-09-22 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Reduce divisions in the line renderer.
++
++ We don't need some divisions if a line segments stays within a single
++ row or a single column of pixels.
++
++ * src/smooth/ftgrays.c (gray_render_line) [FT_LONG64]: Make divisions
++ conditional.
++
++2016-09-15 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/smooth/ftgrays.c (gray_sweep): Remove check for empty table.
++
++2016-09-14 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Another tiny speed-up.
++
++ * src/smooth/ftgrays.c (gray_find_cell): Merge into...
++ (gray_record_cell): ... this function.
++
++2016-09-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/smooth/ftgrays.c (gray_{find,set}_cell): Remove dubious code.
++
++2016-09-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Fix valgrind warning and reoptimize.
++
++ The algorithm calls `gray_set_cell' at the start of each new contour
++ or when the contours cross the cell boundaries. Double-checking for
++ that is wasteful.
++
++ * src/smooth/ftgrays.c (gray_set_cell): Remove check for a new cell.
++ (gray_convert_glyph): Remove initialization introduced by 44b172e88.
++
++2016-09-10 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Fix previous commit.
++
++ Problems reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40
++
++ We now map the strike index right before accessing the physical
++ data, not earlier.
++
++ * src/sfnt/sfobjs.c (sfnt_load_face): Set `face->sbit_strike_map'
++ after creating the map so that...
++
++ * src/sfnt/ttsbit.c (tt_face_load_strike_metrics): ... this function
++ can be used before and after setting up `sbit_strike_map'.
++ (tt_face_set_sbit_strike): Revert change.
++ (tt_sbit_decoder_init, tt_face_load_sbix_image): Map strike index.
++
++ * src/truetype/ttdriver.c (tt_size_select): Revert change.
++
++2016-09-09 Werner Lemberg <wl@gnu.org>
++
++ [ftfuzzer] Minor improvements.
++
++ * src/tools/ftfuzzer/ftfuzzer.cc (LLVMFuzzerTestOneInput): Ignore
++ invalid strikes.
++ Use better values for call to `FT_Set_Char_Size'.
++
++2016-09-09 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Don't provide (completely) broken strike data.
++
++ FreeType tries to sanitize strike header data; we now reject
++ completely broken ones.
++
++ * include/freetype/internal/tttypes.h (TT_FaceRec): New
++ `sbit_strike_map' array pointer.
++
++ * src/base/ftobjs.c (FT_Match_Size): Reject matches where either
++ width or height would be zero.
++ Add tracing message in case of error.
++
++ * src/sfnt/sfobjs.c (sfnt_load_face): Populate `sbit_strike_map',
++ only using (more or less) valid strike header data for
++ FT_Face's `available_sizes' array.
++ (sfnt_done_face): Updated.
++
++ * src/sfnt/ttsbit.c (tt_face_set_sbit_strike): Use
++ `sbit_strike_map'.
++ (tt_face_load_strike_metrics): Improve tracing.
++
++ * src/truetype/ttdriver.c (tt_size_select): Use `sbit_strike_map'.
++
++2016-09-08 Werner Lemberg <wl@gnu.org>
++
++ * Version 2.7 released.
++ =======================
++
++
++ Tag sources with `VER-2-7'.
++
++ * docs/VERSION.TXT: Add entry for version 2.7.
++
++ * README, Jamfile (RefDoc), builds/windows/vc2005/freetype.vcproj,
++ builds/windows/vc2005/index.html,
++ builds/windows/vc2008/freetype.vcproj,
++ builds/windows/vc2008/index.html,
++ builds/windows/vc2010/freetype.vcxproj,
++ builds/windows/vc2010/index.html,
++ builds/windows/visualc/freetype.dsp,
++ builds/windows/visualc/freetype.vcproj,
++ builds/windows/visualc/index.html,
++ builds/windows/visualce/freetype.dsp,
++ builds/windows/visualce/freetype.vcproj,
++ builds/windows/visualce/index.html,
++ builds/wince/vc2005-ce/freetype.vcproj,
++ builds/wince/vc2005-ce/index.html,
++ builds/wince/vc2008-ce/freetype.vcproj,
++ builds/wince/vc2008-ce/index.html: s/2.6.5/2.7/, s/265/27/.
++
++ * include/freetype/freetype.h (FREETYPE_MINOR): Set to 7.
++ (FREETYPE_PATCH): Set to 0.
++
++ * builds/unix/configure.raw (version_info): Set to 18:6:12.
++ * CMakeLists.txt (VERSION_MINOR): Set to 7.
++ (VERSION_PATCH): Set to 0.
++
++ * docs/CHANGES: Updated.
++
++2016-09-08 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttinterp.c: Include `ttgxvar.h'.
++
++ This fixes the `multi' build.
++
++2016-09-08 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Another improvement to Armenian support.
++
++ Suggested by Hrant H Papazian <hpapazian@gmail.com>.
++
++ * src/autofit/afscript.h: Use better suited characters to derive
++ default stem widths.
++
++2016-09-07 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/smooth/ftgrays.c (gray_hline): Micro-optimize.
++
++2016-09-06 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Operate in absolute bitmap coordinates.
++
++ Simpler bitmap addressing improves performance by 1.5%.
++
++ * src/smooth/ftgrays.c (gray_TWorker): Remove count fields.
++ (gray_dump_cells, gray_find_cell, gray_set_cell, gray_hline,
++ gray_sweep, gray_convert_glyph, gray_raster_render): Updated.
++
++2016-09-06 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Improve contour start (take 2).
++
++ * src/smooth/ftgrays.c (gray_move_to): Call `gray_set_cell' directly
++ instead of...
++ (gray_start_cell): ... this function, which is removed.
++ (gray_convert_glyph): Make initial y-coordinate invalid.
++
++2016-09-06 Werner Lemberg <wl@gnu.org>
++
++ [type1] MM fonts support exactly zero named instances (#48748).
++
++ * src/type1/t1load.c (T1_Get_MM_Var): Set `num_namedstyles' to zero.
++
++2016-09-06 Jonathan Kew <jfkthame@gmail.com>
++
++ [cff] Fix uninitialized memory.
++
++ Problem reported as
++
++ https://bugzilla.mozilla.org/show_bug.cgi?id=1270288
++
++ * src/cff/cf2intrp.c (cf2_interpT2CharString): Initialize `storage'
++ array to handle a `get' opcode without a previous `put'.
++
++2016-09-05 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/smooth/ftgrays.c (gray_move_to, gray_start_cell): Revert.
++
++2016-09-05 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Improve contour start.
++
++ * src/smooth/ftgrays.c (gray_move_to): Call `gray_set_cell' directly
++ instead of...
++ (gray_start_cell): ... this function, which is removed.
++
++2016-09-05 Werner Lemberg <wl@gnu.org>
++
++ [cff] Fix memory initialization.
++
++ * src/cff/cf2stack.c (cf2_stack_init): Use `FT_NEW'. The `Q'
++ variants of FreeType's memory allocation macros don't do zeroing.
++
++2016-09-05 Werner Lemberg <wl@gnu.org>
++
++ [ftrandom] Minor improvements.
++
++ * src/tools/ftrandom/ftrandom.c (_XOPEN_SOURCE): New macro, set to
++ 500.
++
++ * src/tools/ftrandom/Makefile (CFLAGS): Split off include
++ directories to ...
++ (INCLUDES): ... this new variable.
++ (LDFLAGS): New variable.
++ (ftrandom.o, ftrandom): Updated.
++
++2016-09-05 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Improve Armenian support.
++
++ Thanks to Hrant H Papazian <hpapazian@gmail.com> for help.
++
++ * src/autofit/afblue.dat (AF_BLUE_STRING_ARMENIAN_*): Improve
++ selection of characters.
++
++ * src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
++
++2016-09-04 Werner Lemberg <wl@gnu.org>
++
++ [ftrandom] Improve Makefile.
++
++ It now supports both a normal build (`./configure && make') and a
++ development build (`make devel').
++
++ * src/tools/ftrandom/Makefile (VPATH): Set it so that
++ `libfreetype.a' gets searched in both `objs' (for the development
++ build) and `objs/.libs' (for a normal build which uses libtool).
++ (LIBS): Add missing libraries.
++ (ftrandom.o): New rule.
++ (ftrandom): Use automatic variables.
++
++2016-09-03 Werner Lemberg <wl@gnu.org>
++
++ [truetype] More fixes for handling of GX deltas.
++
++ Problems reported by Bob Taylor <Bob.Taylor@monotype.com>.
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Fix rough
++ sanity test for glyph variation array header size.
++ Always set stream position before reading packed x and y deltas.
++ Fix thinko w.r.t. `localpoints' array.
++
++2016-09-03 Werner Lemberg <wl@gnu.org>
++
++ [ftrandom] Various fixes.
++
++ * src/tools/ftrandom/ftrandom.c (GOOD_FONTS_DIR): Provide better
++ default.
++ (error_fraction): Make it of type `double' to work as advertized â
++ this was completely broken.
++ Update all related code.
++ (error_count, fcnt): Make it unsigned to fix compiler warnings.
++ Update all related code.
++ (fontlist): Change `len' member to `long' to fix compiler warnings.
++ (FT_MoveTo, FT_LineTo, FT_ConicTo, FT_CubicTo, abort_test): Tag
++ unused variables.
++ (TestFace, FindFonts, copyfont, do_test): Fix compiler warnings.
++ (ExecuteTest): Ditto.
++ Call `FT_Done_FreeType'.
++ (getErrorCnt): Replace `ceil' with an ordinary cast to `unsigned
++ int'.
++ (usage): Improve output.
++ (main): Fix compiler warnings.
++
++ * src/tools/ftrandom/README: Updated.
++
++2016-09-03 Werner Lemberg <wl@gnu.org>
++
++ [base] Avoid negative bitmap strike dimensions (#48985).
++
++ * src/base/ftobjs.c (FT_Open_Face): Check whether negation was
++ actually successful. For example, this can fail for value
++ -32768 if the type is `signed short'. If there are problems,
++ disable the strike.
++
++2016-09-03 Werner Lemberg <wl@gnu.org>
++
++ [cff] Avoid null pointer passed to FT_MEM_COPY (#48984).
++
++ * src/cff/cffload.c (cff_index_get_name): Check `byte_len'.
++
++2016-09-02 Werner Lemberg <wl@gnu.org>
++
++ [unix] Enable 64bit support in file system access (#48962).
++
++ * builds/unix/configure.raw: Call `AC_SYS_LARGEFILE'.
++
++2016-09-02 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Avoid left shift of negative value (#48980).
++
++ * src/sfnt/ttsbit.c (tt_sbit_decoder_load_bit_aligned): Use unsigned
++ constant.
++
++2016-09-02 Werner Lemberg <wl@gnu.org>
++
++ * src/smooth/ftgrays.c (gray_hline): Fix clang compiler warnings.
++
++2016-09-02 Werner Lemberg <wl@gnu.org>
++
++ Some preparations for the next release.
++
++ * include/freetype/config/ftoption.h
++ (TT_CONFIG_OPTION_SUBPIXEL_HINTING): Enable.
++
++ * docs/CHANGES: Updated.
++
++2016-09-01 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Simplify span rendering more.
++
++ It turns out that there is significant cost associated with `FT_Span'
++ creation and calls to `gray_render_span' because it happens so
++ frequently. This removes these steps from our internal use but leaves
++ it alone for `FT_RASTER_FLAG_DIRECT" to preserve API. The speed gain
++ is about 5%.
++
++ * src/smooth/ftgrays.c (gray_render_span): Removed. The code is
++ migrated to...
++ (gray_hline): ... here.
++
++2016-08-30 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Streamline pixmap drawing a bit more.
++
++ Zero coverage is unlikely (1 out of 256) to warrant checking. This
++ gives 0.5% speed improvement in rendering simple glyphs.
++
++ * src/smooth/ftgrays.c (gray_hline, gray_render_span): Remove checks.
++
++2016-08-29 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Streamline pixmap drawing.
++
++ This gives 2% speed improvement in rendering simple glyphs.
++
++ * src/smooth/ftgrays.c (TPixmap): Reduced pixmap descriptor with a
++ pointer to its bottom-left and pitch to be used in...
++ (gray_TWorker): ... here.
++ (gray_render_span): Move pixmap flow check from here...
++ (gray_raster_render): .. to here.
++
++2016-08-27 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Reduce stack of band boundaries.
++
++ * src/smooth/ftgrays.c (gray_TBand): Removed.
++ (gray_convert_glyph): Updated to stack band boundaries concisely.
++
++2016-08-26 Werner Lemberg <wl@gnu.org>
++
++ * src/cid/cidload.c (cid_face_open): Improve handling of `SDBytes'.
++
++2016-08-26 Werner Lemberg <wl@gnu.org>
++
++ [cid] Fix commit from 2016-05-16.
++
++ * src/cid/cidparse.c (cid_parser_new): Fix off-by-one errors.
++
++2016-08-26 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Cache offset and size to bitmap data table.
++
++ This commit avoids `EBDT' and friends being looked up again and
++ again while loading a single embedded bitmap.
++
++ * include/freetype/internal/tttypes.h (TT_FaceRec)
++ [TT_CONFIG_OPTION_EMBEDDED_BITMAPS]: New fields `ebdt_start' and
++ `ebdt_size'.
++
++ * src/sfnt/ttsbit.c (tt_sbit_decoder_init): Move table lookup to ...
++ (tt_face_load_sbit): ... this function; also store the table size
++ and offset.
++
++2016-08-26 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/smooth/ftgrays.c (gray_raster_render): Minor tweaks.
++
++2016-08-26 Werner Lemberg <wl@gnu.org>
++
++ [type1] Fix heap buffer overflow.
++
++ Reported as
++
++ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=36
++
++ * src/type1/t1load.c (parse_charstrings): Reject fonts that don't
++ contain glyph names.
++
++2016-08-25 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Fix previous commit (#48901).
++
++ * src/sfnt/ttcmap.c (tt_cmap4_char_map_binary): Thinkos.
++
++2016-08-25 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Speed up handling of invalid format 4 cmaps.
++
++ * src/sfnt/ttcmap.c (tt_cmap4_next, tt_cmap4_char_map_binary): Add
++ tests for `num_glyph' from `tt_cmap4_char_map_linear'.
++
++2016-08-25 Werner Lemberg <wl@gnu.org>
++
++ * include/freetype/internal/ftdriver.h: Remove unused typedefs.
++
++2016-08-22 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Simplify span rendering.
++
++ This removes unnecessary complexity of span merging and buffering.
++ Instead, the spans are rendered as they come, speeding up the
++ rendering by about 5% as a result.
++
++ * src/smooth/ftgrays.c [FT_MAX_GRAY_SPANS]: Macro removed.
++ (gray_TWorker): Remove span buffer and related fields.
++ (gray_sweep, gray_hline): Updated.
++
++ * include/freetype/ftimage.h: Remove documentation note about
++ `FT_MAX_GRAY_SPANS', which was never in `ftoption.h' and is now gone.
++
++2016-08-16 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix `MPS' instruction.
++
++ According to Greg Hitchcock, MPS in DWrite really returns the point
++ size.
++
++ * src/truetype/ttobjs.h (TT_SizeRec): Add `point_size' member.
++
++ * src/truetype/ttdriver.c (tt_size_request): Set `point_size'.
++
++ * src/truetype/ttinterp.h (TT_ExecContextRec): Add `pointSize'
++ member.
++
++ * src/truetype/ttinterp.c (TT_Load_Context): Updated.
++ (Ins_MPS): Fix instruction.
++
++2016-08-16 Werner Lemberg <wl@gnu.org>
++
++ [lzw] Optimize last commit.
++
++ * src/lzw/ftzopen.c (ft_lzwstate_get_code): Move check into
++ conditional clause.
++
++2016-08-16 Werner Lemberg <wl@gnu.org>
++
++ [lzw] Avoid invalid left shift.
++
++ Reported as
++
++ https://bugzilla.mozilla.org/show_bug.cgi?id=1295366
++
++ * src/lzw/ftzopen.c (ft_lzwstate_get_code): Limit `num_bits'.
++
++2016-08-16 Werner Lemberg <wl@gnu.org>
++
++ [lzw] Avoid buffer overrun.
++
++ Reported as
++
++ https://bugzilla.mozilla.org/show_bug.cgi?id=1273283
++
++ * src/lzw/ftzopen.c (ft_lzwstate_refill): Ensure `buf_size' doesn't
++ underflow.
++
++2016-08-16 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix compiler warning.
++
++ * src/truetype/ttgload.c (load_truetype_glyph): Add cast.
++
++2016-08-13 Werner Lemberg <wl@gnu.org>
++
++ [winfonts] Avoid zero bitmap width and height.
++
++ Reported as
++
++ https://bugzilla.mozilla.org/show_bug.cgi?id=1272173
++
++ * src/winfonts/winfnt.c (FNT_Face_Init): Check zero pixel height.
++ (FNT_Load_Glyph): Check for zero pitch.
++
++2016-08-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/truetype/ttinterp.c (Pop_Push_Count): Revert changes.
++
++2016-08-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/truetype/ttinterp.c (TT_RunIns): Minor and formatting.
++
++2016-08-11 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ * src/truetype/ttinterp.c (Pop_Push_Count): Fix some entries.
++
++2016-08-10 Peter Klotz <Peter.Klotz@ith-icoserve.com>
++
++ * src/smooth/ftgrays.c (gray_hline): Fix uninitialized access.
++
++2016-08-10 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Use correct type for `italicAngle' field (#48732).
++
++ * src/sfnt/ttload.c (tt_face_load_post): Fix types.
++
++2016-08-06 Jon Spencer <jon@jonspencer.ca>
++
++ [sfnt] Fix `FT_Get_Advance' for bitmap strikes.
++
++ `FT_Get_Advance' returns 0 for bitmap fonts. It first gets the
++ advance value from the font table and then scales it by the
++ `font->size->metrics->x_scale' field. But `FT_Select_Size' doesn't
++ set that value for bitmap fonts and the advance gets scaled to zero.
++
++ Taken from
++
++ https://github.com/behdad/harfbuzz/issues/252
++
++ * src/sfnt/ttsbit.c (tt_face_load_strike_metrics)
++ <TT_SBIT_TABLE_TYPE_EBLC>: Set scale values.
++
++2016-08-06 Behdad Esfahbod <behdad@behdad.org>
++
++ [truetype] Fix GX variation handling of composites.
++
++ * src/truetype/ttgload.c (load_truetype_glyph)
++ [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Check `ARGS_ARE_XY_VALUES' flag.
++
++2016-08-05 Alexei Podtelezhnikov <apodtele@gmail.com>
++
++ [smooth] Minor refactoring.
++
++ * src/smooth/ftgrays.c (gray_render_scanline, gray_render_line):
++ Updated.
++
++2016-07-29 Werner Lemberg <wl@gnu.org>
++
++ [sfnt, truetype] Don't abort on invalid `maxComponentDepth'.
++
++ Since 2016-05-16 we detect infinite recursion directly.
++
++ * src/sfnt/ttload.c (tt_face_load_maxp): Don't adjust
++ `maxComponentDepth'.
++ * src/truetype/ttgload.c (load_truetype_glyph): Don't abort if
++ `maxComponentDepth' is not valid. Instead, simply adjust its value
++ and emit a tracing message.
++
++2016-07-26 Werner Lemberg <wl@gnu.org>
++
++ * src/autofit/aflatin.c (af_latin_metrics_scale_dim): Minor.
++
++ No functional change.
++
++2016-07-22 Hin-Tak Leung <htl10@users.sourceforge.net>
++
++ [truetype] Record the end of IDEFs.
++
++ To match the logic in FDEF. The value of the end is only used for
++ bound-checking in `Ins_JMPR', so it may not have been obvious that
++ it was not recorded. Tested (as part of Font Validator 2.0) all the
++ fonts on Fedora and did not see any change.
++
++ * src/truetype/ttinterp.c (Ins_IDEF): Updated.
++
++2016-07-19 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Sanitizer fix, second try.
++
++ * src/truetype/ttgxvar.c (ft_var_readpackedpoints): Fix boundary
++ tests and use only one slot more.
++
++2016-07-19 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Sanitizer fix.
++
++ * src/truetype/ttgxvar.c (ft_var_readpackedpoints): Increase array
++ to fix nested loops.
++
++2016-07-18 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Make GETDATA work only for GX fonts.
++
++ * src/truetype/ttinterp.c (opcode_name): Updated.
++ (Ins_GETDATA): Only define for `TT_CONFIG_OPTION_GX_VAR_SUPPORT'.
++ (TT_RunIns): Updated.
++
++2016-07-17 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Add support for Apple's
++
++ GETDATA[], opcode 0x92
++
++ bytecode instruction. It always returns 17, and we have absolutely
++ no idea what it is good for...
++
++ * src/truetype/ttinterp.c (Pop_Push_Count, opcode_name): Updated.
++ (Ins_GETDATA): New function.
++ (TT_RunIns): Add it.
++
++2016-07-16 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Add bytecode support for GX variation fonts.
++
++ This commit implements undocumented (but confirmed) stuff from
++ Apple's old bytecode engine.
++
++ GETVARIATION[], opcode 0x91
++ This opcode pushes normalized variation coordinates for all axes
++ onto the stack (in 2.14 format). Coordinate of first axis gets
++ pushed first.
++
++ GETINFO[], selector bit 3
++ If GX variation support is enabled, bit 10 of the result is set
++ to 1.
++
++ * src/truetype/ttinterp.c: Include FT_MULTIPLE_MASTERS_H.
++ (opcode_name) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Updated.
++ (Ins_GETINFO) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Handle selector
++ bit 3, checking support for variation glyph hinting.
++ (Ins_GETVARIATION) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: New function
++ to implement opcode 0x91.
++ (TT_RunIns) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Handle opcode 0x91.
++
++2016-07-16 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix GETINFO bytecode instruction.
++
++ * src/truetype/ttinterp.c (Ins_GETINFO): Fix return value for
++ stretching information.
++
++2016-07-16 Behdad Esfahbod <behdad@behdad.org>
++
++ [truetype] Make all glyphs in `Zycon' GX font work.
++
++ * src/truetype/ttgxvar.c (ft_var_readpackedpoints): Fix boundary
++ tests.
++
++2016-07-16 Werner Lemberg <wl@gnu.org>
++
++ [truetype] Fix GX delta tracing.
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Trace
++ relative point movements.
++
++2016-07-16 Behdad Esfahbod <behdad@behdad.org>
++
++ [truetype] More fixes for GX.
++
++ This finally fixes the rendering of the cyclist and the lizard in
++ the `Zycon' font.
++
++ * src/truetype/ttgxvar.c (ft_var_readpackedpoints): `first' point
++ index is always cumulative.
++
++ (tt_handle_deltas): Rename to...
++ (tt_interpolate_deltas): ... This.
++ Add new parameter for output point array.
++ Update caller.
++
++ (TT_Vary_Apply_Glyph_Deltas): Add `points_out' array; it now holds
++ the intermediate results of `tt_interpolate_deltas' that are to be
++ added to `outline->points'.
++
++2016-07-15 Werner Lemberg <wl@gnu.org>
++
++ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Thinko.
++
++ `max_pos' is always larger than `min_pos' so `FT_ABS' is not needed.
++
++ Reported by Alexei.
++
++2016-07-16 Nikolaus Waxweiler <madigens@gmail.com>
++
++ * src/truetype/ttinterp.c (Ins_MIRP): Fix copy-and-paste error.
++
++ Problem reported by Hin-Tak Leung.
++
++2016-07-15 Werner Lemberg <wl@gnu.org>
++
++ [autofit] Update and improve segment and edge tracing.
++
++ * src/autofit/afhints.c (af_glyph_hints_dump_segments): Trace
++ `delta' also.
++ Don't show first point of segment as a replacement for `pos'; this
++ is (a) misleading, since the difference to `pos' can be almost
++ arbitrarily large in corner cases, and (b) it is better to have all
++ segment data in font units instead of a single value given in output
++ space coordinates.
++ Improve layout.
++ (af_glyph_hints_dump_edges): Show px->units and units->px conversion
++ values for convenience.
++ Improve layout.
++
++2016-07-15 Werner Lemberg <wl@gnu.org>
++
++ [autofit] For edges, reject segments wider than 1px (#41334).
++
++ * src/autofit/afhints.h (AF_SegmentRec): New member `delta'.
++
++ * src/autofit/aflatin.c (af_latin_hints_compute_segments): Compute
++ `delta'.
++ (af_latin_hints_compute_edges): Reject segments with a delta larger
++ than 0.5px.
++
++2016-07-14 Werner Lemberg <wl@gnu.org>
++
++ * include/freetype/freetype.h (FT_IS_NAMED_INSTANCE): New macro.
++
++2016-07-14 Werner Lemberg <wl@gnu.org>
++
++ [sfnt] Fix `face_index' value in `FT_Face' for named instances.
++
++ * src/sfnt/sfobjs.c (sfnt_init_face): Don't strip off higher 16bits.
++
++2016-07-14 Werner Lemberg <wl@gnu.org>
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Fix tracing.
++
++2016-07-14 Behdad Esfahbod <behdad@behdad.org>
++
++ [truetype] Fix gxvar delta interpolation.
++
++ The coordinates of the base font should be used for interpolation
++ purposes, NOT the current points (i.e., the result of accumulation
++ of previous deltas).
++
++ * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Initialize
++ `points_org' before looping over all tuples.
++
++
++----------------------------------------------------------------------------
++
++Copyright 2016-2017 by
++David Turner, Robert Wilhelm, and Werner Lemberg.
++
++This file is part of the FreeType project, and may only be used, modified,
++and distributed under the terms of the FreeType project license,
++LICENSE.TXT. By continuing to use, modify, or distribute this file you
++indicate that you have read the license and understand and accept it
++fully.
++
++
++Local Variables:
++version-control: never
++coding: utf-8
++End:
+diff --git a/builds/wince/ftdebug.c b/builds/wince/ftdebug.c
+index 7a20e2facb..f516726c3c 100644
+--- a/builds/wince/ftdebug.c
++++ b/builds/wince/ftdebug.c
+@@ -79,7 +79,7 @@
+
+
+ va_start( ap, fmt );
+- vprintf( fmt, ap );
++ vfprintf( stderr, fmt, ap );
+ /* send the string to the debugger as well */
+ vsprintf( buf, fmt, ap );
+ OutputDebugStringEx( buf );
+diff --git a/builds/windows/ftdebug.c b/builds/windows/ftdebug.c
+index cadfceade4..510768c125 100644
+--- a/builds/windows/ftdebug.c
++++ b/builds/windows/ftdebug.c
+@@ -65,7 +65,7 @@
+
+
+ va_start( ap, fmt );
+- vprintf( fmt, ap );
++ vfprintf( stderr, fmt, ap );
+ /* send the string to the debugger as well */
+ vsprintf( buf, fmt, ap );
+ OutputDebugStringA( buf );
+diff --git a/builds/windows/ftver.rc b/builds/windows/ftver.rc
+new file mode 100644
+index 0000000000..5dcd4a6ca3
+--- /dev/null
++++ b/builds/windows/ftver.rc
+@@ -0,0 +1,43 @@
++#include<Windows.h>
++
++#define FT_VERSION 2,8,1,0
++#define FT_VERSION_STR "2.8.1"
++
++VS_VERSION_INFO VERSIONINFO
++FILEVERSION FT_VERSION
++PRODUCTVERSION FT_VERSION
++FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
++#ifdef _DEBUG
++FILEFLAGS VS_FF_DEBUG
++#endif
++#ifdef _DLL
++FILETYPE VFT_DLL
++#define FT_FILENAME "freetype.dll"
++#else
++FILETYPE VFT_STATIC_LIB
++#define FT_FILENAME "freetype.lib"
++#endif
++BEGIN
++ BLOCK "StringFileInfo"
++ BEGIN
++ BLOCK "040904E4"
++ BEGIN
++ VALUE "CompanyName", "The FreeType Project"
++ VALUE "FileDescription", "Font Rendering Library"
++ VALUE "FileVersion", FT_VERSION_STR
++ VALUE "ProductName", "FreeType"
++ VALUE "ProductVersion", FT_VERSION_STR
++ VALUE "LegalCopyright", "© 2017 The FreeType Project www.freetype.org. All rights reserved."
++ VALUE "InternalName", "freetype"
++ VALUE "OriginalFilename", FT_FILENAME
++ END
++ END
++
++ BLOCK "VarFileInfo"
++ BEGIN
++ /* The following line should only be modified for localized versions. */
++ /* It consists of any number of WORD,WORD pairs, with each pair */
++ /* describing a "language,codepage" combination supported by the file. */
++ VALUE "Translation", 0x409, 1252
++ END
++END
+diff --git a/builds/windows/vc2010/freetype.vcxproj b/builds/windows/vc2010/freetype.vcxproj
+index 5d8182e790..93e755acc5 100644
+--- a/builds/windows/vc2010/freetype.vcxproj
++++ b/builds/windows/vc2010/freetype.vcxproj
+@@ -9,20 +9,12 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+- <ProjectConfiguration Include="Debug Multithreaded|Win32">
+- <Configuration>Debug Multithreaded</Configuration>
++ <ProjectConfiguration Include="Debug Static|Win32">
++ <Configuration>Debug Static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+- <ProjectConfiguration Include="Debug Multithreaded|x64">
+- <Configuration>Debug Multithreaded</Configuration>
+- <Platform>x64</Platform>
+- </ProjectConfiguration>
+- <ProjectConfiguration Include="Debug Singlethreaded|Win32">
+- <Configuration>Debug Singlethreaded</Configuration>
+- <Platform>Win32</Platform>
+- </ProjectConfiguration>
+- <ProjectConfiguration Include="Debug Singlethreaded|x64">
+- <Configuration>Debug Singlethreaded</Configuration>
++ <ProjectConfiguration Include="Debug Static|x64">
++ <Configuration>Debug Static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+@@ -33,20 +25,12 @@
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+- <ProjectConfiguration Include="Release Multithreaded|Win32">
+- <Configuration>Release Multithreaded</Configuration>
+- <Platform>Win32</Platform>
+- </ProjectConfiguration>
+- <ProjectConfiguration Include="Release Multithreaded|x64">
+- <Configuration>Release Multithreaded</Configuration>
+- <Platform>x64</Platform>
+- </ProjectConfiguration>
+- <ProjectConfiguration Include="Release Singlethreaded|Win32">
+- <Configuration>Release Singlethreaded</Configuration>
++ <ProjectConfiguration Include="Release Static|Win32">
++ <Configuration>Release Static</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+- <ProjectConfiguration Include="Release Singlethreaded|x64">
+- <Configuration>Release Singlethreaded</Configuration>
++ <ProjectConfiguration Include="Release Static|x64">
++ <Configuration>Release Static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+@@ -77,153 +61,67 @@
+ End of: Switch the PlatformToolset based on the Visual Studio Version
+ -->
+ <PropertyGroup Label="Globals">
+- <ProjectGuid>{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}</ProjectGuid>
++ <ProjectGuid>{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}</ProjectGuid>
++ <RootNamespace>FreeType</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'" Label="Configuration">
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'" Label="Configuration">
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
+- </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
+- <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
+- </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
+- <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'" Label="Configuration">
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'" Label="Configuration">
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
+- </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
+- <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
+- </PropertyGroup>
+- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'" Label="Configuration">
+- <ConfigurationType>StaticLibrary</ConfigurationType>
+- <UseOfMfc>false</UseOfMfc>
+- <CharacterSet>MultiByte</CharacterSet>
++ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <PropertyGroup>
+- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\</OutDir>
+- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">.\..\..\..\objs\vc2010\$(Platform)\$(Configuration)\</IntDir>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'" />
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'" />
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'" />
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'" />
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'" />
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'" />
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'" />
+- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'" />
+- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'" />
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">freetype281d</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">freetype281d</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">freetype281MTd</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">freetype281MTd</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">freetype281STd</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">freetype281STd</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">freetype281</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">freetype281</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">freetype281MT</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">freetype281MT</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">freetype281ST</TargetName>
+- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">freetype281ST</TargetName>
++ <OutDir>..\..\..\objs\$(Platform)\</OutDir>
++ <IntDir>..\..\..\objs\$(Platform)\$(Configuration)\</IntDir>
++ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRules />
++ <CodeAnalysisRuleAssemblies />
++ <TargetName>freetype</TargetName>
+ </PropertyGroup>
+ <Import Project="$(SolutionDir)\freetype.user.props" Condition="exists('$(SolutionDir)\freetype.user.props')" Label="UserProperties" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <DisableLanguageExtensions>true</DisableLanguageExtensions>
+@@ -237,7 +135,7 @@
+ <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
+ </ClCompile>
+ <ResourceCompile>
+- <PreprocessorDefinitions>_DEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>_DEBUG;_DLL;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Lib>
+@@ -251,7 +149,7 @@
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <DisableLanguageExtensions>true</DisableLanguageExtensions>
+@@ -265,67 +163,7 @@
+ <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
+ </ClCompile>
+ <ResourceCompile>
+- <PreprocessorDefinitions>_DEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Culture>0x0409</Culture>
+- </ResourceCompile>
+- <Lib>
+- <SuppressStartupBanner>true</SuppressStartupBanner>
+- <TargetMachine>MachineX64</TargetMachine>
+- <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+- <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+- </Lib>
+- </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">
+- <ClCompile>
+- <Optimization>Disabled</Optimization>
+- <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessToFile>false</PreprocessToFile>
+- <PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
+- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+- <DisableLanguageExtensions>true</DisableLanguageExtensions>
+- <WarningLevel>Level4</WarningLevel>
+- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+- <CompileAs>Default</CompileAs>
+- <DisableSpecificWarnings>4001</DisableSpecificWarnings>
+- <MultiProcessorCompilation>true</MultiProcessorCompilation>
+- <CompileAsManaged>false</CompileAsManaged>
+- <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
+- <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
+- </ClCompile>
+- <ResourceCompile>
+- <PreprocessorDefinitions>_DEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Culture>0x0409</Culture>
+- </ResourceCompile>
+- <Lib>
+- <SuppressStartupBanner>true</SuppressStartupBanner>
+- <TargetMachine>MachineX86</TargetMachine>
+- <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+- <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+- </Lib>
+- </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">
+- <ClCompile>
+- <Optimization>Disabled</Optimization>
+- <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessToFile>false</PreprocessToFile>
+- <PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
+- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+- <DisableLanguageExtensions>true</DisableLanguageExtensions>
+- <WarningLevel>Level4</WarningLevel>
+- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+- <CompileAs>Default</CompileAs>
+- <DisableSpecificWarnings>4001</DisableSpecificWarnings>
+- <MultiProcessorCompilation>true</MultiProcessorCompilation>
+- <CompileAsManaged>false</CompileAsManaged>
+- <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
+- <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
+- </ClCompile>
+- <ResourceCompile>
+- <PreprocessorDefinitions>_DEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>_DEBUG;_DLL;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Lib>
+@@ -335,11 +173,11 @@
+ <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <DisableLanguageExtensions>true</DisableLanguageExtensions>
+@@ -363,11 +201,11 @@
+ <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>_DEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <DisableLanguageExtensions>true</DisableLanguageExtensions>
+@@ -393,10 +231,10 @@
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+- <Optimization>Full</Optimization>
++ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+@@ -420,7 +258,7 @@
+ <OmitFramePointers>true</OmitFramePointers>
+ </ClCompile>
+ <ResourceCompile>
+- <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>NDEBUG;_DLL;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Lib>
+@@ -433,10 +271,10 @@
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+- <Optimization>Full</Optimization>
++ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+@@ -460,7 +298,7 @@
+ <OmitFramePointers>true</OmitFramePointers>
+ </ClCompile>
+ <ResourceCompile>
+- <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>NDEBUG;_DLL;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Lib>
+@@ -471,12 +309,12 @@
+ <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
+ <ClCompile>
+- <Optimization>Full</Optimization>
++ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+@@ -512,12 +350,12 @@
+ <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'">
+ <ClCompile>
+- <Optimization>Full</Optimization>
++ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+@@ -553,634 +391,25 @@
+ <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">
+- <ClCompile>
+- <Optimization>Full</Optimization>
+- <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+- <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <StringPooling>true</StringPooling>
+- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+- <FunctionLevelLinking>true</FunctionLevelLinking>
+- <DisableLanguageExtensions>true</DisableLanguageExtensions>
+- <WarningLevel>Level4</WarningLevel>
+- <CompileAs>Default</CompileAs>
+- <DisableSpecificWarnings>4001</DisableSpecificWarnings>
+- <MultiProcessorCompilation>true</MultiProcessorCompilation>
+- <WholeProgramOptimization>false</WholeProgramOptimization>
+- <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+- <FloatingPointExceptions>false</FloatingPointExceptions>
+- <CreateHotpatchableImage>false</CreateHotpatchableImage>
+- <CompileAsManaged>false</CompileAsManaged>
+- <ProgramDataBaseFileName>
+- </ProgramDataBaseFileName>
+- <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+- <DebugInformationFormat>
+- </DebugInformationFormat>
+- <IntrinsicFunctions>true</IntrinsicFunctions>
+- <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+- <OmitFramePointers>true</OmitFramePointers>
+- </ClCompile>
+- <ResourceCompile>
+- <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Culture>0x0409</Culture>
+- </ResourceCompile>
+- <Lib />
+- <Lib>
+- <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+- <TargetMachine>MachineX86</TargetMachine>
+- <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+- <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+- </Lib>
+- </ItemDefinitionGroup>
+- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">
+- <ClCompile>
+- <Optimization>Full</Optimization>
+- <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+- <AdditionalIncludeDirectories>$(UserOptionDirectory);..\..\..\include;$(UserIncludeDirectories);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions>NDEBUG;WIN32;_LIB;_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <StringPooling>true</StringPooling>
+- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+- <FunctionLevelLinking>true</FunctionLevelLinking>
+- <DisableLanguageExtensions>true</DisableLanguageExtensions>
+- <WarningLevel>Level4</WarningLevel>
+- <CompileAs>Default</CompileAs>
+- <DisableSpecificWarnings>4001</DisableSpecificWarnings>
+- <MultiProcessorCompilation>true</MultiProcessorCompilation>
+- <WholeProgramOptimization>false</WholeProgramOptimization>
+- <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+- <FloatingPointExceptions>false</FloatingPointExceptions>
+- <CreateHotpatchableImage>false</CreateHotpatchableImage>
+- <CompileAsManaged>false</CompileAsManaged>
+- <ProgramDataBaseFileName>
+- </ProgramDataBaseFileName>
+- <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+- <DebugInformationFormat>
+- </DebugInformationFormat>
+- <IntrinsicFunctions>true</IntrinsicFunctions>
+- <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+- <OmitFramePointers>true</OmitFramePointers>
+- </ClCompile>
+- <ResourceCompile>
+- <PreprocessorDefinitions>NDEBUG;$(UserDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Culture>0x0409</Culture>
+- </ResourceCompile>
+- <Lib />
+- <Lib>
+- <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
+- <TargetMachine>MachineX64</TargetMachine>
+- <AdditionalLibraryDirectories>$(UserLibraryDirectories);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+- <AdditionalDependencies>$(UserDependencies);%(AdditionalDependencies)</AdditionalDependencies>
+- </Lib>
+- </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\autofit\autofit.c" />
+- <ClCompile Include="..\..\..\src\bdf\bdf.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\cff\cff.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\base\ftbase.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
++ <ClCompile Include="..\..\..\src\bdf\bdf.c" />
++ <ClCompile Include="..\..\..\src\cff\cff.c" />
++ <ClCompile Include="..\..\..\src\base\ftbase.c" />
+ <ClCompile Include="..\..\..\src\base\ftbitmap.c" />
+- <ClCompile Include="..\..\..\src\cache\ftcache.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\ftdebug.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">false</DisableLanguageExtensions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">false</DisableLanguageExtensions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">false</DisableLanguageExtensions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">false</DisableLanguageExtensions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">false</DisableLanguageExtensions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">false</DisableLanguageExtensions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">false</DisableLanguageExtensions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">false</DisableLanguageExtensions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
+- <DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
+- </ClCompile>
++ <ClCompile Include="..\..\..\src\cache\ftcache.c" />
+ <ClCompile Include="..\..\..\src\base\ftfstype.c" />
+ <ClCompile Include="..\..\..\src\base\ftgasp.c" />
+- <ClCompile Include="..\..\..\src\base\ftglyph.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\gzip\ftgzip.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\base\ftinit.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\lzw\ftlzw.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
++ <ClCompile Include="..\..\..\src\base\ftglyph.c" />
++ <ClCompile Include="..\..\..\src\gzip\ftgzip.c" />
++ <ClCompile Include="..\..\..\src\base\ftinit.c" />
++ <ClCompile Include="..\..\..\src\lzw\ftlzw.c" />
+ <ClCompile Include="..\..\..\src\base\ftstroke.c" />
+- <ClCompile Include="..\..\..\src\base\ftsystem.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\smooth\smooth.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
++ <ClCompile Include="..\..\..\src\base\ftsystem.c" />
++ <ClCompile Include="..\..\..\src\smooth\smooth.c" />
+ <ClCompile Include="..\..\..\src\base\ftbbox.c" />
+ <ClCompile Include="..\..\..\src\base\ftfntfmt.c" />
+- <ClCompile Include="..\..\..\src\base\ftmm.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
++ <ClCompile Include="..\..\..\src\base\ftmm.c" />
+ <ClCompile Include="..\..\..\src\base\ftpfr.c" />
+ <ClCompile Include="..\..\..\src\base\ftsynth.c" />
+ <ClCompile Include="..\..\..\src\base\fttype1.c" />
+@@ -1189,544 +418,24 @@
+ <ClCompile Include="..\..\..\src\base\ftgxval.c" />
+ <ClCompile Include="..\..\..\src\base\ftotval.c" />
+ <ClCompile Include="..\..\..\src\base\ftpatent.c" />
+- <ClCompile Include="..\..\..\src\pcf\pcf.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\pfr\pfr.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\psaux\psaux.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\pshinter\pshinter.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\psnames\psmodule.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\raster\raster.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\sfnt\sfnt.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\truetype\truetype.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\type1\type1.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\cid\type1cid.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\type42\type42.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+- <ClCompile Include="..\..\..\src\winfonts\winfnt.c">
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Multithreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug Singlethreaded|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+- <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Multithreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Singlethreaded|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+- <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <ClCompile Include="..\..\..\src\pcf\pcf.c" />
++ <ClCompile Include="..\..\..\src\pfr\pfr.c" />
++ <ClCompile Include="..\..\..\src\psaux\psaux.c" />
++ <ClCompile Include="..\..\..\src\pshinter\pshinter.c" />
++ <ClCompile Include="..\..\..\src\psnames\psmodule.c" />
++ <ClCompile Include="..\..\..\src\raster\raster.c" />
++ <ClCompile Include="..\..\..\src\sfnt\sfnt.c" />
++ <ClCompile Include="..\..\..\src\truetype\truetype.c" />
++ <ClCompile Include="..\..\..\src\type1\type1.c" />
++ <ClCompile Include="..\..\..\src\cid\type1cid.c" />
++ <ClCompile Include="..\..\..\src\type42\type42.c" />
++ <ClCompile Include="..\..\..\src\winfonts\winfnt.c" />
++ <ClCompile Include="..\ftdebug.c">
++ <DisableLanguageExtensions>false</DisableLanguageExtensions>
+ </ClCompile>
+- </ItemGroup>
+- <ItemGroup>
+- <ClInclude Include="..\..\..\include\ft2build.h" />
+- <ClInclude Include="..\..\..\include\freetype\config\ftconfig.h" />
+- <ClInclude Include="..\..\..\include\freetype\config\ftheader.h" />
+- <ClInclude Include="..\..\..\include\freetype\config\ftmodule.h" />
+- <ClInclude Include="..\..\..\include\freetype\config\ftoption.h" />
+- <ClInclude Include="..\..\..\include\freetype\config\ftstdlib.h" />
++ <ResourceCompile Include="..\ftver.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+-</Project>
+\ No newline at end of file
++</Project>
+diff --git a/devel/ftoption.h b/devel/ftoption.h
+index 9f9cac1290..21af1cd636 100644
+--- a/devel/ftoption.h
++++ b/devel/ftoption.h
+@@ -268,48 +268,6 @@ FT_BEGIN_HEADER
+ #define FT_CONFIG_OPTION_USE_HARFBUZZ
+
+
+- /*************************************************************************/
+- /* */
+- /* DLL export compilation */
+- /* */
+- /* When compiling FreeType as a DLL, some systems/compilers need a */
+- /* special keyword in front OR after the return type of function */
+- /* declarations. */
+- /* */
+- /* Two macros are used within the FreeType source code to define */
+- /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */
+- /* */
+- /* FT_EXPORT( return_type ) */
+- /* */
+- /* is used in a function declaration, as in */
+- /* */
+- /* FT_EXPORT( FT_Error ) */
+- /* FT_Init_FreeType( FT_Library* alibrary ); */
+- /* */
+- /* */
+- /* FT_EXPORT_DEF( return_type ) */
+- /* */
+- /* is used in a function definition, as in */
+- /* */
+- /* FT_EXPORT_DEF( FT_Error ) */
+- /* FT_Init_FreeType( FT_Library* alibrary ) */
+- /* { */
+- /* ... some code ... */
+- /* return FT_Err_Ok; */
+- /* } */
+- /* */
+- /* You can provide your own implementation of FT_EXPORT and */
+- /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */
+- /* will be later automatically defined as `extern return_type' to */
+- /* allow normal compilation. */
+- /* */
+- /* Do not #undef these macros here since the build system might define */
+- /* them for certain configurations only. */
+- /* */
+-/* #define FT_EXPORT(x) extern x */
+-/* #define FT_EXPORT_DEF(x) x */
+-
+-
+ /*************************************************************************/
+ /* */
+ /* Glyph Postscript Names handling */
+@@ -786,6 +744,16 @@ FT_BEGIN_HEADER
+ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT
+
+
++ /*************************************************************************/
++ /* */
++ /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */
++ /* engine gets compiled into FreeType. If defined, it is possible to */
++ /* switch between the two engines using the `hinting-engine' property of */
++ /* the type1 driver module. */
++ /* */
++#define T1_CONFIG_OPTION_OLD_ENGINE
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+diff --git a/docs/CHANGES b/docs/CHANGES
+index 510da893cb..d81c40f8db 100644
+--- a/docs/CHANGES
++++ b/docs/CHANGES
+@@ -15,12 +15,12 @@ CHANGES BETWEEN 2.8 and 2.8.1
+
+ II. IMPORTANT CHANGES
+
+- - By default, FreeType now offers high quality LCD-optimized
+- output without resorting to ClearType techniques of resolution
+- tripling and filtering. In this method, called Harmony, each
+- color channel is generated separately after shifting the glyph
+- outline, capitalizing on the fact that the color grids on LCD
+- panels are shifted by a third of a pixel. This output is
++ - By default, FreeType now offers high quality LCD-optimized
++ output without resorting to ClearType techniques of resolution
++ tripling and filtering. In this method, called Harmony, each
++ color channel is generated separately after shifting the glyph
++ outline, capitalizing on the fact that the color grids on LCD
++ panels are shifted by a third of a pixel. This output is
+ indistinguishable from ClearType with a light 3-tap filter.
+
+
+@@ -67,16 +67,16 @@ CHANGES BETWEEN 2.8 and 2.8.1
+ were no error or problem reports either it seems that it is no
+ longer needed.
+
+- - The `ftgrid' demo program can now toggle the display of grid lines
+- with the `G' key.
++ - The `ftgrid' demo program can now toggle the display of grid
++ lines with the `G' key.
+
+- - The `ftgrid' demo program can toggle a different set of colors
++ - The `ftgrid' demo program can toggle a different set of colors
+ (suitable to color-blind people) with the `C' key.
+
+- - The `ftgrid' demo program now supports the `-e' command line option
+- to select a cmap.
++ - The `ftgrid' demo program now supports the `-e' command line
++ option to select a cmap.
+
+- - The `ftdump' demo program has a new command line option `-t' to
++ - The `ftdump' demo program has a new command line option `-t' to
+ output the SFNT table list.
+
+
+diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h
+index 889aebf5ab..6967b5fb74 100644
+--- a/include/freetype/config/ftconfig.h
++++ b/include/freetype/config/ftconfig.h
+@@ -73,11 +73,11 @@ FT_BEGIN_HEADER
+
+ /* The size of an `int' type. */
+ #if FT_UINT_MAX == 0xFFFFUL
+-#define FT_SIZEOF_INT (16 / FT_CHAR_BIT)
++#define FT_SIZEOF_INT ( 16 / FT_CHAR_BIT )
+ #elif FT_UINT_MAX == 0xFFFFFFFFUL
+-#define FT_SIZEOF_INT (32 / FT_CHAR_BIT)
++#define FT_SIZEOF_INT ( 32 / FT_CHAR_BIT )
+ #elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
+-#define FT_SIZEOF_INT (64 / FT_CHAR_BIT)
++#define FT_SIZEOF_INT ( 64 / FT_CHAR_BIT )
+ #else
+ #error "Unsupported size of `int' type!"
+ #endif
+@@ -85,11 +85,11 @@ FT_BEGIN_HEADER
+ /* The size of a `long' type. A five-byte `long' (as used e.g. on the */
+ /* DM642) is recognized but avoided. */
+ #if FT_ULONG_MAX == 0xFFFFFFFFUL
+-#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT)
++#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
+ #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
+-#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT)
++#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
+ #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
+-#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT)
++#define FT_SIZEOF_LONG ( 64 / FT_CHAR_BIT )
+ #else
+ #error "Unsupported size of `long' type!"
+ #endif
+@@ -236,12 +236,12 @@ FT_BEGIN_HEADER
+
+ #endif
+
+-#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT)
++#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_UInt32;
+
+-#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT)
++#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_UInt32;
+@@ -252,12 +252,12 @@ FT_BEGIN_HEADER
+
+
+ /* look up an integer type that is at least 32 bits */
+-#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT)
++#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
+
+ typedef int FT_Fast;
+ typedef unsigned int FT_UFast;
+
+-#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT)
++#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
+
+ typedef long FT_Fast;
+ typedef unsigned long FT_UFast;
+@@ -267,7 +267,7 @@ FT_BEGIN_HEADER
+
+ /* determine whether we have a 64-bit int type for platforms without */
+ /* Autoconf */
+-#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT)
++#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
+
+ /* FT_LONG64 must be defined if a 64-bit type is available */
+ #define FT_LONG64
+@@ -408,9 +408,40 @@ FT_BEGIN_HEADER
+ #endif /* !FT_BASE_DEF */
+
+
++ /* When compiling FreeType as a DLL, some systems/compilers need a */
++ /* special attribute in front OR after the return type of function */
++ /* declarations. */
++ /* */
++ /* Two macros are used within the FreeType source code to define */
++ /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */
++ /* */
++ /* FT_EXPORT( return_type ) */
++ /* */
++ /* is used in a function declaration, as in */
++ /* */
++ /* FT_EXPORT( FT_Error ) */
++ /* FT_Init_FreeType( FT_Library* alibrary ); */
++ /* */
++ /* */
++ /* FT_EXPORT_DEF( return_type ) */
++ /* */
++ /* is used in a function definition, as in */
++ /* */
++ /* FT_EXPORT_DEF( FT_Error ) */
++ /* FT_Init_FreeType( FT_Library* alibrary ) */
++ /* { */
++ /* ... some code ... */
++ /* return FT_Err_Ok; */
++ /* } */
++ /* */
++ /* You can provide your own implementation of FT_EXPORT and */
++ /* FT_EXPORT_DEF here if you want. */
++ /* */
+ #ifndef FT_EXPORT
+
+-#ifdef __cplusplus
++#if defined( _DLL )
++#define FT_EXPORT( x ) __declspec( dllexport ) x
++#elif defined( __cplusplus )
+ #define FT_EXPORT( x ) extern "C" x
+ #else
+ #define FT_EXPORT( x ) extern x
+@@ -421,7 +452,9 @@ FT_BEGIN_HEADER
+
+ #ifndef FT_EXPORT_DEF
+
+-#ifdef __cplusplus
++#if defined( _DLL )
++#define FT_EXPORT_DEF( x ) __declspec( dllexport ) x
++#elif defined( __cplusplus )
+ #define FT_EXPORT_DEF( x ) extern "C" x
+ #else
+ #define FT_EXPORT_DEF( x ) extern x
+diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h
+index d491af57c3..ce3b7eeb6e 100644
+--- a/include/freetype/config/ftheader.h
++++ b/include/freetype/config/ftheader.h
+@@ -367,6 +367,19 @@
+ #define FT_PCF_DRIVER_H <freetype/ftpcfdrv.h>
+
+
++ /*************************************************************************
++ *
++ * @macro:
++ * FT_TYPE1_DRIVER_H
++ *
++ * @description:
++ * A macro used in #include statements to name the file containing
++ * structures and macros related to the Type~1 driver module.
++ *
++ */
++#define FT_TYPE1_DRIVER_H <freetype/ftt1drv.h>
++
++
+ /*************************************************************************
+ *
+ * @macro:
+diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
+index 2fbe80b9b4..3d5e5a453a 100644
+--- a/include/freetype/config/ftoption.h
++++ b/include/freetype/config/ftoption.h
+@@ -75,7 +75,7 @@ FT_BEGIN_HEADER
+ /*************************************************************************/
+
+
+- /*************************************************************************/
++ /*#***********************************************************************/
+ /* */
+ /* If you enable this configuration option, FreeType recognizes an */
+ /* environment variable called `FREETYPE_PROPERTIES', which can be used */
+@@ -268,48 +268,6 @@ FT_BEGIN_HEADER
+ /* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+
+- /*************************************************************************/
+- /* */
+- /* DLL export compilation */
+- /* */
+- /* When compiling FreeType as a DLL, some systems/compilers need a */
+- /* special keyword in front OR after the return type of function */
+- /* declarations. */
+- /* */
+- /* Two macros are used within the FreeType source code to define */
+- /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */
+- /* */
+- /* FT_EXPORT( return_type ) */
+- /* */
+- /* is used in a function declaration, as in */
+- /* */
+- /* FT_EXPORT( FT_Error ) */
+- /* FT_Init_FreeType( FT_Library* alibrary ); */
+- /* */
+- /* */
+- /* FT_EXPORT_DEF( return_type ) */
+- /* */
+- /* is used in a function definition, as in */
+- /* */
+- /* FT_EXPORT_DEF( FT_Error ) */
+- /* FT_Init_FreeType( FT_Library* alibrary ) */
+- /* { */
+- /* ... some code ... */
+- /* return FT_Err_Ok; */
+- /* } */
+- /* */
+- /* You can provide your own implementation of FT_EXPORT and */
+- /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */
+- /* will be later automatically defined as `extern return_type' to */
+- /* allow normal compilation. */
+- /* */
+- /* Do not #undef these macros here since the build system might define */
+- /* them for certain configurations only. */
+- /* */
+-/* #define FT_EXPORT(x) extern x */
+-/* #define FT_EXPORT_DEF(x) x */
+-
+-
+ /*************************************************************************/
+ /* */
+ /* Glyph Postscript Names handling */
+@@ -795,6 +753,16 @@ FT_BEGIN_HEADER
+ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT
+
+
++ /*************************************************************************/
++ /* */
++ /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */
++ /* engine gets compiled into FreeType. If defined, it is possible to */
++ /* switch between the two engines using the `hinting-engine' property of */
++ /* the type1 driver module. */
++ /* */
++/* #define T1_CONFIG_OPTION_OLD_ENGINE */
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
+index b0c261799a..b4e6627ea9 100644
+--- a/include/freetype/freetype.h
++++ b/include/freetype/freetype.h
+@@ -138,6 +138,7 @@ FT_BEGIN_HEADER
+ /* FT_FACE_FLAG_TRICKY */
+ /* FT_FACE_FLAG_KERNING */
+ /* FT_FACE_FLAG_MULTIPLE_MASTERS */
++ /* FT_FACE_FLAG_VARIATION */
+ /* FT_FACE_FLAG_GLYPH_NAMES */
+ /* FT_FACE_FLAG_EXTERNAL_STREAM */
+ /* FT_FACE_FLAG_HINTER */
+@@ -147,14 +148,16 @@ FT_BEGIN_HEADER
+ /* FT_HAS_KERNING */
+ /* FT_HAS_FIXED_SIZES */
+ /* FT_HAS_GLYPH_NAMES */
+- /* FT_HAS_MULTIPLE_MASTERS */
+ /* FT_HAS_COLOR */
++ /* FT_HAS_MULTIPLE_MASTERS */
+ /* */
+ /* FT_IS_SFNT */
+ /* FT_IS_SCALABLE */
+ /* FT_IS_FIXED_WIDTH */
+ /* FT_IS_CID_KEYED */
+ /* FT_IS_TRICKY */
++ /* FT_IS_NAMED_INSTANCE */
++ /* FT_IS_VARIATION */
+ /* */
+ /* FT_STYLE_FLAG_BOLD */
+ /* FT_STYLE_FLAG_ITALIC */
+@@ -888,34 +891,42 @@ FT_BEGIN_HEADER
+ /* are set to~0 if there is only one face in */
+ /* the font file. */
+ /* */
+- /* Bits 16-30 are relevant to GX and OpenType */
+- /* variation fonts only, holding the named */
+- /* instance index for the current face index */
+- /* (starting with value~1; value~0 indicates */
+- /* font access without a named instance). For */
+- /* non-variation fonts, bits 16-30 are */
+- /* ignored. If we have the third named */
+- /* instance of face~4, say, `face_index' is */
+- /* set to 0x00030004. */
++ /* [Since 2.6.1] Bits 16-30 are relevant to GX */
++ /* and OpenType variation fonts only, holding */
++ /* the named instance index for the current */
++ /* face index (starting with value~1; value~0 */
++ /* indicates font access without a named */
++ /* instance). For non-variation fonts, bits */
++ /* 16-30 are ignored. If we have the third */
++ /* named instance of face~4, say, `face_index' */
++ /* is set to 0x00030004. */
+ /* */
+ /* Bit 31 is always zero (this is, */
+ /* `face_index' is always a positive value). */
+ /* */
++ /* [Since 2.8.2] Changing the design */
++ /* coordinates with */
++ /* @FT_Set_Var_Design_Coordinates or */
++ /* @FT_Set_Var_Blend_Coordinates does not */
++ /* influence the named instance index value */
++ /* (only @FT_Set_Named_Instance does that). */
++ /* */
+ /* face_flags :: A set of bit flags that give important */
+ /* information about the face; see */
+ /* @FT_FACE_FLAG_XXX for the details. */
+ /* */
+ /* style_flags :: The lower 16~bits contain a set of bit */
+ /* flags indicating the style of the face; see */
+- /* @FT_STYLE_FLAG_XXX for the details. Bits */
+- /* 16-30 hold the number of named instances */
+- /* available for the current face if we have a */
+- /* GX or OpenType variation (sub)font. Bit 31 */
+- /* is always zero (this is, `style_flags' is */
+- /* always a positive value). Note that a */
+- /* variation font has always at least one */
+- /* named instance, namely the default */
+- /* instance. */
++ /* @FT_STYLE_FLAG_XXX for the details. */
++ /* */
++ /* [Since 2.6.1] Bits 16-30 hold the number */
++ /* of named instances available for the */
++ /* current face if we have a GX or OpenType */
++ /* variation (sub)font. Bit 31 is always zero */
++ /* (this is, `style_flags' is always a */
++ /* positive value). Note that a variation */
++ /* font has always at least one named */
++ /* instance, namely the default instance. */
+ /* */
+ /* num_glyphs :: The number of glyphs in the face. If the */
+ /* face is scalable and has sbits (see */
+@@ -1052,6 +1063,9 @@ FT_BEGIN_HEADER
+ /* `descender', `height', `underline_position', and */
+ /* `underline_thickness'. */
+ /* */
++ /* Especially for TrueType fonts see also the documentation for */
++ /* @FT_Size_Metrics. */
++ /* */
+ typedef struct FT_FaceRec_
+ {
+ FT_Long num_faces;
+@@ -1212,8 +1226,15 @@ FT_BEGIN_HEADER
+ /* tricky fonts; they are hard-coded in file `ttobjs.c'. */
+ /* */
+ /* FT_FACE_FLAG_COLOR :: */
+- /* The face has color glyph tables. To access color glyphs use */
+- /* @FT_LOAD_COLOR. */
++ /* [Since 2.5.1] The face has color glyph tables. To access color */
++ /* glyphs use @FT_LOAD_COLOR. */
++ /* */
++ /* FT_FACE_FLAG_VARIATION :: */
++ /* [Since 2.8.2] Set if the current face (or named instance) has */
++ /* been altered with @FT_Set_MM_Design_Coordinates, */
++ /* @FT_Set_Var_Design_Coordinates, or */
++ /* @FT_Set_Var_Blend_Coordinates. This flag is unset by a call to */
++ /* @FT_Set_Named_Instance. */
+ /* */
+ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
+ #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
+@@ -1230,6 +1251,7 @@ FT_BEGIN_HEADER
+ #define FT_FACE_FLAG_CID_KEYED ( 1L << 12 )
+ #define FT_FACE_FLAG_TRICKY ( 1L << 13 )
+ #define FT_FACE_FLAG_COLOR ( 1L << 14 )
++#define FT_FACE_FLAG_VARIATION ( 1L << 15 )
+
+
+ /*************************************************************************
+@@ -1391,11 +1413,37 @@ FT_BEGIN_HEADER
+ * A macro that returns true whenever a face object is a named instance
+ * of a GX or OpenType variation font.
+ *
++ * [Since 2.8.2] Changing the design coordinates with
++ * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does
++ * not influence the return value of this macro (only
++ * @FT_Set_Named_Instance does that).
++ *
++ * @since:
++ * 2.7
++ *
+ */
+ #define FT_IS_NAMED_INSTANCE( face ) \
+ ( (face)->face_index & 0x7FFF0000L )
+
+
++ /*************************************************************************
++ *
++ * @macro:
++ * FT_IS_VARIATION( face )
++ *
++ * @description:
++ * A macro that returns true whenever a face object has been altered
++ * by @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or
++ * @FT_Set_Var_Blend_Coordinates.
++ *
++ * @since:
++ * 2.8.2
++ *
++ */
++#define FT_IS_VARIATION( face ) \
++ ( (face)->face_flags & FT_FACE_FLAG_VARIATION )
++
++
+ /*************************************************************************
+ *
+ * @macro:
+@@ -1437,6 +1485,9 @@ FT_BEGIN_HEADER
+ * A macro that returns true whenever a face object contains
+ * tables for color glyphs.
+ *
++ * @since:
++ * 2.5.1
++ *
+ */
+ #define FT_HAS_COLOR( face ) \
+ ( (face)->face_flags & FT_FACE_FLAG_COLOR )
+@@ -1534,7 +1585,7 @@ FT_BEGIN_HEADER
+ /* to the following. */
+ /* */
+ /* { */
+- /* scaled_ascender = FT_MulFix( face->root.ascender, */
++ /* scaled_ascender = FT_MulFix( face->ascender, */
+ /* size_metrics->y_scale ); */
+ /* } */
+ /* */
+@@ -1548,6 +1599,43 @@ FT_BEGIN_HEADER
+ /* */
+ /* The `FT_Size_Metrics' structure is valid for bitmap fonts also. */
+ /* */
++ /* */
++ /* *TrueType* *fonts* *with* *native* *bytecode* *hinting* */
++ /* */
++ /* All applications that handle TrueType fonts with native hinting */
++ /* must be aware that TTFs expect different rounding of vertical font */
++ /* dimensions. The application has to cater for this, especially if */
++ /* it wants to rely on a TTF's vertical data (for example, to */
++ /* properly align box characters vertically). */
++ /* */
++ /* Only the application knows _in_ _advance_ that it is going to use */
++ /* native hinting for TTFs! FreeType, on the other hand, selects the */
++ /* hinting mode not at the time of creating an @FT_Size object but */
++ /* much later, namely while calling @FT_Load_Glyph. */
++ /* */
++ /* Here is some pseudo code that illustrates a possible solution. */
++ /* */
++ /* { */
++ /* font_format = FT_Get_Font_Format( face ); */
++ /* */
++ /* if ( !strcmp( font_format, "TrueType" ) && */
++ /* do_native_bytecode_hinting ) */
++ /* { */
++ /* ascender = ROUND( FT_MulFix( face->ascender, */
++ /* size_metrics->y_scale ) ); */
++ /* descender = ROUND( FT_MulFix( face->descender, */
++ /* size_metrics->y_scale ) ); */
++ /* } */
++ /* else */
++ /* { */
++ /* ascender = size_metrics->ascender; */
++ /* descender = size_metrics->descender; */
++ /* } */
++ /* */
++ /* height = size_metrics->height; */
++ /* max_advance = size_metrics->max_advance; */
++ /* } */
++ /* */
+ typedef struct FT_Size_Metrics_
+ {
+ FT_UShort x_ppem; /* horizontal pixels per EM */
+@@ -1689,17 +1777,13 @@ FT_BEGIN_HEADER
+ /* @FT_GLYPH_FORMAT_COMPOSITE, but other values */
+ /* are possible. */
+ /* */
+- /* bitmap :: This field is used as a bitmap descriptor */
+- /* when the slot format is */
+- /* @FT_GLYPH_FORMAT_BITMAP. Note that the */
+- /* address and content of the bitmap buffer can */
+- /* change between calls of @FT_Load_Glyph and a */
+- /* few other functions. */
++ /* bitmap :: This field is used as a bitmap descriptor. */
++ /* Note that the address and content of the */
++ /* bitmap buffer can change between calls of */
++ /* @FT_Load_Glyph and a few other functions. */
+ /* */
+ /* bitmap_left :: The bitmap's left bearing expressed in */
+- /* integer pixels. Only valid if the format is */
+- /* @FT_GLYPH_FORMAT_BITMAP, this is, if the */
+- /* glyph slot contains a bitmap. */
++ /* integer pixels. */
+ /* */
+ /* bitmap_top :: The bitmap's top bearing expressed in integer */
+ /* pixels. This is the distance from the */
+@@ -1746,7 +1830,9 @@ FT_BEGIN_HEADER
+ /* If @FT_Load_Glyph is called with default flags (see */
+ /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */
+ /* its native format (e.g., an outline glyph for TrueType and Type~1 */
+- /* formats). */
++ /* formats). [Since 2.8.2] The prospective bitmap metrics are */
++ /* calculated according to @FT_LOAD_TARGET_XXX and other flags even */
++ /* for the outline glyph, even if @FT_LOAD_RENDER is not set. */
+ /* */
+ /* This image can later be converted into a bitmap by calling */
+ /* @FT_Render_Glyph. This function searches the current renderer for */
+@@ -2155,14 +2241,14 @@ FT_BEGIN_HEADER
+ /* with value~0). Set it to~0 if there is only one */
+ /* face in the font file. */
+ /* */
+- /* Bits 16-30 are relevant to GX and OpenType variation */
+- /* fonts only, specifying the named instance index for */
+- /* the current face index (starting with value~1; */
+- /* value~0 makes FreeType ignore named instances). For */
+- /* non-variation fonts, bits 16-30 are ignored. */
+- /* Assuming that you want to access the third named */
+- /* instance in face~4, `face_index' should be set to */
+- /* 0x00030004. If you want to access face~4 without */
++ /* [Since 2.6.1] Bits 16-30 are relevant to GX and */
++ /* OpenType variation fonts only, specifying the named */
++ /* instance index for the current face index (starting */
++ /* with value~1; value~0 makes FreeType ignore named */
++ /* instances). For non-variation fonts, bits 16-30 are */
++ /* ignored. Assuming that you want to access the third */
++ /* named instance in face~4, `face_index' should be set */
++ /* to 0x00030004. If you want to access face~4 without */
+ /* variation handling, simply set `face_index' to */
+ /* value~4. */
+ /* */
+@@ -2869,26 +2955,26 @@ FT_BEGIN_HEADER
+ * Disable the auto-hinter. See also the note below.
+ *
+ * FT_LOAD_COLOR ::
+- * Load embedded color bitmap images. The resulting color bitmaps,
+- * if available, will have the @FT_PIXEL_MODE_BGRA format. If the
+- * flag is not set and color bitmaps are found, they are converted
+- * to 256-level gray bitmaps transparently, using the
++ * [Since 2.5] Load embedded color bitmap images. The resulting color
++ * bitmaps, if available, will have the @FT_PIXEL_MODE_BGRA format.
++ * If the flag is not set and color bitmaps are found, they are
++ * converted to 256-level gray bitmaps transparently, using the
+ * @FT_PIXEL_MODE_GRAY format.
+ *
+ * FT_LOAD_COMPUTE_METRICS ::
+- * Compute glyph metrics from the glyph data, without the use of
+- * bundled metrics tables (for example, the `hdmx' table in TrueType
+- * fonts). This flag is mainly used by font validating or font
+- * editing applications, which need to ignore, verify, or edit those
+- * tables.
++ * [Since 2.6.1] Compute glyph metrics from the glyph data, without
++ * the use of bundled metrics tables (for example, the `hdmx' table in
++ * TrueType fonts). This flag is mainly used by font validating or
++ * font editing applications, which need to ignore, verify, or edit
++ * those tables.
+ *
+ * Currently, this flag is only implemented for TrueType fonts.
+ *
+ * FT_LOAD_BITMAP_METRICS_ONLY ::
+- * Request loading of the metrics and bitmap image information of a
+- * (possibly embedded) bitmap glyph without allocating or copying
+- * the bitmap image data itself. No effect if the target glyph is
+- * not a bitmap image.
++ * [Since 2.7.1] Request loading of the metrics and bitmap image
++ * information of a (possibly embedded) bitmap glyph without
++ * allocating or copying the bitmap image data itself. No effect if
++ * the target glyph is not a bitmap image.
+ *
+ * This flag unsets @FT_LOAD_RENDER.
+ *
+@@ -3473,6 +3559,13 @@ FT_BEGIN_HEADER
+ /* */
+ /* http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5902.AdobePSNameGeneration.html */
+ /* */
++ /* [Since 2.8.2] Special PostScript names for named instances are */
++ /* only returned if the named instance is set with */
++ /* @FT_Set_Named_Instance (and the font has corresponding entries in */
++ /* its `fvar' table). If @FT_IS_VARIATION returns true, the */
++ /* algorithmically derived PostScript name is provided, not looking */
++ /* up special entries for named instances. */
++ /* */
+ FT_EXPORT( const char* )
+ FT_Get_Postscript_Name( FT_Face face );
+
+@@ -3775,6 +3868,9 @@ FT_BEGIN_HEADER
+ * FT_Face_Properties( face, 1, &property );
+ * }
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ FT_EXPORT( FT_Error )
+ FT_Face_Properties( FT_Face face,
+diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h
+index 2bb675ae46..60fadea4bd 100644
+--- a/include/freetype/ftautoh.h
++++ b/include/freetype/ftautoh.h
+@@ -106,6 +106,9 @@ FT_BEGIN_HEADER
+ * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT );
+ * }
+ *
++ * @since:
++ * 2.4.11
++ *
+ */
+
+
+@@ -227,6 +230,9 @@ FT_BEGIN_HEADER
+ * Note that currently Indic support is rudimentary only, missing blue
+ * zone support.
+ *
++ * @since:
++ * 2.4.11
++ *
+ */
+ #define FT_AUTOHINTER_SCRIPT_NONE 0
+ #define FT_AUTOHINTER_SCRIPT_LATIN 1
+@@ -244,6 +250,9 @@ FT_BEGIN_HEADER
+ *
+ * The data exchange structure for the @glyph-to-script-map property.
+ *
++ * @since:
++ * 2.4.11
++ *
+ */
+ typedef struct FT_Prop_GlyphToScriptMap_
+ {
+@@ -289,6 +298,9 @@ FT_BEGIN_HEADER
+ * an @FT_Face structure but not loaded any glyph (using the
+ * auto-hinter), a change of the fallback script will affect this face.
+ *
++ * @since:
++ * 2.4.11
++ *
+ */
+
+
+@@ -372,6 +384,9 @@ FT_BEGIN_HEADER
+ * Set this value right after calling @FT_Set_Char_Size, but before
+ * loading any glyph (using the auto-hinter).
+ *
++ * @since:
++ * 2.4.11
++ *
+ */
+
+
+@@ -480,6 +495,9 @@ FT_BEGIN_HEADER
+ * variable similar to the CFF driver. It can also be set per face
+ * using @FT_Face_Properties with @FT_PARAM_TAG_STEM_DARKENING.
+ *
++ * @since:
++ * 2.6.2
++ *
+ */
+
+
+@@ -499,6 +517,9 @@ FT_BEGIN_HEADER
+ * or autohinter honors it, which the CFF driver always does, but the
+ * autohinter only in `light' hinting mode (as of version 2.7.0).
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ #define FT_PARAM_TAG_STEM_DARKENING \
+ FT_MAKE_TAG( 'd', 'a', 'r', 'k' )
+@@ -519,6 +540,10 @@ FT_BEGIN_HEADER
+ *
+ * This property can be set via the `FREETYPE_PROPERTIES' environment
+ * variable similar to the CFF driver.
++ *
++ * @since:
++ * 2.6.2
++ *
+ */
+
+
+diff --git a/include/freetype/ftbitmap.h b/include/freetype/ftbitmap.h
+index 04b2402ad0..bb778cc0df 100644
+--- a/include/freetype/ftbitmap.h
++++ b/include/freetype/ftbitmap.h
+@@ -97,7 +97,7 @@ FT_BEGIN_HEADER
+ FT_EXPORT( FT_Error )
+ FT_Bitmap_Copy( FT_Library library,
+ const FT_Bitmap *source,
+- FT_Bitmap *target);
++ FT_Bitmap *target );
+
+
+ /*************************************************************************/
+diff --git a/include/freetype/ftcffdrv.h b/include/freetype/ftcffdrv.h
+index 477b6ddb18..f1e9452bf1 100644
+--- a/include/freetype/ftcffdrv.h
++++ b/include/freetype/ftcffdrv.h
+@@ -151,6 +151,9 @@ FT_BEGIN_HEADER
+ *
+ * This property can be set via the `FREETYPE_PROPERTIES' environment
+ * variable (using values `adobe' or `freetype').
++ *
++ * @since:
++ * 2.4.12
+ */
+
+
+@@ -170,6 +173,9 @@ FT_BEGIN_HEADER
+ * FT_CFF_HINTING_ADOBE ::
+ * Use the hinting engine contributed by Adobe.
+ *
++ * @since:
++ * 2.4.12
++ *
+ */
+ #define FT_CFF_HINTING_FREETYPE 0
+ #define FT_CFF_HINTING_ADOBE 1
+@@ -207,6 +213,9 @@ FT_BEGIN_HEADER
+ * It can also be set per face using @FT_Face_Properties with
+ * @FT_PARAM_TAG_STEM_DARKENING.
+ *
++ * @since:
++ * 2.4.12
++ *
+ */
+
+
+@@ -264,6 +273,10 @@ FT_BEGIN_HEADER
+ * FREETYPE_PROPERTIES=\
+ * cff:darkening-parameters=500,300,1000,200,1500,100,2000,0
+ * }
++ *
++ * @since:
++ * 2.5.1
++ *
+ */
+
+
+@@ -290,6 +303,9 @@ FT_BEGIN_HEADER
+ * variable. It can also be set per face using @FT_Face_Properties with
+ * @FT_PARAM_TAG_RANDOM_SEED.
+ *
++ * @since:
++ * 2.8
++ *
+ */
+
+
+@@ -304,6 +320,9 @@ FT_BEGIN_HEADER
+ * module's random seed value with a face-specific one; see
+ * @random-seed.
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ #define FT_PARAM_TAG_RANDOM_SEED \
+ FT_MAKE_TAG( 's', 'e', 'e', 'd' )
+diff --git a/include/freetype/ftcid.h b/include/freetype/ftcid.h
+index 4adcbeeda9..fb9b0c24ce 100644
+--- a/include/freetype/ftcid.h
++++ b/include/freetype/ftcid.h
+@@ -87,7 +87,7 @@ FT_BEGIN_HEADER
+ FT_Get_CID_Registry_Ordering_Supplement( FT_Face face,
+ const char* *registry,
+ const char* *ordering,
+- FT_Int *supplement);
++ FT_Int *supplement );
+
+
+ /**********************************************************************
+diff --git a/include/freetype/ftgxval.h b/include/freetype/ftgxval.h
+index f239c71eb1..97c493c961 100644
+--- a/include/freetype/ftgxval.h
++++ b/include/freetype/ftgxval.h
+@@ -101,15 +101,15 @@ FT_BEGIN_HEADER
+ * The number of tables checked in this module. Use it as a parameter
+ * for the `table-length' argument of function @FT_TrueTypeGX_Validate.
+ */
+-#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1)
++#define FT_VALIDATE_GX_LENGTH ( FT_VALIDATE_GX_LAST_INDEX + 1 )
+
+ /* */
+
+ /* Up to 0x1000 is used by otvalid.
+ Ox2xxx is reserved for feature OT extension. */
+-#define FT_VALIDATE_GX_START 0x4000
+-#define FT_VALIDATE_GX_BITFIELD( tag ) \
+- ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX )
++#define FT_VALIDATE_GX_START 0x4000
++#define FT_VALIDATE_GX_BITFIELD( tag ) \
++ ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX )
+
+
+ /**********************************************************************
+diff --git a/include/freetype/ftgzip.h b/include/freetype/ftgzip.h
+index bd5ceaab9f..ba54827689 100644
+--- a/include/freetype/ftgzip.h
++++ b/include/freetype/ftgzip.h
+@@ -129,6 +129,9 @@ FT_BEGIN_HEADER
+ * @note:
+ * This function may return `FT_Err_Unimplemented_Feature' if your build
+ * of FreeType was not compiled with zlib support.
++ *
++ * @since:
++ * 2.5.1
+ */
+ FT_EXPORT( FT_Error )
+ FT_Gzip_Uncompress( FT_Memory memory,
+diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
+index 1c789e5a44..968460895e 100644
+--- a/include/freetype/ftimage.h
++++ b/include/freetype/ftimage.h
+@@ -169,13 +169,13 @@ FT_BEGIN_HEADER
+ /* @FT_RENDER_MODE_LCD_V. */
+ /* */
+ /* FT_PIXEL_MODE_BGRA :: */
+- /* An image with four 8-bit channels per pixel, representing a */
+- /* color image (such as emoticons) with alpha channel. For each */
+- /* pixel, the format is BGRA, which means, the blue channel comes */
+- /* first in memory. The color channels are pre-multiplied and in */
+- /* the sRGB colorspace. For example, full red at half-translucent */
+- /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */
+- /* See also @FT_LOAD_COLOR. */
++ /* [Since 2.5] An image with four 8-bit channels per pixel, */
++ /* representing a color image (such as emoticons) with alpha */
++ /* channel. For each pixel, the format is BGRA, which means, the */
++ /* blue channel comes first in memory. The color channels are */
++ /* pre-multiplied and in the sRGB colorspace. For example, full */
++ /* red at half-translucent opacity will be represented as */
++ /* `00,00,80,80', not `00,00,FF,80'. See also @FT_LOAD_COLOR. */
+ /* */
+ typedef enum FT_Pixel_Mode_
+ {
+diff --git a/include/freetype/ftlcdfil.h b/include/freetype/ftlcdfil.h
+index bdaf9af906..df1d7ccfab 100644
+--- a/include/freetype/ftlcdfil.h
++++ b/include/freetype/ftlcdfil.h
+@@ -292,6 +292,9 @@ FT_BEGIN_HEADER
+ * the global default values or the values set up with
+ * @FT_Library_SetLcdFilterWeights.
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ #define FT_PARAM_TAG_LCD_FILTER_WEIGHTS \
+ FT_MAKE_TAG( 'l', 'c', 'd', 'f' )
+@@ -305,12 +308,36 @@ FT_BEGIN_HEADER
+ * A typedef for passing the five LCD filter weights to
+ * @FT_Face_Properties within an @FT_Parameter structure.
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ #define FT_LCD_FILTER_FIVE_TAPS 5
+
+ typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS];
+
+
++ FT_BASE( void )
++ ft_lcd_padding( FT_Pos* Min,
++ FT_Pos* Max,
++ FT_GlyphSlot slot );
++
++#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
++
++ typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
++ FT_Render_Mode render_mode,
++ FT_Byte* weights );
++
++
++ /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
++ FT_BASE( void )
++ ft_lcd_filter_fir( FT_Bitmap* bitmap,
++ FT_Render_Mode mode,
++ FT_LcdFiveTapFilter weights );
++
++#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
++
++
+ /* */
+
+
+diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h
+index 80ac98d612..49da79606e 100644
+--- a/include/freetype/ftmm.h
++++ b/include/freetype/ftmm.h
+@@ -323,9 +323,13 @@ FT_BEGIN_HEADER
+ /* FreeType error code. 0~means success. */
+ /* */
+ /* <Note> */
+- /* To reset all axes to the default values, call the function with */
+- /* `num_coords' set to zero and `coords' set to NULL (new feature in */
+- /* FreeType version 2.8.1). */
++ /* [Since 2.8.1] To reset all axes to the default values, call the */
++ /* function with `num_coords' set to zero and `coords' set to NULL. */
++ /* */
++ /* [Since 2.8.2] If `num_coords' is larger than zero, this function */
++ /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */
++ /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */
++ /* is zero, this bit flag gets unset. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FT_Set_MM_Design_Coordinates( FT_Face face,
+@@ -358,9 +362,15 @@ FT_BEGIN_HEADER
+ /* FreeType error code. 0~means success. */
+ /* */
+ /* <Note> */
+- /* To reset all axes to the default values, call the function with */
+- /* `num_coords' set to zero and `coords' set to NULL (new feature in */
+- /* FreeType version 2.8.1). */
++ /* [Since 2.8.1] To reset all axes to the default values, call the */
++ /* function with `num_coords' set to zero and `coords' set to NULL. */
++ /* [Since 2.8.2] `Default values' means the currently selected named */
++ /* instance (or the base font if no named instance is selected). */
++ /* */
++ /* [Since 2.8.2] If `num_coords' is larger than zero, this function */
++ /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */
++ /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */
++ /* is zero, this bit flag gets unset. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FT_Set_Var_Design_Coordinates( FT_Face face,
+@@ -392,6 +402,9 @@ FT_BEGIN_HEADER
+ /* <Return> */
+ /* FreeType error code. 0~means success. */
+ /* */
++ /* <Since> */
++ /* 2.7.1 */
++ /* */
+ FT_EXPORT( FT_Error )
+ FT_Get_Var_Design_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+@@ -427,9 +440,15 @@ FT_BEGIN_HEADER
+ /* FreeType error code. 0~means success. */
+ /* */
+ /* <Note> */
+- /* To reset all axes to the default values, call the function with */
+- /* `num_coords' set to zero and `coords' set to NULL (new feature in */
+- /* FreeType version 2.8.1). */
++ /* [Since 2.8.1] To reset all axes to the default values, call the */
++ /* function with `num_coords' set to zero and `coords' set to NULL. */
++ /* [Since 2.8.2] `Default values' means the currently selected named */
++ /* instance (or the base font if no named instance is selected). */
++ /* */
++ /* [Since 2.8.2] If `num_coords' is larger than zero, this function */
++ /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */
++ /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */
++ /* is zero, this bit flag gets unset. */
+ /* */
+ FT_EXPORT( FT_Error )
+ FT_Set_MM_Blend_Coordinates( FT_Face face,
+@@ -462,6 +481,9 @@ FT_BEGIN_HEADER
+ /* <Return> */
+ /* FreeType error code. 0~means success. */
+ /* */
++ /* <Since> */
++ /* 2.7.1 */
++ /* */
+ FT_EXPORT( FT_Error )
+ FT_Get_MM_Blend_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+@@ -490,6 +512,9 @@ FT_BEGIN_HEADER
+ /* <Description> */
+ /* This is another name of @FT_Get_MM_Blend_Coordinates. */
+ /* */
++ /* <Since> */
++ /* 2.7.1 */
++ /* */
+ FT_EXPORT( FT_Error )
+ FT_Get_Var_Blend_Coordinates( FT_Face face,
+ FT_UInt num_coords,
+@@ -509,6 +534,9 @@ FT_BEGIN_HEADER
+ /* FT_VAR_AXIS_FLAG_HIDDEN :: */
+ /* The variation axis should not be exposed to user interfaces. */
+ /* */
++ /* <Since> */
++ /* 2.8.1 */
++ /* */
+ #define FT_VAR_AXIS_FLAG_HIDDEN 1
+
+
+@@ -534,11 +562,51 @@ FT_BEGIN_HEADER
+ /* <Return> */
+ /* FreeType error code. 0~means success. */
+ /* */
++ /* <Since> */
++ /* 2.8.1 */
++ /* */
+ FT_EXPORT( FT_Error )
+ FT_Get_Var_Axis_Flags( FT_MM_Var* master,
+ FT_UInt axis_index,
+ FT_UInt* flags );
+
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* FT_Set_Named_Instance */
++ /* */
++ /* <Description> */
++ /* Set or change the current named instance. */
++ /* */
++ /* <Input> */
++ /* face :: A handle to the source face. */
++ /* */
++ /* instance_index :: The index of the requested instance, starting */
++ /* with value 1. If set to value 0, FreeType */
++ /* switches to font access without a named */
++ /* instance. */
++ /* */
++ /* <Return> */
++ /* FreeType error code. 0~means success. */
++ /* */
++ /* <Note> */
++ /* The function uses the value of `instance_index' to set bits 16-30 */
++ /* of the face's `face_index' field. It also resets any variation */
++ /* applied to the font, and the @FT_FACE_FLAG_VARIATION bit of the */
++ /* face's `face_flags' field gets reset to zero (i.e., */
++ /* @FT_IS_VARIATION will return false). */
++ /* */
++ /* For Adobe MM fonts (which don't have named instances) this */
++ /* function simply resets the current face to the default instance. */
++ /* */
++ /* <Since> */
++ /* 2.8.2 */
++ /* */
++ FT_EXPORT( FT_Error )
++ FT_Set_Named_Instance( FT_Face face,
++ FT_UInt instance_index );
++
+ /* */
+
+
+diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
+index 4147aadf8b..9c901329ac 100644
+--- a/include/freetype/ftmodapi.h
++++ b/include/freetype/ftmodapi.h
+@@ -475,6 +475,9 @@ FT_BEGIN_HEADER
+ /* <InOut> */
+ /* library :: A handle to a new library object. */
+ /* */
++ /* <Since> */
++ /* 2.8 */
++ /* */
+ FT_EXPORT( void )
+ FT_Set_Default_Properties( FT_Library library );
+
+diff --git a/include/freetype/ftpcfdrv.h b/include/freetype/ftpcfdrv.h
+index 6622c936fb..7f602991c5 100644
+--- a/include/freetype/ftpcfdrv.h
++++ b/include/freetype/ftpcfdrv.h
+@@ -69,7 +69,7 @@ FT_BEGIN_HEADER
+ * selecting `Fixed' in KDE or Gnome one gets results that appear rather
+ * random, the style changes often if one changes the size and one
+ * cannot select some fonts at all. The improve this situation, the PCF
+- * module prepends the foundry name (plus a space) to the family name.
++ * module prepends the foundry name (plus a space) to the family name.
+ * It also checks whether there are `wide' characters; all put together,
+ * family names like `Sony Fixed' or `Misc Fixed Wide' are constructed.
+ *
+@@ -93,6 +93,8 @@ FT_BEGIN_HEADER
+ * This property can be set via the `FREETYPE_PROPERTIES' environment
+ * variable (using values 1 and 0 for `on' and `off', respectively).
+ *
++ * @since:
++ * 2.8
+ */
+
+
+diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h
+index a316540576..d524ad74c7 100644
+--- a/include/freetype/ftsnames.h
++++ b/include/freetype/ftsnames.h
+@@ -189,6 +189,9 @@ FT_BEGIN_HEADER
+ /* Please refer to the TrueType or OpenType specification for more */
+ /* details. */
+ /* */
++ /* <Since> */
++ /* 2.8 */
++ /* */
+ typedef struct FT_SfntLangTag_
+ {
+ FT_Byte* string; /* this string is *not* null-terminated! */
+@@ -229,6 +232,9 @@ FT_BEGIN_HEADER
+ /* invalid format~1 language ID values, FT_Err_Invalid_Argument is */
+ /* returned. */
+ /* */
++ /* <Since> */
++ /* 2.8 */
++ /* */
+ FT_EXPORT( FT_Error )
+ FT_Get_Sfnt_LangTag( FT_Face face,
+ FT_UInt langID,
+@@ -246,6 +252,9 @@ FT_BEGIN_HEADER
+ * 1.4). Use this for backward compatibility with legacy systems that
+ * have a four-faces-per-family restriction.
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ #define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY \
+ FT_MAKE_TAG( 'i', 'g', 'p', 'f' )
+@@ -267,6 +276,9 @@ FT_BEGIN_HEADER
+ * 1.4). Use this for backward compatibility with legacy systems that
+ * have a four-faces-per-family restriction.
+ *
++ * @since:
++ * 2.8
++ *
+ */
+ #define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY \
+ FT_MAKE_TAG( 'i', 'g', 'p', 's' )
+diff --git a/include/freetype/ftt1drv.h b/include/freetype/ftt1drv.h
+new file mode 100644
+index 0000000000..e082f6b4a3
+--- /dev/null
++++ b/include/freetype/ftt1drv.h
+@@ -0,0 +1,123 @@
++/***************************************************************************/
++/* */
++/* ftt1drv.h */
++/* */
++/* FreeType API for controlling the Type 1 driver (specification only). */
++/* */
++/* Copyright 2017 by */
++/* David Turner, Robert Wilhelm, and Werner Lemberg. */
++/* */
++/* This file is part of the FreeType project, and may only be used, */
++/* modified, and distributed under the terms of the FreeType project */
++/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
++/* this file you indicate that you have read the license and */
++/* understand and accept it fully. */
++/* */
++/***************************************************************************/
++
++
++#ifndef FTT1DRV_H_
++#define FTT1DRV_H_
++
++#include <ft2build.h>
++#include FT_FREETYPE_H
++
++#ifdef FREETYPE_H
++#error "freetype.h of FreeType 1 has been loaded!"
++#error "Please fix the directory search order for header files"
++#error "so that freetype.h of FreeType 2 is found first."
++#endif
++
++
++FT_BEGIN_HEADER
++
++
++ /**************************************************************************
++ *
++ * @property:
++ * hinting-engine[type1]
++ *
++ * @description:
++ * Thanks to Adobe, which contributed a new hinting (and parsing)
++ * engine, an application can select between `freetype' and `adobe' if
++ * compiled with T1_CONFIG_OPTION_OLD_ENGINE. If this configuration
++ * macro isn't defined, `hinting-engine' does nothing.
++ *
++ * The default engine is `freetype' if T1_CONFIG_OPTION_OLD_ENGINE is
++ * defined, and `adobe' otherwise.
++ *
++ * The following example code demonstrates how to select Adobe's hinting
++ * engine (omitting the error handling).
++ *
++ * {
++ * FT_Library library;
++ * FT_UInt hinting_engine = FT_T1_HINTING_ADOBE;
++ *
++ *
++ * FT_Init_FreeType( &library );
++ *
++ * FT_Property_Set( library, "type1",
++ * "hinting-engine", &hinting_engine );
++ * }
++ *
++ * @note:
++ * This property can be used with @FT_Property_Get also.
++ *
++ * This property can be set via the `FREETYPE_PROPERTIES' environment
++ * variable (using values `adobe' or `freetype').
++ *
++ * @since:
++ * 2.8.2
++ *
++ */
++
++
++ /**************************************************************************
++ *
++ * @enum:
++ * FT_T1_HINTING_XXX
++ *
++ * @description:
++ * A list of constants used for the @hinting-engine[type1] property to
++ * select the hinting engine for Type 1 fonts.
++ *
++ * @values:
++ * FT_T1_HINTING_FREETYPE ::
++ * Use the old FreeType hinting engine.
++ *
++ * FT_T1_HINTING_ADOBE ::
++ * Use the hinting engine contributed by Adobe.
++ *
++ * @since:
++ * 2.8.2
++ *
++ */
++#define FT_T1_HINTING_FREETYPE 0
++#define FT_T1_HINTING_ADOBE 1
++
++
++ /**************************************************************************
++ *
++ * @constant:
++ * FT_PARAM_TAG_RANDOM_SEED
++ *
++ * @description:
++ * An @FT_Parameter tag to be used with @FT_Face_Properties. The
++ * corresponding 32bit signed integer argument overrides the CFF
++ * module's random seed value with a face-specific one; see
++ * @random-seed.
++ *
++ */
++#define FT_PARAM_TAG_RANDOM_SEED \
++ FT_MAKE_TAG( 's', 'e', 'e', 'd' )
++
++ /* */
++
++
++FT_END_HEADER
++
++
++#endif /* FTT1DRV_H_ */
++
++
++/* END */
+diff --git a/include/freetype/ftttdrv.h b/include/freetype/ftttdrv.h
+index 26bc5e966a..f97c70a2ba 100644
+--- a/include/freetype/ftttdrv.h
++++ b/include/freetype/ftttdrv.h
+@@ -155,7 +155,7 @@ FT_BEGIN_HEADER
+ *
+ * Details on subpixel hinting and some of the necessary tweaks can be
+ * found in Greg Hitchcock's whitepaper at
+- * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
++ * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
+ * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2,
+ * or 6x5 supersampling) like discussed in the paper. Depending on the
+ * chosen interpreter, it simply ignores instructions on vertical stems
+@@ -182,6 +182,9 @@ FT_BEGIN_HEADER
+ *
+ * This property can be set via the `FREETYPE_PROPERTIES' environment
+ * variable (using values `35', `38', or `40').
++ *
++ * @since:
++ * 2.5
+ */
+
+
+@@ -213,7 +216,7 @@ FT_BEGIN_HEADER
+ * TT_INTERPRETER_VERSION_40 ::
+ * Version~40 corresponds to MS rasterizer v.2.1; it is roughly
+ * equivalent to the hinting provided by DirectWrite ClearType (as can
+- * be found, for example, in Microsoft's Edge Browser on Windows~10).
++ * be found, for example, in Microsoft's Edge Browser on Windows~10).
+ * It is used in FreeType to select the `minimal' subpixel hinting
+ * code, a stripped-down and higher performance version of the
+ * `Infinality' code.
+diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h
+index eab8adaad4..8f904cea4a 100644
+--- a/include/freetype/fttypes.h
++++ b/include/freetype/fttypes.h
+@@ -425,7 +425,7 @@ FT_BEGIN_HEADER
+ /* The address of the FreeType object that is under finalization. */
+ /* Its client data is accessed through its `generic' field. */
+ /* */
+- typedef void (*FT_Generic_Finalizer)(void* object);
++ typedef void (*FT_Generic_Finalizer)( void* object );
+
+
+ /*************************************************************************/
+diff --git a/include/freetype/internal/cffotypes.h b/include/freetype/internal/cffotypes.h
+new file mode 100644
+index 0000000000..6fd1e1c7a2
+--- /dev/null
++++ b/include/freetype/internal/cffotypes.h
+@@ -0,0 +1,108 @@
++/***************************************************************************/
++/* */
++/* cffotypes.h */
++/* */
++/* Basic OpenType/CFF object type definitions (specification). */
++/* */
++/* Copyright 2017 by */
++/* David Turner, Robert Wilhelm, and Werner Lemberg. */
++/* */
++/* This file is part of the FreeType project, and may only be used, */
++/* modified, and distributed under the terms of the FreeType project */
++/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
++/* this file you indicate that you have read the license and */
++/* understand and accept it fully. */
++/* */
++/***************************************************************************/
++
++
++#ifndef CFFOTYPES_H_
++#define CFFOTYPES_H_
++
++#include <ft2build.h>
++#include FT_INTERNAL_OBJECTS_H
++#include FT_INTERNAL_CFF_TYPES_H
++#include FT_INTERNAL_TRUETYPE_TYPES_H
++#include FT_SERVICE_POSTSCRIPT_CMAPS_H
++#include FT_INTERNAL_POSTSCRIPT_HINTS_H
++
++
++FT_BEGIN_HEADER
++
++
++ typedef TT_Face CFF_Face;
++
++
++ /*************************************************************************/
++ /* */
++ /* <Type> */
++ /* CFF_Size */
++ /* */
++ /* <Description> */
++ /* A handle to an OpenType size object. */
++ /* */
++ typedef struct CFF_SizeRec_
++ {
++ FT_SizeRec root;
++ FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */
++
++ } CFF_SizeRec, *CFF_Size;
++
++
++ /*************************************************************************/
++ /* */
++ /* <Type> */
++ /* CFF_GlyphSlot */
++ /* */
++ /* <Description> */
++ /* A handle to an OpenType glyph slot object. */
++ /* */
++ typedef struct CFF_GlyphSlotRec_
++ {
++ FT_GlyphSlotRec root;
++
++ FT_Bool hint;
++ FT_Bool scaled;
++
++ FT_Fixed x_scale;
++ FT_Fixed y_scale;
++
++ } CFF_GlyphSlotRec, *CFF_GlyphSlot;
++
++
++ /*************************************************************************/
++ /* */
++ /* <Type> */
++ /* CFF_Internal */
++ /* */
++ /* <Description> */
++ /* The interface to the `internal' field of `FT_Size'. */
++ /* */
++ typedef struct CFF_InternalRec_
++ {
++ PSH_Globals topfont;
++ PSH_Globals subfonts[CFF_MAX_CID_FONTS];
++
++ } CFF_InternalRec, *CFF_Internal;
++
++
++ /*************************************************************************/
++ /* */
++ /* Subglyph transformation record. */
++ /* */
++ typedef struct CFF_Transform_
++ {
++ FT_Fixed xx, xy; /* transformation matrix coefficients */
++ FT_Fixed yx, yy;
++ FT_F26Dot6 ox, oy; /* offsets */
++
++ } CFF_Transform;
++
++
++FT_END_HEADER
++
++
++#endif /* CFFOTYPES_H_ */
++
++
++/* END */
+diff --git a/src/cff/cfftypes.h b/include/freetype/internal/cfftypes.h
+similarity index 98%
+rename from src/cff/cfftypes.h
+rename to include/freetype/internal/cfftypes.h
+index 74f569f08b..0b9dbdf8d9 100644
+--- a/src/cff/cfftypes.h
++++ b/include/freetype/internal/cfftypes.h
+@@ -27,6 +27,7 @@
+ #include FT_INTERNAL_SERVICE_H
+ #include FT_SERVICE_POSTSCRIPT_CMAPS_H
+ #include FT_INTERNAL_POSTSCRIPT_HINTS_H
++#include FT_INTERNAL_TYPE1_TYPES_H
+
+
+ FT_BEGIN_HEADER
+@@ -381,6 +382,9 @@ FT_BEGIN_HEADER
+ /* interface to Postscript Names service */
+ FT_Service_PsCMaps psnames;
+
++ /* interface to CFFLoad service */
++ const void* cffload;
++
+ /* since version 2.3.0 */
+ PS_FontInfoRec* font_info; /* font info dictionary */
+
+@@ -394,6 +398,9 @@ FT_BEGIN_HEADER
+ /* since version 2.7.1 */
+ CFF_VStoreRec vstore; /* parsed vstore structure */
+
++ /* since version 2.8.2 */
++ PS_FontExtraRec* font_extra;
++
+ } CFF_FontRec;
+
+
+diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h
+index 59e5b58a57..7a5459f39c 100644
+--- a/include/freetype/internal/ftmemory.h
++++ b/include/freetype/internal/ftmemory.h
+@@ -210,7 +210,7 @@ extern "C++"
+ NULL, \
+ &error ) )
+
+-#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \
++#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \
+ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \
+ (FT_Long)(itmsz), \
+ (FT_Long)(oldcnt), \
+diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
+index 4231be238a..538f483539 100644
+--- a/include/freetype/internal/ftobjs.h
++++ b/include/freetype/internal/ftobjs.h
+@@ -85,9 +85,9 @@ FT_BEGIN_HEADER
+ : y + ( 3 * x >> 3 ) )
+
+ /* we use FT_TYPEOF to suppress signedness compilation warnings */
+-#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) )
+-#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + (n)/2, n )
+-#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + (n)-1, n )
++#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n) - 1 ) )
++#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + (n) / 2, n )
++#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + (n) - 1, n )
+
+ #define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 )
+ #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 )
+@@ -156,7 +156,7 @@ FT_BEGIN_HEADER
+ } FT_CMapRec;
+
+ /* typecase any pointer to a charmap handle */
+-#define FT_CMAP( x ) ((FT_CMap)( x ))
++#define FT_CMAP( x ) ( (FT_CMap)( x ) )
+
+ /* obvious macros */
+ #define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id
+@@ -369,9 +369,10 @@ FT_BEGIN_HEADER
+ /* operator. Value~0 means to use the font's value. Value~-1 */
+ /* means to use the CFF driver's default. */
+ /* */
+- /* lcd_weights :: */
+- /* Overrides the library default with custom weights for the 5-tap */
+- /* FIR filter. `{0, 0, 0, 0, 0}' means to use the library default. */
++ /* lcd_weights :: */
++ /* lcd_filter_func :: */
++ /* If subpixel rendering is activated, the LCD filtering weights */
++ /* and callback function. */
+ /* */
+ /* refcount :: */
+ /* A counter initialized to~1 at the time an @FT_Face structure is */
+@@ -393,8 +394,10 @@ FT_BEGIN_HEADER
+
+ FT_Char no_stem_darkening;
+ FT_Int32 random_seed;
++
+ #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+- FT_LcdFiveTapFilter lcd_weights; /* preset or custom filter weights */
++ FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
++ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
+ #endif
+
+ FT_Int refcount;
+@@ -516,7 +519,8 @@ FT_BEGIN_HEADER
+
+
+ /* typecast an object to an FT_Module */
+-#define FT_MODULE( x ) ((FT_Module)( x ))
++#define FT_MODULE( x ) ( (FT_Module)(x) )
++
+ #define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz
+ #define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library
+ #define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory
+@@ -602,9 +606,9 @@ FT_BEGIN_HEADER
+
+ /* a few macros used to perform easy typecasts with minimal brain damage */
+
+-#define FT_FACE( x ) ((FT_Face)(x))
+-#define FT_SIZE( x ) ((FT_Size)(x))
+-#define FT_SLOT( x ) ((FT_GlyphSlot)(x))
++#define FT_FACE( x ) ( (FT_Face)(x) )
++#define FT_SIZE( x ) ( (FT_Size)(x) )
++#define FT_SLOT( x ) ( (FT_GlyphSlot)(x) )
+
+ #define FT_FACE_DRIVER( x ) FT_FACE( x )->driver
+ #define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library
+@@ -705,6 +709,12 @@ FT_BEGIN_HEADER
+ ft_glyphslot_free_bitmap( FT_GlyphSlot slot );
+
+
++ /* Preset bitmap metrics of an outline glyphslot prior to rendering. */
++ FT_BASE( void )
++ ft_glyphslot_preset_bitmap( FT_GlyphSlot slot,
++ FT_Render_Mode mode,
++ const FT_Vector* origin );
++
+ /* Allocate a new bitmap buffer in a glyph slot. */
+ FT_BASE( FT_Error )
+ ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot,
+@@ -731,10 +741,10 @@ FT_BEGIN_HEADER
+ /*************************************************************************/
+
+
+-#define FT_RENDERER( x ) ((FT_Renderer)( x ))
+-#define FT_GLYPH( x ) ((FT_Glyph)( x ))
+-#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x ))
+-#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x ))
++#define FT_RENDERER( x ) ( (FT_Renderer)(x) )
++#define FT_GLYPH( x ) ( (FT_Glyph)(x) )
++#define FT_BITMAP_GLYPH( x ) ( (FT_BitmapGlyph)(x) )
++#define FT_OUTLINE_GLYPH( x ) ( (FT_OutlineGlyph)(x) )
+
+
+ typedef struct FT_RendererRec_
+@@ -765,7 +775,7 @@ FT_BEGIN_HEADER
+
+
+ /* typecast a module into a driver easily */
+-#define FT_DRIVER( x ) ((FT_Driver)(x))
++#define FT_DRIVER( x ) ( (FT_Driver)(x) )
+
+ /* typecast a module as a driver, and get its driver class */
+ #define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz
+@@ -821,18 +831,6 @@ FT_BEGIN_HEADER
+ #define FT_DEBUG_HOOK_TRUETYPE 0
+
+
+- typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
+- FT_Render_Mode render_mode,
+- FT_Byte* weights );
+-
+-
+- /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
+- FT_BASE( void )
+- ft_lcd_filter_fir( FT_Bitmap* bitmap,
+- FT_Render_Mode mode,
+- FT_LcdFiveTapFilter weights );
+-
+-
+ /*************************************************************************/
+ /* */
+ /* <Struct> */
+@@ -878,9 +876,6 @@ FT_BEGIN_HEADER
+ /* interpreter. Currently, only the TrueType */
+ /* bytecode debugger uses this. */
+ /* */
+- /* lcd_filter :: If subpixel rendering is activated, the */
+- /* selected LCD filter mode. */
+- /* */
+ /* lcd_weights :: If subpixel rendering is activated, the LCD */
+ /* filter weights, if any. */
+ /* */
+@@ -915,7 +910,6 @@ FT_BEGIN_HEADER
+ FT_DebugHook_Func debug_hooks[4];
+
+ #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+- FT_LcdFilter lcd_filter;
+ FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
+ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
+ #endif
+diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h
+index 71ef9cac3a..e91d8a7ba9 100644
+--- a/include/freetype/internal/ftserv.h
++++ b/include/freetype/internal/ftserv.h
+@@ -330,6 +330,32 @@ FT_BEGIN_HEADER
+ { NULL, NULL } \
+ };
+
++#define FT_DEFINE_SERVICEDESCREC10( class_, \
++ serv_id_1, serv_data_1, \
++ serv_id_2, serv_data_2, \
++ serv_id_3, serv_data_3, \
++ serv_id_4, serv_data_4, \
++ serv_id_5, serv_data_5, \
++ serv_id_6, serv_data_6, \
++ serv_id_7, serv_data_7, \
++ serv_id_8, serv_data_8, \
++ serv_id_9, serv_data_9, \
++ serv_id_10, serv_data_10 ) \
++ static const FT_ServiceDescRec class_[] = \
++ { \
++ { serv_id_1, serv_data_1 }, \
++ { serv_id_2, serv_data_2 }, \
++ { serv_id_3, serv_data_3 }, \
++ { serv_id_4, serv_data_4 }, \
++ { serv_id_5, serv_data_5 }, \
++ { serv_id_6, serv_data_6 }, \
++ { serv_id_7, serv_data_7 }, \
++ { serv_id_8, serv_data_8 }, \
++ { serv_id_9, serv_data_9 }, \
++ { serv_id_10, serv_data_10 }, \
++ { NULL, NULL } \
++ };
++
+ #else /* FT_CONFIG_OPTION_PIC */
+
+ #define FT_DEFINE_SERVICEDESCREC1( class_, \
+@@ -557,7 +583,7 @@ FT_BEGIN_HEADER
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+- FT_ServiceDescRec** output_class) \
++ FT_ServiceDescRec** output_class ) \
+ { \
+ FT_ServiceDescRec* clazz = NULL; \
+ FT_Error error; \
+@@ -608,7 +634,7 @@ FT_BEGIN_HEADER
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+- FT_ServiceDescRec** output_class) \
++ FT_ServiceDescRec** output_class ) \
+ { \
+ FT_ServiceDescRec* clazz = NULL; \
+ FT_Error error; \
+@@ -662,7 +688,7 @@ FT_BEGIN_HEADER
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+- FT_ServiceDescRec** output_class) \
++ FT_ServiceDescRec** output_class ) \
+ { \
+ FT_ServiceDescRec* clazz = NULL; \
+ FT_Error error; \
+@@ -719,7 +745,7 @@ FT_BEGIN_HEADER
+ \
+ FT_Error \
+ FT_Create_Class_ ## class_( FT_Library library, \
+- FT_ServiceDescRec** output_class) \
++ FT_ServiceDescRec** output_class ) \
+ { \
+ FT_ServiceDescRec* clazz = NULL; \
+ FT_Error error; \
+@@ -755,6 +781,68 @@ FT_BEGIN_HEADER
+ return FT_Err_Ok; \
+ }
+
++#define FT_DEFINE_SERVICEDESCREC10( class_, \
++ serv_id_1, serv_data_1, \
++ serv_id_2, serv_data_2, \
++ serv_id_3, serv_data_3, \
++ serv_id_4, serv_data_4, \
++ serv_id_5, serv_data_5, \
++ serv_id_6, serv_data_6, \
++ serv_id_7, serv_data_7, \
++ serv_id_8, serv_data_8, \
++ serv_id_9, serv_data_9, \
++ serv_id_10, serv_data_10 ) \
++ void \
++ FT_Destroy_Class_ ## class_( FT_Library library, \
++ FT_ServiceDescRec* clazz ) \
++ { \
++ FT_Memory memory = library->memory; \
++ \
++ \
++ if ( clazz ) \
++ FT_FREE( clazz ); \
++ } \
++ \
++ FT_Error \
++ FT_Create_Class_ ## class_( FT_Library library, \
++ FT_ServiceDescRec** output_class ) \
++ { \
++ FT_ServiceDescRec* clazz = NULL; \
++ FT_Error error; \
++ FT_Memory memory = library->memory; \
++ \
++ \
++ if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 11 ) ) \
++ return error; \
++ \
++ clazz[ 0].serv_id = serv_id_1; \
++ clazz[ 0].serv_data = serv_data_1; \
++ clazz[ 1].serv_id = serv_id_2; \
++ clazz[ 1].serv_data = serv_data_2; \
++ clazz[ 2].serv_id = serv_id_3; \
++ clazz[ 2].serv_data = serv_data_3; \
++ clazz[ 3].serv_id = serv_id_4; \
++ clazz[ 3].serv_data = serv_data_4; \
++ clazz[ 4].serv_id = serv_id_5; \
++ clazz[ 4].serv_data = serv_data_5; \
++ clazz[ 5].serv_id = serv_id_6; \
++ clazz[ 5].serv_data = serv_data_6; \
++ clazz[ 6].serv_id = serv_id_7; \
++ clazz[ 6].serv_data = serv_data_7; \
++ clazz[ 7].serv_id = serv_id_8; \
++ clazz[ 7].serv_data = serv_data_8; \
++ clazz[ 8].serv_id = serv_id_9; \
++ clazz[ 8].serv_data = serv_data_9; \
++ clazz[ 9].serv_id = serv_id_10; \
++ clazz[ 9].serv_data = serv_data_10; \
++ clazz[10].serv_id = NULL; \
++ clazz[10].serv_data = NULL; \
++ \
++ *output_class = clazz; \
++ \
++ return FT_Err_Ok; \
++ }
++
+ #endif /* FT_CONFIG_OPTION_PIC */
+
+
+@@ -898,7 +986,9 @@ FT_BEGIN_HEADER
+ */
+
+ #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h>
++#define FT_SERVICE_CFF_TABLE_LOAD_H <freetype/internal/services/svcfftl.h>
+ #define FT_SERVICE_CID_H <freetype/internal/services/svcid.h>
++#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h>
+ #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h>
+ #define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h>
+ #define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h>
+@@ -912,10 +1002,9 @@ FT_BEGIN_HEADER
+ #define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h>
+ #define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
+ #define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h>
++#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h>
+ #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
+ #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
+-#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h>
+-#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h>
+
+ /* */
+
+diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h
+index 3e2c07b269..8acc1bec54 100644
+--- a/include/freetype/internal/ftstream.h
++++ b/include/freetype/internal/ftstream.h
+@@ -165,8 +165,8 @@ FT_BEGIN_HEADER
+ #define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )
+
+
+-#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8) | \
+- FT_BYTE_U16( p, 1, 0) )
++#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8 ) | \
++ FT_BYTE_U16( p, 1, 0 ) )
+
+ #define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \
+ FT_BYTE_U16( p, 1, 0 ) )
+diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
+index 02046813a3..23f84b4354 100644
+--- a/include/freetype/internal/internal.h
++++ b/include/freetype/internal/internal.h
+@@ -47,6 +47,9 @@
+
+ #define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h>
+
++#define FT_INTERNAL_CFF_TYPES_H <freetype/internal/cfftypes.h>
++#define FT_INTERNAL_CFF_OBJECTS_TYPES_H <freetype/internal/cffotypes.h>
++
+
+ #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+
+diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
+index 935eb1a9c7..26652f8883 100644
+--- a/include/freetype/internal/psaux.h
++++ b/include/freetype/internal/psaux.h
+@@ -25,12 +25,32 @@
+ #include FT_INTERNAL_OBJECTS_H
+ #include FT_INTERNAL_TYPE1_TYPES_H
+ #include FT_INTERNAL_HASH_H
++#include FT_INTERNAL_TRUETYPE_TYPES_H
+ #include FT_SERVICE_POSTSCRIPT_CMAPS_H
++#include FT_INTERNAL_CFF_TYPES_H
++#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
++
+
+
+ FT_BEGIN_HEADER
+
+
++ /***********************************************************************/
++ /* */
++ /* PostScript modules driver class. */
++ /* */
++ typedef struct PS_DriverRec_
++ {
++ FT_DriverRec root;
++
++ FT_UInt hinting_engine;
++ FT_Bool no_stem_darkening;
++ FT_Int darken_params[8];
++ FT_Int32 random_seed;
++
++ } PS_DriverRec, *PS_Driver;
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+@@ -439,6 +459,205 @@ FT_BEGIN_HEADER
+ } PS_ParserRec;
+
+
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** PS BUILDER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++
++ typedef struct PS_Builder_ PS_Builder;
++ typedef const struct PS_Builder_FuncsRec_* PS_Builder_Funcs;
++
++ typedef struct PS_Builder_FuncsRec_
++ {
++ void
++ (*init)( PS_Builder* ps_builder,
++ void* builder,
++ FT_Bool is_t1 );
++
++ void
++ (*done)( PS_Builder* builder );
++
++ } PS_Builder_FuncsRec;
++
++
++ /*************************************************************************/
++ /* */
++ /* <Structure> */
++ /* PS_Builder */
++ /* */
++ /* <Description> */
++ /* A structure used during glyph loading to store its outline. */
++ /* */
++ /* <Fields> */
++ /* memory :: The current memory object. */
++ /* */
++ /* face :: The current face object. */
++ /* */
++ /* glyph :: The current glyph slot. */
++ /* */
++ /* loader :: XXX */
++ /* */
++ /* base :: The base glyph outline. */
++ /* */
++ /* current :: The current glyph outline. */
++ /* */
++ /* pos_x :: The horizontal translation (if composite glyph). */
++ /* */
++ /* pos_y :: The vertical translation (if composite glyph). */
++ /* */
++ /* left_bearing :: The left side bearing point. */
++ /* */
++ /* advance :: The horizontal advance vector. */
++ /* */
++ /* bbox :: Unused. */
++ /* */
++ /* path_begun :: A flag which indicates that a new path has begun. */
++ /* */
++ /* load_points :: If this flag is not set, no points are loaded. */
++ /* */
++ /* no_recurse :: Set but not used. */
++ /* */
++ /* metrics_only :: A boolean indicating that we only want to compute */
++ /* the metrics of a given glyph, not load all of its */
++ /* points. */
++ /* */
++ /* is_t1 :: Set if current font type is Type 1. */
++ /* */
++ /* funcs :: An array of function pointers for the builder. */
++ /* */
++ struct PS_Builder_
++ {
++ FT_Memory memory;
++ FT_Face face;
++ CFF_GlyphSlot glyph;
++ FT_GlyphLoader loader;
++ FT_Outline* base;
++ FT_Outline* current;
++
++ FT_Pos* pos_x;
++ FT_Pos* pos_y;
++
++ FT_Vector* left_bearing;
++ FT_Vector* advance;
++
++ FT_BBox* bbox; /* bounding box */
++ FT_Bool path_begun;
++ FT_Bool load_points;
++ FT_Bool no_recurse;
++
++ FT_Bool metrics_only;
++ FT_Bool is_t1;
++
++ PS_Builder_FuncsRec funcs;
++
++ };
++
++
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** PS DECODER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++#define PS_MAX_OPERANDS 48
++#define PS_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */
++ /* only 10 are allowed but there exist */
++ /* fonts like `HiraKakuProN-W3.ttf' */
++ /* (Hiragino Kaku Gothic ProN W3; */
++ /* 8.2d6e1; 2014-12-19) that exceed */
++ /* this limit */
++
++ /* execution context charstring zone */
++
++ typedef struct PS_Decoder_Zone_
++ {
++ FT_Byte* base;
++ FT_Byte* limit;
++ FT_Byte* cursor;
++
++ } PS_Decoder_Zone;
++
++
++ typedef FT_Error
++ (*CFF_Decoder_Get_Glyph_Callback)( TT_Face face,
++ FT_UInt glyph_index,
++ FT_Byte** pointer,
++ FT_ULong* length );
++
++ typedef void
++ (*CFF_Decoder_Free_Glyph_Callback)( TT_Face face,
++ FT_Byte** pointer,
++ FT_ULong length );
++
++
++ typedef struct PS_Decoder_
++ {
++ PS_Builder builder;
++
++ FT_Fixed stack[PS_MAX_OPERANDS + 1];
++ FT_Fixed* top;
++
++ PS_Decoder_Zone zones[PS_MAX_SUBRS_CALLS + 1];
++ PS_Decoder_Zone* zone;
++
++ FT_Int flex_state;
++ FT_Int num_flex_vectors;
++ FT_Vector flex_vectors[7];
++
++ CFF_Font cff;
++ CFF_SubFont current_subfont; /* for current glyph_index */
++ FT_Generic* cf2_instance;
++
++ FT_Pos glyph_width;
++ FT_Pos nominal_width;
++
++ FT_Bool read_width;
++ FT_Bool width_only;
++ FT_Int num_hints;
++
++ FT_UInt num_locals;
++ FT_UInt num_globals;
++
++ FT_Int locals_bias;
++ FT_Int globals_bias;
++
++ FT_Byte** locals;
++ FT_Byte** globals;
++
++ FT_Byte** glyph_names; /* for pure CFF fonts only */
++ FT_UInt num_glyphs; /* number of glyphs in font */
++
++ FT_Render_Mode hint_mode;
++
++ FT_Bool seac;
++
++ CFF_Decoder_Get_Glyph_Callback get_glyph_callback;
++ CFF_Decoder_Free_Glyph_Callback free_glyph_callback;
++
++ /* Type 1 stuff */
++ FT_Service_PsCMaps psnames; /* for seac */
++
++ FT_Int lenIV; /* internal for sub routine calls */
++ FT_UInt* locals_len; /* array of subrs length (optional) */
++ FT_Hash locals_hash; /* used if `num_subrs' was massaged */
++
++ FT_Matrix font_matrix;
++ FT_Vector font_offset;
++
++ PS_Blend blend; /* for multiple master support */
++
++ FT_Long* buildchar;
++ FT_UInt len_buildchar;
++
++ } PS_Decoder;
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+@@ -653,10 +872,23 @@ FT_BEGIN_HEADER
+ void
+ (*done)( T1_Decoder decoder );
+
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ FT_Error
++ (*parse_charstrings_old)( T1_Decoder decoder,
++ FT_Byte* base,
++ FT_UInt len );
++#else
++ FT_Error
++ (*parse_metrics)( T1_Decoder decoder,
++ FT_Byte* base,
++ FT_UInt len );
++#endif
++
+ FT_Error
+- (*parse_charstrings)( T1_Decoder decoder,
+- FT_Byte* base,
+- FT_UInt len );
++ (*parse_charstrings)( PS_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len );
++
+
+ } T1_Decoder_FuncsRec;
+
+@@ -700,9 +932,258 @@ FT_BEGIN_HEADER
+
+ FT_Bool seac;
+
++ FT_Generic cf2_instance;
++
+ } T1_DecoderRec;
+
+
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** CFF BUILDER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++
++ typedef struct CFF_Builder_ CFF_Builder;
++
++
++ typedef FT_Error
++ (*CFF_Builder_Check_Points_Func)( CFF_Builder* builder,
++ FT_Int count );
++
++ typedef void
++ (*CFF_Builder_Add_Point_Func)( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y,
++ FT_Byte flag );
++ typedef FT_Error
++ (*CFF_Builder_Add_Point1_Func)( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y );
++ typedef FT_Error
++ (*CFF_Builder_Start_Point_Func)( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y );
++ typedef void
++ (*CFF_Builder_Close_Contour_Func)( CFF_Builder* builder );
++
++ typedef FT_Error
++ (*CFF_Builder_Add_Contour_Func)( CFF_Builder* builder );
++
++ typedef const struct CFF_Builder_FuncsRec_* CFF_Builder_Funcs;
++
++ typedef struct CFF_Builder_FuncsRec_
++ {
++ void
++ (*init)( CFF_Builder* builder,
++ TT_Face face,
++ CFF_Size size,
++ CFF_GlyphSlot glyph,
++ FT_Bool hinting );
++
++ void
++ (*done)( CFF_Builder* builder );
++
++ CFF_Builder_Check_Points_Func check_points;
++ CFF_Builder_Add_Point_Func add_point;
++ CFF_Builder_Add_Point1_Func add_point1;
++ CFF_Builder_Add_Contour_Func add_contour;
++ CFF_Builder_Start_Point_Func start_point;
++ CFF_Builder_Close_Contour_Func close_contour;
++
++ } CFF_Builder_FuncsRec;
++
++
++ /*************************************************************************/
++ /* */
++ /* <Structure> */
++ /* CFF_Builder */
++ /* */
++ /* <Description> */
++ /* A structure used during glyph loading to store its outline. */
++ /* */
++ /* <Fields> */
++ /* memory :: The current memory object. */
++ /* */
++ /* face :: The current face object. */
++ /* */
++ /* glyph :: The current glyph slot. */
++ /* */
++ /* loader :: The current glyph loader. */
++ /* */
++ /* base :: The base glyph outline. */
++ /* */
++ /* current :: The current glyph outline. */
++ /* */
++ /* pos_x :: The horizontal translation (if composite glyph). */
++ /* */
++ /* pos_y :: The vertical translation (if composite glyph). */
++ /* */
++ /* left_bearing :: The left side bearing point. */
++ /* */
++ /* advance :: The horizontal advance vector. */
++ /* */
++ /* bbox :: Unused. */
++ /* */
++ /* path_begun :: A flag which indicates that a new path has begun. */
++ /* */
++ /* load_points :: If this flag is not set, no points are loaded. */
++ /* */
++ /* no_recurse :: Set but not used. */
++ /* */
++ /* metrics_only :: A boolean indicating that we only want to compute */
++ /* the metrics of a given glyph, not load all of its */
++ /* points. */
++ /* */
++ /* hints_funcs :: Auxiliary pointer for hinting. */
++ /* */
++ /* hints_globals :: Auxiliary pointer for hinting. */
++ /* */
++ /* funcs :: A table of method pointers for this object. */
++ /* */
++ struct CFF_Builder_
++ {
++ FT_Memory memory;
++ TT_Face face;
++ CFF_GlyphSlot glyph;
++ FT_GlyphLoader loader;
++ FT_Outline* base;
++ FT_Outline* current;
++
++ FT_Pos pos_x;
++ FT_Pos pos_y;
++
++ FT_Vector left_bearing;
++ FT_Vector advance;
++
++ FT_BBox bbox; /* bounding box */
++
++ FT_Bool path_begun;
++ FT_Bool load_points;
++ FT_Bool no_recurse;
++
++ FT_Bool metrics_only;
++
++ void* hints_funcs; /* hinter-specific */
++ void* hints_globals; /* hinter-specific */
++
++ CFF_Builder_FuncsRec funcs;
++ };
++
++
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** CFF DECODER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++
++#define CFF_MAX_OPERANDS 48
++#define CFF_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */
++ /* only 10 are allowed but there exist */
++ /* fonts like `HiraKakuProN-W3.ttf' */
++ /* (Hiragino Kaku Gothic ProN W3; */
++ /* 8.2d6e1; 2014-12-19) that exceed */
++ /* this limit */
++#define CFF_MAX_TRANS_ELEMENTS 32
++
++ /* execution context charstring zone */
++
++ typedef struct CFF_Decoder_Zone_
++ {
++ FT_Byte* base;
++ FT_Byte* limit;
++ FT_Byte* cursor;
++
++ } CFF_Decoder_Zone;
++
++
++ typedef struct CFF_Decoder_
++ {
++ CFF_Builder builder;
++ CFF_Font cff;
++
++ FT_Fixed stack[CFF_MAX_OPERANDS + 1];
++ FT_Fixed* top;
++
++ CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1];
++ CFF_Decoder_Zone* zone;
++
++ FT_Int flex_state;
++ FT_Int num_flex_vectors;
++ FT_Vector flex_vectors[7];
++
++ FT_Pos glyph_width;
++ FT_Pos nominal_width;
++
++ FT_Bool read_width;
++ FT_Bool width_only;
++ FT_Int num_hints;
++ FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS];
++
++ FT_UInt num_locals;
++ FT_UInt num_globals;
++
++ FT_Int locals_bias;
++ FT_Int globals_bias;
++
++ FT_Byte** locals;
++ FT_Byte** globals;
++
++ FT_Byte** glyph_names; /* for pure CFF fonts only */
++ FT_UInt num_glyphs; /* number of glyphs in font */
++
++ FT_Render_Mode hint_mode;
++
++ FT_Bool seac;
++
++ CFF_SubFont current_subfont; /* for current glyph_index */
++
++ CFF_Decoder_Get_Glyph_Callback get_glyph_callback;
++ CFF_Decoder_Free_Glyph_Callback free_glyph_callback;
++
++ } CFF_Decoder;
++
++
++ typedef const struct CFF_Decoder_FuncsRec_* CFF_Decoder_Funcs;
++
++ typedef struct CFF_Decoder_FuncsRec_
++ {
++ void
++ (*init)( CFF_Decoder* decoder,
++ TT_Face face,
++ CFF_Size size,
++ CFF_GlyphSlot slot,
++ FT_Bool hinting,
++ FT_Render_Mode hint_mode,
++ CFF_Decoder_Get_Glyph_Callback get_callback,
++ CFF_Decoder_Free_Glyph_Callback free_callback );
++
++ FT_Error
++ (*prepare)( CFF_Decoder* decoder,
++ CFF_Size size,
++ FT_UInt glyph_index );
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++ FT_Error
++ (*parse_charstrings_old)( CFF_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len,
++ FT_Bool in_dict );
++#endif
++
++ FT_Error
++ (*parse_charstrings)( PS_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len );
++
++ } CFF_Decoder_FuncsRec;
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+@@ -810,11 +1291,26 @@ FT_BEGIN_HEADER
+ FT_Offset length,
+ FT_UShort seed );
+
++ FT_UInt32
++ (*cff_random)( FT_UInt32 r );
++
++ void
++ (*ps_decoder_init)( PS_Decoder* ps_decoder,
++ void* decoder,
++ FT_Bool is_t1 );
++
++ void
++ (*t1_make_subfont)( FT_Face face,
++ PS_Private priv,
++ CFF_SubFont subfont );
++
+ T1_CMap_Classes t1_cmap_classes;
+
+ /* fields after this comment line were added after version 2.1.10 */
+ const AFM_Parser_FuncsRec* afm_parser_funcs;
+
++ const CFF_Decoder_FuncsRec* cff_decoder_funcs;
++
+ } PSAux_ServiceRec, *PSAux_Service;
+
+ /* backward compatible type definition */
+diff --git a/include/freetype/internal/services/svcfftl.h b/include/freetype/internal/services/svcfftl.h
+new file mode 100644
+index 0000000000..851bcde3ac
+--- /dev/null
++++ b/include/freetype/internal/services/svcfftl.h
+@@ -0,0 +1,112 @@
++/***************************************************************************/
++/* */
++/* svcfftl.h */
++/* */
++/* The FreeType CFF tables loader service (specification). */
++/* */
++/* Copyright 2017 by */
++/* David Turner, Robert Wilhelm, and Werner Lemberg. */
++/* */
++/* This file is part of the FreeType project, and may only be used, */
++/* modified, and distributed under the terms of the FreeType project */
++/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
++/* this file you indicate that you have read the license and */
++/* understand and accept it fully. */
++/* */
++/***************************************************************************/
++
++
++#ifndef SVCFFTL_H_
++#define SVCFFTL_H_
++
++#include FT_INTERNAL_SERVICE_H
++#include FT_INTERNAL_CFF_TYPES_H
++
++
++FT_BEGIN_HEADER
++
++
++#define FT_SERVICE_ID_CFF_LOAD "cff-load"
++
++
++ typedef FT_UShort
++ (*FT_Get_Standard_Encoding_Func)( FT_UInt charcode );
++
++ typedef FT_Error
++ (*FT_Load_Private_Dict_Func)( CFF_Font font,
++ CFF_SubFont subfont,
++ FT_UInt lenNDV,
++ FT_Fixed* NDV );
++
++ typedef FT_Byte
++ (*FT_FD_Select_Get_Func)( CFF_FDSelect fdselect,
++ FT_UInt glyph_index );
++
++ typedef FT_Bool
++ (*FT_Blend_Check_Vector_Func)( CFF_Blend blend,
++ FT_UInt vsindex,
++ FT_UInt lenNDV,
++ FT_Fixed* NDV );
++
++ typedef FT_Error
++ (*FT_Blend_Build_Vector_Func)( CFF_Blend blend,
++ FT_UInt vsindex,
++ FT_UInt lenNDV,
++ FT_Fixed* NDV );
++
++
++ FT_DEFINE_SERVICE( CFFLoad )
++ {
++ FT_Get_Standard_Encoding_Func get_standard_encoding;
++ FT_Load_Private_Dict_Func load_private_dict;
++ FT_FD_Select_Get_Func fd_select_get;
++ FT_Blend_Check_Vector_Func blend_check_vector;
++ FT_Blend_Build_Vector_Func blend_build_vector;
++ };
++
++
++#ifndef FT_CONFIG_OPTION_PIC
++
++#define FT_DEFINE_SERVICE_CFFLOADREC( class_, \
++ get_standard_encoding_, \
++ load_private_dict_, \
++ fd_select_get_, \
++ blend_check_vector_, \
++ blend_build_vector_ ) \
++ static const FT_Service_CFFLoadRec class_ = \
++ { \
++ get_standard_encoding_, \
++ load_private_dict_, \
++ fd_select_get_, \
++ blend_check_vector_, \
++ blend_build_vector_ \
++ };
++
++#else /* FT_CONFIG_OPTION_PIC */
++
++#define FT_DEFINE_SERVICE_CFFLOADREC( class_, \
++ get_standard_encoding_, \
++ load_private_dict_, \
++ fd_select_get_, \
++ blend_check_vector_, \
++ blend_build_vector_ ) \
++ void \
++ FT_Init_Class_ ## class_( FT_Service_CFFLoadRec* clazz ) \
++ { \
++ clazz->get_standard_encoding = get_standard_encoding_; \
++ clazz->load_private_dict = load_private_dict_; \
++ clazz->fd_select_get = fd_select_get_; \
++ clazz->blend_check_vector = blend_check_vector_; \
++ clazz->blend_build_vector = blend_build_vector_; \
++ }
++
++#endif /* FT_CONFIG_OPTION_PIC */
++
++
++FT_END_HEADER
++
++
++#endif
++
++
++/* END */
+diff --git a/include/freetype/internal/services/svgldict.h b/include/freetype/internal/services/svgldict.h
+index 0cd13618d8..3371c6b869 100644
+--- a/include/freetype/internal/services/svgldict.h
++++ b/include/freetype/internal/services/svgldict.h
+@@ -56,7 +56,7 @@ FT_BEGIN_HEADER
+
+ #define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \
+ get_name_, \
+- name_index_) \
++ name_index_ ) \
+ static const FT_Service_GlyphDictRec class_ = \
+ { \
+ get_name_, name_index_ \
+@@ -66,7 +66,7 @@ FT_BEGIN_HEADER
+
+ #define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \
+ get_name_, \
+- name_index_) \
++ name_index_ ) \
+ void \
+ FT_Init_Class_ ## class_( FT_Library library, \
+ FT_Service_GlyphDictRec* clazz ) \
+diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h
+index 1d51cd9090..a934f9452e 100644
+--- a/include/freetype/internal/services/svmm.h
++++ b/include/freetype/internal/services/svmm.h
+@@ -63,6 +63,10 @@ FT_BEGIN_HEADER
+ FT_UInt num_coords,
+ FT_Fixed* coords );
+
++ typedef FT_Error
++ (*FT_Set_Instance_Func)( FT_Face face,
++ FT_UInt instance_index );
++
+ typedef FT_Error
+ (*FT_Get_MM_Blend_Func)( FT_Face face,
+ FT_UInt num_coords,
+@@ -88,6 +92,7 @@ FT_BEGIN_HEADER
+ FT_Get_MM_Var_Func get_mm_var;
+ FT_Set_Var_Design_Func set_var_design;
+ FT_Get_Var_Design_Func get_var_design;
++ FT_Set_Instance_Func set_instance;
+
+ /* for internal use; only needed for code sharing between modules */
+ FT_Get_Var_Blend_Func get_var_blend;
+@@ -97,27 +102,29 @@ FT_BEGIN_HEADER
+
+ #ifndef FT_CONFIG_OPTION_PIC
+
+-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \
+- get_mm_, \
+- set_mm_design_, \
+- set_mm_blend_, \
+- get_mm_blend_, \
+- get_mm_var_, \
+- set_var_design_, \
+- get_var_design_, \
+- get_var_blend_, \
+- done_blend_ ) \
+- static const FT_Service_MultiMastersRec class_ = \
+- { \
+- get_mm_, \
+- set_mm_design_, \
+- set_mm_blend_, \
+- get_mm_blend_, \
+- get_mm_var_, \
+- set_var_design_, \
+- get_var_design_, \
+- get_var_blend_, \
+- done_blend_ \
++#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \
++ get_mm_, \
++ set_mm_design_, \
++ set_mm_blend_, \
++ get_mm_blend_, \
++ get_mm_var_, \
++ set_var_design_, \
++ get_var_design_, \
++ set_instance_, \
++ get_var_blend_, \
++ done_blend_ ) \
++ static const FT_Service_MultiMastersRec class_ = \
++ { \
++ get_mm_, \
++ set_mm_design_, \
++ set_mm_blend_, \
++ get_mm_blend_, \
++ get_mm_var_, \
++ set_var_design_, \
++ get_var_design_, \
++ set_instance_, \
++ get_var_blend_, \
++ done_blend_ \
+ };
+
+ #else /* FT_CONFIG_OPTION_PIC */
+@@ -130,6 +137,7 @@ FT_BEGIN_HEADER
+ get_mm_var_, \
+ set_var_design_, \
+ get_var_design_, \
++ set_instance_, \
+ get_var_blend_, \
+ done_blend_ ) \
+ void \
+@@ -142,6 +150,7 @@ FT_BEGIN_HEADER
+ clazz->get_mm_var = get_mm_var_; \
+ clazz->set_var_design = set_var_design_; \
+ clazz->get_var_design = get_var_design_; \
++ clazz->set_instance = set_instance_; \
+ clazz->get_var_blend = get_var_blend_; \
+ clazz->done_blend = done_blend_; \
+ }
+diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
+index c0758e25fc..3bc6c9893d 100644
+--- a/include/freetype/internal/tttypes.h
++++ b/include/freetype/internal/tttypes.h
+@@ -1299,10 +1299,6 @@ FT_BEGIN_HEADER
+ /* variation tables (rather like Multiple */
+ /* Master data). */
+ /* */
+- /* is_default_instance :: Set if the glyph outlines can be used */
+- /* unmodified (i.e., without applying glyph */
+- /* variation deltas). */
+- /* */
+ /* variation_support :: Flags that indicate which OpenType */
+ /* functionality related to font variation */
+ /* support is present, valid, and usable. */
+@@ -1445,6 +1441,9 @@ FT_BEGIN_HEADER
+ void* var;
+ #endif
+
++ /* a typeless pointer to the PostScript Aux service */
++ void* psaux;
++
+
+ /***********************************************************************/
+ /* */
+@@ -1509,7 +1508,6 @@ FT_BEGIN_HEADER
+ FT_Bool doblend;
+ GX_Blend blend;
+
+- FT_Bool is_default_instance; /* since 2.7.1 */
+ FT_UInt32 variation_support; /* since 2.7.1 */
+
+ const char* var_postscript_prefix; /* since 2.7.2 */
+diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h
+index 3f6b36e108..940b4a06ba 100644
+--- a/include/freetype/t1tables.h
++++ b/include/freetype/t1tables.h
+@@ -554,6 +554,9 @@ FT_BEGIN_HEADER
+ /* T1_ENCODING_TYPE_ISOLATIN1 :: */
+ /* T1_ENCODING_TYPE_EXPERT :: */
+ /* */
++ /* <Since> */
++ /* 2.4.8 */
++ /* */
+ typedef enum T1_EncodingType_
+ {
+ T1_ENCODING_TYPE_NONE = 0,
+@@ -622,6 +625,9 @@ FT_BEGIN_HEADER
+ /* PS_DICT_FS_TYPE :: */
+ /* PS_DICT_ITALIC_ANGLE :: */
+ /* */
++ /* <Since> */
++ /* 2.4.8 */
++ /* */
+ typedef enum PS_Dict_Keys_
+ {
+ /* conventionally in the font dictionary */
+@@ -743,6 +749,9 @@ FT_BEGIN_HEADER
+ * If the font's format is not PostScript-based, this function returns
+ * the `FT_Err_Invalid_Argument' error code.
+ *
++ * @since:
++ * 2.4.8
++ *
+ */
+ FT_EXPORT( FT_Long )
+ FT_Get_PS_Font_Value( FT_Face face,
+diff --git a/modules.cfg b/modules.cfg
+index 517111efeb..56a2340e56 100644
+--- a/modules.cfg
++++ b/modules.cfg
+@@ -42,7 +42,7 @@ FONT_MODULES += type1
+
+ # CFF/OpenType font driver.
+ #
+-# This driver needs the `sfnt', `pshinter', and `psnames' modules.
++# This driver needs the `sfnt', `psaux', `pshinter', and `psnames' modules.
+ FONT_MODULES += cff
+
+ # Type 1 CID-keyed font driver.
+diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
+index 1b21c06c2c..5b70c6d3ad 100644
+--- a/src/autofit/afhints.c
++++ b/src/autofit/afhints.c
+@@ -314,8 +314,12 @@
+ AF_DUMP(( "Table of points:\n" ));
+
+ if ( hints->num_points )
++ {
+ AF_DUMP(( " index hedge hseg vedge vseg flags "
++ /* " XXXXX XXXXX XXXXX XXXXX XXXXX XXXXXX" */
+ " xorg yorg xscale yscale xfit yfit" ));
++ /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */
++ }
+ else
+ AF_DUMP(( " (none)\n" ));
+
+@@ -420,9 +424,14 @@
+ dimension == AF_DIMENSION_HORZ ? "vertical"
+ : "horizontal" ));
+ if ( axis->num_segments )
++ {
+ AF_DUMP(( " index pos delta dir from to "
++ /* " XXXXX XXXXX XXXXX XXXXX XXXX XXXX" */
+ " link serif edge"
++ /* " XXXX XXXXX XXXX" */
+ " height extra flags\n" ));
++ /* " XXXXXX XXXXX XXXXXXXXXXX" */
++ }
+ else
+ AF_DUMP(( " (none)\n" ));
+
+@@ -564,8 +573,12 @@
+ 10.0 * hints->y_scale / 65536.0 / 64.0 ));
+
+ if ( axis->num_edges )
++ {
+ AF_DUMP(( " index pos dir link serif"
++ /* " XXXXX XXXX.XX XXXXX XXXX XXXXX" */
+ " blue opos pos flags\n" ));
++ /* " X XXXX.XX XXXX.XX XXXXXXXXXXX" */
++ }
+ else
+ AF_DUMP(( " (none)\n" ));
+
+diff --git a/src/autofit/afshaper.c b/src/autofit/afshaper.c
+index d259964217..8ee9ba1a62 100644
+--- a/src/autofit/afshaper.c
++++ b/src/autofit/afshaper.c
+@@ -104,10 +104,10 @@
+ {
+ hb_face_t* face;
+
+- hb_set_t* gsub_lookups; /* GSUB lookups for a given script */
+- hb_set_t* gsub_glyphs; /* glyphs covered by GSUB lookups */
+- hb_set_t* gpos_lookups; /* GPOS lookups for a given script */
+- hb_set_t* gpos_glyphs; /* glyphs covered by GPOS lookups */
++ hb_set_t* gsub_lookups = NULL; /* GSUB lookups for a given script */
++ hb_set_t* gsub_glyphs = NULL; /* glyphs covered by GSUB lookups */
++ hb_set_t* gpos_lookups = NULL; /* GPOS lookups for a given script */
++ hb_set_t* gpos_glyphs = NULL; /* glyphs covered by GPOS lookups */
+
+ hb_script_t script;
+ const hb_tag_t* coverage_tags;
+@@ -127,11 +127,6 @@
+
+ face = hb_font_get_face( globals->hb_font );
+
+- gsub_lookups = hb_set_create();
+- gsub_glyphs = hb_set_create();
+- gpos_lookups = hb_set_create();
+- gpos_glyphs = hb_set_create();
+-
+ coverage_tags = coverages[style_class->coverage];
+ script = scripts[style_class->script];
+
+@@ -168,6 +163,7 @@
+ script_tags[1] = HB_TAG_NONE;
+ }
+
++ gsub_lookups = hb_set_create();
+ hb_ot_layout_collect_lookups( face,
+ HB_OT_TAG_GSUB,
+ script_tags,
+@@ -178,13 +174,6 @@
+ if ( hb_set_is_empty( gsub_lookups ) )
+ goto Exit; /* nothing to do */
+
+- hb_ot_layout_collect_lookups( face,
+- HB_OT_TAG_GPOS,
+- script_tags,
+- NULL,
+- coverage_tags,
+- gpos_lookups );
+-
+ FT_TRACE4(( "GSUB lookups (style `%s'):\n"
+ " ",
+ af_style_names[style_class->style] ));
+@@ -193,6 +182,7 @@
+ count = 0;
+ #endif
+
++ gsub_glyphs = hb_set_create();
+ for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); )
+ {
+ #ifdef FT_DEBUG_LEVEL_TRACE
+@@ -220,10 +210,19 @@
+ " ",
+ af_style_names[style_class->style] ));
+
++ gpos_lookups = hb_set_create();
++ hb_ot_layout_collect_lookups( face,
++ HB_OT_TAG_GPOS,
++ script_tags,
++ NULL,
++ coverage_tags,
++ gpos_lookups );
++
+ #ifdef FT_DEBUG_LEVEL_TRACE
+ count = 0;
+ #endif
+
++ gpos_glyphs = hb_set_create();
+ for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); )
+ {
+ #ifdef FT_DEBUG_LEVEL_TRACE
+diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
+index 60c813fd9e..4971f93b49 100644
+--- a/src/base/ftlcdfil.c
++++ b/src/base/ftlcdfil.c
+@@ -31,8 +31,41 @@
+
+ #define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) )
+
++
++ /* add padding according to filter weights */
++ FT_BASE_DEF (void)
++ ft_lcd_padding( FT_Pos* Min,
++ FT_Pos* Max,
++ FT_GlyphSlot slot )
++ {
++ FT_Byte* lcd_weights;
++ FT_Bitmap_LcdFilterFunc lcd_filter_func;
++
++
++ /* Per-face LCD filtering takes priority if set up. */
++ if ( slot->face && slot->face->internal->lcd_filter_func )
++ {
++ lcd_weights = slot->face->internal->lcd_weights;
++ lcd_filter_func = slot->face->internal->lcd_filter_func;
++ }
++ else
++ {
++ lcd_weights = slot->library->lcd_weights;
++ lcd_filter_func = slot->library->lcd_filter_func;
++ }
++
++ if ( lcd_filter_func == ft_lcd_filter_fir )
++ {
++ *Min -= lcd_weights[0] ? 43 :
++ lcd_weights[1] ? 22 : 0;
++ *Max += lcd_weights[4] ? 43 :
++ lcd_weights[3] ? 22 : 0;
++ }
++ }
++
++
+ /* FIR filter used by the default and light filters */
+- FT_BASE( void )
++ FT_BASE_DEF( void )
+ ft_lcd_filter_fir( FT_Bitmap* bitmap,
+ FT_Render_Mode mode,
+ FT_LcdFiveTapFilter weights )
+@@ -305,21 +338,21 @@
+ return FT_THROW( Invalid_Argument );
+ }
+
+- library->lcd_filter = filter;
+-
+ return FT_Err_Ok;
+ }
+
+ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+- FT_BASE( void )
+- ft_lcd_filter_fir( FT_Bitmap* bitmap,
+- FT_Render_Mode mode,
+- FT_LcdFiveTapFilter weights )
++ /* add padding according to accommodate outline shifts */
++ FT_BASE_DEF (void)
++ ft_lcd_padding( FT_Pos* Min,
++ FT_Pos* Max,
++ FT_GlyphSlot slot )
+ {
+- FT_UNUSED( bitmap );
+- FT_UNUSED( mode );
+- FT_UNUSED( weights );
++ FT_UNUSED( slot );
++
++ *Min -= 21;
++ *Max += 21;
+ }
+
+
+diff --git a/src/base/ftmm.c b/src/base/ftmm.c
+index 43877ece45..e0131ece32 100644
+--- a/src/base/ftmm.c
++++ b/src/base/ftmm.c
+@@ -426,4 +426,52 @@
+ }
+
+
++ /* documentation is in ftmm.h */
++
++ FT_EXPORT_DEF( FT_Error )
++ FT_Set_Named_Instance( FT_Face face,
++ FT_UInt instance_index )
++ {
++ FT_Error error;
++
++ FT_Service_MultiMasters service_mm = NULL;
++ FT_Service_MetricsVariations service_mvar = NULL;
++
++
++ /* check of `face' delayed to `ft_face_get_mm_service' */
++
++ error = ft_face_get_mm_service( face, &service_mm );
++ if ( !error )
++ {
++ error = FT_ERR( Invalid_Argument );
++ if ( service_mm->set_instance )
++ error = service_mm->set_instance( face, instance_index );
++ }
++
++ if ( !error )
++ {
++ (void)ft_face_get_mvar_service( face, &service_mvar );
++
++ if ( service_mvar && service_mvar->metrics_adjust )
++ service_mvar->metrics_adjust( face );
++ }
++
++ /* enforce recomputation of auto-hinting data */
++ if ( !error && face->autohint.finalizer )
++ {
++ face->autohint.finalizer( face->autohint.data );
++ face->autohint.data = NULL;
++ }
++
++ if ( !error )
++ {
++ face->face_index = ( instance_index << 16 ) |
++ ( face->face_index & 0xFFFFL );
++ face->face_flags &= ~FT_FACE_FLAG_VARIATION;
++ }
++
++ return error;
++ }
++
++
+ /* END */
+diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
+index 6db8136cfc..eb14c6dd94 100644
+--- a/src/base/ftobjs.c
++++ b/src/base/ftobjs.c
+@@ -327,6 +327,138 @@
+ }
+
+
++ FT_BASE_DEF( void )
++ ft_glyphslot_preset_bitmap( FT_GlyphSlot slot,
++ FT_Render_Mode mode,
++ const FT_Vector* origin )
++ {
++ FT_Outline* outline = &slot->outline;
++ FT_Bitmap* bitmap = &slot->bitmap;
++
++ FT_Pixel_Mode pixel_mode;
++
++ FT_BBox cbox;
++ FT_Pos x_shift = 0;
++ FT_Pos y_shift = 0;
++ FT_Pos x_left, y_top;
++ FT_Pos width, height, pitch;
++
++
++ if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
++ return;
++
++ if ( origin )
++ {
++ x_shift = origin->x;
++ y_shift = origin->y;
++ }
++
++ /* compute the control box, and grid-fit it, */
++ /* taking into account the origin shift */
++ FT_Outline_Get_CBox( outline, &cbox );
++
++ cbox.xMin += x_shift;
++ cbox.yMin += y_shift;
++ cbox.xMax += x_shift;
++ cbox.yMax += y_shift;
++
++ switch ( mode )
++ {
++ case FT_RENDER_MODE_MONO:
++ pixel_mode = FT_PIXEL_MODE_MONO;
++#if 1
++ /* undocumented but confirmed: bbox values get rounded */
++ /* unless the rounded box can collapse for a narrow glyph */
++ if ( cbox.xMax - cbox.xMin < 64 )
++ {
++ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
++ cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
++ }
++ else
++ {
++ cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin );
++ cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax );
++ }
++
++ if ( cbox.yMax - cbox.yMin < 64 )
++ {
++ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
++ cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
++ }
++ else
++ {
++ cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin );
++ cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax );
++ }
++#else
++ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
++ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
++ cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
++ cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
++#endif
++ break;
++
++ case FT_RENDER_MODE_LCD:
++ pixel_mode = FT_PIXEL_MODE_LCD;
++ ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot );
++ goto Round;
++
++ case FT_RENDER_MODE_LCD_V:
++ pixel_mode = FT_PIXEL_MODE_LCD_V;
++ ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot );
++ goto Round;
++
++ case FT_RENDER_MODE_NORMAL:
++ case FT_RENDER_MODE_LIGHT:
++ default:
++ pixel_mode = FT_PIXEL_MODE_GRAY;
++ Round:
++ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
++ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
++ cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax );
++ cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax );
++ }
++
++ x_shift = SUB_LONG( x_shift, cbox.xMin );
++ y_shift = SUB_LONG( y_shift, cbox.yMin );
++
++ x_left = cbox.xMin >> 6;
++ y_top = cbox.yMax >> 6;
++
++ width = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6;
++ height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6;
++
++ switch ( pixel_mode )
++ {
++ case FT_PIXEL_MODE_MONO:
++ pitch = ( ( width + 15 ) >> 4 ) << 1;
++ break;
++
++ case FT_PIXEL_MODE_LCD:
++ width *= 3;
++ pitch = FT_PAD_CEIL( width, 4 );
++ break;
++
++ case FT_PIXEL_MODE_LCD_V:
++ height *= 3;
++ /* fall through */
++
++ case FT_PIXEL_MODE_GRAY:
++ default:
++ pitch = width;
++ }
++
++ slot->bitmap_left = (FT_Int)x_left;
++ slot->bitmap_top = (FT_Int)y_top;
++
++ bitmap->pixel_mode = (unsigned char)pixel_mode;
++ bitmap->num_grays = 256;
++ bitmap->width = (unsigned int)width;
++ bitmap->rows = (unsigned int)height;
++ bitmap->pitch = pitch;
++ }
++
++
+ FT_BASE_DEF( void )
+ ft_glyphslot_set_bitmap( FT_GlyphSlot slot,
+ FT_Byte* buffer )
+@@ -854,22 +986,28 @@
+ FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance ));
+ FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance ));
+
+- /* do we need to render the image now? */
++ /* do we need to render the image or preset the bitmap now? */
+ if ( !error &&
+ slot->format != FT_GLYPH_FORMAT_BITMAP &&
+- slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
+- load_flags & FT_LOAD_RENDER )
++ slot->format != FT_GLYPH_FORMAT_COMPOSITE )
+ {
+ FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
+
+
+- if ( mode == FT_RENDER_MODE_NORMAL &&
+- (load_flags & FT_LOAD_MONOCHROME ) )
++ if ( mode == FT_RENDER_MODE_NORMAL &&
++ load_flags & FT_LOAD_MONOCHROME )
+ mode = FT_RENDER_MODE_MONO;
+
+- error = FT_Render_Glyph( slot, mode );
++ if ( load_flags & FT_LOAD_RENDER )
++ error = FT_Render_Glyph( slot, mode );
++ else if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
++ ft_glyphslot_preset_bitmap( slot, mode, NULL );
+ }
+
++ FT_TRACE5(( " bitmap pixel_mode: %d\n" , slot->bitmap.pixel_mode ));
++ FT_TRACE5(( " bitmap dimensions: %dx%d\n" , slot->bitmap.width,
++ slot->bitmap.rows ));
++
+ Exit:
+ return error;
+ }
+@@ -2441,7 +2579,8 @@
+ internal->no_stem_darkening = -1;
+
+ #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+- ft_memset( internal->lcd_weights, 0, FT_LCD_FILTER_FIVE_TAPS );
++ /* Per-face filtering can only be set up by FT_Face_Properties */
++ internal->lcd_filter_func = NULL;
+ #endif
+ }
+
+@@ -3653,16 +3792,11 @@
+ {
+ #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+ if ( properties->data )
++ {
+ ft_memcpy( face->internal->lcd_weights,
+ properties->data,
+ FT_LCD_FILTER_FIVE_TAPS );
+- else
+- {
+- /* Value NULL indicates `no custom weights, use library */
+- /* defaults', signaled by filling the weight field with zeros. */
+- ft_memset( face->internal->lcd_weights,
+- 0,
+- FT_LCD_FILTER_FIVE_TAPS );
++ face->internal->lcd_filter_func = ft_lcd_filter_fir;
+ }
+ #else
+ error = FT_THROW( Unimplemented_Feature );
+@@ -4453,6 +4587,51 @@
+ }
+ }
+
++ /*
++ * Dump bitmap in Netpbm format (PBM or PGM).
++ */
++
++ /* we use FT_TRACE2 in this block */
++ if ( ft_trace_levels[trace_bitmap] >= 2 &&
++ !error &&
++ slot->bitmap.rows < 128U &&
++ slot->bitmap.width < 128U )
++ {
++ int rows = (int)slot->bitmap.rows;
++ int width = (int)slot->bitmap.width;
++ int pitch = slot->bitmap.pitch;
++ int i, j, m;
++ unsigned char* topleft = slot->bitmap.buffer;
++
++ if ( pitch < 0 )
++ topleft -= pitch * ( rows - 1 );
++
++ FT_TRACE2(( "Netpbm image: start\n" ));
++ switch ( slot->bitmap.pixel_mode )
++ {
++ case FT_PIXEL_MODE_MONO:
++ FT_TRACE2(( "P1 %d %d\n", width, rows ));
++ for ( i = 0; i < rows; i++ )
++ {
++ for ( j = 0; j < width; )
++ for ( m = 128; m > 0 && j < width; m >>= 1, j++ )
++ FT_TRACE2(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 ));
++ FT_TRACE2(( "\n" ));
++ }
++ break;
++
++ default:
++ FT_TRACE2(( "P2 %d %d 255\n", width, rows ));
++ for ( i = 0; i < rows; i++ )
++ {
++ for ( j = 0; j < width; j += 1 )
++ FT_TRACE2(( " %3u", topleft[i * pitch + j] ));
++ FT_TRACE2(( "\n" ));
++ }
++ }
++ FT_TRACE2(( "Netpbm image: end\n" ));
++ }
++
+ #undef FT_COMPONENT
+ #define FT_COMPONENT trace_objs
+
+@@ -4995,9 +5174,9 @@
+ #ifdef FT_CONFIG_OPTION_PIC
+ Fail:
+ ft_pic_container_destroy( library );
+-#endif
+ FT_FREE( library );
+ return error;
++#endif
+ }
+
+
+diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
+index 9ceb9cf1ba..cbbcb859ab 100644
+--- a/src/base/ftoutln.c
++++ b/src/base/ftoutln.c
+@@ -540,8 +540,8 @@
+
+ for ( n = 0; n < outline->n_points; n++ )
+ {
+- vec->x += xOffset;
+- vec->y += yOffset;
++ vec->x = ADD_LONG( vec->x, xOffset );
++ vec->y = ADD_LONG( vec->y, yOffset );
+ vec++;
+ }
+ }
+diff --git a/src/cff/Jamfile b/src/cff/Jamfile
+index e6dd05fc15..f665a0b25b 100644
+--- a/src/cff/Jamfile
++++ b/src/cff/Jamfile
+@@ -23,15 +23,6 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cff ;
+ cffobjs
+ cffparse
+ cffpic
+- cf2arrst
+- cf2blues
+- cf2error
+- cf2font
+- cf2ft
+- cf2hints
+- cf2intrp
+- cf2read
+- cf2stack
+ ;
+ }
+ else
+diff --git a/src/cff/cff.c b/src/cff/cff.c
+index 397f6dfafe..e9b3264b89 100644
+--- a/src/cff/cff.c
++++ b/src/cff/cff.c
+@@ -27,15 +27,4 @@
+ #include "cffload.c"
+ #include "cffobjs.c"
+
+-#include "cf2arrst.c"
+-#include "cf2blues.c"
+-#include "cf2error.c"
+-#include "cf2font.c"
+-#include "cf2ft.c"
+-#include "cf2hints.c"
+-#include "cf2intrp.c"
+-#include "cf2read.c"
+-#include "cf2stack.c"
+-
+-
+ /* END */
+diff --git a/src/cff/cffcmap.h b/src/cff/cffcmap.h
+index 7792e04248..227c91afb7 100644
+--- a/src/cff/cffcmap.h
++++ b/src/cff/cffcmap.h
+@@ -19,7 +19,7 @@
+ #ifndef CFFCMAP_H_
+ #define CFFCMAP_H_
+
+-#include "cffobjs.h"
++#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+
+ FT_BEGIN_HEADER
+
+diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
+index 38bfc2ca3d..cf630a8a11 100644
+--- a/src/cff/cffdrivr.c
++++ b/src/cff/cffdrivr.c
+@@ -21,16 +21,19 @@
+ #include FT_INTERNAL_DEBUG_H
+ #include FT_INTERNAL_STREAM_H
+ #include FT_INTERNAL_SFNT_H
++#include FT_INTERNAL_POSTSCRIPT_AUX_H
+ #include FT_SERVICE_CID_H
+ #include FT_SERVICE_POSTSCRIPT_INFO_H
+ #include FT_SERVICE_POSTSCRIPT_NAME_H
+ #include FT_SERVICE_TT_CMAP_H
++#include FT_SERVICE_CFF_TABLE_LOAD_H
+
+ #include "cffdrivr.h"
+ #include "cffgload.h"
+ #include "cffload.h"
+ #include "cffcmap.h"
+ #include "cffparse.h"
++#include "cffobjs.h"
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ #include FT_SERVICE_MULTIPLE_MASTERS_H
+@@ -214,8 +217,8 @@
+ {
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ /* no fast retrieval for blended MM fonts without VVAR table */
+- if ( !ttface->is_default_instance &&
+- !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
++ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
++ !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+ return FT_THROW( Unimplemented_Feature );
+ #endif
+
+@@ -246,8 +249,8 @@
+ {
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ /* no fast retrieval for blended MM fonts without HVAR table */
+- if ( !ttface->is_default_instance &&
+- !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
++ if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
++ !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
+ return FT_THROW( Unimplemented_Feature );
+ #endif
+
+@@ -493,11 +496,89 @@
+ }
+
+
++ static FT_Error
++ cff_ps_get_font_extra( CFF_Face face,
++ PS_FontExtraRec* afont_extra )
++ {
++ CFF_Font cff = (CFF_Font)face->extra.data;
++ FT_Error error = FT_Err_Ok;
++
++
++ if ( cff && cff->font_extra == NULL )
++ {
++ CFF_FontRecDict dict = &cff->top_font.font_dict;
++ PS_FontExtraRec* font_extra = NULL;
++ FT_Memory memory = face->root.memory;
++ FT_String* embedded_postscript;
++
++
++ if ( FT_ALLOC( font_extra, sizeof ( *font_extra ) ) )
++ goto Fail;
++
++ font_extra->fs_type = 0U;
++
++ embedded_postscript = cff_index_get_sid_string(
++ cff,
++ dict->embedded_postscript );
++ if ( embedded_postscript )
++ {
++ FT_String* start_fstype;
++ FT_String* start_def;
++
++
++ /* Identify the XYZ integer in `/FSType XYZ def' substring. */
++ if ( ( start_fstype = ft_strstr( embedded_postscript,
++ "/FSType" ) ) != NULL &&
++ ( start_def = ft_strstr( start_fstype +
++ sizeof ( "/FSType" ) - 1,
++ "def" ) ) != NULL )
++ {
++ FT_String* s;
++
++
++ for ( s = start_fstype + sizeof ( "/FSType" ) - 1;
++ s != start_def;
++ s++ )
++ {
++ if ( *s >= '0' && *s <= '9' )
++ {
++ if ( font_extra->fs_type >= ( FT_USHORT_MAX - 9 ) / 10 )
++ {
++ /* Overflow - ignore the FSType value. */
++ font_extra->fs_type = 0U;
++ break;
++ }
++
++ font_extra->fs_type *= 10;
++ font_extra->fs_type += (FT_UShort)( *s - '0' );
++ }
++ else if ( *s != ' ' && *s != '\n' && *s != '\r' )
++ {
++ /* Non-whitespace character between `/FSType' and next `def' */
++ /* - ignore the FSType value. */
++ font_extra->fs_type = 0U;
++ break;
++ }
++ }
++ }
++ }
++
++ cff->font_extra = font_extra;
++ }
++
++ if ( cff )
++ *afont_extra = *cff->font_extra;
++
++ Fail:
++ return error;
++ }
++
++
+ FT_DEFINE_SERVICE_PSINFOREC(
+ cff_service_ps_info,
+
+ (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */
+- (PS_GetFontExtraFunc) NULL, /* ps_get_font_extra */
++ (PS_GetFontExtraFunc) cff_ps_get_font_extra, /* ps_get_font_extra */
+ (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */
+ /* unsupported with CFF fonts */
+ (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */
+@@ -741,8 +822,8 @@
+ const void* value,
+ FT_Bool value_is_string )
+ {
+- FT_Error error = FT_Err_Ok;
+- CFF_Driver driver = (CFF_Driver)module;
++ FT_Error error = FT_Err_Ok;
++ PS_Driver driver = (PS_Driver)module;
+
+ #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+ FT_UNUSED( value_is_string );
+@@ -907,8 +988,8 @@
+ const char* property_name,
+ const void* value )
+ {
+- FT_Error error = FT_Err_Ok;
+- CFF_Driver driver = (CFF_Driver)module;
++ FT_Error error = FT_Err_Ok;
++ PS_Driver driver = (PS_Driver)module;
+
+
+ if ( !ft_strcmp( property_name, "darkening-parameters" ) )
+@@ -1028,6 +1109,17 @@
+ }
+
+
++ static FT_Error
++ cff_set_instance( CFF_Face face,
++ FT_UInt instance_index )
++ {
++ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
++
++
++ return mm->set_instance( FT_FACE( face ), instance_index );
++ }
++
++
+ FT_DEFINE_SERVICE_MULTIMASTERSREC(
+ cff_service_multi_masters,
+
+@@ -1038,6 +1130,7 @@
+ (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */
+ (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */
+ (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */
++ (FT_Set_Instance_Func) cff_set_instance, /* set_instance */
+
+ (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */
+ (FT_Done_Blend_Func) cff_done_blend /* done_blend */
+@@ -1088,6 +1181,22 @@
+ #endif
+
+
++ /*
++ * CFFLOAD SERVICE
++ *
++ */
++
++ FT_DEFINE_SERVICE_CFFLOADREC(
++ cff_service_cff_load,
++
++ (FT_Get_Standard_Encoding_Func)cff_get_standard_encoding,
++ (FT_Load_Private_Dict_Func) cff_load_private_dict,
++ (FT_FD_Select_Get_Func) cff_fd_select_get,
++ (FT_Blend_Check_Vector_Func) cff_blend_check_vector,
++ (FT_Blend_Build_Vector_Func) cff_blend_build_vector
++ )
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+@@ -1102,7 +1211,7 @@
+
+ #if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \
+ defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
+- FT_DEFINE_SERVICEDESCREC9(
++ FT_DEFINE_SERVICEDESCREC10(
+ cff_services,
+
+ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
+@@ -1113,10 +1222,11 @@
+ FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
+- FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET
++ FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
++ FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
+ )
+ #elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES
+- FT_DEFINE_SERVICEDESCREC7(
++ FT_DEFINE_SERVICEDESCREC8(
+ cff_services,
+
+ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
+@@ -1125,10 +1235,11 @@
+ FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET,
+ FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
+- FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET
++ FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
++ FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
+ )
+ #elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
+- FT_DEFINE_SERVICEDESCREC8(
++ FT_DEFINE_SERVICEDESCREC9(
+ cff_services,
+
+ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
+@@ -1138,10 +1249,11 @@
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
+- FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET
++ FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
++ FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
+ )
+ #else
+- FT_DEFINE_SERVICEDESCREC6(
++ FT_DEFINE_SERVICEDESCREC7(
+ cff_services,
+
+ FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
+@@ -1149,7 +1261,8 @@
+ FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
+ FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
+ FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
+- FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET
++ FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
++ FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
+ )
+ #endif
+
+@@ -1208,7 +1321,7 @@
+ FT_MODULE_DRIVER_HAS_HINTER |
+ FT_MODULE_DRIVER_HINTS_LIGHTLY,
+
+- sizeof ( CFF_DriverRec ),
++ sizeof ( PS_DriverRec ),
+ "cff",
+ 0x10000L,
+ 0x20000L,
+diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
+index 20f3a2c28e..5429460cc2 100644
+--- a/src/cff/cffgload.c
++++ b/src/cff/cffgload.c
+@@ -21,13 +21,12 @@
+ #include FT_INTERNAL_STREAM_H
+ #include FT_INTERNAL_SFNT_H
+ #include FT_INTERNAL_CALC_H
++#include FT_INTERNAL_POSTSCRIPT_AUX_H
+ #include FT_OUTLINE_H
+ #include FT_CFF_DRIVER_H
+
+-#include "cffobjs.h"
+ #include "cffload.h"
+ #include "cffgload.h"
+-#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */
+
+ #include "cfferrs.h"
+
+@@ -42,2637 +41,76 @@
+ #define FT_COMPONENT trace_cffgload
+
+
+-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+-
+- typedef enum CFF_Operator_
+- {
+- cff_op_unknown = 0,
+-
+- cff_op_rmoveto,
+- cff_op_hmoveto,
+- cff_op_vmoveto,
+-
+- cff_op_rlineto,
+- cff_op_hlineto,
+- cff_op_vlineto,
+-
+- cff_op_rrcurveto,
+- cff_op_hhcurveto,
+- cff_op_hvcurveto,
+- cff_op_rcurveline,
+- cff_op_rlinecurve,
+- cff_op_vhcurveto,
+- cff_op_vvcurveto,
+-
+- cff_op_flex,
+- cff_op_hflex,
+- cff_op_hflex1,
+- cff_op_flex1,
+-
+- cff_op_endchar,
+-
+- cff_op_hstem,
+- cff_op_vstem,
+- cff_op_hstemhm,
+- cff_op_vstemhm,
+-
+- cff_op_hintmask,
+- cff_op_cntrmask,
+- cff_op_dotsection, /* deprecated, acts as no-op */
+-
+- cff_op_abs,
+- cff_op_add,
+- cff_op_sub,
+- cff_op_div,
+- cff_op_neg,
+- cff_op_random,
+- cff_op_mul,
+- cff_op_sqrt,
+-
+- cff_op_blend,
+-
+- cff_op_drop,
+- cff_op_exch,
+- cff_op_index,
+- cff_op_roll,
+- cff_op_dup,
+-
+- cff_op_put,
+- cff_op_get,
+- cff_op_store,
+- cff_op_load,
+-
+- cff_op_and,
+- cff_op_or,
+- cff_op_not,
+- cff_op_eq,
+- cff_op_ifelse,
+-
+- cff_op_callsubr,
+- cff_op_callgsubr,
+- cff_op_return,
+-
+- /* Type 1 opcodes: invalid but seen in real life */
+- cff_op_hsbw,
+- cff_op_closepath,
+- cff_op_callothersubr,
+- cff_op_pop,
+- cff_op_seac,
+- cff_op_sbw,
+- cff_op_setcurrentpoint,
+-
+- /* do not remove */
+- cff_op_max
+-
+- } CFF_Operator;
+-
+-
+-#define CFF_COUNT_CHECK_WIDTH 0x80
+-#define CFF_COUNT_EXACT 0x40
+-#define CFF_COUNT_CLEAR_STACK 0x20
+-
+- /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
+- /* used for checking the width and requested numbers of arguments */
+- /* only; they are set to zero afterwards */
+-
+- /* the other two flags are informative only and unused currently */
+-
+- static const FT_Byte cff_argument_counts[] =
+- {
+- 0, /* unknown */
+-
+- 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
+- 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
+- 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
+-
+- 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
+- 0 | CFF_COUNT_CLEAR_STACK,
+- 0 | CFF_COUNT_CLEAR_STACK,
+-
+- 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
+- 0 | CFF_COUNT_CLEAR_STACK,
+- 0 | CFF_COUNT_CLEAR_STACK,
+- 0 | CFF_COUNT_CLEAR_STACK,
+- 0 | CFF_COUNT_CLEAR_STACK,
+- 0 | CFF_COUNT_CLEAR_STACK,
+- 0 | CFF_COUNT_CLEAR_STACK,
+-
+- 13, /* flex */
+- 7,
+- 9,
+- 11,
+-
+- 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
+-
+- 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
+- 2 | CFF_COUNT_CHECK_WIDTH,
+- 2 | CFF_COUNT_CHECK_WIDTH,
+- 2 | CFF_COUNT_CHECK_WIDTH,
+-
+- 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
+- 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
+- 0, /* dotsection */
+-
+- 1, /* abs */
+- 2,
+- 2,
+- 2,
+- 1,
+- 0,
+- 2,
+- 1,
+-
+- 1, /* blend */
+-
+- 1, /* drop */
+- 2,
+- 1,
+- 2,
+- 1,
+-
+- 2, /* put */
+- 1,
+- 4,
+- 3,
+-
+- 2, /* and */
+- 2,
+- 1,
+- 2,
+- 4,
+-
+- 1, /* callsubr */
+- 1,
+- 0,
+-
+- 2, /* hsbw */
+- 0,
+- 0,
+- 0,
+- 5, /* seac */
+- 4, /* sbw */
+- 2 /* setcurrentpoint */
+- };
+-
+-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+-
+-
+- /*************************************************************************/
+- /*************************************************************************/
+- /*************************************************************************/
+- /********** *********/
+- /********** *********/
+- /********** GENERIC CHARSTRING PARSING *********/
+- /********** *********/
+- /********** *********/
+- /*************************************************************************/
+- /*************************************************************************/
+- /*************************************************************************/
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Function> */
+- /* cff_builder_init */
+- /* */
+- /* <Description> */
+- /* Initializes a given glyph builder. */
+- /* */
+- /* <InOut> */
+- /* builder :: A pointer to the glyph builder to initialize. */
+- /* */
+- /* <Input> */
+- /* face :: The current face object. */
+- /* */
+- /* size :: The current size object. */
+- /* */
+- /* glyph :: The current glyph object. */
+- /* */
+- /* hinting :: Whether hinting is active. */
+- /* */
+- static void
+- cff_builder_init( CFF_Builder* builder,
+- TT_Face face,
+- CFF_Size size,
+- CFF_GlyphSlot glyph,
+- FT_Bool hinting )
+- {
+- builder->path_begun = 0;
+- builder->load_points = 1;
+-
+- builder->face = face;
+- builder->glyph = glyph;
+- builder->memory = face->root.memory;
+-
+- if ( glyph )
+- {
+- FT_GlyphLoader loader = glyph->root.internal->loader;
+-
+-
+- builder->loader = loader;
+- builder->base = &loader->base.outline;
+- builder->current = &loader->current.outline;
+- FT_GlyphLoader_Rewind( loader );
+-
+- builder->hints_globals = NULL;
+- builder->hints_funcs = NULL;
+-
+- if ( hinting && size )
+- {
+- FT_Size ftsize = FT_SIZE( size );
+- CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data;
+-
+-
+- if ( internal )
+- {
+- builder->hints_globals = (void *)internal->topfont;
+- builder->hints_funcs = glyph->root.internal->glyph_hints;
+- }
+- }
+- }
+-
+- builder->pos_x = 0;
+- builder->pos_y = 0;
+-
+- builder->left_bearing.x = 0;
+- builder->left_bearing.y = 0;
+- builder->advance.x = 0;
+- builder->advance.y = 0;
+- }
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Function> */
+- /* cff_builder_done */
+- /* */
+- /* <Description> */
+- /* Finalizes a given glyph builder. Its contents can still be used */
+- /* after the call, but the function saves important information */
+- /* within the corresponding glyph slot. */
+- /* */
+- /* <Input> */
+- /* builder :: A pointer to the glyph builder to finalize. */
+- /* */
+- static void
+- cff_builder_done( CFF_Builder* builder )
+- {
+- CFF_GlyphSlot glyph = builder->glyph;
+-
+-
+- if ( glyph )
+- glyph->root.outline = *builder->base;
+- }
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Function> */
+- /* cff_compute_bias */
+- /* */
+- /* <Description> */
+- /* Computes the bias value in dependence of the number of glyph */
+- /* subroutines. */
+- /* */
+- /* <Input> */
+- /* in_charstring_type :: The `CharstringType' value of the top DICT */
+- /* dictionary. */
+- /* */
+- /* num_subrs :: The number of glyph subroutines. */
+- /* */
+- /* <Return> */
+- /* The bias value. */
+- static FT_Int
+- cff_compute_bias( FT_Int in_charstring_type,
+- FT_UInt num_subrs )
+- {
+- FT_Int result;
+-
+-
+- if ( in_charstring_type == 1 )
+- result = 0;
+- else if ( num_subrs < 1240 )
+- result = 107;
+- else if ( num_subrs < 33900U )
+- result = 1131;
+- else
+- result = 32768U;
+-
+- return result;
+- }
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Function> */
+- /* cff_decoder_init */
+- /* */
+- /* <Description> */
+- /* Initializes a given glyph decoder. */
+- /* */
+- /* <InOut> */
+- /* decoder :: A pointer to the glyph builder to initialize. */
+- /* */
+- /* <Input> */
+- /* face :: The current face object. */
+- /* */
+- /* size :: The current size object. */
+- /* */
+- /* slot :: The current glyph object. */
+- /* */
+- /* hinting :: Whether hinting is active. */
+- /* */
+- /* hint_mode :: The hinting mode. */
+- /* */
+- FT_LOCAL_DEF( void )
+- cff_decoder_init( CFF_Decoder* decoder,
+- TT_Face face,
+- CFF_Size size,
+- CFF_GlyphSlot slot,
+- FT_Bool hinting,
+- FT_Render_Mode hint_mode )
+- {
+- CFF_Font cff = (CFF_Font)face->extra.data;
+-
+-
+- /* clear everything */
+- FT_ZERO( decoder );
+-
+- /* initialize builder */
+- cff_builder_init( &decoder->builder, face, size, slot, hinting );
+-
+- /* initialize Type2 decoder */
+- decoder->cff = cff;
+- decoder->num_globals = cff->global_subrs_index.count;
+- decoder->globals = cff->global_subrs;
+- decoder->globals_bias = cff_compute_bias(
+- cff->top_font.font_dict.charstring_type,
+- decoder->num_globals );
+-
+- decoder->hint_mode = hint_mode;
+- }
+-
+-
+- /* this function is used to select the subfont */
+- /* and the locals subrs array */
+- FT_LOCAL_DEF( FT_Error )
+- cff_decoder_prepare( CFF_Decoder* decoder,
+- CFF_Size size,
+- FT_UInt glyph_index )
+- {
+- CFF_Builder *builder = &decoder->builder;
+- CFF_Font cff = (CFF_Font)builder->face->extra.data;
+- CFF_SubFont sub = &cff->top_font;
+- FT_Error error = FT_Err_Ok;
+-
+-
+- /* manage CID fonts */
+- if ( cff->num_subfonts )
+- {
+- FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
+-
+-
+- if ( fd_index >= cff->num_subfonts )
+- {
+- FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
+- error = FT_THROW( Invalid_File_Format );
+- goto Exit;
+- }
+-
+- FT_TRACE3(( " in subfont %d:\n", fd_index ));
+-
+- sub = cff->subfonts[fd_index];
+-
+- if ( builder->hints_funcs && size )
+- {
+- FT_Size ftsize = FT_SIZE( size );
+- CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data;
+-
+-
+- /* for CFFs without subfonts, this value has already been set */
+- builder->hints_globals = (void *)internal->subfonts[fd_index];
+- }
+- }
+-
+- decoder->num_locals = sub->local_subrs_index.count;
+- decoder->locals = sub->local_subrs;
+- decoder->locals_bias = cff_compute_bias(
+- decoder->cff->top_font.font_dict.charstring_type,
+- decoder->num_locals );
+-
+- decoder->glyph_width = sub->private_dict.default_width;
+- decoder->nominal_width = sub->private_dict.nominal_width;
+-
+- decoder->current_subfont = sub;
+-
+- Exit:
+- return error;
+- }
+-
+-
+- /* check that there is enough space for `count' more points */
+- FT_LOCAL_DEF( FT_Error )
+- cff_check_points( CFF_Builder* builder,
+- FT_Int count )
+- {
+- return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
+- }
+-
+-
+- /* add a new point, do not check space */
+- FT_LOCAL_DEF( void )
+- cff_builder_add_point( CFF_Builder* builder,
+- FT_Pos x,
+- FT_Pos y,
+- FT_Byte flag )
+- {
+- FT_Outline* outline = builder->current;
+-
+-
+- if ( builder->load_points )
+- {
+- FT_Vector* point = outline->points + outline->n_points;
+- FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
+-
+-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+- CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
+-
+-
+- if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
+- {
+- point->x = x >> 16;
+- point->y = y >> 16;
+- }
+- else
+-#endif
+- {
+- /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
+- point->x = x >> 10;
+- point->y = y >> 10;
+- }
+- *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
+- }
+-
+- outline->n_points++;
+- }
+-
+-
+- /* check space for a new on-curve point, then add it */
+- FT_LOCAL_DEF( FT_Error )
+- cff_builder_add_point1( CFF_Builder* builder,
+- FT_Pos x,
+- FT_Pos y )
+- {
+- FT_Error error;
+-
+-
+- error = cff_check_points( builder, 1 );
+- if ( !error )
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- return error;
+- }
+-
+-
+- /* check space for a new contour, then add it */
+- static FT_Error
+- cff_builder_add_contour( CFF_Builder* builder )
+- {
+- FT_Outline* outline = builder->current;
+- FT_Error error;
+-
+-
+- if ( !builder->load_points )
+- {
+- outline->n_contours++;
+- return FT_Err_Ok;
+- }
+-
+- error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
+- if ( !error )
+- {
+- if ( outline->n_contours > 0 )
+- outline->contours[outline->n_contours - 1] =
+- (short)( outline->n_points - 1 );
+-
+- outline->n_contours++;
+- }
+-
+- return error;
+- }
+-
+-
+- /* if a path was begun, add its first on-curve point */
+- FT_LOCAL_DEF( FT_Error )
+- cff_builder_start_point( CFF_Builder* builder,
+- FT_Pos x,
+- FT_Pos y )
+- {
+- FT_Error error = FT_Err_Ok;
+-
+-
+- /* test whether we are building a new contour */
+- if ( !builder->path_begun )
+- {
+- builder->path_begun = 1;
+- error = cff_builder_add_contour( builder );
+- if ( !error )
+- error = cff_builder_add_point1( builder, x, y );
+- }
+-
+- return error;
+- }
+-
+-
+- /* close the current contour */
+- FT_LOCAL_DEF( void )
+- cff_builder_close_contour( CFF_Builder* builder )
+- {
+- FT_Outline* outline = builder->current;
+- FT_Int first;
+-
+-
+- if ( !outline )
+- return;
+-
+- first = outline->n_contours <= 1
+- ? 0 : outline->contours[outline->n_contours - 2] + 1;
+-
+- /* We must not include the last point in the path if it */
+- /* is located on the first point. */
+- if ( outline->n_points > 1 )
+- {
+- FT_Vector* p1 = outline->points + first;
+- FT_Vector* p2 = outline->points + outline->n_points - 1;
+- FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
+-
+-
+- /* `delete' last point only if it coincides with the first */
+- /* point and if it is not a control point (which can happen). */
+- if ( p1->x == p2->x && p1->y == p2->y )
+- if ( *control == FT_CURVE_TAG_ON )
+- outline->n_points--;
+- }
+-
+- if ( outline->n_contours > 0 )
+- {
+- /* Don't add contours only consisting of one point, i.e., */
+- /* check whether begin point and last point are the same. */
+- if ( first == outline->n_points - 1 )
+- {
+- outline->n_contours--;
+- outline->n_points--;
+- }
+- else
+- outline->contours[outline->n_contours - 1] =
+- (short)( outline->n_points - 1 );
+- }
+- }
+-
+-
+- FT_LOCAL_DEF( FT_Int )
+- cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
+- FT_Int charcode )
+- {
+- FT_UInt n;
+- FT_UShort glyph_sid;
+-
+-
+- /* CID-keyed fonts don't have glyph names */
+- if ( !cff->charset.sids )
+- return -1;
+-
+- /* check range of standard char code */
+- if ( charcode < 0 || charcode > 255 )
+- return -1;
+-
+- /* Get code to SID mapping from `cff_standard_encoding'. */
+- glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode );
+-
+- for ( n = 0; n < cff->num_glyphs; n++ )
+- {
+- if ( cff->charset.sids[n] == glyph_sid )
+- return (FT_Int)n;
+- }
+-
+- return -1;
+- }
+-
+-
+- FT_LOCAL_DEF( FT_Error )
+- cff_get_glyph_data( TT_Face face,
+- FT_UInt glyph_index,
+- FT_Byte** pointer,
+- FT_ULong* length )
+- {
+-#ifdef FT_CONFIG_OPTION_INCREMENTAL
+- /* For incremental fonts get the character data using the */
+- /* callback function. */
+- if ( face->root.internal->incremental_interface )
+- {
+- FT_Data data;
+- FT_Error error =
+- face->root.internal->incremental_interface->funcs->get_glyph_data(
+- face->root.internal->incremental_interface->object,
+- glyph_index, &data );
+-
+-
+- *pointer = (FT_Byte*)data.pointer;
+- *length = (FT_ULong)data.length;
+-
+- return error;
+- }
+- else
+-#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+-
+- {
+- CFF_Font cff = (CFF_Font)(face->extra.data);
+-
+-
+- return cff_index_access_element( &cff->charstrings_index, glyph_index,
+- pointer, length );
+- }
+- }
+-
+-
+- FT_LOCAL_DEF( void )
+- cff_free_glyph_data( TT_Face face,
+- FT_Byte** pointer,
+- FT_ULong length )
+- {
+-#ifndef FT_CONFIG_OPTION_INCREMENTAL
+- FT_UNUSED( length );
+-#endif
+-
+-#ifdef FT_CONFIG_OPTION_INCREMENTAL
+- /* For incremental fonts get the character data using the */
+- /* callback function. */
+- if ( face->root.internal->incremental_interface )
+- {
+- FT_Data data;
+-
+-
+- data.pointer = *pointer;
+- data.length = (FT_Int)length;
+-
+- face->root.internal->incremental_interface->funcs->free_glyph_data(
+- face->root.internal->incremental_interface->object, &data );
+- }
+- else
+-#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+-
+- {
+- CFF_Font cff = (CFF_Font)(face->extra.data);
+-
+-
+- cff_index_forget_element( &cff->charstrings_index, pointer );
+- }
+- }
+-
+-
+-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+-
+- static FT_Error
+- cff_operator_seac( CFF_Decoder* decoder,
+- FT_Pos asb,
+- FT_Pos adx,
+- FT_Pos ady,
+- FT_Int bchar,
+- FT_Int achar )
+- {
+- FT_Error error;
+- CFF_Builder* builder = &decoder->builder;
+- FT_Int bchar_index, achar_index;
+- TT_Face face = decoder->builder.face;
+- FT_Vector left_bearing, advance;
+- FT_Byte* charstring;
+- FT_ULong charstring_len;
+- FT_Pos glyph_width;
+-
+-
+- if ( decoder->seac )
+- {
+- FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
+- return FT_THROW( Syntax_Error );
+- }
+-
+- adx += decoder->builder.left_bearing.x;
+- ady += decoder->builder.left_bearing.y;
+-
+-#ifdef FT_CONFIG_OPTION_INCREMENTAL
+- /* Incremental fonts don't necessarily have valid charsets. */
+- /* They use the character code, not the glyph index, in this case. */
+- if ( face->root.internal->incremental_interface )
+- {
+- bchar_index = bchar;
+- achar_index = achar;
+- }
+- else
+-#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+- {
+- CFF_Font cff = (CFF_Font)(face->extra.data);
+-
+-
+- bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
+- achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
+- }
+-
+- if ( bchar_index < 0 || achar_index < 0 )
+- {
+- FT_ERROR(( "cff_operator_seac:"
+- " invalid seac character code arguments\n" ));
+- return FT_THROW( Syntax_Error );
+- }
+-
+- /* If we are trying to load a composite glyph, do not load the */
+- /* accent character and return the array of subglyphs. */
+- if ( builder->no_recurse )
+- {
+- FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph;
+- FT_GlyphLoader loader = glyph->internal->loader;
+- FT_SubGlyph subg;
+-
+-
+- /* reallocate subglyph array if necessary */
+- error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
+- if ( error )
+- goto Exit;
+-
+- subg = loader->current.subglyphs;
+-
+- /* subglyph 0 = base character */
+- subg->index = bchar_index;
+- subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
+- FT_SUBGLYPH_FLAG_USE_MY_METRICS;
+- subg->arg1 = 0;
+- subg->arg2 = 0;
+- subg++;
+-
+- /* subglyph 1 = accent character */
+- subg->index = achar_index;
+- subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
+- subg->arg1 = (FT_Int)( adx >> 16 );
+- subg->arg2 = (FT_Int)( ady >> 16 );
+-
+- /* set up remaining glyph fields */
+- glyph->num_subglyphs = 2;
+- glyph->subglyphs = loader->base.subglyphs;
+- glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
+-
+- loader->current.num_subglyphs = 2;
+- }
+-
+- FT_GlyphLoader_Prepare( builder->loader );
+-
+- /* First load `bchar' in builder */
+- error = cff_get_glyph_data( face, (FT_UInt)bchar_index,
+- &charstring, &charstring_len );
+- if ( !error )
+- {
+- /* the seac operator must not be nested */
+- decoder->seac = TRUE;
+- error = cff_decoder_parse_charstrings( decoder, charstring,
+- charstring_len, 0 );
+- decoder->seac = FALSE;
+-
+- cff_free_glyph_data( face, &charstring, charstring_len );
+-
+- if ( error )
+- goto Exit;
+- }
+-
+- /* Save the left bearing, advance and glyph width of the base */
+- /* character as they will be erased by the next load. */
+-
+- left_bearing = builder->left_bearing;
+- advance = builder->advance;
+- glyph_width = decoder->glyph_width;
+-
+- builder->left_bearing.x = 0;
+- builder->left_bearing.y = 0;
+-
+- builder->pos_x = adx - asb;
+- builder->pos_y = ady;
+-
+- /* Now load `achar' on top of the base outline. */
+- error = cff_get_glyph_data( face, (FT_UInt)achar_index,
+- &charstring, &charstring_len );
+- if ( !error )
+- {
+- /* the seac operator must not be nested */
+- decoder->seac = TRUE;
+- error = cff_decoder_parse_charstrings( decoder, charstring,
+- charstring_len, 0 );
+- decoder->seac = FALSE;
+-
+- cff_free_glyph_data( face, &charstring, charstring_len );
+-
+- if ( error )
+- goto Exit;
+- }
+-
+- /* Restore the left side bearing, advance and glyph width */
+- /* of the base character. */
+- builder->left_bearing = left_bearing;
+- builder->advance = advance;
+- decoder->glyph_width = glyph_width;
+-
+- builder->pos_x = 0;
+- builder->pos_y = 0;
+-
+- Exit:
+- return error;
+- }
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Function> */
+- /* cff_decoder_parse_charstrings */
+- /* */
+- /* <Description> */
+- /* Parses a given Type 2 charstrings program. */
+- /* */
+- /* <InOut> */
+- /* decoder :: The current Type 1 decoder. */
+- /* */
+- /* <Input> */
+- /* charstring_base :: The base of the charstring stream. */
+- /* */
+- /* charstring_len :: The length in bytes of the charstring stream. */
+- /* */
+- /* in_dict :: Set to 1 if function is called from top or */
+- /* private DICT (needed for Multiple Master CFFs). */
+- /* */
+- /* <Return> */
+- /* FreeType error code. 0 means success. */
+- /* */
+- FT_LOCAL_DEF( FT_Error )
+- cff_decoder_parse_charstrings( CFF_Decoder* decoder,
+- FT_Byte* charstring_base,
+- FT_ULong charstring_len,
+- FT_Bool in_dict )
+- {
+- FT_Error error;
+- CFF_Decoder_Zone* zone;
+- FT_Byte* ip;
+- FT_Byte* limit;
+- CFF_Builder* builder = &decoder->builder;
+- FT_Pos x, y;
+- FT_Fixed* stack;
+- FT_Int charstring_type =
+- decoder->cff->top_font.font_dict.charstring_type;
+- FT_UShort num_designs =
+- decoder->cff->top_font.font_dict.num_designs;
+- FT_UShort num_axes =
+- decoder->cff->top_font.font_dict.num_axes;
+-
+- T2_Hints_Funcs hinter;
+-
+-
+- /* set default width */
+- decoder->num_hints = 0;
+- decoder->read_width = 1;
+-
+- /* initialize the decoder */
+- decoder->top = decoder->stack;
+- decoder->zone = decoder->zones;
+- zone = decoder->zones;
+- stack = decoder->top;
+-
+- hinter = (T2_Hints_Funcs)builder->hints_funcs;
+-
+- builder->path_begun = 0;
+-
+- zone->base = charstring_base;
+- limit = zone->limit = charstring_base + charstring_len;
+- ip = zone->cursor = zone->base;
+-
+- error = FT_Err_Ok;
+-
+- x = builder->pos_x;
+- y = builder->pos_y;
+-
+- /* begin hints recording session, if any */
+- if ( hinter )
+- hinter->open( hinter->hints );
+-
+- /* now execute loop */
+- while ( ip < limit )
+- {
+- CFF_Operator op;
+- FT_Byte v;
+-
+-
+- /********************************************************************/
+- /* */
+- /* Decode operator or operand */
+- /* */
+- v = *ip++;
+- if ( v >= 32 || v == 28 )
+- {
+- FT_Int shift = 16;
+- FT_Int32 val;
+-
+-
+- /* this is an operand, push it on the stack */
+-
+- /* if we use shifts, all computations are done with unsigned */
+- /* values; the conversion to a signed value is the last step */
+- if ( v == 28 )
+- {
+- if ( ip + 1 >= limit )
+- goto Syntax_Error;
+- val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
+- ip += 2;
+- }
+- else if ( v < 247 )
+- val = (FT_Int32)v - 139;
+- else if ( v < 251 )
+- {
+- if ( ip >= limit )
+- goto Syntax_Error;
+- val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
+- }
+- else if ( v < 255 )
+- {
+- if ( ip >= limit )
+- goto Syntax_Error;
+- val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
+- }
+- else
+- {
+- if ( ip + 3 >= limit )
+- goto Syntax_Error;
+- val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
+- ( (FT_UInt32)ip[1] << 16 ) |
+- ( (FT_UInt32)ip[2] << 8 ) |
+- (FT_UInt32)ip[3] );
+- ip += 4;
+- if ( charstring_type == 2 )
+- shift = 0;
+- }
+- if ( decoder->top - stack >= CFF_MAX_OPERANDS )
+- goto Stack_Overflow;
+-
+- val = (FT_Int32)( (FT_UInt32)val << shift );
+- *decoder->top++ = val;
+-
+-#ifdef FT_DEBUG_LEVEL_TRACE
+- if ( !( val & 0xFFFFL ) )
+- FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
+- else
+- FT_TRACE4(( " %.5f", val / 65536.0 ));
+-#endif
+-
+- }
+- else
+- {
+- /* The specification says that normally arguments are to be taken */
+- /* from the bottom of the stack. However, this seems not to be */
+- /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
+- /* arguments similar to a PS interpreter. */
+-
+- FT_Fixed* args = decoder->top;
+- FT_Int num_args = (FT_Int)( args - decoder->stack );
+- FT_Int req_args;
+-
+-
+- /* find operator */
+- op = cff_op_unknown;
+-
+- switch ( v )
+- {
+- case 1:
+- op = cff_op_hstem;
+- break;
+- case 3:
+- op = cff_op_vstem;
+- break;
+- case 4:
+- op = cff_op_vmoveto;
+- break;
+- case 5:
+- op = cff_op_rlineto;
+- break;
+- case 6:
+- op = cff_op_hlineto;
+- break;
+- case 7:
+- op = cff_op_vlineto;
+- break;
+- case 8:
+- op = cff_op_rrcurveto;
+- break;
+- case 9:
+- op = cff_op_closepath;
+- break;
+- case 10:
+- op = cff_op_callsubr;
+- break;
+- case 11:
+- op = cff_op_return;
+- break;
+- case 12:
+- {
+- if ( ip >= limit )
+- goto Syntax_Error;
+- v = *ip++;
+-
+- switch ( v )
+- {
+- case 0:
+- op = cff_op_dotsection;
+- break;
+- case 1: /* this is actually the Type1 vstem3 operator */
+- op = cff_op_vstem;
+- break;
+- case 2: /* this is actually the Type1 hstem3 operator */
+- op = cff_op_hstem;
+- break;
+- case 3:
+- op = cff_op_and;
+- break;
+- case 4:
+- op = cff_op_or;
+- break;
+- case 5:
+- op = cff_op_not;
+- break;
+- case 6:
+- op = cff_op_seac;
+- break;
+- case 7:
+- op = cff_op_sbw;
+- break;
+- case 8:
+- op = cff_op_store;
+- break;
+- case 9:
+- op = cff_op_abs;
+- break;
+- case 10:
+- op = cff_op_add;
+- break;
+- case 11:
+- op = cff_op_sub;
+- break;
+- case 12:
+- op = cff_op_div;
+- break;
+- case 13:
+- op = cff_op_load;
+- break;
+- case 14:
+- op = cff_op_neg;
+- break;
+- case 15:
+- op = cff_op_eq;
+- break;
+- case 16:
+- op = cff_op_callothersubr;
+- break;
+- case 17:
+- op = cff_op_pop;
+- break;
+- case 18:
+- op = cff_op_drop;
+- break;
+- case 20:
+- op = cff_op_put;
+- break;
+- case 21:
+- op = cff_op_get;
+- break;
+- case 22:
+- op = cff_op_ifelse;
+- break;
+- case 23:
+- op = cff_op_random;
+- break;
+- case 24:
+- op = cff_op_mul;
+- break;
+- case 26:
+- op = cff_op_sqrt;
+- break;
+- case 27:
+- op = cff_op_dup;
+- break;
+- case 28:
+- op = cff_op_exch;
+- break;
+- case 29:
+- op = cff_op_index;
+- break;
+- case 30:
+- op = cff_op_roll;
+- break;
+- case 33:
+- op = cff_op_setcurrentpoint;
+- break;
+- case 34:
+- op = cff_op_hflex;
+- break;
+- case 35:
+- op = cff_op_flex;
+- break;
+- case 36:
+- op = cff_op_hflex1;
+- break;
+- case 37:
+- op = cff_op_flex1;
+- break;
+- default:
+- FT_TRACE4(( " unknown op (12, %d)\n", v ));
+- break;
+- }
+- }
+- break;
+- case 13:
+- op = cff_op_hsbw;
+- break;
+- case 14:
+- op = cff_op_endchar;
+- break;
+- case 16:
+- op = cff_op_blend;
+- break;
+- case 18:
+- op = cff_op_hstemhm;
+- break;
+- case 19:
+- op = cff_op_hintmask;
+- break;
+- case 20:
+- op = cff_op_cntrmask;
+- break;
+- case 21:
+- op = cff_op_rmoveto;
+- break;
+- case 22:
+- op = cff_op_hmoveto;
+- break;
+- case 23:
+- op = cff_op_vstemhm;
+- break;
+- case 24:
+- op = cff_op_rcurveline;
+- break;
+- case 25:
+- op = cff_op_rlinecurve;
+- break;
+- case 26:
+- op = cff_op_vvcurveto;
+- break;
+- case 27:
+- op = cff_op_hhcurveto;
+- break;
+- case 29:
+- op = cff_op_callgsubr;
+- break;
+- case 30:
+- op = cff_op_vhcurveto;
+- break;
+- case 31:
+- op = cff_op_hvcurveto;
+- break;
+- default:
+- FT_TRACE4(( " unknown op (%d)\n", v ));
+- break;
+- }
+-
+- if ( op == cff_op_unknown )
+- continue;
+-
+- /* in Multiple Master CFFs, T2 charstrings can appear in */
+- /* dictionaries, but some operators are prohibited */
+- if ( in_dict )
+- {
+- switch ( op )
+- {
+- case cff_op_hstem:
+- case cff_op_vstem:
+- case cff_op_vmoveto:
+- case cff_op_rlineto:
+- case cff_op_hlineto:
+- case cff_op_vlineto:
+- case cff_op_rrcurveto:
+- case cff_op_hstemhm:
+- case cff_op_hintmask:
+- case cff_op_cntrmask:
+- case cff_op_rmoveto:
+- case cff_op_hmoveto:
+- case cff_op_vstemhm:
+- case cff_op_rcurveline:
+- case cff_op_rlinecurve:
+- case cff_op_vvcurveto:
+- case cff_op_hhcurveto:
+- case cff_op_vhcurveto:
+- case cff_op_hvcurveto:
+- case cff_op_hflex:
+- case cff_op_flex:
+- case cff_op_hflex1:
+- case cff_op_flex1:
+- case cff_op_callsubr:
+- case cff_op_callgsubr:
+- goto MM_Error;
+-
+- default:
+- break;
+- }
+- }
+-
+- /* check arguments */
+- req_args = cff_argument_counts[op];
+- if ( req_args & CFF_COUNT_CHECK_WIDTH )
+- {
+- if ( num_args > 0 && decoder->read_width )
+- {
+- /* If `nominal_width' is non-zero, the number is really a */
+- /* difference against `nominal_width'. Else, the number here */
+- /* is truly a width, not a difference against `nominal_width'. */
+- /* If the font does not set `nominal_width', then */
+- /* `nominal_width' defaults to zero, and so we can set */
+- /* `glyph_width' to `nominal_width' plus number on the stack */
+- /* -- for either case. */
+-
+- FT_Int set_width_ok;
+-
+-
+- switch ( op )
+- {
+- case cff_op_hmoveto:
+- case cff_op_vmoveto:
+- set_width_ok = num_args & 2;
+- break;
+-
+- case cff_op_hstem:
+- case cff_op_vstem:
+- case cff_op_hstemhm:
+- case cff_op_vstemhm:
+- case cff_op_rmoveto:
+- case cff_op_hintmask:
+- case cff_op_cntrmask:
+- set_width_ok = num_args & 1;
+- break;
+-
+- case cff_op_endchar:
+- /* If there is a width specified for endchar, we either have */
+- /* 1 argument or 5 arguments. We like to argue. */
+- set_width_ok = in_dict
+- ? 0
+- : ( ( num_args == 5 ) || ( num_args == 1 ) );
+- break;
+-
+- default:
+- set_width_ok = 0;
+- break;
+- }
+-
+- if ( set_width_ok )
+- {
+- decoder->glyph_width = decoder->nominal_width +
+- ( stack[0] >> 16 );
+-
+- if ( decoder->width_only )
+- {
+- /* we only want the advance width; stop here */
+- break;
+- }
+-
+- /* Consumed an argument. */
+- num_args--;
+- }
+- }
+-
+- decoder->read_width = 0;
+- req_args = 0;
+- }
+-
+- req_args &= 0x000F;
+- if ( num_args < req_args )
+- goto Stack_Underflow;
+- args -= req_args;
+- num_args -= req_args;
+-
+- /* At this point, `args' points to the first argument of the */
+- /* operand in case `req_args' isn't zero. Otherwise, we have */
+- /* to adjust `args' manually. */
+-
+- /* Note that we only pop arguments from the stack which we */
+- /* really need and can digest so that we can continue in case */
+- /* of superfluous stack elements. */
+-
+- switch ( op )
+- {
+- case cff_op_hstem:
+- case cff_op_vstem:
+- case cff_op_hstemhm:
+- case cff_op_vstemhm:
+- /* the number of arguments is always even here */
+- FT_TRACE4((
+- op == cff_op_hstem ? " hstem\n" :
+- ( op == cff_op_vstem ? " vstem\n" :
+- ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
+-
+- if ( hinter )
+- hinter->stems( hinter->hints,
+- ( op == cff_op_hstem || op == cff_op_hstemhm ),
+- num_args / 2,
+- args - ( num_args & ~1 ) );
+-
+- decoder->num_hints += num_args / 2;
+- args = stack;
+- break;
+-
+- case cff_op_hintmask:
+- case cff_op_cntrmask:
+- FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
+-
+- /* implement vstem when needed -- */
+- /* the specification doesn't say it, but this also works */
+- /* with the 'cntrmask' operator */
+- /* */
+- if ( num_args > 0 )
+- {
+- if ( hinter )
+- hinter->stems( hinter->hints,
+- 0,
+- num_args / 2,
+- args - ( num_args & ~1 ) );
+-
+- decoder->num_hints += num_args / 2;
+- }
+-
+- /* In a valid charstring there must be at least one byte */
+- /* after `hintmask' or `cntrmask' (e.g., for a `return' */
+- /* instruction). Additionally, there must be space for */
+- /* `num_hints' bits. */
+-
+- if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
+- goto Syntax_Error;
+-
+- if ( hinter )
+- {
+- if ( op == cff_op_hintmask )
+- hinter->hintmask( hinter->hints,
+- (FT_UInt)builder->current->n_points,
+- (FT_UInt)decoder->num_hints,
+- ip );
+- else
+- hinter->counter( hinter->hints,
+- (FT_UInt)decoder->num_hints,
+- ip );
+- }
+-
+-#ifdef FT_DEBUG_LEVEL_TRACE
+- {
+- FT_UInt maskbyte;
+-
+-
+- FT_TRACE4(( " (maskbytes:" ));
+-
+- for ( maskbyte = 0;
+- maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
+- maskbyte++, ip++ )
+- FT_TRACE4(( " 0x%02X", *ip ));
+-
+- FT_TRACE4(( ")\n" ));
+- }
+-#else
+- ip += ( decoder->num_hints + 7 ) >> 3;
+-#endif
+- args = stack;
+- break;
+-
+- case cff_op_rmoveto:
+- FT_TRACE4(( " rmoveto\n" ));
+-
+- cff_builder_close_contour( builder );
+- builder->path_begun = 0;
+- x = ADD_LONG( x, args[-2] );
+- y = ADD_LONG( y, args[-1] );
+- args = stack;
+- break;
+-
+- case cff_op_vmoveto:
+- FT_TRACE4(( " vmoveto\n" ));
+-
+- cff_builder_close_contour( builder );
+- builder->path_begun = 0;
+- y = ADD_LONG( y, args[-1] );
+- args = stack;
+- break;
+-
+- case cff_op_hmoveto:
+- FT_TRACE4(( " hmoveto\n" ));
+-
+- cff_builder_close_contour( builder );
+- builder->path_begun = 0;
+- x = ADD_LONG( x, args[-1] );
+- args = stack;
+- break;
+-
+- case cff_op_rlineto:
+- FT_TRACE4(( " rlineto\n" ));
+-
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, num_args / 2 ) )
+- goto Fail;
+-
+- if ( num_args < 2 )
+- goto Stack_Underflow;
+-
+- args -= num_args & ~1;
+- while ( args < decoder->top )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 1 );
+- args += 2;
+- }
+- args = stack;
+- break;
+-
+- case cff_op_hlineto:
+- case cff_op_vlineto:
+- {
+- FT_Int phase = ( op == cff_op_hlineto );
+-
+-
+- FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
+- : " vlineto\n" ));
+-
+- if ( num_args < 0 )
+- goto Stack_Underflow;
+-
+- /* there exist subsetted fonts (found in PDFs) */
+- /* which call `hlineto' without arguments */
+- if ( num_args == 0 )
+- break;
+-
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, num_args ) )
+- goto Fail;
+-
+- args = stack;
+- while ( args < decoder->top )
+- {
+- if ( phase )
+- x = ADD_LONG( x, args[0] );
+- else
+- y = ADD_LONG( y, args[0] );
+-
+- if ( cff_builder_add_point1( builder, x, y ) )
+- goto Fail;
+-
+- args++;
+- phase ^= 1;
+- }
+- args = stack;
+- }
+- break;
+-
+- case cff_op_rrcurveto:
+- {
+- FT_Int nargs;
+-
+-
+- FT_TRACE4(( " rrcurveto\n" ));
+-
+- if ( num_args < 6 )
+- goto Stack_Underflow;
+-
+- nargs = num_args - num_args % 6;
+-
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, nargs / 2 ) )
+- goto Fail;
+-
+- args -= nargs;
+- while ( args < decoder->top )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[2] );
+- y = ADD_LONG( y, args[3] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[4] );
+- y = ADD_LONG( y, args[5] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args += 6;
+- }
+- args = stack;
+- }
+- break;
+-
+- case cff_op_vvcurveto:
+- {
+- FT_Int nargs;
+-
+-
+- FT_TRACE4(( " vvcurveto\n" ));
+-
+- if ( num_args < 4 )
+- goto Stack_Underflow;
+-
+- /* if num_args isn't of the form 4n or 4n+1, */
+- /* we enforce it by clearing the second bit */
+-
+- nargs = num_args & ~2;
+-
+- if ( cff_builder_start_point( builder, x, y ) )
+- goto Fail;
+-
+- args -= nargs;
+-
+- if ( nargs & 1 )
+- {
+- x = ADD_LONG( x, args[0] );
+- args++;
+- nargs--;
+- }
+-
+- if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
+- goto Fail;
+-
+- while ( args < decoder->top )
+- {
+- y = ADD_LONG( y, args[0] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[1] );
+- y = ADD_LONG( y, args[2] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- y = ADD_LONG( y, args[3] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args += 4;
+- }
+- args = stack;
+- }
+- break;
+-
+- case cff_op_hhcurveto:
+- {
+- FT_Int nargs;
+-
+-
+- FT_TRACE4(( " hhcurveto\n" ));
+-
+- if ( num_args < 4 )
+- goto Stack_Underflow;
+-
+- /* if num_args isn't of the form 4n or 4n+1, */
+- /* we enforce it by clearing the second bit */
+-
+- nargs = num_args & ~2;
+-
+- if ( cff_builder_start_point( builder, x, y ) )
+- goto Fail;
+-
+- args -= nargs;
+- if ( nargs & 1 )
+- {
+- y = ADD_LONG( y, args[0] );
+- args++;
+- nargs--;
+- }
+-
+- if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
+- goto Fail;
+-
+- while ( args < decoder->top )
+- {
+- x = ADD_LONG( x, args[0] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[1] );
+- y = ADD_LONG( y, args[2] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[3] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args += 4;
+- }
+- args = stack;
+- }
+- break;
+-
+- case cff_op_vhcurveto:
+- case cff_op_hvcurveto:
+- {
+- FT_Int phase;
+- FT_Int nargs;
+-
+-
+- FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
+- : " hvcurveto\n" ));
+-
+- if ( cff_builder_start_point( builder, x, y ) )
+- goto Fail;
+-
+- if ( num_args < 4 )
+- goto Stack_Underflow;
+-
+- /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
+- /* we enforce it by clearing the second bit */
+-
+- nargs = num_args & ~2;
+-
+- args -= nargs;
+- if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
+- goto Stack_Underflow;
+-
+- phase = ( op == cff_op_hvcurveto );
+-
+- while ( nargs >= 4 )
+- {
+- nargs -= 4;
+- if ( phase )
+- {
+- x = ADD_LONG( x, args[0] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[1] );
+- y = ADD_LONG( y, args[2] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- y = ADD_LONG( y, args[3] );
+- if ( nargs == 1 )
+- x = ADD_LONG( x, args[4] );
+- cff_builder_add_point( builder, x, y, 1 );
+- }
+- else
+- {
+- y = ADD_LONG( y, args[0] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[1] );
+- y = ADD_LONG( y, args[2] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[3] );
+- if ( nargs == 1 )
+- y = ADD_LONG( y, args[4] );
+- cff_builder_add_point( builder, x, y, 1 );
+- }
+- args += 4;
+- phase ^= 1;
+- }
+- args = stack;
+- }
+- break;
+-
+- case cff_op_rlinecurve:
+- {
+- FT_Int num_lines;
+- FT_Int nargs;
+-
+-
+- FT_TRACE4(( " rlinecurve\n" ));
+-
+- if ( num_args < 8 )
+- goto Stack_Underflow;
+-
+- nargs = num_args & ~1;
+- num_lines = ( nargs - 6 ) / 2;
+-
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, num_lines + 3 ) )
+- goto Fail;
+-
+- args -= nargs;
+-
+- /* first, add the line segments */
+- while ( num_lines > 0 )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args += 2;
+- num_lines--;
+- }
+-
+- /* then the curve */
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[2] );
+- y = ADD_LONG( y, args[3] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[4] );
+- y = ADD_LONG( y, args[5] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args = stack;
+- }
+- break;
+-
+- case cff_op_rcurveline:
+- {
+- FT_Int num_curves;
+- FT_Int nargs;
+-
+-
+- FT_TRACE4(( " rcurveline\n" ));
+-
+- if ( num_args < 8 )
+- goto Stack_Underflow;
+-
+- nargs = num_args - 2;
+- nargs = nargs - nargs % 6 + 2;
+- num_curves = ( nargs - 2 ) / 6;
+-
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, num_curves * 3 + 2 ) )
+- goto Fail;
+-
+- args -= nargs;
+-
+- /* first, add the curves */
+- while ( num_curves > 0 )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[2] );
+- y = ADD_LONG( y, args[3] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- x = ADD_LONG( x, args[4] );
+- y = ADD_LONG( y, args[5] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args += 6;
+- num_curves--;
+- }
+-
+- /* then the final line */
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args = stack;
+- }
+- break;
+-
+- case cff_op_hflex1:
+- {
+- FT_Pos start_y;
+-
+-
+- FT_TRACE4(( " hflex1\n" ));
+-
+- /* adding five more points: 4 control points, 1 on-curve point */
+- /* -- make sure we have enough space for the start point if it */
+- /* needs to be added */
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, 6 ) )
+- goto Fail;
+-
+- /* record the starting point's y position for later use */
+- start_y = y;
+-
+- /* first control point */
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* second control point */
+- x = ADD_LONG( x, args[2] );
+- y = ADD_LONG( y, args[3] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* join point; on curve, with y-value the same as the last */
+- /* control point's y-value */
+- x = ADD_LONG( x, args[4] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- /* third control point, with y-value the same as the join */
+- /* point's y-value */
+- x = ADD_LONG( x, args[5] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* fourth control point */
+- x = ADD_LONG( x, args[6] );
+- y = ADD_LONG( y, args[7] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* ending point, with y-value the same as the start */
+- x = ADD_LONG( x, args[8] );
+- y = start_y;
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args = stack;
+- break;
+- }
+-
+- case cff_op_hflex:
+- {
+- FT_Pos start_y;
+-
+-
+- FT_TRACE4(( " hflex\n" ));
+-
+- /* adding six more points; 4 control points, 2 on-curve points */
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, 6 ) )
+- goto Fail;
+-
+- /* record the starting point's y-position for later use */
+- start_y = y;
+-
+- /* first control point */
+- x = ADD_LONG( x, args[0] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* second control point */
+- x = ADD_LONG( x, args[1] );
+- y = ADD_LONG( y, args[2] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* join point; on curve, with y-value the same as the last */
+- /* control point's y-value */
+- x = ADD_LONG( x, args[3] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- /* third control point, with y-value the same as the join */
+- /* point's y-value */
+- x = ADD_LONG( x, args[4] );
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* fourth control point */
+- x = ADD_LONG( x, args[5] );
+- y = start_y;
+- cff_builder_add_point( builder, x, y, 0 );
+-
+- /* ending point, with y-value the same as the start point's */
+- /* y-value -- we don't add this point, though */
+- x = ADD_LONG( x, args[6] );
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args = stack;
+- break;
+- }
+-
+- case cff_op_flex1:
+- {
+- FT_Pos start_x, start_y; /* record start x, y values for */
+- /* alter use */
+- FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
+- /* algorithm below */
+- FT_Int horizontal, count;
+- FT_Fixed* temp;
+-
+-
+- FT_TRACE4(( " flex1\n" ));
+-
+- /* adding six more points; 4 control points, 2 on-curve points */
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, 6 ) )
+- goto Fail;
+-
+- /* record the starting point's x, y position for later use */
+- start_x = x;
+- start_y = y;
+-
+- /* XXX: figure out whether this is supposed to be a horizontal */
+- /* or vertical flex; the Type 2 specification is vague... */
+-
+- temp = args;
+-
+- /* grab up to the last argument */
+- for ( count = 5; count > 0; count-- )
+- {
+- dx = ADD_LONG( dx, temp[0] );
+- dy = ADD_LONG( dy, temp[1] );
+- temp += 2;
+- }
+-
+- if ( dx < 0 )
+- dx = -dx;
+- if ( dy < 0 )
+- dy = -dy;
+-
+- /* strange test, but here it is... */
+- horizontal = ( dx > dy );
+-
+- for ( count = 5; count > 0; count-- )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y,
+- (FT_Bool)( count == 3 ) );
+- args += 2;
+- }
+-
+- /* is last operand an x- or y-delta? */
+- if ( horizontal )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = start_y;
+- }
+- else
+- {
+- x = start_x;
+- y = ADD_LONG( y, args[0] );
+- }
+-
+- cff_builder_add_point( builder, x, y, 1 );
+-
+- args = stack;
+- break;
+- }
+-
+- case cff_op_flex:
+- {
+- FT_UInt count;
+-
+-
+- FT_TRACE4(( " flex\n" ));
+-
+- if ( cff_builder_start_point( builder, x, y ) ||
+- cff_check_points( builder, 6 ) )
+- goto Fail;
+-
+- for ( count = 6; count > 0; count-- )
+- {
+- x = ADD_LONG( x, args[0] );
+- y = ADD_LONG( y, args[1] );
+- cff_builder_add_point( builder, x, y,
+- (FT_Bool)( count == 4 || count == 1 ) );
+- args += 2;
+- }
+-
+- args = stack;
+- }
+- break;
+-
+- case cff_op_seac:
+- FT_TRACE4(( " seac\n" ));
+-
+- error = cff_operator_seac( decoder,
+- args[0], args[1], args[2],
+- (FT_Int)( args[3] >> 16 ),
+- (FT_Int)( args[4] >> 16 ) );
+-
+- /* add current outline to the glyph slot */
+- FT_GlyphLoader_Add( builder->loader );
+-
+- /* return now! */
+- FT_TRACE4(( "\n" ));
+- return error;
+-
+- case cff_op_endchar:
+- /* in dictionaries, `endchar' simply indicates end of data */
+- if ( in_dict )
+- return error;
+-
+- FT_TRACE4(( " endchar\n" ));
+-
+- /* We are going to emulate the seac operator. */
+- if ( num_args >= 4 )
+- {
+- /* Save glyph width so that the subglyphs don't overwrite it. */
+- FT_Pos glyph_width = decoder->glyph_width;
+-
+-
+- error = cff_operator_seac( decoder,
+- 0L, args[-4], args[-3],
+- (FT_Int)( args[-2] >> 16 ),
+- (FT_Int)( args[-1] >> 16 ) );
+-
+- decoder->glyph_width = glyph_width;
+- }
+- else
+- {
+- cff_builder_close_contour( builder );
+-
+- /* close hints recording session */
+- if ( hinter )
+- {
+- if ( hinter->close( hinter->hints,
+- (FT_UInt)builder->current->n_points ) )
+- goto Syntax_Error;
+-
+- /* apply hints to the loaded glyph outline now */
+- error = hinter->apply( hinter->hints,
+- builder->current,
+- (PSH_Globals)builder->hints_globals,
+- decoder->hint_mode );
+- if ( error )
+- goto Fail;
+- }
+-
+- /* add current outline to the glyph slot */
+- FT_GlyphLoader_Add( builder->loader );
+- }
+-
+- /* return now! */
+- FT_TRACE4(( "\n" ));
+- return error;
+-
+- case cff_op_abs:
+- FT_TRACE4(( " abs\n" ));
+-
+- if ( args[0] < 0 )
+- {
+- if ( args[0] == FT_LONG_MIN )
+- args[0] = FT_LONG_MAX;
+- else
+- args[0] = -args[0];
+- }
+- args++;
+- break;
+-
+- case cff_op_add:
+- FT_TRACE4(( " add\n" ));
+-
+- args[0] = ADD_LONG( args[0], args[1] );
+- args++;
+- break;
+-
+- case cff_op_sub:
+- FT_TRACE4(( " sub\n" ));
+-
+- args[0] = SUB_LONG( args[0], args[1] );
+- args++;
+- break;
+-
+- case cff_op_div:
+- FT_TRACE4(( " div\n" ));
+-
+- args[0] = FT_DivFix( args[0], args[1] );
+- args++;
+- break;
+-
+- case cff_op_neg:
+- FT_TRACE4(( " neg\n" ));
+-
+- if ( args[0] == FT_LONG_MIN )
+- args[0] = FT_LONG_MAX;
+- args[0] = -args[0];
+- args++;
+- break;
+-
+- case cff_op_random:
+- FT_TRACE4(( " random\n" ));
+-
+- /* only use the lower 16 bits of `random' */
+- /* to generate a number in the range (0;1] */
+- args[0] = (FT_Fixed)
+- ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
+- args++;
+-
+- decoder->current_subfont->random =
+- cff_random( decoder->current_subfont->random );
+- break;
+-
+- case cff_op_mul:
+- FT_TRACE4(( " mul\n" ));
+-
+- args[0] = FT_MulFix( args[0], args[1] );
+- args++;
+- break;
+-
+- case cff_op_sqrt:
+- FT_TRACE4(( " sqrt\n" ));
+-
+- if ( args[0] > 0 )
+- {
+- FT_Fixed root = args[0];
+- FT_Fixed new_root;
+-
+-
+- for (;;)
+- {
+- new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
+- if ( new_root == root )
+- break;
+- root = new_root;
+- }
+- args[0] = new_root;
+- }
+- else
+- args[0] = 0;
+- args++;
+- break;
+-
+- case cff_op_drop:
+- /* nothing */
+- FT_TRACE4(( " drop\n" ));
+-
+- break;
+-
+- case cff_op_exch:
+- {
+- FT_Fixed tmp;
+-
+-
+- FT_TRACE4(( " exch\n" ));
+-
+- tmp = args[0];
+- args[0] = args[1];
+- args[1] = tmp;
+- args += 2;
+- }
+- break;
+-
+- case cff_op_index:
+- {
+- FT_Int idx = (FT_Int)( args[0] >> 16 );
+-
+-
+- FT_TRACE4(( " index\n" ));
+-
+- if ( idx < 0 )
+- idx = 0;
+- else if ( idx > num_args - 2 )
+- idx = num_args - 2;
+- args[0] = args[-( idx + 1 )];
+- args++;
+- }
+- break;
+-
+- case cff_op_roll:
+- {
+- FT_Int count = (FT_Int)( args[0] >> 16 );
+- FT_Int idx = (FT_Int)( args[1] >> 16 );
+-
+-
+- FT_TRACE4(( " roll\n" ));
+-
+- if ( count <= 0 )
+- count = 1;
+-
+- args -= count;
+- if ( args < stack )
+- goto Stack_Underflow;
+-
+- if ( idx >= 0 )
+- {
+- while ( idx > 0 )
+- {
+- FT_Fixed tmp = args[count - 1];
+- FT_Int i;
+-
+-
+- for ( i = count - 2; i >= 0; i-- )
+- args[i + 1] = args[i];
+- args[0] = tmp;
+- idx--;
+- }
+- }
+- else
+- {
+- while ( idx < 0 )
+- {
+- FT_Fixed tmp = args[0];
+- FT_Int i;
+-
+-
+- for ( i = 0; i < count - 1; i++ )
+- args[i] = args[i + 1];
+- args[count - 1] = tmp;
+- idx++;
+- }
+- }
+- args += count;
+- }
+- break;
+-
+- case cff_op_dup:
+- FT_TRACE4(( " dup\n" ));
+-
+- args[1] = args[0];
+- args += 2;
+- break;
+-
+- case cff_op_put:
+- {
+- FT_Fixed val = args[0];
+- FT_Int idx = (FT_Int)( args[1] >> 16 );
+-
+-
+- FT_TRACE4(( " put\n" ));
+-
+- /* the Type2 specification before version 16-March-2000 */
+- /* didn't give a hard-coded size limit of the temporary */
+- /* storage array; instead, an argument of the */
+- /* `MultipleMaster' operator set the size */
+- if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
+- decoder->buildchar[idx] = val;
+- }
+- break;
+-
+- case cff_op_get:
+- {
+- FT_Int idx = (FT_Int)( args[0] >> 16 );
+- FT_Fixed val = 0;
+-
+-
+- FT_TRACE4(( " get\n" ));
+-
+- if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
+- val = decoder->buildchar[idx];
+-
+- args[0] = val;
+- args++;
+- }
+- break;
+-
+- case cff_op_store:
+- /* this operator was removed from the Type2 specification */
+- /* in version 16-March-2000 */
+-
+- /* since we currently don't handle interpolation of multiple */
+- /* master fonts, this is a no-op */
+- FT_TRACE4(( " store\n"));
+- break;
+-
+- case cff_op_load:
+- /* this operator was removed from the Type2 specification */
+- /* in version 16-March-2000 */
+- {
+- FT_Int reg_idx = (FT_Int)args[0];
+- FT_Int idx = (FT_Int)args[1];
+- FT_Int count = (FT_Int)args[2];
+-
+-
+- FT_TRACE4(( " load\n" ));
+-
+- /* since we currently don't handle interpolation of multiple */
+- /* master fonts, we store a vector [1 0 0 ...] in the */
+- /* temporary storage array regardless of the Registry index */
+- if ( reg_idx >= 0 && reg_idx <= 2 &&
+- idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
+- count >= 0 && count <= num_axes )
+- {
+- FT_Int end, i;
+-
+-
+- end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
+-
+- if ( idx < end )
+- decoder->buildchar[idx] = 1 << 16;
+-
+- for ( i = idx + 1; i < end; i++ )
+- decoder->buildchar[i] = 0;
+- }
+- }
+- break;
+-
+- case cff_op_blend:
+- /* this operator was removed from the Type2 specification */
+- /* in version 16-March-2000 */
+- {
+- FT_Int num_results = (FT_Int)( args[0] >> 16 );
+-
+-
+- FT_TRACE4(( " blend\n" ));
+-
+- if ( num_results < 0 )
+- goto Syntax_Error;
+-
+- if ( num_results * (FT_Int)num_designs > num_args )
+- goto Stack_Underflow;
+-
+- /* since we currently don't handle interpolation of multiple */
+- /* master fonts, return the `num_results' values of the */
+- /* first master */
+- args -= num_results * ( num_designs - 1 );
+- num_args -= num_results * ( num_designs - 1 );
+- }
+- break;
+-
+- case cff_op_dotsection:
+- /* this operator is deprecated and ignored by the parser */
+- FT_TRACE4(( " dotsection\n" ));
+- break;
+-
+- case cff_op_closepath:
+- /* this is an invalid Type 2 operator; however, there */
+- /* exist fonts which are incorrectly converted from probably */
+- /* Type 1 to CFF, and some parsers seem to accept it */
+-
+- FT_TRACE4(( " closepath (invalid op)\n" ));
+-
+- args = stack;
+- break;
+-
+- case cff_op_hsbw:
+- /* this is an invalid Type 2 operator; however, there */
+- /* exist fonts which are incorrectly converted from probably */
+- /* Type 1 to CFF, and some parsers seem to accept it */
+-
+- FT_TRACE4(( " hsbw (invalid op)\n" ));
+-
+- decoder->glyph_width =
+- ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
+-
+- decoder->builder.left_bearing.x = args[0];
+- decoder->builder.left_bearing.y = 0;
+-
+- x = ADD_LONG( decoder->builder.pos_x, args[0] );
+- y = decoder->builder.pos_y;
+- args = stack;
+- break;
+-
+- case cff_op_sbw:
+- /* this is an invalid Type 2 operator; however, there */
+- /* exist fonts which are incorrectly converted from probably */
+- /* Type 1 to CFF, and some parsers seem to accept it */
+-
+- FT_TRACE4(( " sbw (invalid op)\n" ));
+-
+- decoder->glyph_width =
+- ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
+-
+- decoder->builder.left_bearing.x = args[0];
+- decoder->builder.left_bearing.y = args[1];
+-
+- x = ADD_LONG( decoder->builder.pos_x, args[0] );
+- y = ADD_LONG( decoder->builder.pos_y, args[1] );
+- args = stack;
+- break;
+-
+- case cff_op_setcurrentpoint:
+- /* this is an invalid Type 2 operator; however, there */
+- /* exist fonts which are incorrectly converted from probably */
+- /* Type 1 to CFF, and some parsers seem to accept it */
+-
+- FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
+-
+- x = ADD_LONG( decoder->builder.pos_x, args[0] );
+- y = ADD_LONG( decoder->builder.pos_y, args[1] );
+- args = stack;
+- break;
+-
+- case cff_op_callothersubr:
+- /* this is an invalid Type 2 operator; however, there */
+- /* exist fonts which are incorrectly converted from probably */
+- /* Type 1 to CFF, and some parsers seem to accept it */
+-
+- FT_TRACE4(( " callothersubr (invalid op)\n" ));
+-
+- /* subsequent `pop' operands should add the arguments, */
+- /* this is the implementation described for `unknown' other */
+- /* subroutines in the Type1 spec. */
+- /* */
+- /* XXX Fix return arguments (see discussion below). */
+- args -= 2 + ( args[-2] >> 16 );
+- if ( args < stack )
+- goto Stack_Underflow;
+- break;
+-
+- case cff_op_pop:
+- /* this is an invalid Type 2 operator; however, there */
+- /* exist fonts which are incorrectly converted from probably */
+- /* Type 1 to CFF, and some parsers seem to accept it */
+-
+- FT_TRACE4(( " pop (invalid op)\n" ));
+-
+- /* XXX Increasing `args' is wrong: After a certain number of */
+- /* `pop's we get a stack overflow. Reason for doing it is */
+- /* code like this (actually found in a CFF font): */
+- /* */
+- /* 17 1 3 callothersubr */
+- /* pop */
+- /* callsubr */
+- /* */
+- /* Since we handle `callothersubr' as a no-op, and */
+- /* `callsubr' needs at least one argument, `pop' can't be a */
+- /* no-op too as it basically should be. */
+- /* */
+- /* The right solution would be to provide real support for */
+- /* `callothersubr' as done in `t1decode.c', however, given */
+- /* the fact that CFF fonts with `pop' are invalid, it is */
+- /* questionable whether it is worth the time. */
+- args++;
+- break;
+-
+- case cff_op_and:
+- {
+- FT_Fixed cond = ( args[0] && args[1] );
+-
+-
+- FT_TRACE4(( " and\n" ));
+-
+- args[0] = cond ? 0x10000L : 0;
+- args++;
+- }
+- break;
+-
+- case cff_op_or:
+- {
+- FT_Fixed cond = ( args[0] || args[1] );
+-
+-
+- FT_TRACE4(( " or\n" ));
+-
+- args[0] = cond ? 0x10000L : 0;
+- args++;
+- }
+- break;
+-
+- case cff_op_not:
+- {
+- FT_Fixed cond = !args[0];
+-
+-
+- FT_TRACE4(( " not\n" ));
+-
+- args[0] = cond ? 0x10000L : 0;
+- args++;
+- }
+- break;
+-
+- case cff_op_eq:
+- {
+- FT_Fixed cond = ( args[0] == args[1] );
+-
+-
+- FT_TRACE4(( " eq\n" ));
+-
+- args[0] = cond ? 0x10000L : 0;
+- args++;
+- }
+- break;
+-
+- case cff_op_ifelse:
+- {
+- FT_Fixed cond = ( args[2] <= args[3] );
+-
+-
+- FT_TRACE4(( " ifelse\n" ));
+-
+- if ( !cond )
+- args[0] = args[1];
+- args++;
+- }
+- break;
+-
+- case cff_op_callsubr:
+- {
+- FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
+- decoder->locals_bias );
+-
+-
+- FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
+- idx,
+- zone - decoder->zones + 1 ));
+-
+- if ( idx >= decoder->num_locals )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " invalid local subr index\n" ));
+- goto Syntax_Error;
+- }
+-
+- if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " too many nested subrs\n" ));
+- goto Syntax_Error;
+- }
+-
+- zone->cursor = ip; /* save current instruction pointer */
+-
+- zone++;
+- zone->base = decoder->locals[idx];
+- zone->limit = decoder->locals[idx + 1];
+- zone->cursor = zone->base;
+-
+- if ( !zone->base || zone->limit == zone->base )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " invoking empty subrs\n" ));
+- goto Syntax_Error;
+- }
+-
+- decoder->zone = zone;
+- ip = zone->base;
+- limit = zone->limit;
+- }
+- break;
+-
+- case cff_op_callgsubr:
+- {
+- FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
+- decoder->globals_bias );
+-
+-
+- FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
+- idx,
+- zone - decoder->zones + 1 ));
+-
+- if ( idx >= decoder->num_globals )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " invalid global subr index\n" ));
+- goto Syntax_Error;
+- }
+-
+- if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " too many nested subrs\n" ));
+- goto Syntax_Error;
+- }
+-
+- zone->cursor = ip; /* save current instruction pointer */
+-
+- zone++;
+- zone->base = decoder->globals[idx];
+- zone->limit = decoder->globals[idx + 1];
+- zone->cursor = zone->base;
+-
+- if ( !zone->base || zone->limit == zone->base )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " invoking empty subrs\n" ));
+- goto Syntax_Error;
+- }
+-
+- decoder->zone = zone;
+- ip = zone->base;
+- limit = zone->limit;
+- }
+- break;
+-
+- case cff_op_return:
+- FT_TRACE4(( " return (leaving level %d)\n",
+- decoder->zone - decoder->zones ));
++ FT_LOCAL_DEF( FT_Error )
++ cff_get_glyph_data( TT_Face face,
++ FT_UInt glyph_index,
++ FT_Byte** pointer,
++ FT_ULong* length )
++ {
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ /* For incremental fonts get the character data using the */
++ /* callback function. */
++ if ( face->root.internal->incremental_interface )
++ {
++ FT_Data data;
++ FT_Error error =
++ face->root.internal->incremental_interface->funcs->get_glyph_data(
++ face->root.internal->incremental_interface->object,
++ glyph_index, &data );
+
+- if ( decoder->zone <= decoder->zones )
+- {
+- FT_ERROR(( "cff_decoder_parse_charstrings:"
+- " unexpected return\n" ));
+- goto Syntax_Error;
+- }
+
+- decoder->zone--;
+- zone = decoder->zone;
+- ip = zone->cursor;
+- limit = zone->limit;
+- break;
++ *pointer = (FT_Byte*)data.pointer;
++ *length = (FT_ULong)data.length;
+
+- default:
+- FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
++ return error;
++ }
++ else
++#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+
+- if ( ip[-1] == 12 )
+- FT_ERROR(( " %d", ip[0] ));
+- FT_ERROR(( "\n" ));
++ {
++ CFF_Font cff = (CFF_Font)(face->extra.data);
+
+- return FT_THROW( Unimplemented_Feature );
+- }
+
+- decoder->top = args;
++ return cff_index_access_element( &cff->charstrings_index, glyph_index,
++ pointer, length );
++ }
++ }
+
+- if ( decoder->top - stack >= CFF_MAX_OPERANDS )
+- goto Stack_Overflow;
+
+- } /* general operator processing */
++ FT_LOCAL_DEF( void )
++ cff_free_glyph_data( TT_Face face,
++ FT_Byte** pointer,
++ FT_ULong length )
++ {
++#ifndef FT_CONFIG_OPTION_INCREMENTAL
++ FT_UNUSED( length );
++#endif
+
+- } /* while ip < limit */
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ /* For incremental fonts get the character data using the */
++ /* callback function. */
++ if ( face->root.internal->incremental_interface )
++ {
++ FT_Data data;
+
+- FT_TRACE4(( "..end..\n\n" ));
+
+- Fail:
+- return error;
++ data.pointer = *pointer;
++ data.length = (FT_Int)length;
+
+- MM_Error:
+- FT_TRACE4(( "cff_decoder_parse_charstrings:"
+- " invalid opcode found in top DICT charstring\n"));
+- return FT_THROW( Invalid_File_Format );
++ face->root.internal->incremental_interface->funcs->free_glyph_data(
++ face->root.internal->incremental_interface->object, &data );
++ }
++ else
++#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+
+- Syntax_Error:
+- FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
+- return FT_THROW( Invalid_File_Format );
++ {
++ CFF_Font cff = (CFF_Font)(face->extra.data);
+
+- Stack_Underflow:
+- FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
+- return FT_THROW( Too_Few_Arguments );
+
+- Stack_Overflow:
+- FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
+- return FT_THROW( Stack_Overflow );
++ cff_index_forget_element( &cff->charstrings_index, pointer );
++ }
+ }
+
+-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+-
+
+ /*************************************************************************/
+ /*************************************************************************/
+@@ -2704,11 +142,14 @@
+ FT_Int glyph_index;
+ CFF_Font cff = (CFF_Font)face->other;
+
++ PSAux_Service psaux = (PSAux_Service)face->psaux;
++ const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs;
++
+
+ *max_advance = 0;
+
+ /* Initialize load decoder */
+- cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
++ decoder_funcs->init( &decoder, face, 0, 0, 0, 0, 0, 0 );
+
+ decoder.builder.metrics_only = 1;
+ decoder.builder.load_points = 0;
+@@ -2727,12 +168,12 @@
+ &charstring, &charstring_len );
+ if ( !error )
+ {
+- error = cff_decoder_prepare( &decoder, size, glyph_index );
++ error = decoder_funcs->prepare( &decoder, size, glyph_index );
+ if ( !error )
+- error = cff_decoder_parse_charstrings( &decoder,
+- charstring,
+- charstring_len,
+- 0 );
++ error = decoder_funcs->parse_charstrings_old( &decoder,
++ charstring,
++ charstring_len,
++ 0 );
+
+ cff_free_glyph_data( face, &charstring, &charstring_len );
+ }
+@@ -2758,10 +199,14 @@
+ {
+ FT_Error error;
+ CFF_Decoder decoder;
++ PS_Decoder psdecoder;
+ TT_Face face = (TT_Face)glyph->root.face;
+ FT_Bool hinting, scaled, force_scaling;
+ CFF_Font cff = (CFF_Font)face->extra.data;
+
++ PSAux_Service psaux = (PSAux_Service)face->psaux;
++ const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs;
++
+ FT_Matrix font_matrix;
+ FT_Vector font_offset;
+
+@@ -2951,7 +396,7 @@
+
+ {
+ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+- CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face );
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
+ #endif
+
+
+@@ -2959,8 +404,10 @@
+ FT_ULong charstring_len;
+
+
+- cff_decoder_init( &decoder, face, size, glyph, hinting,
+- FT_LOAD_TARGET_MODE( load_flags ) );
++ decoder_funcs->init( &decoder, face, size, glyph, hinting,
++ FT_LOAD_TARGET_MODE( load_flags ),
++ cff_get_glyph_data,
++ cff_free_glyph_data );
+
+ /* this is for pure CFFs */
+ if ( load_flags & FT_LOAD_ADVANCE_ONLY )
+@@ -2975,23 +422,25 @@
+ if ( error )
+ goto Glyph_Build_Finished;
+
+- error = cff_decoder_prepare( &decoder, size, glyph_index );
++ error = decoder_funcs->prepare( &decoder, size, glyph_index );
+ if ( error )
+ goto Glyph_Build_Finished;
+
+ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ /* choose which CFF renderer to use */
+ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
+- error = cff_decoder_parse_charstrings( &decoder,
+- charstring,
+- charstring_len,
+- 0 );
++ error = decoder_funcs->parse_charstrings_old( &decoder,
++ charstring,
++ charstring_len,
++ 0 );
+ else
+ #endif
+ {
+- error = cf2_decoder_parse_charstrings( &decoder,
+- charstring,
+- charstring_len );
++ psaux->ps_decoder_init( &psdecoder, &decoder, FALSE );
++
++ error = decoder_funcs->parse_charstrings( &psdecoder,
++ charstring,
++ charstring_len );
+
+ /* Adobe's engine uses 16.16 numbers everywhere; */
+ /* as a consequence, glyphs larger than 2000ppem get rejected */
+@@ -3004,9 +453,9 @@
+ force_scaling = TRUE;
+ glyph->hint = hinting;
+
+- error = cf2_decoder_parse_charstrings( &decoder,
+- charstring,
+- charstring_len );
++ error = decoder_funcs->parse_charstrings( &psdecoder,
++ charstring,
++ charstring_len );
+ }
+ }
+
+@@ -3044,7 +493,7 @@
+ Glyph_Build_Finished:
+ /* save new glyph tables, if no error */
+ if ( !error )
+- cff_builder_done( &decoder.builder );
++ decoder.builder.funcs.done( &decoder.builder );
+ /* XXX: anything to do for broken glyph entry? */
+ }
+
+diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
+index 0fa93b4398..ed291b87d4 100644
+--- a/src/cff/cffgload.h
++++ b/src/cff/cffgload.h
+@@ -22,119 +22,11 @@
+
+ #include <ft2build.h>
+ #include FT_FREETYPE_H
+-#include "cffobjs.h"
++#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+
+
+ FT_BEGIN_HEADER
+
+-
+-#define CFF_MAX_OPERANDS 48
+-#define CFF_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */
+- /* only 10 are allowed but there exist */
+- /* fonts like `HiraKakuProN-W3.ttf' */
+- /* (Hiragino Kaku Gothic ProN W3; */
+- /* 8.2d6e1; 2014-12-19) that exceed */
+- /* this limit */
+-#define CFF_MAX_TRANS_ELEMENTS 32
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Structure> */
+- /* CFF_Builder */
+- /* */
+- /* <Description> */
+- /* A structure used during glyph loading to store its outline. */
+- /* */
+- /* <Fields> */
+- /* memory :: The current memory object. */
+- /* */
+- /* face :: The current face object. */
+- /* */
+- /* glyph :: The current glyph slot. */
+- /* */
+- /* loader :: The current glyph loader. */
+- /* */
+- /* base :: The base glyph outline. */
+- /* */
+- /* current :: The current glyph outline. */
+- /* */
+- /* pos_x :: The horizontal translation (if composite glyph). */
+- /* */
+- /* pos_y :: The vertical translation (if composite glyph). */
+- /* */
+- /* left_bearing :: The left side bearing point. */
+- /* */
+- /* advance :: The horizontal advance vector. */
+- /* */
+- /* bbox :: Unused. */
+- /* */
+- /* path_begun :: A flag which indicates that a new path has begun. */
+- /* */
+- /* load_points :: If this flag is not set, no points are loaded. */
+- /* */
+- /* no_recurse :: Set but not used. */
+- /* */
+- /* metrics_only :: A boolean indicating that we only want to compute */
+- /* the metrics of a given glyph, not load all of its */
+- /* points. */
+- /* */
+- /* hints_funcs :: Auxiliary pointer for hinting. */
+- /* */
+- /* hints_globals :: Auxiliary pointer for hinting. */
+- /* */
+- typedef struct CFF_Builder_
+- {
+- FT_Memory memory;
+- TT_Face face;
+- CFF_GlyphSlot glyph;
+- FT_GlyphLoader loader;
+- FT_Outline* base;
+- FT_Outline* current;
+-
+- FT_Pos pos_x;
+- FT_Pos pos_y;
+-
+- FT_Vector left_bearing;
+- FT_Vector advance;
+-
+- FT_BBox bbox; /* bounding box */
+- FT_Bool path_begun;
+- FT_Bool load_points;
+- FT_Bool no_recurse;
+-
+- FT_Bool metrics_only;
+-
+- void* hints_funcs; /* hinter-specific */
+- void* hints_globals; /* hinter-specific */
+-
+- } CFF_Builder;
+-
+-
+- FT_LOCAL( FT_Error )
+- cff_check_points( CFF_Builder* builder,
+- FT_Int count );
+-
+- FT_LOCAL( void )
+- cff_builder_add_point( CFF_Builder* builder,
+- FT_Pos x,
+- FT_Pos y,
+- FT_Byte flag );
+- FT_LOCAL( FT_Error )
+- cff_builder_add_point1( CFF_Builder* builder,
+- FT_Pos x,
+- FT_Pos y );
+- FT_LOCAL( FT_Error )
+- cff_builder_start_point( CFF_Builder* builder,
+- FT_Pos x,
+- FT_Pos y );
+- FT_LOCAL( void )
+- cff_builder_close_contour( CFF_Builder* builder );
+-
+-
+- FT_LOCAL( FT_Int )
+- cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
+- FT_Int charcode );
+ FT_LOCAL( FT_Error )
+ cff_get_glyph_data( TT_Face face,
+ FT_UInt glyph_index,
+@@ -146,74 +38,6 @@ FT_BEGIN_HEADER
+ FT_ULong length );
+
+
+- /* execution context charstring zone */
+-
+- typedef struct CFF_Decoder_Zone_
+- {
+- FT_Byte* base;
+- FT_Byte* limit;
+- FT_Byte* cursor;
+-
+- } CFF_Decoder_Zone;
+-
+-
+- typedef struct CFF_Decoder_
+- {
+- CFF_Builder builder;
+- CFF_Font cff;
+-
+- FT_Fixed stack[CFF_MAX_OPERANDS + 1];
+- FT_Fixed* top;
+-
+- CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1];
+- CFF_Decoder_Zone* zone;
+-
+- FT_Int flex_state;
+- FT_Int num_flex_vectors;
+- FT_Vector flex_vectors[7];
+-
+- FT_Pos glyph_width;
+- FT_Pos nominal_width;
+-
+- FT_Bool read_width;
+- FT_Bool width_only;
+- FT_Int num_hints;
+- FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS];
+-
+- FT_UInt num_locals;
+- FT_UInt num_globals;
+-
+- FT_Int locals_bias;
+- FT_Int globals_bias;
+-
+- FT_Byte** locals;
+- FT_Byte** globals;
+-
+- FT_Byte** glyph_names; /* for pure CFF fonts only */
+- FT_UInt num_glyphs; /* number of glyphs in font */
+-
+- FT_Render_Mode hint_mode;
+-
+- FT_Bool seac;
+-
+- CFF_SubFont current_subfont; /* for current glyph_index */
+-
+- } CFF_Decoder;
+-
+-
+- FT_LOCAL( void )
+- cff_decoder_init( CFF_Decoder* decoder,
+- TT_Face face,
+- CFF_Size size,
+- CFF_GlyphSlot slot,
+- FT_Bool hinting,
+- FT_Render_Mode hint_mode );
+-
+- FT_LOCAL( FT_Error )
+- cff_decoder_prepare( CFF_Decoder* decoder,
+- CFF_Size size,
+- FT_UInt glyph_index );
+-
+ #if 0 /* unused until we support pure CFF fonts */
+
+ /* Compute the maximum advance width of a font through quick parsing */
+@@ -223,13 +47,6 @@ FT_BEGIN_HEADER
+
+ #endif /* 0 */
+
+-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+- FT_LOCAL( FT_Error )
+- cff_decoder_parse_charstrings( CFF_Decoder* decoder,
+- FT_Byte* charstring_base,
+- FT_ULong charstring_len,
+- FT_Bool in_dict );
+-#endif
+
+ FT_LOCAL( FT_Error )
+ cff_slot_load( CFF_GlyphSlot glyph,
+diff --git a/src/cff/cffload.c b/src/cff/cffload.c
+index 12420384af..e8479d48fd 100644
+--- a/src/cff/cffload.c
++++ b/src/cff/cffload.c
+@@ -1345,19 +1345,14 @@
+ for ( i = 0; i < numBlends; i++ )
+ {
+ const FT_Int32* weight = &blend->BV[1];
+- FT_Int32 sum;
++ FT_UInt32 sum;
+
+
+ /* convert inputs to 16.16 fixed point */
+- sum = cff_parse_num( parser, &parser->stack[i + base] ) * 65536;
++ sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
+
+ for ( j = 1; j < blend->lenBV; j++ )
+- sum = ADD_INT32(
+- sum,
+- FT_MulFix(
+- *weight++,
+- cff_parse_num( parser,
+- &parser->stack[delta++] ) * 65536 ) );
++ sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;
+
+ /* point parser stack to new value on blend_stack */
+ parser->stack[i + base] = subFont->blend_top;
+@@ -1367,10 +1362,10 @@
+ /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */
+ /* decode of this, which rounds to an integer. */
+ *subFont->blend_top++ = 255;
+- *subFont->blend_top++ = ( (FT_UInt32)sum & 0xFF000000U ) >> 24;
+- *subFont->blend_top++ = ( (FT_UInt32)sum & 0x00FF0000U ) >> 16;
+- *subFont->blend_top++ = ( (FT_UInt32)sum & 0x0000FF00U ) >> 8;
+- *subFont->blend_top++ = (FT_UInt32)sum & 0x000000FFU;
++ *subFont->blend_top++ = (FT_Byte)( sum >> 24 );
++ *subFont->blend_top++ = (FT_Byte)( sum >> 16 );
++ *subFont->blend_top++ = (FT_Byte)( sum >> 8 );
++ *subFont->blend_top++ = (FT_Byte)sum;
+ }
+
+ /* leave only numBlends results on parser stack */
+@@ -1600,7 +1595,8 @@
+ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
+
+
+- mm->done_blend( FT_FACE( face ) );
++ if (mm)
++ mm->done_blend( FT_FACE( face ) );
+ }
+
+ #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+@@ -1945,18 +1941,6 @@
+ }
+
+
+- FT_LOCAL_DEF( FT_UInt32 )
+- cff_random( FT_UInt32 r )
+- {
+- /* a 32bit version of the `xorshift' algorithm */
+- r ^= r << 13;
+- r ^= r >> 17;
+- r ^= r << 5;
+-
+- return r;
+- }
+-
+-
+ /* There are 3 ways to call this function, distinguished by code. */
+ /* */
+ /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
+@@ -1980,6 +1964,8 @@
+ CFF_FontRecDict top = &subfont->font_dict;
+ CFF_Private priv = &subfont->private_dict;
+
++ PSAux_Service psaux = (PSAux_Service)face->psaux;
++
+ FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT ||
+ code == CFF2_CODE_FONTDICT );
+ FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK
+@@ -2085,7 +2071,7 @@
+ */
+ if ( face->root.internal->random_seed == -1 )
+ {
+- CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face );
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
+
+
+ subfont->random = (FT_UInt32)driver->random_seed;
+@@ -2094,7 +2080,7 @@
+ do
+ {
+ driver->random_seed =
+- (FT_Int32)cff_random( (FT_UInt32)driver->random_seed );
++ (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
+
+ } while ( driver->random_seed < 0 );
+ }
+@@ -2107,7 +2093,8 @@
+ do
+ {
+ face->root.internal->random_seed =
+- (FT_Int32)cff_random( (FT_UInt32)face->root.internal->random_seed );
++ (FT_Int32)psaux->cff_random(
++ (FT_UInt32)face->root.internal->random_seed );
+
+ } while ( face->root.internal->random_seed < 0 );
+ }
+@@ -2548,6 +2535,8 @@
+ font->cf2_instance.finalizer( font->cf2_instance.data );
+ FT_FREE( font->cf2_instance.data );
+ }
++
++ FT_FREE( font->font_extra );
+ }
+
+
+diff --git a/src/cff/cffload.h b/src/cff/cffload.h
+index c745e8127b..ef3c1bd86f 100644
+--- a/src/cff/cffload.h
++++ b/src/cff/cffload.h
+@@ -21,9 +21,9 @@
+
+
+ #include <ft2build.h>
+-#include "cfftypes.h"
++#include FT_INTERNAL_CFF_TYPES_H
+ #include "cffparse.h"
+-#include "cffobjs.h" /* for CFF_Face */
++#include FT_INTERNAL_CFF_OBJECTS_TYPES_H /* for CFF_Face */
+
+
+ FT_BEGIN_HEADER
+@@ -61,9 +61,6 @@ FT_BEGIN_HEADER
+ FT_UInt cid );
+
+
+- FT_LOCAL( FT_UInt32 )
+- cff_random( FT_UInt32 r );
+-
+ FT_LOCAL( FT_Error )
+ cff_font_load( FT_Library library,
+ FT_Stream stream,
+diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
+index 61613933ff..983fd2e71c 100644
+--- a/src/cff/cffobjs.c
++++ b/src/cff/cffobjs.c
+@@ -32,6 +32,7 @@
+ #include FT_SERVICE_MULTIPLE_MASTERS_H
+ #endif
+
++#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+ #include "cffobjs.h"
+ #include "cffload.h"
+ #include "cffcmap.h"
+@@ -39,6 +40,8 @@
+
+ #include "cfferrs.h"
+
++#include FT_INTERNAL_POSTSCRIPT_AUX_H
++
+
+ /*************************************************************************/
+ /* */
+@@ -493,14 +496,16 @@
+ SFNT_Service sfnt;
+ FT_Service_PsCMaps psnames;
+ PSHinter_Service pshinter;
++ PSAux_Service psaux;
++ FT_Service_CFFLoad cffload;
+ FT_Bool pure_cff = 1;
+ FT_Bool cff2 = 0;
+ FT_Bool sfnt_format = 0;
+ FT_Library library = cffface->driver->root.library;
+
+
+- sfnt = (SFNT_Service)FT_Get_Module_Interface(
+- library, "sfnt" );
++ sfnt = (SFNT_Service)FT_Get_Module_Interface( library,
++ "sfnt" );
+ if ( !sfnt )
+ {
+ FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" ));
+@@ -510,8 +515,20 @@
+
+ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
+
+- pshinter = (PSHinter_Service)FT_Get_Module_Interface(
+- library, "pshinter" );
++ pshinter = (PSHinter_Service)FT_Get_Module_Interface( library,
++ "pshinter" );
++
++ psaux = (PSAux_Service)FT_Get_Module_Interface( library,
++ "psaux" );
++ if ( !psaux )
++ {
++ FT_ERROR(( "cff_face_init: cannot access `psaux' module\n" ));
++ error = FT_THROW( Missing_Module );
++ goto Exit;
++ }
++ face->psaux = psaux;
++
++ FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
+
+ FT_TRACE2(( "CFF driver\n" ));
+
+@@ -614,6 +631,7 @@
+
+ cff->pshinter = pshinter;
+ cff->psnames = psnames;
++ cff->cffload = cffload;
+
+ cffface->face_index = face_index & 0xFFFF;
+
+@@ -690,50 +708,22 @@
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ {
+- FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
++ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
++ FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var;
+
+- FT_Int instance_index = face_index >> 16;
++ FT_UInt instance_index = (FT_UInt)face_index >> 16;
+
+
+ if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
+ mm &&
+ instance_index > 0 )
+ {
+- FT_MM_Var* mm_var;
+-
+-
+- error = mm->get_mm_var( cffface, NULL );
++ error = mm->set_instance( cffface, instance_index );
+ if ( error )
+ goto Exit;
+
+- mm->get_var_blend( cffface, NULL, NULL, NULL, &mm_var );
+-
+- if ( mm_var->namedstyle )
+- {
+- FT_Var_Named_Style* named_style;
+- FT_String* style_name;
+-
+-
+- /* in `face_index', the instance index starts with value 1 */
+- named_style = mm_var->namedstyle + instance_index - 1;
+- error = sfnt->get_name( face,
+- (FT_UShort)named_style->strid,
+- &style_name );
+- if ( error )
+- goto Exit;
+-
+- /* set style name; if already set, replace it */
+- if ( face->root.style_name )
+- FT_FREE( face->root.style_name );
+- face->root.style_name = style_name;
+-
+- /* finally, select the named instance */
+- error = mm->set_var_design( cffface,
+- mm_var->num_axis,
+- named_style->coords );
+- if ( error )
+- goto Exit;
+- }
++ if ( var )
++ var->metrics_adjust( cffface );
+ }
+ }
+ #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+@@ -876,7 +866,8 @@
+
+ cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
+ if ( cffface->height < cffface->ascender - cffface->descender )
+- cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
++ cffface->height = (FT_Short)( cffface->ascender -
++ cffface->descender );
+
+ cffface->underline_position =
+ (FT_Short)( dict->underline_position >> 16 );
+@@ -884,27 +875,32 @@
+ (FT_Short)( dict->underline_thickness >> 16 );
+
+ /* retrieve font family & style name */
+- cffface->family_name = cff_index_get_name(
+- cff,
+- (FT_UInt)( face_index & 0xFFFF ) );
++ if ( dict->family_name )
++ {
++ char* family_name;
++
++
++ family_name = cff_index_get_sid_string( cff, dict->family_name );
++ if ( family_name )
++ cffface->family_name = cff_strcpy( memory, family_name );
++ }
++
++ if ( !cffface->family_name )
++ {
++ cffface->family_name = cff_index_get_name(
++ cff,
++ (FT_UInt)( face_index & 0xFFFF ) );
++ if ( cffface->family_name )
++ remove_subset_prefix( cffface->family_name );
++ }
++
+ if ( cffface->family_name )
+ {
+ char* full = cff_index_get_sid_string( cff,
+ dict->full_name );
+ char* fullp = full;
+ char* family = cffface->family_name;
+- char* family_name = NULL;
+-
+
+- remove_subset_prefix( cffface->family_name );
+-
+- if ( dict->family_name )
+- {
+- family_name = cff_index_get_sid_string( cff,
+- dict->family_name );
+- if ( family_name )
+- family = family_name;
+- }
+
+ /* We try to extract the style name from the full name. */
+ /* We need to ignore spaces and dashes during the search. */
+@@ -1159,7 +1155,7 @@
+ FT_LOCAL_DEF( FT_Error )
+ cff_driver_init( FT_Module module ) /* CFF_Driver */
+ {
+- CFF_Driver driver = (CFF_Driver)module;
++ PS_Driver driver = (PS_Driver)module;
+
+ FT_UInt32 seed;
+
+diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
+index 1dba694c53..9f3dff3e5e 100644
+--- a/src/cff/cffobjs.h
++++ b/src/cff/cffobjs.h
+@@ -21,111 +21,11 @@
+
+
+ #include <ft2build.h>
+-#include FT_INTERNAL_OBJECTS_H
+-#include "cfftypes.h"
+-#include FT_INTERNAL_TRUETYPE_TYPES_H
+-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+
+
+ FT_BEGIN_HEADER
+
+
+- /*************************************************************************/
+- /* */
+- /* <Type> */
+- /* CFF_Driver */
+- /* */
+- /* <Description> */
+- /* A handle to an OpenType driver object. */
+- /* */
+- typedef struct CFF_DriverRec_* CFF_Driver;
+-
+- typedef TT_Face CFF_Face;
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Type> */
+- /* CFF_Size */
+- /* */
+- /* <Description> */
+- /* A handle to an OpenType size object. */
+- /* */
+- typedef struct CFF_SizeRec_
+- {
+- FT_SizeRec root;
+- FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */
+-
+- } CFF_SizeRec, *CFF_Size;
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Type> */
+- /* CFF_GlyphSlot */
+- /* */
+- /* <Description> */
+- /* A handle to an OpenType glyph slot object. */
+- /* */
+- typedef struct CFF_GlyphSlotRec_
+- {
+- FT_GlyphSlotRec root;
+-
+- FT_Bool hint;
+- FT_Bool scaled;
+-
+- FT_Fixed x_scale;
+- FT_Fixed y_scale;
+-
+- } CFF_GlyphSlotRec, *CFF_GlyphSlot;
+-
+-
+- /*************************************************************************/
+- /* */
+- /* <Type> */
+- /* CFF_Internal */
+- /* */
+- /* <Description> */
+- /* The interface to the `internal' field of `FT_Size'. */
+- /* */
+- typedef struct CFF_InternalRec_
+- {
+- PSH_Globals topfont;
+- PSH_Globals subfonts[CFF_MAX_CID_FONTS];
+-
+- } CFF_InternalRec, *CFF_Internal;
+-
+-
+- /*************************************************************************/
+- /* */
+- /* Subglyph transformation record. */
+- /* */
+- typedef struct CFF_Transform_
+- {
+- FT_Fixed xx, xy; /* transformation matrix coefficients */
+- FT_Fixed yx, yy;
+- FT_F26Dot6 ox, oy; /* offsets */
+-
+- } CFF_Transform;
+-
+-
+- /***********************************************************************/
+- /* */
+- /* CFF driver class. */
+- /* */
+- typedef struct CFF_DriverRec_
+- {
+- FT_DriverRec root;
+-
+- FT_UInt hinting_engine;
+- FT_Bool no_stem_darkening;
+- FT_Int darken_params[8];
+- FT_Int32 random_seed;
+-
+- } CFF_DriverRec;
+-
+-
+ FT_LOCAL( FT_Error )
+ cff_size_init( FT_Size size ); /* CFF_Size */
+
+@@ -171,10 +71,10 @@ FT_BEGIN_HEADER
+ /* Driver functions */
+ /* */
+ FT_LOCAL( FT_Error )
+- cff_driver_init( FT_Module module ); /* CFF_Driver */
++ cff_driver_init( FT_Module module ); /* PS_Driver */
+
+ FT_LOCAL( void )
+- cff_driver_done( FT_Module module ); /* CFF_Driver */
++ cff_driver_done( FT_Module module ); /* PS_Driver */
+
+
+ FT_END_HEADER
+diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
+index 9d7bf6d22c..e4e2bcd0be 100644
+--- a/src/cff/cffparse.c
++++ b/src/cff/cffparse.c
+@@ -21,10 +21,10 @@
+ #include FT_INTERNAL_STREAM_H
+ #include FT_INTERNAL_DEBUG_H
+ #include FT_INTERNAL_CALC_H
++#include FT_INTERNAL_POSTSCRIPT_AUX_H
+
+ #include "cfferrs.h"
+ #include "cffpic.h"
+-#include "cffgload.h"
+ #include "cffload.h"
+
+
+@@ -1299,9 +1299,14 @@
+ FT_Byte* start,
+ FT_Byte* limit )
+ {
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++ PSAux_Service psaux;
++#endif
++
+ FT_Byte* p = start;
+ FT_Error error = FT_Err_Ok;
+ FT_Library library = parser->library;
++
+ FT_UNUSED( library );
+
+
+@@ -1388,10 +1393,16 @@
+ cff_rec.top_font.font_dict.num_axes = parser->num_axes;
+ decoder.cff = &cff_rec;
+
+- error = cff_decoder_parse_charstrings( &decoder,
+- charstring_base,
+- charstring_len,
+- 1 );
++ psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" );
++ if ( !psaux )
++ {
++ FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" ));
++ error = FT_THROW( Missing_Module );
++ goto Exit;
++ }
++
++ error = psaux->cff_decoder_funcs->parse_charstrings_old(
++ &decoder, charstring_base, charstring_len, 1 );
+
+ /* Now copy the stack data in the temporary decoder object, */
+ /* converting it back to charstring number representations */
+diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
+index 83d1bba45f..961c265017 100644
+--- a/src/cff/cffparse.h
++++ b/src/cff/cffparse.h
+@@ -21,7 +21,7 @@
+
+
+ #include <ft2build.h>
+-#include "cfftypes.h"
++#include FT_INTERNAL_CFF_TYPES_H
+ #include FT_INTERNAL_OBJECTS_H
+
+
+diff --git a/src/cff/cffpic.h b/src/cff/cffpic.h
+index 5db39cd627..a7e01973e6 100644
+--- a/src/cff/cffpic.h
++++ b/src/cff/cffpic.h
+@@ -22,7 +22,6 @@
+
+ #include FT_INTERNAL_PIC_H
+
+-
+ #ifndef FT_CONFIG_OPTION_PIC
+
+ #define CFF_SERVICE_PS_INFO_GET cff_service_ps_info
+@@ -34,6 +33,7 @@
+ #define CFF_SERVICES_GET cff_services
+ #define CFF_SERVICE_MULTI_MASTERS_GET cff_service_multi_masters
+ #define CFF_SERVICE_METRICS_VAR_GET cff_service_metrics_variations
++#define CFF_SERVICE_CFF_LOAD_GET cff_service_cff_load
+ #define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec
+ #define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec
+ #define CFF_FIELD_HANDLERS_GET cff_field_handlers
+@@ -65,6 +65,7 @@ FT_BEGIN_HEADER
+ FT_Service_PropertiesRec cff_service_properties;
+ FT_Service_MultiMastersRec cff_service_multi_masters;
+ FT_Service_MetricsVariationsRec cff_service_metrics_variations;
++ FT_Service_CFFLoadRec cff_service_cff_load;
+ FT_CMap_ClassRec cff_cmap_encoding_class_rec;
+ FT_CMap_ClassRec cff_cmap_unicode_class_rec;
+
+@@ -92,6 +93,8 @@ FT_BEGIN_HEADER
+ ( GET_PIC( library )->cff_service_multi_masters )
+ #define CFF_SERVICE_METRICS_VAR_GET \
+ ( GET_PIC( library )->cff_service_metrics_variations )
++#define CFF_SERVICE_CFF_LOAD_GET \
++ ( GET_PIC( library )->cff_service_cff_load )
+ #define CFF_CMAP_ENCODING_CLASS_REC_GET \
+ ( GET_PIC( library )->cff_cmap_encoding_class_rec )
+ #define CFF_CMAP_UNICODE_CLASS_REC_GET \
+diff --git a/src/cff/rules.mk b/src/cff/rules.mk
+index 86840bfe3c..473b25c1da 100644
+--- a/src/cff/rules.mk
++++ b/src/cff/rules.mk
+@@ -32,27 +32,14 @@ CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \
+ $(CFF_DIR)/cffload.c \
+ $(CFF_DIR)/cffobjs.c \
+ $(CFF_DIR)/cffparse.c \
+- $(CFF_DIR)/cffpic.c \
+- $(CFF_DIR)/cf2arrst.c \
+- $(CFF_DIR)/cf2blues.c \
+- $(CFF_DIR)/cf2error.c \
+- $(CFF_DIR)/cf2font.c \
+- $(CFF_DIR)/cf2ft.c \
+- $(CFF_DIR)/cf2hints.c \
+- $(CFF_DIR)/cf2intrp.c \
+- $(CFF_DIR)/cf2read.c \
+- $(CFF_DIR)/cf2stack.c
++ $(CFF_DIR)/cffpic.c
+
+
+ # CFF driver headers
+ #
+ CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \
+ $(CFF_DIR)/cfferrs.h \
+- $(CFF_DIR)/cfftoken.h \
+- $(CFF_DIR)/cfftypes.h \
+- $(CFF_DIR)/cf2fixed.h \
+- $(CFF_DIR)/cf2glue.h \
+- $(CFF_DIR)/cf2types.h
++ $(CFF_DIR)/cfftoken.h
+
+
+ # CFF driver object(s)
+diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
+index b96c33334d..086e88997b 100644
+--- a/src/cid/cidgload.c
++++ b/src/cid/cidgload.c
+@@ -24,6 +24,10 @@
+ #include FT_OUTLINE_H
+ #include FT_INTERNAL_CALC_H
+
++#include FT_INTERNAL_POSTSCRIPT_AUX_H
++#include FT_INTERNAL_CFF_TYPES_H
++#include FT_TYPE1_DRIVER_H
++
+ #include "ciderrs.h"
+
+
+@@ -52,9 +56,11 @@
+ FT_ULong glyph_length = 0;
+ PSAux_Service psaux = (PSAux_Service)face->psaux;
+
++ FT_Bool force_scaling = FALSE;
++
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+- FT_Incremental_InterfaceRec *inc =
+- face->root.internal->incremental_interface;
++ FT_Incremental_InterfaceRec *inc =
++ face->root.internal->incremental_interface;
+ #endif
+
+
+@@ -169,9 +175,57 @@
+ if ( decoder->lenIV >= 0 )
+ psaux->t1_decrypt( charstring, glyph_length, 4330 );
+
+- error = decoder->funcs.parse_charstrings(
+- decoder, charstring + cs_offset,
+- glyph_length - cs_offset );
++ /* choose which renderer to use */
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ if ( ( (PS_Driver)FT_FACE_DRIVER( face ) )->hinting_engine ==
++ FT_T1_HINTING_FREETYPE ||
++ decoder->builder.metrics_only )
++ error = psaux->t1_decoder_funcs->parse_charstrings_old(
++ decoder,
++ charstring + cs_offset,
++ glyph_length - cs_offset );
++#else
++ if ( decoder->builder.metrics_only )
++ error = psaux->t1_decoder_funcs->parse_metrics(
++ decoder,
++ charstring + cs_offset,
++ glyph_length - cs_offset );
++#endif
++ else
++ {
++ PS_Decoder psdecoder;
++ CFF_SubFontRec subfont;
++
++
++ psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
++
++ psaux->t1_make_subfont( FT_FACE( face ),
++ &dict->private_dict,
++ &subfont );
++ psdecoder.current_subfont = &subfont;
++
++ error = psaux->t1_decoder_funcs->parse_charstrings(
++ &psdecoder,
++ charstring + cs_offset,
++ glyph_length - cs_offset );
++
++ /* Adobe's engine uses 16.16 numbers everywhere; */
++ /* as a consequence, glyphs larger than 2000ppem get rejected */
++ if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
++ {
++ /* this time, we retry unhinted and scale up the glyph later on */
++ /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
++ /* 0x400 for both `x_scale' and `y_scale' in this case) */
++ ((CID_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
++
++ force_scaling = TRUE;
++
++ error = psaux->t1_decoder_funcs->parse_charstrings(
++ &psdecoder,
++ charstring + cs_offset,
++ glyph_length - cs_offset );
++ }
++ }
+ }
+
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+@@ -200,6 +254,8 @@
+ Exit:
+ FT_FREE( charstring );
+
++ ((CID_GlyphSlot)decoder->builder.glyph)->scaled = force_scaling;
++
+ return error;
+ }
+
+@@ -288,10 +344,12 @@
+ T1_DecoderRec decoder;
+ CID_Face face = (CID_Face)cidglyph->face;
+ FT_Bool hinting;
++ FT_Bool scaled;
+
+ PSAux_Service psaux = (PSAux_Service)face->psaux;
+ FT_Matrix font_matrix;
+ FT_Vector font_offset;
++ FT_Bool must_finish_decoder = FALSE;
+
+
+ if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
+@@ -311,7 +369,10 @@
+
+ hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
+ ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
++ scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
+
++ glyph->hint = hinting;
++ glyph->scaled = scaled;
+ cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
+
+ error = psaux->t1_decoder_funcs->init( &decoder,
+@@ -329,6 +390,8 @@
+ /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
+ /* if we ever support CID-keyed multiple master fonts */
+
++ must_finish_decoder = TRUE;
++
+ /* set up the decoder */
+ decoder.builder.no_recurse = FT_BOOL(
+ ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
+@@ -337,12 +400,18 @@
+ if ( error )
+ goto Exit;
+
++ /* copy flags back for forced scaling */
++ hinting = glyph->hint;
++ scaled = glyph->scaled;
++
+ font_matrix = decoder.font_matrix;
+ font_offset = decoder.font_offset;
+
+ /* save new glyph tables */
+ psaux->t1_decoder_funcs->done( &decoder );
+
++ must_finish_decoder = FALSE;
++
+ /* now set the metrics -- this is rather simple, as */
+ /* the left side bearing is the xMin, and the top side */
+ /* bearing the yMax */
+@@ -410,7 +479,7 @@
+ metrics->vertAdvance += font_offset.y;
+ }
+
+- if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
++ if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || scaled )
+ {
+ /* scale the outline and the metrics */
+ FT_Int n;
+@@ -451,6 +520,10 @@
+ }
+
+ Exit:
++
++ if ( must_finish_decoder )
++ psaux->t1_decoder_funcs->done( &decoder );
++
+ return error;
+ }
+
+diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c
+index ceda8ff97f..4f4cf46972 100644
+--- a/src/cid/cidobjs.c
++++ b/src/cid/cidobjs.c
+@@ -26,6 +26,7 @@
+ #include FT_SERVICE_POSTSCRIPT_CMAPS_H
+ #include FT_INTERNAL_POSTSCRIPT_AUX_H
+ #include FT_INTERNAL_POSTSCRIPT_HINTS_H
++#include FT_TYPE1_DRIVER_H
+
+ #include "ciderrs.h"
+
+@@ -463,9 +464,42 @@
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_LOCAL_DEF( FT_Error )
+- cid_driver_init( FT_Module driver )
++ cid_driver_init( FT_Module module )
+ {
+- FT_UNUSED( driver );
++ PS_Driver driver = (PS_Driver)module;
++
++ FT_UInt32 seed;
++
++
++ /* set default property values, cf. `ftt1drv.h' */
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ driver->hinting_engine = FT_T1_HINTING_FREETYPE;
++#else
++ driver->hinting_engine = FT_T1_HINTING_ADOBE;
++#endif
++
++ driver->no_stem_darkening = TRUE;
++
++ driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
++ driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
++ driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
++ driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
++ driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
++ driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
++ driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
++ driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
++
++ /* compute random seed from some memory addresses */
++ seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^
++ (FT_Offset)(char*)&module ^
++ (FT_Offset)(char*)module->memory );
++ seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
++
++ driver->random_seed = (FT_Int32)seed;
++ if ( driver->random_seed < 0 )
++ driver->random_seed = -driver->random_seed;
++ else if ( driver->random_seed == 0 )
++ driver->random_seed = 123456789;
+
+ return FT_Err_Ok;
+ }
+diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c
+index bb611a961e..2ee2707f3e 100644
+--- a/src/cid/cidriver.c
++++ b/src/cid/cidriver.c
+@@ -27,6 +27,8 @@
+ #include FT_SERVICE_FONT_FORMAT_H
+ #include FT_SERVICE_POSTSCRIPT_INFO_H
+ #include FT_SERVICE_CID_H
++#include FT_SERVICE_PROPERTIES_H
++#include FT_TYPE1_DRIVER_H
+
+
+ /*************************************************************************/
+@@ -167,6 +169,237 @@
+ };
+
+
++ /*
++ * PROPERTY SERVICE
++ *
++ */
++ static FT_Error
++ cid_property_set( FT_Module module, /* PS_Driver */
++ const char* property_name,
++ const void* value,
++ FT_Bool value_is_string )
++ {
++ FT_Error error = FT_Err_Ok;
++ PS_Driver driver = (PS_Driver)module;
++
++#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ FT_UNUSED( value_is_string );
++#endif
++
++
++ if ( !ft_strcmp( property_name, "darkening-parameters" ) )
++ {
++ FT_Int* darken_params;
++ FT_Int x1, y1, x2, y2, x3, y3, x4, y4;
++
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ FT_Int dp[8];
++
++
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++ char* ep;
++ int i;
++
++
++ /* eight comma-separated numbers */
++ for ( i = 0; i < 7; i++ )
++ {
++ dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
++ if ( *ep != ',' || s == ep )
++ return FT_THROW( Invalid_Argument );
++
++ s = ep + 1;
++ }
++
++ dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
++ if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
++ return FT_THROW( Invalid_Argument );
++
++ darken_params = dp;
++ }
++ else
++#endif
++ darken_params = (FT_Int*)value;
++
++ x1 = darken_params[0];
++ y1 = darken_params[1];
++ x2 = darken_params[2];
++ y2 = darken_params[3];
++ x3 = darken_params[4];
++ y3 = darken_params[5];
++ x4 = darken_params[6];
++ y4 = darken_params[7];
++
++ if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 ||
++ y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 ||
++ x1 > x2 || x2 > x3 || x3 > x4 ||
++ y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 )
++ return FT_THROW( Invalid_Argument );
++
++ driver->darken_params[0] = x1;
++ driver->darken_params[1] = y1;
++ driver->darken_params[2] = x2;
++ driver->darken_params[3] = y2;
++ driver->darken_params[4] = x3;
++ driver->darken_params[5] = y3;
++ driver->darken_params[6] = x4;
++ driver->darken_params[7] = y4;
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "hinting-engine" ) )
++ {
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++
++
++ if ( !ft_strcmp( s, "adobe" ) )
++ driver->hinting_engine = FT_T1_HINTING_ADOBE;
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ else if ( !ft_strcmp( s, "freetype" ) )
++ driver->hinting_engine = FT_T1_HINTING_FREETYPE;
++#endif
++ else
++ return FT_THROW( Invalid_Argument );
++ }
++ else
++#endif
++ {
++ FT_UInt* hinting_engine = (FT_UInt*)value;
++
++
++ if ( *hinting_engine == FT_T1_HINTING_ADOBE
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ || *hinting_engine == FT_T1_HINTING_FREETYPE
++#endif
++ )
++ driver->hinting_engine = *hinting_engine;
++ else
++ error = FT_ERR( Unimplemented_Feature );
++
++ return error;
++ }
++ }
++ else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
++ {
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++ long nsd = ft_strtol( s, NULL, 10 );
++
++
++ if ( !nsd )
++ driver->no_stem_darkening = FALSE;
++ else
++ driver->no_stem_darkening = TRUE;
++ }
++ else
++#endif
++ {
++ FT_Bool* no_stem_darkening = (FT_Bool*)value;
++
++
++ driver->no_stem_darkening = *no_stem_darkening;
++ }
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "random-seed" ) )
++ {
++ FT_Int32 random_seed;
++
++
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++
++
++ random_seed = (FT_Int32)ft_strtol( s, NULL, 10 );
++ }
++ else
++#endif
++ random_seed = *(FT_Int32*)value;
++
++ if ( random_seed < 0 )
++ random_seed = 0;
++
++ driver->random_seed = random_seed;
++
++ return error;
++ }
++
++ FT_TRACE0(( "cid_property_set: missing property `%s'\n",
++ property_name ));
++ return FT_THROW( Missing_Property );
++ }
++
++
++ static FT_Error
++ cid_property_get( FT_Module module, /* PS_Driver */
++ const char* property_name,
++ const void* value )
++ {
++ FT_Error error = FT_Err_Ok;
++ PS_Driver driver = (PS_Driver)module;
++
++
++ if ( !ft_strcmp( property_name, "darkening-parameters" ) )
++ {
++ FT_Int* darken_params = driver->darken_params;
++ FT_Int* val = (FT_Int*)value;
++
++
++ val[0] = darken_params[0];
++ val[1] = darken_params[1];
++ val[2] = darken_params[2];
++ val[3] = darken_params[3];
++ val[4] = darken_params[4];
++ val[5] = darken_params[5];
++ val[6] = darken_params[6];
++ val[7] = darken_params[7];
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "hinting-engine" ) )
++ {
++ FT_UInt hinting_engine = driver->hinting_engine;
++ FT_UInt* val = (FT_UInt*)value;
++
++
++ *val = hinting_engine;
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
++ {
++ FT_Bool no_stem_darkening = driver->no_stem_darkening;
++ FT_Bool* val = (FT_Bool*)value;
++
++
++ *val = no_stem_darkening;
++
++ return error;
++ }
++
++ FT_TRACE0(( "cid_property_get: missing property `%s'\n",
++ property_name ));
++ return FT_THROW( Missing_Property );
++ }
++
++
++ FT_DEFINE_SERVICE_PROPERTIESREC(
++ cid_service_properties,
++
++ (FT_Properties_SetFunc)cid_property_set, /* set_property */
++ (FT_Properties_GetFunc)cid_property_get ) /* get_property */
++
++
+ /*
+ * SERVICE LIST
+ *
+@@ -178,6 +411,7 @@
+ { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name },
+ { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info },
+ { FT_SERVICE_ID_CID, &cid_service_cid_info },
++ { FT_SERVICE_ID_PROPERTIES, &cid_service_properties },
+ { NULL, NULL }
+ };
+
+@@ -200,7 +434,7 @@
+ FT_MODULE_FONT_DRIVER |
+ FT_MODULE_DRIVER_SCALABLE |
+ FT_MODULE_DRIVER_HAS_HINTER,
+- sizeof ( FT_DriverRec ),
++ sizeof ( PS_DriverRec ),
+
+ "t1cid", /* module name */
+ 0x10000L, /* version 1.0 of driver */
+diff --git a/src/otvalid/otvbase.c b/src/otvalid/otvbase.c
+index 3adad8439c..48ae96173d 100644
+--- a/src/otvalid/otvbase.c
++++ b/src/otvalid/otvbase.c
+@@ -284,22 +284,41 @@
+ OTV_Validator otvalid = &otvalidrec;
+ FT_Bytes p = table;
+ FT_UInt table_size;
++ FT_UShort version;
+
+ OTV_OPTIONAL_TABLE( HorizAxis );
+ OTV_OPTIONAL_TABLE( VertAxis );
+
++ OTV_OPTIONAL_TABLE32( itemVarStore );
++
+
+ otvalid->root = ftvalid;
+
+ FT_TRACE3(( "validating BASE table\n" ));
+ OTV_INIT;
+
+- OTV_LIMIT_CHECK( 6 );
++ OTV_LIMIT_CHECK( 4 );
+
+- if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
++ if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */
+ FT_INVALID_FORMAT;
+
+- table_size = 6;
++ version = FT_NEXT_USHORT( p ); /* minorVersion */
++
++ table_size = 8;
++ switch ( version )
++ {
++ case 0:
++ OTV_LIMIT_CHECK( 4 );
++ break;
++
++ case 1:
++ OTV_LIMIT_CHECK( 8 );
++ table_size += 4;
++ break;
++
++ default:
++ FT_INVALID_FORMAT;
++ }
+
+ OTV_OPTIONAL_OFFSET( HorizAxis );
+ OTV_SIZE_CHECK( HorizAxis );
+@@ -311,6 +330,14 @@
+ if ( VertAxis )
+ otv_Axis_validate( table + VertAxis, otvalid );
+
++ if ( version > 0 )
++ {
++ OTV_OPTIONAL_OFFSET32( itemVarStore );
++ OTV_SIZE_CHECK32( itemVarStore );
++ if ( itemVarStore )
++ OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */
++ }
++
+ FT_TRACE4(( "\n" ));
+ }
+
+diff --git a/src/otvalid/otvcommn.c b/src/otvalid/otvcommn.c
+index 3407d2ad4a..0583620d34 100644
+--- a/src/otvalid/otvcommn.c
++++ b/src/otvalid/otvcommn.c
+@@ -313,19 +313,26 @@
+
+ OTV_NAME_ENTER( "Device" );
+
+- OTV_LIMIT_CHECK( 8 );
++ OTV_LIMIT_CHECK( 6 );
+ StartSize = FT_NEXT_USHORT( p );
+ EndSize = FT_NEXT_USHORT( p );
+ DeltaFormat = FT_NEXT_USHORT( p );
+
+- if ( DeltaFormat < 1 || DeltaFormat > 3 )
+- FT_INVALID_FORMAT;
++ if ( DeltaFormat == 0x8000U )
++ {
++ /* VariationIndex, nothing to do */
++ }
++ else
++ {
++ if ( DeltaFormat < 1 || DeltaFormat > 3 )
++ FT_INVALID_FORMAT;
+
+- if ( EndSize < StartSize )
+- FT_INVALID_DATA;
++ if ( EndSize < StartSize )
++ FT_INVALID_DATA;
+
+- count = EndSize - StartSize + 1;
+- OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */
++ count = EndSize - StartSize + 1;
++ OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */
++ }
+
+ OTV_EXIT;
+ }
+@@ -347,7 +354,7 @@
+ OTV_Validator otvalid )
+ {
+ FT_Bytes p = table;
+- FT_UInt LookupType, SubTableCount;
++ FT_UInt LookupType, LookupFlag, SubTableCount;
+ OTV_Validate_Func validate;
+
+
+@@ -355,7 +362,7 @@
+
+ OTV_LIMIT_CHECK( 6 );
+ LookupType = FT_NEXT_USHORT( p );
+- p += 2; /* skip LookupFlag */
++ LookupFlag = FT_NEXT_USHORT( p );
+ SubTableCount = FT_NEXT_USHORT( p );
+
+ OTV_TRACE(( " (type %d)\n", LookupType ));
+@@ -373,6 +380,9 @@
+ for ( ; SubTableCount > 0; SubTableCount-- )
+ validate( table + FT_NEXT_USHORT( p ), otvalid );
+
++ if ( LookupFlag & 0x10 )
++ OTV_LIMIT_CHECK( 2 ); /* MarkFilteringSet */
++
+ OTV_EXIT;
+ }
+
+diff --git a/src/otvalid/otvcommn.h b/src/otvalid/otvcommn.h
+index 10a603ebb9..40a79851d5 100644
+--- a/src/otvalid/otvcommn.h
++++ b/src/otvalid/otvcommn.h
+@@ -67,29 +67,38 @@ FT_BEGIN_HEADER
+
+
+ #undef FT_INVALID_
+-#define FT_INVALID_( _error ) \
++#define FT_INVALID_( _error ) \
+ ft_validator_error( otvalid->root, FT_THROW( _error ) )
+
+ #define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \
+ FT_Bytes _table ## _p
+
++#define OTV_OPTIONAL_TABLE32( _table ) FT_ULong _table; \
++ FT_Bytes _table ## _p
++
+ #define OTV_OPTIONAL_OFFSET( _offset ) \
+ FT_BEGIN_STMNT \
+ _offset ## _p = p; \
+ _offset = FT_NEXT_USHORT( p ); \
+ FT_END_STMNT
+
+-#define OTV_LIMIT_CHECK( _count ) \
+- FT_BEGIN_STMNT \
++#define OTV_OPTIONAL_OFFSET32( _offset ) \
++ FT_BEGIN_STMNT \
++ _offset ## _p = p; \
++ _offset = FT_NEXT_ULONG( p ); \
++ FT_END_STMNT
++
++#define OTV_LIMIT_CHECK( _count ) \
++ FT_BEGIN_STMNT \
+ if ( p + (_count) > otvalid->root->limit ) \
+- FT_INVALID_TOO_SHORT; \
++ FT_INVALID_TOO_SHORT; \
+ FT_END_STMNT
+
+ #define OTV_SIZE_CHECK( _size ) \
+ FT_BEGIN_STMNT \
+ if ( _size > 0 && _size < table_size ) \
+ { \
+- if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \
++ if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \
+ FT_INVALID_OFFSET; \
+ else \
+ { \
+@@ -102,12 +111,33 @@ FT_BEGIN_HEADER
+ " set to zero.\n" \
+ "\n", #_size )); \
+ \
+- /* always assume 16bit entities */ \
+ _size = pp[0] = pp[1] = 0; \
+ } \
+ } \
+ FT_END_STMNT
+
++#define OTV_SIZE_CHECK32( _size ) \
++ FT_BEGIN_STMNT \
++ if ( _size > 0 && _size < table_size ) \
++ { \
++ if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \
++ FT_INVALID_OFFSET; \
++ else \
++ { \
++ /* strip off `const' */ \
++ FT_Byte* pp = (FT_Byte*)_size ## _p; \
++ \
++ \
++ FT_TRACE3(( "\n" \
++ "Invalid offset to optional table `%s'" \
++ " set to zero.\n" \
++ "\n", #_size )); \
++ \
++ _size = pp[0] = pp[1] = pp[2] = pp[3] = 0; \
++ } \
++ } \
++ FT_END_STMNT
++
+
+ #define OTV_NAME_(x) #x
+ #define OTV_NAME(x) OTV_NAME_(x)
+@@ -146,11 +176,11 @@ FT_BEGIN_HEADER
+
+ #define OTV_INIT otvalid->debug_indent = 0
+
+-#define OTV_ENTER \
+- FT_BEGIN_STMNT \
+- otvalid->debug_indent += 2; \
+- FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \
+- FT_TRACE4(( "%s table\n", \
++#define OTV_ENTER \
++ FT_BEGIN_STMNT \
++ otvalid->debug_indent += 2; \
++ FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \
++ FT_TRACE4(( "%s table\n", \
+ otvalid->debug_function_name[otvalid->nesting_level] )); \
+ FT_END_STMNT
+
+diff --git a/src/otvalid/otvgdef.c b/src/otvalid/otvgdef.c
+index 27b9a69ca8..71f01a9c5f 100644
+--- a/src/otvalid/otvgdef.c
++++ b/src/otvalid/otvgdef.c
+@@ -68,7 +68,7 @@
+ OTV_LIMIT_CHECK( GlyphCount * 2 );
+
+ otvalid->nesting_level++;
+- func = otvalid->func[otvalid->nesting_level];
++ func = otvalid->func[otvalid->nesting_level];
+ otvalid->extra1 = 0;
+
+ for ( ; GlyphCount > 0; GlyphCount-- )
+@@ -133,6 +133,40 @@
+ }
+
+
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** MARK GLYPH SETS *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++ static void
++ otv_MarkGlyphSets_validate( FT_Bytes table,
++ OTV_Validator otvalid )
++ {
++ FT_Bytes p = table;
++ FT_UInt MarkGlyphSetCount;
++
++
++ OTV_NAME_ENTER( "MarkGlyphSets" );
++
++ p += 2; /* skip Format */
++
++ OTV_LIMIT_CHECK( 2 );
++ MarkGlyphSetCount = FT_NEXT_USHORT( p );
++
++ OTV_TRACE(( " (MarkGlyphSetCount = %d)\n", MarkGlyphSetCount ));
++
++ OTV_LIMIT_CHECK( MarkGlyphSetCount * 4 ); /* CoverageOffsets */
++
++ for ( ; MarkGlyphSetCount > 0; MarkGlyphSetCount-- )
++ otv_Coverage_validate( table + FT_NEXT_ULONG( p ), otvalid, -1 );
++
++ OTV_EXIT;
++ }
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+@@ -152,14 +186,18 @@
+ {
+ OTV_ValidatorRec otvalidrec;
+ OTV_Validator otvalid = &otvalidrec;
+- FT_Bytes p = table;
++ FT_Bytes p = table;
+ FT_UInt table_size;
+- FT_Bool need_MarkAttachClassDef;
++ FT_UShort version;
++ FT_Bool need_MarkAttachClassDef = 1;
+
+ OTV_OPTIONAL_TABLE( GlyphClassDef );
+ OTV_OPTIONAL_TABLE( AttachListOffset );
+ OTV_OPTIONAL_TABLE( LigCaretListOffset );
+ OTV_OPTIONAL_TABLE( MarkAttachClassDef );
++ OTV_OPTIONAL_TABLE( MarkGlyphSetsDef );
++
++ OTV_OPTIONAL_TABLE32( itemVarStore );
+
+
+ otvalid->root = ftvalid;
+@@ -167,24 +205,49 @@
+ FT_TRACE3(( "validating GDEF table\n" ));
+ OTV_INIT;
+
+- OTV_LIMIT_CHECK( 12 );
++ OTV_LIMIT_CHECK( 4 );
+
+- if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
++ if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */
+ FT_INVALID_FORMAT;
+
+- /* MarkAttachClassDef has been added to the OpenType */
+- /* specification without increasing GDEF's version, */
+- /* so we use this ugly hack to find out whether the */
+- /* table is needed actually. */
++ version = FT_NEXT_USHORT( p ); /* minorVersion */
+
+- need_MarkAttachClassDef = FT_BOOL(
+- otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
+- otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
++ table_size = 10;
++ switch ( version )
++ {
++ case 0:
++ /* MarkAttachClassDef has been added to the OpenType */
++ /* specification without increasing GDEF's version, */
++ /* so we use this ugly hack to find out whether the */
++ /* table is needed actually. */
++
++ need_MarkAttachClassDef = FT_BOOL(
++ otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
++ otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
++
++ if ( need_MarkAttachClassDef )
++ {
++ OTV_LIMIT_CHECK( 8 );
++ table_size += 2;
++ }
++ else
++ OTV_LIMIT_CHECK( 6 ); /* OpenType < 1.2 */
+
+- if ( need_MarkAttachClassDef )
+- table_size = 12; /* OpenType >= 1.2 */
+- else
+- table_size = 10; /* OpenType < 1.2 */
++ break;
++
++ case 2:
++ OTV_LIMIT_CHECK( 10 );
++ table_size += 4;
++ break;
++
++ case 3:
++ OTV_LIMIT_CHECK( 14 );
++ table_size += 8;
++ break;
++
++ default:
++ FT_INVALID_FORMAT;
++ }
+
+ otvalid->glyph_count = glyph_count;
+
+@@ -217,6 +280,22 @@
+ otv_ClassDef_validate( table + MarkAttachClassDef, otvalid );
+ }
+
++ if ( version > 0 )
++ {
++ OTV_OPTIONAL_OFFSET( MarkGlyphSetsDef );
++ OTV_SIZE_CHECK( MarkGlyphSetsDef );
++ if ( MarkGlyphSetsDef )
++ otv_MarkGlyphSets_validate( table + MarkGlyphSetsDef, otvalid );
++ }
++
++ if ( version > 2 )
++ {
++ OTV_OPTIONAL_OFFSET32( itemVarStore );
++ OTV_SIZE_CHECK32( itemVarStore );
++ if ( itemVarStore )
++ OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */
++ }
++
+ FT_TRACE4(( "\n" ));
+ }
+
+diff --git a/src/otvalid/otvgpos.c b/src/otvalid/otvgpos.c
+index 0fbcc2077c..f185b4a0bd 100644
+--- a/src/otvalid/otvgpos.c
++++ b/src/otvalid/otvgpos.c
+@@ -130,7 +130,7 @@
+ otv_MarkArray_validate( table + Array1, otvalid );
+
+ otvalid->nesting_level++;
+- func = otvalid->func[otvalid->nesting_level];
++ func = otvalid->func[otvalid->nesting_level];
+ otvalid->extra1 = ClassCount;
+
+ func( table + Array2, otvalid );
+@@ -218,10 +218,6 @@
+ OTV_LIMIT_CHECK( 2 );
+ OTV_OPTIONAL_OFFSET( device );
+
+- /* XXX: this value is usually too small, especially if the current */
+- /* ValueRecord is part of an array -- getting the correct table */
+- /* size is probably not worth the trouble */
+-
+ table_size = p - otvalid->extra3;
+
+ OTV_SIZE_CHECK( device );
+@@ -271,7 +267,7 @@
+
+ case 3:
+ {
+- FT_UInt table_size;
++ FT_UInt table_size;
+
+ OTV_OPTIONAL_TABLE( XDeviceTable );
+ OTV_OPTIONAL_TABLE( YDeviceTable );
+@@ -426,6 +422,8 @@
+ /*************************************************************************/
+ /*************************************************************************/
+
++ /* sets otvalid->extra3 (pointer to base table) */
++
+ static void
+ otv_PairSet_validate( FT_Bytes table,
+ FT_UInt format1,
+@@ -438,6 +436,8 @@
+
+ OTV_NAME_ENTER( "PairSet" );
+
++ otvalid->extra3 = table;
++
+ OTV_LIMIT_CHECK( 2 );
+ PairValueCount = FT_NEXT_USHORT( p );
+
+@@ -483,8 +483,6 @@
+
+ OTV_TRACE(( " (format %d)\n", PosFormat ));
+
+- otvalid->extra3 = table;
+-
+ switch ( PosFormat )
+ {
+ case 1: /* PairPosFormat1 */
+@@ -537,7 +535,9 @@
+ otv_ClassDef_validate( table + ClassDef2, otvalid );
+
+ OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 *
+- ( len_value1 + len_value2 ) );
++ ( len_value1 + len_value2 ) );
++
++ otvalid->extra3 = table;
+
+ /* Class1Record */
+ for ( ; ClassCount1 > 0; ClassCount1-- )
+@@ -985,20 +985,42 @@
+ {
+ OTV_ValidatorRec validrec;
+ OTV_Validator otvalid = &validrec;
+- FT_Bytes p = table;
++ FT_Bytes p = table;
++ FT_UInt table_size;
++ FT_UShort version;
+ FT_UInt ScriptList, FeatureList, LookupList;
+
++ OTV_OPTIONAL_TABLE32( featureVariations );
++
+
+ otvalid->root = ftvalid;
+
+ FT_TRACE3(( "validating GPOS table\n" ));
+ OTV_INIT;
+
+- OTV_LIMIT_CHECK( 10 );
++ OTV_LIMIT_CHECK( 4 );
+
+- if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
++ if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */
+ FT_INVALID_FORMAT;
+
++ version = FT_NEXT_USHORT( p ); /* minorVersion */
++
++ table_size = 10;
++ switch ( version )
++ {
++ case 0:
++ OTV_LIMIT_CHECK( 6 );
++ break;
++
++ case 1:
++ OTV_LIMIT_CHECK( 10 );
++ table_size += 4;
++ break;
++
++ default:
++ FT_INVALID_FORMAT;
++ }
++
+ ScriptList = FT_NEXT_USHORT( p );
+ FeatureList = FT_NEXT_USHORT( p );
+ LookupList = FT_NEXT_USHORT( p );
+@@ -1014,6 +1036,14 @@
+ otv_ScriptList_validate( table + ScriptList, table + FeatureList,
+ otvalid );
+
++ if ( version > 0 )
++ {
++ OTV_OPTIONAL_OFFSET32( featureVariations );
++ OTV_SIZE_CHECK32( featureVariations );
++ if ( featureVariations )
++ OTV_TRACE(( " [omitting featureVariations validation]\n" )); /* XXX */
++ }
++
+ FT_TRACE4(( "\n" ));
+ }
+
+diff --git a/src/otvalid/otvgsub.c b/src/otvalid/otvgsub.c
+index f9bd8dc5d8..3b58b6dec4 100644
+--- a/src/otvalid/otvgsub.c
++++ b/src/otvalid/otvgsub.c
+@@ -552,18 +552,40 @@
+ OTV_ValidatorRec otvalidrec;
+ OTV_Validator otvalid = &otvalidrec;
+ FT_Bytes p = table;
++ FT_UInt table_size;
++ FT_UShort version;
+ FT_UInt ScriptList, FeatureList, LookupList;
+
++ OTV_OPTIONAL_TABLE32( featureVariations );
++
+
+ otvalid->root = ftvalid;
+
+ FT_TRACE3(( "validating GSUB table\n" ));
+ OTV_INIT;
+
+- OTV_LIMIT_CHECK( 10 );
++ OTV_LIMIT_CHECK( 4 );
++
++ if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */
++ FT_INVALID_FORMAT;
++
++ version = FT_NEXT_USHORT( p ); /* minorVersion */
++
++ table_size = 10;
++ switch ( version )
++ {
++ case 0:
++ OTV_LIMIT_CHECK( 6 );
++ break;
++
++ case 1:
++ OTV_LIMIT_CHECK( 10 );
++ table_size += 4;
++ break;
+
+- if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
++ default:
+ FT_INVALID_FORMAT;
++ }
+
+ ScriptList = FT_NEXT_USHORT( p );
+ FeatureList = FT_NEXT_USHORT( p );
+@@ -580,6 +602,14 @@
+ otv_ScriptList_validate( table + ScriptList, table + FeatureList,
+ otvalid );
+
++ if ( version > 0 )
++ {
++ OTV_OPTIONAL_OFFSET32( featureVariations );
++ OTV_SIZE_CHECK32( featureVariations );
++ if ( featureVariations )
++ OTV_TRACE(( " [omitting featureVariations validation]\n" )); /* XXX */
++ }
++
+ FT_TRACE4(( "\n" ));
+ }
+
+diff --git a/src/psaux/Jamfile b/src/psaux/Jamfile
+index 798b73d1cd..0e5944d690 100644
+--- a/src/psaux/Jamfile
++++ b/src/psaux/Jamfile
+@@ -22,6 +22,16 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psaux ;
+ psobjs
+ t1cmap
+ t1decode
++ cffdecode
++ psarrst
++ psblues
++ pserror
++ psfont
++ psft
++ pshints
++ psintrp
++ psread
++ psstack
+ ;
+ }
+ else
+diff --git a/src/psaux/cffdecode.c b/src/psaux/cffdecode.c
+new file mode 100644
+index 0000000000..6c48006524
+--- /dev/null
++++ b/src/psaux/cffdecode.c
+@@ -0,0 +1,2357 @@
++/***************************************************************************/
++/* */
++/* cffdecode.c */
++/* */
++/* PostScript CFF (Type 2) decoding routines (body). */
++/* */
++/* Copyright 2017 by */
++/* David Turner, Robert Wilhelm, and Werner Lemberg. */
++/* */
++/* This file is part of the FreeType project, and may only be used, */
++/* modified, and distributed under the terms of the FreeType project */
++/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
++/* this file you indicate that you have read the license and */
++/* understand and accept it fully. */
++/* */
++/***************************************************************************/
++
++
++#include <ft2build.h>
++#include FT_INTERNAL_SERVICE_H
++#include FT_SERVICE_CFF_TABLE_LOAD_H
++
++#include "cffdecode.h"
++#include "psobjs.h"
++
++#include "psauxerr.h"
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++
++ typedef enum CFF_Operator_
++ {
++ cff_op_unknown = 0,
++
++ cff_op_rmoveto,
++ cff_op_hmoveto,
++ cff_op_vmoveto,
++
++ cff_op_rlineto,
++ cff_op_hlineto,
++ cff_op_vlineto,
++
++ cff_op_rrcurveto,
++ cff_op_hhcurveto,
++ cff_op_hvcurveto,
++ cff_op_rcurveline,
++ cff_op_rlinecurve,
++ cff_op_vhcurveto,
++ cff_op_vvcurveto,
++
++ cff_op_flex,
++ cff_op_hflex,
++ cff_op_hflex1,
++ cff_op_flex1,
++
++ cff_op_endchar,
++
++ cff_op_hstem,
++ cff_op_vstem,
++ cff_op_hstemhm,
++ cff_op_vstemhm,
++
++ cff_op_hintmask,
++ cff_op_cntrmask,
++ cff_op_dotsection, /* deprecated, acts as no-op */
++
++ cff_op_abs,
++ cff_op_add,
++ cff_op_sub,
++ cff_op_div,
++ cff_op_neg,
++ cff_op_random,
++ cff_op_mul,
++ cff_op_sqrt,
++
++ cff_op_blend,
++
++ cff_op_drop,
++ cff_op_exch,
++ cff_op_index,
++ cff_op_roll,
++ cff_op_dup,
++
++ cff_op_put,
++ cff_op_get,
++ cff_op_store,
++ cff_op_load,
++
++ cff_op_and,
++ cff_op_or,
++ cff_op_not,
++ cff_op_eq,
++ cff_op_ifelse,
++
++ cff_op_callsubr,
++ cff_op_callgsubr,
++ cff_op_return,
++
++ /* Type 1 opcodes: invalid but seen in real life */
++ cff_op_hsbw,
++ cff_op_closepath,
++ cff_op_callothersubr,
++ cff_op_pop,
++ cff_op_seac,
++ cff_op_sbw,
++ cff_op_setcurrentpoint,
++
++ /* do not remove */
++ cff_op_max
++
++ } CFF_Operator;
++
++
++#define CFF_COUNT_CHECK_WIDTH 0x80
++#define CFF_COUNT_EXACT 0x40
++#define CFF_COUNT_CLEAR_STACK 0x20
++
++ /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
++ /* used for checking the width and requested numbers of arguments */
++ /* only; they are set to zero afterwards */
++
++ /* the other two flags are informative only and unused currently */
++
++ static const FT_Byte cff_argument_counts[] =
++ {
++ 0, /* unknown */
++
++ 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
++ 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
++ 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
++
++ 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
++ 0 | CFF_COUNT_CLEAR_STACK,
++ 0 | CFF_COUNT_CLEAR_STACK,
++
++ 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
++ 0 | CFF_COUNT_CLEAR_STACK,
++ 0 | CFF_COUNT_CLEAR_STACK,
++ 0 | CFF_COUNT_CLEAR_STACK,
++ 0 | CFF_COUNT_CLEAR_STACK,
++ 0 | CFF_COUNT_CLEAR_STACK,
++ 0 | CFF_COUNT_CLEAR_STACK,
++
++ 13, /* flex */
++ 7,
++ 9,
++ 11,
++
++ 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
++
++ 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
++ 2 | CFF_COUNT_CHECK_WIDTH,
++ 2 | CFF_COUNT_CHECK_WIDTH,
++ 2 | CFF_COUNT_CHECK_WIDTH,
++
++ 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
++ 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
++ 0, /* dotsection */
++
++ 1, /* abs */
++ 2,
++ 2,
++ 2,
++ 1,
++ 0,
++ 2,
++ 1,
++
++ 1, /* blend */
++
++ 1, /* drop */
++ 2,
++ 1,
++ 2,
++ 1,
++
++ 2, /* put */
++ 1,
++ 4,
++ 3,
++
++ 2, /* and */
++ 2,
++ 1,
++ 2,
++ 4,
++
++ 1, /* callsubr */
++ 1,
++ 0,
++
++ 2, /* hsbw */
++ 0,
++ 0,
++ 0,
++ 5, /* seac */
++ 4, /* sbw */
++ 2 /* setcurrentpoint */
++ };
++
++
++ static FT_Error
++ cff_operator_seac( CFF_Decoder* decoder,
++ FT_Pos asb,
++ FT_Pos adx,
++ FT_Pos ady,
++ FT_Int bchar,
++ FT_Int achar )
++ {
++ FT_Error error;
++ CFF_Builder* builder = &decoder->builder;
++ FT_Int bchar_index, achar_index;
++ TT_Face face = decoder->builder.face;
++ FT_Vector left_bearing, advance;
++ FT_Byte* charstring;
++ FT_ULong charstring_len;
++ FT_Pos glyph_width;
++
++
++ if ( decoder->seac )
++ {
++ FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
++ return FT_THROW( Syntax_Error );
++ }
++
++ adx += decoder->builder.left_bearing.x;
++ ady += decoder->builder.left_bearing.y;
++
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ /* Incremental fonts don't necessarily have valid charsets. */
++ /* They use the character code, not the glyph index, in this case. */
++ if ( face->root.internal->incremental_interface )
++ {
++ bchar_index = bchar;
++ achar_index = achar;
++ }
++ else
++#endif /* FT_CONFIG_OPTION_INCREMENTAL */
++ {
++ CFF_Font cff = (CFF_Font)(face->extra.data);
++
++
++ bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
++ achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
++ }
++
++ if ( bchar_index < 0 || achar_index < 0 )
++ {
++ FT_ERROR(( "cff_operator_seac:"
++ " invalid seac character code arguments\n" ));
++ return FT_THROW( Syntax_Error );
++ }
++
++ /* If we are trying to load a composite glyph, do not load the */
++ /* accent character and return the array of subglyphs. */
++ if ( builder->no_recurse )
++ {
++ FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph;
++ FT_GlyphLoader loader = glyph->internal->loader;
++ FT_SubGlyph subg;
++
++
++ /* reallocate subglyph array if necessary */
++ error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
++ if ( error )
++ goto Exit;
++
++ subg = loader->current.subglyphs;
++
++ /* subglyph 0 = base character */
++ subg->index = bchar_index;
++ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
++ FT_SUBGLYPH_FLAG_USE_MY_METRICS;
++ subg->arg1 = 0;
++ subg->arg2 = 0;
++ subg++;
++
++ /* subglyph 1 = accent character */
++ subg->index = achar_index;
++ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
++ subg->arg1 = (FT_Int)( adx >> 16 );
++ subg->arg2 = (FT_Int)( ady >> 16 );
++
++ /* set up remaining glyph fields */
++ glyph->num_subglyphs = 2;
++ glyph->subglyphs = loader->base.subglyphs;
++ glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
++
++ loader->current.num_subglyphs = 2;
++ }
++
++ FT_GlyphLoader_Prepare( builder->loader );
++
++ /* First load `bchar' in builder */
++ error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index,
++ &charstring, &charstring_len );
++ if ( !error )
++ {
++ /* the seac operator must not be nested */
++ decoder->seac = TRUE;
++ error = cff_decoder_parse_charstrings( decoder, charstring,
++ charstring_len, 0 );
++ decoder->seac = FALSE;
++
++ decoder->free_glyph_callback( face, &charstring, charstring_len );
++
++ if ( error )
++ goto Exit;
++ }
++
++ /* Save the left bearing, advance and glyph width of the base */
++ /* character as they will be erased by the next load. */
++
++ left_bearing = builder->left_bearing;
++ advance = builder->advance;
++ glyph_width = decoder->glyph_width;
++
++ builder->left_bearing.x = 0;
++ builder->left_bearing.y = 0;
++
++ builder->pos_x = adx - asb;
++ builder->pos_y = ady;
++
++ /* Now load `achar' on top of the base outline. */
++ error = decoder->get_glyph_callback( face, (FT_UInt)achar_index,
++ &charstring, &charstring_len );
++ if ( !error )
++ {
++ /* the seac operator must not be nested */
++ decoder->seac = TRUE;
++ error = cff_decoder_parse_charstrings( decoder, charstring,
++ charstring_len, 0 );
++ decoder->seac = FALSE;
++
++ decoder->free_glyph_callback( face, &charstring, charstring_len );
++
++ if ( error )
++ goto Exit;
++ }
++
++ /* Restore the left side bearing, advance and glyph width */
++ /* of the base character. */
++ builder->left_bearing = left_bearing;
++ builder->advance = advance;
++ decoder->glyph_width = glyph_width;
++
++ builder->pos_x = 0;
++ builder->pos_y = 0;
++
++ Exit:
++ return error;
++ }
++
++#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
++
++
++ /*************************************************************************/
++ /*************************************************************************/
++ /*************************************************************************/
++ /********** *********/
++ /********** *********/
++ /********** GENERIC CHARSTRING PARSING *********/
++ /********** *********/
++ /********** *********/
++ /*************************************************************************/
++ /*************************************************************************/
++ /*************************************************************************/
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* cff_compute_bias */
++ /* */
++ /* <Description> */
++ /* Computes the bias value in dependence of the number of glyph */
++ /* subroutines. */
++ /* */
++ /* <Input> */
++ /* in_charstring_type :: The `CharstringType' value of the top DICT */
++ /* dictionary. */
++ /* */
++ /* num_subrs :: The number of glyph subroutines. */
++ /* */
++ /* <Return> */
++ /* The bias value. */
++ static FT_Int
++ cff_compute_bias( FT_Int in_charstring_type,
++ FT_UInt num_subrs )
++ {
++ FT_Int result;
++
++
++ if ( in_charstring_type == 1 )
++ result = 0;
++ else if ( num_subrs < 1240 )
++ result = 107;
++ else if ( num_subrs < 33900U )
++ result = 1131;
++ else
++ result = 32768U;
++
++ return result;
++ }
++
++
++ FT_LOCAL_DEF( FT_Int )
++ cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
++ FT_Int charcode )
++ {
++ FT_UInt n;
++ FT_UShort glyph_sid;
++
++ FT_Service_CFFLoad cffload;
++
++
++ /* CID-keyed fonts don't have glyph names */
++ if ( !cff->charset.sids )
++ return -1;
++
++ /* check range of standard char code */
++ if ( charcode < 0 || charcode > 255 )
++ return -1;
++
++#if 0
++ /* retrieve cffload from list of current modules */
++ FT_Service_CFFLoad cffload;
++
++
++ FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
++ if ( !cffload )
++ {
++ FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:"
++ " the `cffload' module is not available\n" ));
++ return FT_THROW( Unimplemented_Feature );
++ }
++#endif
++
++ cffload = (FT_Service_CFFLoad)cff->cffload;
++
++ /* Get code to SID mapping from `cff_standard_encoding'. */
++ glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
++
++ for ( n = 0; n < cff->num_glyphs; n++ )
++ {
++ if ( cff->charset.sids[n] == glyph_sid )
++ return (FT_Int)n;
++ }
++
++ return -1;
++ }
++
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* cff_decoder_parse_charstrings */
++ /* */
++ /* <Description> */
++ /* Parses a given Type 2 charstrings program. */
++ /* */
++ /* <InOut> */
++ /* decoder :: The current Type 1 decoder. */
++ /* */
++ /* <Input> */
++ /* charstring_base :: The base of the charstring stream. */
++ /* */
++ /* charstring_len :: The length in bytes of the charstring stream. */
++ /* */
++ /* in_dict :: Set to 1 if function is called from top or */
++ /* private DICT (needed for Multiple Master CFFs). */
++ /* */
++ /* <Return> */
++ /* FreeType error code. 0 means success. */
++ /* */
++ FT_LOCAL_DEF( FT_Error )
++ cff_decoder_parse_charstrings( CFF_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len,
++ FT_Bool in_dict )
++ {
++ FT_Error error;
++ CFF_Decoder_Zone* zone;
++ FT_Byte* ip;
++ FT_Byte* limit;
++ CFF_Builder* builder = &decoder->builder;
++ FT_Pos x, y;
++ FT_Fixed* stack;
++ FT_Int charstring_type =
++ decoder->cff->top_font.font_dict.charstring_type;
++ FT_UShort num_designs =
++ decoder->cff->top_font.font_dict.num_designs;
++ FT_UShort num_axes =
++ decoder->cff->top_font.font_dict.num_axes;
++
++ T2_Hints_Funcs hinter;
++
++
++ /* set default width */
++ decoder->num_hints = 0;
++ decoder->read_width = 1;
++
++ /* initialize the decoder */
++ decoder->top = decoder->stack;
++ decoder->zone = decoder->zones;
++ zone = decoder->zones;
++ stack = decoder->top;
++
++ hinter = (T2_Hints_Funcs)builder->hints_funcs;
++
++ builder->path_begun = 0;
++
++ zone->base = charstring_base;
++ limit = zone->limit = charstring_base + charstring_len;
++ ip = zone->cursor = zone->base;
++
++ error = FT_Err_Ok;
++
++ x = builder->pos_x;
++ y = builder->pos_y;
++
++ /* begin hints recording session, if any */
++ if ( hinter )
++ hinter->open( hinter->hints );
++
++ /* now execute loop */
++ while ( ip < limit )
++ {
++ CFF_Operator op;
++ FT_Byte v;
++
++
++ /********************************************************************/
++ /* */
++ /* Decode operator or operand */
++ /* */
++ v = *ip++;
++ if ( v >= 32 || v == 28 )
++ {
++ FT_Int shift = 16;
++ FT_Int32 val;
++
++
++ /* this is an operand, push it on the stack */
++
++ /* if we use shifts, all computations are done with unsigned */
++ /* values; the conversion to a signed value is the last step */
++ if ( v == 28 )
++ {
++ if ( ip + 1 >= limit )
++ goto Syntax_Error;
++ val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
++ ip += 2;
++ }
++ else if ( v < 247 )
++ val = (FT_Int32)v - 139;
++ else if ( v < 251 )
++ {
++ if ( ip >= limit )
++ goto Syntax_Error;
++ val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
++ }
++ else if ( v < 255 )
++ {
++ if ( ip >= limit )
++ goto Syntax_Error;
++ val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
++ }
++ else
++ {
++ if ( ip + 3 >= limit )
++ goto Syntax_Error;
++ val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
++ ( (FT_UInt32)ip[1] << 16 ) |
++ ( (FT_UInt32)ip[2] << 8 ) |
++ (FT_UInt32)ip[3] );
++ ip += 4;
++ if ( charstring_type == 2 )
++ shift = 0;
++ }
++ if ( decoder->top - stack >= CFF_MAX_OPERANDS )
++ goto Stack_Overflow;
++
++ val = (FT_Int32)( (FT_UInt32)val << shift );
++ *decoder->top++ = val;
++
++#ifdef FT_DEBUG_LEVEL_TRACE
++ if ( !( val & 0xFFFFL ) )
++ FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
++ else
++ FT_TRACE4(( " %.5f", val / 65536.0 ));
++#endif
++
++ }
++ else
++ {
++ /* The specification says that normally arguments are to be taken */
++ /* from the bottom of the stack. However, this seems not to be */
++ /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
++ /* arguments similar to a PS interpreter. */
++
++ FT_Fixed* args = decoder->top;
++ FT_Int num_args = (FT_Int)( args - decoder->stack );
++ FT_Int req_args;
++
++
++ /* find operator */
++ op = cff_op_unknown;
++
++ switch ( v )
++ {
++ case 1:
++ op = cff_op_hstem;
++ break;
++ case 3:
++ op = cff_op_vstem;
++ break;
++ case 4:
++ op = cff_op_vmoveto;
++ break;
++ case 5:
++ op = cff_op_rlineto;
++ break;
++ case 6:
++ op = cff_op_hlineto;
++ break;
++ case 7:
++ op = cff_op_vlineto;
++ break;
++ case 8:
++ op = cff_op_rrcurveto;
++ break;
++ case 9:
++ op = cff_op_closepath;
++ break;
++ case 10:
++ op = cff_op_callsubr;
++ break;
++ case 11:
++ op = cff_op_return;
++ break;
++ case 12:
++ if ( ip >= limit )
++ goto Syntax_Error;
++ v = *ip++;
++
++ switch ( v )
++ {
++ case 0:
++ op = cff_op_dotsection;
++ break;
++ case 1: /* this is actually the Type1 vstem3 operator */
++ op = cff_op_vstem;
++ break;
++ case 2: /* this is actually the Type1 hstem3 operator */
++ op = cff_op_hstem;
++ break;
++ case 3:
++ op = cff_op_and;
++ break;
++ case 4:
++ op = cff_op_or;
++ break;
++ case 5:
++ op = cff_op_not;
++ break;
++ case 6:
++ op = cff_op_seac;
++ break;
++ case 7:
++ op = cff_op_sbw;
++ break;
++ case 8:
++ op = cff_op_store;
++ break;
++ case 9:
++ op = cff_op_abs;
++ break;
++ case 10:
++ op = cff_op_add;
++ break;
++ case 11:
++ op = cff_op_sub;
++ break;
++ case 12:
++ op = cff_op_div;
++ break;
++ case 13:
++ op = cff_op_load;
++ break;
++ case 14:
++ op = cff_op_neg;
++ break;
++ case 15:
++ op = cff_op_eq;
++ break;
++ case 16:
++ op = cff_op_callothersubr;
++ break;
++ case 17:
++ op = cff_op_pop;
++ break;
++ case 18:
++ op = cff_op_drop;
++ break;
++ case 20:
++ op = cff_op_put;
++ break;
++ case 21:
++ op = cff_op_get;
++ break;
++ case 22:
++ op = cff_op_ifelse;
++ break;
++ case 23:
++ op = cff_op_random;
++ break;
++ case 24:
++ op = cff_op_mul;
++ break;
++ case 26:
++ op = cff_op_sqrt;
++ break;
++ case 27:
++ op = cff_op_dup;
++ break;
++ case 28:
++ op = cff_op_exch;
++ break;
++ case 29:
++ op = cff_op_index;
++ break;
++ case 30:
++ op = cff_op_roll;
++ break;
++ case 33:
++ op = cff_op_setcurrentpoint;
++ break;
++ case 34:
++ op = cff_op_hflex;
++ break;
++ case 35:
++ op = cff_op_flex;
++ break;
++ case 36:
++ op = cff_op_hflex1;
++ break;
++ case 37:
++ op = cff_op_flex1;
++ break;
++ default:
++ FT_TRACE4(( " unknown op (12, %d)\n", v ));
++ break;
++ }
++ break;
++ case 13:
++ op = cff_op_hsbw;
++ break;
++ case 14:
++ op = cff_op_endchar;
++ break;
++ case 16:
++ op = cff_op_blend;
++ break;
++ case 18:
++ op = cff_op_hstemhm;
++ break;
++ case 19:
++ op = cff_op_hintmask;
++ break;
++ case 20:
++ op = cff_op_cntrmask;
++ break;
++ case 21:
++ op = cff_op_rmoveto;
++ break;
++ case 22:
++ op = cff_op_hmoveto;
++ break;
++ case 23:
++ op = cff_op_vstemhm;
++ break;
++ case 24:
++ op = cff_op_rcurveline;
++ break;
++ case 25:
++ op = cff_op_rlinecurve;
++ break;
++ case 26:
++ op = cff_op_vvcurveto;
++ break;
++ case 27:
++ op = cff_op_hhcurveto;
++ break;
++ case 29:
++ op = cff_op_callgsubr;
++ break;
++ case 30:
++ op = cff_op_vhcurveto;
++ break;
++ case 31:
++ op = cff_op_hvcurveto;
++ break;
++ default:
++ FT_TRACE4(( " unknown op (%d)\n", v ));
++ break;
++ }
++
++ if ( op == cff_op_unknown )
++ continue;
++
++ /* in Multiple Master CFFs, T2 charstrings can appear in */
++ /* dictionaries, but some operators are prohibited */
++ if ( in_dict )
++ {
++ switch ( op )
++ {
++ case cff_op_hstem:
++ case cff_op_vstem:
++ case cff_op_vmoveto:
++ case cff_op_rlineto:
++ case cff_op_hlineto:
++ case cff_op_vlineto:
++ case cff_op_rrcurveto:
++ case cff_op_hstemhm:
++ case cff_op_hintmask:
++ case cff_op_cntrmask:
++ case cff_op_rmoveto:
++ case cff_op_hmoveto:
++ case cff_op_vstemhm:
++ case cff_op_rcurveline:
++ case cff_op_rlinecurve:
++ case cff_op_vvcurveto:
++ case cff_op_hhcurveto:
++ case cff_op_vhcurveto:
++ case cff_op_hvcurveto:
++ case cff_op_hflex:
++ case cff_op_flex:
++ case cff_op_hflex1:
++ case cff_op_flex1:
++ case cff_op_callsubr:
++ case cff_op_callgsubr:
++ goto MM_Error;
++
++ default:
++ break;
++ }
++ }
++
++ /* check arguments */
++ req_args = cff_argument_counts[op];
++ if ( req_args & CFF_COUNT_CHECK_WIDTH )
++ {
++ if ( num_args > 0 && decoder->read_width )
++ {
++ /* If `nominal_width' is non-zero, the number is really a */
++ /* difference against `nominal_width'. Else, the number here */
++ /* is truly a width, not a difference against `nominal_width'. */
++ /* If the font does not set `nominal_width', then */
++ /* `nominal_width' defaults to zero, and so we can set */
++ /* `glyph_width' to `nominal_width' plus number on the stack */
++ /* -- for either case. */
++
++ FT_Int set_width_ok;
++
++
++ switch ( op )
++ {
++ case cff_op_hmoveto:
++ case cff_op_vmoveto:
++ set_width_ok = num_args & 2;
++ break;
++
++ case cff_op_hstem:
++ case cff_op_vstem:
++ case cff_op_hstemhm:
++ case cff_op_vstemhm:
++ case cff_op_rmoveto:
++ case cff_op_hintmask:
++ case cff_op_cntrmask:
++ set_width_ok = num_args & 1;
++ break;
++
++ case cff_op_endchar:
++ /* If there is a width specified for endchar, we either have */
++ /* 1 argument or 5 arguments. We like to argue. */
++ set_width_ok = in_dict
++ ? 0
++ : ( ( num_args == 5 ) || ( num_args == 1 ) );
++ break;
++
++ default:
++ set_width_ok = 0;
++ break;
++ }
++
++ if ( set_width_ok )
++ {
++ decoder->glyph_width = decoder->nominal_width +
++ ( stack[0] >> 16 );
++
++ if ( decoder->width_only )
++ {
++ /* we only want the advance width; stop here */
++ break;
++ }
++
++ /* Consumed an argument. */
++ num_args--;
++ }
++ }
++
++ decoder->read_width = 0;
++ req_args = 0;
++ }
++
++ req_args &= 0x000F;
++ if ( num_args < req_args )
++ goto Stack_Underflow;
++ args -= req_args;
++ num_args -= req_args;
++
++ /* At this point, `args' points to the first argument of the */
++ /* operand in case `req_args' isn't zero. Otherwise, we have */
++ /* to adjust `args' manually. */
++
++ /* Note that we only pop arguments from the stack which we */
++ /* really need and can digest so that we can continue in case */
++ /* of superfluous stack elements. */
++
++ switch ( op )
++ {
++ case cff_op_hstem:
++ case cff_op_vstem:
++ case cff_op_hstemhm:
++ case cff_op_vstemhm:
++ /* the number of arguments is always even here */
++ FT_TRACE4((
++ op == cff_op_hstem ? " hstem\n" :
++ ( op == cff_op_vstem ? " vstem\n" :
++ ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
++
++ if ( hinter )
++ hinter->stems( hinter->hints,
++ ( op == cff_op_hstem || op == cff_op_hstemhm ),
++ num_args / 2,
++ args - ( num_args & ~1 ) );
++
++ decoder->num_hints += num_args / 2;
++ args = stack;
++ break;
++
++ case cff_op_hintmask:
++ case cff_op_cntrmask:
++ FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
++
++ /* implement vstem when needed -- */
++ /* the specification doesn't say it, but this also works */
++ /* with the 'cntrmask' operator */
++ /* */
++ if ( num_args > 0 )
++ {
++ if ( hinter )
++ hinter->stems( hinter->hints,
++ 0,
++ num_args / 2,
++ args - ( num_args & ~1 ) );
++
++ decoder->num_hints += num_args / 2;
++ }
++
++ /* In a valid charstring there must be at least one byte */
++ /* after `hintmask' or `cntrmask' (e.g., for a `return' */
++ /* instruction). Additionally, there must be space for */
++ /* `num_hints' bits. */
++
++ if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
++ goto Syntax_Error;
++
++ if ( hinter )
++ {
++ if ( op == cff_op_hintmask )
++ hinter->hintmask( hinter->hints,
++ (FT_UInt)builder->current->n_points,
++ (FT_UInt)decoder->num_hints,
++ ip );
++ else
++ hinter->counter( hinter->hints,
++ (FT_UInt)decoder->num_hints,
++ ip );
++ }
++
++#ifdef FT_DEBUG_LEVEL_TRACE
++ {
++ FT_UInt maskbyte;
++
++
++ FT_TRACE4(( " (maskbytes:" ));
++
++ for ( maskbyte = 0;
++ maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
++ maskbyte++, ip++ )
++ FT_TRACE4(( " 0x%02X", *ip ));
++
++ FT_TRACE4(( ")\n" ));
++ }
++#else
++ ip += ( decoder->num_hints + 7 ) >> 3;
++#endif
++ args = stack;
++ break;
++
++ case cff_op_rmoveto:
++ FT_TRACE4(( " rmoveto\n" ));
++
++ cff_builder_close_contour( builder );
++ builder->path_begun = 0;
++ x = ADD_LONG( x, args[-2] );
++ y = ADD_LONG( y, args[-1] );
++ args = stack;
++ break;
++
++ case cff_op_vmoveto:
++ FT_TRACE4(( " vmoveto\n" ));
++
++ cff_builder_close_contour( builder );
++ builder->path_begun = 0;
++ y = ADD_LONG( y, args[-1] );
++ args = stack;
++ break;
++
++ case cff_op_hmoveto:
++ FT_TRACE4(( " hmoveto\n" ));
++
++ cff_builder_close_contour( builder );
++ builder->path_begun = 0;
++ x = ADD_LONG( x, args[-1] );
++ args = stack;
++ break;
++
++ case cff_op_rlineto:
++ FT_TRACE4(( " rlineto\n" ));
++
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, num_args / 2 ) )
++ goto Fail;
++
++ if ( num_args < 2 )
++ goto Stack_Underflow;
++
++ args -= num_args & ~1;
++ while ( args < decoder->top )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 1 );
++ args += 2;
++ }
++ args = stack;
++ break;
++
++ case cff_op_hlineto:
++ case cff_op_vlineto:
++ {
++ FT_Int phase = ( op == cff_op_hlineto );
++
++
++ FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
++ : " vlineto\n" ));
++
++ if ( num_args < 0 )
++ goto Stack_Underflow;
++
++ /* there exist subsetted fonts (found in PDFs) */
++ /* which call `hlineto' without arguments */
++ if ( num_args == 0 )
++ break;
++
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, num_args ) )
++ goto Fail;
++
++ args = stack;
++ while ( args < decoder->top )
++ {
++ if ( phase )
++ x = ADD_LONG( x, args[0] );
++ else
++ y = ADD_LONG( y, args[0] );
++
++ if ( cff_builder_add_point1( builder, x, y ) )
++ goto Fail;
++
++ args++;
++ phase ^= 1;
++ }
++ args = stack;
++ }
++ break;
++
++ case cff_op_rrcurveto:
++ {
++ FT_Int nargs;
++
++
++ FT_TRACE4(( " rrcurveto\n" ));
++
++ if ( num_args < 6 )
++ goto Stack_Underflow;
++
++ nargs = num_args - num_args % 6;
++
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, nargs / 2 ) )
++ goto Fail;
++
++ args -= nargs;
++ while ( args < decoder->top )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[2] );
++ y = ADD_LONG( y, args[3] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[4] );
++ y = ADD_LONG( y, args[5] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args += 6;
++ }
++ args = stack;
++ }
++ break;
++
++ case cff_op_vvcurveto:
++ {
++ FT_Int nargs;
++
++
++ FT_TRACE4(( " vvcurveto\n" ));
++
++ if ( num_args < 4 )
++ goto Stack_Underflow;
++
++ /* if num_args isn't of the form 4n or 4n+1, */
++ /* we enforce it by clearing the second bit */
++
++ nargs = num_args & ~2;
++
++ if ( cff_builder_start_point( builder, x, y ) )
++ goto Fail;
++
++ args -= nargs;
++
++ if ( nargs & 1 )
++ {
++ x = ADD_LONG( x, args[0] );
++ args++;
++ nargs--;
++ }
++
++ if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
++ goto Fail;
++
++ while ( args < decoder->top )
++ {
++ y = ADD_LONG( y, args[0] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[1] );
++ y = ADD_LONG( y, args[2] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ y = ADD_LONG( y, args[3] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args += 4;
++ }
++ args = stack;
++ }
++ break;
++
++ case cff_op_hhcurveto:
++ {
++ FT_Int nargs;
++
++
++ FT_TRACE4(( " hhcurveto\n" ));
++
++ if ( num_args < 4 )
++ goto Stack_Underflow;
++
++ /* if num_args isn't of the form 4n or 4n+1, */
++ /* we enforce it by clearing the second bit */
++
++ nargs = num_args & ~2;
++
++ if ( cff_builder_start_point( builder, x, y ) )
++ goto Fail;
++
++ args -= nargs;
++ if ( nargs & 1 )
++ {
++ y = ADD_LONG( y, args[0] );
++ args++;
++ nargs--;
++ }
++
++ if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
++ goto Fail;
++
++ while ( args < decoder->top )
++ {
++ x = ADD_LONG( x, args[0] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[1] );
++ y = ADD_LONG( y, args[2] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[3] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args += 4;
++ }
++ args = stack;
++ }
++ break;
++
++ case cff_op_vhcurveto:
++ case cff_op_hvcurveto:
++ {
++ FT_Int phase;
++ FT_Int nargs;
++
++
++ FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
++ : " hvcurveto\n" ));
++
++ if ( cff_builder_start_point( builder, x, y ) )
++ goto Fail;
++
++ if ( num_args < 4 )
++ goto Stack_Underflow;
++
++ /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
++ /* we enforce it by clearing the second bit */
++
++ nargs = num_args & ~2;
++
++ args -= nargs;
++ if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
++ goto Stack_Underflow;
++
++ phase = ( op == cff_op_hvcurveto );
++
++ while ( nargs >= 4 )
++ {
++ nargs -= 4;
++ if ( phase )
++ {
++ x = ADD_LONG( x, args[0] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[1] );
++ y = ADD_LONG( y, args[2] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ y = ADD_LONG( y, args[3] );
++ if ( nargs == 1 )
++ x = ADD_LONG( x, args[4] );
++ cff_builder_add_point( builder, x, y, 1 );
++ }
++ else
++ {
++ y = ADD_LONG( y, args[0] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[1] );
++ y = ADD_LONG( y, args[2] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[3] );
++ if ( nargs == 1 )
++ y = ADD_LONG( y, args[4] );
++ cff_builder_add_point( builder, x, y, 1 );
++ }
++ args += 4;
++ phase ^= 1;
++ }
++ args = stack;
++ }
++ break;
++
++ case cff_op_rlinecurve:
++ {
++ FT_Int num_lines;
++ FT_Int nargs;
++
++
++ FT_TRACE4(( " rlinecurve\n" ));
++
++ if ( num_args < 8 )
++ goto Stack_Underflow;
++
++ nargs = num_args & ~1;
++ num_lines = ( nargs - 6 ) / 2;
++
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, num_lines + 3 ) )
++ goto Fail;
++
++ args -= nargs;
++
++ /* first, add the line segments */
++ while ( num_lines > 0 )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args += 2;
++ num_lines--;
++ }
++
++ /* then the curve */
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[2] );
++ y = ADD_LONG( y, args[3] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[4] );
++ y = ADD_LONG( y, args[5] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args = stack;
++ }
++ break;
++
++ case cff_op_rcurveline:
++ {
++ FT_Int num_curves;
++ FT_Int nargs;
++
++
++ FT_TRACE4(( " rcurveline\n" ));
++
++ if ( num_args < 8 )
++ goto Stack_Underflow;
++
++ nargs = num_args - 2;
++ nargs = nargs - nargs % 6 + 2;
++ num_curves = ( nargs - 2 ) / 6;
++
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, num_curves * 3 + 2 ) )
++ goto Fail;
++
++ args -= nargs;
++
++ /* first, add the curves */
++ while ( num_curves > 0 )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[2] );
++ y = ADD_LONG( y, args[3] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ x = ADD_LONG( x, args[4] );
++ y = ADD_LONG( y, args[5] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args += 6;
++ num_curves--;
++ }
++
++ /* then the final line */
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args = stack;
++ }
++ break;
++
++ case cff_op_hflex1:
++ {
++ FT_Pos start_y;
++
++
++ FT_TRACE4(( " hflex1\n" ));
++
++ /* adding five more points: 4 control points, 1 on-curve point */
++ /* -- make sure we have enough space for the start point if it */
++ /* needs to be added */
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, 6 ) )
++ goto Fail;
++
++ /* record the starting point's y position for later use */
++ start_y = y;
++
++ /* first control point */
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* second control point */
++ x = ADD_LONG( x, args[2] );
++ y = ADD_LONG( y, args[3] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* join point; on curve, with y-value the same as the last */
++ /* control point's y-value */
++ x = ADD_LONG( x, args[4] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ /* third control point, with y-value the same as the join */
++ /* point's y-value */
++ x = ADD_LONG( x, args[5] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* fourth control point */
++ x = ADD_LONG( x, args[6] );
++ y = ADD_LONG( y, args[7] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* ending point, with y-value the same as the start */
++ x = ADD_LONG( x, args[8] );
++ y = start_y;
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args = stack;
++ break;
++ }
++
++ case cff_op_hflex:
++ {
++ FT_Pos start_y;
++
++
++ FT_TRACE4(( " hflex\n" ));
++
++ /* adding six more points; 4 control points, 2 on-curve points */
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, 6 ) )
++ goto Fail;
++
++ /* record the starting point's y-position for later use */
++ start_y = y;
++
++ /* first control point */
++ x = ADD_LONG( x, args[0] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* second control point */
++ x = ADD_LONG( x, args[1] );
++ y = ADD_LONG( y, args[2] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* join point; on curve, with y-value the same as the last */
++ /* control point's y-value */
++ x = ADD_LONG( x, args[3] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ /* third control point, with y-value the same as the join */
++ /* point's y-value */
++ x = ADD_LONG( x, args[4] );
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* fourth control point */
++ x = ADD_LONG( x, args[5] );
++ y = start_y;
++ cff_builder_add_point( builder, x, y, 0 );
++
++ /* ending point, with y-value the same as the start point's */
++ /* y-value -- we don't add this point, though */
++ x = ADD_LONG( x, args[6] );
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args = stack;
++ break;
++ }
++
++ case cff_op_flex1:
++ {
++ FT_Pos start_x, start_y; /* record start x, y values for */
++ /* alter use */
++ FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
++ /* algorithm below */
++ FT_Int horizontal, count;
++ FT_Fixed* temp;
++
++
++ FT_TRACE4(( " flex1\n" ));
++
++ /* adding six more points; 4 control points, 2 on-curve points */
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, 6 ) )
++ goto Fail;
++
++ /* record the starting point's x, y position for later use */
++ start_x = x;
++ start_y = y;
++
++ /* XXX: figure out whether this is supposed to be a horizontal */
++ /* or vertical flex; the Type 2 specification is vague... */
++
++ temp = args;
++
++ /* grab up to the last argument */
++ for ( count = 5; count > 0; count-- )
++ {
++ dx = ADD_LONG( dx, temp[0] );
++ dy = ADD_LONG( dy, temp[1] );
++ temp += 2;
++ }
++
++ if ( dx < 0 )
++ dx = -dx;
++ if ( dy < 0 )
++ dy = -dy;
++
++ /* strange test, but here it is... */
++ horizontal = ( dx > dy );
++
++ for ( count = 5; count > 0; count-- )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y,
++ (FT_Bool)( count == 3 ) );
++ args += 2;
++ }
++
++ /* is last operand an x- or y-delta? */
++ if ( horizontal )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = start_y;
++ }
++ else
++ {
++ x = start_x;
++ y = ADD_LONG( y, args[0] );
++ }
++
++ cff_builder_add_point( builder, x, y, 1 );
++
++ args = stack;
++ break;
++ }
++
++ case cff_op_flex:
++ {
++ FT_UInt count;
++
++
++ FT_TRACE4(( " flex\n" ));
++
++ if ( cff_builder_start_point( builder, x, y ) ||
++ cff_check_points( builder, 6 ) )
++ goto Fail;
++
++ for ( count = 6; count > 0; count-- )
++ {
++ x = ADD_LONG( x, args[0] );
++ y = ADD_LONG( y, args[1] );
++ cff_builder_add_point( builder, x, y,
++ (FT_Bool)( count == 4 || count == 1 ) );
++ args += 2;
++ }
++
++ args = stack;
++ }
++ break;
++
++ case cff_op_seac:
++ FT_TRACE4(( " seac\n" ));
++
++ error = cff_operator_seac( decoder,
++ args[0], args[1], args[2],
++ (FT_Int)( args[3] >> 16 ),
++ (FT_Int)( args[4] >> 16 ) );
++
++ /* add current outline to the glyph slot */
++ FT_GlyphLoader_Add( builder->loader );
++
++ /* return now! */
++ FT_TRACE4(( "\n" ));
++ return error;
++
++ case cff_op_endchar:
++ /* in dictionaries, `endchar' simply indicates end of data */
++ if ( in_dict )
++ return error;
++
++ FT_TRACE4(( " endchar\n" ));
++
++ /* We are going to emulate the seac operator. */
++ if ( num_args >= 4 )
++ {
++ /* Save glyph width so that the subglyphs don't overwrite it. */
++ FT_Pos glyph_width = decoder->glyph_width;
++
++
++ error = cff_operator_seac( decoder,
++ 0L, args[-4], args[-3],
++ (FT_Int)( args[-2] >> 16 ),
++ (FT_Int)( args[-1] >> 16 ) );
++
++ decoder->glyph_width = glyph_width;
++ }
++ else
++ {
++ cff_builder_close_contour( builder );
++
++ /* close hints recording session */
++ if ( hinter )
++ {
++ if ( hinter->close( hinter->hints,
++ (FT_UInt)builder->current->n_points ) )
++ goto Syntax_Error;
++
++ /* apply hints to the loaded glyph outline now */
++ error = hinter->apply( hinter->hints,
++ builder->current,
++ (PSH_Globals)builder->hints_globals,
++ decoder->hint_mode );
++ if ( error )
++ goto Fail;
++ }
++
++ /* add current outline to the glyph slot */
++ FT_GlyphLoader_Add( builder->loader );
++ }
++
++ /* return now! */
++ FT_TRACE4(( "\n" ));
++ return error;
++
++ case cff_op_abs:
++ FT_TRACE4(( " abs\n" ));
++
++ if ( args[0] < 0 )
++ {
++ if ( args[0] == FT_LONG_MIN )
++ args[0] = FT_LONG_MAX;
++ else
++ args[0] = -args[0];
++ }
++ args++;
++ break;
++
++ case cff_op_add:
++ FT_TRACE4(( " add\n" ));
++
++ args[0] = ADD_LONG( args[0], args[1] );
++ args++;
++ break;
++
++ case cff_op_sub:
++ FT_TRACE4(( " sub\n" ));
++
++ args[0] = SUB_LONG( args[0], args[1] );
++ args++;
++ break;
++
++ case cff_op_div:
++ FT_TRACE4(( " div\n" ));
++
++ args[0] = FT_DivFix( args[0], args[1] );
++ args++;
++ break;
++
++ case cff_op_neg:
++ FT_TRACE4(( " neg\n" ));
++
++ if ( args[0] == FT_LONG_MIN )
++ args[0] = FT_LONG_MAX;
++ args[0] = -args[0];
++ args++;
++ break;
++
++ case cff_op_random:
++ FT_TRACE4(( " random\n" ));
++
++ /* only use the lower 16 bits of `random' */
++ /* to generate a number in the range (0;1] */
++ args[0] = (FT_Fixed)
++ ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
++ args++;
++
++ decoder->current_subfont->random =
++ cff_random( decoder->current_subfont->random );
++ break;
++
++ case cff_op_mul:
++ FT_TRACE4(( " mul\n" ));
++
++ args[0] = FT_MulFix( args[0], args[1] );
++ args++;
++ break;
++
++ case cff_op_sqrt:
++ FT_TRACE4(( " sqrt\n" ));
++
++ if ( args[0] > 0 )
++ {
++ FT_Fixed root = args[0];
++ FT_Fixed new_root;
++
++
++ for (;;)
++ {
++ new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
++ if ( new_root == root )
++ break;
++ root = new_root;
++ }
++ args[0] = new_root;
++ }
++ else
++ args[0] = 0;
++ args++;
++ break;
++
++ case cff_op_drop:
++ /* nothing */
++ FT_TRACE4(( " drop\n" ));
++
++ break;
++
++ case cff_op_exch:
++ {
++ FT_Fixed tmp;
++
++
++ FT_TRACE4(( " exch\n" ));
++
++ tmp = args[0];
++ args[0] = args[1];
++ args[1] = tmp;
++ args += 2;
++ }
++ break;
++
++ case cff_op_index:
++ {
++ FT_Int idx = (FT_Int)( args[0] >> 16 );
++
++
++ FT_TRACE4(( " index\n" ));
++
++ if ( idx < 0 )
++ idx = 0;
++ else if ( idx > num_args - 2 )
++ idx = num_args - 2;
++ args[0] = args[-( idx + 1 )];
++ args++;
++ }
++ break;
++
++ case cff_op_roll:
++ {
++ FT_Int count = (FT_Int)( args[0] >> 16 );
++ FT_Int idx = (FT_Int)( args[1] >> 16 );
++
++
++ FT_TRACE4(( " roll\n" ));
++
++ if ( count <= 0 )
++ count = 1;
++
++ args -= count;
++ if ( args < stack )
++ goto Stack_Underflow;
++
++ if ( idx >= 0 )
++ {
++ while ( idx > 0 )
++ {
++ FT_Fixed tmp = args[count - 1];
++ FT_Int i;
++
++
++ for ( i = count - 2; i >= 0; i-- )
++ args[i + 1] = args[i];
++ args[0] = tmp;
++ idx--;
++ }
++ }
++ else
++ {
++ while ( idx < 0 )
++ {
++ FT_Fixed tmp = args[0];
++ FT_Int i;
++
++
++ for ( i = 0; i < count - 1; i++ )
++ args[i] = args[i + 1];
++ args[count - 1] = tmp;
++ idx++;
++ }
++ }
++ args += count;
++ }
++ break;
++
++ case cff_op_dup:
++ FT_TRACE4(( " dup\n" ));
++
++ args[1] = args[0];
++ args += 2;
++ break;
++
++ case cff_op_put:
++ {
++ FT_Fixed val = args[0];
++ FT_Int idx = (FT_Int)( args[1] >> 16 );
++
++
++ FT_TRACE4(( " put\n" ));
++
++ /* the Type2 specification before version 16-March-2000 */
++ /* didn't give a hard-coded size limit of the temporary */
++ /* storage array; instead, an argument of the */
++ /* `MultipleMaster' operator set the size */
++ if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
++ decoder->buildchar[idx] = val;
++ }
++ break;
++
++ case cff_op_get:
++ {
++ FT_Int idx = (FT_Int)( args[0] >> 16 );
++ FT_Fixed val = 0;
++
++
++ FT_TRACE4(( " get\n" ));
++
++ if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
++ val = decoder->buildchar[idx];
++
++ args[0] = val;
++ args++;
++ }
++ break;
++
++ case cff_op_store:
++ /* this operator was removed from the Type2 specification */
++ /* in version 16-March-2000 */
++
++ /* since we currently don't handle interpolation of multiple */
++ /* master fonts, this is a no-op */
++ FT_TRACE4(( " store\n" ));
++ break;
++
++ case cff_op_load:
++ /* this operator was removed from the Type2 specification */
++ /* in version 16-March-2000 */
++ {
++ FT_Int reg_idx = (FT_Int)args[0];
++ FT_Int idx = (FT_Int)args[1];
++ FT_Int count = (FT_Int)args[2];
++
++
++ FT_TRACE4(( " load\n" ));
++
++ /* since we currently don't handle interpolation of multiple */
++ /* master fonts, we store a vector [1 0 0 ...] in the */
++ /* temporary storage array regardless of the Registry index */
++ if ( reg_idx >= 0 && reg_idx <= 2 &&
++ idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
++ count >= 0 && count <= num_axes )
++ {
++ FT_Int end, i;
++
++
++ end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
++
++ if ( idx < end )
++ decoder->buildchar[idx] = 1 << 16;
++
++ for ( i = idx + 1; i < end; i++ )
++ decoder->buildchar[i] = 0;
++ }
++ }
++ break;
++
++ case cff_op_blend:
++ /* this operator was removed from the Type2 specification */
++ /* in version 16-March-2000 */
++ {
++ FT_Int num_results = (FT_Int)( args[0] >> 16 );
++
++
++ FT_TRACE4(( " blend\n" ));
++
++ if ( num_results < 0 )
++ goto Syntax_Error;
++
++ if ( num_results * (FT_Int)num_designs > num_args )
++ goto Stack_Underflow;
++
++ /* since we currently don't handle interpolation of multiple */
++ /* master fonts, return the `num_results' values of the */
++ /* first master */
++ args -= num_results * ( num_designs - 1 );
++ num_args -= num_results * ( num_designs - 1 );
++ }
++ break;
++
++ case cff_op_dotsection:
++ /* this operator is deprecated and ignored by the parser */
++ FT_TRACE4(( " dotsection\n" ));
++ break;
++
++ case cff_op_closepath:
++ /* this is an invalid Type 2 operator; however, there */
++ /* exist fonts which are incorrectly converted from probably */
++ /* Type 1 to CFF, and some parsers seem to accept it */
++
++ FT_TRACE4(( " closepath (invalid op)\n" ));
++
++ args = stack;
++ break;
++
++ case cff_op_hsbw:
++ /* this is an invalid Type 2 operator; however, there */
++ /* exist fonts which are incorrectly converted from probably */
++ /* Type 1 to CFF, and some parsers seem to accept it */
++
++ FT_TRACE4(( " hsbw (invalid op)\n" ));
++
++ decoder->glyph_width =
++ ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
++
++ decoder->builder.left_bearing.x = args[0];
++ decoder->builder.left_bearing.y = 0;
++
++ x = ADD_LONG( decoder->builder.pos_x, args[0] );
++ y = decoder->builder.pos_y;
++ args = stack;
++ break;
++
++ case cff_op_sbw:
++ /* this is an invalid Type 2 operator; however, there */
++ /* exist fonts which are incorrectly converted from probably */
++ /* Type 1 to CFF, and some parsers seem to accept it */
++
++ FT_TRACE4(( " sbw (invalid op)\n" ));
++
++ decoder->glyph_width =
++ ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
++
++ decoder->builder.left_bearing.x = args[0];
++ decoder->builder.left_bearing.y = args[1];
++
++ x = ADD_LONG( decoder->builder.pos_x, args[0] );
++ y = ADD_LONG( decoder->builder.pos_y, args[1] );
++ args = stack;
++ break;
++
++ case cff_op_setcurrentpoint:
++ /* this is an invalid Type 2 operator; however, there */
++ /* exist fonts which are incorrectly converted from probably */
++ /* Type 1 to CFF, and some parsers seem to accept it */
++
++ FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
++
++ x = ADD_LONG( decoder->builder.pos_x, args[0] );
++ y = ADD_LONG( decoder->builder.pos_y, args[1] );
++ args = stack;
++ break;
++
++ case cff_op_callothersubr:
++ /* this is an invalid Type 2 operator; however, there */
++ /* exist fonts which are incorrectly converted from probably */
++ /* Type 1 to CFF, and some parsers seem to accept it */
++
++ FT_TRACE4(( " callothersubr (invalid op)\n" ));
++
++ /* subsequent `pop' operands should add the arguments, */
++ /* this is the implementation described for `unknown' other */
++ /* subroutines in the Type1 spec. */
++ /* */
++ /* XXX Fix return arguments (see discussion below). */
++ args -= 2 + ( args[-2] >> 16 );
++ if ( args < stack )
++ goto Stack_Underflow;
++ break;
++
++ case cff_op_pop:
++ /* this is an invalid Type 2 operator; however, there */
++ /* exist fonts which are incorrectly converted from probably */
++ /* Type 1 to CFF, and some parsers seem to accept it */
++
++ FT_TRACE4(( " pop (invalid op)\n" ));
++
++ /* XXX Increasing `args' is wrong: After a certain number of */
++ /* `pop's we get a stack overflow. Reason for doing it is */
++ /* code like this (actually found in a CFF font): */
++ /* */
++ /* 17 1 3 callothersubr */
++ /* pop */
++ /* callsubr */
++ /* */
++ /* Since we handle `callothersubr' as a no-op, and */
++ /* `callsubr' needs at least one argument, `pop' can't be a */
++ /* no-op too as it basically should be. */
++ /* */
++ /* The right solution would be to provide real support for */
++ /* `callothersubr' as done in `t1decode.c', however, given */
++ /* the fact that CFF fonts with `pop' are invalid, it is */
++ /* questionable whether it is worth the time. */
++ args++;
++ break;
++
++ case cff_op_and:
++ {
++ FT_Fixed cond = ( args[0] && args[1] );
++
++
++ FT_TRACE4(( " and\n" ));
++
++ args[0] = cond ? 0x10000L : 0;
++ args++;
++ }
++ break;
++
++ case cff_op_or:
++ {
++ FT_Fixed cond = ( args[0] || args[1] );
++
++
++ FT_TRACE4(( " or\n" ));
++
++ args[0] = cond ? 0x10000L : 0;
++ args++;
++ }
++ break;
++
++ case cff_op_not:
++ {
++ FT_Fixed cond = !args[0];
++
++
++ FT_TRACE4(( " not\n" ));
++
++ args[0] = cond ? 0x10000L : 0;
++ args++;
++ }
++ break;
++
++ case cff_op_eq:
++ {
++ FT_Fixed cond = ( args[0] == args[1] );
++
++
++ FT_TRACE4(( " eq\n" ));
++
++ args[0] = cond ? 0x10000L : 0;
++ args++;
++ }
++ break;
++
++ case cff_op_ifelse:
++ {
++ FT_Fixed cond = ( args[2] <= args[3] );
++
++
++ FT_TRACE4(( " ifelse\n" ));
++
++ if ( !cond )
++ args[0] = args[1];
++ args++;
++ }
++ break;
++
++ case cff_op_callsubr:
++ {
++ FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
++ decoder->locals_bias );
++
++
++ FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
++ idx,
++ zone - decoder->zones + 1 ));
++
++ if ( idx >= decoder->num_locals )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " invalid local subr index\n" ));
++ goto Syntax_Error;
++ }
++
++ if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " too many nested subrs\n" ));
++ goto Syntax_Error;
++ }
++
++ zone->cursor = ip; /* save current instruction pointer */
++
++ zone++;
++ zone->base = decoder->locals[idx];
++ zone->limit = decoder->locals[idx + 1];
++ zone->cursor = zone->base;
++
++ if ( !zone->base || zone->limit == zone->base )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " invoking empty subrs\n" ));
++ goto Syntax_Error;
++ }
++
++ decoder->zone = zone;
++ ip = zone->base;
++ limit = zone->limit;
++ }
++ break;
++
++ case cff_op_callgsubr:
++ {
++ FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
++ decoder->globals_bias );
++
++
++ FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
++ idx,
++ zone - decoder->zones + 1 ));
++
++ if ( idx >= decoder->num_globals )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " invalid global subr index\n" ));
++ goto Syntax_Error;
++ }
++
++ if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " too many nested subrs\n" ));
++ goto Syntax_Error;
++ }
++
++ zone->cursor = ip; /* save current instruction pointer */
++
++ zone++;
++ zone->base = decoder->globals[idx];
++ zone->limit = decoder->globals[idx + 1];
++ zone->cursor = zone->base;
++
++ if ( !zone->base || zone->limit == zone->base )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " invoking empty subrs\n" ));
++ goto Syntax_Error;
++ }
++
++ decoder->zone = zone;
++ ip = zone->base;
++ limit = zone->limit;
++ }
++ break;
++
++ case cff_op_return:
++ FT_TRACE4(( " return (leaving level %d)\n",
++ decoder->zone - decoder->zones ));
++
++ if ( decoder->zone <= decoder->zones )
++ {
++ FT_ERROR(( "cff_decoder_parse_charstrings:"
++ " unexpected return\n" ));
++ goto Syntax_Error;
++ }
++
++ decoder->zone--;
++ zone = decoder->zone;
++ ip = zone->cursor;
++ limit = zone->limit;
++ break;
++
++ default:
++ FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
++
++ if ( ip[-1] == 12 )
++ FT_ERROR(( " %d", ip[0] ));
++ FT_ERROR(( "\n" ));
++
++ return FT_THROW( Unimplemented_Feature );
++ }
++
++ decoder->top = args;
++
++ if ( decoder->top - stack >= CFF_MAX_OPERANDS )
++ goto Stack_Overflow;
++
++ } /* general operator processing */
++
++ } /* while ip < limit */
++
++ FT_TRACE4(( "..end..\n\n" ));
++
++ Fail:
++ return error;
++
++ MM_Error:
++ FT_TRACE4(( "cff_decoder_parse_charstrings:"
++ " invalid opcode found in top DICT charstring\n"));
++ return FT_THROW( Invalid_File_Format );
++
++ Syntax_Error:
++ FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
++ return FT_THROW( Invalid_File_Format );
++
++ Stack_Underflow:
++ FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
++ return FT_THROW( Too_Few_Arguments );
++
++ Stack_Overflow:
++ FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
++ return FT_THROW( Stack_Overflow );
++ }
++
++#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
++
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* cff_decoder_init */
++ /* */
++ /* <Description> */
++ /* Initializes a given glyph decoder. */
++ /* */
++ /* <InOut> */
++ /* decoder :: A pointer to the glyph builder to initialize. */
++ /* */
++ /* <Input> */
++ /* face :: The current face object. */
++ /* */
++ /* size :: The current size object. */
++ /* */
++ /* slot :: The current glyph object. */
++ /* */
++ /* hinting :: Whether hinting is active. */
++ /* */
++ /* hint_mode :: The hinting mode. */
++ /* */
++ FT_LOCAL_DEF( void )
++ cff_decoder_init( CFF_Decoder* decoder,
++ TT_Face face,
++ CFF_Size size,
++ CFF_GlyphSlot slot,
++ FT_Bool hinting,
++ FT_Render_Mode hint_mode,
++ CFF_Decoder_Get_Glyph_Callback get_callback,
++ CFF_Decoder_Free_Glyph_Callback free_callback )
++ {
++ CFF_Font cff = (CFF_Font)face->extra.data;
++
++
++ /* clear everything */
++ FT_ZERO( decoder );
++
++ /* initialize builder */
++ cff_builder_init( &decoder->builder, face, size, slot, hinting );
++
++ /* initialize Type2 decoder */
++ decoder->cff = cff;
++ decoder->num_globals = cff->global_subrs_index.count;
++ decoder->globals = cff->global_subrs;
++ decoder->globals_bias = cff_compute_bias(
++ cff->top_font.font_dict.charstring_type,
++ decoder->num_globals );
++
++ decoder->hint_mode = hint_mode;
++
++ decoder->get_glyph_callback = get_callback;
++ decoder->free_glyph_callback = free_callback;
++ }
++
++
++ /* this function is used to select the subfont */
++ /* and the locals subrs array */
++ FT_LOCAL_DEF( FT_Error )
++ cff_decoder_prepare( CFF_Decoder* decoder,
++ CFF_Size size,
++ FT_UInt glyph_index )
++ {
++ CFF_Builder *builder = &decoder->builder;
++ CFF_Font cff = (CFF_Font)builder->face->extra.data;
++ CFF_SubFont sub = &cff->top_font;
++ FT_Error error = FT_Err_Ok;
++
++ FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload;
++
++
++ /* manage CID fonts */
++ if ( cff->num_subfonts )
++ {
++ FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select,
++ glyph_index );
++
++
++ if ( fd_index >= cff->num_subfonts )
++ {
++ FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
++ error = FT_THROW( Invalid_File_Format );
++ goto Exit;
++ }
++
++ FT_TRACE3(( " in subfont %d:\n", fd_index ));
++
++ sub = cff->subfonts[fd_index];
++
++ if ( builder->hints_funcs && size )
++ {
++ FT_Size ftsize = FT_SIZE( size );
++ CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data;
++
++
++ /* for CFFs without subfonts, this value has already been set */
++ builder->hints_globals = (void *)internal->subfonts[fd_index];
++ }
++ }
++
++ decoder->num_locals = sub->local_subrs_index.count;
++ decoder->locals = sub->local_subrs;
++ decoder->locals_bias = cff_compute_bias(
++ decoder->cff->top_font.font_dict.charstring_type,
++ decoder->num_locals );
++
++ decoder->glyph_width = sub->private_dict.default_width;
++ decoder->nominal_width = sub->private_dict.nominal_width;
++
++ decoder->current_subfont = sub;
++
++ Exit:
++ return error;
++ }
++
++
++/* END */
+diff --git a/src/psaux/cffdecode.h b/src/psaux/cffdecode.h
+new file mode 100644
+index 0000000000..15dfa8d622
+--- /dev/null
++++ b/src/psaux/cffdecode.h
+@@ -0,0 +1,63 @@
++/***************************************************************************/
++/* */
++/* cffdecode.h */
++/* */
++/* PostScript CFF (Type 2) decoding routines (specification). */
++/* */
++/* Copyright 2017 by */
++/* David Turner, Robert Wilhelm, and Werner Lemberg. */
++/* */
++/* This file is part of the FreeType project, and may only be used, */
++/* modified, and distributed under the terms of the FreeType project */
++/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
++/* this file you indicate that you have read the license and */
++/* understand and accept it fully. */
++/* */
++/***************************************************************************/
++
++
++#ifndef CFFDECODE_H_
++#define CFFDECODE_H_
++
++
++#include <ft2build.h>
++
++
++FT_BEGIN_HEADER
++
++ FT_LOCAL( void )
++ cff_decoder_init( CFF_Decoder* decoder,
++ TT_Face face,
++ CFF_Size size,
++ CFF_GlyphSlot slot,
++ FT_Bool hinting,
++ FT_Render_Mode hint_mode,
++ CFF_Decoder_Get_Glyph_Callback get_callback,
++ CFF_Decoder_Free_Glyph_Callback free_callback );
++
++ FT_LOCAL( FT_Error )
++ cff_decoder_prepare( CFF_Decoder* decoder,
++ CFF_Size size,
++ FT_UInt glyph_index );
++
++
++ FT_LOCAL( FT_Int )
++ cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
++ FT_Int charcode );
++
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++ FT_LOCAL( FT_Error )
++ cff_decoder_parse_charstrings( CFF_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len,
++ FT_Bool in_dict );
++#endif
++
++
++FT_END_HEADER
++
++#endif
++
++
++/* END */
+diff --git a/src/cff/cf2arrst.c b/src/psaux/psarrst.c
+similarity index 98%
+rename from src/cff/cf2arrst.c
+rename to src/psaux/psarrst.c
+index 6796450fe1..a8780947f9 100644
+--- a/src/cff/cf2arrst.c
++++ b/src/psaux/psarrst.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2arrst.c */
++/* psarrst.c */
+ /* */
+ /* Adobe's code for Array Stacks (body). */
+ /* */
+@@ -36,13 +36,13 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
+
+-#include "cf2glue.h"
+-#include "cf2arrst.h"
++#include "psglue.h"
++#include "psarrst.h"
+
+-#include "cf2error.h"
++#include "pserror.h"
+
+
+ /*
+diff --git a/src/cff/cf2arrst.h b/src/psaux/psarrst.h
+similarity index 96%
+rename from src/cff/cf2arrst.h
+rename to src/psaux/psarrst.h
+index 3c21a3b672..b3568eb61f 100644
+--- a/src/cff/cf2arrst.h
++++ b/src/psaux/psarrst.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2arrst.h */
++/* psarrst.h */
+ /* */
+ /* Adobe's code for Array Stacks (specification). */
+ /* */
+@@ -36,11 +36,11 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2ARRST_H_
+-#define CF2ARRST_H_
++#ifndef PSARRST_H_
++#define PSARRST_H_
+
+
+-#include "cf2error.h"
++#include "pserror.h"
+
+
+ FT_BEGIN_HEADER
+@@ -94,7 +94,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2ARRST_H_ */
++#endif /* PSARRST_H_ */
+
+
+ /* END */
+diff --git a/src/psaux/psaux.c b/src/psaux/psaux.c
+index c373aa7d5b..e30c9b0841 100644
+--- a/src/psaux/psaux.c
++++ b/src/psaux/psaux.c
+@@ -25,6 +25,17 @@
+ #include "psobjs.c"
+ #include "t1cmap.c"
+ #include "t1decode.c"
++#include "cffdecode.c"
++
++#include "psarrst.c"
++#include "psblues.c"
++#include "pserror.c"
++#include "psfont.c"
++#include "psft.c"
++#include "pshints.c"
++#include "psintrp.c"
++#include "psread.c"
++#include "psstack.c"
+
+
+ /* END */
+diff --git a/src/psaux/psauxmod.c b/src/psaux/psauxmod.c
+index 1f589cefc2..52f9e99999 100644
+--- a/src/psaux/psauxmod.c
++++ b/src/psaux/psauxmod.c
+@@ -21,6 +21,8 @@
+ #include "psobjs.h"
+ #include "t1decode.h"
+ #include "t1cmap.h"
++#include "psft.h"
++#include "cffdecode.h"
+
+ #ifndef T1_CONFIG_OPTION_NO_AFM
+ #include "afmparse.h"
+@@ -59,6 +61,14 @@
+ };
+
+
++ FT_CALLBACK_TABLE_DEF
++ const PS_Builder_FuncsRec ps_builder_funcs =
++ {
++ ps_builder_init, /* init */
++ ps_builder_done /* done */
++ };
++
++
+ FT_CALLBACK_TABLE_DEF
+ const T1_Builder_FuncsRec t1_builder_funcs =
+ {
+@@ -77,9 +87,14 @@
+ FT_CALLBACK_TABLE_DEF
+ const T1_Decoder_FuncsRec t1_decoder_funcs =
+ {
+- t1_decoder_init, /* init */
+- t1_decoder_done, /* done */
+- t1_decoder_parse_charstrings /* parse_charstrings */
++ t1_decoder_init, /* init */
++ t1_decoder_done, /* done */
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ t1_decoder_parse_charstrings, /* parse_charstrings_old */
++#else
++ t1_decoder_parse_metrics, /* parse_metrics */
++#endif
++ cf2_decoder_parse_charstrings /* parse_charstrings */
+ };
+
+
+@@ -104,6 +119,34 @@
+ };
+
+
++ FT_CALLBACK_TABLE_DEF
++ const CFF_Builder_FuncsRec cff_builder_funcs =
++ {
++ cff_builder_init, /* init */
++ cff_builder_done, /* done */
++
++ cff_check_points, /* check_points */
++ cff_builder_add_point, /* add_point */
++ cff_builder_add_point1, /* add_point1 */
++ cff_builder_add_contour, /* add_contour */
++ cff_builder_start_point, /* start_point */
++ cff_builder_close_contour /* close_contour */
++ };
++
++
++ FT_CALLBACK_TABLE_DEF
++ const CFF_Decoder_FuncsRec cff_decoder_funcs =
++ {
++ cff_decoder_init, /* init */
++ cff_decoder_prepare, /* prepare */
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++ cff_decoder_parse_charstrings, /* parse_charstrings_old */
++#endif
++ cf2_decoder_parse_charstrings /* parse_charstrings */
++ };
++
++
+ static
+ const PSAux_Interface psaux_interface =
+ {
+@@ -112,6 +155,9 @@
+ &t1_builder_funcs,
+ &t1_decoder_funcs,
+ t1_decrypt,
++ cff_random,
++ ps_decoder_init,
++ t1_make_subfont,
+
+ (const T1_CMap_ClassesRec*) &t1_cmap_classes,
+
+@@ -120,6 +166,8 @@
+ #else
+ 0,
+ #endif
++
++ &cff_decoder_funcs,
+ };
+
+
+diff --git a/src/cff/cf2blues.c b/src/psaux/psblues.c
+similarity index 99%
+rename from src/cff/cf2blues.c
+rename to src/psaux/psblues.c
+index c491f2f9e5..ae39d03c77 100644
+--- a/src/cff/cf2blues.c
++++ b/src/psaux/psblues.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2blues.c */
++/* psblues.c */
+ /* */
+ /* Adobe's code for handling Blue Zones (body). */
+ /* */
+@@ -36,12 +36,12 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
+
+-#include "cf2blues.h"
+-#include "cf2hints.h"
+-#include "cf2font.h"
++#include "psblues.h"
++#include "pshints.h"
++#include "psfont.h"
+
+
+ /*************************************************************************/
+@@ -67,7 +67,7 @@
+ CF2_Font font )
+ {
+ /* pointer to parsed font object */
+- CFF_Decoder* decoder = font->decoder;
++ PS_Decoder* decoder = font->decoder;
+
+ CF2_Fixed zoneHeight;
+ CF2_Fixed maxZoneHeight = 0;
+diff --git a/src/cff/cf2blues.h b/src/psaux/psblues.h
+similarity index 97%
+rename from src/cff/cf2blues.h
+rename to src/psaux/psblues.h
+index a6bcd9de57..25ef6849c7 100644
+--- a/src/cff/cf2blues.h
++++ b/src/psaux/psblues.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2blues.h */
++/* psblues.h */
+ /* */
+ /* Adobe's code for handling Blue Zones (specification). */
+ /* */
+@@ -65,11 +65,11 @@
+ */
+
+
+-#ifndef CF2BLUES_H_
+-#define CF2BLUES_H_
++#ifndef PSBLUES_H_
++#define PSBLUES_H_
+
+
+-#include "cf2glue.h"
++#include "psglue.h"
+
+
+ FT_BEGIN_HEADER
+@@ -179,7 +179,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2BLUES_H_ */
++#endif /* PSBLUES_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2error.c b/src/psaux/pserror.c
+similarity index 96%
+rename from src/cff/cf2error.c
+rename to src/psaux/pserror.c
+index e3dd69f50d..9169e5222d 100644
+--- a/src/cff/cf2error.c
++++ b/src/psaux/pserror.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2error.c */
++/* pserror.c */
+ /* */
+ /* Adobe's code for error handling (body). */
+ /* */
+@@ -36,8 +36,8 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
+-#include "cf2error.h"
++#include "psft.h"
++#include "pserror.h"
+
+
+ FT_LOCAL_DEF( void )
+diff --git a/src/cff/cf2error.h b/src/psaux/pserror.h
+similarity index 96%
+rename from src/cff/cf2error.h
+rename to src/psaux/pserror.h
+index d2c770d297..13d52062bf 100644
+--- a/src/cff/cf2error.h
++++ b/src/psaux/pserror.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2error.h */
++/* pserror.h */
+ /* */
+ /* Adobe's code for error handling (specification). */
+ /* */
+@@ -36,8 +36,8 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2ERROR_H_
+-#define CF2ERROR_H_
++#ifndef PSERROR_H_
++#define PSERROR_H_
+
+
+ #include FT_MODULE_ERRORS_H
+@@ -50,7 +50,7 @@
+
+
+ #include FT_ERRORS_H
+-#include "cf2ft.h"
++#include "psft.h"
+
+
+ FT_BEGIN_HEADER
+@@ -113,7 +113,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2ERROR_H_ */
++#endif /* PSERROR_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2fixed.h b/src/psaux/psfixed.h
+similarity index 97%
+rename from src/cff/cf2fixed.h
+rename to src/psaux/psfixed.h
+index a041184bda..219589e7fc 100644
+--- a/src/cff/cf2fixed.h
++++ b/src/psaux/psfixed.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2fixed.h */
++/* psfixed.h */
+ /* */
+ /* Adobe's code for Fixed Point Mathematics (specification only). */
+ /* */
+@@ -36,8 +36,8 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2FIXED_H_
+-#define CF2FIXED_H_
++#ifndef PSFIXED_H_
++#define PSFIXED_H_
+
+
+ FT_BEGIN_HEADER
+@@ -89,7 +89,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2FIXED_H_ */
++#endif /* PSFIXED_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2font.c b/src/psaux/psfont.c
+similarity index 91%
+rename from src/cff/cf2font.c
+rename to src/psaux/psfont.c
+index 4ac71a8d71..dde67a739d 100644
+--- a/src/cff/cf2font.c
++++ b/src/psaux/psfont.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2font.c */
++/* psfont.c */
+ /* */
+ /* Adobe's code for font instances (body). */
+ /* */
+@@ -39,12 +39,12 @@
+ #include <ft2build.h>
+ #include FT_INTERNAL_CALC_H
+
+-#include "cf2ft.h"
++#include "psft.h"
+
+-#include "cf2glue.h"
+-#include "cf2font.h"
+-#include "cf2error.h"
+-#include "cf2intrp.h"
++#include "psglue.h"
++#include "psfont.h"
++#include "pserror.h"
++#include "psintrp.h"
+
+
+ /* Compute a stem darkening amount in character space. */
+@@ -243,7 +243,7 @@
+ const CF2_Matrix* transform )
+ {
+ /* pointer to parsed font object */
+- CFF_Decoder* decoder = font->decoder;
++ PS_Decoder* decoder = font->decoder;
+
+ FT_Bool needExtraSetup = FALSE;
+
+@@ -260,7 +260,6 @@
+ CF2_UInt lenNormalizedV = 0;
+ FT_Fixed* normalizedV = NULL;
+
+-
+ /* clear previous error */
+ font->error = FT_Err_Ok;
+
+@@ -273,46 +272,52 @@
+ needExtraSetup = TRUE;
+ }
+
+- /* check for variation vectors */
+- vstore = cf2_getVStore( decoder );
+- hasVariations = ( vstore->dataCount != 0 );
+-
+- if ( hasVariations )
++ if ( !font->isT1 )
+ {
+-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+- /* check whether Private DICT in this subfont needs to be reparsed */
+- font->error = cf2_getNormalizedVector( decoder,
+- &lenNormalizedV,
+- &normalizedV );
+- if ( font->error )
+- return;
++ FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload;
++
++
++ /* check for variation vectors */
++ vstore = cf2_getVStore( decoder );
++ hasVariations = ( vstore->dataCount != 0 );
+
+- if ( cff_blend_check_vector( &subFont->blend,
+- subFont->private_dict.vsindex,
+- lenNormalizedV,
+- normalizedV ) )
++ if ( hasVariations )
+ {
+- /* blend has changed, reparse */
+- cff_load_private_dict( decoder->cff,
+- subFont,
+- lenNormalizedV,
+- normalizedV );
+- needExtraSetup = TRUE;
+- }
++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
++ /* check whether Private DICT in this subfont needs to be reparsed */
++ font->error = cf2_getNormalizedVector( decoder,
++ &lenNormalizedV,
++ &normalizedV );
++ if ( font->error )
++ return;
++
++ if ( cffload->blend_check_vector( &subFont->blend,
++ subFont->private_dict.vsindex,
++ lenNormalizedV,
++ normalizedV ) )
++ {
++ /* blend has changed, reparse */
++ cffload->load_private_dict( decoder->cff,
++ subFont,
++ lenNormalizedV,
++ normalizedV );
++ needExtraSetup = TRUE;
++ }
+ #endif
+
+- /* copy from subfont */
+- font->blend.font = subFont->blend.font;
++ /* copy from subfont */
++ font->blend.font = subFont->blend.font;
+
+- /* clear state of charstring blend */
+- font->blend.usedBV = FALSE;
++ /* clear state of charstring blend */
++ font->blend.usedBV = FALSE;
+
+- /* initialize value for charstring */
+- font->vsindex = subFont->private_dict.vsindex;
++ /* initialize value for charstring */
++ font->vsindex = subFont->private_dict.vsindex;
+
+- /* store vector inputs for blends in charstring */
+- font->lenNDV = lenNormalizedV;
+- font->NDV = normalizedV;
++ /* store vector inputs for blends in charstring */
++ font->lenNDV = lenNormalizedV;
++ font->NDV = normalizedV;
++ }
+ }
+
+ /* if ppem has changed, we need to recompute some cached data */
+diff --git a/src/cff/cf2font.h b/src/psaux/psfont.h
+similarity index 94%
+rename from src/cff/cf2font.h
+rename to src/psaux/psfont.h
+index 17ecd17bbb..e611ac4bdc 100644
+--- a/src/cff/cf2font.h
++++ b/src/psaux/psfont.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2font.h */
++/* psfont.h */
+ /* */
+ /* Adobe's code for font instances (specification). */
+ /* */
+@@ -36,13 +36,14 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2FONT_H_
+-#define CF2FONT_H_
++#ifndef PSFONT_H_
++#define PSFONT_H_
+
+
+-#include "cf2ft.h"
+-#include "cf2blues.h"
+-#include "cffload.h"
++#include FT_SERVICE_CFF_TABLE_LOAD_H
++
++#include "psft.h"
++#include "psblues.h"
+
+
+ FT_BEGIN_HEADER
+@@ -64,6 +65,7 @@ FT_BEGIN_HEADER
+ FT_Memory memory;
+ FT_Error error; /* shared error for this instance */
+
++ FT_Bool isT1;
+ FT_Bool isCFF2;
+ CF2_RenderingFlags renderingFlags;
+
+@@ -89,7 +91,7 @@ FT_BEGIN_HEADER
+
+ /* FreeType related members */
+ CF2_OutlineRec outline; /* freetype glyph outline functions */
+- CFF_Decoder* decoder;
++ PS_Decoder* decoder;
+ CFF_SubFont lastSubfont; /* FreeType parsed data; */
+ /* top font or subfont */
+
+@@ -111,6 +113,8 @@ FT_BEGIN_HEADER
+ /* counterclockwise winding */
+
+ CF2_BluesRec blues; /* computed zone data */
++
++ FT_Service_CFFLoad cffload; /* pointer to cff functions */
+ };
+
+
+@@ -124,7 +128,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2FONT_H_ */
++#endif /* PSFONT_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2ft.c b/src/psaux/psft.c
+similarity index 66%
+rename from src/cff/cf2ft.c
+rename to src/psaux/psft.c
+index c6c00d1623..6c67276d95 100644
+--- a/src/cff/cf2ft.c
++++ b/src/psaux/psft.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2ft.c */
++/* psft.c */
+ /* */
+ /* FreeType Glue Component to Adobe's Interpreter (body). */
+ /* */
+@@ -36,11 +36,18 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
+
+-#include "cf2font.h"
+-#include "cf2error.h"
++#include "psfont.h"
++#include "pserror.h"
++
++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
++#include FT_MULTIPLE_MASTERS_H
++#include FT_SERVICE_MULTIPLE_MASTERS_H
++#endif
++
++#include FT_SERVICE_CFF_TABLE_LOAD_H
+
+
+ #define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
+@@ -83,7 +90,7 @@
+ cf2_setGlyphWidth( CF2_Outline outline,
+ CF2_Fixed width )
+ {
+- CFF_Decoder* decoder = outline->decoder;
++ PS_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+@@ -122,8 +129,8 @@
+ const CF2_CallbackParams params )
+ {
+ /* downcast the object pointer */
+- CF2_Outline outline = (CF2_Outline)callbacks;
+- CFF_Builder* builder;
++ CF2_Outline outline = (CF2_Outline)callbacks;
++ PS_Builder* builder;
+
+ (void)params; /* only used in debug mode */
+
+@@ -134,7 +141,7 @@
+ builder = &outline->decoder->builder;
+
+ /* note: two successive moves simply close the contour twice */
+- cff_builder_close_contour( builder );
++ ps_builder_close_contour( builder );
+ builder->path_begun = 0;
+ }
+
+@@ -146,8 +153,8 @@
+ FT_Error error;
+
+ /* downcast the object pointer */
+- CF2_Outline outline = (CF2_Outline)callbacks;
+- CFF_Builder* builder;
++ CF2_Outline outline = (CF2_Outline)callbacks;
++ PS_Builder* builder;
+
+
+ FT_ASSERT( outline && outline->decoder );
+@@ -159,9 +166,9 @@
+ {
+ /* record the move before the line; also check points and set */
+ /* `path_begun' */
+- error = cff_builder_start_point( builder,
+- params->pt0.x,
+- params->pt0.y );
++ error = ps_builder_start_point( builder,
++ params->pt0.x,
++ params->pt0.y );
+ if ( error )
+ {
+ if ( !*callbacks->error )
+@@ -170,10 +177,10 @@
+ }
+ }
+
+- /* `cff_builder_add_point1' includes a check_points call for one point */
+- error = cff_builder_add_point1( builder,
+- params->pt1.x,
+- params->pt1.y );
++ /* `ps_builder_add_point1' includes a check_points call for one point */
++ error = ps_builder_add_point1( builder,
++ params->pt1.x,
++ params->pt1.y );
+ if ( error )
+ {
+ if ( !*callbacks->error )
+@@ -190,8 +197,8 @@
+ FT_Error error;
+
+ /* downcast the object pointer */
+- CF2_Outline outline = (CF2_Outline)callbacks;
+- CFF_Builder* builder;
++ CF2_Outline outline = (CF2_Outline)callbacks;
++ PS_Builder* builder;
+
+
+ FT_ASSERT( outline && outline->decoder );
+@@ -203,9 +210,9 @@
+ {
+ /* record the move before the line; also check points and set */
+ /* `path_begun' */
+- error = cff_builder_start_point( builder,
+- params->pt0.x,
+- params->pt0.y );
++ error = ps_builder_start_point( builder,
++ params->pt0.x,
++ params->pt0.y );
+ if ( error )
+ {
+ if ( !*callbacks->error )
+@@ -215,7 +222,7 @@
+ }
+
+ /* prepare room for 3 points: 2 off-curve, 1 on-curve */
+- error = cff_check_points( builder, 3 );
++ error = ps_builder_check_points( builder, 3 );
+ if ( error )
+ {
+ if ( !*callbacks->error )
+@@ -223,15 +230,15 @@
+ return;
+ }
+
+- cff_builder_add_point( builder,
+- params->pt1.x,
+- params->pt1.y, 0 );
+- cff_builder_add_point( builder,
+- params->pt2.x,
+- params->pt2.y, 0 );
+- cff_builder_add_point( builder,
+- params->pt3.x,
+- params->pt3.y, 1 );
++ ps_builder_add_point( builder,
++ params->pt1.x,
++ params->pt1.y, 0 );
++ ps_builder_add_point( builder,
++ params->pt2.x,
++ params->pt2.y, 0 );
++ ps_builder_add_point( builder,
++ params->pt3.x,
++ params->pt3.y, 1 );
+ }
+
+
+@@ -253,11 +260,11 @@
+
+ /* get scaling and hint flag from GlyphSlot */
+ static void
+- cf2_getScaleAndHintFlag( CFF_Decoder* decoder,
+- CF2_Fixed* x_scale,
+- CF2_Fixed* y_scale,
+- FT_Bool* hinted,
+- FT_Bool* scaled )
++ cf2_getScaleAndHintFlag( PS_Decoder* decoder,
++ CF2_Fixed* x_scale,
++ CF2_Fixed* y_scale,
++ FT_Bool* hinted,
++ FT_Bool* scaled )
+ {
+ FT_ASSERT( decoder && decoder->builder.glyph );
+
+@@ -284,47 +291,60 @@
+ /* get units per em from `FT_Face' */
+ /* TODO: should handle font matrix concatenation? */
+ static FT_UShort
+- cf2_getUnitsPerEm( CFF_Decoder* decoder )
++ cf2_getUnitsPerEm( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->builder.face );
+- FT_ASSERT( decoder->builder.face->root.units_per_EM );
++ FT_ASSERT( decoder->builder.face->units_per_EM );
+
+- return decoder->builder.face->root.units_per_EM;
++ return decoder->builder.face->units_per_EM;
+ }
+
+
+ /* Main entry point: Render one glyph. */
+ FT_LOCAL_DEF( FT_Error )
+- cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
+- FT_Byte* charstring_base,
+- FT_ULong charstring_len )
++ cf2_decoder_parse_charstrings( PS_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len )
+ {
+ FT_Memory memory;
+ FT_Error error = FT_Err_Ok;
+ CF2_Font font;
+
++ FT_Bool is_t1 = decoder->builder.is_t1;
+
+- FT_ASSERT( decoder && decoder->cff );
++
++ FT_ASSERT( decoder &&
++ ( is_t1 || decoder->cff ) );
++
++ if ( is_t1 && !decoder->current_subfont )
++ {
++ FT_ERROR(( "cf2_decoder_parse_charstrings (Type 1): "
++ "SubFont missing. Use `t1_make_subfont' first\n" ));
++ return FT_THROW( Invalid_Table );
++ }
+
+ memory = decoder->builder.memory;
+
+ /* CF2 data is saved here across glyphs */
+- font = (CF2_Font)decoder->cff->cf2_instance.data;
++ font = (CF2_Font)decoder->cf2_instance->data;
+
+ /* on first glyph, allocate instance structure */
+- if ( !decoder->cff->cf2_instance.data )
++ if ( !decoder->cf2_instance->data )
+ {
+- decoder->cff->cf2_instance.finalizer =
++ decoder->cf2_instance->finalizer =
+ (FT_Generic_Finalizer)cf2_free_instance;
+
+- if ( FT_ALLOC( decoder->cff->cf2_instance.data,
++ if ( FT_ALLOC( decoder->cf2_instance->data,
+ sizeof ( CF2_FontRec ) ) )
+ return FT_THROW( Out_Of_Memory );
+
+- font = (CF2_Font)decoder->cff->cf2_instance.data;
++ font = (CF2_Font)decoder->cf2_instance->data;
+
+ font->memory = memory;
+
++ if ( !is_t1 )
++ font->cffload = (FT_Service_CFFLoad)decoder->cff->cffload;
++
+ /* initialize a client outline, to be shared by each glyph rendered */
+ cf2_outline_init( &font->outline, font->memory, &font->error );
+ }
+@@ -337,13 +357,13 @@
+ {
+ /* build parameters for Adobe engine */
+
+- CFF_Builder* builder = &decoder->builder;
+- CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
++ PS_Builder* builder = &decoder->builder;
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face );
+
+ FT_Bool no_stem_darkening_driver =
+ driver->no_stem_darkening;
+ FT_Char no_stem_darkening_font =
+- builder->face->root.internal->no_stem_darkening;
++ builder->face->internal->no_stem_darkening;
+
+ /* local error */
+ FT_Error error2 = FT_Err_Ok;
+@@ -372,8 +392,14 @@
+ &hinted,
+ &scaled );
+
+- /* copy isCFF2 boolean from TT_Face to CF2_Font */
+- font->isCFF2 = builder->face->is_cff2;
++ if ( is_t1 )
++ font->isCFF2 = FALSE;
++ else
++ {
++ /* copy isCFF2 boolean from TT_Face to CF2_Font */
++ font->isCFF2 = ((TT_Face)builder->face)->is_cff2;
++ }
++ font->isT1 = is_t1;
+
+ font->renderingFlags = 0;
+ if ( hinted )
+@@ -416,7 +442,7 @@
+
+ /* get pointer to current FreeType subfont (based on current glyphID) */
+ FT_LOCAL_DEF( CFF_SubFont )
+- cf2_getSubfont( CFF_Decoder* decoder )
++ cf2_getSubfont( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -426,7 +452,7 @@
+
+ /* get pointer to VStore structure */
+ FT_LOCAL_DEF( CFF_VStore )
+- cf2_getVStore( CFF_Decoder* decoder )
++ cf2_getVStore( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->cff );
+
+@@ -436,7 +462,7 @@
+
+ /* get maxstack value from CFF2 Top DICT */
+ FT_LOCAL_DEF( FT_UInt )
+- cf2_getMaxstack( CFF_Decoder* decoder )
++ cf2_getMaxstack( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->cff );
+
+@@ -450,25 +476,33 @@
+ /* */
+ /* Note: Uses FT_Fixed not CF2_Fixed for the vector. */
+ FT_LOCAL_DEF( FT_Error )
+- cf2_getNormalizedVector( CFF_Decoder* decoder,
++ cf2_getNormalizedVector( PS_Decoder* decoder,
+ CF2_UInt *len,
+ FT_Fixed* *vec )
+ {
++ TT_Face face;
++ FT_Service_MultiMasters mm;
++
++
+ FT_ASSERT( decoder && decoder->builder.face );
+ FT_ASSERT( vec && len );
++ FT_ASSERT( !decoder->builder.is_t1 );
+
+- return cff_get_var_blend( decoder->builder.face, len, NULL, vec, NULL );
++ face = (TT_Face)decoder->builder.face;
++ mm = (FT_Service_MultiMasters)face->mm;
++
++ return mm->get_var_blend( FT_FACE( face ), len, NULL, vec, NULL );
+ }
+ #endif
+
+
+ /* get `y_ppem' from `CFF_Size' */
+ FT_LOCAL_DEF( CF2_Fixed )
+- cf2_getPpemY( CFF_Decoder* decoder )
++ cf2_getPpemY( PS_Decoder* decoder )
+ {
+- FT_ASSERT( decoder &&
+- decoder->builder.face &&
+- decoder->builder.face->root.size );
++ FT_ASSERT( decoder &&
++ decoder->builder.face &&
++ decoder->builder.face->size );
+
+ /*
+ * Note that `y_ppem' can be zero if there wasn't a call to
+@@ -480,7 +514,7 @@
+ *
+ */
+ return cf2_intToFixed(
+- decoder->builder.face->root.size->metrics.y_ppem );
++ decoder->builder.face->size->metrics.y_ppem );
+ }
+
+
+@@ -488,7 +522,7 @@
+ /* FreeType stores these as integer font units */
+ /* (note: variable names seem swapped) */
+ FT_LOCAL_DEF( CF2_Fixed )
+- cf2_getStdVW( CFF_Decoder* decoder )
++ cf2_getStdVW( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -498,7 +532,7 @@
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+- cf2_getStdHW( CFF_Decoder* decoder )
++ cf2_getStdHW( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -509,10 +543,10 @@
+
+ /* note: FreeType stores 1000 times the actual value for `BlueScale' */
+ FT_LOCAL_DEF( void )
+- cf2_getBlueMetrics( CFF_Decoder* decoder,
+- CF2_Fixed* blueScale,
+- CF2_Fixed* blueShift,
+- CF2_Fixed* blueFuzz )
++ cf2_getBlueMetrics( PS_Decoder* decoder,
++ CF2_Fixed* blueScale,
++ CF2_Fixed* blueShift,
++ CF2_Fixed* blueFuzz )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -529,9 +563,9 @@
+ /* get blue values counts and arrays; the FreeType parser has validated */
+ /* the counts and verified that each is an even number */
+ FT_LOCAL_DEF( void )
+- cf2_getBlueValues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data )
++ cf2_getBlueValues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -542,9 +576,9 @@
+
+
+ FT_LOCAL_DEF( void )
+- cf2_getOtherBlues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data )
++ cf2_getOtherBlues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -555,9 +589,9 @@
+
+
+ FT_LOCAL_DEF( void )
+- cf2_getFamilyBlues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data )
++ cf2_getFamilyBlues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -568,9 +602,9 @@
+
+
+ FT_LOCAL_DEF( void )
+- cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data )
++ cf2_getFamilyOtherBlues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -581,7 +615,7 @@
+
+
+ FT_LOCAL_DEF( CF2_Int )
+- cf2_getLanguageGroup( CFF_Decoder* decoder )
++ cf2_getLanguageGroup( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -592,9 +626,9 @@
+ /* convert unbiased subroutine index to `CF2_Buffer' and */
+ /* return 0 on success */
+ FT_LOCAL_DEF( CF2_Int )
+- cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
+- CF2_Int subrNum,
+- CF2_Buffer buf )
++ cf2_initGlobalRegionBuffer( PS_Decoder* decoder,
++ CF2_Int subrNum,
++ CF2_Buffer buf )
+ {
+ CF2_UInt idx;
+
+@@ -620,9 +654,9 @@
+ /* convert AdobeStandardEncoding code to CF2_Buffer; */
+ /* used for seac component */
+ FT_LOCAL_DEF( FT_Error )
+- cf2_getSeacComponent( CFF_Decoder* decoder,
+- CF2_Int code,
+- CF2_Buffer buf )
++ cf2_getSeacComponent( PS_Decoder* decoder,
++ CF2_Int code,
++ CF2_Buffer buf )
+ {
+ CF2_Int gid;
+ FT_Byte* charstring;
+@@ -631,13 +665,14 @@
+
+
+ FT_ASSERT( decoder );
++ FT_ASSERT( !decoder->builder.is_t1 );
+
+ FT_ZERO( buf );
+
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+ /* Incremental fonts don't necessarily have valid charsets. */
+ /* They use the character code, not the glyph index, in this case. */
+- if ( decoder->builder.face->root.internal->incremental_interface )
++ if ( decoder->builder.face->internal->incremental_interface )
+ gid = code;
+ else
+ #endif /* FT_CONFIG_OPTION_INCREMENTAL */
+@@ -647,10 +682,10 @@
+ return FT_THROW( Invalid_Glyph_Format );
+ }
+
+- error = cff_get_glyph_data( decoder->builder.face,
+- (CF2_UInt)gid,
+- &charstring,
+- &len );
++ error = decoder->get_glyph_callback( (TT_Face)decoder->builder.face,
++ (CF2_UInt)gid,
++ &charstring,
++ &len );
+ /* TODO: for now, just pass the FreeType error through */
+ if ( error )
+ return error;
+@@ -667,21 +702,92 @@
+
+
+ FT_LOCAL_DEF( void )
+- cf2_freeSeacComponent( CFF_Decoder* decoder,
+- CF2_Buffer buf )
++ cf2_freeSeacComponent( PS_Decoder* decoder,
++ CF2_Buffer buf )
++ {
++ FT_ASSERT( decoder );
++ FT_ASSERT( !decoder->builder.is_t1 );
++
++ decoder->free_glyph_callback( (TT_Face)decoder->builder.face,
++ (FT_Byte**)&buf->start,
++ (FT_ULong)( buf->end - buf->start ) );
++ }
++
++
++ FT_LOCAL_DEF( FT_Error )
++ cf2_getT1SeacComponent( PS_Decoder* decoder,
++ FT_UInt glyph_index,
++ CF2_Buffer buf )
++ {
++ FT_Data glyph_data;
++ FT_Error error = FT_Err_Ok;
++ T1_Face face = (T1_Face)decoder->builder.face;
++ T1_Font type1 = &face->type1;
++
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ FT_Incremental_InterfaceRec *inc =
++ face->root.internal->incremental_interface;
++
++
++ /* For incremental fonts get the character data using the */
++ /* callback function. */
++ if ( inc )
++ error = inc->funcs->get_glyph_data( inc->object,
++ glyph_index, &glyph_data );
++ else
++#endif
++ /* For ordinary fonts get the character data stored in the face record. */
++ {
++ glyph_data.pointer = type1->charstrings[glyph_index];
++ glyph_data.length = (FT_Int)type1->charstrings_len[glyph_index];
++ }
++
++ if ( !error )
++ {
++ FT_Byte* charstring_base = (FT_Byte*)glyph_data.pointer;
++ FT_ULong charstring_len = (FT_ULong)glyph_data.length;
++
++
++ FT_ASSERT( charstring_base + charstring_len >= charstring_base );
++
++ FT_ZERO( buf );
++ buf->start =
++ buf->ptr = charstring_base;
++ buf->end = charstring_base + charstring_len;
++ }
++
++ return error;
++ }
++
++
++ FT_LOCAL_DEF( void )
++ cf2_freeT1SeacComponent( PS_Decoder* decoder,
++ CF2_Buffer buf )
+ {
++ T1_Face face;
++ FT_Data data;
++
++
+ FT_ASSERT( decoder );
+
+- cff_free_glyph_data( decoder->builder.face,
+- (FT_Byte**)&buf->start,
+- (FT_ULong)( buf->end - buf->start ) );
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ face = (T1_Face)decoder->builder.face;
++
++ data.pointer = buf->start;
++ data.length = (FT_Int)( buf->end - buf->start );
++
++ if ( face->root.internal->incremental_interface )
++ face->root.internal->incremental_interface->funcs->free_glyph_data(
++ face->root.internal->incremental_interface->object,
++ &data );
++#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+ }
+
+
+ FT_LOCAL_DEF( CF2_Int )
+- cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
+- CF2_Int subrNum,
+- CF2_Buffer buf )
++ cf2_initLocalRegionBuffer( PS_Decoder* decoder,
++ CF2_Int subrNum,
++ CF2_Buffer buf )
+ {
+ CF2_UInt idx;
+
+@@ -696,16 +802,42 @@
+
+ FT_ASSERT( decoder->locals );
+
+- buf->start =
+- buf->ptr = decoder->locals[idx];
+- buf->end = decoder->locals[idx + 1];
++ buf->start = decoder->locals[idx];
++
++ if ( decoder->builder.is_t1 )
++ {
++ /* The Type 1 driver stores subroutines without the seed bytes. */
++ /* The CID driver stores subroutines with seed bytes. This */
++ /* case is taken care of when decoder->subrs_len == 0. */
++ if ( decoder->locals_len )
++ buf->end = buf->start + decoder->locals_len[idx];
++ else
++ {
++ /* We are using subroutines from a CID font. We must adjust */
++ /* for the seed bytes. */
++ buf->start += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
++ buf->end = decoder->locals[idx + 1];
++ }
++
++ if ( !buf->start )
++ {
++ FT_ERROR(( "cf2_initLocalRegionBuffer (Type 1 mode):"
++ " invoking empty subrs\n" ));
++ }
++ }
++ else
++ {
++ buf->end = decoder->locals[idx + 1];
++ }
++
++ buf->ptr = buf->start;
+
+ return FALSE; /* success */
+ }
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+- cf2_getDefaultWidthX( CFF_Decoder* decoder )
++ cf2_getDefaultWidthX( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -715,7 +847,7 @@
+
+
+ FT_LOCAL_DEF( CF2_Fixed )
+- cf2_getNominalWidthX( CFF_Decoder* decoder )
++ cf2_getNominalWidthX( PS_Decoder* decoder )
+ {
+ FT_ASSERT( decoder && decoder->current_subfont );
+
+@@ -727,7 +859,7 @@
+ FT_LOCAL_DEF( void )
+ cf2_outline_reset( CF2_Outline outline )
+ {
+- CFF_Decoder* decoder = outline->decoder;
++ PS_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+@@ -741,12 +873,12 @@
+ FT_LOCAL_DEF( void )
+ cf2_outline_close( CF2_Outline outline )
+ {
+- CFF_Decoder* decoder = outline->decoder;
++ PS_Decoder* decoder = outline->decoder;
+
+
+ FT_ASSERT( decoder );
+
+- cff_builder_close_contour( &decoder->builder );
++ ps_builder_close_contour( &decoder->builder );
+
+ FT_GlyphLoader_Add( decoder->builder.loader );
+ }
+diff --git a/src/cff/cf2ft.h b/src/psaux/psft.h
+similarity index 60%
+rename from src/cff/cf2ft.h
+rename to src/psaux/psft.h
+index b054a6e950..ab172110bb 100644
+--- a/src/cff/cf2ft.h
++++ b/src/psaux/psft.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2ft.h */
++/* psft.h */
+ /* */
+ /* FreeType Glue Component to Adobe's Interpreter (specification). */
+ /* */
+@@ -36,11 +36,11 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2FT_H_
+-#define CF2FT_H_
++#ifndef PSFT_H_
++#define PSFT_H_
+
+
+-#include "cf2types.h"
++#include "pstypes.h"
+
+
+ /* TODO: disable asserts for now */
+@@ -49,88 +49,96 @@
+
+ #include FT_SYSTEM_H
+
+-#include "cf2glue.h"
+-#include "cffgload.h" /* for CFF_Decoder */
++#include "psglue.h"
++#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Decoder */
+
+
+ FT_BEGIN_HEADER
+
+
+ FT_LOCAL( FT_Error )
+- cf2_decoder_parse_charstrings( CFF_Decoder* decoder,
+- FT_Byte* charstring_base,
+- FT_ULong charstring_len );
++ cf2_decoder_parse_charstrings( PS_Decoder* decoder,
++ FT_Byte* charstring_base,
++ FT_ULong charstring_len );
+
+ FT_LOCAL( CFF_SubFont )
+- cf2_getSubfont( CFF_Decoder* decoder );
++ cf2_getSubfont( PS_Decoder* decoder );
+
+ FT_LOCAL( CFF_VStore )
+- cf2_getVStore( CFF_Decoder* decoder );
++ cf2_getVStore( PS_Decoder* decoder );
+
+ FT_LOCAL( FT_UInt )
+- cf2_getMaxstack( CFF_Decoder* decoder );
++ cf2_getMaxstack( PS_Decoder* decoder );
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ FT_LOCAL( FT_Error )
+- cf2_getNormalizedVector( CFF_Decoder* decoder,
+- CF2_UInt *len,
+- FT_Fixed* *vec );
++ cf2_getNormalizedVector( PS_Decoder* decoder,
++ CF2_UInt *len,
++ FT_Fixed* *vec );
+ #endif
+
+ FT_LOCAL( CF2_Fixed )
+- cf2_getPpemY( CFF_Decoder* decoder );
++ cf2_getPpemY( PS_Decoder* decoder );
+ FT_LOCAL( CF2_Fixed )
+- cf2_getStdVW( CFF_Decoder* decoder );
++ cf2_getStdVW( PS_Decoder* decoder );
+ FT_LOCAL( CF2_Fixed )
+- cf2_getStdHW( CFF_Decoder* decoder );
++ cf2_getStdHW( PS_Decoder* decoder );
+
+ FT_LOCAL( void )
+- cf2_getBlueMetrics( CFF_Decoder* decoder,
+- CF2_Fixed* blueScale,
+- CF2_Fixed* blueShift,
+- CF2_Fixed* blueFuzz );
++ cf2_getBlueMetrics( PS_Decoder* decoder,
++ CF2_Fixed* blueScale,
++ CF2_Fixed* blueShift,
++ CF2_Fixed* blueFuzz );
+ FT_LOCAL( void )
+- cf2_getBlueValues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data );
++ cf2_getBlueValues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data );
+ FT_LOCAL( void )
+- cf2_getOtherBlues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data );
++ cf2_getOtherBlues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data );
+ FT_LOCAL( void )
+- cf2_getFamilyBlues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data );
++ cf2_getFamilyBlues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data );
+ FT_LOCAL( void )
+- cf2_getFamilyOtherBlues( CFF_Decoder* decoder,
+- size_t* count,
+- FT_Pos* *data );
++ cf2_getFamilyOtherBlues( PS_Decoder* decoder,
++ size_t* count,
++ FT_Pos* *data );
+
+ FT_LOCAL( CF2_Int )
+- cf2_getLanguageGroup( CFF_Decoder* decoder );
++ cf2_getLanguageGroup( PS_Decoder* decoder );
+
+ FT_LOCAL( CF2_Int )
+- cf2_initGlobalRegionBuffer( CFF_Decoder* decoder,
+- CF2_Int subrNum,
+- CF2_Buffer buf );
++ cf2_initGlobalRegionBuffer( PS_Decoder* decoder,
++ CF2_Int subrNum,
++ CF2_Buffer buf );
+ FT_LOCAL( FT_Error )
+- cf2_getSeacComponent( CFF_Decoder* decoder,
+- CF2_Int code,
+- CF2_Buffer buf );
++ cf2_getSeacComponent( PS_Decoder* decoder,
++ CF2_Int code,
++ CF2_Buffer buf );
+ FT_LOCAL( void )
+- cf2_freeSeacComponent( CFF_Decoder* decoder,
+- CF2_Buffer buf );
++ cf2_freeSeacComponent( PS_Decoder* decoder,
++ CF2_Buffer buf );
+ FT_LOCAL( CF2_Int )
+- cf2_initLocalRegionBuffer( CFF_Decoder* decoder,
+- CF2_Int subrNum,
+- CF2_Buffer buf );
++ cf2_initLocalRegionBuffer( PS_Decoder* decoder,
++ CF2_Int subrNum,
++ CF2_Buffer buf );
+
+ FT_LOCAL( CF2_Fixed )
+- cf2_getDefaultWidthX( CFF_Decoder* decoder );
++ cf2_getDefaultWidthX( PS_Decoder* decoder );
+ FT_LOCAL( CF2_Fixed )
+- cf2_getNominalWidthX( CFF_Decoder* decoder );
++ cf2_getNominalWidthX( PS_Decoder* decoder );
+
+
++ FT_LOCAL( FT_Error )
++ cf2_getT1SeacComponent( PS_Decoder* decoder,
++ FT_UInt glyph_index,
++ CF2_Buffer buf );
++ FT_LOCAL( void )
++ cf2_freeT1SeacComponent( PS_Decoder* decoder,
++ CF2_Buffer buf );
++
+ /*
+ * FreeType client outline
+ *
+@@ -139,7 +147,7 @@ FT_BEGIN_HEADER
+ typedef struct CF2_OutlineRec_
+ {
+ CF2_OutlineCallbacksRec root; /* base class must be first */
+- CFF_Decoder* decoder;
++ PS_Decoder* decoder;
+
+ } CF2_OutlineRec, *CF2_Outline;
+
+@@ -153,7 +161,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2FT_H_ */
++#endif /* PSFT_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2glue.h b/src/psaux/psglue.h
+similarity index 96%
+rename from src/cff/cf2glue.h
+rename to src/psaux/psglue.h
+index 56a7c248f4..5545e12a5b 100644
+--- a/src/cff/cf2glue.h
++++ b/src/psaux/psglue.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2glue.h */
++/* psglue.h */
+ /* */
+ /* Adobe's code for shared stuff (specification only). */
+ /* */
+@@ -36,15 +36,15 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2GLUE_H_
+-#define CF2GLUE_H_
++#ifndef PSGLUE_H_
++#define PSGLUE_H_
+
+
+ /* common includes for other modules */
+-#include "cf2error.h"
+-#include "cf2fixed.h"
+-#include "cf2arrst.h"
+-#include "cf2read.h"
++#include "pserror.h"
++#include "psfixed.h"
++#include "psarrst.h"
++#include "psread.h"
+
+
+ FT_BEGIN_HEADER
+@@ -138,7 +138,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2GLUE_H_ */
++#endif /* PSGLUE_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2hints.c b/src/psaux/pshints.c
+similarity index 97%
+rename from src/cff/cf2hints.c
+rename to src/psaux/pshints.c
+index 656eb2cff1..93e1587da9 100644
+--- a/src/cff/cf2hints.c
++++ b/src/psaux/pshints.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2hints.c */
++/* pshints.c */
+ /* */
+ /* Adobe's code for handling CFF hints (body). */
+ /* */
+@@ -36,13 +36,13 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
+
+-#include "cf2glue.h"
+-#include "cf2font.h"
+-#include "cf2hints.h"
+-#include "cf2intrp.h"
++#include "psglue.h"
++#include "psfont.h"
++#include "pshints.h"
++#include "psintrp.h"
+
+
+ /*************************************************************************/
+@@ -299,6 +299,36 @@
+ }
+
+
++ static void
++ cf2_hintmap_dump( CF2_HintMap hintmap )
++ {
++#ifdef FT_DEBUG_LEVEL_TRACE
++ CF2_UInt i;
++
++
++ FT_TRACE6(( " index csCoord dsCoord scale flags\n" ));
++
++ for ( i = 0; i < hintmap->count; i++ )
++ {
++ CF2_Hint hint = &hintmap->edge[i];
++
++
++ FT_TRACE6(( " %3d %7.2f %7.2f %5d %s%s%s%s\n",
++ hint->index,
++ hint->csCoord / 65536.0,
++ hint->dsCoord / ( hint->scale * 1.0 ),
++ hint->scale,
++ ( cf2_hint_isPair( hint ) ? "p" : "g" ),
++ ( cf2_hint_isTop( hint ) ? "t" : "b" ),
++ ( cf2_hint_isLocked( hint ) ? "L" : ""),
++ ( cf2_hint_isSynthetic( hint ) ? "S" : "" ) ));
++ }
++#else
++ FT_UNUSED( hintmap );
++#endif
++ }
++
++
+ /* transform character space coordinate to device space using hint map */
+ static CF2_Fixed
+ cf2_hintmap_map( CF2_HintMap hintmap,
+@@ -612,6 +642,14 @@
+ break;
+ }
+
++ FT_TRACE7(( " Got hint at %.2f (%.2f)\n",
++ firstHintEdge->csCoord / 65536.0,
++ firstHintEdge->dsCoord / 65536.0 ));
++ if ( isPair )
++ FT_TRACE7(( " Got hint at %.2f (%.2f)\n",
++ secondHintEdge->csCoord / 65536.0,
++ secondHintEdge->dsCoord / 65536.0 ));
++
+ /*
+ * Discard any hints that overlap in character space. Most often, this
+ * is while building the initial map, where captured hints from all
+@@ -731,11 +769,20 @@
+ hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */
+ hintmap->count += 1;
+
++ FT_TRACE7(( " Inserting hint %.2f (%.2f)\n",
++ firstHintEdge->csCoord / 65536.0,
++ firstHintEdge->dsCoord / 65536.0 ));
++
+ if ( isPair )
+ {
+ /* insert second edge */
+ hintmap->edge[indexInsert + 1] = *secondHintEdge; /* copy struct */
+ hintmap->count += 1;
++
++ FT_TRACE7(( " Inserting hint %.2f (%.2f)\n",
++ secondHintEdge->csCoord / 65536.0,
++ secondHintEdge->dsCoord / 65536.0 ));
++
+ }
+ }
+
+@@ -970,6 +1017,12 @@
+ }
+ }
+
++ FT_TRACE6(( initialMap ? "flags: [p]air [g]host [t]op "
++ "[b]ottom [L]ocked [S]ynthetic\n"
++ "Initial hintmap\n"
++ : "Hints:\n" ));
++ cf2_hintmap_dump( hintmap );
++
+ /*
+ * Note: The following line is a convenient place to break when
+ * debugging hinting. Examine `hintmap->edge' for the list of
+@@ -982,6 +1035,9 @@
+ /* adjust positions of hint edges that are not locked to blue zones */
+ cf2_hintmap_adjustHints( hintmap );
+
++ FT_TRACE6(( "(adjusted)\n" ));
++ cf2_hintmap_dump( hintmap );
++
+ /* save the position of all hints that were used in this hint map; */
+ /* if we use them again, we'll locate them in the same position */
+ if ( !initialMap )
+diff --git a/src/cff/cf2hints.h b/src/psaux/pshints.h
+similarity index 98%
+rename from src/cff/cf2hints.h
+rename to src/psaux/pshints.h
+index a8984542a0..92e37e98ae 100644
+--- a/src/cff/cf2hints.h
++++ b/src/psaux/pshints.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2hints.h */
++/* pshints.h */
+ /* */
+ /* Adobe's code for handling CFF hints (body). */
+ /* */
+@@ -36,9 +36,8 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2HINTS_H_
+-#define CF2HINTS_H_
+-
++#ifndef PSHINT_H_
++#define PSHINT_H_
+
+ FT_BEGIN_HEADER
+
+@@ -283,7 +282,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2HINTS_H_ */
++#endif /* PSHINT_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2intrp.c b/src/psaux/psintrp.c
+similarity index 55%
+rename from src/cff/cf2intrp.c
+rename to src/psaux/psintrp.c
+index a816280748..a60597e3ce 100644
+--- a/src/cff/cf2intrp.c
++++ b/src/psaux/psintrp.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2intrp.c */
++/* psintrp.c */
+ /* */
+ /* Adobe's CFF Interpreter (body). */
+ /* */
+@@ -36,18 +36,20 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
++#include FT_SERVICE_CFF_TABLE_LOAD_H
+
+-#include "cf2glue.h"
+-#include "cf2font.h"
+-#include "cf2stack.h"
+-#include "cf2hints.h"
+-#include "cf2intrp.h"
++#include "psglue.h"
++#include "psfont.h"
++#include "psstack.h"
++#include "pshints.h"
++#include "psintrp.h"
+
+-#include "cf2error.h"
++#include "pserror.h"
+
+-#include "cffload.h"
++#include "psobjs.h" /* for cff_random */
++#include "t1decode.h" /* for t1 seac */
+
+
+ /*************************************************************************/
+@@ -205,11 +207,11 @@
+ cf2_cmdHLINETO, /* 6 */
+ cf2_cmdVLINETO, /* 7 */
+ cf2_cmdRRCURVETO, /* 8 */
+- cf2_cmdRESERVED_9, /* 9 */
++ cf2_cmdCLOSEPATH, /* 9 T1 only */
+ cf2_cmdCALLSUBR, /* 10 */
+ cf2_cmdRETURN, /* 11 */
+ cf2_cmdESC, /* 12 */
+- cf2_cmdRESERVED_13, /* 13 */
++ cf2_cmdHSBW, /* 13 T1 only */
+ cf2_cmdENDCHAR, /* 14 */
+ cf2_cmdVSINDEX, /* 15 */
+ cf2_cmdBLEND, /* 16 */
+@@ -233,13 +235,13 @@
+ enum
+ {
+ cf2_escDOTSECTION, /* 0 */
+- cf2_escRESERVED_1, /* 1 */
+- cf2_escRESERVED_2, /* 2 */
++ cf2_escVSTEM3, /* 1 T1 only */
++ cf2_escHSTEM3, /* 2 T1 only */
+ cf2_escAND, /* 3 */
+ cf2_escOR, /* 4 */
+ cf2_escNOT, /* 5 */
+- cf2_escRESERVED_6, /* 6 */
+- cf2_escRESERVED_7, /* 7 */
++ cf2_escSEAC, /* 6 T1 only */
++ cf2_escSBW, /* 7 T1 only */
+ cf2_escRESERVED_8, /* 8 */
+ cf2_escABS, /* 9 */
+ cf2_escADD, /* 10 like otherADD */
+@@ -248,8 +250,8 @@
+ cf2_escRESERVED_13, /* 13 */
+ cf2_escNEG, /* 14 */
+ cf2_escEQ, /* 15 */
+- cf2_escRESERVED_16, /* 16 */
+- cf2_escRESERVED_17, /* 17 */
++ cf2_escCALLOTHERSUBR,/* 16 T1 only */
++ cf2_escPOP, /* 17 T1 only */
+ cf2_escDROP, /* 18 */
+ cf2_escRESERVED_19, /* 19 */
+ cf2_escPUT, /* 20 like otherPUT */
+@@ -265,7 +267,7 @@
+ cf2_escROLL, /* 30 */
+ cf2_escRESERVED_31, /* 31 */
+ cf2_escRESERVED_32, /* 32 */
+- cf2_escRESERVED_33, /* 33 */
++ cf2_escSETCURRENTPT, /* 33 T1 only */
+ cf2_escHFLEX, /* 34 */
+ cf2_escFLEX, /* 35 */
+ cf2_escHFLEX1, /* 36 */
+@@ -290,10 +292,13 @@
+ /* variable accumulates delta values from operand stack */
+ CF2_Fixed position = hintOffset;
+
++ if ( font->isT1 && !font->decoder->flex_state && !*haveWidth )
++ FT_ERROR(( "cf2_doStems (Type 1 mode):"
++ " No width. Use hsbw/sbw as first op\n" ));
+
+- if ( hasWidthArg && !*haveWidth )
+- *width = cf2_stack_getReal( opStack, 0 ) +
+- cf2_getNominalWidthX( font->decoder );
++ if ( !font->isT1 && hasWidthArg && !*haveWidth )
++ *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
++ cf2_getNominalWidthX( font->decoder ) );
+
+ if ( font->decoder->width_only )
+ goto exit;
+@@ -476,7 +481,7 @@
+ FT_Error lastError = FT_Err_Ok;
+
+ /* pointer to parsed font object */
+- CFF_Decoder* decoder = font->decoder;
++ PS_Decoder* decoder = font->decoder;
+
+ FT_Error* error = &font->error;
+ FT_Memory memory = font->memory;
+@@ -484,6 +489,15 @@
+ CF2_Fixed scaleY = font->innerTransform.d;
+ CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder );
+
++ /* stuff for Type 1 */
++ FT_Int known_othersubr_result_cnt = 0;
++ FT_Bool large_int = FALSE;
++ FT_Bool initial_map_ready = FALSE;
++
++#define PS_STORAGE_SIZE 3
++ CF2_F16Dot16 results[PS_STORAGE_SIZE]; /* for othersubr results */
++ FT_Int result_cnt = 0;
++
+ /* save this for hinting seac accents */
+ CF2_Fixed hintOriginY = curY;
+
+@@ -492,6 +506,7 @@
+ FT_Byte op1; /* first opcode byte */
+
+ CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */
++ CF2_F16Dot16 flexStore[6]; /* for Type 1 flex */
+
+ /* instruction limit; 20,000,000 matches Avalon */
+ FT_UInt32 instructionLimit = 20000000UL;
+@@ -514,6 +529,8 @@
+
+
+ FT_ZERO( &storage );
++ FT_ZERO( &results );
++ FT_ZERO( &flexStore );
+
+ /* initialize the remaining objects */
+ cf2_arrstack_init( &subrStack,
+@@ -606,6 +623,10 @@
+ /* main interpreter loop */
+ while ( 1 )
+ {
++ if ( font->isT1 )
++ FT_ASSERT( known_othersubr_result_cnt == 0 ||
++ result_cnt == 0 );
++
+ if ( cf2_buf_isEnd( charstring ) )
+ {
+ /* If we've reached the end of the charstring, simulate a */
+@@ -627,6 +648,44 @@
+ op1 = cf2_cmdRESERVED_0;
+ }
+
++ if ( font->isT1 )
++ {
++ if ( !initial_map_ready &&
++ !( op1 == cf2_cmdHSTEM ||
++ op1 == cf2_cmdVSTEM ||
++ op1 == cf2_cmdHSBW ||
++ op1 == cf2_cmdCALLSUBR ||
++ op1 == cf2_cmdRETURN ||
++ op1 == cf2_cmdESC ||
++ op1 == cf2_cmdENDCHAR ||
++ op1 >= 32 /* Numbers */ ) )
++ {
++ /* Skip outline commands first time round. */
++ /* `endchar' will trigger initial hintmap build */
++ /* and rewind the charstring. */
++ cf2_stack_clear( opStack );
++ continue;
++ }
++
++ if ( result_cnt > 0 &&
++ !( op1 == cf2_cmdCALLSUBR ||
++ op1 == cf2_cmdRETURN ||
++ op1 == cf2_cmdESC ||
++ op1 >= 32 /* Numbers */ ) )
++ {
++ /* all operands have been transferred by previous pops */
++ result_cnt = 0;
++ }
++
++ if ( large_int && !( op1 >= 32 || op1 == cf2_escDIV ) )
++ {
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " no `div' after large integer\n" ));
++
++ large_int = FALSE;
++ }
++ }
++
+ /* check for errors once per loop */
+ if ( *error )
+ goto exit;
+@@ -642,8 +701,6 @@
+ {
+ case cf2_cmdRESERVED_0:
+ case cf2_cmdRESERVED_2:
+- case cf2_cmdRESERVED_9:
+- case cf2_cmdRESERVED_13:
+ case cf2_cmdRESERVED_17:
+ /* we may get here if we have a prior error */
+ FT_TRACE4(( " unknown op (%d)\n", op1 ));
+@@ -689,15 +746,15 @@
+ }
+
+ /* check cached blend vector */
+- if ( cff_blend_check_vector( &font->blend,
+- font->vsindex,
+- font->lenNDV,
+- font->NDV ) )
++ if ( font->cffload->blend_check_vector( &font->blend,
++ font->vsindex,
++ font->lenNDV,
++ font->NDV ) )
+ {
+- lastError = cff_blend_build_vector( &font->blend,
+- font->vsindex,
+- font->lenNDV,
+- font->NDV );
++ lastError = font->cffload->blend_build_vector( &font->blend,
++ font->vsindex,
++ font->lenNDV,
++ font->NDV );
+ if ( lastError )
+ goto exit;
+ }
+@@ -720,22 +777,28 @@
+ case cf2_cmdHSTEM:
+ FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" ));
+
+- /* never add hints after the mask is computed */
+- if ( cf2_hintmask_isValid( &hintMask ) )
++ if ( !font->isT1 )
+ {
+- FT_TRACE4(( "cf2_interpT2CharString:"
+- " invalid horizontal hint mask\n" ));
+- break;
++ /* never add hints after the mask is computed */
++ /* except if in Type 1 mode (no hintmask op) */
++ if ( cf2_hintmask_isValid( &hintMask ) )
++ {
++ FT_TRACE4(( "cf2_interpT2CharString:"
++ " invalid horizontal hint mask\n" ));
++ break;
++ }
+ }
+
++ /* add left-sidebearing correction in Type 1 mode */
+ cf2_doStems( font,
+ opStack,
+ &hStemHintArray,
+ width,
+ &haveWidth,
+- 0 );
++ font->isT1 ? decoder->builder.left_bearing->y
++ : 0 );
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ break;
+@@ -744,22 +807,28 @@
+ case cf2_cmdVSTEM:
+ FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" ));
+
+- /* never add hints after the mask is computed */
+- if ( cf2_hintmask_isValid( &hintMask ) )
++ if ( !font->isT1 )
+ {
+- FT_TRACE4(( "cf2_interpT2CharString:"
+- " invalid vertical hint mask\n" ));
+- break;
++ /* never add hints after the mask is computed */
++ /* except if in Type 1 mode (no hintmask op) */
++ if ( cf2_hintmask_isValid( &hintMask ) )
++ {
++ FT_TRACE4(( "cf2_interpT2CharString:"
++ " invalid vertical hint mask\n" ));
++ break;
++ }
+ }
+
++ /* add left-sidebearing correction in Type 1 mode */
+ cf2_doStems( font,
+ opStack,
+ &vStemHintArray,
+ width,
+ &haveWidth,
+- 0 );
++ font->isT1 ? decoder->builder.left_bearing->x
++ : 0 );
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ break;
+@@ -767,6 +836,10 @@
+ case cf2_cmdVMOVETO:
+ FT_TRACE4(( " vmoveto\n" ));
+
++ if ( font->isT1 && !decoder->flex_state && !haveWidth )
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " No width. Use hsbw/sbw as first op\n" ));
++
+ if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
+ *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
+ nominalWidthX );
+@@ -774,7 +847,7 @@
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
+@@ -878,6 +951,20 @@
+ }
+ continue; /* no need to clear stack again */
+
++ case cf2_cmdCLOSEPATH:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (%d)\n", op1 ));
++ else
++ {
++ FT_TRACE4(( " closepath" ));
++
++ /* if there is no path, `closepath' is a no-op */
++ ps_builder_close_contour( &decoder->builder );
++
++ haveWidth = TRUE;
++ }
++ break;
++
+ case cf2_cmdCALLGSUBR:
+ case cf2_cmdCALLSUBR:
+ {
+@@ -887,7 +974,8 @@
+ FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
+ : " callsubr" ));
+
+- if ( charstringIndex > CF2_MAX_SUBR )
++ if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) ||
++ ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
+ {
+ /* max subr plus one for charstring */
+ lastError = FT_THROW( Invalid_Glyph_Format );
+@@ -903,6 +991,18 @@
+ /* set up the new CFF region and pointer */
+ subrNum = cf2_stack_popInt( opStack );
+
++ if ( font->isT1 && decoder->locals_hash )
++ {
++ size_t* val = ft_hash_num_lookup( subrNum,
++ decoder->locals_hash );
++
++
++ if ( val )
++ subrNum = *val;
++ else
++ subrNum = -1;
++ }
++
+ switch ( op1 )
+ {
+ case cf2_cmdCALLGSUBR:
+@@ -1060,20 +1160,13 @@
+ }
+ continue;
+
+- /* these opcodes are reserved in both CFF & CFF2 */
+- case cf2_escRESERVED_1:
+- case cf2_escRESERVED_2:
+- case cf2_escRESERVED_6:
+- case cf2_escRESERVED_7:
++ /* these opcodes are always reserved */
+ case cf2_escRESERVED_8:
+ case cf2_escRESERVED_13:
+- case cf2_escRESERVED_16:
+- case cf2_escRESERVED_17:
+ case cf2_escRESERVED_19:
+ case cf2_escRESERVED_25:
+ case cf2_escRESERVED_31:
+ case cf2_escRESERVED_32:
+- case cf2_escRESERVED_33:
+ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+ break;
+
+@@ -1081,9 +1174,15 @@
+ {
+ if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 )
+ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else if ( font->isT1 && result_cnt > 0 && op2 != cf2_escPOP )
++ {
++ /* all operands have been transferred by previous pops */
++ result_cnt = 0;
++ }
+ else
+ {
+- /* second switch for 2-byte operators handles just CFF */
++ /* second switch for 2-byte operators handles */
++ /* CFF and Type 1 */
+ switch ( op2 )
+ {
+
+@@ -1093,6 +1192,58 @@
+
+ break;
+
++ case cf2_escVSTEM3:
++ case cf2_escHSTEM3:
++ /*
++ * Type 1: Type 2:
++ * x0 dx0 x1 dx1 x2 dx2 vstem3 x dx {dxa dxb}* vstem
++ * y0 dy0 y1 dy1 y2 dy2 hstem3 y dy {dya dyb}* hstem
++ * relative to lsb point relative to zero
++ *
++ */
++ {
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else
++ {
++ CF2_F16Dot16 v0, v1, v2;
++
++ FT_Bool isV = FT_BOOL( op2 == cf2_escVSTEM3 );
++
++
++ FT_TRACE4(( isV ? " vstem3\n"
++ : " hstem3\n" ));
++
++ FT_ASSERT( cf2_stack_count( opStack ) == 6 );
++
++ v0 = cf2_stack_getReal( opStack, 0 );
++ v1 = cf2_stack_getReal( opStack, 2 );
++ v2 = cf2_stack_getReal( opStack, 4 );
++
++ cf2_stack_setReal(
++ opStack, 2,
++ SUB_INT32( SUB_INT32( v1, v0 ),
++ cf2_stack_getReal( opStack, 1 ) ) );
++ cf2_stack_setReal(
++ opStack, 4,
++ SUB_INT32( SUB_INT32( v2, v1 ),
++ cf2_stack_getReal( opStack, 3 ) ) );
++
++ /* add left-sidebearing correction */
++ cf2_doStems( font,
++ opStack,
++ isV ? &vStemHintArray : &hStemHintArray,
++ width,
++ &haveWidth,
++ isV ? decoder->builder.left_bearing->x
++ : decoder->builder.left_bearing->y );
++
++ if ( decoder->width_only )
++ goto exit;
++ }
++ }
++ break;
++
+ case cf2_escAND:
+ {
+ CF2_F16Dot16 arg1;
+@@ -1136,6 +1287,239 @@
+ }
+ continue; /* do not clear the stack */
+
++ case cf2_escSEAC:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else
++ {
++ FT_Error error2;
++ CF2_Int bchar_index, achar_index;
++ FT_Vector left_bearing, advance;
++
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ T1_Face face = (T1_Face)decoder->builder.face;
++#endif
++ CF2_BufferRec component;
++ CF2_Fixed dummyWidth;
++
++ CF2_Int achar = cf2_stack_popInt( opStack );
++ CF2_Int bchar = cf2_stack_popInt( opStack );
++
++ FT_Pos ady = cf2_stack_popFixed ( opStack );
++ FT_Pos adx = cf2_stack_popFixed ( opStack );
++ FT_Pos asb = cf2_stack_popFixed ( opStack );
++
++
++ FT_TRACE4(( " seac\n" ));
++
++ if ( doingSeac )
++ {
++ FT_ERROR(( " nested seac\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit; /* nested seac */
++ }
++
++ if ( decoder->builder.metrics_only )
++ {
++ FT_ERROR(( " unexpected seac\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit; /* unexpected seac */
++ }
++
++ /* `glyph_names' is set to 0 for CID fonts which do */
++ /* not include an encoding. How can we deal with */
++ /* these? */
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ if ( decoder->glyph_names == 0 &&
++ !face->root.internal->incremental_interface )
++#else
++ if ( decoder->glyph_names == 0 )
++#endif /* FT_CONFIG_OPTION_INCREMENTAL */
++ {
++ FT_ERROR((
++ "cf2_interpT2CharString: (Type 1 seac)"
++ " glyph names table not available in this font\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ /* seac weirdness */
++ adx += decoder->builder.left_bearing->x;
++
++#ifdef FT_CONFIG_OPTION_INCREMENTAL
++ if ( face->root.internal->incremental_interface )
++ {
++ /* the caller must handle the font encoding also */
++ bchar_index = bchar;
++ achar_index = achar;
++ }
++ else
++#endif
++ {
++ bchar_index = t1_lookup_glyph_by_stdcharcode_ps(
++ decoder, bchar );
++ achar_index = t1_lookup_glyph_by_stdcharcode_ps(
++ decoder, achar );
++ }
++
++ if ( bchar_index < 0 || achar_index < 0 )
++ {
++ FT_ERROR((
++ "cf2_interpT2CharString: (Type 1 seac)"
++ " invalid seac character code arguments\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ /* if we are trying to load a composite glyph, */
++ /* do not load the accent character and return */
++ /* the array of subglyphs. */
++ if ( decoder->builder.no_recurse )
++ {
++ FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
++ FT_GlyphLoader loader = glyph->internal->loader;
++ FT_SubGlyph subg;
++
++
++ /* reallocate subglyph array if necessary */
++ error2 = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
++ if ( error2 )
++ {
++ lastError = error2; /* pass FreeType error through */
++ goto exit;
++ }
++
++ subg = loader->current.subglyphs;
++
++ /* subglyph 0 = base character */
++ subg->index = bchar_index;
++ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
++ FT_SUBGLYPH_FLAG_USE_MY_METRICS;
++ subg->arg1 = 0;
++ subg->arg2 = 0;
++ subg++;
++
++ /* subglyph 1 = accent character */
++ subg->index = achar_index;
++ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
++ subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
++ subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
++
++ /* set up remaining glyph fields */
++ glyph->num_subglyphs = 2;
++ glyph->subglyphs = loader->base.subglyphs;
++ glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
++
++ loader->current.num_subglyphs = 2;
++
++ goto exit;
++ }
++
++ /* First load `bchar' in builder */
++ /* now load the unscaled outline */
++
++ /* prepare loader */
++ FT_GlyphLoader_Prepare( decoder->builder.loader );
++
++ error2 = cf2_getT1SeacComponent( decoder,
++ (FT_UInt)bchar_index,
++ &component );
++ if ( error2 )
++ {
++ lastError = error2; /* pass FreeType error through */
++ goto exit;
++ }
++ cf2_interpT2CharString( font,
++ &component,
++ callbacks,
++ translation,
++ TRUE,
++ 0,
++ 0,
++ &dummyWidth );
++ cf2_freeT1SeacComponent( decoder, &component );
++
++ /* save the left bearing and width of the base */
++ /* character as they will be erased by the next load */
++
++ left_bearing = *decoder->builder.left_bearing;
++ advance = *decoder->builder.advance;
++
++ decoder->builder.left_bearing->x = 0;
++ decoder->builder.left_bearing->y = 0;
++
++ /* Now load `achar' on top of */
++ /* the base outline */
++
++ error2 = cf2_getT1SeacComponent( decoder,
++ (FT_UInt)achar_index,
++ &component );
++ if ( error2 )
++ {
++ lastError = error2; /* pass FreeType error through */
++ goto exit;
++ }
++ cf2_interpT2CharString( font,
++ &component,
++ callbacks,
++ translation,
++ TRUE,
++ adx - asb,
++ ady,
++ &dummyWidth );
++ cf2_freeT1SeacComponent( decoder, &component );
++
++ /* restore the left side bearing and */
++ /* advance width of the base character */
++
++ *decoder->builder.left_bearing = left_bearing;
++ *decoder->builder.advance = advance;
++
++ goto exit;
++ }
++ break;
++
++ case cf2_escSBW:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else
++ {
++ CF2_Fixed lsb_x, lsb_y;
++ PS_Builder* builder;
++
++
++ FT_TRACE4(( " sbw" ));
++
++ builder = &decoder->builder;
++
++ builder->advance->y = cf2_stack_popFixed( opStack );
++ builder->advance->x = cf2_stack_popFixed( opStack );
++
++ lsb_y = cf2_stack_popFixed( opStack );
++ lsb_x = cf2_stack_popFixed( opStack );
++
++ builder->left_bearing->x =
++ ADD_INT32( builder->left_bearing->x, lsb_x );
++ builder->left_bearing->y =
++ ADD_INT32( builder->left_bearing->y, lsb_y );
++
++ haveWidth = TRUE;
++
++ /* the `metrics_only' indicates that we only want */
++ /* to compute the glyph's metrics (lsb + advance */
++ /* width), not load the rest of it; so exit */
++ /* immediately */
++ if ( builder->metrics_only )
++ goto exit;
++
++ if ( initial_map_ready )
++ {
++ curX = ADD_INT32( curX, lsb_x );
++ curY = ADD_INT32( curY, lsb_y );
++ }
++ }
++ break;
++
+ case cf2_escABS:
+ {
+ CF2_F16Dot16 arg;
+@@ -1193,11 +1577,22 @@
+
+ FT_TRACE4(( " div\n" ));
+
+- divisor = cf2_stack_popFixed( opStack );
+- dividend = cf2_stack_popFixed( opStack );
++ if ( font->isT1 && large_int )
++ {
++ divisor = (CF2_F16Dot16)cf2_stack_popInt( opStack );
++ dividend = (CF2_F16Dot16)cf2_stack_popInt( opStack );
++
++ large_int = FALSE;
++ }
++ else
++ {
++ divisor = cf2_stack_popFixed( opStack );
++ dividend = cf2_stack_popFixed( opStack );
++ }
+
+ cf2_stack_pushFixed( opStack,
+ FT_DivFix( dividend, divisor ) );
++
+ }
+ continue; /* do not clear the stack */
+
+@@ -1232,6 +1627,534 @@
+ }
+ continue; /* do not clear the stack */
+
++ case cf2_escCALLOTHERSUBR:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else
++ {
++ CF2_Int subr_no;
++ CF2_Int arg_cnt;
++ CF2_UInt count;
++ CF2_UInt opIdx = 0;
++
++
++ FT_TRACE4(( " callothersubr\n" ));
++
++ subr_no = cf2_stack_popInt( opStack );
++ arg_cnt = cf2_stack_popInt( opStack );
++
++ /*******************************************************/
++ /* */
++ /* remove all operands to callothersubr from the stack */
++ /* */
++ /* for handled othersubrs, where we know the number of */
++ /* arguments, we increase the stack by the value of */
++ /* known_othersubr_result_cnt */
++ /* */
++ /* for unhandled othersubrs the following pops adjust */
++ /* the stack pointer as necessary */
++
++ count = cf2_stack_count( opStack );
++ FT_ASSERT( (CF2_UInt)arg_cnt <= count );
++
++ opIdx += count - (CF2_UInt)arg_cnt;
++
++ known_othersubr_result_cnt = 0;
++ result_cnt = 0;
++
++ /* XXX TODO: The checks to `arg_count == <whatever>' */
++ /* might not be correct; an othersubr expects a */
++ /* certain number of operands on the PostScript stack */
++ /* (as opposed to the T1 stack) but it doesn't have to */
++ /* put them there by itself; previous othersubrs might */
++ /* have left the operands there if they were not */
++ /* followed by an appropriate number of pops */
++ /* */
++ /* On the other hand, Adobe Reader 7.0.8 for Linux */
++ /* doesn't accept a font that contains charstrings */
++ /* like */
++ /* */
++ /* 100 200 2 20 callothersubr */
++ /* 300 1 20 callothersubr pop */
++ /* */
++ /* Perhaps this is the reason why BuildCharArray */
++ /* exists. */
++
++ switch ( subr_no )
++ {
++ case 0: /* end flex feature */
++ if ( arg_cnt != 3 )
++ goto Unexpected_OtherSubr;
++
++ if ( initial_map_ready &&
++ ( !decoder->flex_state ||
++ decoder->num_flex_vectors != 7 ) )
++ {
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " unexpected flex end\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ /* the two `results' are popped */
++ /* by the following setcurrentpoint */
++ cf2_stack_pushFixed( opStack, curX );
++ cf2_stack_pushFixed( opStack, curY );
++ known_othersubr_result_cnt = 2;
++ break;
++
++ case 1: /* start flex feature */
++ if ( arg_cnt != 0 )
++ goto Unexpected_OtherSubr;
++
++ if ( !initial_map_ready )
++ break;
++
++ if ( ps_builder_check_points( &decoder->builder, 6 ) )
++ goto exit;
++
++ decoder->flex_state = 1;
++ decoder->num_flex_vectors = 0;
++ break;
++
++ case 2: /* add flex vectors */
++ {
++ FT_Int idx;
++ FT_Int idx2;
++
++
++ if ( arg_cnt != 0 )
++ goto Unexpected_OtherSubr;
++
++ if ( !initial_map_ready )
++ break;
++
++ if ( !decoder->flex_state )
++ {
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " missing flex start\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ /* note that we should not add a point for */
++ /* index 0; this will move our current position */
++ /* to the flex point without adding any point */
++ /* to the outline */
++ idx = decoder->num_flex_vectors++;
++ if ( idx > 0 && idx < 7 )
++ {
++ /* in malformed fonts it is possible to have */
++ /* other opcodes in the middle of a flex (which */
++ /* don't increase `num_flex_vectors'); we thus */
++ /* have to check whether we can add a point */
++
++ if ( ps_builder_check_points( &decoder->builder,
++ 1 ) )
++ {
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ /* map: 1->2 2->4 3->6 4->2 5->4 6->6 */
++ idx2 = ( idx > 3 ? idx - 3 : idx ) * 2;
++
++ flexStore[idx2 - 2] = curX;
++ flexStore[idx2 - 1] = curY;
++
++ if ( idx == 3 || idx == 6 )
++ cf2_glyphpath_curveTo( &glyphPath,
++ flexStore[0],
++ flexStore[1],
++ flexStore[2],
++ flexStore[3],
++ flexStore[4],
++ flexStore[5] );
++ }
++ }
++ break;
++
++ case 3: /* change hints */
++ if ( arg_cnt != 1 )
++ goto Unexpected_OtherSubr;
++
++ if ( initial_map_ready )
++ {
++ /* do not clear hints if initial hintmap */
++ /* is not ready - we need to collate all */
++ cf2_arrstack_clear( &vStemHintArray );
++ cf2_arrstack_clear( &hStemHintArray );
++
++ cf2_hintmask_init( &hintMask, error );
++ hintMask.isValid = FALSE;
++ hintMask.isNew = TRUE;
++ }
++
++ known_othersubr_result_cnt = 1;
++ break;
++
++ case 12:
++ case 13:
++ /* counter control hints, clear stack */
++ cf2_stack_clear( opStack );
++ break;
++
++ case 14:
++ case 15:
++ case 16:
++ case 17:
++ case 18: /* multiple masters */
++ {
++ PS_Blend blend = decoder->blend;
++ FT_UInt num_points, nn, mm;
++ CF2_UInt delta;
++ CF2_UInt values;
++
++
++ if ( !blend )
++ {
++ FT_ERROR((
++ "cf2_interpT2CharString:"
++ " unexpected multiple masters operator\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ num_points = (FT_UInt)subr_no - 13 +
++ ( subr_no == 18 );
++ if ( arg_cnt != (FT_Int)( num_points *
++ blend->num_designs ) )
++ {
++ FT_ERROR((
++ "cf2_interpT2CharString:"
++ " incorrect number of multiple masters arguments\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ /* We want to compute */
++ /* */
++ /* a0*w0 + a1*w1 + ... + ak*wk */
++ /* */
++ /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */
++ /* */
++ /* However, given that w0 + w1 + ... + wk == 1, we */
++ /* can rewrite it easily as */
++ /* */
++ /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */
++ /* */
++ /* where k == num_designs-1. */
++ /* */
++ /* I guess that's why it's written in this `compact' */
++ /* form. */
++ /* */
++ delta = opIdx + num_points;
++ values = opIdx;
++ for ( nn = 0; nn < num_points; nn++ )
++ {
++ CF2_Fixed tmp = cf2_stack_getReal( opStack,
++ values );
++
++
++ for ( mm = 1; mm < blend->num_designs; mm++ )
++ tmp = ADD_INT32( tmp,
++ FT_MulFix(
++ cf2_stack_getReal( opStack,
++ delta++ ),
++ blend->weight_vector[mm] ) );
++
++ cf2_stack_setReal( opStack, values++, tmp );
++ }
++ cf2_stack_pop( opStack,
++ (CF2_UInt)arg_cnt - num_points );
++
++ known_othersubr_result_cnt = (FT_Int)num_points;
++ break;
++ }
++
++ case 19:
++ /* <idx> 1 19 callothersubr */
++ /* ==> replace elements starting from index */
++ /* cvi( <idx> ) of BuildCharArray with */
++ /* WeightVector */
++ {
++ FT_Int idx;
++ PS_Blend blend = decoder->blend;
++
++
++ if ( arg_cnt != 1 || !blend )
++ goto Unexpected_OtherSubr;
++
++ idx = cf2_stack_popInt( opStack );
++
++ if ( idx < 0 ||
++ (FT_UInt)idx + blend->num_designs >
++ decoder->len_buildchar )
++ goto Unexpected_OtherSubr;
++
++ ft_memcpy( &decoder->buildchar[idx],
++ blend->weight_vector,
++ blend->num_designs *
++ sizeof ( blend->weight_vector[0] ) );
++ }
++ break;
++
++ case 20:
++ /* <arg1> <arg2> 2 20 callothersubr pop */
++ /* ==> push <arg1> + <arg2> onto T1 stack */
++ {
++ CF2_F16Dot16 summand1;
++ CF2_F16Dot16 summand2;
++
++
++ if ( arg_cnt != 2 )
++ goto Unexpected_OtherSubr;
++
++ summand2 = cf2_stack_popFixed( opStack );
++ summand1 = cf2_stack_popFixed( opStack );
++
++ cf2_stack_pushFixed( opStack,
++ ADD_INT32( summand1,
++ summand2 ) );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++ case 21:
++ /* <arg1> <arg2> 2 21 callothersubr pop */
++ /* ==> push <arg1> - <arg2> onto T1 stack */
++ {
++ CF2_F16Dot16 minuend;
++ CF2_F16Dot16 subtrahend;
++
++
++ if ( arg_cnt != 2 )
++ goto Unexpected_OtherSubr;
++
++ subtrahend = cf2_stack_popFixed( opStack );
++ minuend = cf2_stack_popFixed( opStack );
++
++ cf2_stack_pushFixed( opStack,
++ SUB_INT32( minuend,
++ subtrahend ) );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++ case 22:
++ /* <arg1> <arg2> 2 22 callothersubr pop */
++ /* ==> push <arg1> * <arg2> onto T1 stack */
++ {
++ CF2_F16Dot16 factor1;
++ CF2_F16Dot16 factor2;
++
++
++ if ( arg_cnt != 2 )
++ goto Unexpected_OtherSubr;
++
++ factor2 = cf2_stack_popFixed( opStack );
++ factor1 = cf2_stack_popFixed( opStack );
++
++ cf2_stack_pushFixed( opStack,
++ FT_MulFix( factor1, factor2 ) );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++ case 23:
++ /* <arg1> <arg2> 2 23 callothersubr pop */
++ /* ==> push <arg1> / <arg2> onto T1 stack */
++ {
++ CF2_F16Dot16 dividend;
++ CF2_F16Dot16 divisor;
++
++
++ if ( arg_cnt != 2 )
++ goto Unexpected_OtherSubr;
++
++ divisor = cf2_stack_popFixed( opStack );
++ dividend = cf2_stack_popFixed( opStack );
++
++ if ( divisor == 0 )
++ goto Unexpected_OtherSubr;
++
++ cf2_stack_pushFixed( opStack,
++ FT_DivFix( dividend,
++ divisor ) );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++ case 24:
++ /* <val> <idx> 2 24 callothersubr */
++ /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
++ {
++ CF2_Int idx;
++ PS_Blend blend = decoder->blend;
++
++
++ if ( arg_cnt != 2 || !blend )
++ goto Unexpected_OtherSubr;
++
++ idx = cf2_stack_popInt( opStack );
++
++ if ( idx < 0 ||
++ (FT_UInt)idx >= decoder->len_buildchar )
++ goto Unexpected_OtherSubr;
++
++ decoder->buildchar[idx] =
++ cf2_stack_popFixed( opStack );
++ }
++ break;
++
++ case 25:
++ /* <idx> 1 25 callothersubr pop */
++ /* ==> push BuildCharArray[cvi( idx )] */
++ /* onto T1 stack */
++ {
++ CF2_Int idx;
++ PS_Blend blend = decoder->blend;
++
++
++ if ( arg_cnt != 1 || !blend )
++ goto Unexpected_OtherSubr;
++
++ idx = cf2_stack_popInt( opStack );
++
++ if ( idx < 0 ||
++ (FT_UInt)idx >= decoder->len_buildchar )
++ goto Unexpected_OtherSubr;
++
++ cf2_stack_pushFixed( opStack,
++ decoder->buildchar[idx] );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++#if 0
++ case 26:
++ /* <val> mark <idx> */
++ /* ==> set BuildCharArray[cvi( <idx> )] = <val>, */
++ /* leave mark on T1 stack */
++ /* <val> <idx> */
++ /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
++ XXX which routine has left its mark on the
++ XXX (PostScript) stack?;
++ break;
++#endif
++
++ case 27:
++ /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
++ /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
++ /* otherwise push <res2> */
++ {
++ CF2_F16Dot16 arg1;
++ CF2_F16Dot16 arg2;
++ CF2_F16Dot16 cond1;
++ CF2_F16Dot16 cond2;
++
++
++ if ( arg_cnt != 4 )
++ goto Unexpected_OtherSubr;
++
++ cond2 = cf2_stack_popFixed( opStack );
++ cond1 = cf2_stack_popFixed( opStack );
++ arg2 = cf2_stack_popFixed( opStack );
++ arg1 = cf2_stack_popFixed( opStack );
++
++ cf2_stack_pushFixed( opStack,
++ cond1 <= cond2 ? arg1 : arg2 );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++ case 28:
++ /* 0 28 callothersubr pop */
++ /* ==> push random value from interval [0, 1) */
++ /* onto stack */
++ {
++ CF2_F16Dot16 r;
++
++
++ if ( arg_cnt != 0 )
++ goto Unexpected_OtherSubr;
++
++ /* only use the lower 16 bits of `random' */
++ /* to generate a number in the range (0;1] */
++ r = (CF2_F16Dot16)
++ ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
++
++ decoder->current_subfont->random =
++ cff_random( decoder->current_subfont->random );
++
++ cf2_stack_pushFixed( opStack, r );
++ known_othersubr_result_cnt = 1;
++ }
++ break;
++
++ default:
++ if ( arg_cnt >= 0 && subr_no >= 0 )
++ {
++ FT_Int i;
++
++
++ FT_ERROR((
++ "cf2_interpT2CharString (Type 1 mode):"
++ " unknown othersubr [%d %d], wish me luck\n",
++ arg_cnt, subr_no ));
++
++ /* store the unused args */
++ /* for this unhandled OtherSubr */
++
++ if ( arg_cnt > PS_STORAGE_SIZE )
++ arg_cnt = PS_STORAGE_SIZE;
++ result_cnt = arg_cnt;
++
++ for ( i = 1; i <= arg_cnt; i++ )
++ results[result_cnt - i] =
++ cf2_stack_popFixed( opStack );
++
++ break;
++ }
++ /* fall through */
++
++ Unexpected_OtherSubr:
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " invalid othersubr [%d %d]\n",
++ arg_cnt, subr_no ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++ }
++ continue; /* do not clear the stack */
++
++ case cf2_escPOP:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else
++ {
++ FT_TRACE4(( " pop" ));
++
++ if ( known_othersubr_result_cnt > 0 )
++ {
++ known_othersubr_result_cnt--;
++ /* ignore, we pushed the operands ourselves */
++ continue;
++ }
++
++ if ( result_cnt == 0 )
++ {
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " no more operands for othersubr\n" ));
++ lastError = FT_THROW( Invalid_Glyph_Format );
++ goto exit;
++ }
++
++ result_cnt--;
++ cf2_stack_pushFixed( opStack, results[result_cnt] );
++ }
++ continue; /* do not clear the stack */
++
+ case cf2_escDROP:
+ FT_TRACE4(( " drop\n" ));
+
+@@ -1433,6 +2356,48 @@
+ }
+ continue; /* do not clear the stack */
+
++ case cf2_escSETCURRENTPT:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
++ else
++ {
++ FT_TRACE4(( " setcurrentpoint" ));
++
++ if ( !initial_map_ready )
++ break;
++
++ /* From the T1 specification, section 6.4: */
++ /* */
++ /* The setcurrentpoint command is used only in */
++ /* conjunction with results from OtherSubrs */
++ /* procedures. */
++
++ /* known_othersubr_result_cnt != 0 is already handled */
++ /* above. */
++
++ /* Note, however, that both Ghostscript and Adobe */
++ /* Distiller handle this situation by silently */
++ /* ignoring the inappropriate `setcurrentpoint' */
++ /* instruction. So we do the same. */
++#if 0
++
++ if ( decoder->flex_state != 1 )
++ {
++ FT_ERROR(( "cf2_interpT2CharString:"
++ " unexpected `setcurrentpoint'\n" ));
++ goto Syntax_Error;
++ }
++ else
++ ...
++#endif
++
++ curY = cf2_stack_popFixed( opStack );
++ curX = cf2_stack_popFixed( opStack );
++
++ decoder->flex_state = 0;
++ }
++ break;
++
+ } /* end of 2nd switch checking op2 */
+ }
+ }
+@@ -1441,9 +2406,67 @@
+
+ break;
+
++ case cf2_cmdHSBW:
++ if ( !font->isT1 )
++ FT_TRACE4(( " unknown op (%d)\n", op1 ));
++ else
++ {
++ CF2_Fixed lsb_x;
++ PS_Builder* builder;
++
++
++ FT_TRACE4(( " hsbw" ));
++
++ builder = &decoder->builder;
++
++ builder->advance->x = cf2_stack_popFixed( opStack );
++ builder->advance->y = 0;
++
++ lsb_x = cf2_stack_popFixed( opStack );
++
++ builder->left_bearing->x = ADD_INT32( builder->left_bearing->x,
++ lsb_x );
++
++ haveWidth = TRUE;
++
++ /* the `metrics_only' indicates that we only want to compute */
++ /* the glyph's metrics (lsb + advance width), not load the */
++ /* rest of it; so exit immediately */
++ if ( builder->metrics_only )
++ goto exit;
++
++ if ( initial_map_ready )
++ curX = ADD_INT32( curX, lsb_x );
++ }
++ break;
++
+ case cf2_cmdENDCHAR:
+ FT_TRACE4(( " endchar\n" ));
+
++ if ( font->isT1 && !initial_map_ready )
++ {
++ FT_TRACE5(( "cf2_interpT2CharString (Type 1 mode): "
++ "Build initial hintmap, rewinding...\n" ));
++
++ /* trigger initial hintmap build */
++ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
++
++ initial_map_ready = TRUE;
++
++ /* change hints routine - clear for rewind */
++ cf2_arrstack_clear( &vStemHintArray );
++ cf2_arrstack_clear( &hStemHintArray );
++
++ cf2_hintmask_init( &hintMask, error );
++ hintMask.isValid = FALSE;
++ hintMask.isNew = TRUE;
++
++ /* rewind charstring */
++ charstring->ptr = charstring->start;
++
++ break;
++ }
++
+ if ( cf2_stack_count( opStack ) == 1 ||
+ cf2_stack_count( opStack ) == 5 )
+ {
+@@ -1455,14 +2478,15 @@
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ /* close path if still open */
+ cf2_glyphpath_closeOpenPath( &glyphPath );
+
+- /* disable seac for CFF2 (charstring ending with args on stack) */
+- if ( !font->isCFF2 && cf2_stack_count( opStack ) > 1 )
++ /* disable seac for CFF2 and Type1 */
++ /* (charstring ending with args on stack) */
++ if ( !font->isCFF2 && !font->isT1 && cf2_stack_count( opStack ) > 1 )
+ {
+ /* must be either 4 or 5 -- */
+ /* this is a (deprecated) implied `seac' operator */
+@@ -1543,7 +2567,7 @@
+ &haveWidth,
+ 0 );
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ if ( op1 == cf2_cmdHINTMASK )
+@@ -1596,6 +2620,10 @@
+ case cf2_cmdRMOVETO:
+ FT_TRACE4(( " rmoveto\n" ));
+
++ if ( font->isT1 && !decoder->flex_state && !haveWidth )
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " No width. Use hsbw/sbw as first op\n" ));
++
+ if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
+ *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
+ nominalWidthX );
+@@ -1603,19 +2631,24 @@
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
+ curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
+
+- cf2_glyphpath_moveTo( &glyphPath, curX, curY );
++ if ( !decoder->flex_state )
++ cf2_glyphpath_moveTo( &glyphPath, curX, curY );
+
+ break;
+
+ case cf2_cmdHMOVETO:
+ FT_TRACE4(( " hmoveto\n" ));
+
++ if ( font->isT1 && !decoder->flex_state && !haveWidth )
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " No width. Use hsbw/sbw as first op\n" ));
++
+ if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
+ *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
+ nominalWidthX );
+@@ -1623,7 +2656,7 @@
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+- if ( font->decoder->width_only )
++ if ( decoder->width_only )
+ goto exit;
+
+ curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
+@@ -1919,9 +2952,42 @@
+ ( byte3 << 8 ) |
+ byte4 );
+
+- FT_TRACE4(( " %.5f", v / 65536.0 ));
++ /*
++ * For Type 1:
++ *
++ * According to the specification, values > 32000 or < -32000
++ * must be followed by a `div' operator to make the result be
++ * in the range [-32000;32000]. We expect that the second
++ * argument of `div' is not a large number. Additionally, we
++ * don't handle stuff like `<large1> <large2> <num> div <num>
++ * div' or <large1> <large2> <num> div div'. This is probably
++ * not allowed anyway.
++ *
++ * <large> <num> <num>+ div is not checked but should not be
++ * allowed as the large value remains untouched.
++ *
++ */
++ if ( font->isT1 )
++ {
++ if ( v > 32000 || v < -32000 )
++ {
++ if ( large_int )
++ FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
++ " no `div' after large integer\n" ));
++ else
++ large_int = TRUE;
++ }
+
+- cf2_stack_pushFixed( opStack, v );
++ FT_TRACE4(( " %d", v ));
++
++ cf2_stack_pushInt( opStack, (CF2_Int)v );
++ }
++ else
++ {
++ FT_TRACE4(( " %.5fF", v / 65536.0 ));
++
++ cf2_stack_pushFixed( opStack, v );
++ }
+ }
+ }
+ continue; /* don't clear stack */
+diff --git a/src/cff/cf2intrp.h b/src/psaux/psintrp.h
+similarity index 95%
+rename from src/cff/cf2intrp.h
+rename to src/psaux/psintrp.h
+index ec030e8944..4790aaa302 100644
+--- a/src/cff/cf2intrp.h
++++ b/src/psaux/psintrp.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2font.h */
++/* psintrp.h */
+ /* */
+ /* Adobe's CFF Interpreter (specification). */
+ /* */
+@@ -36,12 +36,12 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2INTRP_H_
+-#define CF2INTRP_H_
++#ifndef PSINTRP_H_
++#define PSINTRP_H_
+
+
+-#include "cf2ft.h"
+-#include "cf2hints.h"
++#include "psft.h"
++#include "pshints.h"
+
+
+ FT_BEGIN_HEADER
+@@ -77,7 +77,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2INTRP_H_ */
++#endif /* PSINTRP_H_ */
+
+
+ /* END */
+diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
+index f04edea411..a88bcb78c9 100644
+--- a/src/psaux/psobjs.c
++++ b/src/psaux/psobjs.c
+@@ -20,6 +20,8 @@
+ #include FT_INTERNAL_POSTSCRIPT_AUX_H
+ #include FT_INTERNAL_DEBUG_H
+ #include FT_INTERNAL_CALC_H
++#include FT_CFF_DRIVER_H
++#include FT_TYPE1_DRIVER_H
+
+ #include "psobjs.h"
+ #include "psconv.h"
+@@ -1758,6 +1760,573 @@
+ }
+
+
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** CFF BUILDER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* cff_builder_init */
++ /* */
++ /* <Description> */
++ /* Initializes a given glyph builder. */
++ /* */
++ /* <InOut> */
++ /* builder :: A pointer to the glyph builder to initialize. */
++ /* */
++ /* <Input> */
++ /* face :: The current face object. */
++ /* */
++ /* size :: The current size object. */
++ /* */
++ /* glyph :: The current glyph object. */
++ /* */
++ /* hinting :: Whether hinting is active. */
++ /* */
++ FT_LOCAL_DEF( void )
++ cff_builder_init( CFF_Builder* builder,
++ TT_Face face,
++ CFF_Size size,
++ CFF_GlyphSlot glyph,
++ FT_Bool hinting )
++ {
++ builder->path_begun = 0;
++ builder->load_points = 1;
++
++ builder->face = face;
++ builder->glyph = glyph;
++ builder->memory = face->root.memory;
++
++ if ( glyph )
++ {
++ FT_GlyphLoader loader = glyph->root.internal->loader;
++
++
++ builder->loader = loader;
++ builder->base = &loader->base.outline;
++ builder->current = &loader->current.outline;
++ FT_GlyphLoader_Rewind( loader );
++
++ builder->hints_globals = NULL;
++ builder->hints_funcs = NULL;
++
++ if ( hinting && size )
++ {
++ FT_Size ftsize = FT_SIZE( size );
++ CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data;
++
++ if ( internal )
++ {
++ builder->hints_globals = (void *)internal->topfont;
++ builder->hints_funcs = glyph->root.internal->glyph_hints;
++ }
++ }
++ }
++
++ builder->pos_x = 0;
++ builder->pos_y = 0;
++
++ builder->left_bearing.x = 0;
++ builder->left_bearing.y = 0;
++ builder->advance.x = 0;
++ builder->advance.y = 0;
++
++ builder->funcs = cff_builder_funcs;
++ }
++
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* cff_builder_done */
++ /* */
++ /* <Description> */
++ /* Finalizes a given glyph builder. Its contents can still be used */
++ /* after the call, but the function saves important information */
++ /* within the corresponding glyph slot. */
++ /* */
++ /* <Input> */
++ /* builder :: A pointer to the glyph builder to finalize. */
++ /* */
++ FT_LOCAL_DEF( void )
++ cff_builder_done( CFF_Builder* builder )
++ {
++ CFF_GlyphSlot glyph = builder->glyph;
++
++
++ if ( glyph )
++ glyph->root.outline = *builder->base;
++ }
++
++
++ /* check that there is enough space for `count' more points */
++ FT_LOCAL_DEF( FT_Error )
++ cff_check_points( CFF_Builder* builder,
++ FT_Int count )
++ {
++ return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
++ }
++
++
++ /* add a new point, do not check space */
++ FT_LOCAL_DEF( void )
++ cff_builder_add_point( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y,
++ FT_Byte flag )
++ {
++ FT_Outline* outline = builder->current;
++
++
++ if ( builder->load_points )
++ {
++ FT_Vector* point = outline->points + outline->n_points;
++ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face );
++
++
++ if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
++ {
++ point->x = x >> 16;
++ point->y = y >> 16;
++ }
++ else
++#endif
++ {
++ /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
++ point->x = x >> 10;
++ point->y = y >> 10;
++ }
++ *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
++ }
++
++ outline->n_points++;
++ }
++
++
++ /* check space for a new on-curve point, then add it */
++ FT_LOCAL_DEF( FT_Error )
++ cff_builder_add_point1( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y )
++ {
++ FT_Error error;
++
++
++ error = cff_check_points( builder, 1 );
++ if ( !error )
++ cff_builder_add_point( builder, x, y, 1 );
++
++ return error;
++ }
++
++
++ /* check space for a new contour, then add it */
++ FT_LOCAL_DEF( FT_Error )
++ cff_builder_add_contour( CFF_Builder* builder )
++ {
++ FT_Outline* outline = builder->current;
++ FT_Error error;
++
++
++ if ( !builder->load_points )
++ {
++ outline->n_contours++;
++ return FT_Err_Ok;
++ }
++
++ error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
++ if ( !error )
++ {
++ if ( outline->n_contours > 0 )
++ outline->contours[outline->n_contours - 1] =
++ (short)( outline->n_points - 1 );
++
++ outline->n_contours++;
++ }
++
++ return error;
++ }
++
++
++ /* if a path was begun, add its first on-curve point */
++ FT_LOCAL_DEF( FT_Error )
++ cff_builder_start_point( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y )
++ {
++ FT_Error error = FT_Err_Ok;
++
++
++ /* test whether we are building a new contour */
++ if ( !builder->path_begun )
++ {
++ builder->path_begun = 1;
++ error = cff_builder_add_contour( builder );
++ if ( !error )
++ error = cff_builder_add_point1( builder, x, y );
++ }
++
++ return error;
++ }
++
++
++ /* close the current contour */
++ FT_LOCAL_DEF( void )
++ cff_builder_close_contour( CFF_Builder* builder )
++ {
++ FT_Outline* outline = builder->current;
++ FT_Int first;
++
++
++ if ( !outline )
++ return;
++
++ first = outline->n_contours <= 1
++ ? 0 : outline->contours[outline->n_contours - 2] + 1;
++
++ /* We must not include the last point in the path if it */
++ /* is located on the first point. */
++ if ( outline->n_points > 1 )
++ {
++ FT_Vector* p1 = outline->points + first;
++ FT_Vector* p2 = outline->points + outline->n_points - 1;
++ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
++
++
++ /* `delete' last point only if it coincides with the first */
++ /* point and if it is not a control point (which can happen). */
++ if ( p1->x == p2->x && p1->y == p2->y )
++ if ( *control == FT_CURVE_TAG_ON )
++ outline->n_points--;
++ }
++
++ if ( outline->n_contours > 0 )
++ {
++ /* Don't add contours only consisting of one point, i.e., */
++ /* check whether begin point and last point are the same. */
++ if ( first == outline->n_points - 1 )
++ {
++ outline->n_contours--;
++ outline->n_points--;
++ }
++ else
++ outline->contours[outline->n_contours - 1] =
++ (short)( outline->n_points - 1 );
++ }
++ }
++
++
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** PS BUILDER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* ps_builder_init */
++ /* */
++ /* <Description> */
++ /* Initializes a given glyph builder. */
++ /* */
++ /* <InOut> */
++ /* builder :: A pointer to the glyph builder to initialize. */
++ /* */
++ /* <Input> */
++ /* face :: The current face object. */
++ /* */
++ /* size :: The current size object. */
++ /* */
++ /* glyph :: The current glyph object. */
++ /* */
++ /* hinting :: Whether hinting should be applied. */
++ /* */
++ FT_LOCAL_DEF( void )
++ ps_builder_init( PS_Builder* ps_builder,
++ void* builder,
++ FT_Bool is_t1 )
++ {
++ FT_ZERO( ps_builder );
++
++ if ( is_t1 )
++ {
++ T1_Builder t1builder = (T1_Builder)builder;
++
++
++ ps_builder->memory = t1builder->memory;
++ ps_builder->face = (FT_Face)t1builder->face;
++ ps_builder->glyph = (CFF_GlyphSlot)t1builder->glyph;
++ ps_builder->loader = t1builder->loader;
++ ps_builder->base = t1builder->base;
++ ps_builder->current = t1builder->current;
++
++ ps_builder->pos_x = &t1builder->pos_x;
++ ps_builder->pos_y = &t1builder->pos_y;
++
++ ps_builder->left_bearing = &t1builder->left_bearing;
++ ps_builder->advance = &t1builder->advance;
++
++ ps_builder->bbox = &t1builder->bbox;
++ ps_builder->path_begun = 0;
++ ps_builder->load_points = t1builder->load_points;
++ ps_builder->no_recurse = t1builder->no_recurse;
++
++ ps_builder->metrics_only = t1builder->metrics_only;
++ }
++ else
++ {
++ CFF_Builder* cffbuilder = (CFF_Builder*)builder;
++
++
++ ps_builder->memory = cffbuilder->memory;
++ ps_builder->face = (FT_Face)cffbuilder->face;
++ ps_builder->glyph = cffbuilder->glyph;
++ ps_builder->loader = cffbuilder->loader;
++ ps_builder->base = cffbuilder->base;
++ ps_builder->current = cffbuilder->current;
++
++ ps_builder->pos_x = &cffbuilder->pos_x;
++ ps_builder->pos_y = &cffbuilder->pos_y;
++
++ ps_builder->left_bearing = &cffbuilder->left_bearing;
++ ps_builder->advance = &cffbuilder->advance;
++
++ ps_builder->bbox = &cffbuilder->bbox;
++ ps_builder->path_begun = cffbuilder->path_begun;
++ ps_builder->load_points = cffbuilder->load_points;
++ ps_builder->no_recurse = cffbuilder->no_recurse;
++
++ ps_builder->metrics_only = cffbuilder->metrics_only;
++ }
++
++ ps_builder->is_t1 = is_t1;
++ ps_builder->funcs = ps_builder_funcs;
++ }
++
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* ps_builder_done */
++ /* */
++ /* <Description> */
++ /* Finalizes a given glyph builder. Its contents can still be used */
++ /* after the call, but the function saves important information */
++ /* within the corresponding glyph slot. */
++ /* */
++ /* <Input> */
++ /* builder :: A pointer to the glyph builder to finalize. */
++ /* */
++ FT_LOCAL_DEF( void )
++ ps_builder_done( PS_Builder* builder )
++ {
++ CFF_GlyphSlot glyph = builder->glyph;
++
++
++ if ( glyph )
++ glyph->root.outline = *builder->base;
++ }
++
++
++ /* check that there is enough space for `count' more points */
++ FT_LOCAL_DEF( FT_Error )
++ ps_builder_check_points( PS_Builder* builder,
++ FT_Int count )
++ {
++ return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
++ }
++
++
++ /* add a new point, do not check space */
++ FT_LOCAL_DEF( void )
++ ps_builder_add_point( PS_Builder* builder,
++ FT_Pos x,
++ FT_Pos y,
++ FT_Byte flag )
++ {
++ FT_Outline* outline = builder->current;
++
++
++ if ( builder->load_points )
++ {
++ FT_Vector* point = outline->points + outline->n_points;
++ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
++
++#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face );
++
++
++ if ( !builder->is_t1 &&
++ driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
++ {
++ point->x = x >> 16;
++ point->y = y >> 16;
++ }
++ else
++#endif
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face );
++#endif
++ if ( builder->is_t1 &&
++ driver->hinting_engine == FT_T1_HINTING_FREETYPE )
++ {
++ point->x = FIXED_TO_INT( x );
++ point->y = FIXED_TO_INT( y );
++ }
++ else
++#endif
++ {
++ /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
++ point->x = x >> 10;
++ point->y = y >> 10;
++ }
++ *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
++ }
++ outline->n_points++;
++ }
++
++
++ /* check space for a new on-curve point, then add it */
++ FT_LOCAL_DEF( FT_Error )
++ ps_builder_add_point1( PS_Builder* builder,
++ FT_Pos x,
++ FT_Pos y )
++ {
++ FT_Error error;
++
++
++ error = ps_builder_check_points( builder, 1 );
++ if ( !error )
++ ps_builder_add_point( builder, x, y, 1 );
++
++ return error;
++ }
++
++
++ /* check space for a new contour, then add it */
++ FT_LOCAL_DEF( FT_Error )
++ ps_builder_add_contour( PS_Builder* builder )
++ {
++ FT_Outline* outline = builder->current;
++ FT_Error error;
++
++
++ /* this might happen in invalid fonts */
++ if ( !outline )
++ {
++ FT_ERROR(( "ps_builder_add_contour: no outline to add points to\n" ));
++ return FT_THROW( Invalid_File_Format );
++ }
++
++ if ( !builder->load_points )
++ {
++ outline->n_contours++;
++ return FT_Err_Ok;
++ }
++
++ error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
++ if ( !error )
++ {
++ if ( outline->n_contours > 0 )
++ outline->contours[outline->n_contours - 1] =
++ (short)( outline->n_points - 1 );
++
++ outline->n_contours++;
++ }
++
++ return error;
++ }
++
++
++ /* if a path was begun, add its first on-curve point */
++ FT_LOCAL_DEF( FT_Error )
++ ps_builder_start_point( PS_Builder* builder,
++ FT_Pos x,
++ FT_Pos y )
++ {
++ FT_Error error = FT_Err_Ok;
++
++
++ /* test whether we are building a new contour */
++ if ( !builder->path_begun )
++ {
++ builder->path_begun = 1;
++ error = ps_builder_add_contour( builder );
++ if ( !error )
++ error = ps_builder_add_point1( builder, x, y );
++ }
++
++ return error;
++ }
++
++
++ /* close the current contour */
++ FT_LOCAL_DEF( void )
++ ps_builder_close_contour( PS_Builder* builder )
++ {
++ FT_Outline* outline = builder->current;
++ FT_Int first;
++
++
++ if ( !outline )
++ return;
++
++ first = outline->n_contours <= 1
++ ? 0 : outline->contours[outline->n_contours - 2] + 1;
++
++ /* in malformed fonts it can happen that a contour was started */
++ /* but no points were added */
++ if ( outline->n_contours && first == outline->n_points )
++ {
++ outline->n_contours--;
++ return;
++ }
++
++ /* We must not include the last point in the path if it */
++ /* is located on the first point. */
++ if ( outline->n_points > 1 )
++ {
++ FT_Vector* p1 = outline->points + first;
++ FT_Vector* p2 = outline->points + outline->n_points - 1;
++ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
++
++
++ /* `delete' last point only if it coincides with the first */
++ /* point and it is not a control point (which can happen). */
++ if ( p1->x == p2->x && p1->y == p2->y )
++ if ( *control == FT_CURVE_TAG_ON )
++ outline->n_points--;
++ }
++
++ if ( outline->n_contours > 0 )
++ {
++ /* Don't add contours only consisting of one point, i.e., */
++ /* check whether the first and the last point is the same. */
++ if ( first == outline->n_points - 1 )
++ {
++ outline->n_contours--;
++ outline->n_points--;
++ }
++ else
++ outline->contours[outline->n_contours - 1] =
++ (short)( outline->n_points - 1 );
++ }
++ }
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+@@ -1766,6 +2335,177 @@
+ /*************************************************************************/
+ /*************************************************************************/
+
++
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* ps_decoder_init */
++ /* */
++ /* <Description> */
++ /* Creates a wrapper decoder for use in the combined */
++ /* Type 1 / CFF interpreter. */
++ /* */
++ /* <InOut> */
++ /* ps_decoder :: A pointer to the decoder to initialize. */
++ /* */
++ /* <Input> */
++ /* decoder :: A pointer to the original decoder. */
++ /* */
++ /* is_t1 :: Flag indicating Type 1 or CFF */
++ /* */
++ FT_LOCAL_DEF( void )
++ ps_decoder_init( PS_Decoder* ps_decoder,
++ void* decoder,
++ FT_Bool is_t1 )
++ {
++ FT_ZERO( ps_decoder );
++
++ if ( is_t1 )
++ {
++ T1_Decoder t1_decoder = (T1_Decoder)decoder;
++
++
++ ps_builder_init( &ps_decoder->builder,
++ &t1_decoder->builder,
++ is_t1 );
++
++ ps_decoder->cf2_instance = &t1_decoder->cf2_instance;
++ ps_decoder->psnames = t1_decoder->psnames;
++
++ ps_decoder->num_glyphs = t1_decoder->num_glyphs;
++ ps_decoder->glyph_names = t1_decoder->glyph_names;
++ ps_decoder->hint_mode = t1_decoder->hint_mode;
++ ps_decoder->blend = t1_decoder->blend;
++
++ ps_decoder->num_locals = (FT_UInt)t1_decoder->num_subrs;
++ ps_decoder->locals = t1_decoder->subrs;
++ ps_decoder->locals_len = t1_decoder->subrs_len;
++ ps_decoder->locals_hash = t1_decoder->subrs_hash;
++
++ ps_decoder->buildchar = t1_decoder->buildchar;
++ ps_decoder->len_buildchar = t1_decoder->len_buildchar;
++
++ ps_decoder->lenIV = t1_decoder->lenIV;
++ }
++ else
++ {
++ CFF_Decoder* cff_decoder = (CFF_Decoder*)decoder;
++
++
++ ps_builder_init( &ps_decoder->builder,
++ &cff_decoder->builder,
++ is_t1 );
++
++ ps_decoder->cff = cff_decoder->cff;
++ ps_decoder->cf2_instance = &cff_decoder->cff->cf2_instance;
++ ps_decoder->current_subfont = cff_decoder->current_subfont;
++
++ ps_decoder->num_globals = cff_decoder->num_globals;
++ ps_decoder->globals = cff_decoder->globals;
++ ps_decoder->globals_bias = cff_decoder->globals_bias;
++ ps_decoder->num_locals = cff_decoder->num_locals;
++ ps_decoder->locals = cff_decoder->locals;
++ ps_decoder->locals_bias = cff_decoder->locals_bias;
++
++ ps_decoder->glyph_width = cff_decoder->glyph_width;
++ ps_decoder->nominal_width = cff_decoder->nominal_width;
++ ps_decoder->width_only = cff_decoder->width_only;
++
++ ps_decoder->hint_mode = cff_decoder->hint_mode;
++
++ ps_decoder->get_glyph_callback = cff_decoder->get_glyph_callback;
++ ps_decoder->free_glyph_callback = cff_decoder->free_glyph_callback;
++ }
++ }
++
++
++ /* Synthesize a SubFont object for Type 1 fonts, for use in the */
++ /* new interpreter to access Private dict data. */
++ FT_LOCAL_DEF( void )
++ t1_make_subfont( FT_Face face,
++ PS_Private priv,
++ CFF_SubFont subfont )
++ {
++ CFF_Private cpriv = &subfont->private_dict;
++ FT_UInt n, count;
++
++
++ FT_ZERO( subfont );
++ FT_ZERO( cpriv );
++
++ count = cpriv->num_blue_values = priv->num_blue_values;
++ for ( n = 0; n < count; n++ )
++ cpriv->blue_values[n] = (FT_Pos)priv->blue_values[n];
++
++ count = cpriv->num_other_blues = priv->num_other_blues;
++ for ( n = 0; n < count; n++ )
++ cpriv->other_blues[n] = (FT_Pos)priv->other_blues[n];
++
++ count = cpriv->num_family_blues = priv->num_family_blues;
++ for ( n = 0; n < count; n++ )
++ cpriv->family_blues[n] = (FT_Pos)priv->family_blues[n];
++
++ count = cpriv->num_family_other_blues = priv->num_family_other_blues;
++ for ( n = 0; n < count; n++ )
++ cpriv->family_other_blues[n] = (FT_Pos)priv->family_other_blues[n];
++
++ cpriv->blue_scale = priv->blue_scale;
++ cpriv->blue_shift = (FT_Pos)priv->blue_shift;
++ cpriv->blue_fuzz = (FT_Pos)priv->blue_fuzz;
++
++ cpriv->standard_width = (FT_Pos)priv->standard_width[0];
++ cpriv->standard_height = (FT_Pos)priv->standard_height[0];
++
++ count = cpriv->num_snap_widths = priv->num_snap_widths;
++ for ( n = 0; n < count; n++ )
++ cpriv->snap_widths[n] = (FT_Pos)priv->snap_widths[n];
++
++ count = cpriv->num_snap_heights = priv->num_snap_heights;
++ for ( n = 0; n < count; n++ )
++ cpriv->snap_heights[n] = (FT_Pos)priv->snap_heights[n];
++
++ cpriv->force_bold = priv->force_bold;
++ cpriv->lenIV = priv->lenIV;
++ cpriv->language_group = priv->language_group;
++ cpriv->expansion_factor = priv->expansion_factor;
++
++ cpriv->subfont = subfont;
++
++
++ /* Initialize the random number generator. */
++ if ( face->internal->random_seed != -1 )
++ {
++ /* If we have a face-specific seed, use it. */
++ /* If non-zero, update it to a positive value. */
++ subfont->random = (FT_UInt32)face->internal->random_seed;
++ if ( face->internal->random_seed )
++ {
++ do
++ {
++ face->internal->random_seed = (FT_Int32)cff_random(
++ (FT_UInt32)face->internal->random_seed );
++
++ } while ( face->internal->random_seed < 0 );
++ }
++ }
++ if ( !subfont->random )
++ {
++ FT_UInt32 seed;
++
++
++ /* compute random seed from some memory addresses */
++ seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^
++ (FT_Offset)(char*)&face ^
++ (FT_Offset)(char*)&subfont );
++ seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
++ if ( seed == 0 )
++ seed = 0x7384;
++
++ subfont->random = seed;
++ }
++ }
++
++
+ FT_LOCAL_DEF( void )
+ t1_decrypt( FT_Byte* buffer,
+ FT_Offset length,
+@@ -1779,4 +2519,16 @@
+ }
+
+
++ FT_LOCAL_DEF( FT_UInt32 )
++ cff_random( FT_UInt32 r )
++ {
++ /* a 32bit version of the `xorshift' algorithm */
++ r ^= r << 13;
++ r ^= r >> 17;
++ r ^= r << 5;
++
++ return r;
++ }
++
++
+ /* END */
+diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h
+index 202e5b2416..08fd4fc7f5 100644
+--- a/src/psaux/psobjs.h
++++ b/src/psaux/psobjs.h
+@@ -22,6 +22,7 @@
+
+ #include <ft2build.h>
+ #include FT_INTERNAL_POSTSCRIPT_AUX_H
++#include FT_INTERNAL_CFF_OBJECTS_TYPES_H
+
+
+ FT_BEGIN_HEADER
+@@ -190,6 +191,92 @@ FT_BEGIN_HEADER
+ t1_builder_close_contour( T1_Builder builder );
+
+
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** CFF BUILDER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++ FT_LOCAL( void )
++ cff_builder_init( CFF_Builder* builder,
++ TT_Face face,
++ CFF_Size size,
++ CFF_GlyphSlot glyph,
++ FT_Bool hinting );
++
++ FT_LOCAL( void )
++ cff_builder_done( CFF_Builder* builder );
++
++ FT_LOCAL( FT_Error )
++ cff_check_points( CFF_Builder* builder,
++ FT_Int count );
++
++ FT_LOCAL( void )
++ cff_builder_add_point( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y,
++ FT_Byte flag );
++ FT_LOCAL( FT_Error )
++ cff_builder_add_point1( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y );
++ FT_LOCAL( FT_Error )
++ cff_builder_start_point( CFF_Builder* builder,
++ FT_Pos x,
++ FT_Pos y );
++ FT_LOCAL( void )
++ cff_builder_close_contour( CFF_Builder* builder );
++
++ FT_LOCAL( FT_Error )
++ cff_builder_add_contour( CFF_Builder* builder );
++
++
++ /*************************************************************************/
++ /*************************************************************************/
++ /***** *****/
++ /***** PS BUILDER *****/
++ /***** *****/
++ /*************************************************************************/
++ /*************************************************************************/
++
++ FT_LOCAL( void )
++ ps_builder_init( PS_Builder* ps_builder,
++ void* builder,
++ FT_Bool is_t1 );
++
++
++ FT_LOCAL( void )
++ ps_builder_done( PS_Builder* builder );
++
++ FT_LOCAL( FT_Error )
++ ps_builder_check_points( PS_Builder* builder,
++ FT_Int count );
++
++ FT_LOCAL( void )
++ ps_builder_add_point( PS_Builder* builder,
++ FT_Pos x,
++ FT_Pos y,
++ FT_Byte flag );
++
++ FT_LOCAL( FT_Error )
++ ps_builder_add_point1( PS_Builder* builder,
++ FT_Pos x,
++ FT_Pos y );
++
++ FT_LOCAL( FT_Error )
++ ps_builder_add_contour( PS_Builder* builder );
++
++ FT_LOCAL( FT_Error )
++ ps_builder_start_point( PS_Builder* builder,
++ FT_Pos x,
++ FT_Pos y );
++
++ FT_LOCAL( void )
++ ps_builder_close_contour( PS_Builder* builder );
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+@@ -198,12 +285,26 @@ FT_BEGIN_HEADER
+ /*************************************************************************/
+ /*************************************************************************/
+
++ FT_LOCAL( void )
++ ps_decoder_init( PS_Decoder* ps_decoder,
++ void* decoder,
++ FT_Bool is_t1 );
++
++ FT_LOCAL( void )
++ t1_make_subfont( FT_Face face,
++ PS_Private priv,
++ CFF_SubFont subfont );
++
+ FT_LOCAL( void )
+ t1_decrypt( FT_Byte* buffer,
+ FT_Offset length,
+ FT_UShort seed );
+
+
++ FT_LOCAL( FT_UInt32 )
++ cff_random( FT_UInt32 r );
++
++
+ FT_END_HEADER
+
+ #endif /* PSOBJS_H_ */
+diff --git a/src/cff/cf2read.c b/src/psaux/psread.c
+similarity index 97%
+rename from src/cff/cf2read.c
+rename to src/psaux/psread.c
+index 2b429e3eeb..719863ce17 100644
+--- a/src/cff/cf2read.c
++++ b/src/psaux/psread.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2read.c */
++/* psread.c */
+ /* */
+ /* Adobe's code for stream handling (body). */
+ /* */
+@@ -36,12 +36,12 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
+
+-#include "cf2glue.h"
++#include "psglue.h"
+
+-#include "cf2error.h"
++#include "pserror.h"
+
+
+ /* Define CF2_IO_FAIL as 1 to enable random errors and random */
+diff --git a/src/cff/cf2read.h b/src/psaux/psread.h
+similarity index 96%
+rename from src/cff/cf2read.h
+rename to src/psaux/psread.h
+index b0b0db803a..464b29ba74 100644
+--- a/src/cff/cf2read.h
++++ b/src/psaux/psread.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2read.h */
++/* psread.h */
+ /* */
+ /* Adobe's code for stream handling (specification). */
+ /* */
+@@ -36,8 +36,8 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2READ_H_
+-#define CF2READ_H_
++#ifndef PSREAD_H_
++#define PSREAD_H_
+
+
+ FT_BEGIN_HEADER
+@@ -62,7 +62,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2READ_H_ */
++#endif /* PSREAD_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2stack.c b/src/psaux/psstack.c
+similarity index 98%
+rename from src/cff/cf2stack.c
+rename to src/psaux/psstack.c
+index 12a026d21d..69d063349a 100644
+--- a/src/cff/cf2stack.c
++++ b/src/psaux/psstack.c
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2stack.c */
++/* psstack.c */
+ /* */
+ /* Adobe's code for emulating a CFF stack (body). */
+ /* */
+@@ -36,14 +36,14 @@
+ /***************************************************************************/
+
+
+-#include "cf2ft.h"
++#include "psft.h"
+ #include FT_INTERNAL_DEBUG_H
+
+-#include "cf2glue.h"
+-#include "cf2font.h"
+-#include "cf2stack.h"
++#include "psglue.h"
++#include "psfont.h"
++#include "psstack.h"
+
+-#include "cf2error.h"
++#include "pserror.h"
+
+
+ /* Allocate and initialize an instance of CF2_Stack. */
+diff --git a/src/cff/cf2stack.h b/src/psaux/psstack.h
+similarity index 97%
+rename from src/cff/cf2stack.h
+rename to src/psaux/psstack.h
+index ef08eefe41..38f7b41c68 100644
+--- a/src/cff/cf2stack.h
++++ b/src/psaux/psstack.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2stack.h */
++/* psstack.h */
+ /* */
+ /* Adobe's code for emulating a CFF stack (specification). */
+ /* */
+@@ -36,8 +36,8 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2STACK_H_
+-#define CF2STACK_H_
++#ifndef PSSTACK_H_
++#define PSSTACK_H_
+
+
+ FT_BEGIN_HEADER
+@@ -115,7 +115,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2STACK_H_ */
++#endif /* PSSTACK_H_ */
+
+
+ /* END */
+diff --git a/src/cff/cf2types.h b/src/psaux/pstypes.h
+similarity index 96%
+rename from src/cff/cf2types.h
+rename to src/psaux/pstypes.h
+index 5b7e1239af..dfbaa3d475 100644
+--- a/src/cff/cf2types.h
++++ b/src/psaux/pstypes.h
+@@ -1,6 +1,6 @@
+ /***************************************************************************/
+ /* */
+-/* cf2types.h */
++/* pstypes.h */
+ /* */
+ /* Adobe's code for defining data types (specification only). */
+ /* */
+@@ -36,8 +36,8 @@
+ /***************************************************************************/
+
+
+-#ifndef CF2TYPES_H_
+-#define CF2TYPES_H_
++#ifndef PSTYPES_H_
++#define PSTYPES_H_
+
+ #include <ft2build.h>
+ #include FT_FREETYPE_H
+@@ -72,7 +72,7 @@ FT_BEGIN_HEADER
+ FT_END_HEADER
+
+
+-#endif /* CF2TYPES_H_ */
++#endif /* PSTYPES_H_ */
+
+
+ /* END */
+diff --git a/src/psaux/rules.mk b/src/psaux/rules.mk
+index 542ae12d2b..266d446f86 100644
+--- a/src/psaux/rules.mk
++++ b/src/psaux/rules.mk
+@@ -33,12 +33,25 @@ PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \
+ $(PSAUX_DIR)/t1cmap.c \
+ $(PSAUX_DIR)/afmparse.c \
+ $(PSAUX_DIR)/psconv.c \
+- $(PSAUX_DIR)/psauxmod.c
++ $(PSAUX_DIR)/psauxmod.c \
++ $(PSAUX_DIR)/psarrst.c \
++ $(PSAUX_DIR)/psblues.c \
++ $(PSAUX_DIR)/pserror.c \
++ $(PSAUX_DIR)/psfont.c \
++ $(PSAUX_DIR)/psft.c \
++ $(PSAUX_DIR)/pshints.c \
++ $(PSAUX_DIR)/psintrp.c \
++ $(PSAUX_DIR)/psread.c \
++ $(PSAUX_DIR)/psstack.c \
++ $(PSAUX_DIR)/cffdecode.c
+
+ # PSAUX driver headers
+ #
+ PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \
+- $(PSAUX_DIR)/psauxerr.h
++ $(PSAUX_DIR)/psauxerr.h \
++ $(PSAUX_DIR)/psfixed.h \
++ $(PSAUX_DIR)/psglue.h \
++ $(PSAUX_DIR)/pstypes.h
+
+
+ # PSAUX driver object(s)
+diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
+index 1250b53f5d..03183c8e0a 100644
+--- a/src/psaux/t1decode.c
++++ b/src/psaux/t1decode.c
+@@ -109,6 +109,56 @@
+ };
+
+
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* t1_lookup_glyph_by_stdcharcode_ps */
++ /* */
++ /* <Description> */
++ /* Looks up a given glyph by its StandardEncoding charcode. Used to */
++ /* implement the SEAC Type 1 operator in the Adobe engine */
++ /* */
++ /* <Input> */
++ /* face :: The current face object. */
++ /* */
++ /* charcode :: The character code to look for. */
++ /* */
++ /* <Return> */
++ /* A glyph index in the font face. Returns -1 if the corresponding */
++ /* glyph wasn't found. */
++ /* */
++ FT_LOCAL_DEF( FT_Int )
++ t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder,
++ FT_Int charcode )
++ {
++ FT_UInt n;
++ const FT_String* glyph_name;
++ FT_Service_PsCMaps psnames = decoder->psnames;
++
++
++ /* check range of standard char code */
++ if ( charcode < 0 || charcode > 255 )
++ return -1;
++
++ glyph_name = psnames->adobe_std_strings(
++ psnames->adobe_std_encoding[charcode]);
++
++ for ( n = 0; n < decoder->num_glyphs; n++ )
++ {
++ FT_String* name = (FT_String*)decoder->glyph_names[n];
++
++
++ if ( name &&
++ name[0] == glyph_name[0] &&
++ ft_strcmp( name, glyph_name ) == 0 )
++ return (FT_Int)n;
++ }
++
++ return -1;
++ }
++
++
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+@@ -158,6 +208,15 @@
+ }
+
+
++ /* parse a single Type 1 glyph */
++ FT_LOCAL_DEF( FT_Error )
++ t1_decoder_parse_glyph( T1_Decoder decoder,
++ FT_UInt glyph )
++ {
++ return decoder->parse_callback( decoder, glyph );
++ }
++
++
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+@@ -1579,14 +1638,286 @@
+ return FT_THROW( Stack_Underflow );
+ }
+
++#else /* T1_CONFIG_OPTION_OLD_ENGINE */
+
+- /* parse a single Type 1 glyph */
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* t1_decoder_parse_metrics */
++ /* */
++ /* <Description> */
++ /* Parses a given Type 1 charstrings program to extract width */
++ /* */
++ /* <Input> */
++ /* decoder :: The current Type 1 decoder. */
++ /* */
++ /* charstring_base :: The base address of the charstring stream. */
++ /* */
++ /* charstring_len :: The length in bytes of the charstring stream. */
++ /* */
++ /* <Return> */
++ /* FreeType error code. 0 means success. */
++ /* */
+ FT_LOCAL_DEF( FT_Error )
+- t1_decoder_parse_glyph( T1_Decoder decoder,
+- FT_UInt glyph )
++ t1_decoder_parse_metrics( T1_Decoder decoder,
++ FT_Byte* charstring_base,
++ FT_UInt charstring_len )
+ {
+- return decoder->parse_callback( decoder, glyph );
++ T1_Decoder_Zone zone;
++ FT_Byte* ip;
++ FT_Byte* limit;
++ T1_Builder builder = &decoder->builder;
++
++#ifdef FT_DEBUG_LEVEL_TRACE
++ FT_Bool bol = TRUE;
++#endif
++
++
++ /* First of all, initialize the decoder */
++ decoder->top = decoder->stack;
++ decoder->zone = decoder->zones;
++ zone = decoder->zones;
++
++ builder->parse_state = T1_Parse_Start;
++
++ FT_TRACE4(( "\n"
++ "Start charstring: get width\n" ));
++
++ zone->base = charstring_base;
++ limit = zone->limit = charstring_base + charstring_len;
++ ip = zone->cursor = zone->base;
++
++ /* now, execute loop */
++ while ( ip < limit )
++ {
++ FT_Long* top = decoder->top;
++ T1_Operator op = op_none;
++ FT_Int32 value = 0;
++
++
++#ifdef FT_DEBUG_LEVEL_TRACE
++ if ( bol )
++ {
++ FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
++ bol = FALSE;
++ }
++#endif
++
++ /*********************************************************************/
++ /* */
++ /* Decode operator or operand */
++ /* */
++ /* */
++
++ /* first of all, decompress operator or value */
++ switch ( *ip++ )
++ {
++ case 1:
++ case 3:
++ case 4:
++ case 5:
++ case 6:
++ case 7:
++ case 8:
++ case 9:
++ case 10:
++ case 11:
++ case 14:
++ case 15:
++ case 21:
++ case 22:
++ case 30:
++ case 31:
++ goto No_Width;
++
++ case 13:
++ op = op_hsbw;
++ break;
++
++ case 12:
++ if ( ip >= limit )
++ {
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " invalid escape (12+EOF)\n" ));
++ goto Syntax_Error;
++ }
++
++ switch ( *ip++ )
++ {
++ case 7:
++ op = op_sbw;
++ break;
++
++ default:
++ goto No_Width;
++ }
++ break;
++
++ case 255: /* four bytes integer */
++ if ( ip + 4 > limit )
++ {
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " unexpected EOF in integer\n" ));
++ goto Syntax_Error;
++ }
++
++ value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
++ ( (FT_UInt32)ip[1] << 16 ) |
++ ( (FT_UInt32)ip[2] << 8 ) |
++ (FT_UInt32)ip[3] );
++ ip += 4;
++
++ /* According to the specification, values > 32000 or < -32000 must */
++ /* be followed by a `div' operator to make the result be in the */
++ /* range [-32000;32000]. We expect that the second argument of */
++ /* `div' is not a large number. Additionally, we don't handle */
++ /* stuff like `<large1> <large2> <num> div <num> div' or */
++ /* <large1> <large2> <num> div div'. This is probably not allowed */
++ /* anyway. */
++ if ( value > 32000 || value < -32000 )
++ {
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " large integer found for width\n" ));
++ goto Syntax_Error;
++ }
++ else
++ {
++ value = (FT_Int32)( (FT_UInt32)value << 16 );
++ }
++
++ break;
++
++ default:
++ if ( ip[-1] >= 32 )
++ {
++ if ( ip[-1] < 247 )
++ value = (FT_Int32)ip[-1] - 139;
++ else
++ {
++ if ( ++ip > limit )
++ {
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " unexpected EOF in integer\n" ));
++ goto Syntax_Error;
++ }
++
++ if ( ip[-2] < 251 )
++ value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
++ else
++ value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
++ }
++
++ value = (FT_Int32)( (FT_UInt32)value << 16 );
++ }
++ else
++ {
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " invalid byte (%d)\n", ip[-1] ));
++ goto Syntax_Error;
++ }
++ }
++
++ /*********************************************************************/
++ /* */
++ /* Push value on stack, or process operator */
++ /* */
++ /* */
++ if ( op == op_none )
++ {
++ if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
++ {
++ FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
++ goto Syntax_Error;
++ }
++
++#ifdef FT_DEBUG_LEVEL_TRACE
++ FT_TRACE4(( " %d", value / 65536 ));
++#endif
++
++ *top++ = value;
++ decoder->top = top;
++ }
++ else /* general operator */
++ {
++ FT_Int num_args = t1_args_count[op];
++
++
++ FT_ASSERT( num_args >= 0 );
++
++ if ( top - decoder->stack < num_args )
++ goto Stack_Underflow;
++
++#ifdef FT_DEBUG_LEVEL_TRACE
++
++ if ( top - decoder->stack != num_args )
++ FT_TRACE0(( "t1_decoder_parse_metrics:"
++ " too much operands on the stack"
++ " (seen %d, expected %d)\n",
++ top - decoder->stack, num_args ));
++
++#endif /* FT_DEBUG_LEVEL_TRACE */
++
++ top -= num_args;
++
++ switch ( op )
++ {
++ case op_hsbw:
++ FT_TRACE4(( " hsbw" ));
++
++ builder->parse_state = T1_Parse_Have_Width;
++
++ builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
++ top[0] );
++
++ builder->advance.x = top[1];
++ builder->advance.y = 0;
++
++ /* we only want to compute the glyph's metrics */
++ /* (lsb + advance width), not load the rest of */
++ /* it; so exit immediately */
++ return FT_Err_Ok;
++
++ case op_sbw:
++ FT_TRACE4(( " sbw" ));
++
++ builder->parse_state = T1_Parse_Have_Width;
++
++ builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
++ top[0] );
++ builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
++ top[1] );
++
++ builder->advance.x = top[2];
++ builder->advance.y = top[3];
++
++ /* we only want to compute the glyph's metrics */
++ /* (lsb + advance width), not load the rest of */
++ /* it; so exit immediately */
++ return FT_Err_Ok;
++
++ default:
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " unhandled opcode %d\n", op ));
++ goto Syntax_Error;
++ }
++
++ } /* general operator processing */
++
++ } /* while ip < limit */
++
++ FT_TRACE4(( "..end..\n\n" ));
++
++ No_Width:
++ FT_ERROR(( "t1_decoder_parse_metrics:"
++ " no width, found op %d instead\n",
++ ip[-1] ));
++ Syntax_Error:
++ return FT_THROW( Syntax_Error );
++
++ Stack_Underflow:
++ return FT_THROW( Stack_Underflow );
+ }
++#endif /* T1_CONFIG_OPTION_OLD_ENGINE */
+
+
+ /* initialize T1 decoder */
+@@ -1641,7 +1972,16 @@
+ FT_LOCAL_DEF( void )
+ t1_decoder_done( T1_Decoder decoder )
+ {
++ FT_Memory memory = decoder->builder.memory;
++
++
+ t1_builder_done( &decoder->builder );
++
++ if ( decoder->cf2_instance.finalizer )
++ {
++ decoder->cf2_instance.finalizer( decoder->cf2_instance.data );
++ FT_FREE( decoder->cf2_instance.data );
++ }
+ }
+
+
+diff --git a/src/psaux/t1decode.h b/src/psaux/t1decode.h
+index 12c27de775..879f8f999a 100644
+--- a/src/psaux/t1decode.h
++++ b/src/psaux/t1decode.h
+@@ -31,7 +31,11 @@ FT_BEGIN_HEADER
+ FT_CALLBACK_TABLE
+ const T1_Decoder_FuncsRec t1_decoder_funcs;
+
++ FT_LOCAL( FT_Int )
++ t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder,
++ FT_Int charcode );
+
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
+ FT_LOCAL( FT_Error )
+ t1_decoder_parse_glyph( T1_Decoder decoder,
+ FT_UInt glyph_index );
+@@ -40,6 +44,12 @@ FT_BEGIN_HEADER
+ t1_decoder_parse_charstrings( T1_Decoder decoder,
+ FT_Byte* base,
+ FT_UInt len );
++#else
++ FT_LOCAL( FT_Error )
++ t1_decoder_parse_metrics( T1_Decoder decoder,
++ FT_Byte* charstring_base,
++ FT_UInt charstring_len );
++#endif
+
+ FT_LOCAL( FT_Error )
+ t1_decoder_init( T1_Decoder decoder,
+diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
+index 185a7f6fc2..ede49167e1 100644
+--- a/src/raster/ftrend1.c
++++ b/src/raster/ftrend1.c
+@@ -97,12 +97,12 @@
+ FT_Render_Mode mode,
+ const FT_Vector* origin )
+ {
+- FT_Error error;
+- FT_Outline* outline;
+- FT_BBox cbox, cbox0;
+- FT_UInt width, height, pitch;
+- FT_Bitmap* bitmap;
+- FT_Memory memory;
++ FT_Error error = FT_Err_Ok;
++ FT_Outline* outline = &slot->outline;
++ FT_Bitmap* bitmap = &slot->bitmap;
++ FT_Memory memory = render->root.memory;
++ FT_Pos x_shift = 0;
++ FT_Pos y_shift = 0;
+
+ FT_Raster_Params params;
+
+@@ -121,60 +121,6 @@
+ return FT_THROW( Cannot_Render_Glyph );
+ }
+
+- outline = &slot->outline;
+-
+- /* translate the outline to the new origin if needed */
+- if ( origin )
+- FT_Outline_Translate( outline, origin->x, origin->y );
+-
+- /* compute the control box, and grid fit it */
+- FT_Outline_Get_CBox( outline, &cbox0 );
+-
+- /* undocumented but confirmed: bbox values get rounded */
+-#if 1
+- cbox.xMin = FT_PIX_ROUND( cbox0.xMin );
+- cbox.yMin = FT_PIX_ROUND( cbox0.yMin );
+- cbox.xMax = FT_PIX_ROUND( cbox0.xMax );
+- cbox.yMax = FT_PIX_ROUND( cbox0.yMax );
+-#else
+- cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
+- cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
+- cbox.xMax = FT_PIX_CEIL( cbox.xMax );
+- cbox.yMax = FT_PIX_CEIL( cbox.yMax );
+-#endif
+-
+- /* If either `width' or `height' round to 0, try */
+- /* explicitly rounding up/down. In the case of */
+- /* glyphs containing only one very narrow feature, */
+- /* this gives the drop-out compensation in the scan */
+- /* conversion code a chance to do its stuff. */
+- width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
+- if ( width == 0 )
+- {
+- cbox.xMin = FT_PIX_FLOOR( cbox0.xMin );
+- cbox.xMax = FT_PIX_CEIL( cbox0.xMax );
+-
+- width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
+- }
+-
+- height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
+- if ( height == 0 )
+- {
+- cbox.yMin = FT_PIX_FLOOR( cbox0.yMin );
+- cbox.yMax = FT_PIX_CEIL( cbox0.yMax );
+-
+- height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
+- }
+-
+- if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX )
+- {
+- error = FT_THROW( Invalid_Argument );
+- goto Exit;
+- }
+-
+- bitmap = &slot->bitmap;
+- memory = render->root.memory;
+-
+ /* release old bitmap buffer */
+ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+ {
+@@ -182,39 +128,48 @@
+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+ }
+
+- pitch = ( ( width + 15 ) >> 4 ) << 1;
+- bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
+-
+- bitmap->width = width;
+- bitmap->rows = height;
+- bitmap->pitch = (int)pitch;
++ ft_glyphslot_preset_bitmap( slot, mode, origin );
+
+- if ( FT_ALLOC_MULT( bitmap->buffer, height, pitch ) )
++ /* allocate new one */
++ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
+ goto Exit;
+
+ slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+
++ x_shift = -slot->bitmap_left * 64;
++ y_shift = ( (FT_Int)bitmap->rows - slot->bitmap_top ) * 64;
++
++ if ( origin )
++ {
++ x_shift += origin->x;
++ y_shift += origin->y;
++ }
++
+ /* translate outline to render it into the bitmap */
+- FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin );
++ if ( x_shift || y_shift )
++ FT_Outline_Translate( outline, x_shift, y_shift );
+
+ /* set up parameters */
+ params.target = bitmap;
+ params.source = outline;
+- params.flags = 0;
++ params.flags = FT_RASTER_FLAG_DEFAULT;
+
+ /* render outline into the bitmap */
+ error = render->raster_render( render->raster, ¶ms );
+
+- FT_Outline_Translate( outline, cbox.xMin, cbox.yMin );
+-
+- if ( error )
+- goto Exit;
++ Exit:
++ if ( !error )
++ /* everything is fine; the glyph is now officially a bitmap */
++ slot->format = FT_GLYPH_FORMAT_BITMAP;
++ else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
++ {
++ FT_FREE( bitmap->buffer );
++ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
++ }
+
+- slot->format = FT_GLYPH_FORMAT_BITMAP;
+- slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 );
+- slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 );
++ if ( x_shift || y_shift )
++ FT_Outline_Translate( outline, -x_shift, -y_shift );
+
+- Exit:
+ return error;
+ }
+
+diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
+index 560db4835a..4c0d00705f 100644
+--- a/src/sfnt/pngshim.c
++++ b/src/sfnt/pngshim.c
+@@ -82,42 +82,45 @@
+ typedef unsigned short v82 __attribute__(( vector_size( 16 ) ));
+
+
+- /* process blocks of 16 bytes in one rush, which gives a nice speed-up */
+- limit = row_info->rowbytes - 16 + 1;
+- for ( ; i < limit; i += 16 )
++ if ( row_info->rowbytes > 15 )
+ {
+- unsigned char* base = &data[i];
++ /* process blocks of 16 bytes in one rush, which gives a nice speed-up */
++ limit = row_info->rowbytes - 16 + 1;
++ for ( ; i < limit; i += 16 )
++ {
++ unsigned char* base = &data[i];
+
+- v82 s, s0, s1, a;
++ v82 s, s0, s1, a;
+
+- /* clang <= 3.9 can't apply scalar values to vectors */
+- /* (or rather, it needs a different syntax) */
+- v82 n0x80 = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
+- v82 n0xFF = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+- v82 n8 = { 8, 8, 8, 8, 8, 8, 8, 8 };
++ /* clang <= 3.9 can't apply scalar values to vectors */
++ /* (or rather, it needs a different syntax) */
++ v82 n0x80 = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
++ v82 n0xFF = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
++ v82 n8 = { 8, 8, 8, 8, 8, 8, 8, 8 };
+
+- v82 ma = { 1, 1, 3, 3, 5, 5, 7, 7 };
+- v82 o1 = { 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF };
+- v82 m0 = { 1, 0, 3, 2, 5, 4, 7, 6 };
++ v82 ma = { 1, 1, 3, 3, 5, 5, 7, 7 };
++ v82 o1 = { 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF };
++ v82 m0 = { 1, 0, 3, 2, 5, 4, 7, 6 };
+
+
+- memcpy( &s, base, 16 ); /* RGBA RGBA RGBA RGBA */
+- s0 = s & n0xFF; /* R B R B R B R B */
+- s1 = s >> n8; /* G A G A G A G A */
++ memcpy( &s, base, 16 ); /* RGBA RGBA RGBA RGBA */
++ s0 = s & n0xFF; /* R B R B R B R B */
++ s1 = s >> n8; /* G A G A G A G A */
+
+- a = vector_shuffle( s1, ma ); /* A A A A A A A A */
+- s1 |= o1; /* G 1 G 1 G 1 G 1 */
+- s0 = vector_shuffle( s0, m0 ); /* B R B R B R B R */
++ a = vector_shuffle( s1, ma ); /* A A A A A A A A */
++ s1 |= o1; /* G 1 G 1 G 1 G 1 */
++ s0 = vector_shuffle( s0, m0 ); /* B R B R B R B R */
+
+- s0 *= a;
+- s1 *= a;
+- s0 += n0x80;
+- s1 += n0x80;
+- s0 = ( s0 + ( s0 >> n8 ) ) >> n8;
+- s1 = ( s1 + ( s1 >> n8 ) ) >> n8;
++ s0 *= a;
++ s1 *= a;
++ s0 += n0x80;
++ s1 += n0x80;
++ s0 = ( s0 + ( s0 >> n8 ) ) >> n8;
++ s1 = ( s1 + ( s1 >> n8 ) ) >> n8;
+
+- s = s0 | ( s1 << n8 );
+- memcpy( base, &s, 16 );
++ s = s0 | ( s1 << n8 );
++ memcpy( base, &s, 16 );
++ }
+ }
+ #endif /* use `vector_size' */
+
+diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
+index 991433ee4c..293306717d 100644
+--- a/src/sfnt/sfdriver.c
++++ b/src/sfnt/sfdriver.c
+@@ -862,7 +862,8 @@
+ NULL,
+ &mm_var );
+
+- if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
++ if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) &&
++ !FT_IS_VARIATION( FT_FACE( face ) ) )
+ {
+ SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+
+@@ -1029,7 +1030,9 @@
+ return face->postscript_name;
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+- if ( face->blend )
++ if ( face->blend &&
++ ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
++ FT_IS_VARIATION( FT_FACE( face ) ) ) )
+ {
+ face->postscript_name = sfnt_get_var_ps_name( face );
+ return face->postscript_name;
+diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
+index 69bf0a5c3d..1764807c62 100644
+--- a/src/sfnt/sfobjs.c
++++ b/src/sfnt/sfobjs.c
+@@ -962,8 +962,6 @@
+ FT_Byte* instance_values = NULL;
+
+
+- face->is_default_instance = 1;
+-
+ instance_index = FT_ABS( face_instance_index ) >> 16;
+
+ /* test whether current face is a GX font with named instances */
+diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
+index df99baa53e..23c8e7df90 100644
+--- a/src/sfnt/ttload.c
++++ b/src/sfnt/ttload.c
+@@ -338,7 +338,7 @@
+ SFNT_HeaderRec sfnt;
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+- FT_UShort nn, valid_entries;
++ FT_UShort nn, valid_entries = 0;
+
+ static const FT_Frame_Field offset_table_fields[] =
+ {
+diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
+index df645e66c9..e84e38d85f 100644
+--- a/src/smooth/ftgrays.c
++++ b/src/smooth/ftgrays.c
+@@ -1300,8 +1300,6 @@ typedef ptrdiff_t FT_PtrDist;
+ int y;
+
+
+- FT_TRACE7(( "gray_sweep: start\n" ));
+-
+ for ( y = ras.min_ey; y < ras.max_ey; y++ )
+ {
+ PCell cell = ras.ycells[y - ras.min_ey];
+@@ -1327,8 +1325,6 @@ typedef ptrdiff_t FT_PtrDist;
+ if ( cover != 0 )
+ gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
+ }
+-
+- FT_TRACE7(( "gray_sweep: end\n" ));
+ }
+
+
+diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
+index 963435de15..82627462e8 100644
+--- a/src/smooth/ftsmooth.c
++++ b/src/smooth/ftsmooth.c
+@@ -97,74 +97,17 @@
+ const FT_Vector* origin,
+ FT_Render_Mode required_mode )
+ {
+- FT_Error error;
++ FT_Error error = FT_Err_Ok;
+ FT_Outline* outline = &slot->outline;
+ FT_Bitmap* bitmap = &slot->bitmap;
+ FT_Memory memory = render->root.memory;
+- FT_BBox cbox;
+ FT_Pos x_shift = 0;
+ FT_Pos y_shift = 0;
+- FT_Pos x_left, y_top;
+- FT_Pos width, height, pitch;
+ FT_Int hmul = ( mode == FT_RENDER_MODE_LCD );
+ FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V );
+
+ FT_Raster_Params params;
+
+- FT_Bool have_outline_shifted = FALSE;
+- FT_Bool have_buffer = FALSE;
+-
+-#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+-
+- FT_LcdFiveTapFilter lcd_weights = { 0 };
+- FT_Bool have_custom_weight = FALSE;
+- FT_Bitmap_LcdFilterFunc lcd_filter_func = NULL;
+-
+-
+- if ( slot->face )
+- {
+- FT_Char i;
+-
+-
+- for ( i = 0; i < FT_LCD_FILTER_FIVE_TAPS; i++ )
+- if ( slot->face->internal->lcd_weights[i] != 0 )
+- {
+- have_custom_weight = TRUE;
+- break;
+- }
+- }
+-
+- /*
+- * The LCD filter can be set library-wide and per-face. Face overrides
+- * library. If the face filter weights are all zero (the default), it
+- * means that the library default should be used.
+- */
+- if ( have_custom_weight )
+- {
+- /*
+- * A per-font filter is set. It always uses the default 5-tap
+- * in-place FIR filter.
+- */
+- ft_memcpy( lcd_weights,
+- slot->face->internal->lcd_weights,
+- FT_LCD_FILTER_FIVE_TAPS );
+- lcd_filter_func = ft_lcd_filter_fir;
+- }
+- else
+- {
+- /*
+- * The face's lcd_weights is {0, 0, 0, 0, 0}, meaning `use library
+- * default'. If the library is set to use no LCD filtering
+- * (lcd_filter_func == NULL), `lcd_filter_func' here is also set to
+- * NULL and the tests further below pass over the filtering process.
+- */
+- ft_memcpy( lcd_weights,
+- slot->library->lcd_weights,
+- FT_LCD_FILTER_FIVE_TAPS );
+- lcd_filter_func = slot->library->lcd_filter_func;
+- }
+-
+-#endif /*FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+ /* check glyph image format */
+ if ( slot->format != render->glyph_format )
+@@ -180,100 +123,6 @@
+ goto Exit;
+ }
+
+- if ( origin )
+- {
+- x_shift = origin->x;
+- y_shift = origin->y;
+- }
+-
+- /* compute the control box, and grid fit it */
+- /* taking into account the origin shift */
+- FT_Outline_Get_CBox( outline, &cbox );
+-
+-#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+-
+- /* add minimal padding for LCD rendering */
+- if ( hmul )
+- {
+- cbox.xMax += 21;
+- cbox.xMin -= 21;
+- }
+-
+- if ( vmul )
+- {
+- cbox.yMax += 21;
+- cbox.yMin -= 21;
+- }
+-
+-#else /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+-
+- /* add minimal padding for LCD filter depending on specific weights */
+- if ( lcd_filter_func )
+- {
+- if ( hmul )
+- {
+- cbox.xMax += lcd_weights[4] ? 43
+- : lcd_weights[3] ? 22 : 0;
+- cbox.xMin -= lcd_weights[0] ? 43
+- : lcd_weights[1] ? 22 : 0;
+- }
+-
+- if ( vmul )
+- {
+- cbox.yMax += lcd_weights[4] ? 43
+- : lcd_weights[3] ? 22 : 0;
+- cbox.yMin -= lcd_weights[0] ? 43
+- : lcd_weights[1] ? 22 : 0;
+- }
+- }
+-
+-#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+-
+- cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift );
+- cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift );
+- cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift );
+- cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift );
+-
+- x_shift -= cbox.xMin;
+- y_shift -= cbox.yMin;
+-
+- x_left = cbox.xMin >> 6;
+- y_top = cbox.yMax >> 6;
+-
+- width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6;
+- height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6;
+-
+- pitch = width;
+- if ( hmul )
+- {
+- width *= 3;
+- pitch = FT_PAD_CEIL( width, 4 );
+- }
+-
+- if ( vmul )
+- height *= 3;
+-
+- /*
+- * XXX: on 16bit system, we return an error for huge bitmap
+- * to prevent an overflow.
+- */
+- if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ||
+- x_left < FT_INT_MIN || y_top < FT_INT_MIN )
+- {
+- error = FT_THROW( Invalid_Pixel_Size );
+- goto Exit;
+- }
+-
+- /* Required check is (pitch * height < FT_ULONG_MAX), */
+- /* but we care realistic cases only. Always pitch <= width. */
+- if ( width > 0x7FFF || height > 0x7FFF )
+- {
+- FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n",
+- width, height ));
+- error = FT_THROW( Raster_Overflow );
+- goto Exit;
+- }
+-
+ /* release old bitmap buffer */
+ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+ {
+@@ -281,30 +130,30 @@
+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+ }
+
++ ft_glyphslot_preset_bitmap( slot, mode, origin );
++
+ /* allocate new one */
+- if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) )
++ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
+ goto Exit;
+- else
+- have_buffer = TRUE;
+
+ slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+
+- slot->format = FT_GLYPH_FORMAT_BITMAP;
+- slot->bitmap_left = (FT_Int)x_left;
+- slot->bitmap_top = (FT_Int)y_top;
++ x_shift = 64 * -slot->bitmap_left;
++ y_shift = 64 * -slot->bitmap_top;
++ if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
++ y_shift += 64 * (FT_Int)bitmap->rows / 3;
++ else
++ y_shift += 64 * (FT_Int)bitmap->rows;
+
+- bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
+- bitmap->num_grays = 256;
+- bitmap->width = (unsigned int)width;
+- bitmap->rows = (unsigned int)height;
+- bitmap->pitch = pitch;
++ if ( origin )
++ {
++ x_shift += origin->x;
++ y_shift += origin->y;
++ }
+
+ /* translate outline to render it into the bitmap */
+ if ( x_shift || y_shift )
+- {
+ FT_Outline_Translate( outline, x_shift, y_shift );
+- have_outline_shifted = TRUE;
+- }
+
+ /* set up parameters */
+ params.target = bitmap;
+@@ -351,8 +200,28 @@
+ if ( error )
+ goto Exit;
+
+- if ( lcd_filter_func )
+- lcd_filter_func( bitmap, mode, lcd_weights );
++ /* finally apply filtering */
++ if ( hmul || vmul )
++ {
++ FT_Byte* lcd_weights;
++ FT_Bitmap_LcdFilterFunc lcd_filter_func;
++
++
++ /* Per-face LCD filtering takes priority if set up. */
++ if ( slot->face && slot->face->internal->lcd_filter_func )
++ {
++ lcd_weights = slot->face->internal->lcd_weights;
++ lcd_filter_func = slot->face->internal->lcd_filter_func;
++ }
++ else
++ {
++ lcd_weights = slot->library->lcd_weights;
++ lcd_filter_func = slot->library->lcd_filter_func;
++ }
++
++ if ( lcd_filter_func )
++ lcd_filter_func( bitmap, mode, lcd_weights );
++ }
+
+ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+@@ -360,36 +229,39 @@
+ {
+ FT_Byte* line;
+ FT_Byte* temp;
+- FT_Int i, j;
++ FT_UInt i, j;
++
++ unsigned int height = bitmap->rows;
++ unsigned int width = bitmap->width;
++ int pitch = bitmap->pitch;
+
+
+ /* Render 3 separate monochrome bitmaps, shifting the outline */
+ /* by 1/3 pixel. */
+ width /= 3;
+
+- FT_Outline_Translate( outline, 21, 0 );
++ bitmap->buffer += width;
+
+ error = render->raster_render( render->raster, ¶ms );
+ if ( error )
+ goto Exit;
+
+ FT_Outline_Translate( outline, -21, 0 );
++ x_shift -= 21;
+ bitmap->buffer += width;
+
+ error = render->raster_render( render->raster, ¶ms );
+ if ( error )
+ goto Exit;
+
+- FT_Outline_Translate( outline, -21, 0 );
+- bitmap->buffer += width;
++ FT_Outline_Translate( outline, 42, 0 );
++ x_shift += 42;
++ bitmap->buffer -= 2 * width;
+
+ error = render->raster_render( render->raster, ¶ms );
+ if ( error )
+ goto Exit;
+
+- FT_Outline_Translate( outline, 21, 0 );
+- bitmap->buffer -= 2 * width;
+-
+ /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */
+ /* XXX: It is more efficient to render every third byte above. */
+
+@@ -398,7 +270,7 @@
+
+ for ( i = 0; i < height; i++ )
+ {
+- line = bitmap->buffer + i * pitch;
++ line = bitmap->buffer + i * (FT_ULong)pitch;
+ for ( j = 0; j < width; j++ )
+ {
+ temp[3 * j ] = line[j];
+@@ -412,60 +284,59 @@
+ }
+ else if ( vmul ) /* lcd_v */
+ {
++ int pitch = bitmap->pitch;
++
++
+ /* Render 3 separate monochrome bitmaps, shifting the outline */
+ /* by 1/3 pixel. Triple the pitch to render on each third row. */
+ bitmap->pitch *= 3;
+ bitmap->rows /= 3;
+
+- FT_Outline_Translate( outline, 0, 21 );
+- bitmap->buffer += 2 * pitch;
++ bitmap->buffer += pitch;
+
+ error = render->raster_render( render->raster, ¶ms );
+ if ( error )
+ goto Exit;
+
+- FT_Outline_Translate( outline, 0, -21 );
+- bitmap->buffer -= pitch;
++ FT_Outline_Translate( outline, 0, 21 );
++ y_shift += 21;
++ bitmap->buffer += pitch;
+
+ error = render->raster_render( render->raster, ¶ms );
+ if ( error )
+ goto Exit;
+
+- FT_Outline_Translate( outline, 0, -21 );
+- bitmap->buffer -= pitch;
++ FT_Outline_Translate( outline, 0, -42 );
++ y_shift -= 42;
++ bitmap->buffer -= 2 * pitch;
+
+ error = render->raster_render( render->raster, ¶ms );
+ if ( error )
+ goto Exit;
+
+- FT_Outline_Translate( outline, 0, 21 );
+-
+ bitmap->pitch /= 3;
+ bitmap->rows *= 3;
+ }
+ else /* grayscale */
+- {
+ error = render->raster_render( render->raster, ¶ms );
+- if ( error )
+- goto Exit;
+- }
+
+ #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+- /* everything is fine; don't deallocate buffer */
+- have_buffer = FALSE;
+-
+- error = FT_Err_Ok;
+-
+ Exit:
+- if ( have_outline_shifted )
+- FT_Outline_Translate( outline, -x_shift, -y_shift );
+- if ( have_buffer )
++ if ( !error )
++ {
++ /* everything is fine; the glyph is now officially a bitmap */
++ slot->format = FT_GLYPH_FORMAT_BITMAP;
++ }
++ else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+ {
+ FT_FREE( bitmap->buffer );
+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+ }
+
++ if ( x_shift || y_shift )
++ FT_Outline_Translate( outline, -x_shift, -y_shift );
++
+ return error;
+ }
+
+@@ -492,14 +363,8 @@
+ FT_Render_Mode mode,
+ const FT_Vector* origin )
+ {
+- FT_Error error;
+-
+- error = ft_smooth_render_generic( render, slot, mode, origin,
+- FT_RENDER_MODE_LCD );
+- if ( !error )
+- slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD;
+-
+- return error;
++ return ft_smooth_render_generic( render, slot, mode, origin,
++ FT_RENDER_MODE_LCD );
+ }
+
+
+@@ -510,14 +375,8 @@
+ FT_Render_Mode mode,
+ const FT_Vector* origin )
+ {
+- FT_Error error;
+-
+- error = ft_smooth_render_generic( render, slot, mode, origin,
+- FT_RENDER_MODE_LCD_V );
+- if ( !error )
+- slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;
+-
+- return error;
++ return ft_smooth_render_generic( render, slot, mode, origin,
++ FT_RENDER_MODE_LCD_V );
+ }
+
+
+diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
+index a1653b241c..ba05cefb35 100644
+--- a/src/truetype/ttdriver.c
++++ b/src/truetype/ttdriver.c
+@@ -233,8 +233,8 @@
+ {
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ /* no fast retrieval for blended MM fonts without VVAR table */
+- if ( !face->is_default_instance &&
+- !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
++ if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
++ !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+ return FT_THROW( Unimplemented_Feature );
+ #endif
+
+@@ -253,8 +253,8 @@
+ {
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ /* no fast retrieval for blended MM fonts without HVAR table */
+- if ( !face->is_default_instance &&
+- !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
++ if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
++ !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
+ return FT_THROW( Unimplemented_Feature );
+ #endif
+
+@@ -498,6 +498,7 @@
+ (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */
+ (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */
+ (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */
++ (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */
+
+ (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */
+ (FT_Done_Blend_Func) tt_done_blend /* done_blend */
+diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
+index 5e102c6151..94ba25673e 100644
+--- a/src/truetype/ttgload.c
++++ b/src/truetype/ttgload.c
+@@ -889,7 +889,8 @@
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+- if ( !loader->face->is_default_instance )
++ if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
++ FT_IS_VARIATION( FT_FACE( loader->face ) ) )
+ {
+ /* Deltas apply to the unscaled data. */
+ error = TT_Vary_Apply_Glyph_Deltas( loader->face,
+@@ -1577,7 +1578,8 @@
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+- if ( !loader->face->is_default_instance )
++ if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
++ FT_IS_VARIATION( FT_FACE( face ) ) )
+ {
+ /* a small outline structure with four elements for */
+ /* communication with `TT_Vary_Apply_Glyph_Deltas' */
+@@ -1751,7 +1753,8 @@
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+- if ( !face->is_default_instance )
++ if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
++ FT_IS_VARIATION( FT_FACE( face ) ) )
+ {
+ short i, limit;
+ FT_SubGlyph subglyph;
+@@ -2609,7 +2612,8 @@
+ TT_LoaderRec loader;
+
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+-#define IS_DEFAULT_INSTANCE ( ( (TT_Face)glyph->face )->is_default_instance )
++#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \
++ FT_IS_VARIATION( glyph->face ) ) )
+ #else
+ #define IS_DEFAULT_INSTANCE 1
+ #endif
+diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
+index 49aa53a687..f3c2430da2 100644
+--- a/src/truetype/ttgxvar.c
++++ b/src/truetype/ttgxvar.c
+@@ -1940,11 +1940,11 @@
+ TT_Get_MM_Var( TT_Face face,
+ FT_MM_Var* *master )
+ {
+- FT_Stream stream = face->root.stream;
+- FT_Memory memory = face->root.memory;
++ FT_Stream stream = face->root.stream;
++ FT_Memory memory = face->root.memory;
+ FT_ULong table_len;
+- FT_Error error = FT_Err_Ok;
+- FT_ULong fvar_start;
++ FT_Error error = FT_Err_Ok;
++ FT_ULong fvar_start = 0;
+ FT_UInt i, j;
+ FT_MM_Var* mmvar = NULL;
+ FT_Fixed* next_coords;
+@@ -1954,10 +1954,20 @@
+ FT_Fixed* c;
+ FT_Var_Named_Style* ns;
+ GX_FVar_Head fvar_head;
+- FT_Bool usePsName;
++ FT_Bool usePsName = 0;
+ FT_UInt num_instances;
++ FT_UInt num_axes;
+ FT_UShort* axis_flags;
+
++ FT_Offset mmvar_size;
++ FT_Offset axis_flags_size;
++ FT_Offset axis_size;
++ FT_Offset namedstyle_size;
++ FT_Offset next_coords_size;
++ FT_Offset next_name_size;
++
++ FT_Bool need_init;
++
+ static const FT_Frame_Field fvar_fields[] =
+ {
+
+@@ -1995,7 +2005,9 @@
+ /* read the font data and set up the internal representation */
+ /* if not already done */
+
+- if ( !face->blend )
++ need_init = !face->blend;
++
++ if ( need_init )
+ {
+ FT_TRACE2(( "FVAR " ));
+
+@@ -2037,21 +2049,49 @@
+ if ( FT_NEW( face->blend ) )
+ goto Exit;
+
+- /* `num_instances' holds the number of all named instances, */
+- /* including the default instance which might be missing */
+- /* in fvar's table of named instances */
+- num_instances = face->root.style_flags >> 16;
+-
+- /* prepare storage area for MM data; this cannot overflow */
+- /* 32-bit arithmetic because of the size limits used in the */
+- /* `fvar' table validity check in `sfnt_init_face' */
+- face->blend->mmvar_len =
+- sizeof ( FT_MM_Var ) +
+- fvar_head.axisCount * sizeof ( FT_UShort ) +
+- fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
+- num_instances * sizeof ( FT_Var_Named_Style ) +
+- num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) +
+- fvar_head.axisCount * 5;
++ num_axes = fvar_head.axisCount;
++ }
++ else
++ num_axes = face->blend->num_axis;
++
++ /* `num_instances' holds the number of all named instances, */
++ /* including the default instance which might be missing */
++ /* in fvar's table of named instances */
++ num_instances = (FT_UInt)face->root.style_flags >> 16;
++
++ /* prepare storage area for MM data; this cannot overflow */
++ /* 32-bit arithmetic because of the size limits used in the */
++ /* `fvar' table validity check in `sfnt_init_face' */
++
++ /* the various `*_size' variables, which we also use as */
++ /* offsets into the `mmlen' array, must be multiples of the */
++ /* pointer size (except the last one); without such an */
++ /* alignment there might be runtime errors due to */
++ /* misaligned addresses */
++#undef ALIGN_SIZE
++#define ALIGN_SIZE( n ) \
++ ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
++
++ mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
++ axis_flags_size = ALIGN_SIZE( num_axes *
++ sizeof ( FT_UShort ) );
++ axis_size = ALIGN_SIZE( num_axes *
++ sizeof ( FT_Var_Axis ) );
++ namedstyle_size = ALIGN_SIZE( num_instances *
++ sizeof ( FT_Var_Named_Style ) );
++ next_coords_size = ALIGN_SIZE( num_instances *
++ num_axes *
++ sizeof ( FT_Fixed ) );
++ next_name_size = num_axes * 5;
++
++ if ( need_init )
++ {
++ face->blend->mmvar_len = mmvar_size +
++ axis_flags_size +
++ axis_size +
++ namedstyle_size +
++ next_coords_size +
++ next_name_size;
+
+ if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
+ goto Exit;
+@@ -2061,7 +2101,7 @@
+ /* the data gets filled in later on */
+
+ mmvar->num_axis =
+- fvar_head.axisCount;
++ num_axes;
+ mmvar->num_designs =
+ ~0U; /* meaningless in this context; each glyph */
+ /* may have a different number of designs */
+@@ -2071,22 +2111,23 @@
+
+ /* alas, no public field in `FT_Var_Axis' for axis flags */
+ axis_flags =
+- (FT_UShort*)&( mmvar[1] );
++ (FT_UShort*)( (char*)mmvar + mmvar_size );
+ mmvar->axis =
+- (FT_Var_Axis*)&( axis_flags[fvar_head.axisCount] );
++ (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
+ mmvar->namedstyle =
+- (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
++ (FT_Var_Named_Style*)( (char*)mmvar->axis + axis_size );
+
+- next_coords =
+- (FT_Fixed*)&( mmvar->namedstyle[num_instances] );
++ next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle +
++ namedstyle_size );
+ for ( i = 0; i < num_instances; i++ )
+ {
+ mmvar->namedstyle[i].coords = next_coords;
+- next_coords += fvar_head.axisCount;
++ next_coords += num_axes;
+ }
+
+- next_name = (FT_String*)next_coords;
+- for ( i = 0; i < fvar_head.axisCount; i++ )
++ next_name = (FT_String*)( (char*)mmvar->namedstyle +
++ namedstyle_size + next_coords_size );
++ for ( i = 0; i < num_axes; i++ )
+ {
+ mmvar->axis[i].name = next_name;
+ next_name += 5;
+@@ -2098,7 +2139,7 @@
+ goto Exit;
+
+ a = mmvar->axis;
+- for ( i = 0; i < fvar_head.axisCount; i++ )
++ for ( i = 0; i < num_axes; i++ )
+ {
+ GX_FVar_Axis axis_rec;
+
+@@ -2148,7 +2189,7 @@
+ /* named instance coordinates are stored as design coordinates; */
+ /* we have to convert them to normalized coordinates also */
+ if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords,
+- fvar_head.axisCount * num_instances ) )
++ num_axes * num_instances ) )
+ goto Exit;
+
+ if ( fvar_head.instanceCount && !face->blend->avar_loaded )
+@@ -2168,14 +2209,14 @@
+ {
+ /* PostScript names add 2 bytes to the instance record size */
+ if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) +
+- 4L * fvar_head.axisCount ) )
++ 4L * num_axes ) )
+ goto Exit;
+
+ ns->strid = FT_GET_USHORT();
+ (void) /* flags = */ FT_GET_USHORT();
+
+ c = ns->coords;
+- for ( j = 0; j < fvar_head.axisCount; j++, c++ )
++ for ( j = 0; j < num_axes; j++, c++ )
+ *c = FT_GET_LONG();
+
+ /* valid psid values are 6, [256;32767], and 0xFFFF */
+@@ -2184,11 +2225,8 @@
+ else
+ ns->psid = 0xFFFF;
+
+- ft_var_to_normalized( face,
+- fvar_head.axisCount,
+- ns->coords,
+- nsc );
+- nsc += fvar_head.axisCount;
++ ft_var_to_normalized( face, num_axes, ns->coords, nsc );
++ nsc += num_axes;
+
+ FT_FRAME_EXIT();
+ }
+@@ -2237,7 +2275,7 @@
+
+ a = mmvar->axis;
+ c = ns->coords;
+- for ( j = 0; j < fvar_head.axisCount; j++, a++, c++ )
++ for ( j = 0; j < num_axes; j++, a++, c++ )
+ *c = a->def;
+ }
+ }
+@@ -2258,23 +2296,24 @@
+ FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
+
+ axis_flags =
+- (FT_UShort*)&( mmvar[1] );
++ (FT_UShort*)( (char*)mmvar + mmvar_size );
+ mmvar->axis =
+- (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] );
++ (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
+ mmvar->namedstyle =
+- (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] );
++ (FT_Var_Named_Style*)( (char*)mmvar->axis+ axis_size );
+
+- next_coords =
+- (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] );
++ next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle +
++ namedstyle_size );
+ for ( n = 0; n < mmvar->num_namedstyles; n++ )
+ {
+ mmvar->namedstyle[n].coords = next_coords;
+- next_coords += mmvar->num_axis;
++ next_coords += num_axes;
+ }
+
+ a = mmvar->axis;
+- next_name = (FT_String*)next_coords;
+- for ( n = 0; n < mmvar->num_axis; n++ )
++ next_name = (FT_String*)( (char*)mmvar->namedstyle +
++ namedstyle_size + next_coords_size );
++ for ( n = 0; n < num_axes; n++ )
+ {
+ a->name = next_name;
+
+@@ -2309,10 +2348,9 @@
+ FT_Error error = FT_Err_Ok;
+ GX_Blend blend;
+ FT_MM_Var* mmvar;
+- FT_UInt i, j;
++ FT_UInt i;
+
+- FT_Bool is_default_instance = TRUE;
+- FT_Bool all_design_coords = FALSE;
++ FT_Bool all_design_coords = FALSE;
+
+ FT_Memory memory = face->root.memory;
+
+@@ -2357,9 +2395,6 @@
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+-
+- if ( coords[i] != 0 )
+- is_default_instance = FALSE;
+ }
+
+ FT_TRACE5(( "\n" ));
+@@ -2454,32 +2489,6 @@
+ }
+ }
+
+- /* check whether the current variation tuple coincides */
+- /* with a named instance */
+-
+- for ( i = 0; i < blend->mmvar->num_namedstyles; i++ )
+- {
+- FT_Fixed* nsc = blend->normalized_stylecoords + i * blend->num_axis;
+- FT_Fixed* ns = blend->normalizedcoords;
+-
+-
+- for ( j = 0; j < blend->num_axis; j++, nsc++, ns++ )
+- {
+- if ( *nsc != *ns )
+- break;
+- }
+-
+- if ( j == blend->num_axis )
+- break;
+- }
+-
+- /* adjust named instance index */
+- face->root.face_index &= 0xFFFF;
+- if ( i < blend->mmvar->num_namedstyles )
+- face->root.face_index |= ( i + 1 ) << 16;
+-
+- face->is_default_instance = is_default_instance;
+-
+ /* enforce recomputation of the PostScript name; */
+ FT_FREE( face->postscript_name );
+ face->postscript_name = NULL;
+@@ -2519,7 +2528,19 @@
+ FT_UInt num_coords,
+ FT_Fixed* coords )
+ {
+- return tt_set_mm_blend( face, num_coords, coords, 1 );
++ FT_Error error;
++
++
++ error = tt_set_mm_blend( face, num_coords, coords, 1 );
++ if ( error )
++ return error;
++
++ if ( num_coords )
++ face->root.face_flags |= FT_FACE_FLAG_VARIATION;
++ else
++ face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
++
++ return FT_Err_Ok;
+ }
+
+
+@@ -2635,9 +2656,7 @@
+ FT_UInt i;
+ FT_Memory memory = face->root.memory;
+
+- FT_Var_Axis* a;
+- FT_Fixed* c;
+-
++ FT_Fixed* c;
+ FT_Fixed* normalized = NULL;
+
+
+@@ -2668,10 +2687,31 @@
+ coords,
+ num_coords * sizeof ( FT_Fixed ) );
+
+- a = mmvar->axis + num_coords;
+ c = blend->coords + num_coords;
+- for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ )
+- *c = a->def;
++
++ if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
++ {
++ FT_UInt instance_index;
++ FT_Var_Named_Style* named_style;
++ FT_Fixed* n;
++
++
++ instance_index = (FT_UInt)face->root.face_index >> 16;
++ named_style = mmvar->namedstyle + instance_index - 1;
++
++ n = named_style->coords + num_coords;
++ for ( i = num_coords; i < mmvar->num_axis; i++, n++, c++ )
++ *c = *n;
++ }
++ else
++ {
++ FT_Var_Axis* a;
++
++
++ a = mmvar->axis + num_coords;
++ for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ )
++ *c = a->def;
++ }
+
+ if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
+ goto Exit;
+@@ -2682,6 +2722,13 @@
+ ft_var_to_normalized( face, num_coords, blend->coords, normalized );
+
+ error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 );
++ if ( error )
++ goto Exit;
++
++ if ( num_coords )
++ face->root.face_flags |= FT_FACE_FLAG_VARIATION;
++ else
++ face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+ Exit:
+ FT_FREE( normalized );
+@@ -2764,6 +2811,90 @@
+ }
+
+
++ /*************************************************************************/
++ /* */
++ /* <Function> */
++ /* TT_Set_Named_Instance */
++ /* */
++ /* <Description> */
++ /* Set the given named instance, also resetting any further */
++ /* variation. */
++ /* */
++ /* <Input> */
++ /* face :: A handle to the source face. */
++ /* */
++ /* instance_index :: The instance index, starting with value 1. */
++ /* Value 0 indicates to not use an instance. */
++ /* */
++ /* <Return> */
++ /* FreeType error code. 0~means success. */
++ /* */
++ FT_LOCAL_DEF( FT_Error )
++ TT_Set_Named_Instance( TT_Face face,
++ FT_UInt instance_index )
++ {
++ FT_Error error = FT_ERR( Invalid_Argument );
++ GX_Blend blend;
++ FT_MM_Var* mmvar;
++
++ FT_UInt num_instances;
++
++
++ if ( !face->blend )
++ {
++ if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
++ goto Exit;
++ }
++
++ blend = face->blend;
++ mmvar = blend->mmvar;
++
++ num_instances = (FT_UInt)face->root.style_flags >> 16;
++
++ /* `instance_index' starts with value 1, thus `>' */
++ if ( instance_index > num_instances )
++ goto Exit;
++
++ if ( instance_index > 0 && mmvar->namedstyle )
++ {
++ FT_Memory memory = face->root.memory;
++ SFNT_Service sfnt = (SFNT_Service)face->sfnt;
++
++ FT_Var_Named_Style* named_style;
++ FT_String* style_name;
++
++
++ named_style = mmvar->namedstyle + instance_index - 1;
++
++ error = sfnt->get_name( face,
++ (FT_UShort)named_style->strid,
++ &style_name );
++ if ( error )
++ goto Exit;
++
++ /* set (or replace) style name */
++ FT_FREE( face->root.style_name );
++ face->root.style_name = style_name;
++
++ /* finally, select the named instance */
++ error = TT_Set_Var_Design( face,
++ mmvar->num_axis,
++ named_style->coords );
++ if ( error )
++ goto Exit;
++ }
++ else
++ error = TT_Set_Var_Design( face, 0, NULL );
++
++ face->root.face_index = ( instance_index << 16 ) |
++ ( face->root.face_index & 0xFFFFL );
++ face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
++
++ Exit:
++ return error;
++ }
++
++
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
+index 7e81719a3e..a9a116500e 100644
+--- a/src/truetype/ttgxvar.h
++++ b/src/truetype/ttgxvar.h
+@@ -401,6 +401,10 @@ FT_BEGIN_HEADER
+ FT_UInt num_coords,
+ FT_Fixed* coords );
+
++ FT_LOCAL( FT_Error )
++ TT_Set_Named_Instance( TT_Face face,
++ FT_UInt instance_index );
++
+ FT_LOCAL( FT_Error )
+ tt_face_vary_cvt( TT_Face face,
+ FT_Stream stream );
+diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
+index ddcc839bb3..2bb43ec06b 100644
+--- a/src/truetype/ttinterp.c
++++ b/src/truetype/ttinterp.c
+@@ -5690,7 +5690,11 @@
+ ( B1 & 63 ) != 0 &&
+ ( B2 & 63 ) != 0 &&
+ B1 != B2 )
+- Move_Zp2_Point( exc, point, -dx, -dy, TRUE );
++ Move_Zp2_Point( exc,
++ point,
++ NEG_LONG( dx ),
++ NEG_LONG( dy ),
++ TRUE );
+ }
+ }
+ else if ( exc->face->sph_compatibility_mode )
+@@ -5722,7 +5726,7 @@
+ if ( ( B1 & 63 ) == 0 &&
+ ( B2 & 63 ) != 0 &&
+ B1 != B2 )
+- Move_Zp2_Point( exc, point, 0, -dy, TRUE );
++ Move_Zp2_Point( exc, point, 0, NEG_LONG( dy ), TRUE );
+ }
+ }
+ else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
+@@ -5991,7 +5995,7 @@
+ exc->tt_metrics.compensations[0] );
+ }
+
+- exc->func_move( exc, &exc->zp0, point, distance - org_dist );
++ exc->func_move( exc, &exc->zp0, point, SUB_LONG( distance, org_dist ) );
+
+ Fail:
+ exc->GS.rp0 = point;
+@@ -6074,8 +6078,12 @@
+
+ /* single width cut-in test */
+
+- if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
+- exc->GS.single_width_cutin )
++ /* |org_dist - single_width_value| < single_width_cutin */
++ if ( exc->GS.single_width_cutin > 0 &&
++ org_dist < exc->GS.single_width_value +
++ exc->GS.single_width_cutin &&
++ org_dist > exc->GS.single_width_value -
++ exc->GS.single_width_cutin )
+ {
+ if ( org_dist >= 0 )
+ org_dist = exc->GS.single_width_value;
+@@ -7153,7 +7161,7 @@
+ SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
+ ( B1 & 63 ) != 0 &&
+ ( B2 & 63 ) != 0 ) ) )
+- exc->func_move( exc, &exc->zp0, A, -B );
++ exc->func_move( exc, &exc->zp0, A, NEG_LONG( B ) );
+ }
+ }
+ else
+diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
+index 081fa2f1a5..70df32b213 100644
+--- a/src/truetype/ttobjs.c
++++ b/src/truetype/ttobjs.c
+@@ -657,46 +657,17 @@
+ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+ {
+- FT_Int instance_index = face_index >> 16;
++ FT_UInt instance_index = (FT_UInt)face_index >> 16;
+
+
+ if ( FT_HAS_MULTIPLE_MASTERS( ttface ) &&
+ instance_index > 0 )
+ {
+- error = TT_Get_MM_Var( face, NULL );
++ error = TT_Set_Named_Instance( face, instance_index );
+ if ( error )
+ goto Exit;
+
+- if ( face->blend->mmvar->namedstyle )
+- {
+- FT_Memory memory = ttface->memory;
+-
+- FT_Var_Named_Style* named_style;
+- FT_String* style_name;
+-
+-
+- /* in `face_index', the instance index starts with value 1 */
+- named_style = face->blend->mmvar->namedstyle + instance_index - 1;
+- error = sfnt->get_name( face,
+- (FT_UShort)named_style->strid,
+- &style_name );
+- if ( error )
+- goto Exit;
+-
+- /* set style name; if already set, replace it */
+- if ( face->root.style_name )
+- FT_FREE( face->root.style_name );
+- face->root.style_name = style_name;
+-
+- /* finally, select the named instance */
+- error = TT_Set_Var_Design( face,
+- face->blend->mmvar->num_axis,
+- named_style->coords );
+- if ( error )
+- goto Exit;
+-
+- tt_apply_mvar( face );
+- }
++ tt_apply_mvar( face );
+ }
+ }
+
+diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
+index c2089947f9..c9559329b5 100644
+--- a/src/type1/t1driver.c
++++ b/src/type1/t1driver.c
+@@ -30,6 +30,7 @@
+ #include FT_INTERNAL_DEBUG_H
+ #include FT_INTERNAL_STREAM_H
+ #include FT_INTERNAL_HASH_H
++#include FT_TYPE1_DRIVER_H
+
+ #include FT_SERVICE_MULTIPLE_MASTERS_H
+ #include FT_SERVICE_GLYPH_DICT_H
+@@ -37,6 +38,7 @@
+ #include FT_SERVICE_POSTSCRIPT_NAME_H
+ #include FT_SERVICE_POSTSCRIPT_CMAPS_H
+ #include FT_SERVICE_POSTSCRIPT_INFO_H
++#include FT_SERVICE_PROPERTIES_H
+ #include FT_SERVICE_KERNING_H
+
+
+@@ -126,6 +128,7 @@
+ (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */
+ (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */
+ (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */
++ (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */
+
+ (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */
+ (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */
+@@ -613,6 +616,237 @@
+ #endif
+
+
++ /*
++ * PROPERTY SERVICE
++ *
++ */
++ static FT_Error
++ t1_property_set( FT_Module module, /* PS_Driver */
++ const char* property_name,
++ const void* value,
++ FT_Bool value_is_string )
++ {
++ FT_Error error = FT_Err_Ok;
++ PS_Driver driver = (PS_Driver)module;
++
++#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ FT_UNUSED( value_is_string );
++#endif
++
++
++ if ( !ft_strcmp( property_name, "darkening-parameters" ) )
++ {
++ FT_Int* darken_params;
++ FT_Int x1, y1, x2, y2, x3, y3, x4, y4;
++
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ FT_Int dp[8];
++
++
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++ char* ep;
++ int i;
++
++
++ /* eight comma-separated numbers */
++ for ( i = 0; i < 7; i++ )
++ {
++ dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
++ if ( *ep != ',' || s == ep )
++ return FT_THROW( Invalid_Argument );
++
++ s = ep + 1;
++ }
++
++ dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
++ if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
++ return FT_THROW( Invalid_Argument );
++
++ darken_params = dp;
++ }
++ else
++#endif
++ darken_params = (FT_Int*)value;
++
++ x1 = darken_params[0];
++ y1 = darken_params[1];
++ x2 = darken_params[2];
++ y2 = darken_params[3];
++ x3 = darken_params[4];
++ y3 = darken_params[5];
++ x4 = darken_params[6];
++ y4 = darken_params[7];
++
++ if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 ||
++ y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 ||
++ x1 > x2 || x2 > x3 || x3 > x4 ||
++ y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 )
++ return FT_THROW( Invalid_Argument );
++
++ driver->darken_params[0] = x1;
++ driver->darken_params[1] = y1;
++ driver->darken_params[2] = x2;
++ driver->darken_params[3] = y2;
++ driver->darken_params[4] = x3;
++ driver->darken_params[5] = y3;
++ driver->darken_params[6] = x4;
++ driver->darken_params[7] = y4;
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "hinting-engine" ) )
++ {
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++
++
++ if ( !ft_strcmp( s, "adobe" ) )
++ driver->hinting_engine = FT_T1_HINTING_ADOBE;
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ else if ( !ft_strcmp( s, "freetype" ) )
++ driver->hinting_engine = FT_T1_HINTING_FREETYPE;
++#endif
++ else
++ return FT_THROW( Invalid_Argument );
++ }
++ else
++#endif
++ {
++ FT_UInt* hinting_engine = (FT_UInt*)value;
++
++
++ if ( *hinting_engine == FT_T1_HINTING_ADOBE
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ || *hinting_engine == FT_T1_HINTING_FREETYPE
++#endif
++ )
++ driver->hinting_engine = *hinting_engine;
++ else
++ error = FT_ERR( Unimplemented_Feature );
++
++ return error;
++ }
++ }
++ else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
++ {
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++ long nsd = ft_strtol( s, NULL, 10 );
++
++
++ if ( !nsd )
++ driver->no_stem_darkening = FALSE;
++ else
++ driver->no_stem_darkening = TRUE;
++ }
++ else
++#endif
++ {
++ FT_Bool* no_stem_darkening = (FT_Bool*)value;
++
++
++ driver->no_stem_darkening = *no_stem_darkening;
++ }
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "random-seed" ) )
++ {
++ FT_Int32 random_seed;
++
++
++#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
++ if ( value_is_string )
++ {
++ const char* s = (const char*)value;
++
++
++ random_seed = (FT_Int32)ft_strtol( s, NULL, 10 );
++ }
++ else
++#endif
++ random_seed = *(FT_Int32*)value;
++
++ if ( random_seed < 0 )
++ random_seed = 0;
++
++ driver->random_seed = random_seed;
++
++ return error;
++ }
++
++ FT_TRACE0(( "t1_property_set: missing property `%s'\n",
++ property_name ));
++ return FT_THROW( Missing_Property );
++ }
++
++
++ static FT_Error
++ t1_property_get( FT_Module module, /* PS_Driver */
++ const char* property_name,
++ const void* value )
++ {
++ FT_Error error = FT_Err_Ok;
++ PS_Driver driver = (PS_Driver)module;
++
++
++ if ( !ft_strcmp( property_name, "darkening-parameters" ) )
++ {
++ FT_Int* darken_params = driver->darken_params;
++ FT_Int* val = (FT_Int*)value;
++
++
++ val[0] = darken_params[0];
++ val[1] = darken_params[1];
++ val[2] = darken_params[2];
++ val[3] = darken_params[3];
++ val[4] = darken_params[4];
++ val[5] = darken_params[5];
++ val[6] = darken_params[6];
++ val[7] = darken_params[7];
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "hinting-engine" ) )
++ {
++ FT_UInt hinting_engine = driver->hinting_engine;
++ FT_UInt* val = (FT_UInt*)value;
++
++
++ *val = hinting_engine;
++
++ return error;
++ }
++ else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
++ {
++ FT_Bool no_stem_darkening = driver->no_stem_darkening;
++ FT_Bool* val = (FT_Bool*)value;
++
++
++ *val = no_stem_darkening;
++
++ return error;
++ }
++
++ FT_TRACE0(( "t1_property_get: missing property `%s'\n",
++ property_name ));
++ return FT_THROW( Missing_Property );
++ }
++
++
++ FT_DEFINE_SERVICE_PROPERTIESREC(
++ t1_service_properties,
++
++ (FT_Properties_SetFunc)t1_property_set, /* set_property */
++ (FT_Properties_GetFunc)t1_property_get ) /* get_property */
++
++
+ /*
+ * SERVICE LIST
+ *
+@@ -624,6 +858,7 @@
+ { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict },
+ { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_1 },
+ { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info },
++ { FT_SERVICE_ID_PROPERTIES, &t1_service_properties },
+
+ #ifndef T1_CONFIG_OPTION_NO_AFM
+ { FT_SERVICE_ID_KERNING, &t1_service_kerning },
+@@ -713,7 +948,7 @@
+ FT_MODULE_DRIVER_SCALABLE |
+ FT_MODULE_DRIVER_HAS_HINTER,
+
+- sizeof ( FT_DriverRec ),
++ sizeof ( PS_DriverRec ),
+
+ "type1",
+ 0x10000L,
+diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
+index aaf19b6dcc..e50d7a5f62 100644
+--- a/src/type1/t1gload.c
++++ b/src/type1/t1gload.c
+@@ -23,6 +23,8 @@
+ #include FT_INTERNAL_STREAM_H
+ #include FT_OUTLINE_H
+ #include FT_INTERNAL_POSTSCRIPT_AUX_H
++#include FT_INTERNAL_CFF_TYPES_H
++#include FT_TYPE1_DRIVER_H
+
+ #include "t1errors.h"
+
+@@ -37,37 +39,28 @@
+ #define FT_COMPONENT trace_t1gload
+
+
+- /*************************************************************************/
+- /*************************************************************************/
+- /*************************************************************************/
+- /********** *********/
+- /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
+- /********** *********/
+- /********** The following code is in charge of computing *********/
+- /********** the maximum advance width of the font. It *********/
+- /********** quickly processes each glyph charstring to *********/
+- /********** extract the value from either a `sbw' or `seac' *********/
+- /********** operator. *********/
+- /********** *********/
+- /*************************************************************************/
+- /*************************************************************************/
+- /*************************************************************************/
+-
+-
+ static FT_Error
+ T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder,
+ FT_UInt glyph_index,
+- FT_Data* char_string )
++ FT_Data* char_string,
++ FT_Bool* force_scaling )
+ {
+ T1_Face face = (T1_Face)decoder->builder.face;
+ T1_Font type1 = &face->type1;
+ FT_Error error = FT_Err_Ok;
+
++ PSAux_Service psaux = (PSAux_Service)face->psaux;
++ const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs;
++ PS_Decoder psdecoder;
++
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+ FT_Incremental_InterfaceRec *inc =
+ face->root.internal->incremental_interface;
+ #endif
+
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
++#endif
+
+ decoder->font_matrix = type1->font_matrix;
+ decoder->font_offset = type1->font_offset;
+@@ -90,9 +83,56 @@
+ }
+
+ if ( !error )
+- error = decoder->funcs.parse_charstrings(
+- decoder, (FT_Byte*)char_string->pointer,
+- (FT_UInt)char_string->length );
++ {
++ /* choose which renderer to use */
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ if ( driver->hinting_engine == FT_T1_HINTING_FREETYPE ||
++ decoder->builder.metrics_only )
++ error = decoder_funcs->parse_charstrings_old(
++ decoder,
++ (FT_Byte*)char_string->pointer,
++ (FT_UInt)char_string->length );
++#else
++ if ( decoder->builder.metrics_only )
++ error = decoder_funcs->parse_metrics(
++ decoder,
++ (FT_Byte*)char_string->pointer,
++ (FT_UInt)char_string->length );
++#endif
++ else
++ {
++ CFF_SubFontRec subfont;
++
++
++ psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
++
++ psaux->t1_make_subfont( FT_FACE( face ),
++ &face->type1.private_dict, &subfont );
++ psdecoder.current_subfont = &subfont;
++
++ error = decoder_funcs->parse_charstrings(
++ &psdecoder,
++ (FT_Byte*)char_string->pointer,
++ (FT_ULong)char_string->length );
++
++ /* Adobe's engine uses 16.16 numbers everywhere; */
++ /* as a consequence, glyphs larger than 2000ppem get rejected */
++ if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
++ {
++ /* this time, we retry unhinted and scale up the glyph later on */
++ /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
++ /* 0x400 for both `x_scale' and `y_scale' in this case) */
++ ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
++
++ *force_scaling = TRUE;
++
++ error = decoder_funcs->parse_charstrings(
++ &psdecoder,
++ (FT_Byte*)char_string->pointer,
++ (FT_ULong)char_string->length );
++ }
++ }
++ }
+
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+
+@@ -126,8 +166,10 @@
+ FT_UInt glyph_index )
+ {
+ FT_Data glyph_data;
+- FT_Error error = T1_Parse_Glyph_And_Get_Char_String(
+- decoder, glyph_index, &glyph_data );
++ FT_Bool force_scaling = FALSE;
++ FT_Error error = T1_Parse_Glyph_And_Get_Char_String(
++ decoder, glyph_index, &glyph_data,
++ &force_scaling );
+
+
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+@@ -149,6 +191,23 @@
+ }
+
+
++ /*************************************************************************/
++ /*************************************************************************/
++ /*************************************************************************/
++ /********** *********/
++ /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
++ /********** *********/
++ /********** The following code is in charge of computing *********/
++ /********** the maximum advance width of the font. It *********/
++ /********** quickly processes each glyph charstring to *********/
++ /********** extract the value from either a `sbw' or `seac' *********/
++ /********** operator. *********/
++ /********** *********/
++ /*************************************************************************/
++ /*************************************************************************/
++ /*************************************************************************/
++
++
+ FT_LOCAL_DEF( FT_Error )
+ T1_Compute_Max_Advance( T1_Face face,
+ FT_Pos* max_advance )
+@@ -278,6 +337,8 @@
+ T1_DecoderRec decoder;
+ T1_Face face = (T1_Face)t1glyph->face;
+ FT_Bool hinting;
++ FT_Bool scaled;
++ FT_Bool force_scaling = FALSE;
+ T1_Font type1 = &face->type1;
+ PSAux_Service psaux = (PSAux_Service)face->psaux;
+ const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs;
+@@ -325,7 +386,10 @@
+
+ hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
+ ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
++ scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
+
++ glyph->hint = hinting;
++ glyph->scaled = scaled;
+ t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
+
+ error = decoder_funcs->init( &decoder,
+@@ -355,13 +419,15 @@
+
+ /* now load the unscaled outline */
+ error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
+- &glyph_data );
++ &glyph_data,
++ &force_scaling );
+ if ( error )
+ goto Exit;
+ #ifdef FT_CONFIG_OPTION_INCREMENTAL
+ glyph_data_loaded = 1;
+ #endif
+
++ hinting = glyph->hint;
+ font_matrix = decoder.font_matrix;
+ font_offset = decoder.font_offset;
+
+@@ -451,7 +517,7 @@
+ }
+ #endif
+
+- if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
++ if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
+ {
+ /* scale the outline and the metrics */
+ FT_Int n;
+diff --git a/src/type1/t1load.c b/src/type1/t1load.c
+index f569d6bec3..9259df64a0 100644
+--- a/src/type1/t1load.c
++++ b/src/type1/t1load.c
+@@ -366,8 +366,8 @@
+ }
+
+
+- FT_LOCAL_DEF( FT_Error )
+- T1_Set_MM_Blend( T1_Face face,
++ static FT_Error
++ t1_set_mm_blend( T1_Face face,
+ FT_UInt num_coords,
+ FT_Fixed* coords )
+ {
+@@ -412,6 +412,27 @@
+ }
+
+
++ FT_LOCAL_DEF( FT_Error )
++ T1_Set_MM_Blend( T1_Face face,
++ FT_UInt num_coords,
++ FT_Fixed* coords )
++ {
++ FT_Error error;
++
++
++ error = t1_set_mm_blend( face, num_coords, coords );
++ if ( error )
++ return error;
++
++ if ( num_coords )
++ face->root.face_flags |= FT_FACE_FLAG_VARIATION;
++ else
++ face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
++
++ return FT_Err_Ok;
++ }
++
++
+ FT_LOCAL_DEF( FT_Error )
+ T1_Get_MM_Blend( T1_Face face,
+ FT_UInt num_coords,
+@@ -452,6 +473,7 @@
+ FT_UInt num_coords,
+ FT_Long* coords )
+ {
++ FT_Error error;
+ PS_Blend blend = face->blend;
+ FT_UInt n, p;
+ FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
+@@ -518,7 +540,28 @@
+ final_blends[n] = the_blend;
+ }
+
+- return T1_Set_MM_Blend( face, blend->num_axis, final_blends );
++ error = t1_set_mm_blend( face, blend->num_axis, final_blends );
++ if ( error )
++ return error;
++
++ if ( num_coords )
++ face->root.face_flags |= FT_FACE_FLAG_VARIATION;
++ else
++ face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
++
++ return FT_Err_Ok;
++ }
++
++
++ /* MM fonts don't have named instances, so only the design is reset */
++
++ FT_LOCAL_DEF( FT_Error )
++ T1_Reset_MM_Blend( T1_Face face,
++ FT_UInt instance_index )
++ {
++ FT_UNUSED( instance_index );
++
++ return T1_Set_MM_Blend( face, 0, NULL );
+ }
+
+
+diff --git a/src/type1/t1load.h b/src/type1/t1load.h
+index 2d86984f0e..492ba5addb 100644
+--- a/src/type1/t1load.h
++++ b/src/type1/t1load.h
+@@ -89,6 +89,10 @@ FT_BEGIN_HEADER
+ FT_UInt num_coords,
+ FT_Long* coords );
+
++ FT_LOCAL( FT_Error )
++ T1_Reset_MM_Blend( T1_Face face,
++ FT_UInt instance_index );
++
+ FT_LOCAL( FT_Error )
+ T1_Get_Var_Design( T1_Face face,
+ FT_UInt num_coords,
+diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c
+index 5ac1292ae0..c6bae004af 100644
+--- a/src/type1/t1objs.c
++++ b/src/type1/t1objs.c
+@@ -21,6 +21,7 @@
+ #include FT_INTERNAL_DEBUG_H
+ #include FT_INTERNAL_STREAM_H
+ #include FT_TRUETYPE_IDS_H
++#include FT_TYPE1_DRIVER_H
+
+ #include "t1gload.h"
+ #include "t1load.h"
+@@ -578,9 +579,42 @@
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_LOCAL_DEF( FT_Error )
+- T1_Driver_Init( FT_Module driver )
++ T1_Driver_Init( FT_Module module )
+ {
+- FT_UNUSED( driver );
++ PS_Driver driver = (PS_Driver)module;
++
++ FT_UInt32 seed;
++
++
++ /* set default property values, cf. `ftt1drv.h' */
++#ifdef T1_CONFIG_OPTION_OLD_ENGINE
++ driver->hinting_engine = FT_T1_HINTING_FREETYPE;
++#else
++ driver->hinting_engine = FT_T1_HINTING_ADOBE;
++#endif
++
++ driver->no_stem_darkening = TRUE;
++
++ driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
++ driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
++ driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
++ driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
++ driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
++ driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
++ driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
++ driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
++
++ /* compute random seed from some memory addresses */
++ seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^
++ (FT_Offset)(char*)&module ^
++ (FT_Offset)(char*)module->memory );
++ seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
++
++ driver->random_seed = (FT_Int32)seed;
++ if ( driver->random_seed < 0 )
++ driver->random_seed = -driver->random_seed;
++ else if ( driver->random_seed == 0 )
++ driver->random_seed = 123456789;
+
+ return FT_Err_Ok;
+ }
+diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h
+index 39d26bf8b9..d009b394bf 100644
+--- a/src/type1/t1objs.h
++++ b/src/type1/t1objs.h
+@@ -120,12 +120,12 @@ FT_BEGIN_HEADER
+ FT_Bool hint;
+ FT_Bool scaled;
+
+- FT_Int max_points;
+- FT_Int max_contours;
+-
+ FT_Fixed x_scale;
+ FT_Fixed y_scale;
+
++ FT_Int max_points;
++ FT_Int max_contours;
++
+ } T1_GlyphSlotRec;
+
+
diff --git a/media-libs/freetype/freetype-2.8-r1.ebuild b/media-libs/freetype/freetype-2.8-r1.ebuild
deleted file mode 120000
index c3c6a8c..0000000
--- a/media-libs/freetype/freetype-2.8-r1.ebuild
+++ /dev/null
@@ -1 +0,0 @@
-freetype-2.8.ebuild
\ No newline at end of file
diff --git a/media-libs/freetype/freetype-2.8.1-r1.ebuild b/media-libs/freetype/freetype-2.8.1-r1.ebuild
new file mode 120000
index 0000000..b0ac200
--- /dev/null
+++ b/media-libs/freetype/freetype-2.8.1-r1.ebuild
@@ -0,0 +1 @@
+freetype-2.8.1.ebuild
\ No newline at end of file
diff --git a/media-libs/freetype/freetype-2.8.ebuild b/media-libs/freetype/freetype-2.8.1.ebuild
similarity index 86%
rename from media-libs/freetype/freetype-2.8.ebuild
rename to media-libs/freetype/freetype-2.8.1.ebuild
index f3451e2..29bfdfd 100644
--- a/media-libs/freetype/freetype-2.8.ebuild
+++ b/media-libs/freetype/freetype-2.8.1.ebuild
@@ -54,6 +54,14 @@
|| die "unable to disable option $1"
}
+ disable_module() {
+ sed -r -i -e "/^(FONT|AUX|HINTING|RASTER)_MODULES \+= $1/ s/^/#/" \
+ modules.cfg || die "unable to disable module $1"
+ }
+
+ epatch "${FILESDIR}"/${PN}-2.8.1-94f6d57a4.patch
+ epatch "${FILESDIR}"/${PN}-2.4.11-sizeof-types.patch # 459966
+
# Enable stem-darkening for CFF font
# TODO(jshin): Evaluate the impact of disabling stem-darkening.
epatch "${FILESDIR}"/${PN}-2.6.2-enable-cff-stem-darkening.patch
@@ -69,12 +77,19 @@
enable_option "TT_CONFIG_OPTION_SUBPIXEL_HINTING 2"
fi
+ # TODO(jshin): Consider disabling SUBPIXEL_RENDERING and using
+ # Harmony (new default in 2.8.1 when FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+ # is undefined), instead. See
+ # https://bugs.chromium.org/p/chromium/issues/detail?id=654563#c3 .
if ! use bindist; then
# See http://freetype.org/patents.html
# ClearType is covered by several Microsoft patents in the US
enable_option FT_CONFIG_OPTION_SUBPIXEL_RENDERING
fi
+ disable_option "FT_CONFIG_OPTION_MAC_FONTS"
+ disable_option "TT_CONFIG_OPTION_BDF"
+
if ! use adobe-cff; then
enable_option CFF_CONFIG_OPTION_OLD_ENGINE
fi
@@ -84,7 +99,18 @@
enable_option FT_DEBUG_MEMORY
fi
- epatch "${FILESDIR}"/${PN}-2.4.11-sizeof-types.patch # 459966
+ disable_module pcr
+ disable_module winfonts
+ disable_module pcf
+ disable_module bdf
+ disable_module lzw
+ # TODO(jshin): Check if ghostscript needs type42. (crbug.com/784767)
+ # disable_module type42
+
+ if ! use bzip2; then
+ disable_module bzip2
+ fi
+
if use utils; then
cd "${WORKDIR}/ft2demos-${PV}" || die