Last active
April 7, 2023 13:42
-
-
Save okay-type/6a8fbb6b2e4423ef761ceb958d3a2260 to your computer and use it in GitHub Desktop.
A hack to see different italic angles when drawing a ufo
This file contains 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.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