def importAllGlifFiles(font, dirName=None, doProgress=True, bar=None): """import all GLIFs into a FontLab font""" if dirName is None: if font.file_name: dir, base = os.path.split(font.file_name) base = base.split(".")[0] + ".glyphs" dirName = os.path.join(dir, base) else: dirName = GetFolder("Please select a folder with .glif files") glyphSet = GlyphSet(dirName) glyphNames = glyphSet.keys() glyphNames.sort() barStart = 0 closeBar = False if doProgress: if not bar: bar = ProgressBar("Importing Glyphs", len(glyphNames)) closeBar = True else: barStart = bar.getCurrentTick() else: bar = None try: for i in range(len(glyphNames)): #if not (i % 10) and not bar.tick(barStart + i): # raise KeyboardInterrupt glyphName = glyphNames[i] flGlyph = NewGlyph(font, glyphName, clear=True) pen = FLPointPen(flGlyph) glyph = GlyphPlaceholder() glyphSet.readGlyph(glyphName, glyph, pen) if hasattr(glyph, "width"): flGlyph.width = int(round(glyph.width)) if hasattr(glyph, "unicodes"): flGlyph.unicodes = glyph.unicodes if hasattr(glyph, "note"): flGlyph.note = glyph.note # XXX must encode if hasattr(glyph, "lib"): from cStringIO import StringIO from robofab.plistlib import writePlist lib = glyph.lib if lib: if len(lib) == 1 and "org.robofab.fontlab.customdata" in lib: data = lib["org.robofab.fontlab.customdata"].data else: f = StringIO() writePlist(glyph.lib, f) data = f.getvalue() flGlyph.customdata = data # XXX the next bit is only correct when font is the current font :-( fl.UpdateGlyph(font.FindGlyph(glyphName)) if bar and not i % 10: bar.tick(barStart + i) except KeyboardInterrupt: if bar: bar.close() bar = None fl.UpdateFont(FontIndex(font)) if bar and closeBar: bar.close()
def exportGlyphs(font, glyphs=None, dest=None, doProgress=True, bar=None): """Export all glyphs in a FontLab font""" if dest is None: dir, base = os.path.split(font.file_name) base = base.split(".")[0] + ".glyphs" dest = os.path.join(dir, base) if not os.path.exists(dest): os.makedirs(dest) glyphSet = GlyphSet(dest) if glyphs is None: indices = range(len(font)) else: indices = [] for glyphName in glyphs: indices.append(font.FindGlyph(glyphName)) barStart = 0 closeBar = False if doProgress: if not bar: bar = ProgressBar("Exporting Glyphs", len(indices)) closeBar = True else: barStart = bar.getCurrentTick() else: bar = None try: done = {} for i in range(len(indices)): #if not (i % 10) and not bar.tick(i + barStart): # raise KeyboardInterrupt index = indices[i] flGlyph = font[index] if flGlyph is None: continue glyphName = flGlyph.name if not glyphName: print "can't dump glyph #%s, it has no glyph name" % i else: if glyphName in done: n = 1 while ("%s#%s" % (glyphName, n)) in done: n += 1 glyphName = "%s#%s" % (glyphName, n) done[glyphName] = None exportGlyph(glyphName, flGlyph, glyphSet) if bar and not i % 10: bar.tick(barStart + i) # Write out contents.plist glyphSet.writeContents() except KeyboardInterrupt: if bar: bar.close() bar = None if bar and closeBar: bar.close()
def testReverseContents(self): gset = GlyphSet(GLYPHSETDIR) d = {} for k, v in gset.getReverseContents().items(): d[v] = k org = {} for k, v in gset.contents.items(): org[k] = v.lower() self.assertEqual(d, org)
def testGetUnicodes(self): src = GlyphSet(GLYPHSETDIR) unicodes = src.getUnicodes() for glyphName in src.keys(): g = src[glyphName] g.drawPoints(None) # load attrs if not hasattr(g, "unicodes"): self.assertEqual(unicodes[glyphName], []) else: self.assertEqual(g.unicodes, unicodes[glyphName])
def testGuessSmoothPen(self): glyphSet = GlyphSet(getDemoFontGlyphSetPath()) for name in glyphSet.keys(): digestPen = DigestPointPen() glyphSet[name].drawPoints(digestPen) digest1 = digestPen.getDigest() digestPen = DigestPointPen() pen = GuessSmoothPointPen(digestPen) glyphSet[name].drawPoints(pen) digest2 = digestPen.getDigest() self.assertEqual(digest1, digest2)
def testCustomFileNamingScheme(self): def myGlyphNameToFileName(glyphName, glyphSet): return "prefix" + glyphNameToFileName(glyphName, glyphSet) src = GlyphSet(GLYPHSETDIR) dst = GlyphSet(self.dstDir, myGlyphNameToFileName) for glyphName in src.keys(): g = src[glyphName] g.drawPoints(None) # load attrs dst.writeGlyph(glyphName, g, g.drawPoints) d = {} for k, v in src.contents.items(): print k, v d[k] = "prefix" + v self.assertEqual(d, dst.contents)
def getGlyphSet(self): """ Return the GlyphSet associated with the glyphs directory in the .ufo. """ glyphsPath = os.path.join(self._path, GLYPHS_DIRNAME) return GlyphSet(glyphsPath)
def getCharacterMapping(self): """ Return a dictionary that maps unicode values (ints) to lists of glyph names. """ glyphsPath = os.path.join(self._path, GLYPHS_DIRNAME) glyphSet = GlyphSet(glyphsPath) allUnicodes = glyphSet.getUnicodes() cmap = {} for glyphName, unicodes in allUnicodes.iteritems(): for code in unicodes: if code in cmap: cmap[code].append(glyphName) else: cmap[code] = [glyphName] return cmap
def testReverseContents2(self): src = GlyphSet(GLYPHSETDIR) dst = GlyphSet(self.dstDir) dstMap = dst.getReverseContents() self.assertEqual(dstMap, {}) for glyphName in src.keys(): g = src[glyphName] g.drawPoints(None) # load attrs dst.writeGlyph(glyphName, g, g.drawPoints) self.assertNotEqual(dstMap, {}) srcMap = dict(src.getReverseContents()) # copy self.assertEqual(dstMap, srcMap) del srcMap["a.glif"] dst.deleteGlyph("a") self.assertEqual(dstMap, srcMap)
def testReversContourFromGlyphSet(self): glyphSet = GlyphSet(getDemoFontGlyphSetPath()) digestPen = DigestPointPen() glyphSet["testglyph1"].drawPoints(digestPen) digest1 = digestPen.getDigest() digestPen = DigestPointPen() pen = ReverseContourPointPen(digestPen) glyphSet["testglyph1.reversed"].drawPoints(pen) digest2 = digestPen.getDigest() self.assertEqual(digest1, digest2)
def testRoundTrip(self): srcDir = GLYPHSETDIR dstDir = self.dstDir src = GlyphSet(srcDir) dst = GlyphSet(dstDir) for glyphName in src.keys(): g = src[glyphName] g.drawPoints(None) # load attrs dst.writeGlyph(glyphName, g, g.drawPoints) # compare raw file data: for glyphName in src.keys(): fileName = src.contents[glyphName] org = file(os.path.join(srcDir, fileName), READ_MODE).read() new = file(os.path.join(dstDir, fileName), READ_MODE).read() self.assertEqual( org, new, "%r .glif file differs after round tripping" % glyphName)
def testRoundTrip(self): srcDir = GLYPHSETDIR dstDir = self.dstDir src = GlyphSet(srcDir) dst = GlyphSet(dstDir) for glyphName in src.keys(): g = src[glyphName] g.drawPoints(None) # load attrs dst.writeGlyph(glyphName, g, g.drawPoints) # compare raw file data: for glyphName in src.keys(): fileName = src.contents[glyphName] org = file(os.path.join(srcDir, fileName), READ_MODE).read() new = file(os.path.join(dstDir, fileName), READ_MODE).read() self.assertEqual(org, new, "%r .glif file differs after round tripping" % glyphName)
def testShapesFromGlyphSet(self): glyphSet = GlyphSet(getDemoFontGlyphSetPath()) for name in glyphSet.keys(): self._doTest(glyphSet[name].drawPoints, name)
"""Read all glyphs from the demo font, and write them out again. This is useful for testing round-tripping stability, but also to update the font when the GLIF format changes. The third application is to update the contents.plist file in case glyphs have been added or removed. """ import os from robofab.test.testSupport import getDemoFontPath from robofab.glifLib import GlyphSet from robofab.pens.adapterPens import GuessSmoothPointPen ufoPath = getDemoFontPath() glyphSet = GlyphSet(os.path.join(ufoPath, "glyphs")) glyphSet.rebuildContents( ) # ignore existing contents.plist, rebuild from dir listing for name in glyphSet.keys(): g = glyphSet[name] g.drawPoints(None) # force all attrs to be loaded def drawPoints(pen): pen = GuessSmoothPointPen(pen) g.drawPoints(pen) glyphSet.writeGlyph(name, g, drawPoints) glyphSet.writeContents() # write out contents.plist
def importAllGlifFiles(font, dirName=None, doProgress=True, bar=None): """import all GLIFs into a FontLab font""" if dirName is None: if font.file_name: dir, base = os.path.split(font.file_name) base = base.split(".")[0] + ".glyphs" dirName = os.path.join(dir, base) else: dirName = GetFolder("Please select a folder with .glif files") glyphSet = GlyphSet(dirName) glyphNames = glyphSet.keys() glyphNames.sort() barStart = 0 closeBar = False if doProgress: if not bar: bar = ProgressBar("Importing Glyphs", len(glyphNames)) closeBar = True else: barStart = bar.getCurrentTick() else: bar = None try: for i in range(len(glyphNames)): #if not (i % 10) and not bar.tick(barStart + i): # raise KeyboardInterrupt glyphName = glyphNames[i] flGlyph = NewGlyph(font, glyphName, clear=True) pen = FLPointPen(flGlyph) glyph = GlyphPlaceholder() glyphSet.readGlyph(glyphName, glyph, pen) if hasattr(glyph, "width"): flGlyph.width = int(round(glyph.width)) if hasattr(glyph, "unicodes"): flGlyph.unicodes = glyph.unicodes if hasattr(glyph, "note"): flGlyph.note = glyph.note # XXX must encode if hasattr(glyph, "lib"): from cStringIO import StringIO from robofab.plistlib import writePlist lib = glyph.lib if lib: if len(lib ) == 1 and "org.robofab.fontlab.customdata" in lib: data = lib["org.robofab.fontlab.customdata"].data else: f = StringIO() writePlist(glyph.lib, f) data = f.getvalue() flGlyph.customdata = data # XXX the next bit is only correct when font is the current font :-( fl.UpdateGlyph(font.FindGlyph(glyphName)) if bar and not i % 10: bar.tick(barStart + i) except KeyboardInterrupt: if bar: bar.close() bar = None fl.UpdateFont(FontIndex(font)) if bar and closeBar: bar.close()
def testRebuildContents(self): gset = GlyphSet(GLYPHSETDIR) contents = gset.contents gset.rebuildContents() self.assertEqual(contents, gset.contents)
print "selection", todo if g is not None: todo.append(g.name) for f in AllFonts(): ufoPath = None print "f.path", f, f.path if f.path is None: # huh, in case there is a ghost font. print "skipping", f continue ufoPath = f.path.replace(".vfb", ".ufo") if not os.path.exists(ufoPath): ufoPath = GetFolder("Select a UFO to save the GLIF in:") if ufoPath.find(".ufo") == -1: Message("You need to select an UFO. Quitting.") ufoPath = None if ufoPath is None: continue for c in todo: if c not in f: print "font is missing", c continue g = f[c] path = os.path.join(os.path.dirname(ufoPath), os.path.basename(ufoPath), "glyphs") print "saving glyph %s in %s"%(g.name, path) gs = GlyphSet(path, glyphNameToFileNameFunc=glyphNameToShortFileName) gs.writeGlyph(g.name, g, g.drawPoints) gs.writeContents() print 'done'
def getGlyphSet(self, glyphNameToFileNameFunc=None): """ Return the GlyphSet associated with the glyphs directory in the .ufo. """ return GlyphSet(self.makeGlyphPath(), glyphNameToFileNameFunc)
"""Read all glyphs from the demo font, and write them out again. This is useful for testing round-tripping stability, but also to update the font when the GLIF format changes. The third application is to update the contents.plist file in case glyphs have been added or removed. """ import os from robofab.test.testSupport import getDemoFontPath from robofab.glifLib import GlyphSet from robofab.pens.adapterPens import GuessSmoothPointPen ufoPath = getDemoFontPath() glyphSet = GlyphSet(os.path.join(ufoPath, "glyphs")) glyphSet.rebuildContents() # ignore existing contents.plist, rebuild from dir listing for name in glyphSet.keys(): g = glyphSet[name] g.drawPoints(None) # force all attrs to be loaded def drawPoints(pen): pen = GuessSmoothPointPen(pen) g.drawPoints(pen) glyphSet.writeGlyph(name, g, drawPoints) glyphSet.writeContents() # write out contents.plist