mirror of
https://github.com/ryanoasis/nerd-fonts.git
synced 2025-01-06 21:49:40 +02:00
Merge pull request #1733 from ryanoasis/feature/progress-indicators
font-patcher: Add progress indicators
This commit is contained in:
commit
d5d0f2d154
108
font-patcher
108
font-patcher
@ -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.15.0"
|
||||
script_version = "4.16.0"
|
||||
|
||||
version = "3.2.1"
|
||||
projectName = "Nerd Fonts"
|
||||
@ -964,6 +964,16 @@ class font_patcher:
|
||||
# 0x2592: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'dont_copy': box_keep}},
|
||||
# 0x2593: {'align': 'c', 'valign': 'c', 'stretch': 'xy', 'params': {'dont_copy': box_keep}},
|
||||
}
|
||||
SYM_ATTR_PROGRESS = {
|
||||
'default': {'align': 'c', 'valign': 'c', 'stretch': '^pa1!', 'params': {'overlap': -0.03, 'careful': True}}, # Cirles
|
||||
# All the squares:
|
||||
0xee00: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.05, 'careful': True}},
|
||||
0xee01: {'align': 'c', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.10, 'careful': True}},
|
||||
0xee02: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.05, 'careful': True}},
|
||||
0xee03: {'align': 'r', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.05, 'careful': True}},
|
||||
0xee04: {'align': 'c', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.10, 'careful': True}},
|
||||
0xee05: {'align': 'l', 'valign': 'c', 'stretch': '^xy', 'params': {'overlap': 0.05, 'careful': True}},
|
||||
}
|
||||
CUSTOM_ATTR = {
|
||||
# previous custom scaling => do not touch the icons
|
||||
# 'default': {'align': 'c', 'valign': '', 'stretch': '', 'params': {}}
|
||||
@ -983,9 +993,9 @@ class font_patcher:
|
||||
# Shifting in addition to scaling can be selected too (see below).
|
||||
# - ScaleGroups:
|
||||
# Here you specify a group of glyphs that should be handled together
|
||||
# with the same scaling and shifting. The basis for it is a 'combined
|
||||
# bounding box' of all glyphs in that group. All glyphs are handled as
|
||||
# if they fill that combined bounding box.
|
||||
# with the same scaling and shifting (see bottom). The basis for it is
|
||||
# a 'combined bounding box' of all glyphs in that group. All glyphs are
|
||||
# handled as if they fill that combined bounding box.
|
||||
# (- ScaleGroupsVert: Removed with this commit)
|
||||
#
|
||||
# The ScaleGlyph method: You set 'ScaleGlyph' to the unicode of the reference glyph.
|
||||
@ -1002,7 +1012,7 @@ class font_patcher:
|
||||
#
|
||||
# For the ScaleGroup method you define any number groups of glyphs and each group is
|
||||
# handled separately. The combined bounding box of all glyphs in the group is determined
|
||||
# and based on that the scale and shift for all the glyphs in the group.
|
||||
# and based on that the scale and shift (see bottom) for all the glyphs in the group.
|
||||
# You define the groups as value of 'ScaleGroups'.
|
||||
# It is a List of: ((lists of glyph codes) or (ranges of glyph codes))
|
||||
# 'ScaleGroups': [
|
||||
@ -1013,15 +1023,21 @@ class font_patcher:
|
||||
# See prepareScaleRules() for some more details.
|
||||
# For historic reasons ScaleGroups is sometimes called 'new method' and ScaleGlyph 'old'.
|
||||
# The codepoints mentioned here are symbol-font-codepoints.
|
||||
#
|
||||
# Shifting:
|
||||
# If we have a combined bounding box stored in a range, that
|
||||
# box is used to align all symbols in the range identically.
|
||||
# - If the symbol font is proportinal only the v alignment is synced.
|
||||
# - If the symbol font is monospaced v and h alignemnts are synced.
|
||||
# To make sure the behavior is as expected you are required to set a ShiftMode property
|
||||
# accordingly. It just checks, you can not (!) select what is done with that property.
|
||||
|
||||
BOX_SCALE_LIST = {'ScaleGroups': [
|
||||
BOX_SCALE_LIST = {'ShiftMode': 'xy', 'ScaleGroups': [
|
||||
[*range(0x2500, 0x2570 + 1), *range(0x2574, 0x257f + 1)], # box drawing
|
||||
range(0x2571, 0x2573 + 1), # diagonals
|
||||
[*range(0x2580, 0x2590 + 1), 0x2594, 0x2595], # blocks
|
||||
range(0x2591, 0x2593 + 1), # greys
|
||||
range(0x2594, 0x259f + 1), # quards (Note: quard 2597 in Hack is wrong, scales like block!)
|
||||
range(0x2580, 0x259f + 1), # blocks and greys (greys are less tall originally, so overlap will be less)
|
||||
]}
|
||||
CODI_SCALE_LIST = {'ScaleGroups': [
|
||||
CODI_SCALE_LIST = {'ShiftMode': 'xy', 'ScaleGroups': [
|
||||
[0xea61, 0xeb13], # lightbulb
|
||||
range(0xeab4, 0xeab7 + 1), # chevrons
|
||||
[0xea7d, *range(0xea99, 0xeaa1 + 1), 0xebcb], # arrows
|
||||
@ -1033,7 +1049,7 @@ class font_patcher:
|
||||
range(0xebd5, 0xebd7 + 1), # compasses
|
||||
]}
|
||||
DEVI_SCALE_LIST = None
|
||||
FONTA_SCALE_LIST = {'ScaleGroups': [
|
||||
FONTA_SCALE_LIST = {'ShiftMode': '', 'ScaleGroups': [
|
||||
[0xf005, 0xf006, 0xf089], # star, star empty, half star
|
||||
range(0xf026, 0xf028 + 1), # volume off, down, up
|
||||
range(0xf02b, 0xf02c + 1), # tag, tags
|
||||
@ -1054,11 +1070,11 @@ class font_patcher:
|
||||
range(0xf221, 0xf22d + 1), # gender or so
|
||||
range(0xf255, 0xf25b + 1), # hand symbols
|
||||
]}
|
||||
HEAVY_SCALE_LIST = {'ScaleGlyph': 0x2771, # widest bracket, horizontally
|
||||
HEAVY_SCALE_LIST = {'ShiftMode': 'y', 'ScaleGlyph': 0x2771, # widest bracket, horizontally
|
||||
'GlyphsToScale': [
|
||||
(0x276c, 0x2771) # all
|
||||
]}
|
||||
OCTI_SCALE_LIST = {'ScaleGroups': [
|
||||
OCTI_SCALE_LIST = {'ShiftMode': '', 'ScaleGroups': [
|
||||
[*range(0xf03d, 0xf040 + 1), 0xf019, 0xf030, 0xf04a, 0xf051, 0xf071, 0xf08c ], # arrows
|
||||
[0xF0E7, # Smily and ...
|
||||
0xf044, 0xf05a, 0xf05b, 0xf0aa, # triangles
|
||||
@ -1070,7 +1086,11 @@ class font_patcher:
|
||||
range(0xf2c2, 0xf2c5 + 1), # move to
|
||||
[0xf07b, 0xf0a1, 0xf0d6, 0xf306], # bookmarks
|
||||
]}
|
||||
WEATH_SCALE_LIST = {'ScaleGroups': [
|
||||
PROGR_SCALE_LIST = {'ShiftMode': 'xy', 'ScaleGroups': [
|
||||
range(0xedff, 0xee05 + 1), # boxes... with helper glyph for Y padding
|
||||
range(0xee06, 0xee0b + 1), # circles
|
||||
]}
|
||||
WEATH_SCALE_LIST = {'ShiftMode': '', 'ScaleGroups': [
|
||||
[0xf03c, 0xf042, 0xf045 ], # degree signs
|
||||
[0xf043, 0xf044, 0xf048, 0xf04b, 0xf04c, 0xf04d, 0xf057, 0xf058, 0xf087, 0xf088], # arrows
|
||||
range(0xf053, 0xf055 + 1), # thermometers
|
||||
@ -1104,6 +1124,7 @@ class font_patcher:
|
||||
{'Enabled': True, 'Name': "Seti-UI + Custom", 'Filename': "original-source.otf", 'Exact': False, 'SymStart': 0xE4FA, 'SymEnd': 0xE5FF, 'SrcStart': 0xE5FA, 'ScaleRules': None, 'Attributes': SYM_ATTR_DEFAULT},
|
||||
{'Enabled': True, 'Name': "Heavy Angle Brackets", 'Filename': "extraglyphs.sfd", 'Exact': True, 'SymStart': 0x276C, 'SymEnd': 0x2771, 'SrcStart': None, 'ScaleRules': HEAVY_SCALE_LIST, 'Attributes': SYM_ATTR_HEAVYBRACKETS},
|
||||
{'Enabled': box_enabled, 'Name': "Box Drawing", 'Filename': "extraglyphs.sfd", 'Exact': True, 'SymStart': 0x2500, 'SymEnd': 0x259F, 'SrcStart': None, 'ScaleRules': BOX_SCALE_LIST, 'Attributes': SYM_ATTR_BOX},
|
||||
{'Enabled': True, 'Name': "Progress Indicators", 'Filename': "extraglyphs.sfd", 'Exact': True, 'SymStart': 0xEE00, 'SymEnd': 0xEE0B, 'SrcStart': None, 'ScaleRules': PROGR_SCALE_LIST, 'Attributes': SYM_ATTR_PROGRESS},
|
||||
{'Enabled': True, 'Name': "Devicons", 'Filename': "devicons/devicons.ttf", 'Exact': False, 'SymStart': 0xE600, 'SymEnd': 0xE7E3, 'SrcStart': 0xE700, 'ScaleRules': DEVI_SCALE_LIST, 'Attributes': SYM_ATTR_DEFAULT},
|
||||
{'Enabled': self.args.powerline, 'Name': "Powerline Symbols", 'Filename': "powerline-symbols/PowerlineSymbols.otf", 'Exact': True, 'SymStart': 0xE0A0, 'SymEnd': 0xE0A2, 'SrcStart': None, 'ScaleRules': None, 'Attributes': SYM_ATTR_POWERLINE},
|
||||
{'Enabled': self.args.powerline, 'Name': "Powerline Symbols", 'Filename': "powerline-symbols/PowerlineSymbols.otf", 'Exact': True, 'SymStart': 0xE0B0, 'SymEnd': 0xE0B3, 'SrcStart': None, 'ScaleRules': None, 'Attributes': SYM_ATTR_POWERLINE},
|
||||
@ -1344,25 +1365,29 @@ class font_patcher:
|
||||
return 1
|
||||
return 2
|
||||
|
||||
def get_scale_factors(self, sym_dim, stretch):
|
||||
def get_scale_factors(self, sym_dim, stretch, overlap=None):
|
||||
""" Get scale in x and y as tuple """
|
||||
# It is possible to have empty glyphs, so we need to skip those.
|
||||
if not sym_dim['width'] or not sym_dim['height']:
|
||||
return (1.0, 1.0)
|
||||
|
||||
target_width = self.font_dim['width'] * self.get_target_width(stretch)
|
||||
if overlap:
|
||||
target_width += self.font_dim['width'] * overlap
|
||||
scale_ratio_x = target_width / sym_dim['width']
|
||||
|
||||
# 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'] if '^' in stretch else self.font_dim['iconheight']
|
||||
target_height *= 1.0 - self.font_dim['ypadding']
|
||||
if overlap:
|
||||
target_height *= 1.0 + min(0.01, overlap) # never aggressive vertical overlap
|
||||
scale_ratio_y = target_height / sym_dim['height']
|
||||
|
||||
if 'pa' in stretch:
|
||||
# We want to preserve x/y aspect ratio, so find biggest scale factor that allows symbol to fit
|
||||
scale_ratio_x = min(scale_ratio_x, scale_ratio_y)
|
||||
if not self.args.single and not '!' in stretch:
|
||||
if not self.args.single and not '!' in stretch and not overlap:
|
||||
# non monospaced fonts just scale down on 'pa', not up
|
||||
scale_ratio_x = min(scale_ratio_x, 1.0)
|
||||
scale_ratio_y = scale_ratio_x
|
||||
@ -1502,25 +1527,26 @@ class font_patcher:
|
||||
|
||||
# Prepare symbol glyph dimensions
|
||||
sym_dim = get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph])
|
||||
if glyph_scale_data is not None:
|
||||
if glyph_scale_data[1] is not None:
|
||||
sym_dim = glyph_scale_data[1] # Use combined bounding box
|
||||
(scale_ratio_x, scale_ratio_y) = self.get_scale_factors(sym_dim, stretch)
|
||||
else:
|
||||
# This is roughly alike get_scale_factors(glyph_scale_data[1], 'pa')
|
||||
# Except we do not have glyph_scale_data[1] always...
|
||||
(scale_ratio_x, scale_ratio_y) = (glyph_scale_data[0], glyph_scale_data[0])
|
||||
else:
|
||||
(scale_ratio_x, scale_ratio_y) = self.get_scale_factors(sym_dim, stretch)
|
||||
|
||||
overlap = sym_attr['params'].get('overlap')
|
||||
if overlap and ypadding:
|
||||
logger.critical("Conflicting params: overlap and ypadding")
|
||||
sys.exit(1)
|
||||
if overlap:
|
||||
scale_ratio_x *= 1.0 + (self.font_dim['width'] / (sym_dim['width'] * scale_ratio_x)) * overlap
|
||||
y_overlap = min(0.01, overlap) # never aggressive vertical overlap
|
||||
scale_ratio_y *= 1.0 + (self.font_dim['height'] / (sym_dim['height'] * scale_ratio_y)) * y_overlap
|
||||
|
||||
if glyph_scale_data is not None:
|
||||
if glyph_scale_data[1] is not None:
|
||||
sym_dim = glyph_scale_data[1] # Use combined bounding box
|
||||
(scale_ratio_x, scale_ratio_y) = self.get_scale_factors(sym_dim, stretch, overlap)
|
||||
else:
|
||||
# This is roughly alike get_scale_factors(glyph_scale_data[1], 'pa')
|
||||
# Except we do not have glyph_scale_data[1] always...
|
||||
(scale_ratio_x, scale_ratio_y) = (glyph_scale_data[0], glyph_scale_data[0])
|
||||
if overlap:
|
||||
scale_ratio_x *= 1.0 + (self.font_dim['width'] / (sym_dim['width'] * scale_ratio_x)) * overlap
|
||||
y_overlap = min(0.01, overlap) # never aggressive vertical overlap
|
||||
scale_ratio_y *= 1.0 + (self.font_dim['height'] / (sym_dim['height'] * scale_ratio_y)) * y_overlap
|
||||
else:
|
||||
(scale_ratio_x, scale_ratio_y) = self.get_scale_factors(sym_dim, stretch, overlap)
|
||||
|
||||
|
||||
# Size in x to size in y ratio limit (to prevent over-wide glyphs)
|
||||
xy_ratio_max = sym_attr['params'].get('xy-ratio')
|
||||
@ -1567,15 +1593,17 @@ class font_patcher:
|
||||
elif sym_attr['align'] == 'r':
|
||||
# Right align
|
||||
x_align_distance += self.font_dim['width'] * self.get_target_width(stretch) - sym_dim['width']
|
||||
# If symbol glyph is wider than target font cell, just left-align
|
||||
x_align_distance = max(self.font_dim['xmin'] - sym_dim['xmin'], x_align_distance)
|
||||
if not overlap:
|
||||
# If symbol glyph is wider than target font cell, just left-align
|
||||
x_align_distance = max(self.font_dim['xmin'] - sym_dim['xmin'], x_align_distance)
|
||||
|
||||
if overlap:
|
||||
overlap_width = self.font_dim['width'] * overlap
|
||||
if sym_attr['align'] == 'l':
|
||||
x_align_distance -= overlap_width
|
||||
elif sym_attr['align'] == 'c':
|
||||
if overlap_width > 0:
|
||||
# center aligned keeps being center aligned even with overlap
|
||||
if overlap_width < 0 and self.args.nonmono and sym_dim['advance'] is None: # Keep positive bearing due to negative overlap (propo)
|
||||
x_align_distance -= overlap_width / 2
|
||||
elif sym_attr['align'] == 'r' and not self.args.nonmono:
|
||||
# Check and correct overlap; it can go wrong if we have a xy-ratio limit
|
||||
@ -1609,7 +1637,7 @@ class font_patcher:
|
||||
else:
|
||||
width = sym_dim['width']
|
||||
# If we have overlap we need to subtract that to keep/get negative bearings
|
||||
if overlap and (sym_attr['align'] == 'l' or sym_attr['align'] == 'r'):
|
||||
if overlap:
|
||||
width -= overlap_width
|
||||
# Fontforge handles the width change like this:
|
||||
# - Keep existing left_side_bearing
|
||||
@ -1707,11 +1735,21 @@ class font_patcher:
|
||||
scaleRules['bbdims'] = []
|
||||
if 'ScaleGroups' not in scaleRules:
|
||||
scaleRules['ScaleGroups'] = []
|
||||
|
||||
mode = scaleRules['ShiftMode'] # Mode is only documentary
|
||||
for group in scaleRules['ScaleGroups']:
|
||||
sym_dim = get_multiglyph_boundingBox([ symbolFont[g] if g in symbolFont else None for g in group ], destGlyph)
|
||||
scale = self.get_scale_factors(sym_dim, stretch)[0]
|
||||
scaleRules['scales'].append(scale)
|
||||
scaleRules['bbdims'].append(sym_dim)
|
||||
if (mode):
|
||||
if ('x' in mode) != (sym_dim['advance'] is not None):
|
||||
d = '0x{:X} - 0x{:X}'.format(group[0], group[-1])
|
||||
if ('x' in mode) :
|
||||
logger.critical("Scaling in group %s is expected to do horizonal shifts but can not", d)
|
||||
else:
|
||||
logger.critical("Scaling in group %s is expected to not do horizonal shifts but will", d)
|
||||
sys.exit(1)
|
||||
|
||||
if 'ScaleGlyph' in scaleRules:
|
||||
# Rewrite to equivalent ScaleGroup
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user