from __future__ import absolute_import, unicode_literals import os import tempfile import shutil import unittest from io import open from .testSupport import getDemoFontGlyphSetPath from fontTools.ufoLib.glifLib import ( GlyphSet, glyphNameToFileName, readGlyphFromString, writeGlyphToString, ) from fontTools.misc.etree import XML_DECLARATION GLYPHSETDIR = getDemoFontGlyphSetPath() class GlyphSetTests(unittest.TestCase): def setUp(self): self.dstDir = tempfile.mktemp() os.mkdir(self.dstDir) def tearDown(self): shutil.rmtree(self.dstDir) def testRoundTrip(self): import difflib srcDir = GLYPHSETDIR dstDir = self.dstDir src = GlyphSet(srcDir, ufoFormatVersion=2, validateRead=True, validateWrite=True) dst = GlyphSet(dstDir, ufoFormatVersion=2, validateRead=True, validateWrite=True) 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 sorted(src.keys()): fileName = src.contents[glyphName] with open(os.path.join(srcDir, fileName), "r") as f: org = f.read() with open(os.path.join(dstDir, fileName), "r") as f: new = f.read() added = [] removed = [] for line in difflib.unified_diff( org.split("\n"), new.split("\n")): if line.startswith("+ "): added.append(line[1:]) elif line.startswith("- "): removed.append(line[1:]) self.assertEqual( added, removed, "%s.glif file differs after round tripping" % glyphName) def testRebuildContents(self): gset = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True) contents = gset.contents gset.rebuildContents() self.assertEqual(contents, gset.contents) def testReverseContents(self): gset = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True) 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 testReverseContents2(self): src = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True) dst = GlyphSet(self.dstDir, validateRead=True, validateWrite=True) 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 testCustomFileNamingScheme(self): def myGlyphNameToFileName(glyphName, glyphSet): return "prefix" + glyphNameToFileName(glyphName, glyphSet) src = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True) dst = GlyphSet(self.dstDir, myGlyphNameToFileName, validateRead=True, validateWrite=True) 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(): d[k] = "prefix" + v self.assertEqual(d, dst.contents) def testGetUnicodes(self): src = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True) 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]) class FileNameTests(unittest.TestCase): def testDefaultFileNameScheme(self): self.assertEqual(glyphNameToFileName("a", None), "a.glif") self.assertEqual(glyphNameToFileName("A", None), "A_.glif") self.assertEqual(glyphNameToFileName("Aring", None), "A_ring.glif") self.assertEqual(glyphNameToFileName("F_A_B", None), "F__A__B_.glif") self.assertEqual(glyphNameToFileName("A.alt", None), "A_.alt.glif") self.assertEqual(glyphNameToFileName("A.Alt", None), "A_.A_lt.glif") self.assertEqual(glyphNameToFileName(".notdef", None), "_notdef.glif") self.assertEqual(glyphNameToFileName("T_H", None), "T__H_.glif") self.assertEqual(glyphNameToFileName("T_h", None), "T__h.glif") self.assertEqual(glyphNameToFileName("t_h", None), "t_h.glif") self.assertEqual(glyphNameToFileName("F_F_I", None), "F__F__I_.glif") self.assertEqual(glyphNameToFileName("f_f_i", None), "f_f_i.glif") self.assertEqual(glyphNameToFileName("AE", None), "A_E_.glif") self.assertEqual(glyphNameToFileName("Ae", None), "A_e.glif") self.assertEqual(glyphNameToFileName("ae", None), "ae.glif") self.assertEqual(glyphNameToFileName("aE", None), "aE_.glif") self.assertEqual(glyphNameToFileName("a.alt", None), "a.alt.glif") self.assertEqual(glyphNameToFileName("A.aLt", None), "A_.aL_t.glif") self.assertEqual(glyphNameToFileName("A.alT", None), "A_.alT_.glif") self.assertEqual(glyphNameToFileName("Aacute_V.swash", None), "A_acute_V_.swash.glif") self.assertEqual(glyphNameToFileName(".notdef", None), "_notdef.glif") self.assertEqual(glyphNameToFileName("con", None), "_con.glif") self.assertEqual(glyphNameToFileName("CON", None), "C_O_N_.glif") self.assertEqual(glyphNameToFileName("con.alt", None), "_con.alt.glif") self.assertEqual(glyphNameToFileName("alt.con", None), "alt._con.glif") class _Glyph(object): pass class ReadWriteFuncTest(unittest.TestCase): def testRoundTrip(self): glyph = _Glyph() glyph.name = "a" glyph.unicodes = [0x0061] s1 = writeGlyphToString(glyph.name, glyph) glyph2 = _Glyph() readGlyphFromString(s1, glyph2) self.assertEqual(glyph.__dict__, glyph2.__dict__) s2 = writeGlyphToString(glyph2.name, glyph2) self.assertEqual(s1, s2) def testXmlDeclaration(self): s = writeGlyphToString("a", _Glyph()) self.assertTrue(s.startswith(XML_DECLARATION % "UTF-8"))