def interpolate(self): progress = ProgressWindow( "Interpolation", tickCount = len(self.instances), ) for instance in self.instances: #ip = NewFont(self.family_name, instance.style_name, showUI=self.show_ui) ip = self.masters[instance.master0].copy() ip.info.familyName = self.family_name ip.info.styleName = instance.style_name progress.update("Interpolating %s %s ..." % (self.family_name, instance.style_name)) ip.interpolate( instance.factor, self.masters[instance.master0], self.masters[instance.master1], doProgress=False ) ip.info.openTypeOS2WeightClass = instance.weight_class ip.features.text = instance.features self.post_interpolation(ip) instance.font = ip progress.close()
def generate(self): progress = ProgressWindow( "Generation", tickCount = len(self.instances) * 2, ) i = 0 for instance in self.instances: font = instance.font ps_name = "%s-%s" % (font.info.familyName, font.info.styleName) ps_name = ps_name.replace(" ", "") self.pre_generate(font, progress) font_path = join(self.base_path, self.instance_dir, "%s.otf" % ps_name) font.generate( path=font_path, format="otf", decompose=True, checkOutlines=True, autohint=True, releaseMode=True, glyphOrder=None, progressBar=None, useMacRoman=False, ) if self.use_notifications: notify("Font was generated", ps_name, font_path) font.close() i += 1 if self.use_notifications: notify("Fonts Generated", "%i fonts were generated." % i, "%s" % join(self.base_path, self.instance_dir)) progress.close()
def readFromFile_ofType_(self, path, tp): progress = ProgressWindow("Opening...") try: font = self.font = Font(path) window = self.vanillaWindowController = DefconAppKitTestDocumentWindow(font) self.addWindowController_(window.w.getNSWindowController()) finally: progress.close() return True
def readFromFile_ofType_(self, path, tp): progress = ProgressWindow("Opening...") try: font = self.font = Font(path) window = self.vanillaWindowController = DefconAppKitTestDocumentWindow( font) self.addWindowController_(window.w.getNSWindowController()) finally: progress.close() return True
def send(self, sender): recipients = self.window.recipients.get() selection = [ recipients[i] for i in self.window.recipients.getSelection() ] if selection == []: selection = self.window.recipients.get() recipients = ', '.join(selection) progress = ProgressWindow('', tickCount=3, parentWindow=self.window) try: tmpdir = tempfile.mkdtemp(prefix="ghostlines") progress.update('Generating OTF') # Should be controlled which options are used somewhere filename = os.path.join(tmpdir, self.font.info.familyName + '.otf') self.font.generate(format="otf", path=filename, decompose=True, checkOutlines=True, autohint=True) progress.update('Sending via Ghostlines') with open(filename, 'rb') as otf: params = dict(otf=otf, recipients=recipients, notes=self.window.notes_field.get(), designer_email_address=self.window. email_address_field.get()) license_path = self.license_storage.retrieve() if license_path is not '' and os.path.exists(license_path): with open(license_path, 'rb') as license: filename = os.path.basename(license_path) _, extension = os.path.splitext(license_path) content_type = filetypes[extension] params['license'] = (filename, license, content_type) response = Ghostlines('v0.1').send(**params) else: response = Ghostlines('v0.1').send(**params) if response.status_code == requests.codes.created: message("{} was delivered".format(self.font.info.familyName)) else: print repr(response) message( "{} could not be delivered".format( self.font.info.familyName), "Error code: {}\n{}".format(response.status_code, response.json())) finally: progress.close()
def send(self, *_): subscribers = self.window.subscriber_info.subscribers.get() subscriber_ids = [ subscribers[i]["id"] for i in self.window.subscriber_info.subscribers.getSelection() ] notes = self.note_draft_storage.retrieve() font_family_id = self.family_id_storage.retrieve() license_path = self.license_storage.retrieve() progress = ProgressWindow('', tickCount=3, parentWindow=self.window) try: tmpdir = tempfile.mkdtemp(prefix="ghostlines") progress.update('Generating OTF') # Should be controlled which options are used somewhere otf_path = os.path.join(tmpdir, '{}.otf'.format(self.font.info.familyName)) self.font.generate(format="otf", path=otf_path, decompose=True, checkOutlines=True, autohint=True) progress.update('Sending via Ghostlines') params = dict(notes=notes, font_family_id=font_family_id) with open(otf_path, 'rb') as otf: params['otfs'] = [(os.path.basename(otf_path), otf.read(), "application/octet-stream")] if subscriber_ids: params['subscriber_ids[]'] = subscriber_ids if self.license_exists: with open(license_path, 'rb') as license: filename = os.path.basename(license_path) _, extension = os.path.splitext(license_path) content_type = filetypes[extension] params['license'] = (filename, license.read(), content_type) token = AppStorage("accessToken").retrieve() response = Ghostlines('v1', token=token).create_release(**params) if response.status_code == requests.codes.created: message("{} was delivered".format(self.font.info.familyName)) self.refresh_releases() else: ErrorMessage( "{} could not be delivered".format( self.font.info.familyName), response.json()["errors"]) finally: progress.close()
def initDocument(self, added, document): u""" """ progressWindow = ProgressWindow() if not added: print 'Document %s, already open' % document.pid else: self.currentDocument = document window = self.openWindow(document) self.windows[document.pid] = window self.redrawPaper = True window.paper.update() progressWindow.close()
def _export_sbix(self, otfpath, palette=0, image_format="png", replace_outlines=False, parent_window=None): if not have_flat: print("ColorFont._export_sbix: The 'flat' Python module is missing.") print("Please see <https://github.com/jenskutilek/RoboChrome/blob/master/README.md>") return if replace_outlines: alt_glyphname_string = "%s" else: alt_glyphname_string = "%s.mac" font = TTFont(otfpath) if (font.has_key("sbix")): print(" WARNING: Replacing existing sbix table in %s" % otfpath) replace_outlines = True # insert special nodes into glyphs self._format_outlines_special(font, replace_outlines) # build sbix table sbix = table__s_b_i_x("sbix") if parent_window is not None: progress = ProgressWindow("Rendering bitmaps ...", tickCount=len(self.bitmap_sizes)*len(self.keys()), parentWindow=parent_window) for current_ppem in sorted(self.bitmap_sizes): current_set = Strike(ppem=current_ppem) for glyphname in self.keys(): if parent_window is not None: progress.update("Rendering /%s @ %i px ..." % (glyphname, current_ppem)) alt_glyphname = alt_glyphname_string % glyphname if image_format == "png": image_data = self[glyphname].get_png(palette, current_ppem) elif image_format == "pdf": image_data = self[glyphname].get_pdf(palette, current_ppem) else: # TODO: handle tiff, jpg, (dupe, mask) # fallback image_data = self[glyphname].get_png(palette, current_ppem) if image_data is not None: current_set.glyphs[alt_glyphname] = sbixGlyph( glyphName=glyphname, graphicType=image_format, imageData=image_data, ) sbix.strikes[current_ppem] = current_set if parent_window is not None: progress.close() font["sbix"] = sbix font.save(otfpath[:-4] + "_sbix" + otfpath[-4:]) font.close()
def ok(self, sender=None): self.w.cancel_button.enable(False) self.w.ok_button.enable(False) self.w.copy_button.enable(False) fonts = self.w.font_list.getSelection() progress = ProgressWindow( "", tickCount = len(fonts), parentWindow = self.w, ) results = [] for i in range(len(AllFonts())): font = AllFonts()[i] if i in fonts: progress.update("Processing %s %s ..." % (font.info.familyName, font.info.styleName)) result = self.function(font) if result is None: result = "Unknown" results.append( { "Font": "%s %s" % (font.info.familyName, font.info.styleName), "Result": result, } ) else: results.append( { "Font": "%s %s" % (font.info.familyName, font.info.styleName), "Result": self.w.font_list.get()[i]["Result"], } ) progress.close() self.w.font_list.set(results) self.w.font_list.setSelection(fonts) self.w.cancel_button.setTitle("Close") self.w.cancel_button.enable(True) self.w.ok_button.enable(True) self.w.copy_button.enable(True)
def generate(self, saveDir): if not saveDir: return saveDir = saveDir[0] f = self.font.naked() glyphs = [g for g in f if not g.template] progress = ProgressWindow("Generating .png's", tickCount=len(glyphs), parentWindow=self.window) gridSize = int(getExtensionDefault(GRID_DEFAULTS_KEY, 50)) for g in glyphs: if g.unicode is not None: fileName = "%04X" %g.unicode else: fileName = glyphNameToFileName(g.name, f) path = os.path.join(saveDir, "%s.png" %fileName) image = g.getRepresentation("com.typemytype.pixelImageFactory", gridSize=gridSize) data = image.TIFFRepresentation() imageRep = NSBitmapImageRep.imageRepWithData_(data) pngData = imageRep.representationUsingType_properties_(NSPNGFileType, None) pngData.writeToFile_atomically_(path, False) progress.update() progress.close()
def generateGlyphSet(self, sender): incomingSpot = None if hasattr(sender, 'spot'): incomingSpot = sender.spot generateSheet = self.w.generateSheet generateSheet.close() glyphTab = generateSheet.tabs[1] axesGrid = self.axesGrid['horizontal'], self.axesGrid['vertical'] masters = self.masters targetFontNameIndex = glyphTab.targetFont.get() targetFontName = glyphTab.targetFont.getItems()[targetFontNameIndex] cmap = masters[0][1].getCharacterMapping() glyphList = splitText(glyphTab.glyphSet.get(), cmap) spot = self.parseSpot(glyphTab.spot.get(), axesGrid) if spot is not None and len(spot): spot = spot[0] suffix = glyphTab.suffix.get() if spot is not None: progress = ProgressWindow('Generating glyphs', parentWindow=self.w) i, j = spot instanceLocation = Location(horizontal=i, vertical=j) masterLocations = [(matrixMaster.getLocation(), matrixMaster.getFont()) for matrixMaster in masters] if targetFontName == 'New font': targetFont = RFont(showUI=False) else: targetFont = AllFonts().getFontsByFamilyNameStyleName(*targetFontName.split(' > ')) self.interpolateGlyphSet(instanceLocation, glyphList, masterLocations, targetFont, suffix) targetFont.showUI() progress.close() if incomingSpot is not None: ch, j = incomingSpot pickedCell = getattr(self.w.matrix, '%s%s'%(ch, j)) pickedCell.selectionMask.show(False)
def _export_sbix(self, otfpath, palette=0, image_format="png", replace_outlines=False, parent_window=None): if not have_flat: print( "ColorFont._export_sbix: The 'flat' Python module is missing.") print( "Please see <https://github.com/jenskutilek/RoboChrome/blob/master/README.md>" ) return if replace_outlines: alt_glyphname_string = "%s" else: alt_glyphname_string = "%s.mac" font = TTFont(otfpath) if (font.has_key("sbix")): print(" WARNING: Replacing existing sbix table in %s" % otfpath) replace_outlines = True # insert special nodes into glyphs self._format_outlines_special(font, replace_outlines) # build sbix table sbix = table__s_b_i_x("sbix") if parent_window is not None: progress = ProgressWindow("Rendering bitmaps ...", tickCount=len(self.bitmap_sizes) * len(self.keys()), parentWindow=parent_window) for current_ppem in sorted(self.bitmap_sizes): current_set = Strike(ppem=current_ppem) for glyphname in self.keys(): if parent_window is not None: progress.update("Rendering /%s @ %i px ..." % (glyphname, current_ppem)) alt_glyphname = alt_glyphname_string % glyphname if image_format == "png": image_data = self[glyphname].get_png(palette, current_ppem) elif image_format == "pdf": image_data = self[glyphname].get_pdf(palette, current_ppem) else: # TODO: handle tiff, jpg, (dupe, mask) # fallback image_data = self[glyphname].get_png(palette, current_ppem) if image_data is not None: current_set.glyphs[alt_glyphname] = sbixGlyph( glyphName=glyphname, graphicType=image_format, imageData=image_data, ) sbix.strikes[current_ppem] = current_set if parent_window is not None: progress.close() font["sbix"] = sbix font.save(otfpath[:-4] + "_sbix" + otfpath[-4:]) font.close()
def send(self, sender): recipients = ', '.join(self.window.recipients.get()) progress = ProgressWindow('', tickCount=3, parentWindow=self.window) try: tmpdir = tempfile.mkdtemp(prefix="ghostlines") progress.update('Generating OTF') # Should be controlled which options are used somewhere filename = os.path.join(tmpdir, self.font.info.familyName + '.otf') self.font.generate(filename, "otf", decompose=True, checkOutlines=True, autohint=True) progress.update('Sending via Ghostlines') with open(filename, 'rb') as otf: params = dict( otf=otf, recipients=recipients, notes=self.window.notes_field.get(), designer_email_address=self.window.email_address_field.get() ) license_path = self.license_storage.retrieve() if license_path is not '' and os.path.exists(license_path): with open(license_path, 'rb') as license: filename = os.path.basename(license_path) _, extension = os.path.splitext(license_path) content_type = filetypes[extension] params['license'] = (filename, license, content_type) response = Ghostlines('v0.1').send(**params) else: response = Ghostlines('v0.1').send(**params) if response.status_code == requests.codes.created: message("{} was delivered".format(self.font.info.familyName)) else: print repr(response) message("{} could not be delivered".format(self.font.info.familyName), "Error code: {}\n{}".format(response.status_code, response.json())) finally: progress.close()
def okCallback(self, sender): self.w.close() progress = ProgressWindow("Downloading DrawBot %s" % self.currentVersion) downloadCurrentVersion() progress.close()
def generateCompatibilityReport(self, reportInfo): markGlyphs = reportInfo['markGlyphs'] compatibleColor = reportInfo['compatibleColor'] incompatibleColor = reportInfo['incompatibleColor'] mixedCompatibilityColor = reportInfo['mixedColor'] title = 'Generating report' if markGlyphs: title += ' & marking glyphs' progress = ProgressWindow(title, parentWindow=self.w) masterFonts = [font for _, font in self.masters] glyphList, strayGlyphs = self.compareGlyphSets(masterFonts) digest = [] interpolationReports = [] incompatibleGlyphs = 0 for glyphName in glyphList: refMasterFont = masterFonts[0] refMasterGlyph = refMasterFont[glyphName] for masterFont in masterFonts[1:]: firstGlyph = refMasterFont[glyphName] secondGlyph = masterFont[glyphName] try: compatible, report = firstGlyph.isCompatible(secondGlyph) except: report = u'Compatibility check error' compatible == False if compatible == False: names = '%s <X> %s'%(fontName(refMasterFont), fontName(masterFont)) reportID = (names, report) if reportID not in interpolationReports: digest.append(names) digest += [u'– %s'%(reportLine) for reportLine in report] digest.append('\n') interpolationReports.append(reportID) incompatibleGlyphs += 1 if markGlyphs: if refMasterFont[glyphName].mark == compatibleColor: refMasterFont[glyphName].mark = mixedCompatibilityColor elif refMasterFont[glyphName].mark != compatibleColor and refMasterFont[glyphName].mark != mixedCompatibilityColor: refMasterFont[glyphName].mark = incompatibleColor masterFont[glyphName].mark = incompatibleColor elif compatible == True: if markGlyphs: if refMasterFont[glyphName].mark == incompatibleColor or refMasterFont[glyphName].mark == mixedCompatibilityColor: refMasterFont[glyphName].mark = mixedCompatibilityColor masterFont[glyphName].mark = mixedCompatibilityColor else: refMasterFont[glyphName].mark = compatibleColor masterFont[glyphName].mark = compatibleColor progress.close() print u'\n* Compatible glyphs: %s'%(len(glyphList) - incompatibleGlyphs) print u'** Incompatible glyphs: %s'%(incompatibleGlyphs) print u'*** Stray glyphs: %s\n– %s\n'%(len(strayGlyphs),u'\n– '.join(list(strayGlyphs))) print '\n'.join(digest)
def generateInstanceFont(self, spot, generationInfos): if generationInfos['sourceFont']: start = time() report = [] doGlyphs = bool(generationInfos['interpolateGlyphs']) doKerning = bool(generationInfos['interpolateKerning']) doFontInfos = bool(generationInfos['interpolateFontInfos']) addGroups = bool(generationInfos['addGroups']) doReport = bool(generationInfos['report']) UI = bool(generationInfos['openFonts']) try: masters = self.masters baseFont = generationInfos['sourceFont'][0] newFont = None folderPath = None s = re.search('(.*)/(.*)(.ufo)', baseFont.path) if s is not None: folderPath = s.group(1) masterFonts = [font for _, font in masters] i, j = spot ch = getKeyForValue(i) instanceLocation = Location(horizontal=i, vertical=j) instanceName = '%s%s'%(ch.upper(), j+1) masterLocations = [(matrixMaster.getLocation(), matrixMaster.getFont()) for matrixMaster in masters] progress = ProgressWindow('Generating instance %s%s'%(ch.upper(), j+1), parentWindow=self.w) report.append(u'\n*** Generating instance %s ***\n'%(instanceName)) # Build fontx if (doGlyphs == True) or (doKerning == True) or (doFontInfos == True) or (addGroups == True): if hasattr(RFont, 'showUI') or (not hasattr(RFont, 'showUI') and (folderPath is not None)): newFont = RFont(showUI=False) elif not hasattr(RFont, 'showUI') and (folderPath is None): newFont = RFont() newFont.info.familyName = baseFont.info.familyName newFont.info.styleName = '%s%s'%(ch.upper(), j+1) try: newFont.glyphOrder = baseFont.glyphOrder except: try: newFont.glyphOrder = baseFont.lib['public.glyphOrder'] except: try: newFont.lib['public.glyphOrder'] = baseFont.lib['public.glyphOrder'] except: try: newFont.lib['public.glyphOrder'] = baseFont.glyphOrder except: pass if folderPath is not None: instancesFolder = u'%s%s'%(folderPath, '/matrix-instances') if not os.path.isdir(instancesFolder): os.makedirs(instancesFolder) folderPath = instancesFolder path = '%s/%s-%s%s'%(folderPath, newFont.info.familyName, newFont.info.styleName, '.ufo') interpolatedGlyphs = [] interpolatedInfo = None interpolatedKerning = None interpolationReports = [] report.append(u'+ Created new font') # interpolate font infos if doFontInfos == True: infoMasters = [(infoLocation, MathInfo(masterFont.info)) for infoLocation, masterFont in masterLocations] try: bias, iM = buildMutator(infoMasters) instanceInfo = iM.makeInstance(instanceLocation) instanceInfo.extractInfo(newFont.info) report.append(u'+ Successfully interpolated font info') except: report.append(u'+ Couldn’t interpolate font info') # interpolate kerning if doKerning == True: kerningMasters = [(kerningLocation, MathKerning(masterFont.kerning)) for kerningLocation, masterFont in masterLocations] try: bias, kM = buildMutator(kerningMasters) instanceKerning = kM.makeInstance(instanceLocation) instanceKerning.extractKerning(newFont) report.append(u'+ Successfully interpolated kerning') if addGroups == True: for key, value in baseFont.groups.items(): newFont.groups[key] = value report.append(u'+ Successfully transferred groups') except: report.append(u'+ Couldn’t interpolate kerning') # filter compatible glyphs glyphList, strayGlyphs = self.compareGlyphSets(masterFonts) incompatibleGlyphs = [] if doGlyphs == True: for glyphName in glyphList: masterGlyphs = [(masterLocation, MathGlyph(masterFont[glyphName])) for masterLocation, masterFont in masterLocations] try: bias, gM = buildMutator(masterGlyphs) newGlyph = RGlyph() instanceGlyph = gM.makeInstance(instanceLocation) newFont.insertGlyph(instanceGlyph.extractGlyph(newGlyph), glyphName) except: incompatibleGlyphs.append(glyphName) continue report.append(u'+ Successfully interpolated %s glyphs'%(len(newFont))) report.append(u'+ Couldn’t interpolate %s glyphs'%(len(incompatibleGlyphs))) if (newFont is not None) and hasattr(RFont, 'showUI') and (folderPath is None) and UI: newFont.autoUnicodes() newFont.round() newFont.showUI() elif (newFont is not None) and (folderPath is not None): newFont.autoUnicodes() newFont.round() newFont.save(path) report.append(u'\n—> Saved font to UFO at %s\n'%(path)) if UI: f = RFont(path) elif (newFont is not None): print u'Couldn’t save font to UFO.' except: print u'Couldn’t finish generating, something happened…' return finally: progress.close() if doReport: print '\n'.join(report)
def _drawReport(self, referenceFont, someFonts, glyphNames, reportPath, caption): assert isinstance(reportPath, str) or isinstance( reportPath, unicode), 'this should be a string or unicode' assert isinstance(someFonts, list), 'this should be a list of RFont' prog = ProgressWindow(text='{}: drawing glyphs...'.format(caption), tickCount=len(glyphNames)) try: db.newDrawing() twoLinesFontStyles = [ ff.info.styleName.replace(' ', '\n') for ff in someFonts ] quota = self._initPage(twoLinesFontStyles) for indexName, eachGlyphName in enumerate(glyphNames): db.save() db.translate(PDF_MARGIN, quota) # set name for eachSetName, eachGroup in SMART_SETS: if eachGlyphName in eachGroup: setName = eachSetName[3:].replace('.txt', '').replace( '_', ' ') break else: setName = '' db.text(setName, (COLS['set name'], 0)) # line number db.fill(*BLACK) db.text('{:0>4d}'.format(indexName), (COLS['line'], 0)) # unicode hex if eachGlyphName in referenceFont and referenceFont[ eachGlyphName].unicode: uniIntValue = referenceFont[eachGlyphName].unicode elif eachGlyphName in someFonts[0] and someFonts[0][ eachGlyphName].unicode: uniIntValue = someFonts[0][eachGlyphName].unicode else: uniIntValue = None if uniIntValue: uniHexValue = 'U+{:04X}'.format(uniIntValue) db.fill(*BLACK) db.text(uniHexValue, (COLS['unicode'], 0)) # os char if uniIntValue: txt = db.FormattedString() txt.fontSize(BODY_SIZE_GLYPH) txt.fill(*GRAY) txt += 'H' txt.fill(*BLACK) txt += unichr(uniIntValue) txt.fill(*GRAY) txt += 'p' db.text(txt, (COLS['char'], 0)) # glyphname db.fontSize(BODY_SIZE_TEXT) db.text(eachGlyphName, (COLS['glyph name'], 0)) # glyphs db.translate(COLS['template'], 0) for eachFont in [referenceFont] + someFonts: if eachGlyphName in eachFont: eachGlyph = eachFont[eachGlyphName] lftRefGL = eachFont['H'] rgtRefGL = eachFont['p'] db.save() db.scale(BODY_SIZE_GLYPH / eachFont.info.unitsPerEm) db.fill(*GRAY) db.drawGlyph(lftRefGL) db.translate(lftRefGL.width, 0) db.fill(*BLACK) db.drawGlyph(eachGlyph) db.translate(eachGlyph.width, 0) db.fill(*GRAY) db.drawGlyph(rgtRefGL) db.restore() db.translate(TAB_WIDTH, 0) db.restore() prog.update() quota -= TAB_LINE_HEIGHT if quota <= PDF_MARGIN: quota = self._initPage(twoLinesFontStyles) prog.setTickCount(value=None) prog.update(text='{}: saving PDF...'.format(caption)) db.saveImage(reportPath) db.endDrawing() except Exception as error: prog.close() raise error prog.close()
def startProgress(self, text="", tickCount=None): from defconAppKit.windows.progressWindow import ProgressWindow return ProgressWindow(text, tickCount, self.w)
def generateInstanceFont(self, spot, generationInfos): # self.w.spotSheet.close() # delattr(self.w, 'spotSheet') if generationInfos['sourceFont']: baseFont = generationInfos['sourceFont'][0] doKerning = generationInfos['interpolateKerning'] doFontInfos = generationInfos['interpolateFontInfos'] doReport = generationInfos['printReport'] progress = ProgressWindow('Generating instance', parentWindow=self.w) fonts = [font for _, font in self.masters] i, j = spot ch = getKeyForValue(i) instanceLocation = Location(horizontal=i, vertical=j) masterLocations = [(Location(horizontal=getValueForKey(_ch), vertical=_j), masterFont) for (_ch, _j), masterFont in self.masters] # Build font newFont = RFont(showUI=False) newFont.info.familyName = baseFont.info.familyName newFont.info.styleName = '%s%s'%(ch.upper(), j+1) interpolatedGlyphs = [] interpolatedInfo = None interpolatedKerning = None interpolationReports = [] # interpolate font infos if doFontInfos: infoMasters = [(location, MathInfo(font.info)) for location, font in masterLocations] try: bias, iM = buildMutator(infoMasters) instanceInfo = iM.makeInstance(instanceLocation) instanceInfo.extractInfo(newFont.info) except: pass # interpolate kerning if doKerning: kerningMasters = [(location, MathKerning(font.kerning)) for location, font in masterLocations] try: bias, kM = buildMutator(kerningMasters) instanceKerning = kM.makeInstance(instanceLocation) instanceKerning.extractKerning(newFont) for key, value in baseFont.groups.items(): newFont.groups[key] = value except: pass # filter compatible glyphs fontKeys = [set(font.keys()) for font in fonts] glyphList = set() for i, item in enumerate(fontKeys): if i == 0: glyphList = item elif i > 0: glyphList = glyphList & item compatibleBaseGlyphList = [] compatibleCompositeGlyphList = [] for glyphName in glyphList: glyphs = [font[glyphName] for font in fonts] compatible = True for glyph in glyphs[1:]: comp, report = glyphs[0].isCompatible(glyph) if comp == False: name = '%s <X> %s'%(fontName(glyphs[0].getParent()), fontName(glyph.getParent())) reportLine = (name, report) if reportLine not in interpolationReports: interpolationReports.append(reportLine) compatible = False if compatible: compatibleBaseGlyphList.append(glyphName) # initiate glyph interpolation for glyphName in compatibleBaseGlyphList: glyphMasters = [(location, MathGlyph(font[glyphName])) for location, font in masterLocations] try: bias, gM = buildMutator(glyphMasters) newGlyph = RGlyph() instanceGlyph = gM.makeInstance(instanceLocation) interpolatedGlyphs.append((glyphName, instanceGlyph.extractGlyph(newGlyph))) except: continue for name, iGlyph in interpolatedGlyphs: newFont.insertGlyph(iGlyph, name) progress.close() digest = [] if doReport: for fontNames, report in interpolationReports: digest.append(fontNames) digest += [u'– %s'%(reportLine) for reportLine in report] digest.append('\n') print '\n'.join(digest) newFont.showUI()
def _export_svg(self, otfpath, palette=0, parent_window=None): font = TTFont(otfpath) if font.has_key("SVG "): print(" WARNING: Replacing existing SVG table in %s" % otfpath) # font.getReverseGlyphMap(rebuild=1) svg = table_S_V_G_("SVG ") svg.version = 0 svg.docList = [] svg.colorPalettes = None if parent_window is not None: progress = ProgressWindow("Rendering SVG ...", tickCount=len(self.keys()), parentWindow=parent_window) _palette = self.palettes[palette] _svg_palette = [] _docList = [] reindex = {0xffff: 0xffff} count = 0 for i in sorted(_palette.keys(), key=lambda k: int(k)): red = int(_palette[i][1:3], 16) green = int(_palette[i][3:5], 16) blue = int(_palette[i][5:7], 16) if len(_palette[i]) >= 9: alpha = int(_palette[i][7:9], 16) else: alpha = 0xff reindex[int(i)] = count count += 1 _svg_palette.append((red, green, blue, alpha)) # print("Palette:", len(_svg_palette), _svg_palette) _pen = SVGpen(self.rfont, optimize_output=True) for glyphname in self.keys(): # ["A", "P"]: #self.keys(): # look up glyph id try: gid = font.getGlyphID(glyphname) except: assert 0, "SVG table contains a glyph name not in font.getGlyphNames(): " + str(glyphname) # update progress bar if parent_window is not None: progress.update("Rendering SVG for /%s ..." % glyphname) # build svg glyph _svg_transfrom_group = """<g transform="scale(1 -1)">%s</g>""" contents = u"" for i in range(len(self[glyphname].layers)): _color_index = reindex[self[glyphname].colors[i]] # print(" Layer %i, color %i" % (i, _color_index)) rglyph = self.rfont[self[glyphname].layers[i]] if _color_index == 0xffff: r, g, b, a = (0, 0, 0, 0xff) else: r, g, b, a = _svg_palette[_color_index] _pen.reset() rglyph.draw(_pen) if _pen.d: contents += u'<g fill="#%02x%02x%02x"><path d="%s"/></g>' % (r, g, b, _pen.d) if contents: contents = _svg_transfrom_group % contents _svg_doc = u"""<svg enable-background="new 0 0 64 64" id="glyph%i" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">%s</svg>""" % (gid, contents) _docList.append((_svg_doc, gid, gid)) svg.docList = sorted(_docList, key=itemgetter(1)) if parent_window is not None: progress.close() # save font["SVG "] = svg font.save(otfpath[:-4] + "_svg" + otfpath[-4:]) font.close()
def generateInstanceFont(self, spot, generationInfos): # self.w.spotSheet.close() # delattr(self.w, 'spotSheet') if generationInfos['sourceFont']: try: masters = self.masters baseFont = generationInfos['sourceFont'][0] folderPath = None s = re.search('(.*)/(.*)(.ufo)', baseFont.path) if s is not None: folderPath = s.group(1) doKerning = generationInfos['interpolateKerning'] doFontInfos = generationInfos['interpolateFontInfos'] doReport = generationInfos['printReport'] noUI = True progress = ProgressWindow('Generating instance', parentWindow=self.w) masterFonts = [font for _, font in masters] i, j = spot ch = getKeyForValue(i) instanceLocation = Location(horizontal=i, vertical=j) masterLocations = [(Location(horizontal=getValueForKey(_ch), vertical=_j), masterFont) for (_ch, _j), masterFont in masters] # Build font if hasattr(RFont, 'showUI') or (not hasattr(RFont, 'showUI') and (folderPath is not None)): newFont = RFont(showUI=False) elif not hasattr(RFont, 'showUI') and (folderPath is None): newFont = RFont() newFont.info.familyName = baseFont.info.familyName newFont.info.styleName = '%s%s'%(ch.upper(), j+1) try: newFont.glyphOrder = baseFont.glyphOrder except: try: newFont.glyphOrder = baseFont.lib['public.glyphOrder'] except: try: newFont.lib['public.glyphOrder'] = baseFont.lib['public.glyphOrder'] except: try: newFont.lib['public.glyphOrder'] = baseFont.glyphOrder except: pass if folderPath is not None: path = '%s/%s-%s%s'%(folderPath, newFont.info.familyName, newFont.info.styleName, '.ufo') interpolatedGlyphs = [] interpolatedInfo = None interpolatedKerning = None interpolationReports = [] # interpolate font infos if doFontInfos: infoMasters = [(infoLocation, MathInfo(masterFont.info)) for infoLocation, masterFont in masterLocations] try: bias, iM = buildMutator(infoMasters) instanceInfo = iM.makeInstance(instanceLocation) instanceInfo.extractInfo(newFont.info) except: pass # interpolate kerning if doKerning: kerningMasters = [(kerningLocation, MathKerning(masterFont.kerning)) for kerningLocation, masterFont in masterLocations] try: bias, kM = buildMutator(kerningMasters) instanceKerning = kM.makeInstance(instanceLocation) instanceKerning.extractKerning(newFont) for key, value in baseFont.groups.items(): newFont.groups[key] = value except: pass # filter compatible glyphs fontKeys = [set(masterFont.keys()) for masterFont in masterFonts] glyphList = set() for i, item in enumerate(fontKeys): if i == 0: glyphList = item elif i > 0: glyphList = glyphList & item incompatibleGlyphs = [] for glyphName in glyphList: glyphs = [(MathGlyph(masterFont[glyphName]), masterFont, masterLocation) for masterLocation, masterFont in masterLocations] allCompatible = True refMasterGlyph = glyphs[0][0] refMasterFont = glyphs[0][1] refMasterLocation = glyphs[0][2] masterGlyphs = [(refMasterLocation, refMasterGlyph)] for masterGlyph, _masterFont, _masterLocation in glyphs[1:]: compatible = refMasterGlyph.isCompatible(masterGlyph) if compatible == False: incompatibleGlyphs.append((glyphName, refMasterFont, _masterFont)) allCompatible = False elif compatible == True: masterGlyphs.append((_masterLocation, masterGlyph)) if allCompatible: try: bias, gM = buildMutator(masterGlyphs) newGlyph = RGlyph() instanceGlyph = gM.makeInstance(instanceLocation) interpolatedGlyphs.append((glyphName, instanceGlyph.extractGlyph(newGlyph))) except: continue for name, interpolatedGlyph in interpolatedGlyphs: newFont.insertGlyph(interpolatedGlyph, name) progress.close() interpolationReports = [] digest = [] if doReport: for glyphName, firstFont, secondFont in incompatibleGlyphs: firstGlyph = firstFont[glyphName] secondGlyph = secondFont[glyphName] comp, report = firstGlyph.isCompatible(secondGlyph) names = '%s <X> %s'%(fontName(firstFont), fontName(secondFont)) reportID = (name, report) if reportID not in interpolationReports: digest.append(names) digest += [u'– %s'%(reportLine) for reportLine in report] digest.append('\n') interpolationReports.append(reportID) print '\n'.join(digest) if hasattr(RFont, 'showUI') and (folderPath is None): newFont.showUI() elif (folderPath is not None): newFont.save(path) f = RFont(path) except: try: progress.close() except: print u'Couldn’t finish generating, something happened…' return
def _export_svg(self, otfpath, palette=0, parent_window=None): font = TTFont(otfpath) if font.has_key("SVG "): print(" WARNING: Replacing existing SVG table in %s" % otfpath) # font.getReverseGlyphMap(rebuild=1) svg = table_S_V_G_("SVG ") svg.version = 0 svg.docList = [] svg.colorPalettes = None if parent_window is not None: progress = ProgressWindow("Rendering SVG ...", tickCount=len(self.keys()), parentWindow=parent_window) _palette = self.palettes[palette] _svg_palette = [] _docList = [] reindex = {0xffff: 0xffff} count = 0 for i in sorted(_palette.keys(), key=lambda k: int(k)): red = int(_palette[i][1:3], 16) green = int(_palette[i][3:5], 16) blue = int(_palette[i][5:7], 16) if len(_palette[i]) >= 9: alpha = int(_palette[i][7:9], 16) else: alpha = 0xff reindex[int(i)] = count count += 1 _svg_palette.append((red, green, blue, alpha)) # print("Palette:", len(_svg_palette), _svg_palette) _pen = SVGpen(self.rfont, optimize_output=True) for glyphname in self.keys(): # ["A", "P"]: #self.keys(): # look up glyph id try: gid = font.getGlyphID(glyphname) except: assert 0, "SVG table contains a glyph name not in font.getGlyphNames(): " + str( glyphname) # update progress bar if parent_window is not None: progress.update("Rendering SVG for /%s ..." % glyphname) # build svg glyph _svg_transfrom_group = """<g transform="scale(1 -1)">%s</g>""" contents = u"" for i in range(len(self[glyphname].layers)): _color_index = reindex[self[glyphname].colors[i]] # print(" Layer %i, color %i" % (i, _color_index)) rglyph = self.rfont[self[glyphname].layers[i]] if _color_index == 0xffff: r, g, b, a = (0, 0, 0, 0xff) else: r, g, b, a = _svg_palette[_color_index] _pen.reset() rglyph.draw(_pen) if _pen.d: contents += u'<g fill="#%02x%02x%02x"><path d="%s"/></g>' % ( r, g, b, _pen.d) if contents: contents = _svg_transfrom_group % contents _svg_doc = u"""<svg enable-background="new 0 0 64 64" id="glyph%i" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">%s</svg>""" % ( gid, contents) _docList.append((_svg_doc, gid, gid)) svg.docList = sorted(_docList, key=itemgetter(1)) if parent_window is not None: progress.close() # save font["SVG "] = svg font.save(otfpath[:-4] + "_svg" + otfpath[-4:]) font.close()