from math import hypot from mojo.subscriber import Subscriber, registerGlyphEditorSubscriber from mojo.roboFont import RPoint RED = 1, 0, 0, 1 WHITE = 1, 1, 1, 1 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 glyphEditorDidSetGlyph(self, info): self.drawMeasurements(info) def glyphDidChangeSelection(self, info): self.drawMeasurements(info) def drawMeasurements(self, info): # get the glyph from the notification glyph = info["glyph"] # get the selection selection = glyph.selectedPoints + glyph.selectedAnchors # 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 = [] # if 2 points selected, add one to get horizontal/vertical measurements if len(selection) == 2: pos = selection[0].x, selection[1].y # only add the point if it doesn’t match with an existing one if not any([pos == p.position for p in selection]): helperPoint = RPoint() helperPoint.position = pos selection = set(selection + (helperPoint,)) # 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__': registerGlyphEditorSubscriber(PointDistanceController)