We now request HarfBuzz version 2.6.8 (published in June 2020) or newer to
simplify the setup; this version introduced function
`hb_ot_layout_lookup_get_glyph_alternates`, which we need for the adjustment
database of the auto-hinter.
No CMake support yet for dynamic loading.
* include/freetype/config/ftoption.h, devel/ftoption.h
(FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC): New configuration macro.
* builds/unix/configure.raw: Implement `--with-harfbuzz=dynamic`.
This gets tested automatically if we can't link with `libharfbuzz`.
(ft_option_set, ft_option_unset): Refine.
Require at least HarfBuzz version 2.6.8.
* meson.build: Do the same as `configure.raw`.
* meson_options.txt: Updated.
* CMakeLists.txt: Require at least HarfBuzz version 2.6.8.
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.
* src/autofit/afshaper.c: Move around code so that the non-HarfBuzz code is
present even if `FT_CONFIG_OPTION_USE_HARFBUZZ` is not defined. This is a
preliminary step to allow deactivation of HarfBuzz at run-time.
Pass `AF_FaceGlobals` to many functions, or provide it, tagged with
`FT_UNUSED`. We need this later on to access a dynamically linked HarfBuzz
library.
* src/autofit/ft-hb-ft.h (ft_hb_ft_font_create): Use `globals` argument.
Drop unused `destroy` argument.
* src/autofit/ft-hb-ft.c (ft_hb_ft_face_create, ft_hb_ft_font_create): Use
`globals` argument.
Drop unused `destroy` argument.
(ft_hb_ft_face_create, ft_hb_ft_reference_table): Cast `user_data` to
`AF_FaceGlobals`.
* src/autofit/afadjust.c (af_get_glyph_alternates_helper,
af_get_glyph_alternates): Add `globals` argument.
Update callers.
* src/autofit/afshaper.c, src/autofit/afshaper.h (af_shaper_buf_create,
af_shaper_buf_destroy): Use `globals` argument.
* src/autofit/afglobal.c (af_face_globals_new): Updated.
* src/autofit/afcjk.c (af_cjk_metrics_init_widths,
af_cjk_metrics_init_blues, af_cjk_metrics_check_digits): Updated.
* src/autofit/aflatin.c (af_latin_metrics_init_widths,
af_latin_metrics_init_blues, af_latin_metrics_check_digits): Updated.
* src/autofit/ft-hb.h: New file, defining the `hb` macro. Later on, we
provide a different definition of this macro depending on a yet-to-come
configuration option to support dynamic loading of HarfBuzz functions.
* src/autofit/afadjust.c, src/autofit/afglobal.c, src/autofit/afshaper.c,
stc/ft-hb-ft.c: Use it.
This adds many pre-combined Latin glyphs, Cyrillic, Greek, and some
characters from other scripts (or rather, Unicode blocks).
Fixes issues #112 and #471.
This code catches situations like U+1F90 ('ᾐ'), where some fonts have
exactly the same vertical minimum for the lower accent as for the base
glyph.
* src/autofit/aflatin.c (af_find_highest_contour, af_find_lowest_contour):
Handle it.
The auto-hinter now supports up to four tilde glyphs (two above and two
below a base character).
Note that diacritics above (or below) a tilde are now also ignored by the
auto-hinter.
* src/autofit/afadjust.h (AF_ADJUST_TILDE_TOP2, AF_ADJUST_TILDE_BOTTOM2):
New macros.
* src/autofit/afadjust.c (af_reverse_character_map_new): Updated.
* src/autofit/aflatin.c (af_remove_top_points_from_edges,
af_remove_bottom_points_from_edges): Make functions also handle all
contours higher (or lower) of the given one in the argument.
(af_touch_top_contours, af_touch_bottom_contours): New functions.
(af_latin_stretch_top_tilde, af_latin_stretch_bottom_tilde): Use it to
also handle all contours higher (or lower) than the tilde contour.
* (af_latin_hints_apply): Handle more tilde glyphs.
* src/autofit/aflatin.c (af_latin_stretch_top_tilde,
af_latin_stretch_bottom_tilde): Return vertical size difference between
stretched and original contour.
(af_latin_align_top_tilde, af_latin_align_bottom_tilde): Return applied
delta.
(af_latin_hints_apply): Updated; the return values are not used yet.
Move some existing code that we soon need elsewhere into separate functions.
* src/autofit/aflatin.c (af_move_contours_up, af_move_contours, down): New
functions.
(af_glyph_hints_apply_vertical_separation_adjustments): Use them.
(af_touch_contour): New function.
(af_latin_stretch_top_tilde, af_latin_stretch_bottom_tilde): Use it.
(af_latin_remove_top_tilde_points_from_edges,
af_latin_remove_bottom_tilde_points_from_edges): Renamed to...
(af_remove_top_points_from_edges, af_remove_bottom_points_from_edges):
...this.
Update callers.
* src/autofit/aflatin.c (af_find_highest_contour, af_find_lowest_contour):
Updated.
(af_glyph_hints_apply_vertical_separation_adjustments): Use
`af_compute_vertical_extrema`, `af_find_highest_contour`, and
`af_find_lowest_contour`.
(af_latin_hints_apply): Use `af_compute_vertical_extrema`,
* src/autofit/afadjust.h (AF_ADJUST_TILDE_BOTTOM): New macro.
* src/autofit/afadjust.c (af_reverse_character_map_new): Updated.
* src/autofit/aflatin.c (af_find_lowest_contour,
af_latin_remove_bottom_tilde_points_from_edges,
af_latin_stretch_bottom_tilde, af_latin_align_bottom_tilde): New functions
in analogy to the top tilde versions.
(af_glyph_hints_apply_vertical_separation_adjustments): Add support in
analogy to the top tilde code.
(af_latin_hints_apply): Updated.
We are going to add more values, and we want to use combinations of them.
* src/autofit/afadjust.h (AF_VerticalSeparationAdjustmentType): Replace
with...
(AF_ADJUST_UP, AF_ADJUST_DOWN, AF_ADJUST_NONE): ... new macros.
(AF_AdjustmentDatabaseEntry): Rename field
`vertical_separation_adjustment_type` to `flags`.
* src/autofit/afadjust.c (af_reverse_character_map_new),
src/autofit/aflatin.c
(af_glyph_hints_apply_vertical_separation_adjustments): Updated.
As it turns out, the original implementation using
`hb_ot_shape_glyphs_closure` is extremely slow if a font has a rich set of
OpenType features. For example, this function was called 66954 times while
loading font `arial.ttf` version 7.00, increasing FreeType's startup time by
a factor of 10, which is unacceptable.
The new algorithm uses a completely different, more low-level approach, no
longer working with OpenType features but with OpenType lookups. It relies
on function `hb_ot_layout_lookup_get_glyph_alternates`, also replacing
recursion with a simple loop. In total, this brings the additional startup
time back to an acceptable range of a few percent.
A side effect of the new approach is that it catches more alternate forms:
the old code didn't properly handle script-specific features.
To make the change more readable, this commit only adds new code.
Reported as
https://bugs.ghostscript.com/show_bug.cgi?id=708295
* src/autofit/aflatin.c
(af_glyph_hints_apply_vertical_separation_adjustments): Initialize all
array elements of `contour_y_minima` and `contour_y_maxima`.