import vanilla import merz from mojo.subscriber import Subscriber, WindowController, registerRoboFontSubscriber from mojo.roboFont import AllFonts WHITE = (1, 1, 1, 1) class RoboFontWithUISubscriberDemo(Subscriber, WindowController): debug = True def build(self): self.fontList = [] self.w = vanilla.FloatingWindow((0, 500), "RoboFont Useless Data") columnDescriptions = [ dict(title="name") ] self.fontList = vanilla.List( "auto", [], columnDescriptions=columnDescriptions, showColumnTitles=False, allowsEmptySelection=False, allowsMultipleSelection=False, selectionCallback=self.fontListSelectionCallback ) self.infoList = vanilla.List( "auto", [] ) self.featureList = vanilla.List( "auto", [] ) self.namesView = merz.MerzView( "auto", backgroundColor=(0, 0, 0, 1) ) columnDescriptions = [ dict( width=300 ), {}, {}, dict( width=100 ), ] rows = [ dict( height=25, cells=( vanilla.TextBox("auto", "Fonts:"), vanilla.TextBox("auto", "Info:"), vanilla.TextBox("auto", "Features:"), vanilla.TextBox("auto", "Glyphs:"), ) ), dict( height=400, cells=( self.fontList, self.infoList, self.featureList, self.namesView ), ), ] self.w.gridView = vanilla.GridView( "auto", rows, columnDescriptions=columnDescriptions, columnWidth=150, columnSpacing=10, rowHeight=25, rowSpacing=0 ) metrics = dict( margin=15 ) rules = [ "H:|-margin-[gridView]-margin-|", "V:|-margin-[gridView]-margin-|" ] self.w.addAutoPosSizeRules(rules, metrics) def started(self): for font in AllFonts(): self.fontList.append( dict( name=f"{font.info.familyName}-{font.info.styleName}", font=font ) ) self.w.open() # ---- callbacks with delays ---- # fontDocumentDidOpenNewDelay = 0 def fontDocumentDidOpenNew(self, info): font = info["font"] self.fontList.append( dict( name="New Family-New Style", font=font ) ) fontDocumentDidOpenDelay = 0 def fontDocumentDidOpen(self, info): font = info["font"] self.fontList.append( dict( name=f"{font.info.familyName}-{font.info.styleName}", font=font ) ) fontDocumentWillCloseDelay = 0 def fontDocumentWillClose(self, info): font = info["font"] for i, item in enumerate(self.fontList.get()): if item["font"] == font: break del self.fontList[i] def fontListSelectionCallback(self, sender): selection = sender.getSelection() if not selection: font = None else: font = sender[selection[0]]["font"] self.updateInfoList(font) self.updateFeatureList(font) self.updateNamesView(font) # ---- update functions ---- # def updateInfoList(self, font): items = [] if font is not None: text = [] if font.info.copyright is not None: text.append(font.info.copyright) if font.info.trademark is not None: text.append(font.info.trademark) if font.info.license is not None: text.append(font.info.license) text = "\n".join(text) if text: items = text.replace("\n", " ").split(" ") items = [i for i in items if i] items.sort() self.infoList.set(items) def updateFeatureList(self, font): items = [] if font is not None: text = font.features.text if text: items = text.replace("\n", " ").split(" ") items = [i for i in items if i] items.sort() self.featureList.set(items) def updateNamesView(self, font): if font is None: names = [] else: names = font.glyphOrder view = self.namesView container = view.getMerzContainer() container.clearSublayers() if not names: return lengths = [len(name) for name in names] minLength = min(lengths) maxLength = max(lengths) xSteps = maxLength - minLength ySteps = len(names) width = view.width() height = view.height() offset = 10 if xSteps == 0: xStep = 0 else: xStep = (width - (offset * 2)) / xSteps yStep = (height - (offset * 2)) / ySteps pathLayer = container.appendPathSublayer( fillColor=None, strokeColor=WHITE, strokeWidth=1 ) pen = pathLayer.getPen() pen.moveTo((offset, offset)) y = offset for length in lengths: x = offset + (xStep * length) pen.lineTo((x, y)) y += yStep pen.endPath() registerRoboFontSubscriber(RoboFontWithUISubscriberDemo)