def __init__(self): self.filters = PenBallFiltersManager() self.filters.loadFiltersFromJSON('/'.join([LOCALPATH, JSONFILE])) self.glyphNames = [] self.observedGlyphs = [] self.cachedFont = RFont(showUI=False) self.currentFont = CurrentFont() filtersList = self.filters.keys() if len(filtersList) > 0: self.currentFilterName = filtersList[0] else: self.currentFilterName = None self.fill = True self.observers = [ ('fontChanged', 'fontBecameCurrent'), ('fontChanged', 'fontDidOpen'), ('fontChanged', 'fontDidClose'), ] self.w = Window((100, 100, 800, 500), 'PenBall Wizard v{0}'.format(__version__), minSize=(500, 400)) self.w.filtersPanel = Group((0, 0, 300, -0)) self.w.filtersPanel.filtersList = List((0, 0, -0, -40), filtersList, selectionCallback=self.filterSelectionChanged, doubleClickCallback=self.filterEdit, allowsMultipleSelection=False, allowsEmptySelection=False, rowHeight=22) self.w.filtersPanel.controls = Group((0, -40, -0, 0)) self.w.filtersPanel.addFilter = SquareButton((0, -40, 100, 40), 'Add filter', sizeStyle='small', callback=self.addFilter) self.w.filtersPanel.addFilterChain = SquareButton((100, -40, 100, 40), 'Add operations', sizeStyle='small', callback=self.addFilterChain) self.w.filtersPanel.removeFilter = SquareButton((-100, -40, 100, 40), 'Remove filter', sizeStyle='small', callback=self.removeFilter) self.w.textInput = EditText((300, 0, -90, 22), '', callback=self.stringInput) self.w.generate = SquareButton((-90, 0, 90, 22), 'Generate', callback=self.generateGlyphsToFont, sizeStyle='small') self.w.preview = MultiLineView((300, 22, -0, -0)) self.w.switchFillStroke = SquareButton((-75, -40, 60, 25), 'Stroke', callback=self.switchFillStroke, sizeStyle='small') displayStates = self.w.preview.getDisplayStates() for key in ['Show Metrics','Upside Down','Stroke','Beam','Inverse','Water Fall','Multi Line']: displayStates[key] = False for key in ['Fill','Single Line']: displayStates[key] = True self.w.preview.setDisplayStates(displayStates) for callback, event in self.observers: addObserver(self, callback, event) self.updateControls() self.w.bind('close', self.end) self.launchWindow() self.w.open()
def _BuildUI(self, font): self.w = Window((792, 612)) self.w.editText = EditText((10, 10, -10, 24), callback=self.editTextCallback) self.w.lineView = MultiLineView( (0, 40, -0, -0), pointSize=104, lineHeight=130, selectionCallback=self.lineViewSelectionCallback) #self.w.lineView.setFont(font) self.drawLines() print self.w.lineView.getDisplayStates()
def __init__(self, font): self.font = None self._glyphs = [] statusBarHeight = 20 self.w = Window((900, 700), "Glyph Builder", minSize=(400, 400)) self.w.getNSWindow().setCollectionBehavior_( 128) # NSWindowCollectionBehaviorFullScreenPrimary toolbarItems = [ dict( itemIdentifier="save", label="Save", imageNamed="toolbarScriptSave", callback=self.saveFile, ), dict( itemIdentifier="open", label="Open", imageNamed="toolbarScriptOpen", callback=self.openFile, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict( itemIdentifier="reload", label="Update", imageNamed="toolbarScriptReload", callback=self.reload, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict( itemIdentifier="analyse", label="Analyse", imageNamed="prefToolbarSort", callback=self.analyse, ), dict(itemIdentifier=NSToolbarFlexibleSpaceItemIdentifier), dict(itemIdentifier="buildGlyphs", label="Build Glyphs", imageNamed="toolbarRun", callback=self.generateGlyphs), ] self.w.addToolbar(toolbarIdentifier="GlyphBuilderControllerToolbar", toolbarItems=toolbarItems, addStandardItems=False) self.constructions = CodeEditor((0, 0, -0, -0), constructions, lexer=GlyphConstructionLexer()) # self.constructions.wrapWord(False) # in only availbel in the RoboFont 1.7 beta self.constructions.getNSScrollView().setBorderType_(NSNoBorder) self.preview = MultiLineView( (0, 0, -0, -0), pointSize=50, lineHeight=500, applyKerning=False, displayOptions={ "Beam": False, "displayMode": "Multi Line" }, selectionCallback=self.previewSelectionCallback) self.analyser = AnalyserTextEditor((0, 0, -0, -0), readOnly=True) self.analyserPreview = Group((0, 0, -0, -0)) constructionColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 0, 0, 0, .6) self.analyserPreview.construction = GlyphPreview( (0, 0, -0, -0), contourColor=constructionColor, componentColor=constructionColor) self.analyserPreview.construction.getNSView()._buffer = 100 originColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 1, 0, 0, .6) self.analyserPreview.origin = GlyphPreview((0, 0, -0, -0), contourColor=originColor, componentColor=originColor) self.analyserPreview.origin.getNSView()._buffer = 100 self.analyserPreview.build = Button((10, -30, -10, 20), "Build", sizeStyle="small", callback=self.buildSingleGlyph) self.analyserPreview.build.enable(False) paneDescriptions = [ dict(view=self.analyser, identifier="analyserText", canCollapse=False, minSize=100), dict(view=self.analyserPreview, identifier="analyserPreview", canCollapse=False, minSize=100), ] self.analyserSplit = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, isVertical=False, dividerThickness=1) paneDescriptions = [ dict(view=self.constructions, identifier="constructions", canCollapse=False, minSize=200, maxSize=600, liveResizeable=False), dict(view=self.preview, identifier="preview", canCollapse=False, minSize=300, liveResizeable=True), dict(view=self.analyserSplit, identifier="analyser", canCollapse=True, minSize=100, maxSize=300, liveResizeable=False) ] self.w.split = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, dividerThickness=1) # self.w.split.showPane("analyser", True) self.w.statusBar = StatusBar( (0, -statusBarHeight, -0, statusBarHeight)) self.w.statusBar.hiddenReload = Button((0, 0, -0, -0), "Reload", self.reload) button = self.w.statusBar.hiddenReload.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenReload.bind("\r", ["command"]) self.w.statusBar.hiddenSave = Button((0, 0, -0, -0), "Reload", self.saveFile) button = self.w.statusBar.hiddenSave.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenSave.bind("s", ["command"]) self.subscribeFont(font) self.setUpBaseWindowBehavior() addObserver(self, "fontBecameCurrent", "fontBecameCurrent") addObserver(self, "fontResignCurrent", "fontResignCurrent") self.w.open()
class GlyphBuilderController(BaseWindowController): fileNameKey = "%s.lastSavedFileName" % defaultKey def __init__(self, font): self.font = None self._glyphs = [] statusBarHeight = 20 self.w = Window((900, 700), "Glyph Builder", minSize=(400, 400)) self.w.getNSWindow().setCollectionBehavior_( 128) # NSWindowCollectionBehaviorFullScreenPrimary toolbarItems = [ dict( itemIdentifier="save", label="Save", imageNamed="toolbarScriptSave", callback=self.saveFile, ), dict( itemIdentifier="open", label="Open", imageNamed="toolbarScriptOpen", callback=self.openFile, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict( itemIdentifier="reload", label="Update", imageNamed="toolbarScriptReload", callback=self.reload, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict( itemIdentifier="analyse", label="Analyse", imageNamed="prefToolbarSort", callback=self.analyse, ), dict(itemIdentifier=NSToolbarFlexibleSpaceItemIdentifier), dict(itemIdentifier="buildGlyphs", label="Build Glyphs", imageNamed="toolbarRun", callback=self.generateGlyphs), ] self.w.addToolbar(toolbarIdentifier="GlyphBuilderControllerToolbar", toolbarItems=toolbarItems, addStandardItems=False) self.constructions = CodeEditor((0, 0, -0, -0), constructions, lexer=GlyphConstructionLexer()) # self.constructions.wrapWord(False) # in only availbel in the RoboFont 1.7 beta self.constructions.getNSScrollView().setBorderType_(NSNoBorder) self.preview = MultiLineView( (0, 0, -0, -0), pointSize=50, lineHeight=500, applyKerning=False, displayOptions={ "Beam": False, "displayMode": "Multi Line" }, selectionCallback=self.previewSelectionCallback) self.analyser = AnalyserTextEditor((0, 0, -0, -0), readOnly=True) self.analyserPreview = Group((0, 0, -0, -0)) constructionColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 0, 0, 0, .6) self.analyserPreview.construction = GlyphPreview( (0, 0, -0, -0), contourColor=constructionColor, componentColor=constructionColor) self.analyserPreview.construction.getNSView()._buffer = 100 originColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 1, 0, 0, .6) self.analyserPreview.origin = GlyphPreview((0, 0, -0, -0), contourColor=originColor, componentColor=originColor) self.analyserPreview.origin.getNSView()._buffer = 100 self.analyserPreview.build = Button((10, -30, -10, 20), "Build", sizeStyle="small", callback=self.buildSingleGlyph) self.analyserPreview.build.enable(False) paneDescriptions = [ dict(view=self.analyser, identifier="analyserText", canCollapse=False, minSize=100), dict(view=self.analyserPreview, identifier="analyserPreview", canCollapse=False, minSize=100), ] self.analyserSplit = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, isVertical=False, dividerThickness=1) paneDescriptions = [ dict(view=self.constructions, identifier="constructions", canCollapse=False, minSize=200, maxSize=600, liveResizeable=False), dict(view=self.preview, identifier="preview", canCollapse=False, minSize=300, liveResizeable=True), dict(view=self.analyserSplit, identifier="analyser", canCollapse=True, minSize=100, maxSize=300, liveResizeable=False) ] self.w.split = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, dividerThickness=1) # self.w.split.showPane("analyser", True) self.w.statusBar = StatusBar( (0, -statusBarHeight, -0, statusBarHeight)) self.w.statusBar.hiddenReload = Button((0, 0, -0, -0), "Reload", self.reload) button = self.w.statusBar.hiddenReload.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenReload.bind("\r", ["command"]) self.w.statusBar.hiddenSave = Button((0, 0, -0, -0), "Reload", self.saveFile) button = self.w.statusBar.hiddenSave.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenSave.bind("s", ["command"]) self.subscribeFont(font) self.setUpBaseWindowBehavior() addObserver(self, "fontBecameCurrent", "fontBecameCurrent") addObserver(self, "fontResignCurrent", "fontResignCurrent") self.w.open() def subscribeFont(self, font): self.unsubscribeFont() self.font = font if font is not None: self.preview.setFont(font) self.font.naked().addObserver(self, "fontChanged", "Font.Changed") self.constructionsCallback(self.constructions) def unsubscribeFont(self): if self.font is not None: self.preview.setFont(None) self.preview.set([]) self.font.removeObserver(self, notification="Font.Changed") self.font = None def constructionsCallback(self, sender, update=True): if self.font is None: return font = self.font.naked() self.glyphConstructorFont = GlyphConstructorFont(font) self._glyphs = [] errors = [] try: constructions = ParseGlyphConstructionListFromString( sender.get(), font) except GlyphBuilderError as err: constructions = [] errors.append(str(err)) for construction in constructions: if not construction: glyph = self.preview.createNewLineGlyph() elif construction in self.glyphConstructorFont.glyphsDone: glyph = self.glyphConstructorFont.glyphsDone[construction] else: try: constructionGlyph = GlyphConstructionBuilder( construction, self.glyphConstructorFont, characterMap=None) except GlyphBuilderError as err: errors.append(str(err)) continue if constructionGlyph.name is None: errors.append(construction) continue if RoboFontVersion < "2.0": glyph = font._instantiateGlyphObject() else: glyph = font.layers.defaultLayer.instantiateGlyphObject() glyph.name = constructionGlyph.name glyph.unicode = constructionGlyph.unicode glyph.note = constructionGlyph.note glyph.markColor = constructionGlyph.markColor if RoboFontVersion < "2.0": glyph.setParent(self.glyphConstructorFont) glyph.dispatcher = font.dispatcher else: glyph._font = weakref.ref(self.glyphConstructorFont) # glyph._dispatcher = font._dispatcher glyph.width = constructionGlyph.width constructionGlyph.draw(glyph.getPen()) self.glyphConstructorFont.glyphsDone[glyph.name] = glyph self._glyphs.append(glyph) if errors: print("Errors:") print("\n".join(errors)) if update: self.preview.set(self._glyphs) self.analyser.set(analyseConstructions(font, self._glyphs)) # preview def previewSelectionCallback(self, sender): def _niceNumber(value): i = int(value) if i == value: return "%i" % value else: return "%.2f" % value glyph = sender.getSelectedGlyph() if glyph is not None and glyph.name is None: glyph = None status = [] if glyph is not None: width = _niceNumber(glyph.width) leftMargin = _niceNumber(glyph.leftMargin) rightMargin = _niceNumber(glyph.rightMargin) status = [ glyph.name, "width: %s left: %s right: %s" % (width, leftMargin, rightMargin), "components: %s" % (", ".join( [component.baseGlyph for component in glyph.components])) ] if glyph.unicode: status.append("unicode: %04X" % glyph.unicode) if glyph.note: status.append("note: %s" % (glyph.note[:30] + (glyph.note[30:] and unichr(0x2026)))) if glyph.markColor: status.append("mark: %s" % ", ".join([str(c) for c in glyph.markColor])) self.w.statusBar.set(status) self.analyserPreview.construction.setGlyph(glyph) self.analyserPreview.build.enable(glyph is not None) if glyph is not None: self.analyserPreview.build.setTitle("Build %s" % glyph.name) else: self.analyserPreview.build.setTitle("Build") if glyph is not None and glyph.name in self.font: self.analyserPreview.origin.setGlyph(self.font[glyph.name]) else: self.analyserPreview.origin.setGlyph(None) def buildSingleGlyph(self, sender): glyph = self.preview.getSelectedGlyph() if glyph is None: return if self.font is None: return dest = self.font.newGlyph(glyph.name) dest.clear() glyph.draw(dest.getPen()) dest.unicode = glyph.unicode dest.note = glyph.note if glyph.markColor: dest.markColor = glyph.markColor dest.width = glyph.width # toolbar def generateGlyphs(self, sender): self.reload(update=False) if not self._glyphs: return if self.font is None: return BuildGlyphsSheet(self._glyphs, self.font, self.w) def reload(self, sender=None, update=True): self.constructionsCallback(self.constructions, update) def _saveFile(self, path): if self.font is not None: self.font.lib[self.fileNameKey] = os.path.splitext( os.path.basename(path))[0] txt = self.constructions.get() f = open(path, "w") f.write(txt) f.close() def saveFile(self, sender=None): preferredName = None if self.font is not None and self.font.path is not None: preferredName = os.path.splitext(os.path.basename( self.font.path))[0] if self.fileNameKey in self.font.lib.keys(): # see if we have saved this file before and use that as first choice preferredName = self.font.lib.get(self.fileNameKey) self.showPutFile(["glyphConstruction"], fileName=preferredName, callback=self._saveFile) def _openFile(self, paths): if paths: path = paths[0] f = open(path, "r") txt = f.read() f.close() self.constructions.set(txt) def openFile(self, sender=None): directory = fileName = None if self.font is not None and self.font.path is not None: if self.fileNameKey in self.font.lib.keys(): fileName = self.font.lib.get(self.fileNameKey, "") fileName += ".glyphConstruction" directory = os.path.dirname(self.font.path) fileName = os.path.join(directory, fileName) directory = None getFile(fileTypes=["glyphConstruction"], parentWindow=self.w.getNSWindow(), directory=directory, fileName=fileName, resultCallback=self._openFile) # self.showGetFile(["glyphConstruction"], callback=self._openFile) def analyse(self, sender=None): self.w.split.togglePane("analyser", False) self.reload() # notifications def fontChanged(self, notification): self.reload() def fontBecameCurrent(self, notification): font = notification["font"] self.subscribeFont(font) def fontResignCurrent(self, notification): self.unsubscribeFont() def windowCloseCallback(self, sender): self.unsubscribeFont() removeObserver(self, "fontBecameCurrent") removeObserver(self, "fontResignCurrent") super(GlyphBuilderController, self).windowCloseCallback(sender)
def __init__(self): self.font = CurrentFont() self.glyph = CurrentGlyph() self.upm = self.font.info.unitsPerEm self.rf3 = int(roboFontVersion.split(".")[0]) >= 3 if self.rf3: self.layer = CurrentLayer() # key: glyph name -- value: list containing assembled glyphs self.glyphPreviewCacheDict = {} # key: anchor name -- value: list of mark glyph names self.anchorsOnMarksDict = {} # key: anchor name -- value: list of base glyph names self.anchorsOnBasesDict = {} self.CXTanchorsOnBasesDict = {} # key: mark glyph name -- value: anchor name # NOTE: It's expected that each mark glyph only has one type of anchor self.marksDict = {} self.fillAnchorsAndMarksDicts() # list of glyph names that will be displayed in the UI list self.glyphNamesList = [] # list of glyph names selected in the UI list self.selectedGlyphNamesList = [] # list of the glyph objects that should be inserted # before and after the accented glyphs self.extraGlyphsList = [] self.Blue, self.Alpha = 1, 0.6 self.font.naked().addObserver(self, "fontWasModified", "Font.Changed") addObserver(self, "_fontWillClose", "fontWillClose") addObserver(self, "_currentFontChanged", "fontResignCurrent") addObserver(self, "_currentGlyphChanged", "currentGlyphChanged") addObserver(self, "_drawFill", "draw") addObserver(self, "_drawFill", "drawInactive") addObserver(self, "_previewFill", "drawPreview") # observer for the draw event addObserver(self, "_drawGlyphs", "draw") # draw the glyphs when the glyph window is not in focus addObserver(self, "_drawGlyphs", "drawInactive") addObserver(self, "_drawGlyphs", "drawPreview") integerNumFormatter = NSNumberFormatter.alloc().init() integerNumFormatter.setAllowsFloats_(False) integerNumFormatter.setGeneratesDecimalNumbers_(False) intPosMinZeroNumFormatter = NSNumberFormatter.alloc().init() intPosMinZeroNumFormatter.setAllowsFloats_(False) intPosMinZeroNumFormatter.setGeneratesDecimalNumbers_(False) intPosMinZeroNumFormatter.setMinimum_(NSNumber.numberWithInt_(0)) intPosMinOneNumFormatter = NSNumberFormatter.alloc().init() intPosMinOneNumFormatter.setAllowsFloats_(False) intPosMinOneNumFormatter.setGeneratesDecimalNumbers_(False) intPosMinOneNumFormatter.setMinimum_(NSNumber.numberWithInt_(1)) self.textSize = getExtensionDefault("%s.%s" % (extensionKey, "textSize")) if not self.textSize: self.textSize = 150 self.lineHeight = getExtensionDefault("%s.%s" % (extensionKey, "lineHeight")) if not self.lineHeight: self.lineHeight = 200 self.extraSidebearings = getExtensionDefault( "%s.%s" % (extensionKey, "extraSidebearings")) if not self.extraSidebearings: self.extraSidebearings = [0, 0] self.extraGlyphs = getExtensionDefault("%s.%s" % (extensionKey, "extraGlyphs")) if not self.extraGlyphs: self.extraGlyphs = '' posSize = getExtensionDefault("%s.%s" % (extensionKey, "posSize")) if not posSize: posSize = (100, 100, 1200, 400) self.calibrateMode = getExtensionDefault( "%s.%s" % (extensionKey, "calibrateMode")) if not self.calibrateMode: self.calibrateMode = False calibrateModeStrings = getExtensionDefault( "%s.%s" % (extensionKey, "calibrateModeStrings")) if not calibrateModeStrings: calibrateModeStrings = { 'group1.baseInput': 'dotlessi o s', 'group1.markInput': 'dieresis circumflex macron breve caron', 'group2.baseInput': 'I O S', 'group2.markInput': 'dieresis.cap circumflex.cap macron.cap ' 'breve.cap caron.cap', 'group3.baseInput': 'I.sc O.sc S.sc', 'group3.markInput': 'dieresis circumflex macron breve caron', 'group4.baseInput': '', 'group4.markInput': '', } # -- Window -- self.w = FloatingWindow(posSize, extensionName, minSize=(500, 400)) self.w.fontList = List((10, 10, 190, -41), self.glyphNamesList, selectionCallback=self.listSelectionCallback) if roboFontVersion < '1.7': # use the full width of the column self.w.fontList.getNSTableView().sizeToFit() self.w.fontList.show(not self.calibrateMode) self.w.lineView = MultiLineView((210, 10, -10, -41), pointSize=self.textSize, lineHeight=self.lineHeight, displayOptions={ "Beam": False, "displayMode": "Multi Line" }) self.w.lineView.setFont(self.font) # -- Calibration Mode -- baseLabel = "Bases" markLabel = "Marks" width, height = 190, 140 self.cm = Group((0, 0, 0, 0)) # --- self.cm.group1 = Group((5, height * 0, width, height - 10)) self.cm.group1.baseLabel = TextBox((0, 0, width, 20), baseLabel) self.cm.group1.baseInput = EditText( (0, 21, width, 22), calibrateModeStrings['group1.baseInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group1.markLabel = TextBox((0, 50, width, 20), markLabel) self.cm.group1.markInput = EditText( (0, 71, width, 44), calibrateModeStrings['group1.markInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group1.divider = HorizontalLine((0, -1, -0, 1)) # --- self.cm.group2 = Group((5, height * 1, width, height - 10)) self.cm.group2.baseLabel = TextBox((0, 0, width, 20), baseLabel) self.cm.group2.baseInput = EditText( (0, 21, width, 22), calibrateModeStrings['group2.baseInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group2.markLabel = TextBox((0, 50, width, 20), markLabel) self.cm.group2.markInput = EditText( (0, 71, width, 44), calibrateModeStrings['group2.markInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group2.divider = HorizontalLine((0, -1, -0, 1)) # --- self.cm.group3 = Group((5, height * 2, width, height - 10)) self.cm.group3.baseLabel = TextBox((0, 0, width, 20), baseLabel) self.cm.group3.baseInput = EditText( (0, 21, width, 22), calibrateModeStrings['group3.baseInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group3.markLabel = TextBox((0, 50, width, 20), markLabel) self.cm.group3.markInput = EditText( (0, 71, width, 44), calibrateModeStrings['group3.markInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group3.divider = HorizontalLine((0, -1, -0, 1)) # --- self.cm.group4 = Group((5, height * 3, width, height - 10)) self.cm.group4.baseLabel = TextBox((0, 0, width, 20), baseLabel) self.cm.group4.baseInput = EditText( (0, 21, width, 22), calibrateModeStrings['group4.baseInput'], callback=self.updateCalibrateMode, continuous=False) self.cm.group4.markLabel = TextBox((0, 50, width, 20), markLabel) self.cm.group4.markInput = EditText( (0, 71, width, 44), calibrateModeStrings['group4.markInput'], callback=self.updateCalibrateMode, continuous=False) # --- view = DefconAppKitTopAnchoredNSView.alloc().init() view.addSubview_(self.cm.getNSView()) view.setFrame_(((0, 0), (width + 10, height * 4 - 23))) self.cm.setPosSize((0, 0, width + 10, height * 4 - 22)) self.w.scrollView = ScrollView((5, 10, width + 10, -41), view, drawsBackground=False, hasHorizontalScroller=False) self.w.scrollView.getNSScrollView().setBorderType_(NSNoBorder) # NSScrollElasticityNone self.w.scrollView.getNSScrollView().setVerticalScrollElasticity_(1) self.w.scrollView.show(self.calibrateMode) # -- Footer -- self.w.footer = Group((10, -32, -10, -10)) self.w.footer.calibrateModeCheck = CheckBox( (0, 0, 200, -0), "Calibration Mode", callback=self.calibrateModeCallback, value=self.calibrateMode) self.w.footer.textSizeLabel = TextBox((200, 2, 100, -0), "Text Size") self.w.footer.textSize = EditText((260, 0, 35, -0), self.textSize, callback=self.textSizeCallback, continuous=False, formatter=intPosMinOneNumFormatter) self.w.footer.lineHeightLabel = TextBox((310, 2, 100, -0), "Line Height") self.w.footer.lineHeight = EditText((385, 0, 35, -0), self.lineHeight, callback=self.lineHeightCallback, continuous=False, formatter=integerNumFormatter) self.w.footer.extraSidebearingsLabel = TextBox((436, 2, 180, -0), "Extra Sidebearings") self.w.footer.extraSidebearingsChar = TextBox((592, 2, 20, -0), "&") self.w.footer.extraSidebearingLeft = EditText( (557, 0, 35, -0), self.extraSidebearings[0], callback=self.extraSidebearingsCallback, continuous=False, formatter=intPosMinZeroNumFormatter) self.w.footer.extraSidebearingRight = EditText( (604, 0, 35, -0), self.extraSidebearings[1], callback=self.extraSidebearingsCallback, continuous=False, formatter=intPosMinZeroNumFormatter) self.w.footer.extraGlyphsLabel = TextBox((655, 2, 180, -0), "Extra Glyphs") self.w.footer.extraGlyphs = EditText((739, 0, -0, -0), self.extraGlyphs, callback=self.extraGlyphsCallback, continuous=False) # trigger the initial state and contents of the window self.extraGlyphsCallback() # calls self.updateExtensionWindow() self.w.bind("close", self.windowClose) self.w.open() self.w.makeKey()
def __init__(self, ): self.obfuscated = False self.events = [ ('updateFontList','fontDidOpen'), ('updateFontList','fontDidClose') ] self.builtGlyphs = {} self.copiedDefinitions = None self.fonts = fonts = AllFonts() self.controlGlyph = 'H' if not len(fonts): print '## Derivative Glyph Builder ##\nNo open fonts.' return f = fonts[0] self.collectFontData(f) m = 20 self.w = FloatingWindow((700, 700), 'Derivative Glyphs Builder %s' % (DGBVersion), minSize=(600, 700)) self.w.inner = Group((m, m, -m, -15)) # self.w.inner.fontName = TextBox((0, 0, -0, 20), '%s %s' % (f.info.familyName.upper(), f.info.styleName.upper())) self.w.inner.fonts = PopUpButton((0, 0, -250, 20), listFontNames(fonts), callback=self.changeCurrentFont) self.w.inner.derivatives = List((0, 35, -360, 330), self.buildDerivativesUIList(self.derivatives), selectionCallback=self.selectDerivativeGlyph, editCallback=self.editDerivativeGlyphNames, columnDescriptions=[{'title':'Derivative Glyph', 'width':130}, {'title':'Base Glyphs'}]) self.w.inner.addDefinition = SquareButton((0, 365, -500, 20), 'Add', callback=self.addDefinition, sizeStyle='small') self.w.inner.removeDefinition = SquareButton((-500, 365, 140, 20), 'Remove', callback=self.removeDefinition, sizeStyle='small') self.w.inner.definition = Box((-340, 35, -0, 350)) m = 15 self.w.inner.definition.inner = Group((m, m, -m, 0)) self.w.inner.previewTop = HorizontalLine((0, 399, -0, 1)) self.w.inner.preview = MultiLineView((0, 400, -0, -40), hasHorizontalScroller=True, hasVerticalScroller=False) self.w.inner.previewBottom = HorizontalLine((0, -40, -0, 1)) self.w.inner.preview.setDisplayMode('Single Line') displayStates = self.w.inner.preview.getDisplayStates() displayStates['Show Metrics'] = True self.w.inner.preview.setDisplayStates(displayStates) self.w.inner.preview.setCanSelect(True) self.w.inner.preview._glyphLineView._italicAngle = self.tempFont.info.italicAngle self.w.inner.preview._glyphLineView._italicSlantOffset = self.tempFont.lib['com.typemytype.robofont.italicSlantOffset'] self.w.inner.controlGlyphTitle = TextBox((0, -18, 80, 14), 'Control glyph', sizeStyle='small') self.w.inner.controlGlyph = EditText((80, -22, 90, 22), text='H', callback=self.changeControlGlyph, continuous=False) self.w.inner.buildSelectedGlyphs = Button((-200, -22, 200, 20), 'Build selected glyphs', callback=self.buildSelectedGlyphs) self.w.inner.copySelectedDefinitions = Button((-230, 0, 120, 20), 'Copy', callback=self.copySelectedDefinitions) self.w.inner.pasteDefinitions = Button((-100, 0, 100, 20), 'Paste', callback=self.pasteDefinitions) self.w.inner.pasteDefinitions.enable(False) self.buildDefinitionSheet() for callback, event in self.events: addObserver(self, callback, event) self.w.bind('close', self.endOperations) self.w.open()
def __init__(self): self.w = Window((180, 340), u'Touché!', minSize=(180, 340), maxSize=(1000, 898)) p = 10 w = 160 # options self.w.options = Group((0, 0, 180, 220)) buttons = { "checkSelBtn": { "text": "Check selected glyphs\nfor touching pairs", "callback": self.checkSel, "y": p }, "checkAllBtn": { "text": "Check entire font\n(can take several minutes!)", "callback": self.checkAll, "y": 60 } } for button, data in buttons.items(): setattr( self.w.options, button, SquareButton((p, data["y"], w, 40), data["text"], callback=data["callback"], sizeStyle="small")) self.w.options.zeroCheck = CheckBox((p, 108, w, 20), "Ignore zero-width glyphs", value=True, sizeStyle="small") self.w.options.progress = ProgressSpinner((82, 174, 16, 16), sizeStyle="small") # results self.w.results = Group((0, 220, 180, -0)) self.w.results.show(False) textBoxes = {"stats": 24, "result": 42} for box, y in textBoxes.items(): setattr(self.w.results, box, TextBox((p, y, w, 14), "", sizeStyle="small")) moreButtons = { "spaceView": { "text": "View all in Space Center", "callback": self.showAllPairs, "y": 65 }, "exportTxt": { "text": "Export as MM pair list", "callback": self.exportPairList, "y": 90 } } for button, data in moreButtons.items(): setattr( self.w.results, button, SquareButton((p, data["y"], w, 20), data["text"], callback=data["callback"], sizeStyle="small")) # list and preview self.w.outputList = List((180, 0, 188, -0), [{ "left glyph": "", "right glyph": "" }], columnDescriptions=[{ "title": "left glyph" }, { "title": "right glyph" }], showColumnTitles=False, allowsMultipleSelection=False, enableDelete=False, selectionCallback=self.showPair) self.w.preview = MultiLineView((368, 0, -0, -0), pointSize=256) self.w.open()
def __init__(self, RCJKI): self.RCJKI = RCJKI self.w = Window((800, 300), "Text Center", minSize = (400, 320)) self.w.leftInput = EditText( (0, 0, 60, 20), "", callback = self.inputCallback ) self.w.input = EditText( (60, 0, -60, 20), "", callback = self.inputCallback ) self.pointsSize = [9, 10, 11, 12, 14, 16, 18, 20, 24, 30, 36, 48, 60, 72, 96, 144, 256, 512, 1024], self.w.pointSize = ComboBox( (-60, 0, -0, 20), *self.pointsSize, callback = self.pointSizeCallback ) self.w.pointSize.set(72) self.displayOptions = { 'displayMode': 'Multi Line', # 'Show Kerning': True, 'Multi Line': True, # 'xHeight Cut': False, 'Water Fall': False, # 'Single Line': True, # 'Inverse': False, 'Show Metrics': False, 'Left to Right': True, 'Right to Left': False, 'Center': False, # 'Upside Down': False, 'Stroke': False, 'Fill': False, 'Beam': False, 'Guides': False, 'Blues': False, 'Family Blues': False, 'Show Control glyphs': True, 'Show Space Matrix': True, 'Show Template Glyphs': True, 'showLayers': [] } self.w.multiLineView = MultiLineView( (200, 20, -0, -0), pointSize=72, displayOptions = self.displayOptions ) self.w.multiLineView.setFont(self.RCJKI.currentFont._fullRFont) self.w.multiLineView.setLineHeight(200) self.sourcesList = [] if self.RCJKI.currentFont.fontVariations: self.sourcesList = [dict(Axis = x, PreviewValue = 0) for x in self.RCJKI.currentFont.fontVariations] slider = SliderListCell(minValue = 0, maxValue = 1) self.w.sourcesList = List( (0, 20, 200, 90), self.sourcesList, columnDescriptions = [ {"title": "Axis", "editable": False, "width": 60}, {"title": "PreviewValue", "cell": slider}], showColumnTitles = False, editCallback = self.sourcesListEditCallback, allowsMultipleSelection = False ) self.accordionViewDescriptions = [ dict(label="Display options", view=displayModeGroup((0, 0, -0, -0), self), size=100, collapsed=True, canResize=0), dict(label="Glyphs that use:", view=GlyphUsingDC((0, 0, -0, -0), self), size=180, collapsed=True, canResize=1), dict(label="Deep components that use:", view=DCUsingAE((0, 0, -0, -0), self), size=180, collapsed=True, canResize=1), ] self.w.accordionView = AccordionView((0, 120, 200, -0), self.accordionViewDescriptions, ) self.observer() self.w.open() self.w.bind("close", self.windowWillClose)
def __init__(self, font): self.font = None self._glyphs = [] statusBarHeight = 20 self.w = Window((900, 700), "Glyph Builder", minSize=(400, 400)) if NSApp().runningOnLion(): self.w.getNSWindow().setCollectionBehavior_(128) #NSWindowCollectionBehaviorFullScreenPrimary toolbarItems = [ dict(itemIdentifier="save", label="Save", imageNamed="toolbarScriptSave", callback=self.saveFile, ), dict(itemIdentifier="open", label="Open", imageNamed="toolbarScriptOpen", callback=self.openFile, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict(itemIdentifier="reload", label="Update", imageNamed="toolbarScriptReload", callback=self.reload, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict(itemIdentifier="analyse", label="Analyse", imageNamed="prefToolbarSort", callback=self.analyse, ), dict(itemIdentifier=NSToolbarFlexibleSpaceItemIdentifier), dict(itemIdentifier="buildGlyphs", label="Build Glyphs", imageNamed="toolbarRun", callback=self.generateGlyphs ), ] toolbar = self.w.addToolbar(toolbarIdentifier="GlyphBuilderControllerToolbar", toolbarItems=toolbarItems, addStandardItems=False) self.constructions = CodeEditor((0, 0, -0, -0),constructions, lexer=GlyphConstructionLexer()) #self.constructions.wrapWord(False) # in only availbel in the RoboFont 1.7 beta self.constructions.getNSScrollView().setBorderType_(NSNoBorder) self.preview = MultiLineView((0, 0, -0, -0), pointSize=50, lineHeight=500, applyKerning=False, displayOptions={"Beam" : False, "displayMode" : "Multi Line"}, selectionCallback=self.previewSelectionCallback) self.analyser = AnalyserTextEditor((0, 0, -0, -0), readOnly=True) self.analyserPreview = Group((0, 0, -0, -0)) self.analyserPreview.construction = GlyphPreview((0, 0, -0, -0), contourColor=NSColor.redColor(), componentColor=NSColor.redColor()) self.analyserPreview.construction.getNSView()._buffer = 100 self.analyserPreview.origin = GlyphPreview((0, 0, -0, -0),contourColor=NSColor.blackColor(), componentColor=NSColor.blackColor()) self.analyserPreview.origin.getNSView()._buffer = 100 self.analyserPreview.build = Button((10, -25, -10, 19), "Build", sizeStyle="small", callback=self.buildSingleGlyph) self.analyserPreview.build.enable(False) paneDescriptions = [ dict(view=self.analyser, identifier="analyserText", canCollapse=False, minSize=100), dict(view=self.analyserPreview, identifier="analyserPreview", canCollapse=False, minSize=100), ] self.analyserSplit = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, isVertical=False, dividerThickness=1) paneDescriptions = [ dict(view=self.constructions, identifier="constructions", canCollapse=False, minSize=200, maxSize=600, liveResizeable=False), dict(view=self.preview, identifier="preview", canCollapse=False, minSize=300, liveResizeable=True), dict(view=self.analyserSplit, identifier="analyser", canCollapse=True, minSize=100, maxSize=300, liveResizeable=False) ] self.w.split = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, dividerThickness=1) #self.w.split.showPane("analyser", True) self.w.statusBar = StatusBar((0, -statusBarHeight, -0, statusBarHeight)) self.w.statusBar.hiddenReload = Button((0, 0, -0, -0), "Reload", self.reload) button = self.w.statusBar.hiddenReload.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenReload.bind("\r", ["command"]) self.w.statusBar.hiddenSave = Button((0, 0, -0, -0), "Reload", self.saveFile) button = self.w.statusBar.hiddenSave.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenSave.bind("s", ["command"]) self.subscribeFont(font) self.setUpBaseWindowBehavior() addObserver(self, "fontBecameCurrent", "fontBecameCurrent") addObserver(self, "fontResignCurrent", "fontResignCurrent") self.w.open()
class GlyphBuilderController(BaseWindowController): def __init__(self, font): self.font = None self._glyphs = [] statusBarHeight = 20 self.w = Window((900, 700), "Glyph Builder", minSize=(400, 400)) if NSApp().runningOnLion(): self.w.getNSWindow().setCollectionBehavior_(128) #NSWindowCollectionBehaviorFullScreenPrimary toolbarItems = [ dict(itemIdentifier="save", label="Save", imageNamed="toolbarScriptSave", callback=self.saveFile, ), dict(itemIdentifier="open", label="Open", imageNamed="toolbarScriptOpen", callback=self.openFile, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict(itemIdentifier="reload", label="Update", imageNamed="toolbarScriptReload", callback=self.reload, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict(itemIdentifier="analyse", label="Analyse", imageNamed="prefToolbarSort", callback=self.analyse, ), dict(itemIdentifier=NSToolbarFlexibleSpaceItemIdentifier), dict(itemIdentifier="buildGlyphs", label="Build Glyphs", imageNamed="toolbarRun", callback=self.generateGlyphs ), ] toolbar = self.w.addToolbar(toolbarIdentifier="GlyphBuilderControllerToolbar", toolbarItems=toolbarItems, addStandardItems=False) self.constructions = CodeEditor((0, 0, -0, -0),constructions, lexer=GlyphConstructionLexer()) #self.constructions.wrapWord(False) # in only availbel in the RoboFont 1.7 beta self.constructions.getNSScrollView().setBorderType_(NSNoBorder) self.preview = MultiLineView((0, 0, -0, -0), pointSize=50, lineHeight=500, applyKerning=False, displayOptions={"Beam" : False, "displayMode" : "Multi Line"}, selectionCallback=self.previewSelectionCallback) self.analyser = AnalyserTextEditor((0, 0, -0, -0), readOnly=True) self.analyserPreview = Group((0, 0, -0, -0)) self.analyserPreview.construction = GlyphPreview((0, 0, -0, -0), contourColor=NSColor.redColor(), componentColor=NSColor.redColor()) self.analyserPreview.construction.getNSView()._buffer = 100 self.analyserPreview.origin = GlyphPreview((0, 0, -0, -0),contourColor=NSColor.blackColor(), componentColor=NSColor.blackColor()) self.analyserPreview.origin.getNSView()._buffer = 100 self.analyserPreview.build = Button((10, -25, -10, 19), "Build", sizeStyle="small", callback=self.buildSingleGlyph) self.analyserPreview.build.enable(False) paneDescriptions = [ dict(view=self.analyser, identifier="analyserText", canCollapse=False, minSize=100), dict(view=self.analyserPreview, identifier="analyserPreview", canCollapse=False, minSize=100), ] self.analyserSplit = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, isVertical=False, dividerThickness=1) paneDescriptions = [ dict(view=self.constructions, identifier="constructions", canCollapse=False, minSize=200, maxSize=600, liveResizeable=False), dict(view=self.preview, identifier="preview", canCollapse=False, minSize=300, liveResizeable=True), dict(view=self.analyserSplit, identifier="analyser", canCollapse=True, minSize=100, maxSize=300, liveResizeable=False) ] self.w.split = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, dividerThickness=1) #self.w.split.showPane("analyser", True) self.w.statusBar = StatusBar((0, -statusBarHeight, -0, statusBarHeight)) self.w.statusBar.hiddenReload = Button((0, 0, -0, -0), "Reload", self.reload) button = self.w.statusBar.hiddenReload.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenReload.bind("\r", ["command"]) self.w.statusBar.hiddenSave = Button((0, 0, -0, -0), "Reload", self.saveFile) button = self.w.statusBar.hiddenSave.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenSave.bind("s", ["command"]) self.subscribeFont(font) self.setUpBaseWindowBehavior() addObserver(self, "fontBecameCurrent", "fontBecameCurrent") addObserver(self, "fontResignCurrent", "fontResignCurrent") self.w.open() def subscribeFont(self, font): self.unsubscribeFont() self.font = font if font is not None: self.preview.setFont(font) self.font.naked().addObserver(self, "fontChanged", "Font.Changed") self.constructionsCallback(self.constructions) def unsubscribeFont(self): if self.font is not None: self.preview.setFont(None) self.preview.set([]) self.font.removeObserver(self, notification="Font.Changed") self.font = None def constructionsCallback(self, sender, update=True): if self.font is None: return font = self.font.naked() self.glyphConstructorFont = GlyphConstructorFont(font) self._glyphs = [] errors = [] try: constructions = ParseGlyphConstructionListFromString(sender.get()) except GlyphBuilderError, err: constructions = [] errors.append(str(err)) for construction in constructions: if not construction: glyph = self.preview.createNewLineGlyph() elif construction in self.glyphConstructorFont.glyphsDone: glyph = self.glyphConstructorFont.glyphsDone[construction] else: try: constructionGlyph = GlyphConstructionBuilder(construction, self.glyphConstructorFont) except GlyphBuilderError, err: errors.append(str(err)) continue if constructionGlyph.name is None: errors.append(construction) continue glyph = font._instantiateGlyphObject() glyph.name = constructionGlyph.name glyph.unicode = constructionGlyph.unicode glyph.note = constructionGlyph.note glyph.mark = constructionGlyph.mark glyph.setParent(self.glyphConstructorFont) glyph.dispatcher = font.dispatcher glyph.width = constructionGlyph.width constructionGlyph.draw(glyph.getPen()) self.glyphConstructorFont.glyphsDone[glyph.name] = glyph self._glyphs.append(glyph)
def __init__(self): self.value = 150 self.w = vanilla.Window((700, 210), "Interpol Steps Preview", minSize=(100, 200)) self.w.infoOutput = TextBox((460, 8, -70, 20), "Open 2 Fonts + select a glyph.", alignment="right", sizeStyle="mini") self.w.button = Button((-65, 2, 60, 20), "Options", sizeStyle="small", callback=self.toggleOptions) self.d = Drawer((125, 200), self.w, minSize=(125, 100), maxSize=(125, 200), preferredEdge='right', trailingOffset=15, leadingOffset=0) self.d.fontSize = TextBox( (8, 5, 50, 10), "FONTSIZE", sizeStyle="mini", ) self.d.lineHeight = TextBox( (62, 5, 100, 10), "LINEHEIGHT", sizeStyle="mini", ) self.d.button3 = SquareButton((10, 20, 25, 18), "-", sizeStyle="small", callback=self.ChangePointSizeMinus) self.d.button4 = SquareButton((35, 20, 25, 18), "+", sizeStyle="small", callback=self.ChangePointSizePlus) self.d.button5 = SquareButton((65, 20, 25, 18), "-", sizeStyle="small", callback=self.ChangeLineheightMinus) self.d.button6 = SquareButton((90, 20, 25, 18), "+", sizeStyle="small", callback=self.ChangeLineheightPlus) self.d.interpolStepsText = TextBox((55, 50, 100, 20), "Interpol Steps", sizeStyle="mini") self.d.extrapolStepsText = TextBox((55, 75, 100, 20), "Extrapol Steps", sizeStyle="mini") self.d.interpolStepper = EditIntStepper((10, 45, 45, 22), 4, callback=self.glyphChanged, minValue=1, maxValue=30, sizeStyle='regular') self.d.extrapolStepper = EditIntStepper((10, 70, 45, 22), 1, callback=self.glyphChanged, minValue=0, maxValue=20, sizeStyle='regular') self.d.checkBoxInfo = TextBox((10, 98, 100, 20), "Display Options:", sizeStyle="mini") self.d.checkBoxMetrics = CheckBox((10, 110, 130, 20), "Metrics", sizeStyle="small", callback=self.Metrics) self.d.checkBoxR2L = CheckBox((10, 125, 130, 20), "Right to Left", sizeStyle="small", callback=self.R2L) self.d.checkBoxInverse = CheckBox((10, 140, 130, 20), "Inverse", sizeStyle="small", callback=self.Inverse) self.d.checkBoxStroke = CheckBox((10, 155, 130, 20), "Stroke", sizeStyle="small", callback=self.Stroke) self.w.glyphLineView = MultiLineView((0, 25, 0, 0)) self.w.stemWidthOutputText = TextBox((10, 8, 500, 20), "Beam Y-Pos:", sizeStyle="mini") self.w.stemWidthBeamX = EditText((70, 3, 30, 19), "200", sizeStyle="small", callback=self.stepsCallback) self.w.stemWidthOutput = TextBox( (105, 8, -205, 13), "Measurements of the 1st stem will be displayed here.", sizeStyle="mini") events.addObserver(self, "glyphChanged", "currentGlyphChanged") self.setUpBaseWindowBehavior() self.w.open() self.d.open() self.listOfValues = []
class GlyphBuilderController(BaseWindowController): fileNameKey = "%s.lastSavedFileName" % defaultKey def __init__(self, font): self.font = None self._glyphs = [] statusBarHeight = 20 self.w = Window((900, 700), "Glyph Builder", minSize=(400, 400)) self.w.getNSWindow().setCollectionBehavior_(128) # NSWindowCollectionBehaviorFullScreenPrimary toolbarItems = [ dict( itemIdentifier="save", label="Save", imageNamed="toolbarScriptSave", callback=self.saveFile, ), dict( itemIdentifier="open", label="Open", imageNamed="toolbarScriptOpen", callback=self.openFile, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict( itemIdentifier="reload", label="Update", imageNamed="toolbarScriptReload", callback=self.reload, ), dict(itemIdentifier=NSToolbarSpaceItemIdentifier), dict( itemIdentifier="analyse", label="Analyse", imageNamed="prefToolbarSort", callback=self.analyse, ), dict(itemIdentifier=NSToolbarFlexibleSpaceItemIdentifier), dict( itemIdentifier="buildGlyphs", label="Build Glyphs", imageNamed="toolbarRun", callback=self.generateGlyphs ), ] self.w.addToolbar(toolbarIdentifier="GlyphBuilderControllerToolbar", toolbarItems=toolbarItems, addStandardItems=False) self.constructions = CodeEditor((0, 0, -0, -0), constructions, lexer=GlyphConstructionLexer()) # self.constructions.wrapWord(False) # in only availbel in the RoboFont 1.7 beta self.constructions.getNSScrollView().setBorderType_(NSNoBorder) self.preview = MultiLineView( (0, 0, -0, -0), pointSize=50, lineHeight=500, applyKerning=False, displayOptions={ "Beam": False, "displayMode": "Multi Line" }, selectionCallback=self.previewSelectionCallback ) self.analyser = AnalyserTextEditor((0, 0, -0, -0), readOnly=True) self.analyserPreview = Group((0, 0, -0, -0)) constructionColor = NSColor.colorWithCalibratedRed_green_blue_alpha_(0, 0, 0, .6) self.analyserPreview.construction = GlyphPreview((0, 0, -0, -0), contourColor=constructionColor, componentColor=constructionColor) self.analyserPreview.construction.getNSView()._buffer = 100 originColor = NSColor.colorWithCalibratedRed_green_blue_alpha_(1, 0, 0, .6) self.analyserPreview.origin = GlyphPreview((0, 0, -0, -0), contourColor=originColor, componentColor=originColor) self.analyserPreview.origin.getNSView()._buffer = 100 self.analyserPreview.build = Button((10, -25, -10, 19), "Build", sizeStyle="small", callback=self.buildSingleGlyph) self.analyserPreview.build.enable(False) paneDescriptions = [ dict(view=self.analyser, identifier="analyserText", canCollapse=False, minSize=100), dict(view=self.analyserPreview, identifier="analyserPreview", canCollapse=False, minSize=100), ] self.analyserSplit = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, isVertical=False, dividerThickness=1) paneDescriptions = [ dict(view=self.constructions, identifier="constructions", canCollapse=False, minSize=200, maxSize=600, liveResizeable=False), dict(view=self.preview, identifier="preview", canCollapse=False, minSize=300, liveResizeable=True), dict(view=self.analyserSplit, identifier="analyser", canCollapse=True, minSize=100, maxSize=300, liveResizeable=False) ] self.w.split = Splitter((0, 0, -0, -statusBarHeight), paneDescriptions=paneDescriptions, drawBorderLine=False, dividerThickness=1) # self.w.split.showPane("analyser", True) self.w.statusBar = StatusBar((0, -statusBarHeight, -0, statusBarHeight)) self.w.statusBar.hiddenReload = Button((0, 0, -0, -0), "Reload", self.reload) button = self.w.statusBar.hiddenReload.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenReload.bind("\r", ["command"]) self.w.statusBar.hiddenSave = Button((0, 0, -0, -0), "Reload", self.saveFile) button = self.w.statusBar.hiddenSave.getNSButton() button.setBezelStyle_(NSRoundRectBezelStyle) button.setAlphaValue_(0) self.w.statusBar.hiddenSave.bind("s", ["command"]) self.subscribeFont(font) self.setUpBaseWindowBehavior() addObserver(self, "fontBecameCurrent", "fontBecameCurrent") addObserver(self, "fontResignCurrent", "fontResignCurrent") self.w.open() def subscribeFont(self, font): self.unsubscribeFont() self.font = font if font is not None: self.preview.setFont(font) self.font.naked().addObserver(self, "fontChanged", "Font.Changed") self.constructionsCallback(self.constructions) def unsubscribeFont(self): if self.font is not None: self.preview.setFont(None) self.preview.set([]) self.font.removeObserver(self, notification="Font.Changed") self.font = None def constructionsCallback(self, sender, update=True): if self.font is None: return font = self.font.naked() self.glyphConstructorFont = GlyphConstructorFont(font) self._glyphs = [] errors = [] try: constructions = ParseGlyphConstructionListFromString(sender.get(), font) except GlyphBuilderError as err: constructions = [] errors.append(str(err)) for construction in constructions: if not construction: glyph = self.preview.createNewLineGlyph() elif construction in self.glyphConstructorFont.glyphsDone: glyph = self.glyphConstructorFont.glyphsDone[construction] else: try: constructionGlyph = GlyphConstructionBuilder(construction, self.glyphConstructorFont) except GlyphBuilderError as err: errors.append(str(err)) continue if constructionGlyph.name is None: errors.append(construction) continue if RoboFontVersion < "2.0": glyph = font._instantiateGlyphObject() else: glyph = font.layers.defaultLayer.instantiateGlyphObject() glyph.name = constructionGlyph.name glyph.unicode = constructionGlyph.unicode glyph.note = constructionGlyph.note glyph.markColor = constructionGlyph.markColor if RoboFontVersion < "2.0": glyph.setParent(self.glyphConstructorFont) glyph.dispatcher = font.dispatcher else: glyph._font = weakref.ref(self.glyphConstructorFont) # glyph._dispatcher = font._dispatcher glyph.width = constructionGlyph.width constructionGlyph.draw(glyph.getPen()) self.glyphConstructorFont.glyphsDone[glyph.name] = glyph self._glyphs.append(glyph) if errors: print("Errors:") print("\n".join(errors)) if update: self.preview.set(self._glyphs) self.analyser.set(analyseConstructions(font, self._glyphs)) # preview def previewSelectionCallback(self, sender): def _niceNumber(value): i = int(value) if i == value: return "%i" % value else: return "%.2f" % value glyph = sender.getSelectedGlyph() if glyph is not None and glyph.name is None: glyph = None status = [] if glyph is not None: width = _niceNumber(glyph.width) leftMargin = _niceNumber(glyph.leftMargin) rightMargin = _niceNumber(glyph.rightMargin) status = [ glyph.name, "width: %s left: %s right: %s" % (width, leftMargin, rightMargin), "components: %s" % (", ".join([component.baseGlyph for component in glyph.components])) ] if glyph.unicode: status.append("unicode: %04X" % glyph.unicode) if glyph.note: status.append("note: %s" % (glyph.note[:30] + (glyph.note[30:] and unichr(0x2026)))) if glyph.markColor: status.append("mark: %s" % ", ".join([str(c) for c in glyph.markColor])) self.w.statusBar.set(status) self.analyserPreview.construction.setGlyph(glyph) self.analyserPreview.build.enable(glyph is not None) if glyph is not None: self.analyserPreview.build.setTitle("Build %s" % glyph.name) else: self.analyserPreview.build.setTitle("Build") if glyph is not None and glyph.name in self.font: self.analyserPreview.origin.setGlyph(self.font[glyph.name]) else: self.analyserPreview.origin.setGlyph(None) def buildSingleGlyph(self, sender): glyph = self.preview.getSelectedGlyph() if glyph is None: return if self.font is None: return dest = self.font.newGlyph(glyph.name) dest.clear() glyph.draw(dest.getPen()) dest.unicode = glyph.unicode dest.note = glyph.note if glyph.markColor: dest.markColor = glyph.markColor dest.width = glyph.width # toolbar def generateGlyphs(self, sender): self.reload(update=False) if not self._glyphs: return if self.font is None: return BuildGlyphsSheet(self._glyphs, self.font, self.w) def reload(self, sender=None, update=True): self.constructionsCallback(self.constructions, update) def _saveFile(self, path): if self.font is not None: self.font.lib[self.fileNameKey] = os.path.splitext(os.path.basename(path))[0] txt = self.constructions.get() f = open(path, "w") f.write(txt) f.close() def saveFile(self, sender=None): preferredName = None if self.font is not None and self.font.path is not None: preferredName = os.path.splitext(os.path.basename(self.font.path))[0] if self.fileNameKey in self.font.lib.keys(): # see if we have saved this file before and use that as first choice preferredName = self.font.lib.get(self.fileNameKey) self.showPutFile(["glyphConstruction"], fileName=preferredName, callback=self._saveFile) def _openFile(self, paths): if paths: path = paths[0] f = open(path, "r") txt = f.read() f.close() self.constructions.set(txt) def openFile(self, sender=None): directory = fileName = None if self.font is not None and self.font.path is not None: if self.fileNameKey in self.font.lib.keys(): fileName = self.font.lib.get(self.fileNameKey, "") fileName += ".glyphConstruction" directory = os.path.dirname(self.font.path) fileName = os.path.join(directory, fileName) directory = None getFile(fileTypes=["glyphConstruction"], parentWindow=self.w.getNSWindow(), directory=directory, fileName=fileName, resultCallback=self._openFile) # self.showGetFile(["glyphConstruction"], callback=self._openFile) def analyse(self, sender=None): self.w.split.togglePane("analyser", False) self.reload() # notifications def fontChanged(self, notification): self.reload() def fontBecameCurrent(self, notification): font = notification["font"] self.subscribeFont(font) def fontResignCurrent(self, notification): self.unsubscribeFont() def windowCloseCallback(self, sender): self.unsubscribeFont() removeObserver(self, "fontBecameCurrent") removeObserver(self, "fontResignCurrent") super(GlyphBuilderController, self).windowCloseCallback(sender)
def __init__(self): self.filters = PenBallFiltersManager() # self.filters.loadFiltersFromJSON('/'.join([LOCALPATH, JSONFILE])) filtersList = getExtensionDefault( '{0}.filtersList'.format(PENBALLWIZARD_EXTENSIONKEY), []) self.filters.loadFiltersList(filtersList) self.glyphNames = [] self.observedGlyphs = [] self.currentFont = CurrentFont() self.initCachedFont() filtersList = self.filters.keys() if len(filtersList) > 0: self.currentFilterName = filtersList[0] else: self.currentFilterName = None self.fill = True self.observers = [ ('fontChanged', 'fontBecameCurrent'), ('fontChanged', 'fontDidOpen'), ('fontChanged', 'fontDidClose'), ] self.displaySettingsRecord = { 1: ('✓ Fill', True), 2: ('Stroke', False), 3: ('Inverse', False), } self.w = Window((100, 100, 800, 500), 'PenBall Wizard v{0}'.format(__version__), minSize=(500, 400)) self.w.filtersPanel = Group((0, 0, 300, -0)) self.w.filtersPanel.filtersList = List( (0, 0, -0, -80), filtersList, selectionCallback=self.filterSelectionChanged, doubleClickCallback=self.filterEdit, allowsMultipleSelection=False, allowsEmptySelection=False, rowHeight=22) self.w.filtersPanel.controls = Group((0, -80, -0, 0)) self.w.filtersPanel.addFilter = SquareButton((0, -80, 100, 40), 'Add filter', sizeStyle='small', callback=self.addFilter) self.w.filtersPanel.addFilterChain = SquareButton( (100, -80, 100, 40), 'Add operations', sizeStyle='small', callback=self.addFilterChain) self.w.filtersPanel.removeFilter = SquareButton( (-100, -80, 100, 40), 'Remove filter', sizeStyle='small', callback=self.removeFilter) self.w.textInput = EditText((300, 0, -75, 22), '', callback=self.stringInput) self.w.generate = SquareButton((0, -40, 300, -0), 'Generate', callback=self.buildGenerationSheet, sizeStyle='small') self.w.displaySettings = PopUpButton( (-70, 3, -10, 15), self.makeDisplaySettingsMenuItems(), sizeStyle='mini', callback=self.changeDisplaySettings) self.w.displaySettings.getNSPopUpButton().setPullsDown_(True) self.w.displaySettings.getNSPopUpButton().setBordered_(False) self.w.preview = MultiLineView((300, 22, -0, -0)) self.updatePreview() displayStates = self.w.preview.getDisplayStates() for key in [ 'Show Metrics', 'Upside Down', 'Stroke', 'Beam', 'Inverse', 'Water Fall', 'Multi Line' ]: displayStates[key] = False for key in ['Fill', 'Single Line']: displayStates[key] = True self.w.preview.setDisplayStates(displayStates) for callback, event in self.observers: addObserver(self, callback, event) self.updateControls() self.w.bind('close', self.end) self.launchWindow() self.w.open()
def __init__(self): super(MultiFontMetricsWindow, self).__init__() # ui vars originLeft = 0 originRight = 0 width = 956 height = 640 netWidth = width - MARGIN_LFT - MARGIN_RGT jumpingY = MARGIN_TOP # let's see if there are opened fonts (fontDB, ctrlFontsList, fontsOrder) self.loadFontsOrder() self.updateUnicodeMinimum() # defining plugin windows self.w = Window((originLeft, originRight, width, height), "Multi Font Metrics Window", minSize=(800, 400)) self.w.bind('resize', self.mainWindowResize) switchButtonWdt = 140 self.w.switchButton = PopUpButton( (MARGIN_LFT, jumpingY, switchButtonWdt, vanillaControlsSize['PopUpButtonRegularHeight']), self.textModeOptions, sizeStyle='regular', callback=self.switchButtonCallback) # free text textCtrlX = MARGIN_LFT + MARGIN_COL + switchButtonWdt self.w.typewriterCtrl = Typewriter( (textCtrlX, jumpingY, -(RIGHT_COLUMN + MARGIN_COL + MARGIN_RGT), vanillaControlsSize['EditTextRegularHeight']), self.unicodeMinimum, callback=self.typewriterCtrlCallback) self.w.typewriterCtrl.show(False) # strings ctrls self.w.textStringsControls = TextStringsControls( (textCtrlX, jumpingY, -(RIGHT_COLUMN + MARGIN_COL + MARGIN_RGT), vanillaControlsSize['PopUpButtonRegularHeight'] + 1), self.unicodeMinimum, callback=self.textStringsControlsCallback) self.stringDisplayMode, self.glyphNamesToDisplay = self.w.textStringsControls.get( ) # multi line jumpingY += vanillaControlsSize['ButtonRegularHeight'] + MARGIN_ROW self.calcSpacingMatrixHeight() self.multiLineOptions = { 'Show Kerning': self.applyKerning, 'Center': False, 'Show Space Matrix': False, 'Single Line': False, 'displayMode': u'Multi Line', 'Stroke': False, 'xHeight Cut': False, 'Upside Down': False, 'Beam': False, 'Water Fall': False, 'Inverse': False, 'Show Template Glyphs': True, 'Multi Line': True, 'Right to Left': False, 'Show Metrics': self.showMetrics, 'Show Control glyphs': True, 'Fill': True, 'Left to Right': self.leftToRight } self.w.lineView = MultiLineView( (MARGIN_LFT, jumpingY, -(RIGHT_COLUMN + MARGIN_COL + MARGIN_RGT), -MARGIN_BTM - MARGIN_HALFROW - self.spacingMatrixHeight), pointSize=self.bodySize, lineHeight=self.lineHeight, doubleClickCallback=self.lineViewDoubleClickCallback, selectionCallback=self.lineViewSelectionCallback, bordered=True, applyKerning=self.applyKerning, hasHorizontalScroller=False, hasVerticalScroller=True, displayOptions=self.multiLineOptions, updateUserDefaults=False, menuForEventCallback=None) # static options # body self.w.bodyCtrl = ComboBoxWithCaption( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, vanillaControlsSize['ComboBoxSmallHeight'] + 1), 'Body Size:', self.bodySizeOptions, '{}'.format(self.bodySize), sizeStyle='small', callback=self.bodyCtrlCallback) # line height jumpingY += vanillaControlsSize['ComboBoxSmallHeight'] + int( MARGIN_HALFROW) self.w.lineHgtCtrl = ComboBoxWithCaption( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, vanillaControlsSize['ComboBoxSmallHeight'] + 1), 'Line Height:', self.lineHeightOptions, '{}'.format(self.lineHeight), sizeStyle='small', callback=self.lineHgtCtrlCallback) # show metrics jumpingY += vanillaControlsSize['ComboBoxSmallHeight'] + MARGIN_ROW self.w.showMetricsCheck = CheckBox( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, vanillaControlsSize['CheckBoxSmallHeight']), "Show Metrics", value=self.showMetrics, sizeStyle='small', callback=self.showMetricsCheckCallback) # show kerning checkbox jumpingY += vanillaControlsSize['CheckBoxSmallHeight'] + MARGIN_ROW * .3 self.w.applyKerningCheck = CheckBox( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, vanillaControlsSize['CheckBoxSmallHeight']), "Show Kerning", value=self.applyKerning, sizeStyle='small', callback=self.applyKerningCheckCallback) jumpingY += vanillaControlsSize['CheckBoxSmallHeight'] + MARGIN_ROW * .3 self.w.leftToRightCheck = CheckBox( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, vanillaControlsSize['CheckBoxSmallHeight']), "Left to right", value=self.leftToRight, sizeStyle='small', callback=self.leftToRightCheckCallback) # separationLine jumpingY += vanillaControlsSize['CheckBoxSmallHeight'] + int( MARGIN_HALFROW) self.w.separationLineOne = HorizontalLine( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, 1)) jumpingY += int(MARGIN_HALFROW) fontsOrderControllerHeight = FONT_ROW_HEIGHT * len(self.fontsOrder) + 2 self.w.fontsOrderController = FontsOrderController( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, fontsOrderControllerHeight), self.fontsOrder, callback=self.fontsOrderControllerCallback) jumpingY += fontsOrderControllerHeight self.w.separationLineTwo = HorizontalLine( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, 1)) # joystick jumpingY += MARGIN_HALFROW self.w.joystick = SpacingJoystick( (-(RIGHT_COLUMN + MARGIN_RGT), jumpingY, RIGHT_COLUMN, 0), verticalMode=self.verticalMode, marginCallback=self.joystickMarginCallback, verticalCallback=self.joystickVerticalCallback) # edit metrics self.w.spacingMatrix = SpacingMatrix( (MARGIN_LFT, -(MARGIN_BTM + self.spacingMatrixHeight), self.w.getPosSize()[2] - MARGIN_LFT - MARGIN_RGT, self.spacingMatrixHeight), glyphNamesToDisplay=self.glyphNamesToDisplay, verticalMode=self.verticalMode, fontsOrder=self.fontsOrder, callback=self.spacingMatrixCallback) # add observer addObserver(self, 'newFontOpened', "newFontDidOpen") addObserver(self, 'openCloseFontCallback', "fontDidOpen") addObserver(self, 'openCloseFontCallback', "fontDidClose") # lit up! self.updateSubscriptions() self.updateLineView() self.setUpBaseWindowBehavior() self.w.open()