for constency with the rest of fontTools tests. Also, in setup.cfg we tell pytest to only search for modules named like these
348 lines
9.9 KiB
Python
348 lines
9.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from __future__ import absolute_import, unicode_literals
|
|
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)
|
|
|
|
def getFontPath(self, fileName):
|
|
testdata = os.path.join(os.path.dirname(__file__), "testdata")
|
|
return os.path.join(testdata, fileName)
|
|
|
|
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
|
|
# ---------------------
|
|
|
|
class TestInfoObject(object): 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
|
|
}
|
|
|
|
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"]
|
|
}
|
|
|
|
def setUp(self):
|
|
self.tempDir = tempfile.mktemp()
|
|
os.mkdir(self.tempDir)
|
|
self.ufoPath = os.path.join(self.tempDir, "test.ufo")
|
|
|
|
def tearDown(self):
|
|
shutil.rmtree(self.tempDir)
|
|
|
|
def makeUFO(self, formatVersion):
|
|
self.clearUFO()
|
|
if not os.path.exists(self.ufoPath):
|
|
os.mkdir(self.ufoPath)
|
|
# 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
|
|
}
|
|
}
|
|
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"]
|
|
}
|
|
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)
|
|
|
|
def clearUFO(self):
|
|
if os.path.exists(self.ufoPath):
|
|
shutil.rmtree(self.ufoPath)
|
|
|
|
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)
|
|
|
|
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
|
|
}
|
|
|
|
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"]
|
|
}
|
|
|
|
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
|
|
}
|
|
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
|
|
}
|
|
}
|
|
|
|
|
|
downConversionMapping = {
|
|
"side1" : {
|
|
"BGroup" : "public.kern1.BGroup",
|
|
"CGroup" : "public.kern1.CGroup"
|
|
},
|
|
"side2" : {
|
|
"CGroup" : "public.kern2.CGroup",
|
|
"DGroup" : "public.kern2.DGroup"
|
|
}
|
|
}
|
|
|
|
def setUp(self):
|
|
self.tempDir = tempfile.mktemp()
|
|
os.mkdir(self.tempDir)
|
|
self.dstDir = os.path.join(self.tempDir, "test.ufo")
|
|
|
|
def tearDown(self):
|
|
shutil.rmtree(self.tempDir)
|
|
|
|
def tearDownUFO(self):
|
|
shutil.rmtree(self.dstDir)
|
|
|
|
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()
|