Skip to content

Commit

Permalink
font-patcher: Shift glyphs in a ScaleGlyph identically
Browse files Browse the repository at this point in the history
[why]
Ranges of glyphs in the ScaleGlyph shall be handles 'as one' glyph,
utilizing the same scale (and new: the same shift) for each of them.

The shift has been ignored until now; each glyph is shifted based on its
individual bounding box and not the combined bounding box.

This is needed now for Braille glyphs, where the relative position of an
identical 'dot' is of significance.

[how]
We use the ScaleGlyph's new combined bounding box feature (previous
commit) to do the shifting based on that virtual box instead of the
concrete glyph's box.

For this to work we always prepareScaleGlyph(); previously we only did
it if we needed the scale for --mono.

Because we do the shifting after the scaling the combined bounding box
also needs to be scaled.

Cave: The actual glyph transformation (scaling) is not exact and incurs
rounding errors. To prevent that we usually first scale, then determine
the new bounding box (which is slightly different from what mathe-
matically would be expected), then do the shift based on the new BB.

This can not be done with our 'virtual' bounding box, so we resort to
the 'mathematically correct' shift, which can be off by some 0.x %.
Do not use this on glyphs that shall go right to the border of the font
'cells'.
To enforce this it is only active if we have a negative 'overlap' (i.e.
padding) around that glyphs.

Signed-off-by: Fini Jastrow <[email protected]>
  • Loading branch information
Finii committed Sep 7, 2022
1 parent 112c7bd commit 0d26d0a
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions font-patcher
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ class font_patcher:
progressText = ''
careful = False
glyphSetLength = 0
self.prepareScaleGlyph(scaleGlyph, symbolFont)

if self.args.careful:
careful = True
Expand Down Expand Up @@ -1067,7 +1068,10 @@ class font_patcher:
self.sourceFont[currentSourceFontGlyph].transform(psMat.scale(scale_ratio_x, scale_ratio_y))

# Use the dimensions from the newly pasted and stretched glyph
sym_dim = get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph])
if overlap >= 0:
sym_dim = get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph])
else
sym_dim = get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph], scaleGlyph, scale_ratio_x, scale_ratio_y)
y_align_distance = 0
if sym_attr['valign'] == 'c':
# Center the symbol vertically by matching the center of the line height and center of symbol
Expand Down Expand Up @@ -1193,6 +1197,8 @@ class font_patcher:
# 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 not scaleGlyph:
return
if 'scales' in scaleGlyph:
# Already prepared... must not happen, ignore call
return
Expand Down Expand Up @@ -1221,8 +1227,6 @@ class font_patcher:

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
Expand Down Expand Up @@ -1268,8 +1272,27 @@ def get_multiglyph_boundingBox(glyphs):
'height': bbox[3] + (-bbox[1]),
}

def get_glyph_dimensions(glyph):
""" Returns dict of the dimesions of the glyph passed to it. """
def get_glyph_dimensions(glyph, scaleGlyph = None, scale_x = 1.0, scale_y = 1.0):
""" Returns dict of the dimensions of the glyph passed to it. """
if scaleGlyph:
# Return the combined bounding box on glyphs affected by scaleGlyph
# Take the scaling into account. Note that this scaling is not fully
# correct because the actual scaled glyph will have a slightly different
# (rounded) scale. Usually one should determine the bounding box after actual
# scaling, but we can not really scale the virtual combined bounding box.
for glyph_list, sym_dim in zip(scaleGlyph['GlyphsToScale'], scaleGlyph['bbdims']):
if not glyph.unicode in glyph_list:
continue
if not sym_dim:
continue
return {
'xmin' : sym_dim['xmin'] * scale_x,
'ymin' : sym_dim['ymin'] * scale_y,
'xmax' : sym_dim['xmax'] * scale_x,
'ymax' : sym_dim['ymax'] * scale_y,
'width' : sym_dim['width'] * scale_x,
'height': sym_dim['height'] * scale_y,
}
return get_multiglyph_boundingBox([ glyph ])

def update_progress(progress):
Expand Down

0 comments on commit 0d26d0a

Please sign in to comment.