Skip to content

Instantly share code, notes, and snippets.

@rbmntjs
Last active July 1, 2018 16:46
Show Gist options
  • Save rbmntjs/d8cbcca859c38bd182b2 to your computer and use it in GitHub Desktop.
Save rbmntjs/d8cbcca859c38bd182b2 to your computer and use it in GitHub Desktop.
A simple Python script that loops through your font, looks for anchors, and spits out a mark feature.
'''
Print all requested anchors as a mark feature
Requires Robofont, Robofab and the Adobe FDK
'''
# TODO: Include mkmk?
####################################################
### Edit the next settings to match your font setup.
####################################################
# Which anchors do you want to listen for?
# This dictionary defines the anchor name and the mark class.
# You can add more as you need
anchors = {
'top': '@mark_top',
'base': '@mark_base',
'below': '@mark_below',
'ogonek': '@mark_ogonek',
'_top': '@mark_top',
'_base': '@mark_base',
'_below': '@mark_below',
'_ogonek': '@mark_ogonek'
}
# Want to give your lookup a particular name? Here’s how.
lookupname = 'marks_latin'
##################################
### From here on, no more editing!
##################################
f = CurrentFont()
# Start of the lookup code. We’ll append to this later
# These string should probably not be modified, but there is a lot of repetition
# For now, I guess appending is a lesser evil
newlist = 'feature mark {\n\tlookup ' + lookupname + ' {\n'
markclasses = ''
# In order to get AZaz alphabetic order, we take the names,
# sort, then use that as the key for the real loop
names = f.keys()
names.sort()
# Store all the names of the glyphs you need in the GDEF table
# Also store the diacritics
gdef_names = ''
gdef_diacritics = ''
# First, make sure we have a font open
try:
f
except:
print 'No font active. Please have a font active.'
raise
else:
# There is a font active. Run the code
for n in names:
# Now n is a string. We need to have an object. So:
g = f[n] # Set the g object to be a glyph object again
if g.anchors:
base_anchor_vals = '' # Create a variable that contains all the anchors per glyph
mark_anchor_vals = '' # Store the diacritics ones as well
for a in g.anchors:
if a.name.startswith('_'):# If it does, this is a diacritic
mark_anchor_mark = anchors[a.name]
mark_anchor_vals += '<anchor ' + str(int(a.x)) + ' ' + str(int(a.y)) + '> ' + mark_anchor_mark
else:# If it doesn’t, this is a base glyph
base_anchor_mark = anchors[a.name]
base_anchor_vals += ' <anchor ' + str(int(a.x)) + ' ' + str(int(a.y)) + '> mark ' + base_anchor_mark
if a.name.startswith('_'):# If it does, this is a diacritic
gdef_diacritics += g.name + ' '# Add the name to the diacritics we touch
markclasses += 'markClass [' + g.name + '] ' + mark_anchor_vals + ';\n'
else:# If it doesn’t, this is a base glyph
gdef_names += g.name + ' '# Add the name to the base glyphs we touch
newlist += '\t\tpos base [' + g.name + ']' + base_anchor_vals + ';\n'
newlist += '\t} ' + lookupname + ';\n} mark;\n'
print markclasses
print newlist
gdef_base = '@BASE = [' + gdef_names + '];\n\n'
gdef_marks = '@COMBINING_MARKS = [' + gdef_diacritics + '];\n\n'
gdef = 'table GDEF {\n\tGlyphClassDef @BASE,,@COMBINING_MARKS,;\n} GDEF;'
print gdef_base, gdef_marks, gdef
@rbmntjs
Copy link
Author

rbmntjs commented Feb 15, 2016

Added a simple markClasses setup as well, and made the GDEF classes available for easy insertion. The loop is the ugly part now: I could roll it all into a smarter if setup, but it’s all a bit entangled.

@rbmntjs
Copy link
Author

rbmntjs commented Feb 16, 2016

I’ve now consolidated the two loops into one, and made more explicit variables. That’s better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment