From 299fc76096d1471c29dacbfb5af693405f6592b6 Mon Sep 17 00:00:00 2001 From: Fini Jastrow Date: Sat, 28 Jan 2023 12:26:27 +0100 Subject: [PATCH] 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 Signed-off-by: Fini Jastrow --- font-patcher | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/font-patcher b/font-patcher index 2a110bc9a..c226095e1 100755 --- a/font-patcher +++ b/font-patcher @@ -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):