Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

font-patcher: Prevent excessively tall icons in mono fonts #1564

Merged
merged 2 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions bin/scripts/test-vertical-lines.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
#!/usr/bin/env bash
# Nerd Fonts Version: 3.1.1
# Script Version: 1.0.0
# Script Version: 1.0.1
#
# A more conceise version of the Powerline test, designed to show
# the dreaded 'faint vertical lines' phenomenon from LCD antialiasing

COL_A='\033[48;5;51m\033[38;5;200m'
COL_B='\033[48;5;200m\033[38;5;51m'
COL_A=$(printf '\033[48;5;51m\033[38;5;200m')
COL_B=$(printf '\033[48;5;200m\033[38;5;51m')
COL_C=$(printf '\033[48;5;238m\033[38;5;253m')
COL_D=$(printf '\033[48;5;253m\033[38;5;238m')

printf "\
${COL_A} \n\
Under \ue0b2${COL_B} lap ${COL_A}\ue0b0 and \ue0b6${COL_B} top ${COL_A}\ue0b4 mop \n\
${COL_A}Over \ue0b2${COL_B} lap ${COL_A}\ue0b0 and \ue0b6${COL_B} top ${COL_A}\ue0b4 mop trop lop klop\n\
\n"

COL_A='\033[48;5;238m\033[38;5;253m'
COL_B='\033[48;5;253m\033[38;5;238m'
%s \n\
Under \ue0b2%s lap %s\ue0b0 and \ue0b6%s top %s\ue0b4 mop \n\
%sOver \ue0b2%s lap %s\ue0b0 and \ue0b6%s top %s\ue0b4 mop trop lop klop\n\
\n" \
"${COL_A}" "${COL_B}" "${COL_A}" "${COL_B}" "${COL_A}" \
"${COL_A}" "${COL_B}" "${COL_A}" "${COL_B}" "${COL_A}"

printf "\
${COL_A} \n\
Under \ue0b2${COL_B} lap ${COL_A}\ue0b0 and \ue0b6${COL_B} top ${COL_A}\ue0b4 mop \n\
${COL_A}Over \ue0b2${COL_B} lap ${COL_A}\ue0b0 and \ue0b6${COL_B} top ${COL_A}\ue0b4 mop trop lop klop\n\
\n"
%s \n\
Under \ue0b2%s lap %s\ue0b0 and \ue0b6%s top %s\ue0b4 mop \n\
%sOver \ue0b2%s lap %s\ue0b0 and \ue0b6%s top %s\ue0b4 mop trop lop klop\n\
\n" \
"${COL_C}" "${COL_D}" "${COL_C}" "${COL_D}" "${COL_C}" \
"${COL_C}" "${COL_D}" "${COL_C}" "${COL_D}" "${COL_C}"
106 changes: 60 additions & 46 deletions font-patcher
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from __future__ import absolute_import, print_function, unicode_literals

# Change the script version when you edit this script:
script_version = "4.10.2"
script_version = "4.11.0"

version = "3.1.1"
projectName = "Nerd Fonts"
Expand Down Expand Up @@ -840,6 +840,7 @@ class font_patcher:
# '1' means occupu 1 cell (default for 'xy')
# '2' means occupy 2 cells (default for 'pa')
# '!' means do the 'pa' scaling even with non mono fonts (else it just scales down, never up)
# '^' means that scaling shall fill the whole cell and not only the icon-cap-height (for mono fonts, other always use the whole cell)
# Dont_copy does not overwrite existing glyphs but rescales the preexisting ones
#
# Be careful, stretch may not change within a ScaleRule!
Expand All @@ -848,63 +849,63 @@ class font_patcher:
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}}
}
SYM_ATTR_POWERLINE = {
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}},
'default': {'align': 'c', 'valign': 'c', 'stretch': '^pa', 'params': {}},

# Arrow tips
0xe0b0: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.7}},
0xe0b1: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'xy-ratio': 0.7}},
0xe0b2: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.7}},
0xe0b3: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'xy-ratio': 0.7}},
0xe0b0: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.7}},
0xe0b1: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'xy-ratio': 0.7}},
0xe0b2: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.7}},
0xe0b3: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'xy-ratio': 0.7}},

# Rounded arcs
0xe0b4: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.59}},
0xe0b5: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'xy-ratio': 0.5}},
0xe0b6: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.59}},
0xe0b7: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'xy-ratio': 0.5}},
0xe0b4: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.59}},
0xe0b5: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'xy-ratio': 0.5}},
0xe0b6: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.06, 'xy-ratio': 0.59}},
0xe0b7: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'xy-ratio': 0.5}},

# Bottom Triangles
0xe0b8: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
0xe0b9: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
0xe0ba: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
0xe0bb: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {}},
0xe0b8: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02}},
0xe0b9: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {}},
0xe0ba: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02}},
0xe0bb: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {}},

# Top Triangles
0xe0bc: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
0xe0bd: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {}},
0xe0be: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
0xe0bf: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {}},
0xe0bc: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02}},
0xe0bd: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {}},
0xe0be: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02}},
0xe0bf: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {}},

# Flames
0xe0c0: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': 0.01}},
0xe0c1: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {}},
0xe0c2: {'align': 'r', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': 0.01}},
0xe0c3: {'align': 'r', 'valign': 'c', 'stretch': 'xy2', 'params': {}},
0xe0c0: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': 0.01}},
0xe0c1: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {}},
0xe0c2: {'align': 'r', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': 0.01}},
0xe0c3: {'align': 'r', 'valign': 'c', 'stretch': '^xy2', 'params': {}},

# Small squares
0xe0c4: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.86}},
0xe0c5: {'align': 'r', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.86}},
0xe0c4: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.86}},
0xe0c5: {'align': 'r', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.86}},

# Bigger squares
0xe0c6: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.78}},
0xe0c7: {'align': 'r', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.78}},
0xe0c6: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.78}},
0xe0c7: {'align': 'r', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': -0.03, 'xy-ratio': 0.78}},

# Waveform
0xe0c8: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': 0.01}},
0xe0ca: {'align': 'r', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': 0.01}},
0xe0c8: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': 0.01}},
0xe0ca: {'align': 'r', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': 0.01}},

# Hexagons
0xe0cc: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {'overlap': 0.02, 'xy-ratio': 0.85}},
0xe0cd: {'align': 'l', 'valign': 'c', 'stretch': 'xy2', 'params': {'xy-ratio': 0.865}},
0xe0cc: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {'overlap': 0.02, 'xy-ratio': 0.85}},
0xe0cd: {'align': 'l', 'valign': 'c', 'stretch': '^xy2', 'params': {'xy-ratio': 0.865}},

# Legos
0xe0ce: {'align': 'l', 'valign': 'c', 'stretch': 'pa', 'params': {}},
0xe0cf: {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': {}},
0xe0d0: {'align': 'l', 'valign': 'c', 'stretch': 'pa', 'params': {}},
0xe0d1: {'align': 'l', 'valign': 'c', 'stretch': 'pa', 'params': {}},
0xe0ce: {'align': 'l', 'valign': 'c', 'stretch': '^pa', 'params': {}},
0xe0cf: {'align': 'c', 'valign': 'c', 'stretch': '^pa', 'params': {}},
0xe0d0: {'align': 'l', 'valign': 'c', 'stretch': '^pa', 'params': {}},
0xe0d1: {'align': 'l', 'valign': 'c', 'stretch': '^pa', 'params': {}},

# Top and bottom trapezoid
0xe0d2: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02, 'xy-ratio': 0.7}},
0xe0d4: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02, 'xy-ratio': 0.7}}
0xe0d2: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02, 'xy-ratio': 0.7}},
0xe0d4: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02, 'xy-ratio': 0.7}}
}
SYM_ATTR_TRIGRAPH = {
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa1!', 'params': {'overlap': -0.10, 'careful': True}}
Expand All @@ -922,7 +923,7 @@ class font_patcher:
'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa1!', 'params': {'ypadding': 0.3, 'careful': True}}
}
SYM_ATTR_BOX = {
'default': {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02, 'dont_copy': box_keep}},
'default': {'align': 'c', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.02, 'dont_copy': box_keep}},
# No overlap with checkered greys (commented out because that raises problems on rescaling clients)
# 0x2591: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'dont_copy': box_keep}},
# 0x2592: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'dont_copy': box_keep}},
Expand Down Expand Up @@ -1190,7 +1191,7 @@ class font_patcher:

# print("FINI hhea {} typo {} win {} use {} {} {}".format(hhea_btb, typo_btb, win_btb, use_typo, our_btb != hhea_btb, self.sourceFont.fontname))

self.font_dim = {'xmin': 0, 'ymin': 0, 'xmax': 0, 'ymax': 0, 'width' : 0, 'height': 0, 'ypadding': 0}
self.font_dim = {'xmin': 0, 'ymin': 0, 'xmax': 0, 'ymax': 0, 'width' : 0, 'height': 0, 'iconheight': 0, 'ypadding': 0}

if metrics == Metric.HHEA:
self.font_dim['ymin'] = self.sourceFont.hhea_descent - half_gap(self.sourceFont.hhea_linegap, False)
Expand All @@ -1212,18 +1213,28 @@ class font_patcher:
# Assume we are using our prepared templates
self.symbolsonly = True
self.font_dim = {
'xmin' : 0,
'ymin' : -self.sourceFont.descent,
'xmax' : self.sourceFont.em,
'ymax' : self.sourceFont.ascent,
'width' : self.sourceFont.em,
'height': self.sourceFont.descent + self.sourceFont.ascent,
'xmin' : 0,
'ymin' : -self.sourceFont.descent,
'xmax' : self.sourceFont.em,
'ymax' : self.sourceFont.ascent,
'width' : self.sourceFont.em,
'height' : self.sourceFont.descent + self.sourceFont.ascent,
'iconheight': self.sourceFont.descent + self.sourceFont.ascent,
'ypadding' : 0,
}
our_btb = self.sourceFont.descent + self.sourceFont.ascent
if self.font_dim['height'] <= 0:
logger.critical("Can not detect sane font height")
sys.exit(1)

self.font_dim['iconheight'] = self.font_dim['height']
if self.args.single and self.sourceFont.capHeight > 0:
# Limit the icon height on monospaced fonts because very slender and tall icons render
# excessivly tall otherwise. We ignore that effect for the other variants because it
# does not look so much out of place there.
# Icons can be bigger than the letter capitals, but not the whole cell:
self.font_dim['iconheight'] = (self.sourceFont.capHeight * 2 + self.font_dim['height']) / 3

# Make all metrics equal
self.sourceFont.os2_typolinegap = 0
self.sourceFont.os2_typoascent = self.font_dim['ymax']
Expand Down Expand Up @@ -1277,7 +1288,9 @@ class font_patcher:
if self.font_dim['width'] <= 0:
logger.critical("Can not detect sane font width")
sys.exit(1)
logger.debug("Final font cell dimensions %d w x %d h", self.font_dim['width'], self.font_dim['height'])
logger.debug("Final font cell dimensions %d w x %d h%s",
self.font_dim['width'], self.font_dim['height'],
' (with icon cell {} h)'.format(int(self.font_dim['iconheight'])) if self.font_dim['iconheight'] != self.font_dim['height'] else '')

self.xavgwidth.append(self.args.xavgwidth)
if isinstance(self.xavgwidth[-1], int) and self.xavgwidth[-1] == 0:
Expand All @@ -1303,7 +1316,8 @@ class font_patcher:

# font_dim['height'] represents total line height, keep our symbols sized based upon font's em
# Use the font_dim['height'] only for explicit 'y' scaling (not 'pa')
target_height = self.font_dim['height'] * (1.0 - self.font_dim['ypadding'])
target_height = self.font_dim['height'] if '^' in stretch else self.font_dim['iconheight']
target_height *= 1.0 - self.font_dim['ypadding']
scale_ratio_y = target_height / sym_dim['height']

if 'pa' in stretch:
Expand Down