Skip to content

Instantly share code, notes, and snippets.

@roberto-arista
Created December 24, 2021 11:08
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 roberto-arista/11893947b9de0321b8b637f87f6849e4 to your computer and use it in GitHub Desktop.
Save roberto-arista/11893947b9de0321b8b637f87f6849e4 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
from math import hypot
from mojo.subscriber import Subscriber, WindowController
from mojo.subscriber import registerGlyphEditorSubscriber, unregisterGlyphEditorSubscriber
from mojo.roboFont import OpenWindow
from vanilla import FloatingWindow, CheckBox
RED = 1, 0, 0, 1
WHITE = 1, 1, 1, 1
class PointDistanceControllerPalette(WindowController):
debug = True
def build(self):
self.w = FloatingWindow((200, 40), "PointDistanceController")
self.w.checkBox = CheckBox((10, 10, -10, 20), "Display Distances",
callback=self.checkBoxCallback, value=True)
self.w.open()
def started(self):
PointDistanceController.controller = self
registerGlyphEditorSubscriber(PointDistanceController)
def destroy(self):
unregisterGlyphEditorSubscriber(PointDistanceController)
PointDistanceController.controller = None
def checkBoxCallback(self, sender):
if sender.get():
PointDistanceController.controller = self
registerGlyphEditorSubscriber(PointDistanceController)
else:
PointDistanceController.controller = None
unregisterGlyphEditorSubscriber(PointDistanceController)
class PointDistanceController(Subscriber):
debug = True
def build(self):
glyphEditor = self.getGlyphEditor()
self.container = glyphEditor.extensionContainer(
identifier="com.roboFont.PointDistanceController.foreground",
location="foreground",
clear=True
)
self.distancesLayer = self.container.appendBaseSublayer()
def destroy(self):
self.container.clearSublayers()
def glyphDidChangeSelection(self, info):
# get the glyph from the notification
glyph = info["glyph"]
# get the selection
selection = glyph.selection
# check if the selection is more than 1 and less than 6
if 2 <= len(selection) <= 5:
self.distancesLayer.setVisible(True)
self.distancesLayer.clearSublayers()
done = []
# loop over all the points in the selection
for p in selection:
# loope in a the loop again over all the points in the selection
for p2 in selection:
# check if the point is not the same
if p == p2:
continue
# check if we already handled the point
if set([p, p2]) in done:
continue
# add a line to the distances layer
self.distancesLayer.appendLineSublayer(
startPoint=(p.x, p.y),
endPoint=(p2.x, p2.y),
strokeWidth=1,
strokeColor=RED
)
# calculate the center point
cx = p.x + (p2.x - p.x) * .5
cy = p.y + (p2.y - p.y) * .5
# calculate the distance
dist = hypot(p2.x - p.x, p2.y - p.y)
# store connections to avoid duplicates
done.append(set([p, p2]))
# create the label layer
self.distancesLayer.appendTextLineSublayer(
position=(cx, cy),
backgroundColor=RED,
text=f"{dist:.0f}" if dist % 1 == 0 else f"{dist:.2f}",
font="system",
weight="bold",
pointSize=12,
padding=(4, 1),
cornerRadius=4,
fillColor=WHITE,
horizontalAlignment='center',
verticalAlignment='center',
)
else:
self.distancesLayer.setVisible(False)
if __name__ == '__main__':
OpenWindow(PointDistanceControllerPalette)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment