Commit graph

8208 commits

Author SHA1 Message Date
Werner Lemberg
25369eca99 [autofit] Avoid recomputation of highest and lowest contour.
* src/autofit/aflatin.c (af_latin_hints_apply): Compute highest and lowest
  contour in this function.
  (af_latin_remove_top_tilde_points_from_edges,
  af_latin_remove_bottom_tilde_points_from_edges,
  af_latin_stretch_top_tilde, af_latin_stretch_bottom_tilde,
  af_latin_align_top_tilde, af_latin_align_bottom_tilde): Updated.
2025-04-28 17:52:35 +00:00
Werner Lemberg
64da9d4798 * src/aflatin.c (af_latin_trace_height): Remove.
Update caller.

The algorithm works fine.
2025-04-28 17:52:35 +00:00
Werner Lemberg
ba94c9547e [autofit] Support vertical stretching of tilde below base glyph. (2/2)
* 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.
2025-04-28 17:52:35 +00:00
Werner Lemberg
ec28f4880b [autofit] Support vertical stretching of tilde below base glyph. (1/2)
* src/autofit/aflatin.c (af_latin_remove_tilde_points_from_edges,
  af_latin_stretch_tilde, af_latin_align_tilde): Rename to...
  (af_latin_remove_top_tilde_points_from_edges, af_latin_stretch_top_tilde,
  af_latin_align_top_tilde): ...this.
  Update all callers.
  (af_latin_hints_apply): Rename `is_tilde` to `is_top_tilde`.
2025-04-28 17:52:35 +00:00
Werner Lemberg
8d1f51565a [autofit] Allow vertical adjustment at the top and bottom simultaneously.
This will be used to hint characters like U+1FB7 ('ᾷ').

* src/autofit/aflatin.c
  (af_glyph_hints_apply_vertical_separation_adjustments): Implement it.
2025-04-28 17:52:35 +00:00
Werner Lemberg
5e0b08713c * src/autofit/afadjust.c (af_reverse_character_map_new): Update tracing. 2025-04-28 17:52:35 +00:00
Werner Lemberg
162a93b101 [autofit] Indicate tilde handling with a flag macro, too.
* src/autofit/afadjust.h (AF_ADJUST_TILDE_TOP): New macro.
  (AF_AdjustmentDatabaseEntry): Remove field `apply_tilde`.

* src/autofit/afadjust.c (adjustment_database,
  af_reverse_character_map_new), src/autofit/aflatin.c
  (af_glyph_hints_apply_vertical_separation_adjustments,
  af_latin_hints_apply): Updated.
2025-04-28 17:52:35 +00:00
Werner Lemberg
582cc21bed [aflatin] Convert adjustment database enum to macros.
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.
2025-04-28 17:52:35 +00:00
Werner Lemberg
566e30c176 [autofit] Shorten adjustment enum names.
* src/autofit/afadjust.h (AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP,
  AF_VERTICAL_ADJUSTMENT_BOTTOM_CONTOUR_DOWN, AF_VERTICAL_ADJUSTMENT_NONE):
  Renamed to...
  (AF_ADJUST_UP, AF_ADJUST_DOWN, AF_ADJUST_NONE): ...this.

* src/autofit/afadjust.c (adjustment_database,
  af_reverse_character_map_expand), src/autofit/aflatin.c
  (af_glyph_hints_apply_vertical_separation_adjustments): Updated.
2025-04-28 17:52:35 +00:00
Werner Lemberg
1da283b8ae * src/autofit/afranges.c: Updated to Unicode 17.0.
But no support for new scripts (volunteers welcomed).
2025-04-26 10:05:02 +02:00
Werner Lemberg
3ce99005fd * src/autofit/afranges.c: Updated to Unicode 16.0.
But no support for new scripts (volunteers welcomed).
2025-04-26 10:05:02 +02:00
Werner Lemberg
08a13fe202 * src/autofit/afranges.c: Updated to Unicode 15.1.
But no support for new scripts (volunteers welcomed).
2025-04-26 10:05:00 +02:00
Werner Lemberg
3019fa6cb1 * src/autofit/afranges.c: Updated to Unicode 14.0.
But no support for new scripts (volunteers welcomed).
2025-04-26 09:56:44 +02:00
Werner Lemberg
373aa74487 * src/autofit/afranges.c: Updated to Unicode 13.0.
But no support for new scripts (volunteers welcomed).
2025-04-26 09:56:41 +02:00
Werner Lemberg
12a9f65d7f * src/autofit/afranges.c: Updated to Unicode 12.0.
But no support for new scripts (volunteers welcomed).
2025-04-26 08:17:00 +02:00
Alexei Podtelezhnikov
3467c2177c * include/freetype/internal/ftcalc.h (FT_MulFix_64): Silence UBSAN. 2025-04-25 08:09:48 -04:00
Behdad Esfahbod
1019b1c2b9 * src/autofit/afadjust.c (af_get_glyph_alternates): Fix endless loop. 2025-04-22 06:20:22 +02:00
Werner Lemberg
b5b3fd579e * src/afadjust.c: Fix test for newer HarfBuzz version (second try). 2025-04-20 10:48:54 +02:00
Werner Lemberg
05f3cf135e * src/afadjust.c: Fix test for newer HarfBuzz version. 2025-04-20 10:29:32 +02:00
Werner Lemberg
a64b49ccfc [autofit] Request at least HarfBuzz 7.2.0 for diacritic support. (3/3)
This version (from April 2023) added 'SingleSubst' support to
`hb_ot_layout_lookup_get_glyph_alternates`.
2025-04-20 10:07:13 +02:00
Werner Lemberg
de98b1bab5 [autofit] Speed up creation of the adjustment database's reverse map. (2/3)
Remove the old code and activate the new one.
2025-04-20 10:05:48 +02:00
Werner Lemberg
573201be7d [autofit] Speed up creation of the adjustment database's reverse map. (1/3)
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.
2025-04-20 10:04:39 +02:00
Werner Lemberg
9536e4728f * src/autofit/afadjust.c (af_reverse_character_map_new): Check map limit.
Reported as

  https://issues.chromium.org/issues/410925355
2025-04-18 06:36:18 +02:00
Alexei Podtelezhnikov
6ed79d5b7a * include/freetype/internal/ftcalc.h: Fix fringe compilation. 2025-04-17 22:46:06 -04:00
Alexei Podtelezhnikov
4fad257a7e * src/base/ftcalc.c (ft_corner_orientation) [!FT_INT32]: Fix up. 2025-04-17 22:32:21 -04:00
Werner Lemberg
d6c2922875 [autofit] Don't access uninitialized memory.
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`.
2025-04-17 19:36:51 +02:00
Alexei Podtelezhnikov
66e0d25ecb * src/truetype/ttinterp.c (TT_MulFix14,TT_DotFix14)[!FT_INT64]: Sync. 2025-04-17 15:37:27 +00:00
Alexei Podtelezhnikov
9eecaa0788 * src/truetype/ttinterp.c (TT_DotFix14): Silence UBSAN. 2025-04-17 12:44:37 +00:00
Alexei Podtelezhnikov
0a650e8c52 * src/base/ftcalc.c: Miscellaneous cleanups. 2025-04-16 22:54:54 -04:00
Werner Lemberg
cc849c32cf [autofit] Avoid crash.
Reported as

  https://issues.oss-fuzz.com/issues/410811029

* src/autofit/aflatin.c (af_remove_segments_containing_point): Check
  `edge->last`.
2025-04-16 19:42:02 +02:00
Alexei Podtelezhnikov
ccabe7ac02 [base, truetype] Silence UBSAN (cont'd).
* src/truetype/ttinterp.c (TT_MulFix14, TT_DotFix14): Use MUL_INT64.
* include/freetype/internal/ftcalc.c (FT_MulFix): Ditto.
2025-04-15 18:49:36 +00:00
Werner Lemberg
dc55f4e6c1 [autofit] Avoid unnecessary recomputation of HarfBuzz data.
Call the functions once per font instead of once per glyph.

* src/autofit/afadjust.c (af_all_glyph_variants): Move code to compute the
  `feature_tags` and `type_3_lookup_indices` sets to...
  (af_reverse_character_map_new): ...this function.
2025-04-15 12:54:54 +02:00
Werner Lemberg
d1ac9524fd [autofit] Fix creation of the adjustment database's reverse map.
Due to the way the reverse map array gets constructed with HarfBuzz, there
might be multiple, identical glyph index entries with different character
values in the array.  As an example, an OpenType feature like 'unic' might
map lowercase glyph 'ae' to uppercase glyph 'AE', in addition to the already
present cmap entry for 'AE'.

In most cases, this incorrect mapping is harmless (but still wrong).
However, there exist some lowercase/uppercase character pairs where the
diacritic for the uppercase character is on the other vertical side of the
base character as for the lowercase character.  An example is U+0122 (LATIN
CAPITAL LETTER G WITH CEDILLA) and U+0123 (LATIN SMALL LETTER G WITH
CEDILLA): the former has the cedilla below, the latter above.  A wrong
mapping would thus shift the base glyph 'G' up by a pixel instead of
shifting the cedilla down.

We fix this by always giving precedence to cmap entries.

* src/autofit/afadjust.c (af_reverse_character_map_entry_compare): Do a
  secondary sort on the character code.

  (af_reverse_character_map_lookup): Adjust binary search to return the
  first occurrence of an entry (i.e., the one with the lowest array index).

  (af_reverse_character_map_new)[FT_CONFIG_OPTION_USE_HARFBUZZ]: Implement
  cmap priority.
2025-04-15 12:53:34 +02:00
Werner Lemberg
057970696d [autofit] Reduce adjustment database lookups.
This is also in preparation for a follow-up commit.

* src/autofit/afadjust.h (af_lookup_vertical_separation_type,
  af_lookup_tilde_correction_type): Replaced with...
  (af_adjustment_database_lookup, af_reverse_character_map_lookup):
  ... this.

* src/autofit/afadjust.c (af_adjustment_database_lookup,
  af_adjustment_database_lookup): Updated.
  (af_lookup_vertical_separation_type, af_lookup_tilde_correction_type):
  Removed.
  (af_reverse_character_map_new)[FT_DEBUG_LEVEL_TRACE]: Updated.

* src/autofit/aflatin.c
  (af_glyph_hints_apply_vertical_separation_adjustments,
  af_latin_hints_apply): Updated.
2025-04-15 12:46:16 +02:00
Werner Lemberg
233cdea8f4 * src/afadjust.c (adjustment_database): Make it complete up to U+017F. 2025-04-15 12:46:16 +02:00
Werner Lemberg
535498a0f9 * src/autofit/afadjust.c (af_reverse_character_map_new): Add tracing code. 2025-04-15 12:46:16 +02:00
Werner Lemberg
c34e551cad * src/afadjust.c: Minor fixes. 2025-04-15 12:46:14 +02:00
Werner Lemberg
218c59a292 [autofit] Better vertical separation adjustment support. (2/2)
* src/autofit/aflatin.c
  (af_glyph_hints_apply_vertical_separation_adjustments): Handle diacritics
  with more than a single contour.
2025-04-15 12:45:09 +02:00
Werner Lemberg
52d4573e50 [autofit] Better vertical separation adjustment support. (1/2)
Test vertical maxima instead of vertical minima to identify the highest
contour (and vice versa to identify the lowest contour).  Doing so will
allow support of diacritics that consist of more than a single outline.

This works because of the topological constraints ensured by the adjustment
database.

* src/autofit/aflatin.c (af_find_highest_contour,
  af_glyph_hints_apply_vertical_separation_adjustments): Implement it.
2025-04-15 12:45:09 +02:00
Werner Lemberg
c6106cffe2 [autofit] Use new y extrema arrays.
* src/autofit/aflatin.c
  (af_glyph_hints_apply_vertical_separation_adjustments): Implement it.
2025-04-15 12:45:09 +02:00
Werner Lemberg
8d49ccd672 [autofit] Provide infrastructure for storing y extrema of contours.
We need this for better positioning support of diacritics.

* src/autofit/afhints.h (AF_GlyphHintsRec): New fields `contour_y_minima`
  and `contour_y_maxima`, together with its embedded variants.

* src/autofit/afhints.c (af_glyph_hints_done, af_glyph_hints_reload): Handle
  new arrays.
2025-04-15 12:45:09 +02:00
Werner Lemberg
53a5e2e65b [autofit] Avoid crash.
Reported as

  https://issues.oss-fuzz.com/issues/410609442

* src/autofit/aflatin.c (af_remove_segments_containing_point): Check `edge`.
2025-04-15 06:58:52 +02:00
Werner Lemberg
558bde6e39 [autofit] Fix just introduced heap buffer overflow
Reported as

  https://issues.oss-fuzz.com/issues/410393975

* src/autofit/afadjust.c [!FT_CONFIG_OPTION_USE_HARFBUZZ]: Synchronize with
  HarfBuzz code.
2025-04-14 21:37:18 +02:00
Werner Lemberg
ae3879c0a1 * docs/CHANGES: Mention Craig's GSoC 2023 project. 2025-04-14 06:51:01 +02:00
Craig White
24ac6c5d6a [autofit] Add GSUB table handling to reverse character map generation.
If HarfBuzz is enabled, the reverse character map generation now considers
GSUB entries when looking for glyphs that correspond to a code point.

* src/autofit/afadjust.c (af_all_glyph_variants_helper,
af_all_glyph_variants) [FT_CONFIG_OPTION_USE_HARFBUZZ]: New functions.

(af_reverse_character_map_new) [FT_CONFIG_OPTION_USE_HARFBUZZ]: Call new
code.
2025-04-14 06:50:00 +02:00
Craig White
771449f14a [autofit] Add tilde-unflattening algorithm.
* src/autofit/aflatin.c (af_find_highest_contour,
af_remove_segments_containing_point,
af_latin_remove_tilde_points_from_edges, af_latin_stretch_tilde,
af_latin_align_tilde): New functions.
(af_latin_hints_apply): Call tilde-unflatting code if necessary.
2025-04-14 06:50:00 +02:00
Craig White
7099b09e96 [autofit] Implement vertical separation adjustment.
* src/autofit/aflatin.c: Include `afadjust.h`.
(af_latin_metrics_init): Call `af_reverse_character_map_new`.
(af_latin_metrics_done): New function.

(af_move_contour_vertically, af_check_contour_horizontal_overlap,
af_glyph_hints_apply_vertical_separation_adjustments): New functions.

(af_latin_hints_apply): Call
`af_glyph_hints_apply_vertical_separation_adjustments`.

(af_latin_writing_system_class): Updated.

* src/autofit/aftypes.h (AF_StyleMetricsRec): Add `reverse_charmap` field.
2025-04-14 06:50:00 +02:00
Craig White
14ac6140fc [autofit] Add code for reverse charmaps and adjustment database lookup.
* src/autofit/aftypes.h (AF_ReverseMapEntry, AF_ReverseCharacterMap): New
structures.

* src/autofit/afadjust.c (af_adjustment_database_lookup,
af_reverse_character_map_entry_compare, af_reverse_character_map_lookup,
af_lookup_vertical_separation_type, af_lookup_tilde_correction_type,
af_reverse_character_map_expand, af_reverse_character_map_new,
af_reverse_character_map_done): New functions.

* src/autofit/afadjust.c: Updated.
2025-04-14 06:50:00 +02:00
Craig White
c46ebd7650 [autofit] Add adjustment database.
* src/autofit/afadjust.c, src/autofit/afadjust.h: New files.

* include/freetype/internal/fttrace.h: Add 'afadjust' component.

* src/autofit/autofit.c: Include `afadjust.c`.

* src/autofit/rules.mk (AUTOF_DRV_SRC): Add `afadjust.c`.
2025-04-14 06:50:00 +02:00
Craig White
f0660df3a9 [base] Make find_unicode_charmap a base function.
This is needed for forthcoming changes in the auto-hinter.

* include/freetype/internal/ftobjs.h, src/base/ftobjs.c: Updated.
2025-04-14 06:50:00 +02:00