font-patcher: Fix more 'Nerd Font Mono' too wide

[why]
The 'monospace' width is determined by examining all the 'normal' glyphs
and taking the widest one.

'Normal' means 0x00-0x17f: the Latin Extended-A range.

Unfortunately some fonts that claim to be monospaced still have some
glyphs that are wider than the others.

[how]
Exclude a small group of glyphs from the 'find the widest glyph'.
The list is specifically targetted at the fonts we patch, see PR #1045.

Most of these glyphs are either visually small and it is unclear why
they are too wide (like double-quotes), or they are from the real
extended set, notably all the Eth (D with a slash) and other added-slash
or added-caron glyphs.

In ignoring them we might 'break' these specific glyphs for the people
who use them (like: they extend out of the cell into the next), but that
is the only way to keep the 'monospaced promise' without redesigning the
actual font.
But without these exceptions we have Nerd Font Mono fonts that increase
the cell width so that 'normal text' is rendered almost unreadable.
So this is an improvement for most users; and I see no way so solve
these font issues for all users (without redesigning the font itself ;).

Also add a 'warning' if a (still) problematic font is to be patched.
As reminder for self-patcher or when we add fonts here.

[note]
Related commit
  fbe07b8ab  Fix Noto too wide
  2945cecd1  Fix Overpass Mono too wide

Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
Fini Jastrow 2023-01-11 12:34:54 +01:00 committed by Fini
parent 8845e3fb99
commit 99c2608313

View file

@ -944,19 +944,29 @@ class font_patcher:
# Ignore the y-values, os2_winXXXXX values set above are used for line height
#
# 0x00-0x17f is the Latin Extended-A range
warned = self.args.quiet or self.args.nonmono # Do not warn if quiet or proportional target
for glyph in range(0x21, 0x17f):
if glyph in range(0x7F, 0xBF) or glyph in range(0x132, 0x134):
continue # ignore special characters like '1/4' etc and 'IJ' 'ij'
if glyph in range(0x7F, 0xBF) or glyph in [
0x132, 0x134, # IJ, ij (in Overpass Mono)
0x022, 0x027, 0x060, # Single and double quotes in Inconsolata LGC
0x0D0, 0x10F, 0x110, 0x111, 0x127, 0x13E, 0x140, 0x165, # Eth and others with stroke or caron in RobotoMono
]:
continue # ignore special characters like '1/4' etc and some specifics
try:
(_, _, xmax, _) = self.sourceFont[glyph].boundingBox()
except TypeError:
continue
# print("WIDTH {:X} {} ({} {})".format(glyph, self.sourceFont[glyph].width, self.font_dim['width'], xmax))
if self.font_dim['width'] < self.sourceFont[glyph].width:
self.font_dim['width'] = self.sourceFont[glyph].width
# print("New MAXWIDTH-A {} {} {}".format(glyph, self.sourceFont[glyph].width, xmax))
if not warned and glyph > 0x7a: # NOT 'basic' glyph, which includes a-zA-Z
print("Extended glyphs wider than basic glyphs")
warned = True
# print("New MAXWIDTH-A {} {} -> {} {}".format(glyph, self.sourceFont[glyph].width, self.font_dim['width'], xmax))
if xmax > self.font_dim['xmax']:
self.font_dim['xmax'] = xmax
# print("New MAXWIDTH-B {} {} {}".format(glyph, self.sourceFont[glyph].width, xmax))
# print("New MAXWIDTH-B {} {} -> {} {}".format(glyph, self.sourceFont[glyph].width, self.font_dim['width'], xmax))
# print("FINAL", self.font_dim)
def get_scale_factor(self, sym_dim):