This commit adds support for kerning from 'GPOS' tables, while maintaining
support for basic 'kern' tables. `FT_HAS_KERNING` will be true for a font
with either available and `FT_Get_Kerning` will still use the basic 'kern'
table data if avilable, otherwise check the GPOS 'kern' feature.
This feature is disabled by default; it can be enabled with the
`TT_CONFIG_OPTION_GPOS_KERNING` flag.
Only basic kerning (pair positioning with just an x advance) is supported
from the GPOS layout features; support for that was added to make the
existing `FT_Get_Kerning` API more consistently functional. FreeType does
not intend to extend itself to further GPOS functionality though; a
higher-level library like HarfBuzz can be used instead for that.
* include/freetype/config/ftoption.h, include/devel/ftoption.h
(TT_CONFIG_OPTION_GPOS_KERNING): New configuration option.
* include/freetype/internal/fttrace.h: Add `ttgpos` trace handler.
* include/freetype/internal/sfnt.h (SFNT_Interface): Add `load_gpos` and
`get_gpos_kerning` fields.
(FT_DEFINE_SFNT_INTERFACE): Updated.
* include/freetype/internal/tttypes.h: Include `fttypes.h`.
(TT_FaceRec) [TT_CONFIG_OPTION_GPOS_KERNING]: Add `gpos_table` and
`gpos_kerning_available` fields.
* src/sfnt/ttgpos.c, src/sfnt/ttgpos.h: New files.
* src/sfnt/sfdriver.c [TT_CONFIG_OPTION_GPOS_KERNING]: Include `ttgpos.h`.
(sfnt_interface): Updated.
* src/sfnt/sfnt.c: Include `ttgpos.c`.
* src/sfnt/sfobjs.c [TT_CONFIG_OPTION_GPOS_KERNING]: Include `ttgpos.h`.
(sfnt_load_face) [TT_CONFIG_OPTION_GPOS_KERNING]: Load and free GPOS kerning
data; check GPOS kerning availability.
* src/truetype/ttdriver.c (tt_get_kerning): Use GPOS kerning if there's no
'kern' table.
As a result of 7b308a29dd, the regular 64-bit execution is now faster
than SSE2. The rendering speed of script fonts at 64 ppem or larger is
improved by about 3% without SSE2. See !314 for the testing results.
* src/smooth/ftgrays.c (gray_render_conic)[FT_INT64]: Remove SSE2 code.
A font has surfaced with `post` version 1.0 and fewer than 258 glyphs.
Its glyphs did not correspond to their names. We now reject such `post`
strictly following specifications.
* src/sfnt/ttpost.c (tt_face_get_ps_name): Check the number of glyphs
for version 1.0.
Reported as
https://bugs.chromium.org/p/chromium/issues/detail?id=1505216
* src/sfnt/ttcolr.c (find_base_glyph_v1_record): Guard access of the search
pointer during binary search. The pointer needs to be checked as we go as
the test that compares number of v1 glyphs with table size at the time of
loading the table is not sufficient on its own.
A scenario is possible in which the `BaseGlyphRecord` list extends into
non-`BaseGlyphRecord` parts of the 'COLR' v1 table (but passed the size
comparison check). Then, at those locations, invalid glyph ID values are
read and may provoke an invalid read due to reassigning min and max values
during the binary search.
This is a follow-up to commit 26a7f047,
[cff] Make blend operator work with floats in private dicts.
which addressed the 'party baseline' bug. However, the reporting user
indicated that the default location and some other points in design space
rendered OK, but other points in design space still had problems. The most
obvious issue being that the x-heights of lower-case letters did not align;
see
https://github.com/adobe-fonts/source-serif/issues/121#issuecomment-1773794136
After some analysis we determined that this was due to an interaction
between `BlueValue` rounding and the zone-based algorithm. In short, for a
point to be considered in a zone it must fall within the bounds of the zone.
(There is a slop factor in some cases, but only a very small one.) In the
Adobe-contributed side of the code, point values are not integer-rounded,
instead they're kept as (some form of) fixed. Rounding just the `BlueValues`
means that points that need to be considered within a zone will fall outside
of it at some points in design space.
The majority of this patch changes the storage and parsing of `BlueValues`
to keep them as `FT_Fixed`. No significant code changes were needed because
the values are converted to `Fixed` anyway when stored in `CF_BlueRec`. No
attempt was made to address problems in the older pshinter code beyond
converting the values from `FT_Fixed` to `FT_Short` when copying the private
dictionary. (However, as the point values are also rounded in that code,
the problem is much less likely to occur, although inconsistency between
rounding and truncation could cause an analogous problem.)
* include/freetype/internal/cfftypes.h (CFF_PrivateRec): Use `FT_Fixed` for
`blue_values`, `other_blues`, `family_blues`, and `family_other_blues`.
* src/cff/cffload.c (cff_blend_doBlend): Updated.
* src/cff/cffobjs.c (CFF_fixedToInt): New macro.
(cff_make_private_dict): Use it.
* src/cff/cffparse.h (cff_kind_delta_fixed): New enum value.
* src/cff/cffparse.c (do_fixed): Updated.
(CFF_FIELD_DELTA, CFF_FIELD_DELTA_FIXED, CFF_DELTA_KIND): New set of macros,
replacing `CFF_FIELD_DELTA`.
(cff_parser_run): Updated to handle fixed-float deltas.
* src/cff/cfftoken.h: Updated to use `CFF_FIELD_DELTA_FIXED` for blue
values.
* src/psaux/psblues.c (cf2_blueToFixed): Removed, no longer needed.
(cf2_blues_init): Updated.
* src/pxaux/psft.c, src/pxaux/psft.h (cf2_getBlueValues, cf2_getOtherBlues,
cf2_getFamilyBlues, cf2_getFamilyOtherBlues): Updated signatures.
* src/psaux/psobjs.c (t1_make_subfont): Updated.
MSBuild.exe can now be fired from the root folder without options.
* builds/windows/vc2010/freetype.sln: Relocated to...
* MSBuild.sln: ... here with minor changes.
* MSBuild.rsp: New file with command line options.
* docs/INSTALL: Reference `MSBuild.sln`.
While it is recommended to have an explicit point at each curve
extrema, they might be missing or outline could be rotated. This
leads to excessive bisections in raster to find them. This change
helps to decrease the number of bisections. The scanline
intersections remain monotonous, of course.
* src/raster/ftraster.c (Conic_To, Cubic_To): Check that control
points cross the scanlines to bisect.
This reduces the code duplication.
* src/raster/ftraster.c (Function_Sweep_Span): Change signature.
(Vertical_Sweep_Drop, Horizontal_Sweep_Drop): Focus on pixel setting
and move duplicated the dropout control logic to...
(Draw_Sweep): ... this function and refactor.
(Vertical_Sweep_Span, Horizontal_Sweep_Span): Minor.
This results in noticeable performance improvement.
* src/raster/ftraster.c (Insert_Y_Turns): All bottom y-turns are still
sorted and stored; only the maximum top y-turn is recorded now. The
function is renamed.
(End_Profile): Updated accordingly.
(Convert_Glyph): Reserve space for the top value.
* src/raster/ftraster.c (black_TWorker): Remove the fresh flag.
(New_Profile): Set the starting scanline here based on the current
coordinate and initialize the joint crossing if necessary.
(Line_Up, Bezier_Up): Do not deal with fresh and joint starts at all.
(Line_Down, Bezier_Down): Simplify.
(Conic_To, Cubic_To): Update the current coordinate after each
subsection.
* src/raster/ftraster.c (Line_Up, Bezier_Up): Deal with the scanline
joints directly based on the initial y-coordinate.
(New_Profile, black_TWorker): Remove the boolean flag.
* src/raster/ftraster.c (black_TWorker): Store signed maximum indexes
in both directions instead of unsigned dimensions of the original bitmap.
(*_Sweep_*, Render_Glyph, ft_black_render): Updated all users.
* src/raster/ftraster.c (TProfile): Get rid of `countL`.
(Draw_Sweep): Use `start` for countdown to activation.
(Horizontal_Sweep_Drop, Vertical_Sweep_Drop): Rely on `height` and
`offset` to verify profile ends for the stub detection.
* src/raster/ftraster.c (s/Sort/Increment): Rename this function to
reflect its true purpose, delete exhausted profiles here...
(Draw_Sweep): ... instead of here.
While curving close to a pixel center, vertical and horizontal pass
might split the curve differently and cause a rare dropout. This
makes the split condition invariant of the sweep direction and more
robust.
* src/raster/ftraster.c (Bezier_Up): Modify the split condition.