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 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 _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 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 okCallback(self, sender): self.w.close() progress = ProgressWindow("Downloading DrawBot %s" % self.currentVersion) downloadCurrentVersion() progress.close()
def startProgress(self, text="", tickCount=None): from defconAppKit.windows.progressWindow import ProgressWindow return ProgressWindow(text, tickCount, self.w)
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']: 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 _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()