Skip to content

Instantly share code, notes, and snippets.

@okay-type
Forked from connordavenport/syncAnchors.py
Last active March 23, 2021 17:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okay-type/371e72cd3247a3fd03695b9c6f86005b to your computer and use it in GitHub Desktop.
Save okay-type/371e72cd3247a3fd03695b9c6f86005b to your computer and use it in GitHub Desktop.
Sync Anchors
from mojo.subscriber import Subscriber, registerGlyphEditorSubscriber
'''
A startup script to help keep anchors in-sync across glyphs
The script will not append anchors, only move existing anchors
To set a linked glyph, add 'LinkedGlyphs' in your main glyph's .note
Under that line add a comma separated list of glyph names (no spaces)
e.g.
glyph == "O"
LinkedGlyphs
Oslash,Ohorn
forked from https://gist.github.com/connordavenport/905b29d9fd19087ba1ebd3976c910123
'''
class nsync(Subscriber):
debug = False
linkedKey = 'LinkedGlyphs'
anchorColor = (0.502, 0.0015, 0.9985, 1.0)
def build(self):
self.font = None
self.glyph = None
def destroy(self):
if self.debug == True:
print('nsync', 'destroy!')
def glyphAnchorsDidChange(self, info):
self.glyph = info['glyph']
self.font = self.glyph.font
if self.glyph:
# baseAnchors = self.glyph.anchors
glyphs = self.getGlyphs(self.glyph)
fkeys = self.font.glyphOrder
if glyphs != []:
for gs in glyphs:
if gs in fkeys and gs != self.glyph.name:
for a in self.glyph.anchors:
if self.getAnchorMap(self.font[gs]).get(a.name):
oa = self.getAnchorMap(self.font[gs])[a.name]
oa.position = a.position
oa.color = self.anchorColor
def getGlyphs(self, glyph):
note = self.glyph.note
if note:
linkedGlyphs = []
try:
for line in range(len(note.split('\n'))):
if self.linkedKey in note.split('\n')[line]:
for i in note.split('\n')[line + 1].split(','):
linkedGlyphs.append(i)
except:
pass
else:
linkedGlyphs = []
return linkedGlyphs
def getAnchorMap(self, glyph):
anchorMap = {a.name: a for a in glyph.anchors}
return anchorMap
registerGlyphEditorSubscriber(nsync)
from vanilla import *
import os
from AppKit import NSFilenamesPboardType, NSDragOperationCopy
from mojo.UI import PostBannerNotification
class dosomething():
def __init__(self):
L = 10 # left
W = 200 - L * 2 # width
T = L * 1 # top
H = 25 # vertical unit
winHeight = 9
self.w = Window((200, winHeight * H), 'Do-er')
self.w.fileList = List(
(W + (L * 3), T, 380, -T),
[],
columnDescriptions=[
{"title": "Files", "allowsSorting": True}], # files
showColumnTitles=False,
allowsMultipleSelection=True,
enableDelete=True,
otherApplicationDropSettings=dict(
type=NSFilenamesPboardType,
operation=NSDragOperationCopy,
callback=self.dropCallback
),
)
self.w.target = TextBox((L, T + 4, W, H), 'In these files')
T += H
self.w.targets = RadioGroup(
(L, T, W, H * 3),
['current ufo', 'all open ufos', 'file list'],
callback=self.targets,
)
self.w.targets.set(0)
T += H * 3
self.w.lineB = HorizontalLine((L, T, W, H))
T += H
self.w.go = Button((L, T, W, H), 'DO IT!', callback=self.x)
self.w.open()
def dropCallback(self, sender, dropInfo):
isProposal = dropInfo["isProposal"]
supportedFontFileFormats = [".ufo", ".ttf", ".otf"]
existingPaths = sender.get()
paths = dropInfo["data"]
paths = [path for path in paths if path not in existingPaths]
paths = [path for path in paths if os.path.splitext(path)[-1].lower() in supportedFontFileFormats or os.path.isdir(path)]
if not paths:
return False
if not isProposal:
for path in paths:
item = {}
item['Files'] = path
self.w.fileList.append(item)
return True
def targets(self, sender):
if sender.get() == 2:
xywh = list(self.w.getPosSize())
xywh[2] = 600
self.w.setPosSize(xywh)
else:
xywh = list(self.w.getPosSize())
xywh[2] = 200
self.w.setPosSize(xywh)
def x(self, sender):
fromThese = self.w.targets.get()
targets = []
fontToClose = []
if fromThese == 0:
targets = [CurrentFont()]
elif fromThese == 1:
targets = AllFonts()
elif fromThese == 2:
for path in self.w.fileList:
f = OpenFont(path['Files'], showInterface=False)
fontToClose.append(f)
targets = fontToClose
for f in targets:
print(f)
self.do(f)
if len(fontToClose) > 0:
for f in fontToClose:
f.save()
f.close()
self.w.close()
PostBannerNotification('Robofont', 'all accents done building')
def do(self, f):
glyphAnchorSyncInfo = [
{'baseGlyph': 'O', 'descGlyphs': 'Oslash Ohorn'},
{'baseGlyph': 'U', 'descGlyphs': 'Uhorn'},
{'baseGlyph': 'o', 'descGlyphs': 'oslash ohorn'},
{'baseGlyph': 'u', 'descGlyphs': 'uslash uhorn'},
]
fkeys = f.glyphOrder
for entry in glyphAnchorSyncInfo:
baseGlyph = entry['baseGlyph']
if baseGlyph in fkeys:
baseGlyph = f[baseGlyph]
baseGlyph.note = 'LinkedGlyphs\n'
descGlyphs = entry['descGlyphs'].split(' ')
for descGlyph in descGlyphs:
baseGlyph.note += descGlyph
if descGlyph != descGlyphs[-1]:
baseGlyph.note += ','
dosomething()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment