mirror of
https://github.com/ryanoasis/nerd-fonts.git
synced 2024-09-19 09:51:48 +02:00
font-patcher: Redesign ScaleGlyph parameter
[why] While patching for --mono with Font Awesome we get glyphs that are too wide, for example '_520' (0xF22B). In the symbol font original it is about 1918 wide. According to ScaleGlyph FONTA_SCALE_LIST it shall be scaled as 0xF17A - which is only 1664 wide. This results in too wide symbols in the patched font. [how] The ScaleGlyph dict works like this: - 'ScaleGlyph' Lead glyph, which scaling factor is taken - 'GlyphsToScale': List of (glyph code) or (list of two glyph codes that form a closed range)) that shall be scaled Note that this allows only one group for the whole symbol font, and that the scaling factor is defined by a specific character, which needs to be manually selected (on each symbol font update). The redesign drops 'ScaleGlyph' and changes the glyph list to: - 'GlyphsToScale': List of ((lists of glyph codes) or (ranges of glyph codes)) that shall be scaled Each item in 'GlyphsToScale' (a range or an explicit list) forms a group of glyphs that shall be as rescaled all with the same and maximum possible (for the included glyphs) factor. The old data structure is automatically rewritten to new entries. [note] This commit just changes the algorithm. As the new ScaleGlyph is not used for any font, there is no change in the patched fonts. Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
parent
cfcd15aa25
commit
e5768e925c
1 changed files with 69 additions and 29 deletions
98
font-patcher
98
font-patcher
|
@ -662,11 +662,6 @@ class font_patcher:
|
||||||
sourceFontList = list(range(sourceFontStart, sourceFontEnd + 1))
|
sourceFontList = list(range(sourceFontStart, sourceFontEnd + 1))
|
||||||
sourceFontCounter = 0
|
sourceFontCounter = 0
|
||||||
|
|
||||||
scale_factor = 0
|
|
||||||
if scaleGlyph:
|
|
||||||
sym_dim = get_glyph_dimensions(symbolFont[scaleGlyph['ScaleGlyph']])
|
|
||||||
scale_factor = self.get_scale_factor(sym_dim)
|
|
||||||
|
|
||||||
# Create glyphs from symbol font
|
# Create glyphs from symbol font
|
||||||
#
|
#
|
||||||
# If we are going to copy all Glyphs, then assume we want to be careful
|
# If we are going to copy all Glyphs, then assume we want to be careful
|
||||||
|
@ -745,15 +740,14 @@ class font_patcher:
|
||||||
# find the largest possible scaling factor that will allow the glyph
|
# find the largest possible scaling factor that will allow the glyph
|
||||||
# to fit in both the x and y directions
|
# to fit in both the x and y directions
|
||||||
if sym_attr['stretch'] == 'pa':
|
if sym_attr['stretch'] == 'pa':
|
||||||
if scale_factor and use_scale_glyph(sym_glyph.unicode, scaleGlyph['GlyphsToScale']):
|
scale_ratio_x = False
|
||||||
# We want to preserve the relative size of each glyph to other glyphs
|
if scaleGlyph:
|
||||||
# in the same symbol font.
|
# We want to preserve the relative size of each glyph in a glyph group
|
||||||
scale_ratio_x = scale_factor
|
scale_ratio_x = self.get_glyph_scale(sym_glyph.unicode, scaleGlyph, symbolFont)
|
||||||
scale_ratio_y = scale_factor
|
if scale_ratio_x is False:
|
||||||
else:
|
# In the remaining cases, each glyph is sized independently to each other
|
||||||
# In this case, each glyph is sized independently to each other
|
|
||||||
scale_ratio_x = self.get_scale_factor(sym_dim)
|
scale_ratio_x = self.get_scale_factor(sym_dim)
|
||||||
scale_ratio_y = scale_ratio_x
|
scale_ratio_y = scale_ratio_x
|
||||||
else:
|
else:
|
||||||
if 'x' in sym_attr['stretch']:
|
if 'x' in sym_attr['stretch']:
|
||||||
# Stretch the glyph horizontally to fit the entire available width
|
# Stretch the glyph horizontally to fit the entire available width
|
||||||
|
@ -876,6 +870,53 @@ class font_patcher:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def prepareScaleGlyph(self, scaleGlyph, symbolFont):
|
||||||
|
""" Prepare raw ScaleGlyph data for use """
|
||||||
|
# The GlyphData is a dict with these (possible) entries:
|
||||||
|
# 'GlyphsToScale': List of ((lists of glyph codes) or (ranges of glyph codes)) that shall be scaled
|
||||||
|
# 'scales': List of associated scale factors, one for each entry in 'GlyphsToScale' (generated by this function)
|
||||||
|
# Example:
|
||||||
|
# { 'GlyphsToScale': [ range(1, 3), [ 7, 10 ], ],
|
||||||
|
# 'scales': [ 1.23, 1.33, ] }
|
||||||
|
#
|
||||||
|
# Each item in 'GlyphsToScale' (a range or an explicit list) forms a group of glyphs that shall be
|
||||||
|
# as rescaled all with the same and maximum possible (for the included glyphs) factor.
|
||||||
|
#
|
||||||
|
# Previously this structure has been used:
|
||||||
|
# 'ScaleGlyph' Lead glyph, which scaling factor is taken
|
||||||
|
# 'GlyphsToScale': List of (glyph code) or (list of two glyph codes that form a closed range)) that shall be scaled
|
||||||
|
# Note that this allows only one group for the whle symbol font, and that the scaling factor is defined by
|
||||||
|
# a specific character, which needs to be manually selected (on each symbol font update).
|
||||||
|
# Previous entries are automatically rewritten to the new style.
|
||||||
|
if 'scales' in scaleGlyph:
|
||||||
|
# Already prepared... must not happen, ignore call
|
||||||
|
return
|
||||||
|
if 'ScaleGlyph' in scaleGlyph:
|
||||||
|
# old method. Rewrite to new.
|
||||||
|
flat_list = []
|
||||||
|
for i in scaleGlyph['GlyphsToScale']:
|
||||||
|
if isinstance(i, tuple):
|
||||||
|
flat_list += list(range(i[0], i[1] + 1))
|
||||||
|
else:
|
||||||
|
flat_list.append(i)
|
||||||
|
scaleGlyph['GlyphsToScale'] = [ flat_list ]
|
||||||
|
sym_dim = get_glyph_dimensions(symbolFont[scaleGlyph['ScaleGlyph']])
|
||||||
|
scaleGlyph['scales'] = [ self.get_scale_factor(sym_dim) ]
|
||||||
|
else:
|
||||||
|
scaleGlyph['scales'] = []
|
||||||
|
for group in scaleGlyph['GlyphsToScale']:
|
||||||
|
sym_dim = get_multiglyph_boundingBox([ symbolFont[g] if g in symbolFont else None for g in group ])
|
||||||
|
scaleGlyph['scales'].append(self.get_scale_factor(sym_dim))
|
||||||
|
|
||||||
|
def get_glyph_scale(self, unicode_value, scaleGlyph, symbolFont):
|
||||||
|
""" Determines whether or not to use scaled glyphs for glyphs in passed glyph_list """
|
||||||
|
if not 'scales' in scaleGlyph:
|
||||||
|
self.prepareScaleGlyph(scaleGlyph, symbolFont)
|
||||||
|
for glyph_list, scale in zip(scaleGlyph['GlyphsToScale'], scaleGlyph['scales']):
|
||||||
|
if unicode_value in glyph_list:
|
||||||
|
return scale
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def replace_font_name(font_name, replacement_dict):
|
def replace_font_name(font_name, replacement_dict):
|
||||||
""" Replaces all keys with vals from replacement_dict in font_name. """
|
""" Replaces all keys with vals from replacement_dict in font_name. """
|
||||||
|
@ -892,10 +933,18 @@ def make_sure_path_exists(path):
|
||||||
if exception.errno != errno.EEXIST:
|
if exception.errno != errno.EEXIST:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def get_multiglyph_boundingBox(glyphs):
|
||||||
def get_glyph_dimensions(glyph):
|
""" Returns dict of the dimensions of multiple glyphs combined """
|
||||||
""" Returns dict of the dimesions of the glyph passed to it. """
|
bbox = [ None, None, None, None ]
|
||||||
bbox = glyph.boundingBox()
|
for glyph in glyphs:
|
||||||
|
if glyph is None:
|
||||||
|
# Glyph has been in defining range but is not in the actual font
|
||||||
|
continue
|
||||||
|
gbb = glyph.boundingBox()
|
||||||
|
bbox[0] = gbb[0] if bbox[0] is None or bbox[0] > gbb[0] else bbox[0]
|
||||||
|
bbox[1] = gbb[1] if bbox[1] is None or bbox[1] > gbb[1] else bbox[1]
|
||||||
|
bbox[2] = gbb[2] if bbox[2] is None or bbox[2] < gbb[2] else bbox[2]
|
||||||
|
bbox[3] = gbb[3] if bbox[3] is None or bbox[3] < gbb[3] else bbox[3]
|
||||||
return {
|
return {
|
||||||
'xmin' : bbox[0],
|
'xmin' : bbox[0],
|
||||||
'ymin' : bbox[1],
|
'ymin' : bbox[1],
|
||||||
|
@ -905,18 +954,9 @@ def get_glyph_dimensions(glyph):
|
||||||
'height': bbox[3] + (-bbox[1]),
|
'height': bbox[3] + (-bbox[1]),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_glyph_dimensions(glyph):
|
||||||
def use_scale_glyph(unicode_value, glyph_list):
|
""" Returns dict of the dimesions of the glyph passed to it. """
|
||||||
""" Determines whether or not to use scaled glyphs for glyphs in passed glyph_list """
|
return get_multiglyph_boundingBox([ glyph ])
|
||||||
for i in glyph_list:
|
|
||||||
if isinstance(i, tuple):
|
|
||||||
if unicode_value >= i[0] and unicode_value <= i[1]:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
if unicode_value == i:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def update_progress(progress):
|
def update_progress(progress):
|
||||||
""" Updates progress bar length.
|
""" Updates progress bar length.
|
||||||
|
|
Loading…
Reference in a new issue