Skip to content

Instantly share code, notes, and snippets.

@connordavenport
Last active September 27, 2023 16:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save connordavenport/905b29d9fd19087ba1ebd3976c910123 to your computer and use it in GitHub Desktop.
Save connordavenport/905b29d9fd19087ba1ebd3976c910123 to your computer and use it in GitHub Desktop.
Sync Anchors
from mojo.subscriber import Subscriber, registerGlyphEditorSubscriber, disableSubscriberEvents
'''
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
On that same line add a comma separated list of glyph names (no spaces)
Adding a ! after a glyph name with a semicolon separated list will add
an exception and only those anchors will be moved
e.g.
glyph == "O"
LinkedGlyphs:Oslash,Ohorn!top;bottom
^ this will ignore
all anchors but these
'''
LINKED_KEY = 'LinkedGlyphs'
ANCHOR_COLOR = (0.502, 0.0015, 0.9985, 1.0)
class sinkAnchors(Subscriber):
debug = True
def glyphEditorGlyphDidChangeContours(self, info):
glyph = info["glyph"]
with disableSubscriberEvents():
if glyph:
baseAnchors = glyph.anchors
glyphs = self.getGlyphs(glyph)
if glyphs != []:
for gs in glyphs:
exception = [a.name for a in glyph.anchors]
e = gs.split("!")
if len(e) > 1:
exception = e[1].split(";")
gs = gs.split("!")[0]
if gs in self.font.keys() and gs != glyph.name:
for a in glyph.anchors:
if a.name in exception:
if self.getAnchorMap(self.font[gs]).get(a.name):
oa = self.getAnchorMap(self.font[gs])[a.name]
oa.position = a.position
oa.color = ANCHOR_COLOR
def getGlyphs(self, glyph):
# function partially stolen from ContoursLock by Thom Janssen
note = glyph.note
splitNote = note.split('\n')
if note:
linkedGlyphs = []
try:
for line in range(len(splitNote)):
if LINKED_KEY in splitNote[line]:
for i in splitNote[line].split(':')[1].split(','):
linkedGlyphs.append(i)
except:
pass
else:
linkedGlyphs = []
return linkedGlyphs
def getAnchorMap(glyph):
anchorMap = {a.name:a for a in glyph.anchors}
return anchorMap
registerGlyphEditorSubscriber(sinkAnchors)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment