font-patcher: Break alternative unicode links before patching

[why]
The D2Coding font has a lot of glyphs shared between multiple unicode
codepoints.
Usually we just want to change the glyph on one particular codepoint
and not on all linked ones; which will affect codepoints not in our
patching ranges.

For example the glyph FULL BLOCK is used by codepoint 2588 and E286. In
the Exxx range they have a lot of icons, and also a full block.

[how]
Remove all links on glyphs that we are about to patch over, so that we
really just patch the codepoint we want to patch (and have no hidden
'links').

[note]
This could in principle break alts or ligs if they rely on another
codepoint that we removed. But breaking ligs is always a possibility
when patching over existing glyphs.

[note]
I checked several (not all) fonts in our repertoire, and only D2coding
is massively affected.

The only other fonts are these with 2 codepoints each:
heavy_data.ttf Removing alternate unicode on F001 (FB01)
heavy_data.ttf Removing alternate unicode on F002 (FB02)
Tinos-Regular.ttf Removing alternate unicode on F001 (FB01)
Tinos-Regular.ttf Removing alternate unicode on F002 (FB02)

Fixes: 1454

Reported-by: @hdd1013
Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
Fini Jastrow 2023-12-10 18:00:52 +01:00 committed by Fini
parent f25aa13bba
commit da4fb70b7e

View file

@ -6,7 +6,7 @@
from __future__ import absolute_import, print_function, unicode_literals from __future__ import absolute_import, print_function, unicode_literals
# Change the script version when you edit this script: # Change the script version when you edit this script:
script_version = "4.8.3" script_version = "4.8.4"
version = "3.1.1" version = "3.1.1"
projectName = "Nerd Fonts" projectName = "Nerd Fonts"
@ -1411,6 +1411,18 @@ class font_patcher:
# Just prepare scaling of existing glyphs # Just prepare scaling of existing glyphs
glyph_scale_data = self.get_glyph_scale(sym_glyph.encoding, scaleRules, stretch, self.sourceFont, currentSourceFontGlyph) if scaleRules is not None else None glyph_scale_data = self.get_glyph_scale(sym_glyph.encoding, scaleRules, stretch, self.sourceFont, currentSourceFontGlyph) if scaleRules is not None else None
else: else:
# Break apart multiple unicodes linking to one glyph
if currentSourceFontGlyph in self.sourceFont:
altuni = self.sourceFont[currentSourceFontGlyph].altuni
if altuni:
codes = { v for v, s, r in altuni if v >= 0 }
codes.add(self.sourceFont[currentSourceFontGlyph].unicode)
codes.remove(currentSourceFontGlyph)
codes = [ "{:04X}".format(c) for c in sorted(list(codes)) ]
logger.debug("Removing alternate unicode on %X (%s)", currentSourceFontGlyph, ' '.join(codes));
self.sourceFont[currentSourceFontGlyph].altuni = None
self.sourceFont.encoding = 'UnicodeFull' # Rebuild encoding table (needed after altuni changes)
# This will destroy any content currently in currentSourceFontGlyph, so do it first # This will destroy any content currently in currentSourceFontGlyph, so do it first
glyph_scale_data = self.get_glyph_scale(sym_glyph.encoding, scaleRules, stretch, symbolFont, currentSourceFontGlyph) if scaleRules is not None else None glyph_scale_data = self.get_glyph_scale(sym_glyph.encoding, scaleRules, stretch, symbolFont, currentSourceFontGlyph) if scaleRules is not None else None