fonttools/Tests/ufoLib/UFOConversion_test.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

325 lines
12 KiB
Python
Raw Permalink Normal View History

import os
import shutil
import unittest
import tempfile
from io import open
from fontTools.ufoLib import UFOReader, UFOWriter
from fontTools.ufoLib import plistlib
from .testSupport import expectedFontInfo1To2Conversion, expectedFontInfo2To1Conversion
# the format version 1 lib.plist contains some data
# that these tests shouldn't be concerned about.
removeFromFormatVersion1Lib = [
"org.robofab.opentype.classes",
"org.robofab.opentype.features",
"org.robofab.opentype.featureorder",
"org.robofab.postScriptHintData",
]
class ConversionFunctionsTestCase(unittest.TestCase):
def tearDown(self):
path = self.getFontPath("TestFont1 (UFO1) converted.ufo")
if os.path.exists(path):
shutil.rmtree(path)
path = self.getFontPath("TestFont1 (UFO2) converted.ufo")
if os.path.exists(path):
shutil.rmtree(path)
2022-12-13 11:26:36 +00:00
def getFontPath(self, fileName):
testdata = os.path.join(os.path.dirname(__file__), "testdata")
return os.path.join(testdata, fileName)
2022-12-13 11:26:36 +00:00
def compareFileStructures(self, path1, path2, expectedInfoData, testFeatures):
# result
metainfoPath1 = os.path.join(path1, "metainfo.plist")
fontinfoPath1 = os.path.join(path1, "fontinfo.plist")
kerningPath1 = os.path.join(path1, "kerning.plist")
groupsPath1 = os.path.join(path1, "groups.plist")
libPath1 = os.path.join(path1, "lib.plist")
featuresPath1 = os.path.join(path1, "features.plist")
glyphsPath1 = os.path.join(path1, "glyphs")
glyphsPath1_contents = os.path.join(glyphsPath1, "contents.plist")
glyphsPath1_A = os.path.join(glyphsPath1, "A_.glif")
glyphsPath1_B = os.path.join(glyphsPath1, "B_.glif")
# expected result
metainfoPath2 = os.path.join(path2, "metainfo.plist")
fontinfoPath2 = os.path.join(path2, "fontinfo.plist")
kerningPath2 = os.path.join(path2, "kerning.plist")
groupsPath2 = os.path.join(path2, "groups.plist")
libPath2 = os.path.join(path2, "lib.plist")
featuresPath2 = os.path.join(path2, "features.plist")
glyphsPath2 = os.path.join(path2, "glyphs")
glyphsPath2_contents = os.path.join(glyphsPath2, "contents.plist")
glyphsPath2_A = os.path.join(glyphsPath2, "A_.glif")
glyphsPath2_B = os.path.join(glyphsPath2, "B_.glif")
# look for existence
self.assertEqual(os.path.exists(metainfoPath1), True)
self.assertEqual(os.path.exists(fontinfoPath1), True)
self.assertEqual(os.path.exists(kerningPath1), True)
self.assertEqual(os.path.exists(groupsPath1), True)
self.assertEqual(os.path.exists(libPath1), True)
self.assertEqual(os.path.exists(glyphsPath1), True)
self.assertEqual(os.path.exists(glyphsPath1_contents), True)
self.assertEqual(os.path.exists(glyphsPath1_A), True)
self.assertEqual(os.path.exists(glyphsPath1_B), True)
if testFeatures:
self.assertEqual(os.path.exists(featuresPath1), True)
# look for aggrement
with open(metainfoPath1, "rb") as f:
data1 = plistlib.load(f)
with open(metainfoPath2, "rb") as f:
data2 = plistlib.load(f)
self.assertEqual(data1, data2)
with open(fontinfoPath1, "rb") as f:
data1 = plistlib.load(f)
self.assertEqual(sorted(data1.items()), sorted(expectedInfoData.items()))
with open(kerningPath1, "rb") as f:
data1 = plistlib.load(f)
with open(kerningPath2, "rb") as f:
data2 = plistlib.load(f)
self.assertEqual(data1, data2)
with open(groupsPath1, "rb") as f:
data1 = plistlib.load(f)
with open(groupsPath2, "rb") as f:
data2 = plistlib.load(f)
self.assertEqual(data1, data2)
with open(libPath1, "rb") as f:
data1 = plistlib.load(f)
with open(libPath2, "rb") as f:
data2 = plistlib.load(f)
if "UFO1" in libPath1:
for key in removeFromFormatVersion1Lib:
if key in data1:
del data1[key]
if "UFO1" in libPath2:
for key in removeFromFormatVersion1Lib:
if key in data2:
del data2[key]
self.assertEqual(data1, data2)
with open(glyphsPath1_contents, "rb") as f:
data1 = plistlib.load(f)
with open(glyphsPath2_contents, "rb") as f:
data2 = plistlib.load(f)
self.assertEqual(data1, data2)
with open(glyphsPath1_A, "rb") as f:
data1 = plistlib.load(f)
with open(glyphsPath2_A, "rb") as f:
data2 = plistlib.load(f)
self.assertEqual(data1, data2)
with open(glyphsPath1_B, "rb") as f:
data1 = plistlib.load(f)
with open(glyphsPath2_B, "rb") as f:
data2 = plistlib.load(f)
self.assertEqual(data1, data2)
# ---------------------
# kerning up conversion
# ---------------------
2022-12-13 11:26:36 +00:00
class TestInfoObject:
pass
class KerningUpConversionTestCase(unittest.TestCase):
expectedKerning = {
("public.kern1.BGroup", "public.kern2.CGroup"): 7,
("public.kern1.BGroup", "public.kern2.DGroup"): 8,
("public.kern1.BGroup", "A"): 5,
("public.kern1.BGroup", "B"): 6,
("public.kern1.CGroup", "public.kern2.CGroup"): 11,
("public.kern1.CGroup", "public.kern2.DGroup"): 12,
("public.kern1.CGroup", "A"): 9,
("public.kern1.CGroup", "B"): 10,
("A", "public.kern2.CGroup"): 3,
("A", "public.kern2.DGroup"): 4,
("A", "A"): 1,
("A", "B"): 2,
("X", "A"): 13,
("X", "public.kern2.CGroup"): 14,
}
2022-12-13 11:26:36 +00:00
expectedGroups = {
"BGroup": ["B"],
"CGroup": ["C", "Ccedilla"],
"DGroup": ["D"],
"public.kern1.BGroup": ["B"],
"public.kern1.CGroup": ["C", "Ccedilla"],
"public.kern2.CGroup": ["C", "Ccedilla"],
"public.kern2.DGroup": ["D"],
"Not A Kerning Group": ["A"],
"X": ["X", "X.sc"],
}
2022-12-13 11:26:36 +00:00
def setUp(self):
self.tempDir = tempfile.mktemp()
os.mkdir(self.tempDir)
self.ufoPath = os.path.join(self.tempDir, "test.ufo")
2022-12-13 11:26:36 +00:00
def tearDown(self):
shutil.rmtree(self.tempDir)
2022-12-13 11:26:36 +00:00
def makeUFO(self, formatVersion):
self.clearUFO()
if not os.path.exists(self.ufoPath):
os.mkdir(self.ufoPath)
2022-12-13 11:26:36 +00:00
# glyphs
glyphsPath = os.path.join(self.ufoPath, "glyphs")
if not os.path.exists(glyphsPath):
os.mkdir(glyphsPath)
glyphFile = "X_.glif"
glyphsContents = dict(X=glyphFile)
path = os.path.join(glyphsPath, "contents.plist")
with open(path, "wb") as f:
plistlib.dump(glyphsContents, f)
path = os.path.join(glyphsPath, glyphFile)
with open(path, "w") as f:
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
2022-12-13 11:26:36 +00:00
# metainfo.plist
metaInfo = dict(creator="test", formatVersion=formatVersion)
path = os.path.join(self.ufoPath, "metainfo.plist")
with open(path, "wb") as f:
plistlib.dump(metaInfo, f)
# kerning
kerning = {
"A": {"A": 1, "B": 2, "CGroup": 3, "DGroup": 4},
"BGroup": {"A": 5, "B": 6, "CGroup": 7, "DGroup": 8},
"CGroup": {"A": 9, "B": 10, "CGroup": 11, "DGroup": 12},
"X": {"A": 13, "CGroup": 14},
}
path = os.path.join(self.ufoPath, "kerning.plist")
with open(path, "wb") as f:
plistlib.dump(kerning, f)
# groups
groups = {
"BGroup": ["B"],
"CGroup": ["C", "Ccedilla"],
"DGroup": ["D"],
"Not A Kerning Group": ["A"],
"X": ["X", "X.sc"], # a group with a name that is also a glyph name
}
path = os.path.join(self.ufoPath, "groups.plist")
with open(path, "wb") as f:
plistlib.dump(groups, f)
# font info
fontInfo = {"familyName": "Test"}
path = os.path.join(self.ufoPath, "fontinfo.plist")
with open(path, "wb") as f:
plistlib.dump(fontInfo, f)
2022-12-13 11:26:36 +00:00
def clearUFO(self):
if os.path.exists(self.ufoPath):
shutil.rmtree(self.ufoPath)
2022-12-13 11:26:36 +00:00
def testUFO1(self):
self.makeUFO(formatVersion=2)
reader = UFOReader(self.ufoPath, validate=True)
kerning = reader.readKerning()
self.assertEqual(self.expectedKerning, kerning)
groups = reader.readGroups()
self.assertEqual(self.expectedGroups, groups)
info = TestInfoObject()
reader.readInfo(info)
2022-12-13 11:26:36 +00:00
def testUFO2(self):
self.makeUFO(formatVersion=2)
reader = UFOReader(self.ufoPath, validate=True)
kerning = reader.readKerning()
self.assertEqual(self.expectedKerning, kerning)
groups = reader.readGroups()
self.assertEqual(self.expectedGroups, groups)
info = TestInfoObject()
reader.readInfo(info)
class KerningDownConversionTestCase(unittest.TestCase):
expectedKerning = {
("public.kern1.BGroup", "public.kern2.CGroup"): 7,
("public.kern1.BGroup", "public.kern2.DGroup"): 8,
("public.kern1.BGroup", "A"): 5,
("public.kern1.BGroup", "B"): 6,
("public.kern1.CGroup", "public.kern2.CGroup"): 11,
("public.kern1.CGroup", "public.kern2.DGroup"): 12,
("public.kern1.CGroup", "A"): 9,
("public.kern1.CGroup", "B"): 10,
("A", "public.kern2.CGroup"): 3,
("A", "public.kern2.DGroup"): 4,
("A", "A"): 1,
("A", "B"): 2,
}
2022-12-13 11:26:36 +00:00
groups = {
"BGroup": ["B"],
"CGroup": ["C"],
"DGroup": ["D"],
"public.kern1.BGroup": ["B"],
"public.kern1.CGroup": ["C", "Ccedilla"],
"public.kern2.CGroup": ["C", "Ccedilla"],
"public.kern2.DGroup": ["D"],
"Not A Kerning Group": ["A"],
}
expectedWrittenGroups = {
"BGroup": ["B"],
"CGroup": ["C", "Ccedilla"],
"DGroup": ["D"],
"Not A Kerning Group": ["A"],
}
2022-12-13 11:26:36 +00:00
kerning = {
("public.kern1.BGroup", "public.kern2.CGroup"): 7,
("public.kern1.BGroup", "public.kern2.DGroup"): 8,
("public.kern1.BGroup", "A"): 5,
("public.kern1.BGroup", "B"): 6,
("public.kern1.CGroup", "public.kern2.CGroup"): 11,
("public.kern1.CGroup", "public.kern2.DGroup"): 12,
("public.kern1.CGroup", "A"): 9,
("public.kern1.CGroup", "B"): 10,
("A", "public.kern2.CGroup"): 3,
("A", "public.kern2.DGroup"): 4,
("A", "A"): 1,
("A", "B"): 2,
2022-12-13 11:26:36 +00:00
}
expectedWrittenKerning = {
"BGroup": {"CGroup": 7, "DGroup": 8, "A": 5, "B": 6},
"CGroup": {"CGroup": 11, "DGroup": 12, "A": 9, "B": 10},
"A": {"CGroup": 3, "DGroup": 4, "A": 1, "B": 2},
}
2022-12-13 11:26:36 +00:00
downConversionMapping = {
"side1": {"BGroup": "public.kern1.BGroup", "CGroup": "public.kern1.CGroup"},
"side2": {"CGroup": "public.kern2.CGroup", "DGroup": "public.kern2.DGroup"},
}
2022-12-13 11:26:36 +00:00
def setUp(self):
self.tempDir = tempfile.mktemp()
os.mkdir(self.tempDir)
self.dstDir = os.path.join(self.tempDir, "test.ufo")
2022-12-13 11:26:36 +00:00
def tearDown(self):
shutil.rmtree(self.tempDir)
2022-12-13 11:26:36 +00:00
def tearDownUFO(self):
shutil.rmtree(self.dstDir)
2022-12-13 11:26:36 +00:00
def testWrite(self):
writer = UFOWriter(self.dstDir, formatVersion=2)
writer.setKerningGroupConversionRenameMaps(self.downConversionMapping)
writer.writeKerning(self.kerning)
writer.writeGroups(self.groups)
# test groups
path = os.path.join(self.dstDir, "groups.plist")
with open(path, "rb") as f:
writtenGroups = plistlib.load(f)
self.assertEqual(writtenGroups, self.expectedWrittenGroups)
# test kerning
path = os.path.join(self.dstDir, "kerning.plist")
with open(path, "rb") as f:
writtenKerning = plistlib.load(f)
self.assertEqual(writtenKerning, self.expectedWrittenKerning)
self.tearDownUFO()