mirror of
https://github.com/ryanoasis/nerd-fonts.git
synced 2024-09-19 09:51:48 +02:00
font-patcher: Centralize scaling code
[why] The glyph rescaling is scattered about two functions and several branches. It becomes hard to follow what is done when and why. [how] Use one function that determines any glyph scaling, that includes all handling except ScaleGlyph related stuff. This simplifies the code in copy_glyphs() a lot, and keeps all the scaling in get_scale_factors(). [note] No behavioral change introduced with this. [note] Well, it fixes the possible problem (it will never happen, but lurks) that a glyph is in the ScaleGlyph range AND has Y scaling set. The old code first uses the ScaleGlyph scaling and afterwards violates it by mindlessly doing the Y stretch. This would not happen anymore with the new code. If a ScaleGlyph is specified for a certain glyph, that ScaleGlyph is followed and nothing else. Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
parent
99c2608313
commit
ebd381c86b
1 changed files with 45 additions and 53 deletions
98
font-patcher
98
font-patcher
|
@ -969,17 +969,33 @@ class font_patcher:
|
|||
# print("FINAL", self.font_dim)
|
||||
|
||||
|
||||
def get_scale_factor(self, sym_dim):
|
||||
scale_ratio = 1
|
||||
def get_scale_factors(self, sym_dim, stretch):
|
||||
""" 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)
|
||||
|
||||
# We want to preserve x/y aspect ratio, so find biggest scale factor that allows symbol to fit
|
||||
scale_ratio_x = self.font_dim['width'] / sym_dim['width']
|
||||
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
||||
if scale_ratio_x > scale_ratio_y:
|
||||
scale_ratio = scale_ratio_y
|
||||
# For monospaced fonts all chars need to be maximum 'one' space wide
|
||||
target_width = self.font_dim['width']
|
||||
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']
|
||||
scale_ratio_y = target_height / sym_dim['height']
|
||||
|
||||
if stretch == 'pa':
|
||||
# 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)
|
||||
scale_ratio_y = scale_ratio_x
|
||||
else:
|
||||
scale_ratio = scale_ratio_x
|
||||
return scale_ratio
|
||||
# Keep the not-stretched direction
|
||||
if not 'x' in stretch:
|
||||
scale_ratio_x = 1.0
|
||||
if not 'y' in stretch:
|
||||
scale_ratio_y = 1.0
|
||||
|
||||
return (scale_ratio_x, scale_ratio_y)
|
||||
|
||||
|
||||
def copy_glyphs(self, sourceFontStart, symbolFont, symbolFontStart, symbolFontEnd, exactEncoding, scaleRules, setName, attributes):
|
||||
|
@ -1039,6 +1055,10 @@ class font_patcher:
|
|||
currentSourceFontGlyph = sourceFontStart + sourceFontCounter
|
||||
sourceFontCounter += 1
|
||||
|
||||
# For debugging process only limited glyphs
|
||||
# if currentSourceFontGlyph != 0xe7bd:
|
||||
# continue
|
||||
|
||||
if not self.args.quiet:
|
||||
if self.args.progressbars:
|
||||
update_progress(round(float(index + 1) / glyphSetLength, 2))
|
||||
|
@ -1077,48 +1097,20 @@ class font_patcher:
|
|||
|
||||
# Prepare symbol glyph dimensions
|
||||
sym_dim = get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph])
|
||||
scale_ratio_x = 1
|
||||
scale_ratio_y = 1
|
||||
if glyph_scale_data is not None:
|
||||
# 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, sym_attr['stretch'])
|
||||
|
||||
# Now that we have copy/pasted the glyph, if we are creating a monospace
|
||||
# font we need to scale and move the glyphs. It is possible to have
|
||||
# empty glyphs, so we need to skip those.
|
||||
if self.args.single and sym_dim['width'] and sym_dim['height']:
|
||||
# If we want to preserve that aspect ratio of the glyphs we need to
|
||||
# find the largest possible scaling factor that will allow the glyph
|
||||
# to fit in both the x and y directions
|
||||
if sym_attr['stretch'] == 'pa':
|
||||
scale_ratio_x = None
|
||||
if glyph_scale_data:
|
||||
# We want to preserve the relative size of each glyph in a glyph group
|
||||
scale_ratio_x = glyph_scale_data[0]
|
||||
if scale_ratio_x is None:
|
||||
# In the remaining cases, each glyph is sized independently to each other
|
||||
scale_ratio_x = self.get_scale_factor(sym_dim)
|
||||
scale_ratio_y = scale_ratio_x
|
||||
else:
|
||||
if 'x' in sym_attr['stretch']:
|
||||
# Stretch the glyph horizontally to fit the entire available width
|
||||
scale_ratio_x = None
|
||||
if glyph_scale_data is not None and glyph_scale_data[1] is not None:
|
||||
scale_ratio_x = self.font_dim['width'] / glyph_scale_data[1]['width']
|
||||
if scale_ratio_x is None:
|
||||
scale_ratio_x = self.font_dim['width'] / sym_dim['width']
|
||||
# end if single width
|
||||
|
||||
# non-monospace (double width glyphs)
|
||||
# elif sym_dim['width'] and sym_dim['height']:
|
||||
# any special logic we want to apply for double-width variation
|
||||
# would go here
|
||||
|
||||
if 'y' in sym_attr['stretch']:
|
||||
# Stretch the glyph vertically to total line height (good for powerline separators)
|
||||
# Currently stretching vertically for both monospace and double-width
|
||||
scale_ratio_y = None
|
||||
if glyph_scale_data is not None and glyph_scale_data[1] is not None:
|
||||
scale_ratio_y = self.font_dim['height'] / glyph_scale_data[1]['height']
|
||||
if scale_ratio_y is None:
|
||||
scale_ratio_y = self.font_dim['height'] / sym_dim['height']
|
||||
if not self.args.single:
|
||||
# any special logic we want to apply for double-width variation
|
||||
# would go here:
|
||||
# non monospaced fonts just scale y, on 'y' scale request (not 'pa')
|
||||
scale_ratio_x = 1.0
|
||||
if not 'y' in sym_attr['stretch']:
|
||||
scale_ratio_y = 1.0
|
||||
|
||||
overlap = sym_attr['params'].get('overlap')
|
||||
|
||||
|
@ -1286,7 +1278,7 @@ class font_patcher:
|
|||
# 'bbdims': [ dim_dict1, dim_dict2, ] }
|
||||
#
|
||||
# Each item in 'ScaleGroups' (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.
|
||||
# as rescaled all with the same and maximum possible (for the included glyphs) 'pa' factor.
|
||||
# If the 'bbdims' is present they all shall be shifted in the same way.
|
||||
#
|
||||
# Previously this structure has been used:
|
||||
|
@ -1307,7 +1299,7 @@ class font_patcher:
|
|||
scaleRules['ScaleGroups'] = []
|
||||
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_factor(sym_dim)
|
||||
scale = self.get_scale_factors(sym_dim, 'pa')[0]
|
||||
scaleRules['scales'].append(scale)
|
||||
scaleRules['bbdims'].append(sym_dim)
|
||||
|
||||
|
@ -1320,7 +1312,7 @@ class font_patcher:
|
|||
else:
|
||||
group_list.append(i)
|
||||
sym_dim = get_glyph_dimensions(symbolFont[scaleRules['ScaleGlyph']])
|
||||
scale = self.get_scale_factor(sym_dim)
|
||||
scale = self.get_scale_factors(sym_dim, 'pa')[0]
|
||||
scaleRules['ScaleGroups'].append(group_list)
|
||||
scaleRules['scales'].append(scale)
|
||||
scaleRules['bbdims'].append(None) # The 'old' style keeps just the scale, not the positioning
|
||||
|
|
Loading…
Reference in a new issue