We completely validate the accessed data from the 'GSUB' table, making this
field unnecessary.
* src/autofit/afglobal.h (AF_FaceGlobalsRec): Remove `gsub_length` field.
* src/autofit/afglobal.c (af_face_globals_new), src/autofit/afgsub.c
(af_parse_gsub): Updated.
As reported by clang 19.
* src/autofit/afadjust.c (add_substitute): Make first argument unsigned.
Update all callers.
Other minor signedness fixes.
(af_reverse_character_map_new): Minor signedness fixes.
* src/autofit/afgsub.c (af_hash_insert): Minor signedness fixes.
* src/autofit/aflatin.c
(af_glyph_hints_apply_vertical_separation_adjustments): Make third
argument unsigned.
Update all callers.
Other minor signedness fixes.
(af_latin_hints_apply): Minor signedness fixes.
* src/bdf/bdflib.c (bdf_parse_bitmap_): Minor signedness fix.
* src/truetype/ttobjs.c (tt_size_init_bytecode): Minor signedness fix.
Due to the new GSUB parsing we no longer need
`hb_ot_layout_lookup_get_glyph_alternates`.
This partially reverts commit 5d2fd7608a.
* CMakeLists.txt (HARFBUZZ_MIN_VERSION), meson.build (harfbuzz_dep),
builds/unix/configure.raw (harfbuzz_pkg): Set version to 2.0.0.
* src/autofit/ft-hb-decls.h: Remove entry for
`hb_ot_layout_lookup_get_glyph_alternates`.
With this commit, the start-up time for creating the reverse character map
gets reduced from more than 300% to about 25% (as tested with `arial.ttf`
version 7.00).
* src/autofit/afadjust.c [FT_CONFIG_OPTION_USE_HARFBUZZ]: Include
`afgsub.h`.
(add_substitute): New auxiliary function to recursively add elements to
the reverse cmap.
(af_reverse_character_map_new): New code that replaces the old code
removed in the previous commit.
Rip out some HarfBuzz code of `af_reverse_character_map_new`. The new code
comes immediately in a follow-up commit, making it easier to follow the
changes.
* src/autofit/afadjust.c (af_get_glyph_alternates_helper,
af_get_glyph_alternates): Remove.
(af_reverse_character_map_new): Remove code to create the `*map` hash.
Create an array of GSUB lookup indices for `SingleSubst` and
`AlternateSubst` lookup types to exit early if we have different types.
Also improve tracing.
* src/autofit/afglobal.h (AF_FaceGlobals) [FT_CONFIG_OPTION_USE_HARFBUZZ]:
New fields `gsub_length`, `gsub`, and `gsub_lookups_single_alternate`.
* src/autofit/afglobal.c [FT_CONFIG_OPTION_USE_HARFBUZZ]: Include
`afgsub.h`.
(af_face_globals_new) [FT_CONFIG_OPTION_USE_HARFBUZZ]: Call
`af_parse_gsub` to fill `gsub_lookups_single_alternate`.
(af_face_globals_free): Updated.
* src/autofit/afadjust.c (af_get_glyph_alternates_helper): Exit early if we
possible.
(af_reverse_character_map_new): Trace GSUB lookup indices to be checked.
Using HarfBuzz's API functions to construct the reverse map is too slow; we
have to call `hb_ot_layout_lookup_get_glyph_alternates` far too often
because it can only handle a single glyph at a time. For this reason we are
going to parse the GSUB table by ourselves.
The new non-local functions are `af_parse_gsub` and `af_map_lookup`.
* src/autofit/afgsub.c, src/autofit/afgsub.h: New files for parsing,
validating, and mapping the `SingleSubst` and `AlternateSubst` subtable
types of a GSUB table.
* src/autofit/autofit.c, src/autofit/rules.mk (AUTOF_DRV_SRC): Updated.
This commit actually implements what commit 43ec023e1a describes.
* src/autofit/ft-hb.c (FT_RTLD_FLAGS): New macro for `dlopen`; it uses
`RTLD_GLOBAL` only if `RTLD_DEFAULT` is available.
With this commit, the following warning gets removed.
```
In file included from src/autofit/autofit.c:21:0:
src/autofit/ft-hb.c: In function 'ft_hb_funcs_init':
src/autofit/ft-hb.c:75:35: warning:
variable 'version_atleast' set but not used [-Wunused-but-set-variable]
ft_hb_version_atleast_func_t version_atleast = NULL;
^~~~~~~~~~~~~~~
```
* src/autofit/ft-hb.c (ft_hb_funcs_init): Move `NULL` check of
`version_atleast` out of ifdefs.
Using `RTLD_DEFAULT` we see whether the process already has HarfBuzz linked
in, and reuse it. If this symbol is not defined it is tempting to use
`RTLD_GLOBAL` instead, which would make the library available to the whole
process. However, without `RTLD_DEFAULT`, we would risk loading a second
HarfBuzz library, and if the linker mixes them up, probably giving symbols
from the new library to other clients, we might get into trouble. For this
reason, we do not pass `RTLD_GLOBAL` to `dlopen`; the default is
`RTLD_LOCAL`, and the rest of the process won't see the loaded HarfBuzz and
hopefully all be happy.
See the added comment for an explanation.
This partially undoes commit f68733d4a8.
* src/autofit/afadjust.c (af_reverse_character_map_new): Always loop over all
elements of the adjustment database.
(in_range): Removed, no longer needed.
* src/autofit/afadjust.c (af_get_glyph_alternates): Move creation and
deletion of the `helper_result` set to...
(af_reverse_character_map_new): ...this function.
Gain for `arial.ttf` version 7.00: approx. 1%.
This commit, together with the previous one, makes the startup of the
auto-hinter much faster.
Note, though, that the startup time for handling the diacritic database is
still rather large. For example, loading `arial.ttf` version 7.00 followed
by auto-hinting a first Latin glyph is still approx. three times slower
than before the introduction of the database (this is because function
`hb_ot_layout_lookup_get_glyph_alternates` is called very often).
* src/autofit/afshaper.c (scripts): Rename this array to...
(af_hb_scripts): ...this and export it.
(af_shaper_get_coverage_hb): Updated.
* src/autofit/afshaper.h: Updated.
* src/autofit/afadjust.c (af_reverse_character_map_new): Pass the current
script to `hb_ot_layout_collect_lookups` to make HarfBuzz check less
lookups while searching for glyph alternates.
Build reverse cmap for characters of the current script style only.
* src/autofit/afadjust.c (in_range): New function.
(af_reverse_character_map_new): Pass `AF_StyleMetrics` instead of
`AF_FaceGlobals` so that we can access the current script style.
Use `in_range` to limit tested code points.
* src/autofit/afadjust.h: Updated.
* src/autofit/aflatin.c (af_latin_metrics_init): Updated.
* src/autofit/afglobal.h (AF_HAS_CMAP_ENTRY): New flag.
(AF_STYLE_MASK): Update value.
* src/autofit/afglobal.c (af_face_globals_compute_style_coverage): Set
`AF_HAS_CMAP_ENTRY`.
* src/autofit/afadjust.c (af_reverse_character_map_new): For the creation of
the reverse map, change code to handle glyphs with cmap entries before
glyphs without cmap entries. Doing so avoids some code redundancy and
reduces the number of hash lookups.
This is the clean-up from the previous commit.
* src/autofit/afadjust.c (af_reverse_character_map_entry_compare,
af_reverse_character_map_lookup, af_reverse_character_map_expand):
Removed.
* src/autofit/afadjust.h: Updated.
* src/autofit/aftypes.h (AF_ReverseMapEntry, AF_ReverseCharacterMap):
Removed.
This greatly simplifies the code.
* src/autofit/afadjust.c (af_reverse_character_map_new): Implement it.
(af_reverse_character_map_done): Updated.
* src/autofit/afadjust.h: Updated.
* src/autofit/aflatin.c
(af_glyph_hints_apply_vertical_separation_adjustments): Updated.
* src/autofit/aftypes.h: Include `fthash.h`.
(AF_StyleMetrics): Change type of `reverse_charmap` to `FT_Hash`.
The series of commits that introduced this adjustment support had some
flaws.
- If there were two diacritics on top of a base glyph, and the upper
diacritic was a tilde, the vertical centering correction was incorrectly
applied to the lower, non-tilde glyph instead of the tilde.
- The maximum value allowed to shift a glyph was too strict (and also not
handling rounding issues), causing some diacritics and combinations of
diacritics to be not shifted at all.
* src/autofit/aflatin.c
(af_glyph_hints_apply_vertical_separation_adjustments): Correctly handle
vertical centering correction.
The old algorithm removed segments from edges to make the auto-hinter ignore
a tilde. However, the implementation had two flaws.
- Edge array elements were moved around without reordering them afterwards.
- The linking between edges and segments wasn't correctly updated for moved
edges, which could cause endless loops.
Correcting both problems are non-trivial; additionally, a fix would make
the auto-hinter slower.
For these reasons, a new, simpler approach is taken: A new flag allows
points to be tagged as being ignored, and if such a point is enountered, it
doesn't get added to a segment.
Fixes issue #1333.
* src/autofit/afhints.h (AF_FLAG_IGNORE): New macro.
* src/autofit/aflatin.c (af_latin_hints_compute_segments, af_touch_contour):
Use it.
(af_remove_segments_containing_point, af_remove_top_points_from_edges,
af_remove_bottom_points_from_edges): Removed.
(af_latin_stretch_top_tilde): Call `af_touch_top_contours` and
`af_touch_bottom_contours` unconditionally.
(af_latin_hints_apply): Updated.
This commit does two things.
- Ignore accents that have too large heights. This situation can happen if
an accent outline is unexpectedly not the highest (or lowest) contour.
- Add a new adjustment flag `AF_ADJUST_NO_HEIGHT_CHECK` to override the
height check.
* src/autofit/afadjust.h (AF_ADJUST_NO_HEIGHT_CHECK): New macro.
* src/autofit/afadjust.c (adjustment_database): Updated.
* src/autofit/aflatin.c (af_latin_hints_apply): Handle new flag.
(af_glyph_hints_apply_vertical_separation_adjustments): Check limit.
* src/autofit/afadjust.h (AF_IGNORE_CAPITAL_TOP, AF_IGNORE_CAPITAL_BOTTOM,
AF_IGNORE_SMALL_TOP, AF_IGNORE_SMALL_BOTTOM): New macros.
* src/autofit/afadjust.c (af_reverse_character_map_new)
[FT_DEBUG_LEVEL_TRACE]: Updated.
Also fix debugging strings of other flags.
* src/autofit/afhints.h (AF_EDGE_NO_BLUE): New edge flag to make the
auto-hinter ignore the edge while assigning blue zones.
* src/autofit/aflatin.c (af_latin_hints_compute_blue_edges): Use it.
(af_prevent_top_blue_alignment, af_prevent_bottom_blue_alignment,
af_latin_get_base_glyph_blues, af_latin_ignore_top,
af_latin_ignore_bottom): New functions.
(af_latin_hints_apply): Updated.
Introduce blue zone properties that will be used to make the auto-hinter
ignore diacritics attached on the top or the bottom of a base character.
* src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_CAPITAL_BOTTOM,
AF_BLUE_PROPERTY_LATIN_SMALL_BOTTOM): New properties.
* src/autofit/afblue.dat: Use them.
* src/autofit/afblue.c, src/autofit/afblue.h: Rengenerated.
* src/autofit/aflatin.h (AF_LATIN_IS_CAPITAL_BOTTOM_BLUE,
AF_LATIN_IS_SMALL_BOTTOM_BLUE, AF_LATIN_BLUE_BOTTOM,
AF_LATIN_BLUE_BOTTOM_SMALL): New macros.
* src/autofit/aflatin.c (af_latin_metrics_init_blues)[FT_DEBUG_LEVEL_TRACE]:
Updated.
Handle the case where loading HarfBuzz dynamically fails.
* src/autofit/ft-hb.c, src/autofit/ft-hb.h (ft_hb_enabled): New function.
* src/autofit/afglobal.c (af_face_globals_new, af_face_globals_free):
Guard HarfBuzz functions with `ft_hb_enabled`.
* src/autofit/aflatin.c (af_latin_metrics_init_widths,
af_latin_metrics_init_blues, af_latin_metrics_check_digits): Simplify
setup of `shaper_buf`.
Guard calls of `af_shaper_buf_create` with `ft_hb_enabled`.
* src/autofit/afcjk.c (af_cjk_metrics_init_widths,
af_cjk_metrics_init_blues, af_cjk_metrics_check_digits): Dito.
* src/autofit/afshaper.c: Guard all HarfBuzz function calls with
`ft_hb_enabled`.
This commit activates the mini-HarfBuzz header files and provides the
necessary infrastructure for dynamically loading HarfBuzz if
`FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC` is defined (this macro gets set up
in a follow-up commit).
* src/autofit/ft-hb.c: New file, providing `ft_hb_funcs_init` and
`ft_hb_funcs_done` for loading HarfBuzz dynamically. The name of the
library is hold in the macro `FT_LIBHARFBUZZ`, which can be overridden.
* src/autofit/ft-hb.h: Don't include `hb.h` but `ft-hb-types.h`.
(hb): Modified to handle both standard linking and dynamically
loading of HarfBuzz.
(HB_EXTERN): New macro to load `ft-hb-decls.h`.
* src/autofit/afadjust.c [FT_CONFIG_OPTION_USE_HARFBUZZ]: For the sake of
dynamically loading the HarfBuzz library, replace the compile-time macro
`HB_VERSION_ATLEAST` with a call to the run-time function
`hb_version_atleast` where necessary – a follow-up commit will set the
minimum version of HarfBuzz to 2.6.8, which provides all necessary
functions needed by FreeType.
* src/autofit/afmodule.h: Include `ft-hb.h`.
(AF_ModuleRec) [FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC]: Add `hb_funcs`
structure to hold pointers to the dynamically loaded HarfBuzz functions.
* src/autofit/afmodule.c (af_autofitter_init, af_autofitter_done)
[FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC]: Call `ft_hb_funcs_init` and
`ft_hb_funcs_done`.
* src/autofit/afshaper.h: Updated.
* src/autofit/autofit.c: Include `ft-hb.c`.
* src/autofit/rules.mk (AUTOF_DRV_SRC, AUTOF_DRV_H): Updated.
Add 'mini' HarfBuzz declarations to make FreeType independent on HarfBuzz
header files.
The files get activated in a follow-up commit.
* src/autofit/ft-hb-decls.h, src/autofit/ft-hb-types.h: New files, holding
verbatim (or slightly massaged) entries from public HarfBuzz header files.
* src/autofit/hb-script: New file.
A verbatim copy of a public HarfBuzz header file.