Last active
September 7, 2020 20:32
-
-
Save frankrolf/ec914189f0ebb374217a3b7298f4e20e to your computer and use it in GitHub Desktop.
Robofont observer to avoid writing fractional coordinates.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from mojo.events import addObserver | |
import mojo | |
VERSION = mojo.roboFont.version | |
class FloatObserver(object): | |
def __init__(self): | |
# addObserver(self, 'saveCallback', 'fontWillClose') | |
addObserver(self, 'saveCallback', 'fontWillSave') | |
def check_float_list(self, flat_list): | |
if( | |
any([isinstance(coord, float) for coord in flat_list]) | |
): | |
return True | |
return False | |
def glyph_has_float_av(self, glyph): | |
# Check if the glyph in question has a .0 advance width. | |
if isinstance(glyph.width, float) and glyph.width == int(glyph.width): | |
return True | |
return False | |
def glyph_has_float_anchors(self, glyph): | |
# Check if the anchors have a .0 position. | |
anchors = [value for a in glyph.anchors for value in a.position] | |
if self.check_float_list(anchors): | |
return True | |
return False | |
def glyph_has_float(self, glyph): | |
# Check if the glyph has a float advance width, | |
# float point coordinates, or float component offsets. | |
if isinstance(glyph.width, float): | |
return True | |
points = [crd for c in glyph for p in c.points for crd in (p.x, p.y)] | |
components = [offset for c in glyph.components for offset in c.offset] | |
if self.check_float_list(points): | |
return True | |
if( | |
self.check_float_list(components) and | |
[int(v) for v in components] != components | |
): | |
return True | |
return False | |
def saveCallback(self, sender): | |
f = sender['font'] | |
glyphOrder = f.glyphOrder | |
float_glyphs = [ | |
gn for gn in glyphOrder if self.glyph_has_float(f[gn])] | |
float_av_glyphs = [ | |
gn for gn in glyphOrder if self.glyph_has_float_av(f[gn])] | |
float_anchor_glyphs = [ | |
gn for gn in glyphOrder if self.glyph_has_float_anchors(f[gn])] | |
# if any([float_glyphs, float_av_glyphs, float_anchor_glyphs]): | |
# print(f.info.familyName, f.info.styleName) | |
if float_glyphs: | |
print('float coords:', ' '.join(float_glyphs)) | |
if float_av_glyphs: | |
print('float av:', ' '.join(float_av_glyphs)) | |
if float_anchor_glyphs: | |
print('float anchors:', ' '.join(float_anchor_glyphs)) | |
for gn in float_glyphs: | |
f[gn].round() | |
if VERSION.startswith('3'): | |
f[gn].changed() | |
else: | |
f[gn].update() | |
for gn in float_av_glyphs: | |
g = f[gn] | |
# weird: g.width = int(g.width) does not work. | |
old_width = int(g.width) | |
g.width = old_width + 1 | |
g.width = old_width | |
for gn in float_anchor_glyphs: | |
g = f[gn] | |
for a in g.anchors: | |
old_x = int(round(a.x)) | |
old_y = int(round(a.y)) | |
a.x = old_x + 1 | |
a.x = old_x | |
a.y = old_y + 1 | |
a.y = old_y | |
print('Adding floatObserver.') | |
FloatObserver() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment