font-patcher: Do not destroy ligs or SS

[why]
When a certain 'higher codepoint' glyph is needed for a substitution or
ligature rule of a basic glyph and we replace the 'higher codepoint'
glyph with a symbol that stylistic set or ligature will be broken.

[how]
We can not determine if a certain glyph is the _target_ of a pos-sub
rule (at least I could not find a way). What we do is remove all pos-sub
entries that _start_ at a symbol-patched glyph [1], but that is not the
same.

Instead of walking through all substitution tables we just examine the
'basic glyphs' and also protect all glyphs that they reference through
most of the possub tables.

In fact I encountered only "Substitution" entries and never "Ligature"
entries, but we handle both alike. "Pair", "AltSub", and "MultSub" are
not handled, but could be added if need be.

[1] #711

Fixes: #901

Reported-by: Xiangyu Zhu <frefreak.zxy@gmail.com>
Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
Fini Jastrow 2023-01-28 12:26:27 +01:00
parent 59be26d8c2
commit 299fc76096

View file

@ -940,9 +940,17 @@ class font_patcher:
# Find out which other glyphs are also needed to keep the basic
# glyphs intact.
# 0x00-0x17f is the Latin Extended-A range
for glyph in range(0x21, 0x17f):
basic_glyphs = set()
# Collect substitution destinations
for glyph in range(0x21, 0x17f + 1):
if not glyph in self.sourceFont:
continue
basic_glyphs.add(glyph)
for possub in self.sourceFont[glyph].getPosSub('*'):
if possub[1] == 'Substitution' or possub[1] == 'Ligature':
basic_glyphs.add(self.sourceFont[possub[2]].unicode)
basic_glyphs.discard(-1) # the .notdef glyph
for glyph in basic_glyphs:
self.add_glyphrefs_to_essential(glyph)
def get_sourcefont_dimensions(self):