[FREETYPE] Update to v2.7.1. Patch by Katayama Hirofumi MZ, verified by me. CORE...
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 19 Mar 2017 17:53:42 +0000 (17:53 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 19 Mar 2017 17:53:42 +0000 (17:53 +0000)
svn path=/trunk/; revision=74206

136 files changed:
reactos/media/doc/3rd Party Files.txt
reactos/sdk/lib/3rdparty/freetype/ChangeLog
reactos/sdk/lib/3rdparty/freetype/README
reactos/sdk/lib/3rdparty/freetype/include/freetype/config/ftconfig.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/freetype.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/ftimage.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/ftmm.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/ftrender.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/ftserv.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h [new file with mode: 0644]
reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/tttypes.h
reactos/sdk/lib/3rdparty/freetype/include/freetype/tttags.h
reactos/sdk/lib/3rdparty/freetype/src/autofit/afcjk.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/afdummy.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/afglobal.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/afhints.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/afindic.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/aflatin2.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/afloader.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/afmodule.c
reactos/sdk/lib/3rdparty/freetype/src/autofit/aftypes.h
reactos/sdk/lib/3rdparty/freetype/src/base/ftadvanc.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftbbox.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftbitmap.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftcalc.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftdbgmem.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftglyph.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftmac.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftmm.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftobjs.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftrfork.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftsnames.c
reactos/sdk/lib/3rdparty/freetype/src/base/ftutil.c
reactos/sdk/lib/3rdparty/freetype/src/bdf/bdfdrivr.c
reactos/sdk/lib/3rdparty/freetype/src/bdf/bdflib.c
reactos/sdk/lib/3rdparty/freetype/src/bzip2/ftbzip2.c
reactos/sdk/lib/3rdparty/freetype/src/cache/ftcbasic.c
reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.c
reactos/sdk/lib/3rdparty/freetype/src/cache/ftccache.h
reactos/sdk/lib/3rdparty/freetype/src/cache/ftccmap.c
reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmanag.c
reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.c
reactos/sdk/lib/3rdparty/freetype/src/cache/ftcmru.h
reactos/sdk/lib/3rdparty/freetype/src/cache/ftcsbits.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2arrst.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2error.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2fixed.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2font.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2ft.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2hints.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2intrp.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cf2stack.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cffcmap.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cffdrivr.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cffgload.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cffload.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cffobjs.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.c
reactos/sdk/lib/3rdparty/freetype/src/cff/cffparse.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cffpic.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cfftoken.h
reactos/sdk/lib/3rdparty/freetype/src/cff/cfftypes.h
reactos/sdk/lib/3rdparty/freetype/src/cid/cidload.c
reactos/sdk/lib/3rdparty/freetype/src/cid/cidparse.c
reactos/sdk/lib/3rdparty/freetype/src/cid/cidriver.c
reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c
reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmod.c
reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmort.c
reactos/sdk/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c
reactos/sdk/lib/3rdparty/freetype/src/gzip/ftgzip.c
reactos/sdk/lib/3rdparty/freetype/src/gzip/ftzconf.h [new file with mode: 0644]
reactos/sdk/lib/3rdparty/freetype/src/gzip/zlib.h
reactos/sdk/lib/3rdparty/freetype/src/lzw/ftzopen.c
reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvcommn.c
reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmath.c
reactos/sdk/lib/3rdparty/freetype/src/otvalid/otvmod.c
reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfdrivr.c
reactos/sdk/lib/3rdparty/freetype/src/pcf/pcfread.c
reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrcmap.c
reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrdrivr.c
reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrload.c
reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrobjs.c
reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.c
reactos/sdk/lib/3rdparty/freetype/src/pfr/pfrsbit.h
reactos/sdk/lib/3rdparty/freetype/src/psaux/psauxmod.c
reactos/sdk/lib/3rdparty/freetype/src/psaux/psobjs.c
reactos/sdk/lib/3rdparty/freetype/src/psaux/t1cmap.c
reactos/sdk/lib/3rdparty/freetype/src/psaux/t1decode.c
reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshalgo.c
reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshmod.c
reactos/sdk/lib/3rdparty/freetype/src/pshinter/pshrec.c
reactos/sdk/lib/3rdparty/freetype/src/psnames/psmodule.c
reactos/sdk/lib/3rdparty/freetype/src/psnames/pstables.h
reactos/sdk/lib/3rdparty/freetype/src/raster/ftraster.c
reactos/sdk/lib/3rdparty/freetype/src/raster/ftrend1.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/pngshim.h
reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfdriver.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/sfobjs.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttbdf.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttcmap.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttload.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttmtx.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttpost.c
reactos/sdk/lib/3rdparty/freetype/src/sfnt/ttsbit.c
reactos/sdk/lib/3rdparty/freetype/src/smooth/ftgrays.c
reactos/sdk/lib/3rdparty/freetype/src/smooth/ftsmooth.c
reactos/sdk/lib/3rdparty/freetype/src/tools/apinames.c
reactos/sdk/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c
reactos/sdk/lib/3rdparty/freetype/src/tools/glnames.py
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttdriver.c
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgload.c
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.c
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttgxvar.h
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.c
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttinterp.h
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttobjs.c
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpic.h
reactos/sdk/lib/3rdparty/freetype/src/truetype/ttpload.c
reactos/sdk/lib/3rdparty/freetype/src/type1/t1afm.c
reactos/sdk/lib/3rdparty/freetype/src/type1/t1driver.c
reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.c
reactos/sdk/lib/3rdparty/freetype/src/type1/t1load.h
reactos/sdk/lib/3rdparty/freetype/src/type1/t1parse.c
reactos/sdk/lib/3rdparty/freetype/src/type42/t42drivr.c
reactos/sdk/lib/3rdparty/freetype/src/type42/t42objs.c
reactos/sdk/lib/3rdparty/freetype/src/type42/t42parse.c
reactos/sdk/lib/3rdparty/freetype/src/winfonts/winfnt.c

index 04ed3f1..8cc916b 100644 (file)
@@ -23,7 +23,7 @@ Used Version: 1.1
 Website: http://www.geocities.com/dborca/opengl/tc.html
 
 Title: FreeType
-Used Version: 2.7.0
+Used Version: 2.7.1
 Website: http://www.freetype.org
 
 Title: Mesa3D
index 113dd3c..23f5748 100644 (file)
+2016-09-08  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 repitition) 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 dummp 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 strokes 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.
 
        * src/tools/ftrandom/ftrandom.c (GOOD_FONTS_DIR): Provide better
        default.
-       (error_fraction): Make it of type `double' to work as advertized \96
+       (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.
index 5a49290..097024c 100644 (file)
@@ -1,5 +1,5 @@
-  FreeType 2.7
-  ============
+  FreeType 2.7.1
+  ==============
 
   Homepage: http://www.freetype.org
 
@@ -24,9 +24,9 @@
 
   and download one of the following files.
 
-    freetype-doc-2.7.tar.bz2
-    freetype-doc-2.7.tar.gz
-    ftdoc27.zip
+    freetype-doc-2.7.1.tar.bz2
+    freetype-doc-2.7.1.tar.gz
+    ftdoc271.zip
 
   To view the documentation online, go to
 
index 157a704..62b807f 100644 (file)
@@ -143,6 +143,14 @@ FT_BEGIN_HEADER
 #endif
 
 
+  /* Fix compiler warning with sgi compiler */
+#if defined( __sgi ) && !defined( __GNUC__ )
+#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
+#pragma set woff 3505
+#endif
+#endif
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Section>                                                             */
@@ -338,10 +346,11 @@ FT_BEGIN_HEADER
 
 
   /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( __GNUC__ >= 2                         || \
-      defined( __IBM__TYPEOF__ )            || \
-      ( __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  (__typeof__ (type))
+#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
+      ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
+        defined( __IBM__TYPEOF__ ) )                                 || \
+      ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
+#define FT_TYPEOF( type )  ( __typeof__ ( type ) )
 #else
 #define FT_TYPEOF( type )  /* empty */
 #endif
index 3a50734..08f5952 100644 (file)
@@ -951,6 +951,10 @@ FT_BEGIN_HEADER
   /*                           strikes in the face.  It is set to NULL if  */
   /*                           there is no bitmap strike.                  */
   /*                                                                       */
+  /*                           Note that FreeType tries to sanitize the    */
+  /*                           strike data since they are sometimes sloppy */
+  /*                           or incorrect, but this can easily fail.     */
+  /*                                                                       */
   /*    num_charmaps        :: The number of charmaps in the face.         */
   /*                                                                       */
   /*    charmaps            :: An array of the charmaps of the face.       */
@@ -1727,7 +1731,6 @@ FT_BEGIN_HEADER
   /*    position (e.g., coordinates (0,0) on the baseline).  Of course,    */
   /*    `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.         */
   /*                                                                       */
-  /* <Note>                                                                */
   /*    Here is a small pseudo code fragment that shows how to use         */
   /*    `lsb_delta' and `rsb_delta':                                       */
   /*                                                                       */
@@ -1755,6 +1758,12 @@ FT_BEGIN_HEADER
   /*      endfor                                                           */
   /*    }                                                                  */
   /*                                                                       */
+  /*    If you use strong auto-hinting, you *must* apply these delta       */
+  /*    values!  Otherwise you will experience far too large inter-glyph   */
+  /*    spacing at small rendering sizes in most cases.  Note that it      */
+  /*    doesn't harm to use the above code for other hinting modes also,   */
+  /*    since the delta values are zero then.                              */
+  /*                                                                       */
   typedef struct  FT_GlyphSlotRec_
   {
     FT_Library        library;
@@ -2322,7 +2331,10 @@ FT_BEGIN_HEADER
   /*    FT_Select_Size                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Select a bitmap strike.                                            */
+  /*    Select a bitmap strike.  To be more precise, this function sets    */
+  /*    the scaling factors of the active @FT_Size object in a face so     */
+  /*    that bitmaps from this particular strike are taken by              */
+  /*    @FT_Load_Glyph and friends.                                        */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face         :: A handle to a target face object.                  */
@@ -2334,6 +2346,20 @@ FT_BEGIN_HEADER
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    For bitmaps embedded in outline fonts it is common that only a     */
+  /*    subset of the available glyphs at a given ppem value is available. */
+  /*    FreeType silently uses outlines if there is no bitmap for a given  */
+  /*    glyph index.                                                       */
+  /*                                                                       */
+  /*    For GX variation fonts, a bitmap strike makes sense only if the    */
+  /*    default instance is active (this is, no glyph variation takes      */
+  /*    place); otherwise, FreeType simply ignores bitmap strikes.  The    */
+  /*    same is true for all named instances that are different from the   */
+  /*    default instance.                                                  */
+  /*                                                                       */
+  /*    Don't use this function if you are using the FreeType cache API.   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Select_Size( FT_Face  face,
                   FT_Int   strike_index );
@@ -2786,6 +2812,14 @@ FT_BEGIN_HEADER
    *
    *     Currently, this flag is only implemented for TrueType fonts.
    *
+   *   FT_LOAD_BITMAP_METRICS_ONLY ::
+   *     This flag is used to 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.
+   *
    *   FT_LOAD_CROP_BITMAP ::
    *     Ignored.  Deprecated.
    *
@@ -2832,6 +2866,7 @@ FT_BEGIN_HEADER
   /* Bits 16..19 are used by `FT_LOAD_TARGET_' */
 #define FT_LOAD_COLOR                        ( 1L << 20 )
 #define FT_LOAD_COMPUTE_METRICS              ( 1L << 21 )
+#define FT_LOAD_BITMAP_METRICS_ONLY          ( 1L << 22 )
 
   /* */
 
@@ -4206,7 +4241,7 @@ FT_BEGIN_HEADER
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  7
-#define FREETYPE_PATCH  0
+#define FREETYPE_PATCH  1
 
 
   /*************************************************************************/
index 4f86c56..7b46155 100644 (file)
@@ -1180,6 +1180,7 @@ FT_BEGIN_HEADER
   typedef struct  FT_Raster_Funcs_
   {
     FT_Glyph_Format        glyph_format;
+
     FT_Raster_NewFunc      raster_new;
     FT_Raster_ResetFunc    raster_reset;
     FT_Raster_SetModeFunc  raster_set_mode;
index b5d6858..a0238c5 100644 (file)
@@ -171,6 +171,7 @@ FT_BEGIN_HEADER
   {
     FT_Fixed*  coords;
     FT_UInt    strid;
+    FT_UInt    psid;   /* since 2.7.1 */
 
   } FT_Var_Named_Style;
 
@@ -334,6 +335,34 @@ FT_BEGIN_HEADER
                                  FT_Fixed*  coords );
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Var_Design_Coordinates                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    For Multiple Master and GX Var fonts, get the design coordinates   */
+  /*    of the currently selected interpolated font.                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face       :: A handle to the source face.                         */
+  /*                                                                       */
+  /*    num_coords :: The number of design coordinates to retrieve.  If it */
+  /*                  is larger than the number of axes, set the excess    */
+  /*                  values to~0.                                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    coords     :: The design coordinates array.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_Var_Design_Coordinates( FT_Face    face,
+                                 FT_UInt    num_coords,
+                                 FT_Fixed*  coords );
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -353,7 +382,8 @@ FT_BEGIN_HEADER
   /*                  use default values for the remaining axes.           */
   /*                                                                       */
   /*    coords     :: The design coordinates array (each element must be   */
-  /*                  between 0 and 1.0).                                  */
+  /*                  between 0 and 1.0 for MM fonts, and between -1.0 and */
+  /*                  1.0 for GX var fonts).                               */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
@@ -364,6 +394,35 @@ FT_BEGIN_HEADER
                                FT_Fixed*  coords );
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_MM_Blend_Coordinates                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    For Multiple Masters and GX var fonts, get the normalized blend    */
+  /*    coordinates of the currently selected interpolated font.           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face       :: A handle to the source face.                         */
+  /*                                                                       */
+  /*    num_coords :: The number of normalized blend coordinates to        */
+  /*                  retrieve.  If it is larger than the number of axes,  */
+  /*                  set the excess values to~0.5 for MM fonts, and to~0  */
+  /*                  for GX var fonts.                                    */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    coords     :: The normalized blend coordinates array.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_MM_Blend_Coordinates( FT_Face    face,
+                               FT_UInt    num_coords,
+                               FT_Fixed*  coords );
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -377,6 +436,20 @@ FT_BEGIN_HEADER
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords );
 
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Var_Blend_Coordinates                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is another name of @FT_Get_MM_Blend_Coordinates.              */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_Var_Blend_Coordinates( FT_Face    face,
+                                FT_UInt    num_coords,
+                                FT_Fixed*  coords );
+
   /* */
 
 
index 9f7ed9e..278d24a 100644 (file)
@@ -75,6 +75,7 @@ FT_BEGIN_HEADER
   {
     FT_Long                 glyph_size;
     FT_Glyph_Format         glyph_format;
+
     FT_Glyph_InitFunc       glyph_init;
     FT_Glyph_DoneFunc       glyph_done;
     FT_Glyph_CopyFunc       glyph_copy;
index 0a9f2d4..25b18a5 100644 (file)
@@ -193,6 +193,7 @@ FT_BEGIN_HEADER
   typedef struct  FT_CMap_ClassRec_
   {
     FT_ULong               size;
+
     FT_CMap_InitFunc       init;
     FT_CMap_DoneFunc       done;
     FT_CMap_CharIndexFunc  char_index;
@@ -530,7 +531,8 @@ FT_BEGIN_HEADER
 
   FT_BASE( FT_Pointer )
   ft_module_get_service( FT_Module    module,
-                         const char*  service_id );
+                         const char*  service_id,
+                         FT_Bool      global );
 
 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
   FT_BASE( FT_Error )
@@ -874,7 +876,7 @@ FT_BEGIN_HEADER
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
     FT_LcdFilter             lcd_filter;
     FT_Int                   lcd_extra;        /* number of extra pixels */
-    FT_Byte                  lcd_weights[7];   /* filter weights, if any */
+    FT_Byte                  lcd_weights[5];   /* filter weights, if any */
     FT_Bitmap_LcdFilterFunc  lcd_filter_func;  /* filtering callback     */
 #endif
 
index b923401..718fa62 100644 (file)
@@ -43,11 +43,12 @@ FT_BEGIN_HEADER
 
   typedef struct  FT_RFork_Ref_
   {
-    FT_UShort  res_id;
-    FT_Long    offset;
+    FT_Short  res_id;
+    FT_Long   offset;
 
   } FT_RFork_Ref;
 
+
 #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
   typedef FT_Error
   (*ft_raccess_guess_func)( FT_Library  library,
index 9189717..663722f 100644 (file)
@@ -109,27 +109,27 @@ FT_BEGIN_HEADER
    */
 #ifdef __cplusplus
 
-#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
-  FT_BEGIN_STMNT                                                   \
-    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \
-    FT_Pointer   _tmp_;                                            \
-    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \
-                                                                   \
-                                                                   \
-    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
-    *_pptr_ = _tmp_;                                               \
+#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
+  FT_BEGIN_STMNT                                                      \
+    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );       \
+    FT_Pointer   _tmp_;                                               \
+    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                        \
+                                                                      \
+                                                                      \
+    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
+    *_pptr_ = _tmp_;                                                  \
   FT_END_STMNT
 
 #else /* !C++ */
 
-#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
-  FT_BEGIN_STMNT                                                   \
-    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \
-    FT_Pointer  _tmp_;                                             \
-                                                                   \
-                                                                   \
-    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
-    ptr   = _tmp_;                                                 \
+#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
+  FT_BEGIN_STMNT                                                      \
+    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );        \
+    FT_Pointer  _tmp_;                                                \
+                                                                      \
+                                                                      \
+    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
+    ptr   = _tmp_;                                                    \
   FT_END_STMNT
 
 #endif /* !C++ */
@@ -167,6 +167,7 @@ FT_BEGIN_HEADER
   /*    FT_DEFINE_SERVICEDESCREC5                                          */
   /*    FT_DEFINE_SERVICEDESCREC6                                          */
   /*    FT_DEFINE_SERVICEDESCREC7                                          */
+  /*    FT_DEFINE_SERVICEDESCREC8                                          */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Used to initialize an array of FT_ServiceDescRec structures.       */
@@ -283,6 +284,28 @@ FT_BEGIN_HEADER
     { NULL, NULL }                                                          \
   };
 
+#define FT_DEFINE_SERVICEDESCREC8( 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 )                 \
+  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 },                                             \
+    { NULL, NULL }                                                          \
+  };
+
 #else /* FT_CONFIG_OPTION_PIC */
 
 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
@@ -593,6 +616,62 @@ FT_BEGIN_HEADER
     return FT_Err_Ok;                                                       \
   }
 
+#define FT_DEFINE_SERVICEDESCREC8( 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 )                 \
+  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 ) * 9 ) )                         \
+      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   = NULL;                                              \
+    clazz[8].serv_data = NULL;                                              \
+                                                                            \
+    *output_class = clazz;                                                  \
+                                                                            \
+    return FT_Err_Ok;                                                       \
+  }
+
 #endif /* FT_CONFIG_OPTION_PIC */
 
 
@@ -739,6 +818,7 @@ FT_BEGIN_HEADER
 #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
 #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
 #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
+#define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h>
 #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
 #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
 #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
diff --git a/reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h b/reactos/sdk/lib/3rdparty/freetype/include/freetype/internal/services/svmetric.h
new file mode 100644 (file)
index 0000000..7a4fed4
--- /dev/null
@@ -0,0 +1,155 @@
+/***************************************************************************/
+/*                                                                         */
+/*  svmetric.h                                                             */
+/*                                                                         */
+/*    The FreeType services for metrics variations (specification).        */
+/*                                                                         */
+/*  Copyright 2016 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 SVMETRIC_H_
+#define SVMETRIC_H_
+
+#include FT_INTERNAL_SERVICE_H
+
+
+FT_BEGIN_HEADER
+
+
+  /*
+   *  A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables.
+   *
+   */
+
+#define FT_SERVICE_ID_METRICS_VARIATIONS  "metrics-variations"
+
+
+  /* HVAR */
+
+  typedef FT_Error
+  (*FT_HAdvance_Adjust_Func)( FT_Face  face,
+                              FT_UInt  gindex,
+                              FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_LSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_RSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  /* VVAR */
+
+  typedef FT_Error
+  (*FT_VAdvance_Adjust_Func)( FT_Face  face,
+                              FT_UInt  gindex,
+                              FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_TSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_BSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_VOrg_Adjust_Func)( FT_Face  face,
+                          FT_UInt  gindex,
+                          FT_Int  *avalue );
+
+  /* MVAR */
+
+  typedef FT_Error
+  (*FT_Metrics_Adjust_Func)( FT_Face   face,
+                             FT_ULong  tag,
+                             FT_Int   *avalue );
+
+
+  FT_DEFINE_SERVICE( MetricsVariations )
+  {
+    FT_HAdvance_Adjust_Func  hadvance_adjust;
+    FT_LSB_Adjust_Func       lsb_adjust;
+    FT_RSB_Adjust_Func       rsb_adjust;
+
+    FT_VAdvance_Adjust_Func  vadvance_adjust;
+    FT_TSB_Adjust_Func       tsb_adjust;
+    FT_BSB_Adjust_Func       bsb_adjust;
+    FT_VOrg_Adjust_Func      vorg_adjust;
+
+    FT_Metrics_Adjust_Func   metrics_adjust;
+  };
+
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_,            \
+                                                hadvance_adjust_,  \
+                                                lsb_adjust_,       \
+                                                rsb_adjust_,       \
+                                                vadvance_adjust_,  \
+                                                tsb_adjust_,       \
+                                                bsb_adjust_,       \
+                                                vorg_adjust_,      \
+                                                metrics_adjust_  ) \
+  static const FT_Service_MetricsVariationsRec  class_ =           \
+  {                                                                \
+    hadvance_adjust_,                                              \
+    lsb_adjust_,                                                   \
+    rsb_adjust_,                                                   \
+    vadvance_adjust_,                                              \
+    tsb_adjust_,                                                   \
+    bsb_adjust_,                                                   \
+    vorg_adjust_,                                                  \
+    metrics_adjust_                                                \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_,               \
+                                                hadvance_adjust_,     \
+                                                lsb_adjust_,          \
+                                                rsb_adjust_,          \
+                                                vadvance_adjust_,     \
+                                                tsb_adjust_,          \
+                                                bsb_adjust_,          \
+                                                vorg_adjust_,         \
+                                                metrics_adjust_  )    \
+  void                                                                \
+  FT_Init_Class_ ## class_( FT_Service_MetricsVariationsRec*  clazz ) \
+  {                                                                   \
+    clazz->hadvance_adjust = hadvance_adjust_;                        \
+    clazz->lsb_adjust      = lsb_adjust_;                             \
+    clazz->rsb_adjust      = rsb_adjust_;                             \
+    clazz->vadvance_adjust = vadvance_adjust_;                        \
+    clazz->tsb_adjust      = tsb_adjust_;                             \
+    clazz->bsb_adjust      = bsb_adjust_;                             \
+    clazz->vorg_adjust     = vorg_adjust_;                            \
+    clazz->metrics_adjust  = metrics_adjust_;                         \
+  };
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+  /* */
+
+
+FT_END_HEADER
+
+#endif /* SVMETRIC_H_ */
+
+
+/* END */
index b78a19f..e54845a 100644 (file)
@@ -58,46 +58,91 @@ FT_BEGIN_HEADER
                            FT_UInt   num_coords,
                            FT_Long*  coords );
 
+  typedef FT_Error
+  (*FT_Get_Var_Design_Func)( FT_Face    face,
+                             FT_UInt    num_coords,
+                             FT_Fixed*  coords );
+
+  typedef FT_Error
+  (*FT_Get_MM_Blend_Func)( FT_Face   face,
+                           FT_UInt   num_coords,
+                           FT_Long*  coords );
+
+  typedef FT_Error
+  (*FT_Get_Var_Blend_Func)( FT_Face      face,
+                            FT_UInt     *num_coords,
+                            FT_Fixed*   *coords,
+                            FT_MM_Var*  *mm_var );
+
+  typedef void
+  (*FT_Done_Blend_Func)( FT_Face );
+
 
   FT_DEFINE_SERVICE( MultiMasters )
   {
     FT_Get_MM_Func          get_mm;
     FT_Set_MM_Design_Func   set_mm_design;
     FT_Set_MM_Blend_Func    set_mm_blend;
+    FT_Get_MM_Blend_Func    get_mm_blend;
     FT_Get_MM_Var_Func      get_mm_var;
     FT_Set_Var_Design_Func  set_var_design;
+    FT_Get_Var_Design_Func  get_var_design;
+
+    /* for internal use; only needed for code sharing between modules */
+    FT_Get_Var_Blend_Func   get_var_blend;
+    FT_Done_Blend_Func      done_blend;
   };
 
 
 #ifndef FT_CONFIG_OPTION_PIC
 
-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                          \
-                                           get_mm_,                         \
-                                           set_mm_design_,                  \
-                                           set_mm_blend_,                   \
-                                           get_mm_var_,                     \
-                                           set_var_design_ )                \
-  static const FT_Service_MultiMastersRec  class_ =                         \
-  {                                                                         \
-    get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_    \
+#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_                                              \
   };
 
 #else /* FT_CONFIG_OPTION_PIC */
 
-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                          \
-                                           get_mm_,                         \
-                                           set_mm_design_,                  \
-                                           set_mm_blend_,                   \
-                                           get_mm_var_,                     \
-                                           set_var_design_ )                \
-  void                                                                      \
-  FT_Init_Class_ ## class_( FT_Service_MultiMastersRec*  clazz )            \
-  {                                                                         \
-    clazz->get_mm         = get_mm_;                                        \
-    clazz->set_mm_design  = set_mm_design_;                                 \
-    clazz->set_mm_blend   = set_mm_blend_;                                  \
-    clazz->get_mm_var     = get_mm_var_;                                    \
-    clazz->set_var_design = set_var_design_;                                \
+#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_ )         \
+  void                                                           \
+  FT_Init_Class_ ## class_( FT_Service_MultiMastersRec*  clazz ) \
+  {                                                              \
+    clazz->get_mm         = get_mm_;                             \
+    clazz->set_mm_design  = set_mm_design_;                      \
+    clazz->set_mm_blend   = set_mm_blend_;                       \
+    clazz->get_mm_blend   = get_mm_blend_;                       \
+    clazz->get_mm_var     = get_mm_var_;                         \
+    clazz->set_var_design = set_var_design_;                     \
+    clazz->get_var_design = get_var_design_;                     \
+    clazz->get_var_blend  = get_var_blend_;                      \
+    clazz->done_blend     = done_blend_;                         \
   }
 
 #endif /* FT_CONFIG_OPTION_PIC */
index 4ed980b..eef3b10 100644 (file)
@@ -1060,6 +1060,75 @@ FT_BEGIN_HEADER
   } TT_SbitTableType;
 
 
+  /* OpenType 1.8 brings new tables for variation font support;  */
+  /* to make the old MM and GX fonts still work we need to check */
+  /* the presence (and validity) of the functionality provided   */
+  /* by those tables.  The following flag macros are for the     */
+  /* field `variation_support'.                                  */
+  /*                                                             */
+  /* Note that `fvar' gets checked immediately at font loading,  */
+  /* while the other features are only loaded if MM support is   */
+  /* actually requested.                                         */
+
+  /* FVAR */
+#define TT_FACE_FLAG_VAR_FVAR  ( 1 << 0 )
+
+  /* HVAR */
+#define TT_FACE_FLAG_VAR_HADVANCE  ( 1 << 1 )
+#define TT_FACE_FLAG_VAR_LSB       ( 1 << 2 )
+#define TT_FACE_FLAG_VAR_RSB       ( 1 << 3 )
+
+  /* VVAR */
+#define TT_FACE_FLAG_VAR_VADVANCE  ( 1 << 4 )
+#define TT_FACE_FLAG_VAR_TSB       ( 1 << 5 )
+#define TT_FACE_FLAG_VAR_BSB       ( 1 << 6 )
+#define TT_FACE_FLAG_VAR_VORG      ( 1 << 7 )
+
+  /* MVAR gasp data */
+#define TT_FACE_FLAG_VAR_GASP_0  ( 1 << 20 )
+#define TT_FACE_FLAG_VAR_GASP_1  ( 1 << 21 )
+#define TT_FACE_FLAG_VAR_GASP_2  ( 1 << 22 )
+#define TT_FACE_FLAG_VAR_GASP_3  ( 1 << 23 )
+#define TT_FACE_FLAG_VAR_GASP_4  ( 1 << 24 )
+#define TT_FACE_FLAG_VAR_GASP_5  ( 1 << 25 )
+#define TT_FACE_FLAG_VAR_GASP_6  ( 1 << 26 )
+#define TT_FACE_FLAG_VAR_GASP_7  ( 1 << 27 )
+#define TT_FACE_FLAG_VAR_GASP_8  ( 1 << 28 )
+#define TT_FACE_FLAG_VAR_GASP_9  ( 1 << 29 )
+
+  /* The following flag macros are for the field `mvar_support'. */
+
+  /* remaining MVAR data */
+#define TT_FACE_FLAG_VAR_CPHT  ( 1 <<  0 )
+#define TT_FACE_FLAG_VAR_HASC  ( 1 <<  1 )
+#define TT_FACE_FLAG_VAR_HCLA  ( 1 <<  2 )
+#define TT_FACE_FLAG_VAR_HCLD  ( 1 <<  3 )
+#define TT_FACE_FLAG_VAR_HCOF  ( 1 <<  4 )
+#define TT_FACE_FLAG_VAR_HCRN  ( 1 <<  5 )
+#define TT_FACE_FLAG_VAR_HCRS  ( 1 <<  6 )
+#define TT_FACE_FLAG_VAR_HDSC  ( 1 <<  7 )
+#define TT_FACE_FLAG_VAR_HLGP  ( 1 <<  8 )
+#define TT_FACE_FLAG_VAR_SBXO  ( 1 <<  9 )
+#define TT_FACE_FLAG_VAR_SBXS  ( 1 << 10 )
+#define TT_FACE_FLAG_VAR_SBYO  ( 1 << 11 )
+#define TT_FACE_FLAG_VAR_SBYS  ( 1 << 12 )
+#define TT_FACE_FLAG_VAR_SPXO  ( 1 << 13 )
+#define TT_FACE_FLAG_VAR_SPXS  ( 1 << 14 )
+#define TT_FACE_FLAG_VAR_SPYO  ( 1 << 15 )
+#define TT_FACE_FLAG_VAR_SPYS  ( 1 << 16 )
+#define TT_FACE_FLAG_VAR_STRO  ( 1 << 17 )
+#define TT_FACE_FLAG_VAR_STRS  ( 1 << 18 )
+#define TT_FACE_FLAG_VAR_UNDO  ( 1 << 19 )
+#define TT_FACE_FLAG_VAR_UNDS  ( 1 << 20 )
+#define TT_FACE_FLAG_VAR_VASC  ( 1 << 21 )
+#define TT_FACE_FLAG_VAR_VCOF  ( 1 << 22 )
+#define TT_FACE_FLAG_VAR_VCRN  ( 1 << 23 )
+#define TT_FACE_FLAG_VAR_VCRS  ( 1 << 24 )
+#define TT_FACE_FLAG_VAR_VDSC  ( 1 << 25 )
+#define TT_FACE_FLAG_VAR_VLGP  ( 1 << 26 )
+#define TT_FACE_FLAG_VAR_XHGT  ( 1 << 27 )
+
+
   /*************************************************************************/
   /*                                                                       */
   /*                         TrueType Face Type                            */
@@ -1161,6 +1230,11 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    psnames              :: A pointer to the PostScript names service. */
   /*                                                                       */
+  /*    mm                   :: A pointer to the Multiple Masters service. */
+  /*                                                                       */
+  /*    var                  :: A pointer to the Metrics Variations        */
+  /*                            service.                                   */
+  /*                                                                       */
   /*    hdmx                 :: The face's horizontal device metrics       */
   /*                            (`hdmx' table).  This table is optional in */
   /*                            TrueType/OpenType fonts.                   */
@@ -1182,18 +1256,6 @@ FT_BEGIN_HEADER
   /*                            file  `ttconfig.h' for comments on the     */
   /*                            TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.  */
   /*                                                                       */
-  /*    num_locations        :: The number of glyph locations in this      */
-  /*                            TrueType file.  This should be             */
-  /*                            identical to the number of glyphs.         */
-  /*                            Ignored for Type 2 fonts.                  */
-  /*                                                                       */
-  /*    glyph_locations      :: An array of longs.  These are offsets to   */
-  /*                            glyph data within the `glyf' table.        */
-  /*                            Ignored for Type 2 font faces.             */
-  /*                                                                       */
-  /*    glyf_len             :: The length of the `glyf' table.  Needed    */
-  /*                            for malformed `loca' tables.               */
-  /*                                                                       */
   /*    font_program_size    :: Size in bytecodes of the face's font       */
   /*                            program.  0 if none defined.  Ignored for  */
   /*                            Type 2 fonts.                              */
@@ -1219,20 +1281,20 @@ FT_BEGIN_HEADER
   /*                            units.  Comes from the `cvt ' table.       */
   /*                            Ignored for Type 2 fonts.                  */
   /*                                                                       */
-  /*    num_kern_pairs       :: The number of kerning pairs present in the */
-  /*                            font file.  The engine only loads the      */
-  /*                            first horizontal format 0 kern table it    */
-  /*                            finds in the font file.  Ignored for       */
-  /*                            Type 2 fonts.                              */
-  /*                                                                       */
-  /*    kern_table_index     :: The index of the kerning table in the font */
-  /*                            kerning directory.  Ignored for Type 2     */
-  /*                            fonts.                                     */
-  /*                                                                       */
   /*    interpreter          :: A pointer to the TrueType bytecode         */
   /*                            interpreters field is also used to hook    */
   /*                            the debugger in `ttdebug'.                 */
   /*                                                                       */
+  /*    extra                :: Reserved for third-party font drivers.     */
+  /*                                                                       */
+  /*    postscript_name      :: The PS name of the font.  Used by the      */
+  /*                            postscript name service.                   */
+  /*                                                                       */
+  /*    glyf_len             :: The length of the `glyf' table.  Needed    */
+  /*                            for malformed `loca' tables.               */
+  /*                                                                       */
+  /*    glyf_offset          :: The file offset of the `glyf' table.       */
+  /*                                                                       */
   /*    doblend              :: A boolean which is set if the font should  */
   /*                            be blended (this is for GX var).           */
   /*                                                                       */
@@ -1240,10 +1302,92 @@ FT_BEGIN_HEADER
   /*                            variation tables (rather like Multiple     */
   /*                            Master data).                              */
   /*                                                                       */
-  /*    extra                :: Reserved for third-party font drivers.     */
+  /*    is_default_instance  :: Set if the glyph outlines can be used      */
+  /*                            unmodified (i.e., without applying glyph   */
+  /*                            variation deltas).                         */
   /*                                                                       */
-  /*    postscript_name      :: The PS name of the font.  Used by the      */
-  /*                            postscript name service.                   */
+  /*    variation_support    :: Flags that indicate which OpenType         */
+  /*                            functionality related to font variation    */
+  /*                            support is present, valid, and usable.     */
+  /*                            For example, TT_FACE_FLAG_VAR_FVAR is only */
+  /*                            set if we have at least one design axis.   */
+  /*                                                                       */
+  /*    mvar_support         :: Flags that indicate which metrics          */
+  /*                            variations are supported.                  */
+  /*                                                                       */
+  /*    horz_metrics_size    :: The size of the `hmtx' table.              */
+  /*                                                                       */
+  /*    vert_metrics_size    :: The size of the `vmtx' table.              */
+  /*                                                                       */
+  /*    num_locations        :: The number of glyph locations in this      */
+  /*                            TrueType file.  This should be             */
+  /*                            identical to the number of glyphs.         */
+  /*                            Ignored for Type 2 fonts.                  */
+  /*                                                                       */
+  /*    glyph_locations      :: An array of longs.  These are offsets to   */
+  /*                            glyph data within the `glyf' table.        */
+  /*                            Ignored for Type 2 font faces.             */
+  /*                                                                       */
+  /*    hdmx_table           :: A pointer to the `hdmx' table.             */
+  /*                                                                       */
+  /*    hdmx_table_size      :: The size of the `hdmx' table.              */
+  /*                                                                       */
+  /*    hdmx_record_count    :: The number of hdmx records.                */
+  /*                                                                       */
+  /*    hdmx_record_size     :: The size of a single hdmx record.          */
+  /*                                                                       */
+  /*    hdmx_record_sizes    :: An array holding the ppem sizes available  */
+  /*                            in the `hdmx' table.                       */
+  /*                                                                       */
+  /*    sbit_table           :: A pointer to the font's embedded bitmap    */
+  /*                            location table.                            */
+  /*                                                                       */
+  /*    sbit_table_size      :: The size of `sbit_table'.                  */
+  /*                                                                       */
+  /*    sbit_table_type      :: The sbit table type (CBLC, SBIX, etc.).    */
+  /*                                                                       */
+  /*    sbit_num_strikes     :: The number of sbit strikes exposed by      */
+  /*                            FreeType's API, omitting invalid strikes.  */
+  /*                                                                       */
+  /*    sbit_strike_map      :: A mapping between the strike indices       */
+  /*                            exposed by the API and the indices used in */
+  /*                            the font's sbit table.                     */
+  /*                                                                       */
+  /*    kern_table           :: A pointer to the `kern' table.             */
+  /*                                                                       */
+  /*    kern_table_size      :: The size of the `kern' table.              */
+  /*                                                                       */
+  /*    num_kern_tables      :: The number of supported kern subtables     */
+  /*                            (up to 32; FreeType recognizes only        */
+  /*                            horizontal ones with format 0).            */
+  /*                                                                       */
+  /*    kern_avail_bits      :: The availability status of kern subtables; */
+  /*                            if bit n is set, table n is available.     */
+  /*                                                                       */
+  /*    kern_order_bits      :: The sortedness status of kern subtables;   */
+  /*                            if bit n is set, table n is sorted.        */
+  /*                                                                       */
+  /*    bdf                  :: Data related to an SFNT font's `bdf'       */
+  /*                            table; see `tttypes.h'.                    */
+  /*                                                                       */
+  /*    horz_metrics_offset  :: The file offset of the `hmtx' table.       */
+  /*                                                                       */
+  /*    vert_metrics_offset  :: The file offset of the `vmtx' table.       */
+  /*                                                                       */
+  /*    sph_found_func_flags :: Flags identifying special bytecode         */
+  /*                            functions (used by the v38 implementation  */
+  /*                            of the bytecode interpreter).              */
+  /*                                                                       */
+  /*    sph_compatibility_mode ::                                          */
+  /*                            This flag is set if we are in ClearType    */
+  /*                            backwards compatibility mode (used by the  */
+  /*                            v38 implementation of the bytecode         */
+  /*                            interpreter).                              */
+  /*                                                                       */
+  /*    ebdt_start           :: The file offset of the sbit data table     */
+  /*                            (CBDT, bdat, etc.).                        */
+  /*                                                                       */
+  /*    ebdt_size            :: The size of the sbit data table.           */
   /*                                                                       */
   typedef struct  TT_FaceRec_
   {
@@ -1288,6 +1432,16 @@ FT_BEGIN_HEADER
     /* handle glyph names <-> unicode & Mac values                   */
     void*                 psnames;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    /* a typeless pointer to the FT_Service_MultiMasters table used to */
+    /* handle variation fonts                                          */
+    void*                 mm;
+
+    /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
+    /* used to handle the HVAR, VVAR, and MVAR OpenType tables         */
+    void*                 var;
+#endif
+
 
     /***********************************************************************/
     /*                                                                     */
@@ -1344,18 +1498,22 @@ FT_BEGIN_HEADER
     const char*           postscript_name;
 
     FT_ULong              glyf_len;
+    FT_ULong              glyf_offset;    /* since 2.7.1 */
+
+    FT_Bool               isCFF2;         /* since 2.7.1 */
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_Bool               doblend;
     GX_Blend              blend;
+
+    FT_Bool               is_default_instance;   /* since 2.7.1 */
+    FT_UInt32             variation_support;     /* since 2.7.1 */
+    FT_UInt32             mvar_support;          /* since 2.7.1 */
 #endif
 
     /* since version 2.2 */
 
-    FT_Byte*              horz_metrics;
     FT_ULong              horz_metrics_size;
-
-    FT_Byte*              vert_metrics;
     FT_ULong              vert_metrics_size;
 
     FT_ULong              num_locations; /* in broken TTF, gid > 0xFFFF */
@@ -1371,6 +1529,7 @@ FT_BEGIN_HEADER
     FT_ULong              sbit_table_size;
     TT_SbitTableType      sbit_table_type;
     FT_UInt               sbit_num_strikes;
+    FT_UInt*              sbit_strike_map;
 
     FT_Byte*              kern_table;
     FT_ULong              kern_table_size;
@@ -1491,8 +1650,6 @@ FT_BEGIN_HEADER
     FT_Vector        pp1;
     FT_Vector        pp2;
 
-    FT_ULong         glyf_offset;
-
     /* the zone where we load our glyphs */
     TT_GlyphZoneRec  base;
     TT_GlyphZoneRec  zone;
index f3c9aa5..63f6258 100644 (file)
@@ -43,6 +43,7 @@ FT_BEGIN_HEADER
 #define TTAG_CBDT  FT_MAKE_TAG( 'C', 'B', 'D', 'T' )
 #define TTAG_CBLC  FT_MAKE_TAG( 'C', 'B', 'L', 'C' )
 #define TTAG_CFF   FT_MAKE_TAG( 'C', 'F', 'F', ' ' )
+#define TTAG_CFF2  FT_MAKE_TAG( 'C', 'F', 'F', '2' )
 #define TTAG_CID   FT_MAKE_TAG( 'C', 'I', 'D', ' ' )
 #define TTAG_cmap  FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
 #define TTAG_cvar  FT_MAKE_TAG( 'c', 'v', 'a', 'r' )
@@ -61,6 +62,7 @@ FT_BEGIN_HEADER
 #define TTAG_GPOS  FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
 #define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
 #define TTAG_gvar  FT_MAKE_TAG( 'g', 'v', 'a', 'r' )
+#define TTAG_HVAR  FT_MAKE_TAG( 'H', 'V', 'A', 'R' )
 #define TTAG_hdmx  FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
 #define TTAG_head  FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
 #define TTAG_hhea  FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
@@ -79,6 +81,7 @@ FT_BEGIN_HEADER
 #define TTAG_MMSD  FT_MAKE_TAG( 'M', 'M', 'S', 'D' )
 #define TTAG_mort  FT_MAKE_TAG( 'm', 'o', 'r', 't' )
 #define TTAG_morx  FT_MAKE_TAG( 'm', 'o', 'r', 'x' )
+#define TTAG_MVAR  FT_MAKE_TAG( 'M', 'V', 'A', 'R' )
 #define TTAG_name  FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
 #define TTAG_opbd  FT_MAKE_TAG( 'o', 'p', 'b', 'd' )
 #define TTAG_OS2   FT_MAKE_TAG( 'O', 'S', '/', '2' )
@@ -100,6 +103,7 @@ FT_BEGIN_HEADER
 #define TTAG_VDMX  FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
 #define TTAG_vhea  FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
 #define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+#define TTAG_VVAR  FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
 #define TTAG_wOFF  FT_MAKE_TAG( 'w', 'O', 'F', 'F' )
 
 
index f21ae3a..68e72f8 100644 (file)
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                       /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_cjk_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_cjk_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_cjk_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_cjk_hints_apply          /* style_hints_apply     */
   )
 
 
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) NULL,
-    (AF_WritingSystem_ScaleMetricsFunc)NULL,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   NULL,
-    (AF_WritingSystem_ApplyHintsFunc)  NULL
+    (AF_WritingSystem_InitHintsFunc)   NULL, /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  NULL  /* style_hints_apply     */
   )
 
 
index f3960c8..ff47dcb 100644 (file)
 
     sizeof ( AF_StyleMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) NULL,
-    (AF_WritingSystem_ScaleMetricsFunc)NULL,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL,                /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)NULL,                /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)NULL,                /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_dummy_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_dummy_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_dummy_hints_init, /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_dummy_hints_apply /* style_hints_apply     */
   )
 
 
index ac6dcaf..11ed0df 100644 (file)
       AF_Script_UniRange  range;
 
 
-      if ( script_class->script_uni_ranges == NULL )
+      if ( !script_class->script_uni_ranges )
         continue;
 
       /*
       globals->hb_buf = NULL;
 #endif
 
-      globals->glyph_count               = 0;
-      globals->stem_darkening_for_ppem   = 0;
-      globals->darken_x                  = 0;
-      globals->darken_y                  = 0;
-      globals->standard_vertical_width   = 0;
-      globals->standard_horizontal_width = 0;
-      globals->scale_down_factor         = 0;
-      /* no need to free this one! */
-      globals->glyph_styles              = NULL;
-      globals->face                      = NULL;
-
+      /* no need to free `globals->glyph_styles'; */
+      /* it is part of the `globals' array        */
       FT_FREE( globals );
     }
   }
                              [style_class->writing_system];
 
     metrics = globals->metrics[style];
-    if ( metrics == NULL )
+    if ( !metrics )
     {
       /* create the global metrics object if necessary */
       FT_Memory  memory = globals->face->memory;
index 0f7f6e5..8ad3e1c 100644 (file)
@@ -45,7 +45,7 @@
 
     if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
     {
-      if ( axis->segments == NULL )
+      if ( !axis->segments )
       {
         axis->segments     = axis->embedded.segments;
         axis->max_segments = AF_SEGMENTS_EMBEDDED;
 
     if ( axis->num_edges < AF_EDGES_EMBEDDED )
     {
-      if ( axis->edges == NULL )
+      if ( !axis->edges )
       {
         axis->edges     = axis->embedded.edges;
         axis->max_edges = AF_EDGES_EMBEDDED;
 
     if ( new_max <= AF_CONTOURS_EMBEDDED )
     {
-      if ( hints->contours == NULL )
+      if ( !hints->contours )
       {
         hints->contours     = hints->embedded.contours;
         hints->max_contours = AF_CONTOURS_EMBEDDED;
 
     if ( new_max <= AF_POINTS_EMBEDDED )
     {
-      if ( hints->points == NULL )
+      if ( !hints->points )
       {
         hints->points     = hints->embedded.points;
         hints->max_points = AF_POINTS_EMBEDDED;
         AF_Point  point, first, last;
 
 
-        if ( edge == NULL )
+        if ( !edge )
           continue;
 
         first = seg->first;
         AF_Point  point, first, last;
 
 
-        if ( edge == NULL )
+        if ( !edge )
           continue;
 
         first = seg->first;
index 097a2b2..cfaf719 100644 (file)
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                         /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_indic_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_indic_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_indic_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_indic_hints_apply          /* style_hints_apply     */
   )
 
 
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) NULL,
-    (AF_WritingSystem_ScaleMetricsFunc)NULL,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   NULL,
-    (AF_WritingSystem_ApplyHintsFunc)  NULL
+    (AF_WritingSystem_InitHintsFunc)   NULL, /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  NULL  /* style_hints_apply     */
   )
 
 
index 09b3609..5775dd8 100644 (file)
                 "af_latin_metrics_scale_dim:"
                 " x height alignment (style `%s'):\n"
                 "                           "
-                " vertical scaling changed from %.4f to %.4f (by %d%%)\n"
+                " vertical scaling changed from %.5f to %.5f (by %d%%)\n"
                 "\n",
                 af_style_names[metrics->root.style_class->style],
                 scale / 65536.0,
                                 seg->serif->edge         &&
                                 seg->serif->edge != edge );
 
-          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
+          if ( ( seg->link && seg->link->edge ) || is_serif )
           {
             AF_Edge     edge2;
             AF_Segment  seg2;
 
     sizeof ( AF_LatinMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                         /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_latin_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_latin_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_latin_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_latin_hints_apply          /* style_hints_apply     */
   )
 
 
index 5db4a41..e1cc1f5 100644 (file)
                                 seg->serif->edge         &&
                                 seg->serif->edge != edge );
 
-          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
+          if ( ( seg->link && seg->link->edge ) || is_serif )
           {
             AF_Edge     edge2;
             AF_Segment  seg2;
 
     sizeof ( AF_LatinMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                          /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_latin2_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_latin2_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_latin2_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_latin2_hints_apply          /* style_hints_apply     */
   )
 
 
index 26bba06..7f75fc3 100644 (file)
@@ -51,7 +51,7 @@
     loader->face    = face;
     loader->globals = (AF_FaceGlobals)face->autohint.data;
 
-    if ( loader->globals == NULL )
+    if ( !loader->globals )
     {
       error = af_face_globals_new( face, &loader->globals, module );
       if ( !error )
           ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) )
 
 
-  /* Do the main work of `af_loader_load_glyph'.  Note that we never   */
-  /* have to deal with composite glyphs as those get loaded into       */
-  /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */
-  /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies     */
-  /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called.     */
-
   static FT_Error
-  af_loader_load_g( AF_Loader  loader,
-                    AF_Scaler  scaler,
-                    FT_UInt    glyph_index,
-                    FT_Int32   load_flags )
+  af_loader_embolden_glyph_in_slot( AF_Loader        loader,
+                                    FT_Face          face,
+                                    AF_StyleMetrics  style_metrics )
   {
-    AF_Module  module = loader->globals->module;
+    FT_Error  error = FT_Err_Ok;
 
-    FT_Error          error;
-    FT_Face           face     = loader->face;
-    AF_StyleMetrics   metrics  = loader->metrics;
-    AF_GlyphHints     hints    = loader->hints;
-    FT_GlyphSlot      slot     = face->glyph;
-    FT_Slot_Internal  internal = slot->internal;
-    FT_GlyphLoader    gloader  = internal->loader;
-    FT_Int32          flags;
+    FT_GlyphSlot           slot    = face->glyph;
+    AF_FaceGlobals         globals = loader->globals;
+    AF_WritingSystemClass  writing_system_class;
 
+    FT_Pos  stdVW = 0;
+    FT_Pos  stdHW = 0;
 
-    flags = load_flags | FT_LOAD_LINEAR_DESIGN;
-    error = FT_Load_Glyph( face, glyph_index, flags );
-    if ( error )
+    FT_Bool  size_changed = face->size->metrics.x_ppem
+                              != globals->stem_darkening_for_ppem;
+
+    FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
+    FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );
+
+    FT_Matrix  scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };
+
+
+    /* Skip stem darkening for broken fonts. */
+    if ( !face->units_per_EM )
+    {
+      error = FT_Err_Corrupted_Font_Header;
       goto Exit;
+    }
 
     /*
-     * Apply stem darkening (emboldening) here before hints are applied to
-     * the outline.  Glyphs are scaled down proportionally to the
-     * emboldening so that curve points don't fall outside their precomputed
-     * blue zones.
-     *
-     * Any emboldening done by the font driver (e.g., the CFF driver)
-     * doesn't reach here because the autohinter loads the unprocessed
-     * glyphs in font units for analysis (functions `af_*_metrics_init_*')
-     * and then above to prepare it for the rasterizers by itself,
-     * independently of the font driver.  So emboldening must be done here,
-     * within the autohinter.
-     *
-     * All glyphs to be autohinted pass through here one by one.  The
-     * standard widths can therefore change from one glyph to the next,
-     * depending on what script a glyph is assigned to (each script has its
-     * own set of standard widths and other metrics).  The darkening amount
-     * must therefore be recomputed for each size and
-     * `standard_{vertical,horizontal}_width' change.
+     *  We depend on the writing system (script analyzers) to supply
+     *  standard widths for the script of the glyph we are looking at.  If
+     *  it can't deliver, stem darkening is disabled.
      */
-    if ( !module->no_stem_darkening )
+    writing_system_class =
+      AF_WRITING_SYSTEM_CLASSES_GET[style_metrics->style_class->writing_system];
+
+    if ( writing_system_class->style_metrics_getstdw )
+      writing_system_class->style_metrics_getstdw( style_metrics,
+                                                   &stdHW,
+                                                   &stdVW );
+    else
     {
-      AF_FaceGlobals         globals = loader->globals;
-      AF_WritingSystemClass  writing_system_class;
+      error = FT_Err_Unimplemented_Feature;
+      goto Exit;
+    }
 
-      FT_Pos  stdVW = 0;
-      FT_Pos  stdHW = 0;
+    if ( size_changed                                               ||
+         ( stdVW > 0 && stdVW != globals->standard_vertical_width ) )
+    {
+      FT_Fixed  darken_by_font_units_x, darken_x;
 
-      FT_Bool  size_changed = face->size->metrics.x_ppem
-                                != globals->stem_darkening_for_ppem;
 
-      FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
-      FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );
+      darken_by_font_units_x =
+        af_intToFixed( af_loader_compute_darkening( loader,
+                                                    face,
+                                                    stdVW ) );
+      darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
+                                       face->size->metrics.x_scale ),
+                            em_ratio );
 
-      FT_Matrix  scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };
+      globals->standard_vertical_width = stdVW;
+      globals->stem_darkening_for_ppem = face->size->metrics.x_ppem;
+      globals->darken_x                = af_fixedToInt( darken_x );
+    }
+
+    if ( size_changed                                                 ||
+         ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) )
+    {
+      FT_Fixed  darken_by_font_units_y, darken_y;
 
 
-      /* Skip stem darkening for broken fonts. */
-      if ( !face->units_per_EM )
-        goto After_Emboldening;
+      darken_by_font_units_y =
+        af_intToFixed( af_loader_compute_darkening( loader,
+                                                    face,
+                                                    stdHW ) );
+      darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
+                                       face->size->metrics.y_scale ),
+                            em_ratio );
+
+      globals->standard_horizontal_width = stdHW;
+      globals->stem_darkening_for_ppem   = face->size->metrics.x_ppem;
+      globals->darken_y                  = af_fixedToInt( darken_y );
 
       /*
-       * We depend on the writing system (script analyzers) to supply
-       * standard widths for the script of the glyph we are looking at.  If
-       * it can't deliver, stem darkening is effectively disabled.
+       *  Scale outlines down on the Y-axis to keep them inside their blue
+       *  zones.  The stronger the emboldening, the stronger the downscaling
+       *  (plus heuristical padding to prevent outlines still falling out
+       *  their zones due to rounding).
+       *
+       *  Reason: `FT_Outline_Embolden' works by shifting the rightmost
+       *  points of stems farther to the right, and topmost points farther
+       *  up.  This positions points on the Y-axis outside their
+       *  pre-computed blue zones and leads to distortion when applying the
+       *  hints in the code further below.  Code outside this emboldening
+       *  block doesn't know we are presenting it with modified outlines the
+       *  analyzer didn't see!
+       *
+       *  An unfortunate side effect of downscaling is that the emboldening
+       *  effect is slightly decreased.  The loss becomes more pronounced
+       *  versus the CFF driver at smaller sizes, e.g., at 9ppem and below.
        */
-      writing_system_class =
-        AF_WRITING_SYSTEM_CLASSES_GET[metrics->style_class->writing_system];
+      globals->scale_down_factor =
+        FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ),
+                   em_size );
+    }
 
-      if ( writing_system_class->style_metrics_getstdw )
-        writing_system_class->style_metrics_getstdw( metrics,
-                                                     &stdHW,
-                                                     &stdVW );
-      else
-        goto After_Emboldening;
+    FT_Outline_EmboldenXY( &slot->outline,
+                           globals->darken_x,
+                           globals->darken_y );
 
+    scale_down_matrix.yy = globals->scale_down_factor;
+    FT_Outline_Transform( &slot->outline, &scale_down_matrix );
 
-      if ( size_changed                                               ||
-           ( stdVW > 0 && stdVW != globals->standard_vertical_width ) )
-      {
-        FT_Fixed  darken_by_font_units_x, darken_x;
+  Exit:
+    return error;
+  }
 
 
-        darken_by_font_units_x =
-          af_intToFixed( af_loader_compute_darkening( loader,
-                                                      face,
-                                                      stdVW ) );
-        darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
-                                         face->size->metrics.x_scale ),
-                              em_ratio );
+  /* Load the glyph at index into the current slot of a face and hint it. */
 
-        globals->standard_vertical_width = stdVW;
-        globals->stem_darkening_for_ppem = face->size->metrics.x_ppem;
-        globals->darken_x                = af_fixedToInt( darken_x );
-      }
+  FT_LOCAL_DEF( FT_Error )
+  af_loader_load_glyph( AF_Loader  loader,
+                        AF_Module  module,
+                        FT_Face    face,
+                        FT_UInt    glyph_index,
+                        FT_Int32   load_flags )
+  {
+    FT_Error  error;
 
-      if ( size_changed                                                 ||
-           ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) )
-      {
-        FT_Fixed  darken_by_font_units_y, darken_y;
-
-
-        darken_by_font_units_y =
-          af_intToFixed( af_loader_compute_darkening( loader,
-                                                      face,
-                                                      stdHW ) );
-        darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
-                                         face->size->metrics.y_scale ),
-                              em_ratio );
-
-        globals->standard_horizontal_width = stdHW;
-        globals->stem_darkening_for_ppem   = face->size->metrics.x_ppem;
-        globals->darken_y                  = af_fixedToInt( darken_y );
-
-        /*
-         * Scale outlines down on the Y-axis to keep them inside their blue
-         * zones.  The stronger the emboldening, the stronger the
-         * downscaling (plus heuristical padding to prevent outlines still
-         * falling out their zones due to rounding).
-         *
-         * Reason: `FT_Outline_Embolden' works by shifting the rightmost
-         * points of stems farther to the right, and topmost points farther
-         * up.  This positions points on the Y-axis outside their
-         * pre-computed blue zones and leads to distortion when applying the
-         * hints in the code further below.  Code outside this emboldening
-         * block doesn't know we are presenting it with modified outlines
-         * the analyzer didn't see!
-         *
-         * An unfortunate side effect of downscaling is that the emboldening
-         * effect is slightly decreased.  The loss becomes more pronounced
-         * versus the CFF driver at smaller sizes, e.g., at 9ppem and below.
-         */
-        globals->scale_down_factor =
-          FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ),
-                     em_size );
-      }
+    FT_Size           size     = face->size;
+    FT_GlyphSlot      slot     = face->glyph;
+    FT_Slot_Internal  internal = slot->internal;
+    FT_GlyphLoader    gloader  = internal->loader;
+
+    AF_GlyphHints          hints          = loader->hints;
+    AF_ScalerRec           scaler;
+    AF_StyleMetrics        style_metrics;
+    FT_UInt                style_options  = AF_STYLE_NONE_DFLT;
+    AF_StyleClass          style_class;
+    AF_WritingSystemClass  writing_system_class;
+
+#ifdef FT_CONFIG_OPTION_PIC
+    AF_FaceGlobals  globals = loader->globals;
+#endif
+
+
+    if ( !size )
+      return FT_THROW( Invalid_Size_Handle );
+
+    FT_ZERO( &scaler );
+
+    /*
+     *  TODO: This code currently doesn't support fractional advance widths,
+     *  i.e.  placing hinted glyphs at anything other than integer
+     *  x-positions.  This is only relevant for the warper code, which
+     *  scales and shifts glyphs to optimize blackness of stems (hinting on
+     *  the x-axis by nature places things on pixel integers, hinting on the
+     *  y-axis only, i.e.  LIGHT mode, doesn't touch the x-axis).  The delta
+     *  values of the scaler would need to be adjusted.
+     */
+    scaler.face    = face;
+    scaler.x_scale = size->metrics.x_scale;
+    scaler.x_delta = 0;
+    scaler.y_scale = size->metrics.y_scale;
+    scaler.y_delta = 0;
+
+    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
+    scaler.flags       = 0;
+
+    error = af_loader_reset( loader, module, face );
+    if ( error )
+      goto Exit;
+
+#ifdef FT_OPTION_AUTOFIT2
+    /* XXX: undocumented hook to activate the latin2 writing system. */
+    if ( load_flags & ( 1UL << 20 ) )
+      style_options = AF_STYLE_LTN2_DFLT;
+#endif
+
+    /*
+     *  Glyphs (really code points) are assigned to scripts.  Script
+     *  analysis is done lazily: For each glyph that passes through here,
+     *  the corresponding script analyzer is called, but returns immediately
+     *  if it has been run already.
+     */
+    error = af_face_globals_get_metrics( loader->globals, glyph_index,
+                                         style_options, &style_metrics );
+    if ( error )
+      goto Exit;
 
-      FT_Outline_EmboldenXY( &slot->outline,
-                             globals->darken_x,
-                             globals->darken_y );
+    style_class          = style_metrics->style_class;
+    writing_system_class =
+      AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
 
-      scale_down_matrix.yy = globals->scale_down_factor;
-      FT_Outline_Transform( &slot->outline, &scale_down_matrix );
+    loader->metrics = style_metrics;
+
+    if ( writing_system_class->style_metrics_scale )
+      writing_system_class->style_metrics_scale( style_metrics, &scaler );
+    else
+      style_metrics->scaler = scaler;
+
+    if ( writing_system_class->style_hints_init )
+    {
+      error = writing_system_class->style_hints_init( hints,
+                                                      style_metrics );
+      if ( error )
+        goto Exit;
     }
 
-  After_Emboldening:
+    /*
+     *  Do the main work of `af_loader_load_glyph'.  Note that we never have
+     *  to deal with composite glyphs as those get loaded into
+     *  FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function.
+     *  In the rare cases where FT_LOAD_NO_RECURSE is set, it implies
+     *  FT_LOAD_NO_SCALE and as such the auto-hinter is never called.
+     */
+    load_flags |=  FT_LOAD_NO_SCALE         |
+                   FT_LOAD_IGNORE_TRANSFORM |
+                   FT_LOAD_LINEAR_DESIGN;
+    load_flags &= ~FT_LOAD_RENDER;
+
+    error = FT_Load_Glyph( face, glyph_index, load_flags );
+    if ( error )
+      goto Exit;
+
+    /*
+     *  Apply stem darkening (emboldening) here before hints are applied to
+     *  the outline.  Glyphs are scaled down proportionally to the
+     *  emboldening so that curve points don't fall outside their
+     *  precomputed blue zones.
+     *
+     *  Any emboldening done by the font driver (e.g., the CFF driver)
+     *  doesn't reach here because the autohinter loads the unprocessed
+     *  glyphs in font units for analysis (functions `af_*_metrics_init_*')
+     *  and then above to prepare it for the rasterizers by itself,
+     *  independently of the font driver.  So emboldening must be done here,
+     *  within the autohinter.
+     *
+     *  All glyphs to be autohinted pass through here one by one.  The
+     *  standard widths can therefore change from one glyph to the next,
+     *  depending on what script a glyph is assigned to (each script has its
+     *  own set of standard widths and other metrics).  The darkening amount
+     *  must therefore be recomputed for each size and
+     *  `standard_{vertical,horizontal}_width' change.
+     *
+     *  Ignore errors and carry on without emboldening.
+     */
+    if ( !module->no_stem_darkening )
+      af_loader_embolden_glyph_in_slot( loader, face, style_metrics );
+
     loader->transformed = internal->glyph_transformed;
     if ( loader->transformed )
     {
                               loader->trans_delta.x,
                               loader->trans_delta.y );
 
-      /* compute original horizontal phantom points (and ignore */
-      /* vertical ones)                                         */
+      /* compute original horizontal phantom points */
+      /* (and ignore vertical ones)                 */
       loader->pp1.x = hints->x_delta;
       loader->pp1.y = hints->y_delta;
       loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
       if ( slot->outline.n_points == 0 )
         goto Hint_Metrics;
 
-      /* now load the slot image into the auto-outline and run the */
-      /* automatic hinting process                                 */
+      /* now load the slot image into the auto-outline */
+      /* and run the automatic hinting process         */
       {
 #ifdef FT_CONFIG_OPTION_PIC
-        AF_FaceGlobals         globals = loader->globals;
+        AF_FaceGlobals  globals = loader->globals;
 #endif
-        AF_StyleClass          style_class = metrics->style_class;
-        AF_WritingSystemClass  writing_system_class =
-          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
 
 
         if ( writing_system_class->style_hints_apply )
           writing_system_class->style_hints_apply( glyph_index,
                                                    hints,
                                                    &gloader->base.outline,
-                                                   metrics );
+                                                   style_metrics );
       }
 
       /* we now need to adjust the metrics according to the change in */
       /* width/positioning that occurred during the hinting process   */
-      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
+      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT )
       {
-        FT_Pos        old_rsb, old_lsb, new_lsb;
-        FT_Pos        pp1x_uh, pp2x_uh;
+        FT_Pos  old_rsb, old_lsb, new_lsb;
+        FT_Pos  pp1x_uh, pp2x_uh;
+
         AF_AxisHints  axis  = &hints->axis[AF_DIMENSION_HORZ];
         AF_Edge       edge1 = axis->edges;         /* leftmost edge  */
         AF_Edge       edge2 = edge1 +
         if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
         {
           old_rsb = loader->pp2.x - edge2->opos;
-          old_lsb = edge1->opos;
+          /* loader->pp1.x is always zero at this point of time */
+          old_lsb = edge1->opos /* - loader->pp1.x */;
           new_lsb = edge1->pos;
 
-          /* remember unhinted values to later account */
-          /* for rounding errors                       */
-
           pp1x_uh = new_lsb    - old_lsb;
           pp2x_uh = edge2->pos + old_rsb;
 
 
       vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;
       vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;
-      vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale );
-      vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale );
+      vvector.x = FT_MulFix( vvector.x, style_metrics->scaler.x_scale );
+      vvector.y = FT_MulFix( vvector.y, style_metrics->scaler.y_scale );
 
       /* transform the hinted outline if needed */
       if ( loader->transformed )
         FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
         FT_Vector_Transform( &vvector, &loader->trans_matrix );
       }
-#if 1
+
       /* we must translate our final outline by -pp1.x and compute */
       /* the new metrics                                           */
       if ( loader->pp1.x )
         FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
-#endif
+
       FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
 
       bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
       /* for mono-width fonts (like Andale, Courier, etc.) we need */
       /* to keep the original rounded advance width; ditto for     */
       /* digits if all have the same advance width                 */
-#if 0
-      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
-        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
-      else
-        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
-                                               x_scale );
-#else
-      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT                      &&
+      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT                       &&
            ( FT_IS_FIXED_WIDTH( slot->face )                              ||
              ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
-               metrics->digits_have_same_width                          ) ) )
+               style_metrics->digits_have_same_width                    ) ) )
       {
-        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
-                                               metrics->scaler.x_scale );
+        slot->metrics.horiAdvance =
+          FT_MulFix( slot->metrics.horiAdvance,
+                     style_metrics->scaler.x_scale );
 
         /* Set delta values to 0.  Otherwise code that uses them is */
         /* going to ruin the fixed advance width.                   */
         if ( slot->metrics.horiAdvance )
           slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
       }
-#endif
 
       slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
-                                             metrics->scaler.y_scale );
+                                             style_metrics->scaler.y_scale );
 
       slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
       slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
 
-#if 0
-      /* reassign all outline fields except flags to protect them */
-      slot->outline.n_contours = internal->loader->base.outline.n_contours;
-      slot->outline.n_points   = internal->loader->base.outline.n_points;
-      slot->outline.points     = internal->loader->base.outline.points;
-      slot->outline.tags       = internal->loader->base.outline.tags;
-      slot->outline.contours   = internal->loader->base.outline.contours;
-#endif
-
       slot->format  = FT_GLYPH_FORMAT_OUTLINE;
     }
 
   }
 
 
-  /* Load a glyph. */
-
-  FT_LOCAL_DEF( FT_Error )
-  af_loader_load_glyph( AF_Loader  loader,
-                        AF_Module  module,
-                        FT_Face    face,
-                        FT_UInt    gindex,
-                        FT_Int32   load_flags )
-  {
-    FT_Error      error;
-    FT_Size       size   = face->size;
-    AF_ScalerRec  scaler;
-
-
-    if ( !size )
-      return FT_THROW( Invalid_Size_Handle );
-
-    FT_ZERO( &scaler );
-
-    scaler.face    = face;
-    scaler.x_scale = size->metrics.x_scale;
-    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
-    scaler.y_scale = size->metrics.y_scale;
-    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
-
-    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
-    scaler.flags       = 0;  /* XXX: fix this */
-
-    error = af_loader_reset( loader, module, face );
-    if ( !error )
-    {
-      AF_StyleMetrics  metrics;
-      FT_UInt          options = AF_STYLE_NONE_DFLT;
-
-
-#ifdef FT_OPTION_AUTOFIT2
-      /* XXX: undocumented hook to activate the latin2 writing system */
-      if ( load_flags & ( 1UL << 20 ) )
-        options = AF_STYLE_LTN2_DFLT;
-#endif
-
-      error = af_face_globals_get_metrics( loader->globals, gindex,
-                                           options, &metrics );
-      if ( !error )
-      {
-#ifdef FT_CONFIG_OPTION_PIC
-        AF_FaceGlobals         globals = loader->globals;
-#endif
-        AF_StyleClass          style_class = metrics->style_class;
-        AF_WritingSystemClass  writing_system_class =
-          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
-
-
-        loader->metrics = metrics;
-
-        if ( writing_system_class->style_metrics_scale )
-          writing_system_class->style_metrics_scale( metrics, &scaler );
-        else
-          metrics->scaler = scaler;
-
-        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
-        load_flags &= ~FT_LOAD_RENDER;
-
-        if ( writing_system_class->style_hints_init )
-        {
-          error = writing_system_class->style_hints_init( loader->hints,
-                                                          metrics );
-          if ( error )
-            goto Exit;
-        }
-
-        error = af_loader_load_g( loader, &scaler, gindex, load_flags );
-      }
-    }
-  Exit:
-    return error;
-  }
-
-
   /*
    * Compute amount of font units the face should be emboldened by, in
    * analogy to the CFF driver's `cf2_computeDarkening' function.  See there
index 5f831e0..42e5691 100644 (file)
 
   FT_DEFINE_SERVICE_PROPERTIESREC(
     af_service_properties,
+
     (FT_Properties_SetFunc)af_property_set,        /* set_property */
     (FT_Properties_GetFunc)af_property_get )       /* get_property */
 
 
   FT_DEFINE_SERVICEDESCREC1(
     af_services,
+
     FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET )
 
 
     error = af_loader_load_glyph( loader, module, slot->face,
                                   glyph_index, load_flags );
 
-    af_glyph_hints_dump_points( hints, 0 );
-    af_glyph_hints_dump_segments( hints, 0 );
-    af_glyph_hints_dump_edges( hints, 0 );
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( ft_trace_levels[FT_COMPONENT] )
+    {
+#endif
+      af_glyph_hints_dump_points( hints, 0 );
+      af_glyph_hints_dump_segments( hints, 0 );
+      af_glyph_hints_dump_edges( hints, 0 );
+#ifdef FT_DEBUG_LEVEL_TRACE
+    }
+#endif
 
     af_loader_done( loader );
 
 
   FT_DEFINE_AUTOHINTER_INTERFACE(
     af_autofitter_interface,
+
     NULL,                                                    /* reset_face */
     NULL,                                              /* get_global_hints */
     NULL,                                             /* done_global_hints */
 
     (const void*)&AF_INTERFACE_GET,
 
-    (FT_Module_Constructor)af_autofitter_init,
-    (FT_Module_Destructor) af_autofitter_done,
-    (FT_Module_Requester)  af_get_interface )
+    (FT_Module_Constructor)af_autofitter_init,  /* module_init   */
+    (FT_Module_Destructor) af_autofitter_done,  /* module_done   */
+    (FT_Module_Requester)  af_get_interface     /* get_interface */
+  )
 
 
 /* END */
index ef62043..61b6b12 100644 (file)
@@ -221,7 +221,7 @@ extern void*  _af_debug_hints;
   (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints    hints,
                                      AF_StyleMetrics  metrics );
 
-  typedef void
+  typedef FT_Error
   (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt          glyph_index,
                                       AF_GlyphHints    hints,
                                       FT_Outline*      outline,
index 9e2ab89..59c7450 100644 (file)
@@ -36,7 +36,7 @@
     if ( flags & FT_LOAD_NO_SCALE )
       return FT_Err_Ok;
 
-    if ( face->size == NULL )
+    if ( !face->size )
       return FT_THROW( Invalid_Size_Handle );
 
     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
    /*  - unscaled load                                             */
    /*  - unhinted load                                             */
    /*  - light-hinted load                                         */
-   /*  - neither a MM nor a GX font                                */
+   /*  - if a variations font, it must have an `HVAR' or `VVAR'    */
+   /*    table (thus the old MM or GX fonts don't qualify; this    */
+   /*    gets checked by the driver-specific functions)            */
 
-#define LOAD_ADVANCE_FAST_CHECK( face, flags )                          \
-          ( ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    ||   \
-              FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) && \
-            !FT_HAS_MULTIPLE_MASTERS( face )                         )
+#define LOAD_ADVANCE_FAST_CHECK( face, flags )                      \
+          ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
+            FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
 
 
   /* documentation is in ftadvanc.h */
index d3e45ff..804dc90 100644 (file)
   }
 
 
-  FT_DEFINE_OUTLINE_FUNCS(bbox_interface,
-    (FT_Outline_MoveTo_Func) BBox_Move_To,
-    (FT_Outline_LineTo_Func) BBox_Line_To,
-    (FT_Outline_ConicTo_Func)BBox_Conic_To,
-    (FT_Outline_CubicTo_Func)BBox_Cubic_To,
-    0, 0
+  FT_DEFINE_OUTLINE_FUNCS(
+    bbox_interface,
+
+    (FT_Outline_MoveTo_Func) BBox_Move_To,   /* move_to  */
+    (FT_Outline_LineTo_Func) BBox_Line_To,   /* line_to  */
+    (FT_Outline_ConicTo_Func)BBox_Conic_To,  /* conic_to */
+    (FT_Outline_CubicTo_Func)BBox_Cubic_To,  /* cubic_to */
+    0,                                       /* shift    */
+    0                                        /* delta    */
   )
 
 
     {
       abbox->xMin = abbox->xMax = 0;
       abbox->yMin = abbox->yMax = 0;
+
       return 0;
     }
 
 
     for ( n = 0; n < outline->n_points; n++ )
     {
-      FT_UPDATE_BBOX( vec, cbox);
+      FT_UPDATE_BBOX( vec, cbox );
 
       if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )
-        FT_UPDATE_BBOX( vec, bbox);
+        FT_UPDATE_BBOX( vec, bbox );
 
       vec++;
     }
       TBBox_Rec  user;
 
 #ifdef FT_CONFIG_OPTION_PIC
-      FT_Outline_Funcs bbox_interface;
-      Init_Class_bbox_interface(&bbox_interface);
+      FT_Outline_Funcs  bbox_interface;
+
+
+      Init_Class_bbox_interface( &bbox_interface );
 #endif
 
       user.bbox = bbox;
index f0a6aff..f98012e 100644 (file)
@@ -76,7 +76,7 @@
     source_pitch_sign = source->pitch < 0 ? -1 : 1;
     target_pitch_sign = target->pitch < 0 ? -1 : 1;
 
-    if ( source->buffer == NULL )
+    if ( !source->buffer )
     {
       *target = *source;
       if ( source_pitch_sign != target_pitch_sign )
index 67549d0..1c23922 100644 (file)
       FT_Add64( &temp, &temp2, &temp );
 
       /* last attempt to ditch long division */
-      a = temp.hi == 0 ? temp.lo / c
-                       : ft_div64by32( temp.hi, temp.lo, c );
+      a = ( temp.hi == 0 ) ? temp.lo / c
+                           : ft_div64by32( temp.hi, temp.lo, c );
     }
 
     a_ = (FT_Long)a;
       ft_multo64( a, b, &temp );
 
       /* last attempt to ditch long division */
-      a = temp.hi == 0 ? temp.lo / c
-                       : ft_div64by32( temp.hi, temp.lo, c );
+      a = ( temp.hi == 0 ) ? temp.lo / c
+                           : ft_div64by32( temp.hi, temp.lo, c );
     }
 
     a_ = (FT_Long)a;
index 38d1a80..fcdceef 100644 (file)
                       ft_mem_table_alloc(
                         table,
                         new_size * (FT_Long)sizeof ( FT_MemNode ) );
-      if ( new_buckets == NULL )
+      if ( !new_buckets )
         return;
 
       FT_ARRAY_ZERO( new_buckets, new_size );
 
 
     table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
-    if ( table == NULL )
+    if ( !table )
       goto Exit;
 
     FT_ZERO( table );
     for (;;)
     {
       node = *pnode;
-      if ( node == NULL )
+      if ( !node )
         break;
 
       if ( node->file_name == _ft_debug_file   &&
     }
 
     node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );
-    if ( node == NULL )
+    if ( !node )
       ft_mem_debug_panic(
         "not enough memory to perform memory debugging\n" );
 
 
       /* we need to create a new node in this table */
       node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );
-      if ( node == NULL )
+      if ( !node )
         ft_mem_debug_panic( "not enough memory to run memory tests" );
 
       node->address = address;
     FT_MemTable  table = (FT_MemTable)memory->user;
 
 
-    if ( block == NULL )
+    if ( !block )
       ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
                           FT_FILENAME( _ft_debug_file ),
                           _ft_debug_lineno );
 
     /* the following is valid according to ANSI C */
 #if 0
-    if ( block == NULL || cur_size == 0 )
+    if ( !block || !cur_size )
       ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
                           file_name, line_no );
 #endif
       return NULL;
 
     new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size );
-    if ( new_block == NULL )
+    if ( !new_block )
       return NULL;
 
     ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
         memory->free    = ft_mem_debug_free;
 
         p = getenv( "FT2_ALLOC_TOTAL_MAX" );
-        if ( p != NULL )
+        if ( p )
         {
           FT_Long  total_max = ft_strtol( p, NULL, 10 );
 
         }
 
         p = getenv( "FT2_ALLOC_COUNT_MAX" );
-        if ( p != NULL )
+        if ( p )
         {
           FT_Long  total_count = ft_strtol( p, NULL, 10 );
 
         }
 
         p = getenv( "FT2_KEEP_ALIVE" );
-        if ( p != NULL )
+        if ( p )
         {
           FT_Long  keep_alive = ft_strtol( p, NULL, 10 );
 
index c2376dd..d336b1c 100644 (file)
   }
 
 
-  FT_DEFINE_GLYPH(ft_bitmap_glyph_class,
+  FT_DEFINE_GLYPH(
+    ft_bitmap_glyph_class,
+
     sizeof ( FT_BitmapGlyphRec ),
     FT_GLYPH_FORMAT_BITMAP,
 
-    ft_bitmap_glyph_init,
-    ft_bitmap_glyph_done,
-    ft_bitmap_glyph_copy,
-    0,                          /* FT_Glyph_TransformFunc */
-    ft_bitmap_glyph_bbox,
-    0                           /* FT_Glyph_PrepareFunc   */
+    ft_bitmap_glyph_init,    /* FT_Glyph_InitFunc       glyph_init      */
+    ft_bitmap_glyph_done,    /* FT_Glyph_DoneFunc       glyph_done      */
+    ft_bitmap_glyph_copy,    /* FT_Glyph_CopyFunc       glyph_copy      */
+    NULL,                    /* FT_Glyph_TransformFunc  glyph_transform */
+    ft_bitmap_glyph_bbox,    /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
+    NULL                     /* FT_Glyph_PrepareFunc    glyph_prepare   */
   )
 
 
   }
 
 
-  FT_DEFINE_GLYPH( ft_outline_glyph_class,
+  FT_DEFINE_GLYPH(
+    ft_outline_glyph_class,
+
     sizeof ( FT_OutlineGlyphRec ),
     FT_GLYPH_FORMAT_OUTLINE,
 
-    ft_outline_glyph_init,
-    ft_outline_glyph_done,
-    ft_outline_glyph_copy,
-    ft_outline_glyph_transform,
-    ft_outline_glyph_bbox,
-    ft_outline_glyph_prepare
+    ft_outline_glyph_init,      /* FT_Glyph_InitFunc       glyph_init      */
+    ft_outline_glyph_done,      /* FT_Glyph_DoneFunc       glyph_done      */
+    ft_outline_glyph_copy,      /* FT_Glyph_CopyFunc       glyph_copy      */
+    ft_outline_glyph_transform, /* FT_Glyph_TransformFunc  glyph_transform */
+    ft_outline_glyph_bbox,      /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
+    ft_outline_glyph_prepare    /* FT_Glyph_PrepareFunc    glyph_prepare   */
   )
 
 
     /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
     /* then calling FT_Render_Glyph_Internal()                            */
 
-    FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
-    FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
+    FT_ZERO( &dummy );
+    FT_ZERO( &dummy_internal );
     dummy.internal = &dummy_internal;
     dummy.library  = library;
     dummy.format   = clazz->glyph_format;
index e97fdbf..f0edc94 100644 (file)
     for (;;)
     {
       post_data = Get1Resource( TTAG_POST, res_id++ );
-      if ( post_data == NULL )
+      if ( !post_data )
         break;  /* we are done */
 
       code = (*post_data)[0];
     for (;;)
     {
       post_data = Get1Resource( TTAG_POST, res_id++ );
-      if ( post_data == NULL )
+      if ( !post_data )
         break;  /* we are done */
 
       post_size = (FT_ULong)GetHandleSize( post_data ) - 2;
         if ( last_code != -1 )
         {
           /* we are done adding a chunk, fill in the size field */
-          if ( size_p != NULL )
+          if ( size_p )
           {
             *size_p++ = (FT_Byte)(   pfb_chunk_size         & 0xFF );
             *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8  ) & 0xFF );
 
 
     sfnt = GetResource( TTAG_sfnt, sfnt_id );
-    if ( sfnt == NULL )
+    if ( !sfnt )
       return FT_THROW( Invalid_Handle );
 
     sfnt_size = (FT_ULong)GetHandleSize( sfnt );
       return FT_THROW( Cannot_Open_Resource );
 
     num_faces_in_res = 0;
-    for ( res_index = 1; ; ++res_index )
+    for ( res_index = 1; ; res_index++ )
     {
       short  num_faces_in_fond;
 
     /* if it works, fine.                                           */
 
     error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface );
-    if ( error == 0 )
-      return error;
+    if ( error )
+    {
+      /* let it fall through to normal loader (.ttf, .otf, etc.); */
+      /* we signal this by returning no error and no FT_Face      */
+      *aface = NULL;
+    }
 
-    /* let it fall through to normal loader (.ttf, .otf, etc.); */
-    /* we signal this by returning no error and no FT_Face      */
-    *aface = NULL;
-    return 0;
+    return FT_Err_Ok;
   }
 
 
     /* try resourcefork based font: LWFN, FFIL */
     error = FT_New_Face_From_Resource( library, (UInt8 *)pathname,
                                        face_index, aface );
-    if ( error != 0 || *aface != NULL )
+    if ( error || *aface )
       return error;
 
     /* let it fall through to normal loader (.ttf, .otf, etc.) */
     args.flags    = FT_OPEN_PATHNAME;
     args.pathname = (char*)pathname;
+
     return FT_Open_Face( library, &args, face_index, aface );
   }
 
       error = FT_THROW( Cannot_Open_Resource );
 
     error = FT_New_Face_From_Resource( library, pathname, face_index, aface );
-    if ( error != 0 || *aface != NULL )
+    if ( error || *aface )
       return error;
 
     /* fallback to datafork font */
index 6b759ca..1b724ac 100644 (file)
         error = service->set_mm_design( face, num_coords, coords );
     }
 
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
     return error;
   }
 
         error = service->set_var_design( face, num_coords, coords );
     }
 
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Var_Design_Coordinates( FT_Face    face,
+                                 FT_UInt    num_coords,
+                                 FT_Fixed*  coords )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !coords )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service->get_var_design )
+        error = service->get_var_design( face, num_coords, coords );
+    }
+
     return error;
   }
 
     {
       error = FT_ERR( Invalid_Argument );
       if ( service->set_mm_blend )
-         error = service->set_mm_blend( face, num_coords, coords );
+        error = service->set_mm_blend( face, num_coords, coords );
+    }
+
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
     }
 
     return error;
     {
       error = FT_ERR( Invalid_Argument );
       if ( service->set_mm_blend )
-         error = service->set_mm_blend( face, num_coords, coords );
+        error = service->set_mm_blend( face, num_coords, coords );
+    }
+
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_MM_Blend_Coordinates( FT_Face    face,
+                               FT_UInt    num_coords,
+                               FT_Fixed*  coords )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !coords )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service->get_mm_blend )
+        error = service->get_mm_blend( face, num_coords, coords );
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  /* This is exactly the same as the previous function.  It exists for */
+  /* orthogonality.                                                    */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Var_Blend_Coordinates( FT_Face    face,
+                                FT_UInt    num_coords,
+                                FT_Fixed*  coords )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !coords )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service->get_mm_blend )
+        error = service->get_mm_blend( face, num_coords, coords );
     }
 
     return error;
index 0c9e409..4f2a9ec 100644 (file)
 #define GRID_FIT_METRICS
 
 
+  /* forward declaration */
+  static FT_Error
+  ft_open_face_internal( FT_Library           library,
+                         const FT_Open_Args*  args,
+                         FT_Long              face_index,
+                         FT_Face             *aface,
+                         FT_Bool              test_mac_fonts );
+
+
   FT_BASE_DEF( FT_Pointer )
   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
                           const char*     service_id )
       load_flags &= ~FT_LOAD_RENDER;
     }
 
+    if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
+      load_flags &= ~FT_LOAD_RENDER;
+
     /*
      * Determine whether we need to auto-hint or not.
      * The general rules are:
 
     end = first + face->num_charmaps;  /* points after the last one */
 
-    for ( cur = first; cur < end; ++cur )
+    for ( cur = first; cur < end; cur++ )
     {
       if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&
            cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
     args.pathname = (char*)pathname;
     args.stream   = NULL;
 
-    return FT_Open_Face( library, &args, face_index, aface );
+    return ft_open_face_internal( library, &args, face_index, aface, 1 );
   }
 
 #endif
     args.memory_size = file_size;
     args.stream      = NULL;
 
-    return FT_Open_Face( library, &args, face_index, aface );
+    return ft_open_face_internal( library, &args, face_index, aface, 1 );
   }
 
 
 
   /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
   /* It frees the memory it uses.                                  */
-  /* From ftmac.c.                                                 */
+  /* From `ftmac.c'.                                               */
   static void
   memory_stream_close( FT_Stream  stream )
   {
 
 
   /* Create a new memory stream from a buffer and a size. */
-  /* From ftmac.c.                                        */
+  /* From `ftmac.c'.                                      */
   static FT_Error
   new_memory_stream( FT_Library           library,
                      FT_Byte*             base,
       return FT_THROW( Invalid_Argument );
 
     *astream = NULL;
-    memory = library->memory;
+    memory   = library->memory;
     if ( FT_NEW( stream ) )
       goto Exit;
 
 
 
   /* Create a new FT_Face given a buffer and a driver name. */
-  /* from ftmac.c */
+  /* From `ftmac.c'.                                        */
   FT_LOCAL_DEF( FT_Error )
   open_face_from_buffer( FT_Library   library,
                          FT_Byte*     base,
       return error;
     }
 
-    args.flags = FT_OPEN_STREAM;
+    args.flags  = FT_OPEN_STREAM;
     args.stream = stream;
     if ( driver_name )
     {
-      args.flags = args.flags | FT_OPEN_DRIVER;
+      args.flags  = args.flags | FT_OPEN_DRIVER;
       args.driver = FT_Get_Module( library, driver_name );
     }
 
       face_index &= 0x7FFF0000L; /* retain GX data */
 #endif
 
-    error = FT_Open_Face( library, &args, face_index, aface );
+    error = ft_open_face_internal( library, &args, face_index, aface, 0 );
 
-    if ( error == FT_Err_Ok )
+    if ( !error )
       (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
     else
 #ifdef FT_MACINTOSH
   {
     FT_Error   error  = FT_ERR( Cannot_Open_Resource );
     FT_Memory  memory = library->memory;
+
     FT_Byte*   pfb_data = NULL;
     int        i, type, flags;
     FT_ULong   len;
     /* Find the length of all the POST resources, concatenated.  Assume */
     /* worst case (each resource in its own section).                   */
     pfb_len = 0;
-    for ( i = 0; i < resource_cnt; ++i )
+    for ( i = 0; i < resource_cnt; i++ )
     {
       error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] );
       if ( error )
         goto Exit;
-      if ( FT_READ_ULONG( temp ) )
+      if ( FT_READ_ULONG( temp ) )  /* actually LONG */
         goto Exit;
 
       /* FT2 allocator takes signed long buffer length,
        */
       FT_TRACE4(( "                 POST fragment #%d: length=0x%08x"
                   " total pfb_len=0x%08x\n",
-                  i, temp, pfb_len + temp + 6));
+                  i, temp, pfb_len + temp + 6 ));
+
       if ( FT_MAC_RFORK_MAX_LEN < temp               ||
            FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 )
       {
         FT_TRACE2(( "             MacOS resource length cannot exceed"
-                    " 0x%08x\n", FT_MAC_RFORK_MAX_LEN ));
+                    " 0x%08x\n",
+                    FT_MAC_RFORK_MAX_LEN ));
+
         error = FT_THROW( Invalid_Offset );
         goto Exit;
       }
       pfb_len += temp + 6;
     }
 
-    FT_TRACE2(( "             total buffer size to concatenate %d"
-                " POST fragments: 0x%08x\n",
-                 resource_cnt, pfb_len + 2));
-    if ( pfb_len + 2 < 6 ) {
+    FT_TRACE2(( "             total buffer size to concatenate"
+                " %d POST fragments: 0x%08x\n",
+                 resource_cnt, pfb_len + 2 ));
+
+    if ( pfb_len + 2 < 6 )
+    {
       FT_TRACE2(( "             too long fragment length makes"
-                  " pfb_len confused: pfb_len=0x%08x\n", pfb_len ));
+                  " pfb_len confused: pfb_len=0x%08x\n",
+                  pfb_len ));
+
       error = FT_THROW( Array_Too_Large );
       goto Exit;
     }
+
     if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
       goto Exit;
 
     pfb_pos     = 6;
     pfb_lenpos  = 2;
 
-    len = 0;
+    len  = 0;
     type = 1;
-    for ( i = 0; i < resource_cnt; ++i )
+
+    for ( i = 0; i < resource_cnt; i++ )
     {
       error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] );
       if ( error )
 
       if ( FT_READ_USHORT( flags ) )
         goto Exit2;
-      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
-                   i, offsets[i], rlen, flags ));
+
+      FT_TRACE3(( "POST fragment[%d]:"
+                  " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
+                  i, offsets[i], rlen, flags ));
 
       error = FT_ERR( Array_Too_Large );
-      /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
+
+      /* postpone the check of `rlen longer than buffer' */
+      /* until `FT_Stream_Read'                          */
+
       if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
       {
-        FT_TRACE3(( "    Skip POST fragment #%d because it is a comment\n", i ));
+        FT_TRACE3(( "    Skip POST fragment #%d because it is a comment\n",
+                    i ));
         continue;
       }
 
-      /* the flags are part of the resource, so rlen >= 2.  */
+      /* the flags are part of the resource, so rlen >= 2,  */
       /* but some fonts declare rlen = 0 for empty fragment */
       if ( rlen > 2 )
         rlen -= 2;
       else
       {
         FT_TRACE3(( "    Write POST fragment #%d header (4-byte) to buffer"
-                    " %p + 0x%08x\n", i, pfb_data, pfb_lenpos ));
+                    " %p + 0x%08x\n",
+                    i, pfb_data, pfb_lenpos ));
+
         if ( pfb_lenpos + 3 > pfb_len + 2 )
           goto Exit2;
+
         pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
         pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
         pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
           break;
 
         FT_TRACE3(( "    Write POST fragment #%d header (6-byte) to buffer"
-                    " %p + 0x%08x\n", i, pfb_data, pfb_pos ));
+                    " %p + 0x%08x\n",
+                    i, pfb_data, pfb_pos ));
+
         if ( pfb_pos + 6 > pfb_len + 2 )
           goto Exit2;
+
         pfb_data[pfb_pos++] = 0x80;
 
         type = flags >> 8;
-        len = rlen;
+        len  = rlen;
 
         pfb_data[pfb_pos++] = (FT_Byte)type;
         pfb_lenpos          = pfb_pos;
         goto Exit2;
 
       FT_TRACE3(( "    Load POST fragment #%d (%d byte) to buffer"
-                  " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos ));
+                  " %p + 0x%08x\n",
+                  i, rlen, pfb_data, pfb_pos ));
+
       error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
       if ( error )
         goto Exit2;
+
       pfb_pos += rlen;
     }
 
     error = FT_ERR( Array_Too_Large );
+
     if ( pfb_pos + 2 > pfb_len + 2 )
       goto Exit2;
     pfb_data[pfb_pos++] = 0x80;
                                   aface );
 
   Exit2:
-    if ( error == FT_ERR( Array_Too_Large ) )
+    if ( FT_ERR_EQ( error, Array_Too_Large ) )
       FT_TRACE2(( "  Abort due to too-short buffer to store"
                   " all POST fragments\n" ));
-    else if ( error == FT_ERR( Invalid_Offset ) )
+    else if ( FT_ERR_EQ( error, Invalid_Offset ) )
       FT_TRACE2(( "  Abort due to invalid offset in a POST fragment\n" ));
+
     if ( error )
       error = FT_ERR( Cannot_Open_Resource );
     FT_FREE( pfb_data );
 
     if ( FT_READ_LONG( rlen ) )
       goto Exit;
-    if ( rlen == -1 )
+    if ( rlen 1 )
       return FT_THROW( Cannot_Open_Resource );
     if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN )
       return FT_THROW( Invalid_Offset );
   {
     FT_Memory  memory = library->memory;
     FT_Error   error;
-    FT_Long    map_offset, rdara_pos;
+    FT_Long    map_offset, rdata_pos;
     FT_Long    *data_offsets;
     FT_Long    count;
 
 
     error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
-                                       &map_offset, &rdara_pos );
+                                       &map_offset, &rdata_pos );
     if ( error )
       return error;
 
     /* POST resources must be sorted to concatenate properly */
     error = FT_Raccess_Get_DataOffsets( library, stream,
-                                        map_offset, rdara_pos,
+                                        map_offset, rdata_pos,
                                         TTAG_POST, TRUE,
                                         &data_offsets, &count );
     if ( !error )
     /* sfnt resources should not be sorted to preserve the face order by
        QuickDraw API */
     error = FT_Raccess_Get_DataOffsets( library, stream,
-                                        map_offset, rdara_pos,
+                                        map_offset, rdata_pos,
                                         TTAG_sfnt, FALSE,
                                         &data_offsets, &count );
     if ( !error )
     FT_Long        dlen, offset;
 
 
-    if ( NULL == stream )
+    if ( !stream )
       return FT_THROW( Invalid_Stream_Operation );
 
     error = FT_Stream_Seek( stream, 0 );
                 const FT_Open_Args*  args,
                 FT_Long              face_index,
                 FT_Face             *aface )
+  {
+    return ft_open_face_internal( library, args, face_index, aface, 1 );
+  }
+
+
+  static FT_Error
+  ft_open_face_internal( FT_Library           library,
+                         const FT_Open_Args*  args,
+                         FT_Long              face_index,
+                         FT_Face             *aface,
+                         FT_Bool              test_mac_fonts )
   {
     FT_Error     error;
     FT_Driver    driver = NULL;
     FT_Module*   cur;
     FT_Module*   limit;
 
+#ifndef FT_CONFIG_OPTION_MAC_FONTS
+    FT_UNUSED( test_mac_fonts );
+#endif
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    FT_TRACE3(( "FT_Open_Face: " ));
+    if ( face_index < 0 )
+      FT_TRACE3(( "Requesting number of faces and named instances\n"));
+    else
+    {
+      FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL ));
+      if ( face_index & 0x7FFF0000L )
+        FT_TRACE3(( ", named instance %ld", face_index >> 16 ));
+      FT_TRACE3(( "\n" ));
+    }
+#endif
 
     /* test for valid `library' delayed to `FT_Stream_New' */
 
             goto Success;
 
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
-          if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
+          if ( test_mac_fonts                                           &&
+               ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
                FT_ERR_EQ( error, Table_Missing )                        )
           {
             /* TrueType but essential tables are missing */
         goto Fail2;
 
 #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
-      error = load_mac_face( library, stream, face_index, aface, args );
-      if ( !error )
+      if ( test_mac_fonts )
       {
-        /* We don't want to go to Success here.  We've already done that. */
-        /* On the other hand, if we succeeded we still need to close this */
-        /* stream (we opened a different stream which extracted the       */
-        /* interesting information out of this stream here.  That stream  */
-        /* will still be open and the face will point to it).             */
-        FT_Stream_Free( stream, external_stream );
-        return error;
+        error = load_mac_face( library, stream, face_index, aface, args );
+        if ( !error )
+        {
+          /* We don't want to go to Success here.  We've already done   */
+          /* that.  On the other hand, if we succeeded we still need to */
+          /* close this stream (we opened a different stream which      */
+          /* extracted the interesting information out of this stream   */
+          /* here.  That stream will still be open and the face will    */
+          /* point to it).                                              */
+          FT_Stream_Free( stream, external_stream );
+          return error;
+        }
       }
 
       if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
       destroy_face( memory, face, driver );
 
   Exit:
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( !error && face_index < 0 )
+    {
+      FT_TRACE3(( "FT_Open_Face: The font has %ld faces\n"
+                  "              and %ld named instances for face %ld\n",
+                  face->num_faces,
+                  face->style_flags >> 16,
+                  -face_index - 1 ));
+    }
+#endif
+
     FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
 
     return error;
     w = FT_PIX_ROUND( w );
     h = FT_PIX_ROUND( h );
 
+    if ( !w || !h )
+      return FT_THROW( Invalid_Pixel_Size );
+
     for ( i = 0; i < face->num_fixed_sizes; i++ )
     {
       FT_Bitmap_Size*  bsize = face->available_sizes + i;
       }
     }
 
+    FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" ));
+
     return FT_THROW( Invalid_Pixel_Size );
   }
 
     FT_CMap    cmap = NULL;
 
 
-    if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
+    if ( !clazz || !charmap || !charmap->face )
       return FT_THROW( Invalid_Argument );
 
     face   = charmap->face;
       FT_CMap     ucmap = FT_CMAP( face->charmap );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap  vcmap = FT_CMAP( charmap );
 
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap  vcmap = FT_CMAP( charmap );
 
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap    vcmap  = FT_CMAP( charmap );
         FT_Memory  memory = FT_FACE_MEMORY( face );
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap    vcmap  = FT_CMAP( charmap );
         FT_Memory  memory = FT_FACE_MEMORY( face );
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap    vcmap  = FT_CMAP( charmap );
         FT_Memory  memory = FT_FACE_MEMORY( face );
     if ( face && FT_IS_SFNT( face ) )
     {
       FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
-      if ( service != NULL )
+      if ( service )
         table = service->get_table( face, tag );
     }
 
       return FT_THROW( Invalid_Face_Handle );
 
     FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
-    if ( service == NULL )
+    if ( !service )
       return FT_THROW( Unimplemented_Feature );
 
     return service->load_table( face, tag, offset, buffer, length );
       return FT_THROW( Invalid_Face_Handle );
 
     FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
-    if ( service == NULL )
+    if ( !service )
       return FT_THROW( Unimplemented_Feature );
 
     return service->table_info( face, table_index, tag, &offset, length );
 
     face = charmap->face;
     FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
-    if ( service == NULL )
+    if ( !service )
       return 0;
     if ( service->get_cmap_info( charmap, &cmap_info ))
       return 0;
 
     face = charmap->face;
     FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
-    if ( service == NULL )
+    if ( !service )
       return -1;
     if ( service->get_cmap_info( charmap, &cmap_info ))
       return -1;
     if ( ft_trace_levels[trace_bitmap] >= 3 )
     {
       /* we convert to a single bitmap format for computing the checksum */
-      if ( !error )
+      if ( !error && slot->bitmap.buffer )
       {
         FT_Bitmap  bitmap;
         FT_Error   err;
 
   FT_BASE_DEF( FT_Pointer )
   ft_module_get_service( FT_Module    module,
-                         const char*  service_id )
+                         const char*  service_id,
+                         FT_Bool      global )
   {
     FT_Pointer  result = NULL;
 
       if ( module->clazz->get_interface )
         result = module->clazz->get_interface( module, service_id );
 
-      if ( result == NULL )
+      if ( global && !result )
       {
         /* we didn't find it, look in all other modules then */
         FT_Library  library = module->library;
             if ( cur[0]->clazz->get_interface )
             {
               result = cur[0]->clazz->get_interface( cur[0], service_id );
-              if ( result != NULL )
+              if ( result )
                 break;
             }
           }
 
         service = (FT_Service_TrueTypeEngine)
                     ft_module_get_service( module,
-                                           FT_SERVICE_ID_TRUETYPE_ENGINE );
+                                           FT_SERVICE_ID_TRUETYPE_ENGINE,
+                                           0 );
         if ( service )
           result = service->engine_type;
       }
index 4660c97..eac2ddb 100644 (file)
@@ -56,7 +56,7 @@
   {
     FT_Error       error;
     unsigned char  head[16], head2[16];
-    FT_Long        map_pos, rdata_len;
+    FT_Long        map_pos, map_len, rdata_len;
     int            allzeros, allmatch, i;
     FT_Long        type_list;
 
     if ( error )
       return error;
 
-    error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
+    error = FT_Stream_Read( stream, (FT_Byte*)head, 16 );
     if ( error )
       return error;
 
     /* ensure positive values */
-    if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 )
+    if ( head[0]  >= 0x80 ||
+         head[4]  >= 0x80 ||
+         head[8]  >= 0x80 ||
+         head[12] >= 0x80 )
       return FT_THROW( Unknown_File_Format );
 
     *rdata_pos = ( head[ 0] << 24 ) |
                  ( head[ 9] << 16 ) |
                  ( head[10] <<  8 ) |
                    head[11];
+    map_len    = ( head[12] << 24 ) |
+                 ( head[13] << 16 ) |
+                 ( head[14] <<  8 ) |
+                   head[15];
 
-    /* map_len = head[12] .. head[15] */
-
-    if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 )
+    /* the map must not be empty */
+    if ( !map_pos )
       return FT_THROW( Unknown_File_Format );
 
-    if ( FT_LONG_MAX - rfork_offset < *rdata_pos ||
-         FT_LONG_MAX - rfork_offset < map_pos    )
+    /* check whether rdata and map overlap */
+    if ( *rdata_pos < map_pos )
+    {
+      if ( *rdata_pos > map_pos - rdata_len )
+        return FT_THROW( Unknown_File_Format );
+    }
+    else
+    {
+      if ( map_pos > *rdata_pos - map_len )
+        return FT_THROW( Unknown_File_Format );
+    }
+
+    /* check whether end of rdata or map exceeds stream size */
+    if ( FT_LONG_MAX - rdata_len < *rdata_pos                               ||
+         FT_LONG_MAX - map_len < map_pos                                    ||
+
+         FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset            ||
+         FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset                 ||
+
+         (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size ||
+         (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size      )
       return FT_THROW( Unknown_File_Format );
 
     *rdata_pos += rfork_offset;
 
     allzeros = 1;
     allmatch = 1;
-    for ( i = 0; i < 16; ++i )
+    for ( i = 0; i < 16; i++ )
     {
       if ( head2[i] != 0 )
         allzeros = 0;
 
     /* If we have reached this point then it is probably a mac resource */
     /* file.  Now, does it contain any interesting resources?           */
-    /* Skip handle to next resource map, the file resource number, and  */
-    /* attributes.                                                      */
+
     (void)FT_STREAM_SKIP( 4        /* skip handle to next resource map */
                           + 2      /* skip file resource number */
                           + 2 );   /* skip attributes */
 
-    if ( FT_READ_USHORT( type_list ) )
+    if ( FT_READ_SHORT( type_list ) )
       return error;
-    if ( type_list == -1 )
+    if ( type_list < 0 )
       return FT_THROW( Unknown_File_Format );
 
     error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) );
     if ( error )
       return error;
 
-    if ( FT_READ_USHORT( cnt ) )
+    if ( FT_READ_SHORT( cnt ) )
       return error;
     cnt++;
 
-    for ( i = 0; i < cnt; ++i )
+    /* `rpos' is a signed 16bit integer offset to resource records; the    */
+    /* size of a resource record is 12 bytes.  The map header is 28 bytes, */
+    /* and a type list needs 10 bytes or more.  If we assume that the name */
+    /* list is empty and we have only a single entry in the type list,     */
+    /* there can be at most                                                */
+    /*                                                                     */
+    /*   (32768 - 28 - 10) / 12 = 2727                                     */
+    /*                                                                     */
+    /* resources.                                                          */
+    /*                                                                     */
+    /* A type list starts with a two-byte counter, followed by 10-byte     */
+    /* type records.  Assuming that there are no resources, the number of  */
+    /* type records can be at most                                         */
+    /*                                                                     */
+    /*   (32768 - 28 - 2) / 8 = 4079                                       */
+    /*                                                                     */
+    if ( cnt > 4079 )
+      return FT_THROW( Invalid_Table );
+
+    for ( i = 0; i < cnt; i++ )
     {
       if ( FT_READ_LONG( tag_internal ) ||
-           FT_READ_USHORT( subcnt )     ||
-           FT_READ_USHORT( rpos )       )
+           FT_READ_SHORT( subcnt )      ||
+           FT_READ_SHORT( rpos )        )
         return error;
 
       FT_TRACE2(( "Resource tags: %c%c%c%c\n",
         *count = subcnt + 1;
         rpos  += map_offset;
 
+        /* a zero count might be valid in the resource specification, */
+        /* however, it is completely useless to us                    */
+        if ( *count < 1 || *count > 2727 )
+          return FT_THROW( Invalid_Table );
+
         error = FT_Stream_Seek( stream, (FT_ULong)rpos );
         if ( error )
           return error;
         if ( FT_NEW_ARRAY( ref, *count ) )
           return error;
 
-        for ( j = 0; j < *count; ++j )
+        for ( j = 0; j < *count; j++ )
         {
-          if ( FT_READ_USHORT( ref[j].res_id ) )
+          if ( FT_READ_SHORT( ref[j].res_id ) )
             goto Exit;
-          if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
+          if ( FT_STREAM_SKIP( 2 ) )  /* resource name offset */
             goto Exit;
-          if ( FT_READ_LONG( temp ) )
+          if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */
             goto Exit;
-          if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
+          if ( FT_STREAM_SKIP( 4 ) )  /* mbz */
+            goto Exit;
+
+          if ( ref[j].res_id < 0 || temp < 0 )
+          {
+            error = FT_THROW( Invalid_Table );
             goto Exit;
+          }
 
           ref[j].offset = temp & 0xFFFFFFL;
+
           FT_TRACE3(( "             [%d]:"
                       " resource_id=0x%04x, offset=0x%08x\n",
                       j, ref[j].res_id, ref[j].offset ));
         }
 
-        if (sort_by_res_id)
+        if ( sort_by_res_id )
         {
-          ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ),
-                    ( int(*)(const void*, const void*) )
-                    ft_raccess_sort_ref_by_id );
+          ft_qsort( ref,
+                    (size_t)*count,
+                    sizeof ( FT_RFork_Ref ),
+                    ( int(*)(const void*,
+                             const void*) )ft_raccess_sort_ref_by_id );
 
           FT_TRACE3(( "             -- sort resources by their ids --\n" ));
-          for ( j = 0; j < *count; ++ j ) {
+
+          for ( j = 0; j < *count; j++ )
             FT_TRACE3(( "             [%d]:"
                         " resource_id=0x%04x, offset=0x%08x\n",
                         j, ref[j].res_id, ref[j].offset ));
-          }
         }
 
         if ( FT_NEW_ARRAY( offsets_internal, *count ) )
          *      gap between reference IDs are acceptable?
          *      further investigation on Apple implementation is needed.
          */
-        for ( j = 0; j < *count; ++j )
+        for ( j = 0; j < *count; j++ )
           offsets_internal[j] = rdata_pos + ref[j].offset;
 
         *offsets = offsets_internal;
index ce79641..e0d5f82 100644 (file)
@@ -58,7 +58,7 @@
 
 
         /* load name on demand */
-        if ( entry->stringLength > 0 && entry->string == NULL )
+        if ( entry->stringLength > 0 && !entry->string )
         {
           FT_Memory  memory = face->memory;
           FT_Stream  stream = face->stream;
index fad7d1a..36d2dd7 100644 (file)
@@ -74,7 +74,7 @@
     if ( size > 0 )
     {
       block = memory->alloc( memory, size );
-      if ( block == NULL )
+      if ( !block )
         error = FT_THROW( Out_Of_Memory );
     }
     else if ( size < 0 )
     }
     else if ( cur_count == 0 )
     {
-      FT_ASSERT( block == NULL );
+      FT_ASSERT( !block );
 
       block = ft_mem_alloc( memory, new_count*item_size, &error );
     }
 
 
       block2 = memory->realloc( memory, cur_size, new_size, block );
-      if ( block2 == NULL )
+      if ( !block2 )
         error = FT_THROW( Out_Of_Memory );
       else
         block = block2;
index a381cf6..a2242be 100644 (file)
@@ -276,7 +276,7 @@ THE SOFTWARE.
 
         len = lengths[nn];
 
-        if ( src == NULL )
+        if ( !src )
           continue;
 
         /* separate elements with a space */
@@ -423,7 +423,7 @@ THE SOFTWARE.
       else
         bdfface->family_name = NULL;
 
-      if ( ( error = bdf_interpret_style( face ) ) != 0 )
+      if ( FT_SET_ERROR( bdf_interpret_style( face ) ) )
         goto Exit;
 
       /* the number of glyphs (with one slot for the undefined glyph */
@@ -439,7 +439,7 @@ THE SOFTWARE.
         FT_Short         resolution_x = 0, resolution_y = 0;
 
 
-        FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );
+        FT_ZERO( bsize );
 
         bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
 
@@ -866,10 +866,10 @@ THE SOFTWARE.
       0x10000L,
       0x20000L,
 
-      0,    /* module-specific interface */
+      NULL,    /* module-specific interface */
 
-      0,                        /* FT_Module_Constructor  module_init   */
-      0,                        /* FT_Module_Destructor   module_done   */
+      NULL,                     /* FT_Module_Constructor  module_init   */
+      NULL,                     /* FT_Module_Destructor   module_done   */
       bdf_driver_requester      /* FT_Module_Requester    get_interface */
     },
 
@@ -879,16 +879,16 @@ THE SOFTWARE.
 
     BDF_Face_Init,              /* FT_Face_InitFunc  init_face */
     BDF_Face_Done,              /* FT_Face_DoneFunc  done_face */
-    0,                          /* FT_Size_InitFunc  init_size */
-    0,                          /* FT_Size_DoneFunc  done_size */
-    0,                          /* FT_Slot_InitFunc  init_slot */
-    0,                          /* FT_Slot_DoneFunc  done_slot */
+    NULL,                       /* FT_Size_InitFunc  init_size */
+    NULL,                       /* FT_Size_DoneFunc  done_size */
+    NULL,                       /* FT_Slot_InitFunc  init_slot */
+    NULL,                       /* FT_Slot_DoneFunc  done_slot */
 
     BDF_Glyph_Load,             /* FT_Slot_LoadFunc  load_glyph */
 
-    0,                          /* FT_Face_GetKerningFunc   get_kerning  */
-    0,                          /* FT_Face_AttachFunc       attach_file  */
-    0,                          /* FT_Face_GetAdvancesFunc  get_advances */
+    NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
+    NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */
 
     BDF_Size_Request,           /* FT_Size_RequestFunc  request_size */
     BDF_Size_Select             /* FT_Size_SelectFunc   select_size  */
index e1dce95..7fd95a7 100644 (file)
     /* See whether this property type exists yet or not. */
     /* If not, create it.                                */
     propid = ft_hash_str_lookup( name, &(font->proptbl) );
-    if ( propid == NULL )
+    if ( !propid )
     {
       error = bdf_create_property( name, BDF_ATOM, font );
       if ( error )
       }
 
       fp = font->props + font->props_size;
-      FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) );
+      FT_ZERO( fp );
       font->props_size++;
     }
 
         p->font->comments[p->font->comments_len] = 0;
       }
     }
-    else if ( error == FT_Err_Ok )
+    else if ( !error )
       error = FT_THROW( Invalid_File_Format );
 
     *font = p->font;
index 4577a83..4d0b388 100644 (file)
     bzstream->next_in  = (char*)zip->buffer;
 
     if ( BZ2_bzDecompressInit( bzstream, 0, 0 ) != BZ_OK ||
-         bzstream->next_in == NULL                       )
+         !bzstream->next_in                              )
       error = FT_THROW( Invalid_File_Format );
 
   Exit:
index 8e6de8c..fc8905c 100644 (file)
   {
     {
       sizeof ( FTC_BasicFamilyRec ),
-      ftc_basic_family_compare,
-      ftc_basic_family_init,
-      0,                        /* FTC_MruNode_ResetFunc */
-      0                         /* FTC_MruNode_DoneFunc  */
+
+      ftc_basic_family_compare, /* FTC_MruNode_CompareFunc  node_compare */
+      ftc_basic_family_init,    /* FTC_MruNode_InitFunc     node_init    */
+      NULL,                     /* FTC_MruNode_ResetFunc    node_reset   */
+      NULL                      /* FTC_MruNode_DoneFunc     node_done    */
     },
-    ftc_basic_family_load_glyph
+
+    ftc_basic_family_load_glyph /* FTC_IFamily_LoadGlyphFunc  family_load_glyph */
   };
 
 
   const FTC_GCacheClassRec  ftc_basic_image_cache_class =
   {
     {
-      ftc_inode_new,
-      ftc_inode_weight,
-      ftc_gnode_compare,
-      ftc_basic_gnode_compare_faceid,
-      ftc_inode_free,
+      ftc_inode_new,                  /* FTC_Node_NewFunc      node_new           */
+      ftc_inode_weight,               /* FTC_Node_WeightFunc   node_weight        */
+      ftc_gnode_compare,              /* FTC_Node_CompareFunc  node_compare       */
+      ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc  node_remove_faceid */
+      ftc_inode_free,                 /* FTC_Node_FreeFunc     node_free          */
 
       sizeof ( FTC_GCacheRec ),
-      ftc_gcache_init,
-      ftc_gcache_done
+      ftc_gcache_init,                /* FTC_Cache_InitFunc    cache_init         */
+      ftc_gcache_done                 /* FTC_Cache_DoneFunc    cache_done         */
     },
+
     (FTC_MruListClass)&ftc_basic_image_family_class
   };
 
   {
     {
       sizeof ( FTC_BasicFamilyRec ),
-      ftc_basic_family_compare,
-      ftc_basic_family_init,
-      0,                            /* FTC_MruNode_ResetFunc */
-      0                             /* FTC_MruNode_DoneFunc  */
+      ftc_basic_family_compare,     /* FTC_MruNode_CompareFunc  node_compare */
+      ftc_basic_family_init,        /* FTC_MruNode_InitFunc     node_init    */
+      NULL,                         /* FTC_MruNode_ResetFunc    node_reset   */
+      NULL                          /* FTC_MruNode_DoneFunc     node_done    */
     },
+
     ftc_basic_family_get_count,
     ftc_basic_family_load_bitmap
   };
   const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
   {
     {
-      ftc_snode_new,
-      ftc_snode_weight,
-      ftc_snode_compare,
-      ftc_basic_gnode_compare_faceid,
-      ftc_snode_free,
+      ftc_snode_new,                  /* FTC_Node_NewFunc      node_new           */
+      ftc_snode_weight,               /* FTC_Node_WeightFunc   node_weight        */
+      ftc_snode_compare,              /* FTC_Node_CompareFunc  node_compare       */
+      ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc  node_remove_faceid */
+      ftc_snode_free,                 /* FTC_Node_FreeFunc     node_free          */
 
       sizeof ( FTC_GCacheRec ),
-      ftc_gcache_init,
-      ftc_gcache_done
+      ftc_gcache_init,                /* FTC_Cache_InitFunc    cache_init         */
+      ftc_gcache_done                 /* FTC_Cache_DoneFunc    cache_done         */
     },
+
     (FTC_MruListClass)&ftc_basic_sbit_family_class
   };
 
index 3b1a4bc..de20255 100644 (file)
         for (;;)
         {
           node = *pnode;
-          if ( node == NULL )
+          if ( !node )
             break;
 
           if ( node->hash & ( mask + 1 ) )
       FTC_Node  node = *pnode;
 
 
-      if ( node == NULL )
+      if ( !node )
       {
         FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" ));
         return;
     cache = manager->caches[node->cache_index];
 
 #ifdef FT_DEBUG_ERROR
-    if ( cache == NULL )
+    if ( !cache )
     {
       FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
       return;
     FTC_Node_CompareFunc  compare = cache->clazz.node_compare;
 
 
-    if ( cache == NULL || anode == NULL )
+    if ( !cache || !anode )
       return FT_THROW( Invalid_Argument );
 
     /* Go to the `top' node of the list sharing same masked hash */
     for (;;)
     {
       node = *pnode;
-      if ( node == NULL )
+      if ( !node )
         goto NewNode;
 
       if ( node->hash == hash                           &&
       /* Update pnode by modified linked list */
       while ( *pnode != node )
       {
-        if ( *pnode == NULL )
+        if ( !*pnode )
         {
           FT_ERROR(( "FTC_Cache_Lookup: oops!!!  node missing\n" ));
           goto NewNode;
         FT_Bool   list_changed = FALSE;
 
 
-        if ( node == NULL )
+        if ( !node )
           break;
 
         if ( cache->clazz.node_remove_faceid( node, face_id,
index 1b12959..ab4ea51 100644 (file)
@@ -227,7 +227,7 @@ FT_BEGIN_HEADER
     for (;;)                                                             \
     {                                                                    \
       _node = *_pnode;                                                   \
-      if ( _node == NULL )                                               \
+      if ( !_node )                                                      \
         goto NewNode_;                                                   \
                                                                          \
       if ( _node->hash == _hash                             &&           \
@@ -245,7 +245,7 @@ FT_BEGIN_HEADER
       /* Update _pnode by possibly modified linked list */               \
       while ( *_pnode != _node )                                         \
       {                                                                  \
-        if ( *_pnode == NULL )                                           \
+        if ( !*_pnode )                                                  \
         {                                                                \
           FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" ));  \
           goto NewNode_;                                                 \
@@ -325,7 +325,7 @@ FT_BEGIN_HEADER
         break;                                                    \
                                                                   \
       _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
-      if ( _try_done > 0 && ( list_changed != NULL ) )            \
+      if ( _try_done > 0 && list_changed != NULL )                \
         *(FT_Bool*)( list_changed ) = TRUE;                       \
                                                                   \
       if ( _try_done == 0 )                                       \
index 41a0ce9..f0a85f9 100644 (file)
   static
   const FTC_CacheClassRec  ftc_cmap_cache_class =
   {
-    ftc_cmap_node_new,
-    ftc_cmap_node_weight,
-    ftc_cmap_node_compare,
-    ftc_cmap_node_remove_faceid,
-    ftc_cmap_node_free,
+    ftc_cmap_node_new,           /* FTC_Node_NewFunc      node_new           */
+    ftc_cmap_node_weight,        /* FTC_Node_WeightFunc   node_weight        */
+    ftc_cmap_node_compare,       /* FTC_Node_CompareFunc  node_compare       */
+    ftc_cmap_node_remove_faceid, /* FTC_Node_CompareFunc  node_remove_faceid */
+    ftc_cmap_node_free,          /* FTC_Node_FreeFunc     node_free          */
 
     sizeof ( FTC_CacheRec ),
-    ftc_cache_init,
-    ftc_cache_done,
+    ftc_cache_init,              /* FTC_Cache_InitFunc    cache_init         */
+    ftc_cache_done,              /* FTC_Cache_DoneFunc    cache_done         */
   };
 
 
index 661a32a..9a25b97 100644 (file)
   const FTC_MruListClassRec  ftc_size_list_class =
   {
     sizeof ( FTC_SizeNodeRec ),
-    ftc_size_node_compare,
-    ftc_size_node_init,
-    ftc_size_node_reset,
-    ftc_size_node_done
+
+    ftc_size_node_compare,  /* FTC_MruNode_CompareFunc  node_compare */
+    ftc_size_node_init,     /* FTC_MruNode_InitFunc     node_init    */
+    ftc_size_node_reset,    /* FTC_MruNode_ResetFunc    node_reset   */
+    ftc_size_node_done      /* FTC_MruNode_DoneFunc     node_done    */
   };
 
 
   {
     sizeof ( FTC_FaceNodeRec),
 
-    ftc_face_node_compare,
-    ftc_face_node_init,
-    0,                          /* FTC_MruNode_ResetFunc */
-    ftc_face_node_done
+    ftc_face_node_compare,  /* FTC_MruNode_CompareFunc  node_compare */
+    ftc_face_node_init,     /* FTC_MruNode_InitFunc     node_init    */
+    NULL,                   /* FTC_MruNode_ResetFunc    node_reset   */
+    ftc_face_node_done      /* FTC_MruNode_DoneFunc     node_done    */
   };
 
 
                 manager->num_nodes ));
 #endif
 
-    if ( manager->cur_weight < manager->max_weight || first == NULL )
+    if ( manager->cur_weight < manager->max_weight || !first )
       return;
 
     /* go to last node -- it's a circular list */
 
 
     /* try to remove `count' nodes from the list */
-    if ( first == NULL )  /* empty list! */
+    if ( !first )  /* empty list! */
       return 0;
 
     /* go to last node - it's a circular list */
index d107584..7c460b9 100644 (file)
@@ -76,7 +76,7 @@
     FTC_MruNode  first = *plist;
 
 
-    FT_ASSERT( first != NULL );
+    FT_ASSERT( first );
 
     if ( first != node )
     {
     FTC_MruNode  prev, next;
 
 
-    FT_ASSERT( first != NULL );
+    FT_ASSERT( first );
 
 #ifdef FT_DEBUG_ERROR
       {
                    FTC_MruNode  *anode )
   {
     FT_Error     error;
-    FTC_MruNode  node = NULL;
+    FTC_MruNode  node   = NULL;
     FT_Memory    memory = list->memory;
 
 
 
 
     node = FTC_MruList_Find( list, key );
-    if ( node == NULL )
+    if ( !node )
       return FTC_MruList_New( list, key, anode );
 
     *anode = node;
 
 
     first = list->nodes;
-    while ( first && ( selection == NULL || selection( first, key ) ) )
+    while ( first && ( !selection || selection( first, key ) ) )
     {
       FTC_MruList_Remove( list, first );
       first = list->nodes;
index ae3c4ce..27ad55a 100644 (file)
@@ -108,6 +108,7 @@ FT_BEGIN_HEADER
   typedef struct  FTC_MruListClassRec_
   {
     FT_Offset                node_size;
+
     FTC_MruNode_CompareFunc  node_compare;
     FTC_MruNode_InitFunc     node_init;
     FTC_MruNode_ResetFunc    node_reset;
@@ -115,6 +116,7 @@ FT_BEGIN_HEADER
 
   } FTC_MruListClassRec;
 
+
   typedef struct  FTC_MruListRec_
   {
     FT_UInt              num_nodes;
index d6f1ddc..78cd8de 100644 (file)
        *
        */
 
-      if ( sbit->buffer == NULL && sbit->width == 255 )
+      if ( !sbit->buffer && sbit->width == 255 )
       {
         FT_ULong  size;
         FT_Error  error;
index 89f3e9f..6796450 100644 (file)
@@ -58,7 +58,7 @@
                      FT_Error*     error,
                      size_t        sizeItem )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     /* initialize the structure */
     arrstack->memory    = memory;
@@ -78,7 +78,7 @@
     FT_Memory  memory = arrstack->memory;     /* for FT_FREE */
 
 
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     arrstack->allocated = 0;
     arrstack->count     = 0;
@@ -95,7 +95,7 @@
   cf2_arrstack_setNumElements( CF2_ArrStack  arrstack,
                                size_t        numElements )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     {
       FT_Error   error  = FT_Err_Ok;        /* for FT_REALLOC */
   cf2_arrstack_setCount( CF2_ArrStack  arrstack,
                          size_t        numElements )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     if ( numElements > arrstack->allocated )
     {
   FT_LOCAL_DEF( void )
   cf2_arrstack_clear( CF2_ArrStack  arrstack )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     arrstack->count = 0;
   }
   FT_LOCAL_DEF( size_t )
   cf2_arrstack_size( const CF2_ArrStack  arrstack )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     return arrstack->count;
   }
   FT_LOCAL_DEF( void* )
   cf2_arrstack_getBuffer( const CF2_ArrStack  arrstack )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     return arrstack->ptr;
   }
     void*  newPtr;
 
 
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     if ( idx >= arrstack->count )
     {
   cf2_arrstack_push( CF2_ArrStack  arrstack,
                      const void*   ptr )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     if ( arrstack->count == arrstack->allocated )
     {
       }
     }
 
-    FT_ASSERT( ptr != NULL );
+    FT_ASSERT( ptr );
 
     {
       size_t  offset = arrstack->count * arrstack->sizeItem;
index b5595a3..e3dd69f 100644 (file)
@@ -44,7 +44,7 @@
   cf2_setError( FT_Error*  error,
                 FT_Error   value )
   {
-    if ( error && *error == 0 )
+    if ( error && !*error )
       *error = value;
   }
 
index 74af377..2e4b503 100644 (file)
@@ -51,8 +51,8 @@ FT_BEGIN_HEADER
 
 #define CF2_FIXED_MAX      ( (CF2_Fixed)0x7FFFFFFFL )
 #define CF2_FIXED_MIN      ( (CF2_Fixed)0x80000000L )
-#define CF2_FIXED_ONE      0x10000L
-#define CF2_FIXED_EPSILON  0x0001
+#define CF2_FIXED_ONE      ( (CF2_Fixed)0x10000L )
+#define CF2_FIXED_EPSILON  ( (CF2_Fixed)0x0001 )
 
   /* in C 89, left and right shift of negative numbers is  */
   /* implementation specific behaviour in the general case */
index 83fd348..a86e361 100644 (file)
   }
 
 
-  /* set up values for the current FontDict and matrix */
+  /* set up values for the current FontDict and matrix; */
+  /* called for each glyph to be rendered               */
 
   /* caller's transform is adjusted for subpixel positioning */
   static void
 
     FT_Bool  needExtraSetup = FALSE;
 
+    CFF_VStoreRec*  vstore;
+    FT_Bool         hasVariations = FALSE;
+
     /* character space units */
     CF2_Fixed  boldenX = font->syntheticEmboldeningAmountX;
     CF2_Fixed  boldenY = font->syntheticEmboldeningAmountY;
     CFF_SubFont  subFont;
     CF2_Fixed    ppem;
 
+    CF2_UInt   lenNormalizedV = 0;
+    FT_Fixed*  normalizedV    = NULL;
+
 
     /* clear previous error */
     font->error = FT_Err_Ok;
       needExtraSetup    = TRUE;
     }
 
+    /* check for variation vectors */
+    vstore        = cf2_getVStore( decoder );
+    hasVariations = ( vstore->dataCount != 0 );
+
+    if ( hasVariations )
+    {
+#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 ( cff_blend_check_vector( &subFont->blend,
+                                   subFont->private_dict.vsindex,
+                                   lenNormalizedV,
+                                   normalizedV ) )
+      {
+        /* blend has changed, reparse */
+        cff_load_private_dict( decoder->cff,
+                               subFont,
+                               lenNormalizedV,
+                               normalizedV );
+        needExtraSetup = TRUE;
+      }
+#endif
+
+      /* copy from subfont */
+      font->blend.font = subFont->blend.font;
+
+      /* clear state of charstring blend */
+      font->blend.usedBV = FALSE;
+
+      /* initialize value for charstring */
+      font->vsindex = subFont->private_dict.vsindex;
+
+      /* store vector inputs for blends in charstring */
+      font->lenNDV = lenNormalizedV;
+      font->NDV    = normalizedV;
+    }
+
     /* if ppem has changed, we need to recompute some cached data         */
     /* note: because of CID font matrix concatenation, ppem and transform */
     /*       do not necessarily track.                                    */
 
       /* compute blue zones for this instance */
       cf2_blues_init( &font->blues, font );
-    }
+
+    } /* needExtraSetup */
   }
 
 
index bd05e69..17ecd17 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "cf2ft.h"
 #include "cf2blues.h"
+#include "cffload.h"
 
 
 FT_BEGIN_HEADER
@@ -63,6 +64,7 @@ FT_BEGIN_HEADER
     FT_Memory  memory;
     FT_Error   error;     /* shared error for this instance */
 
+    FT_Bool             isCFF2;
     CF2_RenderingFlags  renderingFlags;
 
     /* variables that depend on Transform:  */
@@ -74,6 +76,12 @@ FT_BEGIN_HEADER
     CF2_Matrix  outerTransform;    /* post hinting; includes rotations */
     CF2_Fixed   ppem;              /* transform-dependent              */
 
+    /* variation data */
+    CFF_BlendRec  blend;            /* cached charstring blend vector  */
+    CF2_UInt      vsindex;          /* current vsindex                 */
+    CF2_UInt      lenNDV;           /* current length NDV or zero      */
+    FT_Fixed*     NDV;              /* ptr to current NDV or NULL      */
+
     CF2_Int  unitsPerEm;
 
     CF2_Fixed  syntheticEmboldeningAmountX;   /* character space units */
index 55f3206..c0d067e 100644 (file)
       FT_Memory  memory = font->memory;
 
 
-      (void)memory;
+      FT_FREE( font->blend.lastNDV );
+      FT_FREE( font->blend.BV );
     }
   }
 
                     FT_Memory    memory,
                     FT_Error*    error )
   {
-    FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );
+    FT_ZERO( outline );
 
     outline->root.memory = memory;
     outline->root.error  = error;
     font = (CF2_Font)decoder->cff->cf2_instance.data;
 
     /* on first glyph, allocate instance structure */
-    if ( decoder->cff->cf2_instance.data == NULL )
+    if ( !decoder->cff->cf2_instance.data )
     {
       decoder->cff->cf2_instance.finalizer =
         (FT_Generic_Finalizer)cf2_free_instance;
                                &hinted,
                                &scaled );
 
+      /* copy isCFF2 boolean from TT_Face to CF2_Font */
+      font->isCFF2 = builder->face->isCFF2;
+
       font->renderingFlags = 0;
       if ( hinted )
         font->renderingFlags |= CF2_FlagsHinted;
   }
 
 
+  /* get pointer to VStore structure */
+  FT_LOCAL_DEF( CFF_VStore )
+  cf2_getVStore( CFF_Decoder*  decoder )
+  {
+    FT_ASSERT( decoder && decoder->cff );
+
+    return &decoder->cff->vstore;
+  }
+
+
+  /* get maxstack value from CFF2 Top DICT */
+  FT_LOCAL_DEF( FT_UInt )
+  cf2_getMaxstack( CFF_Decoder*  decoder )
+  {
+    FT_ASSERT( decoder && decoder->cff );
+
+    return decoder->cff->top_font.font_dict.maxstack;
+  }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  /* Get normalized design vector for current render request; */
+  /* return pointer and length.                               */
+  /*                                                          */
+  /* Note: Uses FT_Fixed not CF2_Fixed for the vector.        */
+  FT_LOCAL_DEF( FT_Error )
+  cf2_getNormalizedVector( CFF_Decoder*  decoder,
+                           CF2_UInt     *len,
+                           FT_Fixed*    *vec )
+  {
+    FT_ASSERT( decoder && decoder->builder.face );
+    FT_ASSERT( vec && len );
+
+    return cff_get_var_blend( decoder->builder.face, len, vec, NULL );
+  }
+#endif
+
+
   /* get `y_ppem' from `CFF_Size' */
   FT_LOCAL_DEF( CF2_Fixed )
   cf2_getPpemY( CFF_Decoder*  decoder )
index 8e55e84..b054a6e 100644 (file)
@@ -64,6 +64,18 @@ FT_BEGIN_HEADER
   FT_LOCAL( CFF_SubFont )
   cf2_getSubfont( CFF_Decoder*  decoder );
 
+  FT_LOCAL( CFF_VStore )
+  cf2_getVStore( CFF_Decoder*  decoder );
+
+  FT_LOCAL( FT_UInt )
+  cf2_getMaxstack( CFF_Decoder*  decoder );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  FT_LOCAL( FT_Error )
+  cf2_getNormalizedVector( CFF_Decoder*  decoder,
+                           CF2_UInt     *len,
+                           FT_Fixed*    *vec );
+#endif
 
   FT_LOCAL( CF2_Fixed )
   cf2_getPpemY( CFF_Decoder*  decoder );
index bbbe8e3..c8f7dfe 100644 (file)
         /* calculate all four possibilities; moves down are negative */
         CF2_Fixed  downMoveDown = 0 - fracDown;
         CF2_Fixed  upMoveDown   = 0 - fracUp;
-        CF2_Fixed  downMoveUp   = fracDown == 0
+        CF2_Fixed  downMoveUp   = ( fracDown == 0 )
                                     ? 0
                                     : cf2_intToFixed( 1 ) - fracDown;
-        CF2_Fixed  upMoveUp     = fracUp == 0
+        CF2_Fixed  upMoveUp     = ( fracUp == 0 )
                                     ? 0
                                     : cf2_intToFixed( 1 ) - fracUp;