Skip to content

Instantly share code, notes, and snippets.

@okay-type
Last active April 7, 2023 13:42
Show Gist options
  • Save okay-type/6a8fbb6b2e4423ef761ceb958d3a2260 to your computer and use it in GitHub Desktop.
Save okay-type/6a8fbb6b2e4423ef761ceb958d3a2260 to your computer and use it in GitHub Desktop.
A hack to see different italic angles when drawing a ufo
from mojo.subscriber import Subscriber, registerRoboFontSubscriber
'''
Italic angles are complicated.
Technically, they don't really exist.
They're constructed by font editors to make drawing slanted things more consistent.
It's very helpful.
In reality, however, a lot of designs don't have just one consistent angle.
Italic capitals are often more upright than lowercase.
Sometimes italic punctuation is entirely upright.
Italic angles are complicated.
Usually the designer just picks a general angle and deals with it.
But sometimes it's really useful to see the exact glyph-specific italic angle.
This tool attempts to do that.
FYI: I have not really tested this.
It using a dictionary of fonts and groups of glyphs -- see: angle_data{}
Currently (and very dumbly) this tool does a hard-change of the f.info.italicAngle and italicOffset
Notes:
This simply looks for "Italic" in the f.info.styleName
You can use a substring of the f.info.familyName (e.g.: "Harry" works as shorthand for "Harry Slab")
Problems:
I tried to undo the font info hacking (it reverts to the initial values when you save),
but there are a whole lot of problems you can run into if you're not careful.
If you rereun the tool while editing a overridden glyph you will lose your default italic values
This really shouldnt change the font info, but I haven't have time to figure out if there's a smarter way
Might be a good idea to hard-code the default values as a catch-all entry in the dictionary
Bugs:
Sometimes when switching between glyphs in different groups, Robofont will fail to update the italicOffset preview
v1 2023 4 6
initial proof of concept
Jackson
[email protected]
'''
angle_data = {
'Arbitrary Font Name Substring': {
'arbitrary group name': {
'italicAngle': -14,
'italicOffset': -86,
'glyphs': ['a', 'list', 'of', 'glyph', 'names']
},
},
'Harry': {
'lowercase': {
'italicAngle': -14,
'italicOffset': -86,
'glyphs': 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.split(' ')
},
'math': {
'italicAngle': 0,
'italicOffset': 5,
'glyphs': 'plus minus plusminus divide multiply equal less greater'.split(' ')
},
}
}
class ItalicAnglessss(Subscriber):
debug = True
def build(self):
print('building ItalicAnglessss()')
self.wait = False
self.initial_values = {}
for f in AllFonts():
self.cache_initial_italic_data(f)
def destroy(self):
for f in AllFonts():
self.revert_initial_italic_data(f)
print('ItalicAnglessss Terminated!')
def cache_initial_italic_data(self, f):
initial_italicAngle = f.info.italicAngle or 0
initial_italicOffset = f.lib['com.typemytype.robofont.italicSlantOffset'] or 0
print('caching initial italic data', f.path, initial_italicAngle, initial_italicOffset)
self.initial_values = self.initial_values | {f: [initial_italicAngle, initial_italicOffset]}
def fontInfoDidChange(self, info):
if self.wait == False:
self.cache_initial_italic_data(info['font'])
def fontDocumentDidOpen(self, info):
self.cache_initial_italic_data(info['font'])
def revert_initial_italic_data(self, f):
if 'Italic' in f.info.styleName:
f.info.italicAngle = self.initial_values[f][0] or 0
f.lib['com.typemytype.robofont.italicSlantOffset'] = self.initial_values[f][1] or 0
print('reverting initial italic data', f.path, f.info.italicAngle, f.lib['com.typemytype.robofont.italicSlantOffset'])
def fontDocumentWillSave(self, info):
self.revert_initial_italic_data(info['font'])
def glyphEditorDidSetGlyph(self, info):
glyph = info['glyph']
self.update(glyph)
def update(self, glyph):
f = glyph.font
if 'Italic' in f.info.styleName:
group, italicAngle, italicOffset = self.find(glyph)
print(glyph.name, italicAngle, italicOffset)
self.wait = True
f.info.italicAngle = italicAngle
f.lib['com.typemytype.robofont.italicSlantOffset'] = italicOffset
f.changed()
self.wait = False
def find(self, glyph):
f = glyph.font
group = 'default'
italicAngle = 0
italicOffset = 0
# get default values from initial cache
if f in self.initial_values:
group = 'initial_values'
italicAngle = self.initial_values[f][0]
italicOffset = self.initial_values[f][1]
# check dictionary for other values
for family, dict in angle_data.items():
if family in f.info.familyName:
for key, dict in angle_data[family].items():
if glyph.name in dict['glyphs']:
group = key
italicAngle = dict['italicAngle']
italicOffset = dict['italicOffset']
return([group, italicAngle, italicOffset])
if __name__ == '__main__':
registerRoboFontSubscriber(ItalicAnglessss)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment