Merge pull request #2588 from fonttools/hb-repack-mock-test
mock hb.repack error to test pure-python serializer gets used on failure
This commit is contained in:
commit
cc6b12582c
@ -1,4 +1,5 @@
|
||||
import io
|
||||
import fontTools.ttLib.tables.otBase
|
||||
from fontTools.misc.testTools import getXML, stripVariableItemsFromTTX
|
||||
from fontTools.misc.textTools import tobytes, tostr
|
||||
from fontTools import subset
|
||||
@ -19,35 +20,32 @@ import pathlib
|
||||
import pytest
|
||||
|
||||
|
||||
class SubsetTest(unittest.TestCase):
|
||||
def __init__(self, methodName):
|
||||
unittest.TestCase.__init__(self, methodName)
|
||||
# Python 3 renamed assertRaisesRegexp to assertRaisesRegex,
|
||||
# and fires deprecation warnings if a program uses the old name.
|
||||
if not hasattr(self, "assertRaisesRegex"):
|
||||
self.assertRaisesRegex = self.assertRaisesRegexp
|
||||
class SubsetTest:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.tempdir = None
|
||||
cls.num_tempfiles = 0
|
||||
|
||||
def setUp(self):
|
||||
self.tempdir = None
|
||||
self.num_tempfiles = 0
|
||||
|
||||
def tearDown(self):
|
||||
if self.tempdir:
|
||||
shutil.rmtree(self.tempdir)
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
if cls.tempdir:
|
||||
shutil.rmtree(cls.tempdir)
|
||||
|
||||
@staticmethod
|
||||
def getpath(testfile):
|
||||
path, _ = os.path.split(__file__)
|
||||
return os.path.join(path, "data", testfile)
|
||||
|
||||
def temp_path(self, suffix):
|
||||
if not self.tempdir:
|
||||
self.tempdir = tempfile.mkdtemp()
|
||||
self.num_tempfiles += 1
|
||||
return os.path.join(self.tempdir,
|
||||
"tmp%d%s" % (self.num_tempfiles, suffix))
|
||||
@classmethod
|
||||
def temp_path(cls, suffix):
|
||||
if not cls.tempdir:
|
||||
cls.tempdir = tempfile.mkdtemp()
|
||||
cls.num_tempfiles += 1
|
||||
return os.path.join(cls.tempdir,
|
||||
"tmp%d%s" % (cls.num_tempfiles, suffix))
|
||||
|
||||
def read_ttx(self, path):
|
||||
@staticmethod
|
||||
def read_ttx(path):
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
ttx = f.read()
|
||||
# don't care whether TTF or OTF, thus strip sfntVersion as well
|
||||
@ -62,21 +60,21 @@ class SubsetTest(unittest.TestCase):
|
||||
for line in difflib.unified_diff(
|
||||
expected, actual, fromfile=expected_ttx, tofile=path):
|
||||
sys.stdout.write(line)
|
||||
self.fail("TTX output is different from expected")
|
||||
pytest.fail("TTX output is different from expected")
|
||||
|
||||
def compile_font(self, path, suffix):
|
||||
savepath = self.temp_path(suffix=suffix)
|
||||
font = TTFont(recalcBBoxes=False, recalcTimestamp=False)
|
||||
font.importXML(path)
|
||||
font.save(savepath, reorderTables=None)
|
||||
return font, savepath
|
||||
return savepath
|
||||
|
||||
# -----
|
||||
# Tests
|
||||
# -----
|
||||
|
||||
def test_layout_scripts(self):
|
||||
_, fontpath = self.compile_font(self.getpath("layout_scripts.ttx"), ".otf")
|
||||
fontpath = self.compile_font(self.getpath("layout_scripts.ttx"), ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--glyphs=*", "--layout-features=*",
|
||||
"--layout-scripts=latn,arab.URD,arab.dflt",
|
||||
@ -86,41 +84,41 @@ class SubsetTest(unittest.TestCase):
|
||||
["GPOS", "GSUB"])
|
||||
|
||||
def test_no_notdef_outline_otf(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf")
|
||||
fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--no-notdef-outline", "--gids=0", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_no_notdef_outline_otf.ttx"), ["CFF "])
|
||||
|
||||
def test_no_notdef_outline_cid(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestCID-Regular.ttx"), ".otf")
|
||||
fontpath = self.compile_font(self.getpath("TestCID-Regular.ttx"), ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--no-notdef-outline", "--gids=0", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_no_notdef_outline_cid.ttx"), ["CFF "])
|
||||
|
||||
def test_no_notdef_outline_ttf(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--no-notdef-outline", "--gids=0", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_no_notdef_outline_ttf.ttx"), ["glyf", "hmtx"])
|
||||
|
||||
def test_subset_ankr(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestANKR.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestANKR.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_ankr.ttx"), ["ankr"])
|
||||
|
||||
def test_subset_ankr_remove(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestANKR.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestANKR.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=two", "--output-file=%s" % subsetpath])
|
||||
self.assertNotIn("ankr", TTFont(subsetpath))
|
||||
assert "ankr" not in TTFont(subsetpath)
|
||||
|
||||
def test_subset_bsln_format_0(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestBSLN-0.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestBSLN-0.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -133,7 +131,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# a subsetted font with {zero, one} and the implicit .notdef, all
|
||||
# glyphs in the resulting font use the Roman baseline. In this case,
|
||||
# we expect a format 0 'bsln' table because it is the most compact.
|
||||
_, fontpath = self.compile_font(self.getpath("TestBSLN-1.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestBSLN-1.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030-0031",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -149,7 +147,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# subsetted font, we expect a format 1 'bsln' table whose default
|
||||
# is Roman, but with an override that uses the ideographic baseline
|
||||
# for uni2EA2.
|
||||
_, fontpath = self.compile_font(self.getpath("TestBSLN-1.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestBSLN-1.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030-0031,U+2EA2",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -160,7 +158,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# The 'bsln' table in TestBSLN-2 refers to control points in glyph 'P'
|
||||
# for defining its baselines. Therefore, the subsetted font should
|
||||
# include this glyph even though it is not requested explicitly.
|
||||
_, fontpath = self.compile_font(self.getpath("TestBSLN-2.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestBSLN-2.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -174,7 +172,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# baseline measurement, all glyphs in the resulting font use the Roman
|
||||
# baseline. In this case, we expect a format 2 'bsln' table because it
|
||||
# is the most compact encoding.
|
||||
_, fontpath = self.compile_font(self.getpath("TestBSLN-3.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestBSLN-3.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -190,7 +188,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# subsetted font, we expect a format 1 'bsln' table whose default
|
||||
# is Roman, but with an override that uses the ideographic baseline
|
||||
# for uni2EA2.
|
||||
_, fontpath = self.compile_font(self.getpath("TestBSLN-3.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestBSLN-3.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030-0031,U+2EA2",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -198,35 +196,35 @@ class SubsetTest(unittest.TestCase):
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_bsln_3.ttx"), ["bsln"])
|
||||
|
||||
def test_subset_clr(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestCLR-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestCLR-Regular.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=smileface", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_keep_colr.ttx"), ["GlyphOrder", "hmtx", "glyf", "COLR", "CPAL"])
|
||||
|
||||
def test_subset_gvar(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestGVAR.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestGVAR.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+002B,U+2212", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_keep_gvar.ttx"), ["GlyphOrder", "avar", "fvar", "gvar", "name"])
|
||||
|
||||
def test_subset_gvar_notdef_outline(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestGVAR.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestGVAR.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030", "--notdef_outline", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_keep_gvar_notdef_outline.ttx"), ["GlyphOrder", "avar", "fvar", "gvar", "name"])
|
||||
|
||||
def test_subset_lcar_remove(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestLCAR-0.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestLCAR-0.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.assertNotIn("lcar", subsetfont)
|
||||
assert "lcar" not in subsetfont
|
||||
|
||||
def test_subset_lcar_format_0(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestLCAR-0.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestLCAR-0.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+FB01",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -234,7 +232,7 @@ class SubsetTest(unittest.TestCase):
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_lcar_0.ttx"), ["lcar"])
|
||||
|
||||
def test_subset_lcar_format_1(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestLCAR-1.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestLCAR-1.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+FB01",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -242,14 +240,14 @@ class SubsetTest(unittest.TestCase):
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_lcar_1.ttx"), ["lcar"])
|
||||
|
||||
def test_subset_math(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestMATH-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestMATH-Regular.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0041,U+0028,U+0302,U+1D400,U+1D435", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_keep_math.ttx"), ["GlyphOrder", "CFF ", "MATH", "hmtx"])
|
||||
|
||||
def test_subset_math_partial(self):
|
||||
_, fontpath = self.compile_font(self.getpath("test_math_partial.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("test_math_partial.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--text=A", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -260,21 +258,21 @@ class SubsetTest(unittest.TestCase):
|
||||
# the Optical Bounds table. When subsetting, we do not request any
|
||||
# of those glyphs. Therefore, the produced subsetted font should
|
||||
# not contain an 'opbd' table.
|
||||
_, fontpath = self.compile_font(self.getpath("TestOPBD-0.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestOPBD-0.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.assertNotIn("opbd", subsetfont)
|
||||
assert "opbd" not in subsetfont
|
||||
|
||||
def test_subset_opbd_format_0(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestOPBD-0.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestOPBD-0.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=A", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_opbd_0.ttx"), ["opbd"])
|
||||
|
||||
def test_subset_opbd_format_1(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestOPBD-1.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestOPBD-1.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=A", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -283,12 +281,12 @@ class SubsetTest(unittest.TestCase):
|
||||
def test_subset_prop_remove_default_zero(self):
|
||||
# If all glyphs have an AAT glyph property with value 0,
|
||||
# the "prop" table should be removed from the subsetted font.
|
||||
_, fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0041",
|
||||
"--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.assertNotIn("prop", subsetfont)
|
||||
assert "prop" not in subsetfont
|
||||
|
||||
def test_subset_prop_0(self):
|
||||
# If all glyphs share the same AAT glyph properties, the "prop" table
|
||||
@ -297,7 +295,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# Unless the shared value is zero, in which case the subsetted font
|
||||
# should have no "prop" table at all. But that case has already been
|
||||
# tested above in test_subset_prop_remove_default_zero().
|
||||
_, fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030-0032", "--no-notdef-glyph",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -308,7 +306,7 @@ class SubsetTest(unittest.TestCase):
|
||||
# If not all glyphs share the same AAT glyph properties, the subsetted
|
||||
# font should contain a "prop" table in format 1. To save space, the
|
||||
# DefaultProperties should be set to the most frequent value.
|
||||
_, fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=U+0030-0032", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath])
|
||||
@ -318,32 +316,32 @@ class SubsetTest(unittest.TestCase):
|
||||
def test_options(self):
|
||||
# https://github.com/fonttools/fonttools/issues/413
|
||||
opt1 = subset.Options()
|
||||
self.assertTrue('Xyz-' not in opt1.layout_features)
|
||||
assert 'Xyz-' not in opt1.layout_features
|
||||
opt2 = subset.Options()
|
||||
opt2.layout_features.append('Xyz-')
|
||||
self.assertTrue('Xyz-' in opt2.layout_features)
|
||||
self.assertTrue('Xyz-' not in opt1.layout_features)
|
||||
assert 'Xyz-' in opt2.layout_features
|
||||
assert 'Xyz-' not in opt1.layout_features
|
||||
|
||||
def test_google_color(self):
|
||||
_, fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--gids=0,1", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.assertTrue("CBDT" in subsetfont)
|
||||
self.assertTrue("CBLC" in subsetfont)
|
||||
self.assertTrue("x" in subsetfont['CBDT'].strikeData[0])
|
||||
self.assertFalse("y" in subsetfont['CBDT'].strikeData[0])
|
||||
assert "CBDT" in subsetfont
|
||||
assert "CBLC" in subsetfont
|
||||
assert "x" in subsetfont['CBDT'].strikeData[0]
|
||||
assert "y" not in subsetfont['CBDT'].strikeData[0]
|
||||
|
||||
def test_google_color_all(self):
|
||||
_, fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=*", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.assertTrue("x" in subsetfont['CBDT'].strikeData[0])
|
||||
self.assertTrue("y" in subsetfont['CBDT'].strikeData[0])
|
||||
assert "x" in subsetfont['CBDT'].strikeData[0]
|
||||
assert "y" in subsetfont['CBDT'].strikeData[0]
|
||||
|
||||
def test_sbix(self):
|
||||
_, fontpath = self.compile_font(self.getpath("sbix.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("sbix.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--gids=0,1", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -351,7 +349,7 @@ class SubsetTest(unittest.TestCase):
|
||||
"expect_sbix.ttx"), ["sbix"])
|
||||
|
||||
def test_timing_publishes_parts(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
|
||||
options = subset.Options()
|
||||
options.timing = True
|
||||
@ -362,15 +360,15 @@ class SubsetTest(unittest.TestCase):
|
||||
subsetter.subset(font)
|
||||
logs = captor.records
|
||||
|
||||
self.assertTrue(len(logs) > 5)
|
||||
self.assertEqual(len(logs), len([l for l in logs if 'msg' in l.args and 'time' in l.args]))
|
||||
assert len(logs) > 5
|
||||
assert len(logs) == len([l for l in logs if 'msg' in l.args and 'time' in l.args])
|
||||
# Look for a few things we know should happen
|
||||
self.assertTrue(filter(lambda l: l.args['msg'] == "load 'cmap'", logs))
|
||||
self.assertTrue(filter(lambda l: l.args['msg'] == "subset 'cmap'", logs))
|
||||
self.assertTrue(filter(lambda l: l.args['msg'] == "subset 'glyf'", logs))
|
||||
assert filter(lambda l: l.args['msg'] == "load 'cmap'", logs)
|
||||
assert filter(lambda l: l.args['msg'] == "subset 'cmap'", logs)
|
||||
assert filter(lambda l: l.args['msg'] == "subset 'glyf'", logs)
|
||||
|
||||
def test_passthrough_tables(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
font = TTFont(fontpath)
|
||||
unknown_tag = 'ZZZZ'
|
||||
unknown_table = newTable(unknown_tag)
|
||||
@ -383,17 +381,17 @@ class SubsetTest(unittest.TestCase):
|
||||
subsetfont = TTFont(subsetpath)
|
||||
|
||||
# tables we can't subset are dropped by default
|
||||
self.assertFalse(unknown_tag in subsetfont)
|
||||
assert unknown_tag not in subsetfont
|
||||
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--passthrough-tables", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
|
||||
# unknown tables are kept if --passthrough-tables option is passed
|
||||
self.assertTrue(unknown_tag in subsetfont)
|
||||
assert unknown_tag in subsetfont
|
||||
|
||||
def test_non_BMP_text_arg_input(self):
|
||||
_, fontpath = self.compile_font(
|
||||
fontpath = self.compile_font(
|
||||
self.getpath("TestTTF-Regular_non_BMP_char.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
text = tostr(u"A\U0001F6D2", encoding='utf-8')
|
||||
@ -401,11 +399,11 @@ class SubsetTest(unittest.TestCase):
|
||||
subset.main([fontpath, "--text=%s" % text, "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
|
||||
self.assertEqual(subsetfont['maxp'].numGlyphs, 3)
|
||||
self.assertEqual(subsetfont.getGlyphOrder(), ['.notdef', 'A', 'u1F6D2'])
|
||||
assert subsetfont['maxp'].numGlyphs == 3
|
||||
assert subsetfont.getGlyphOrder() == ['.notdef', 'A', 'u1F6D2']
|
||||
|
||||
def test_non_BMP_text_file_input(self):
|
||||
_, fontpath = self.compile_font(
|
||||
fontpath = self.compile_font(
|
||||
self.getpath("TestTTF-Regular_non_BMP_char.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
text = tobytes(u"A\U0001F6D2", encoding='utf-8')
|
||||
@ -419,12 +417,12 @@ class SubsetTest(unittest.TestCase):
|
||||
finally:
|
||||
os.remove(tmp.name)
|
||||
|
||||
self.assertEqual(subsetfont['maxp'].numGlyphs, 3)
|
||||
self.assertEqual(subsetfont.getGlyphOrder(), ['.notdef', 'A', 'u1F6D2'])
|
||||
assert subsetfont['maxp'].numGlyphs == 3
|
||||
assert subsetfont.getGlyphOrder() == ['.notdef', 'A', 'u1F6D2']
|
||||
|
||||
def test_no_hinting_CFF(self):
|
||||
ttxpath = self.getpath("Lobster.subset.ttx")
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--no-hinting", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath, "*"])
|
||||
@ -434,7 +432,7 @@ class SubsetTest(unittest.TestCase):
|
||||
|
||||
def test_desubroutinize_CFF(self):
|
||||
ttxpath = self.getpath("Lobster.subset.ttx")
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--desubroutinize", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath, "*"])
|
||||
@ -444,7 +442,7 @@ class SubsetTest(unittest.TestCase):
|
||||
|
||||
def test_desubroutinize_hinted_subrs_CFF(self):
|
||||
ttxpath = self.getpath("test_hinted_subrs_CFF.ttx")
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--desubroutinize", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath, "*"])
|
||||
@ -454,7 +452,7 @@ class SubsetTest(unittest.TestCase):
|
||||
|
||||
def test_desubroutinize_cntrmask_CFF(self):
|
||||
ttxpath = self.getpath("test_cntrmask_CFF.ttx")
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--desubroutinize", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath, "*"])
|
||||
@ -464,7 +462,7 @@ class SubsetTest(unittest.TestCase):
|
||||
|
||||
def test_no_hinting_desubroutinize_CFF(self):
|
||||
ttxpath = self.getpath("test_hinted_subrs_CFF.ttx")
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--no-hinting", "--desubroutinize", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath, "*"])
|
||||
@ -473,7 +471,7 @@ class SubsetTest(unittest.TestCase):
|
||||
"expect_no_hinting_desubroutinize_CFF.ttx"), ["CFF "])
|
||||
|
||||
def test_no_hinting_TTF(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--no-hinting", "--notdef-outline",
|
||||
"--output-file=%s" % subsetpath, "*"])
|
||||
@ -481,11 +479,11 @@ class SubsetTest(unittest.TestCase):
|
||||
self.expect_ttx(subsetfont, self.getpath(
|
||||
"expect_no_hinting_TTF.ttx"), ["glyf", "maxp"])
|
||||
for tag in subset.Options().hinting_tables:
|
||||
self.assertTrue(tag not in subsetfont)
|
||||
assert tag not in subsetfont
|
||||
|
||||
def test_notdef_width_cid(self):
|
||||
# https://github.com/fonttools/fonttools/pull/845
|
||||
_, fontpath = self.compile_font(self.getpath("NotdefWidthCID-Regular.ttx"), ".otf")
|
||||
fontpath = self.compile_font(self.getpath("NotdefWidthCID-Regular.ttx"), ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--no-notdef-outline", "--gids=0,1", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -498,18 +496,18 @@ class SubsetTest(unittest.TestCase):
|
||||
head = font['head']
|
||||
bounds = [head.xMin, head.yMin, head.xMax, head.yMax]
|
||||
|
||||
_, fontpath = self.compile_font(ttxpath, ".ttf")
|
||||
fontpath = self.compile_font(ttxpath, ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
|
||||
# by default, the subsetter does not recalculate the bounding box
|
||||
subset.main([fontpath, "--output-file=%s" % subsetpath, "*"])
|
||||
head = TTFont(subsetpath)['head']
|
||||
self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax])
|
||||
assert bounds == [head.xMin, head.yMin, head.xMax, head.yMax]
|
||||
|
||||
subset.main([fontpath, "--recalc-bounds", "--output-file=%s" % subsetpath, "*"])
|
||||
head = TTFont(subsetpath)['head']
|
||||
bounds = [132, 304, 365, 567]
|
||||
self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax])
|
||||
assert bounds == [head.xMin, head.yMin, head.xMax, head.yMax]
|
||||
|
||||
def test_recalc_bounds_otf(self):
|
||||
ttxpath = self.getpath("TestOTF-Regular.ttx")
|
||||
@ -518,76 +516,76 @@ class SubsetTest(unittest.TestCase):
|
||||
head = font['head']
|
||||
bounds = [head.xMin, head.yMin, head.xMax, head.yMax]
|
||||
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
|
||||
# by default, the subsetter does not recalculate the bounding box
|
||||
subset.main([fontpath, "--output-file=%s" % subsetpath, "*"])
|
||||
head = TTFont(subsetpath)['head']
|
||||
self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax])
|
||||
assert bounds == [head.xMin, head.yMin, head.xMax, head.yMax]
|
||||
|
||||
subset.main([fontpath, "--recalc-bounds", "--output-file=%s" % subsetpath, "*"])
|
||||
head = TTFont(subsetpath)['head']
|
||||
bounds = [132, 304, 365, 567]
|
||||
self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax])
|
||||
assert bounds == [head.xMin, head.yMin, head.xMax, head.yMax]
|
||||
|
||||
def test_recalc_timestamp_ttf(self):
|
||||
ttxpath = self.getpath("TestTTF-Regular.ttx")
|
||||
font = TTFont()
|
||||
font.importXML(ttxpath)
|
||||
modified = font['head'].modified
|
||||
_, fontpath = self.compile_font(ttxpath, ".ttf")
|
||||
fontpath = self.compile_font(ttxpath, ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
|
||||
# by default, the subsetter does not recalculate the modified timestamp
|
||||
subset.main([fontpath, "--output-file=%s" % subsetpath, "*"])
|
||||
self.assertEqual(modified, TTFont(subsetpath)['head'].modified)
|
||||
assert modified == TTFont(subsetpath)['head'].modified
|
||||
|
||||
subset.main([fontpath, "--recalc-timestamp", "--output-file=%s" % subsetpath, "*"])
|
||||
self.assertLess(modified, TTFont(subsetpath)['head'].modified)
|
||||
assert modified < TTFont(subsetpath)['head'].modified
|
||||
|
||||
def test_recalc_timestamp_otf(self):
|
||||
ttxpath = self.getpath("TestOTF-Regular.ttx")
|
||||
font = TTFont()
|
||||
font.importXML(ttxpath)
|
||||
modified = font['head'].modified
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
|
||||
# by default, the subsetter does not recalculate the modified timestamp
|
||||
subset.main([fontpath, "--output-file=%s" % subsetpath, "*"])
|
||||
self.assertEqual(modified, TTFont(subsetpath)['head'].modified)
|
||||
assert modified == TTFont(subsetpath)['head'].modified
|
||||
|
||||
subset.main([fontpath, "--recalc-timestamp", "--output-file=%s" % subsetpath, "*"])
|
||||
self.assertLess(modified, TTFont(subsetpath)['head'].modified)
|
||||
assert modified < TTFont(subsetpath)['head'].modified
|
||||
|
||||
def test_recalc_max_context(self):
|
||||
ttxpath = self.getpath("Lobster.subset.ttx")
|
||||
font = TTFont()
|
||||
font.importXML(ttxpath)
|
||||
max_context = font['OS/2'].usMaxContext
|
||||
_, fontpath = self.compile_font(ttxpath, ".otf")
|
||||
fontpath = self.compile_font(ttxpath, ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
|
||||
# by default, the subsetter does not recalculate the usMaxContext
|
||||
subset.main([fontpath, "--drop-tables+=GSUB,GPOS",
|
||||
"--output-file=%s" % subsetpath])
|
||||
self.assertEqual(max_context, TTFont(subsetpath)['OS/2'].usMaxContext)
|
||||
assert max_context == TTFont(subsetpath)['OS/2'].usMaxContext
|
||||
|
||||
subset.main([fontpath, "--recalc-max-context",
|
||||
"--drop-tables+=GSUB,GPOS",
|
||||
"--output-file=%s" % subsetpath])
|
||||
self.assertEqual(0, TTFont(subsetpath)['OS/2'].usMaxContext)
|
||||
assert 0 == TTFont(subsetpath)['OS/2'].usMaxContext
|
||||
|
||||
def test_retain_gids_ttf(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
font = TTFont(fontpath)
|
||||
|
||||
self.assertEqual(font["hmtx"]["A"], (500, 132))
|
||||
self.assertEqual(font["hmtx"]["B"], (400, 132))
|
||||
assert font["hmtx"]["A"] == (500, 132)
|
||||
assert font["hmtx"]["B"] == (400, 132)
|
||||
|
||||
self.assertGreater(font["glyf"]["A"].numberOfContours, 0)
|
||||
self.assertGreater(font["glyf"]["B"].numberOfContours, 0)
|
||||
assert font["glyf"]["A"].numberOfContours > 0
|
||||
assert font["glyf"]["B"].numberOfContours > 0
|
||||
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main(
|
||||
@ -601,29 +599,29 @@ class SubsetTest(unittest.TestCase):
|
||||
)
|
||||
subsetfont = TTFont(subsetpath)
|
||||
|
||||
self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()[0:3])
|
||||
assert subsetfont.getGlyphOrder() == font.getGlyphOrder()[0:3]
|
||||
|
||||
hmtx = subsetfont["hmtx"]
|
||||
self.assertEqual(hmtx["A"], ( 0, 0))
|
||||
self.assertEqual(hmtx["B"], (400, 132))
|
||||
assert hmtx["A"] == (0, 0)
|
||||
assert hmtx["B"] == (400, 132)
|
||||
|
||||
glyf = subsetfont["glyf"]
|
||||
self.assertEqual(glyf["A"].numberOfContours, 0)
|
||||
self.assertGreater(glyf["B"].numberOfContours, 0)
|
||||
assert glyf["A"].numberOfContours == 0
|
||||
assert glyf["B"].numberOfContours > 0
|
||||
|
||||
def test_retain_gids_cff(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf")
|
||||
fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf")
|
||||
font = TTFont(fontpath)
|
||||
|
||||
self.assertEqual(font["hmtx"]["A"], (500, 132))
|
||||
self.assertEqual(font["hmtx"]["B"], (400, 132))
|
||||
self.assertEqual(font["hmtx"]["C"], (500, 0))
|
||||
assert font["hmtx"]["A"] == (500, 132)
|
||||
assert font["hmtx"]["B"] == (400, 132)
|
||||
assert font["hmtx"]["C"] == (500, 0)
|
||||
|
||||
font["CFF "].cff[0].decompileAllCharStrings()
|
||||
cs = font["CFF "].cff[0].CharStrings
|
||||
self.assertGreater(len(cs["A"].program), 0)
|
||||
self.assertGreater(len(cs["B"].program), 0)
|
||||
self.assertGreater(len(cs["C"].program), 0)
|
||||
assert len(cs["A"].program) > 0
|
||||
assert len(cs["B"].program) > 0
|
||||
assert len(cs["C"].program) > 0
|
||||
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main(
|
||||
@ -637,29 +635,30 @@ class SubsetTest(unittest.TestCase):
|
||||
)
|
||||
subsetfont = TTFont(subsetpath)
|
||||
|
||||
self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()[0:3])
|
||||
assert subsetfont.getGlyphOrder() == font.getGlyphOrder()[0:3]
|
||||
|
||||
hmtx = subsetfont["hmtx"]
|
||||
self.assertEqual(hmtx["A"], (0, 0))
|
||||
self.assertEqual(hmtx["B"], (400, 132))
|
||||
assert hmtx["A"] == (0, 0)
|
||||
assert hmtx["B"] == (400, 132)
|
||||
|
||||
subsetfont["CFF "].cff[0].decompileAllCharStrings()
|
||||
cs = subsetfont["CFF "].cff[0].CharStrings
|
||||
|
||||
self.assertEqual(cs["A"].program, ["endchar"])
|
||||
self.assertGreater(len(cs["B"].program), 0)
|
||||
assert cs["A"].program == ["endchar"]
|
||||
assert len(cs["B"].program) > 0
|
||||
|
||||
def test_retain_gids_cff2(self):
|
||||
ttx_path = self.getpath("../../varLib/data/master_ttx_varfont_otf/TestCFF2VF.ttx")
|
||||
font, fontpath = self.compile_font(ttx_path, ".otf")
|
||||
fontpath = self.compile_font(ttx_path, ".otf")
|
||||
font = TTFont(fontpath)
|
||||
|
||||
self.assertEqual(font["hmtx"]["A"], (600, 31))
|
||||
self.assertEqual(font["hmtx"]["T"], (600, 41))
|
||||
assert font["hmtx"]["A"] == (600, 31)
|
||||
assert font["hmtx"]["T"] == (600, 41)
|
||||
|
||||
font["CFF2"].cff[0].decompileAllCharStrings()
|
||||
cs = font["CFF2"].cff[0].CharStrings
|
||||
self.assertGreater(len(cs["A"].program), 0)
|
||||
self.assertGreater(len(cs["T"].program), 0)
|
||||
assert len(cs["A"].program) > 0
|
||||
assert len(cs["T"].program) > 0
|
||||
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main(
|
||||
@ -672,33 +671,33 @@ class SubsetTest(unittest.TestCase):
|
||||
)
|
||||
subsetfont = TTFont(subsetpath)
|
||||
|
||||
self.assertEqual(len(subsetfont.getGlyphOrder()), len(font.getGlyphOrder()[0:3]))
|
||||
assert len(subsetfont.getGlyphOrder()) == len(font.getGlyphOrder()[0:3])
|
||||
|
||||
hmtx = subsetfont["hmtx"]
|
||||
self.assertEqual(hmtx["glyph00001"], ( 0, 0))
|
||||
self.assertEqual(hmtx["T"], (600, 41))
|
||||
assert hmtx["glyph00001"] == (0, 0)
|
||||
assert hmtx["T"] == (600, 41)
|
||||
|
||||
subsetfont["CFF2"].cff[0].decompileAllCharStrings()
|
||||
cs = subsetfont["CFF2"].cff[0].CharStrings
|
||||
self.assertEqual(cs["glyph00001"].program, [])
|
||||
self.assertGreater(len(cs["T"].program), 0)
|
||||
assert cs["glyph00001"].program == []
|
||||
assert len(cs["T"].program) > 0
|
||||
|
||||
def test_HVAR_VVAR(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestHVVAR.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestHVVAR.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--text=BD", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_HVVAR.ttx"), ["GlyphOrder", "HVAR", "VVAR", "avar", "fvar"])
|
||||
|
||||
def test_HVAR_VVAR_retain_gids(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestHVVAR.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestHVVAR.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--text=BD", "--retain-gids", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_HVVAR_retain_gids.ttx"), ["GlyphOrder", "HVAR", "VVAR", "avar", "fvar"])
|
||||
|
||||
def test_subset_flavor(self):
|
||||
_, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf")
|
||||
font = TTFont(fontpath)
|
||||
|
||||
woff_path = self.temp_path(".woff")
|
||||
@ -712,7 +711,7 @@ class SubsetTest(unittest.TestCase):
|
||||
)
|
||||
woff = TTFont(woff_path)
|
||||
|
||||
self.assertEqual(woff.flavor, "woff")
|
||||
assert woff.flavor == "woff"
|
||||
|
||||
woff2_path = self.temp_path(".woff2")
|
||||
subset.main(
|
||||
@ -725,7 +724,7 @@ class SubsetTest(unittest.TestCase):
|
||||
)
|
||||
woff2 = TTFont(woff2_path)
|
||||
|
||||
self.assertEqual(woff2.flavor, "woff2")
|
||||
assert woff2.flavor == "woff2"
|
||||
|
||||
ttf_path = self.temp_path(".ttf")
|
||||
subset.main(
|
||||
@ -737,13 +736,13 @@ class SubsetTest(unittest.TestCase):
|
||||
)
|
||||
ttf = TTFont(ttf_path)
|
||||
|
||||
self.assertEqual(ttf.flavor, None)
|
||||
assert ttf.flavor is None
|
||||
|
||||
def test_subset_context_subst_format_3(self):
|
||||
# https://github.com/fonttools/fonttools/issues/1879
|
||||
# Test font contains 'calt' feature with Format 3 ContextSubst lookup subtables
|
||||
ttx = self.getpath("TestContextSubstFormat3.ttx")
|
||||
font, fontpath = self.compile_font(ttx, ".ttf")
|
||||
fontpath = self.compile_font(ttx, ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--unicodes=*", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
@ -751,13 +750,14 @@ class SubsetTest(unittest.TestCase):
|
||||
self.expect_ttx(subsetfont, ttx)
|
||||
|
||||
def test_cmap_prune_format12(self):
|
||||
_, fontpath = self.compile_font(self.getpath("CmapSubsetTest.ttx"), ".ttf")
|
||||
fontpath = self.compile_font(self.getpath("CmapSubsetTest.ttx"), ".ttf")
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
subset.main([fontpath, "--glyphs=a", "--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("CmapSubsetTest.subset.ttx"), ["cmap"])
|
||||
|
||||
def test_GPOS_PairPos_Format2_useClass0(self):
|
||||
@pytest.mark.parametrize("text, n", [("!", 1), ("#", 2)])
|
||||
def test_GPOS_PairPos_Format2_useClass0(self, text, n):
|
||||
# Check two things related to class 0 ('every other glyph'):
|
||||
# 1) that it's reused for ClassDef1 when it becomes empty as the subset glyphset
|
||||
# is intersected with the table's Coverage
|
||||
@ -767,29 +767,27 @@ class SubsetTest(unittest.TestCase):
|
||||
# The test font (from Harfbuzz test suite) is constructed to trigger these two
|
||||
# situations depending on the input subset --text.
|
||||
# https://github.com/fonttools/fonttools/pull/2221
|
||||
_, fontpath = self.compile_font(
|
||||
fontpath = self.compile_font(
|
||||
self.getpath("GPOS_PairPos_Format2_PR_2221.ttx"), ".ttf"
|
||||
)
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
|
||||
for n, text in enumerate("!#", start=1):
|
||||
expected_ttx = self.getpath(
|
||||
f"GPOS_PairPos_Format2_ClassDef{n}_useClass0.subset.ttx"
|
||||
)
|
||||
with self.subTest(text=text, expected_ttx=expected_ttx):
|
||||
subset.main(
|
||||
[
|
||||
fontpath,
|
||||
f"--text='{text}'",
|
||||
"--layout-features+=test",
|
||||
"--output-file=%s" % subsetpath,
|
||||
]
|
||||
)
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, expected_ttx, ["GPOS"])
|
||||
expected_ttx = self.getpath(
|
||||
f"GPOS_PairPos_Format2_ClassDef{n}_useClass0.subset.ttx"
|
||||
)
|
||||
subset.main(
|
||||
[
|
||||
fontpath,
|
||||
f"--text='{text}'",
|
||||
"--layout-features+=test",
|
||||
"--output-file=%s" % subsetpath,
|
||||
]
|
||||
)
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, expected_ttx, ["GPOS"])
|
||||
|
||||
def test_GPOS_SinglePos_prune_post_subset_no_value(self):
|
||||
_, fontpath = self.compile_font(
|
||||
fontpath = self.compile_font(
|
||||
self.getpath("GPOS_SinglePos_no_value_issue_2312.ttx"), ".ttf"
|
||||
)
|
||||
subsetpath = self.temp_path(".ttf")
|
||||
@ -801,15 +799,60 @@ class SubsetTest(unittest.TestCase):
|
||||
["GlyphOrder", "GPOS"],
|
||||
)
|
||||
|
||||
def test_harfbuzz_repacker(self):
|
||||
_, fontpath = self.compile_font(self.getpath("harfbuzz_repacker.ttx"), ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
subset.main([fontpath, "--unicodes=0x53a9", "--layout-features=*",
|
||||
"--output-file=%s" % subsetpath])
|
||||
subsetfont = TTFont(subsetpath)
|
||||
self.expect_ttx(subsetfont, self.getpath("expect_harfbuzz_repacker.ttx"),
|
||||
["GSUB"])
|
||||
@pytest.mark.parametrize(
|
||||
"installed, ok",
|
||||
[
|
||||
pytest.param(True, True, id="installed-ok"),
|
||||
pytest.param(True, False, id="installed-fail"),
|
||||
pytest.param(False, True, id="not_installed"),
|
||||
],
|
||||
)
|
||||
def test_harfbuzz_repacker(self, caplog, monkeypatch, installed, ok):
|
||||
# Use a mock to test the pure-python serializer is used when uharfbuzz
|
||||
# returns an error or is not installed
|
||||
have_uharfbuzz = fontTools.ttLib.tables.otBase.have_uharfbuzz
|
||||
if installed:
|
||||
if not have_uharfbuzz:
|
||||
pytest.skip("uharfbuzz is not installed")
|
||||
if not ok:
|
||||
# pretend hb.repack returns an error
|
||||
import uharfbuzz as hb
|
||||
|
||||
def mock_repack(data, obj_list):
|
||||
raise hb.RepackerError("mocking")
|
||||
|
||||
monkeypatch.setattr(hb, "repack", mock_repack)
|
||||
else:
|
||||
if have_uharfbuzz:
|
||||
# pretend uharfbuzz is not installed
|
||||
monkeypatch.setattr(
|
||||
fontTools.ttLib.tables.otBase, "have_uharfbuzz", False
|
||||
)
|
||||
|
||||
fontpath = self.compile_font(self.getpath("harfbuzz_repacker.ttx"), ".otf")
|
||||
subsetpath = self.temp_path(".otf")
|
||||
with caplog.at_level(logging.ERROR, "fontTools.ttLib.tables.otBase"):
|
||||
subset.main(
|
||||
[
|
||||
fontpath,
|
||||
"--unicodes=0x53a9",
|
||||
"--layout-features=*",
|
||||
f"--output-file={subsetpath}",
|
||||
]
|
||||
)
|
||||
subsetfont = TTFont(subsetpath)
|
||||
# both hb.repack and pure-python serializer compile to the same ttx
|
||||
self.expect_ttx(
|
||||
subsetfont, self.getpath("expect_harfbuzz_repacker.ttx"), ["GSUB"]
|
||||
)
|
||||
|
||||
# test we emit a log.error if hb.repack fails (and we don't if successful)
|
||||
assert (
|
||||
(
|
||||
"hb.repack failed, reverting to pure-python serializer; "
|
||||
"the error message was: mocking"
|
||||
) in caplog.text
|
||||
) ^ ok
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
Loading…
x
Reference in New Issue
Block a user