aboutsummaryrefslogtreecommitdiff
path: root/Tests/ttLib/ttFont_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/ttLib/ttFont_test.py')
-rw-r--r--Tests/ttLib/ttFont_test.py114
1 files changed, 110 insertions, 4 deletions
diff --git a/Tests/ttLib/ttFont_test.py b/Tests/ttLib/ttFont_test.py
index e0e82b24..2203b4d9 100644
--- a/Tests/ttLib/ttFont_test.py
+++ b/Tests/ttLib/ttFont_test.py
@@ -2,8 +2,16 @@ import io
import os
import re
import random
+import tempfile
from fontTools.feaLib.builder import addOpenTypeFeaturesFromString
-from fontTools.ttLib import TTFont, newTable, registerCustomTableClass, unregisterCustomTableClass
+from fontTools.ttLib import (
+ TTFont,
+ TTLibError,
+ newTable,
+ registerCustomTableClass,
+ unregisterCustomTableClass,
+)
+from fontTools.ttLib.standardGlyphOrder import standardGlyphOrder
from fontTools.ttLib.tables.DefaultTable import DefaultTable
from fontTools.ttLib.tables._c_m_a_p import CmapSubtable
import pytest
@@ -13,7 +21,6 @@ DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
class CustomTableClass(DefaultTable):
-
def decompile(self, data, ttFont):
self.numbers = list(data)
@@ -143,6 +150,17 @@ def test_setGlyphOrder_also_updates_glyf_glyphOrder():
assert font["glyf"].glyphOrder == new_order
+def test_getGlyphOrder_not_true_post_format_1(caplog):
+ # https://github.com/fonttools/fonttools/issues/2736
+ caplog.set_level("WARNING")
+ font = TTFont(os.path.join(DATA_DIR, "bogus_post_format_1.ttf"))
+ hmtx = font["hmtx"]
+ assert len(hmtx.metrics) > len(standardGlyphOrder)
+ log_rec = caplog.records[-1]
+ assert log_rec.levelname == "WARNING"
+ assert "Not enough names found in the 'post' table" in log_rec.message
+
+
@pytest.mark.parametrize("lazy", [None, True, False])
def test_ensureDecompiled(lazy):
# test that no matter the lazy value, ensureDecompiled decompiles all tables
@@ -159,7 +177,7 @@ def test_ensureDecompiled(lazy):
feature dist {
pos period period -30;
} dist;
- """
+ """,
)
# also add an additional cmap subtable that will be lazily-loaded
cm = CmapSubtable.newSubtable(14)
@@ -167,7 +185,7 @@ def test_ensureDecompiled(lazy):
cm.platEncID = 5
cm.language = 0
cm.cmap = {}
- cm.uvsDict = {0xFE00: [(0x002e, None)]}
+ cm.uvsDict = {0xFE00: [(0x002E, None)]}
font["cmap"].tables.append(cm)
# save and reload, potentially lazily
@@ -212,3 +230,91 @@ def test_ensureDecompiled(lazy):
assert "Lookup" in font["GSUB"].table.LookupList.__dict__
assert "reader" not in font["GPOS"].table.LookupList.__dict__
assert "Lookup" in font["GPOS"].table.LookupList.__dict__
+
+
+@pytest.fixture
+def testFont_fvar_avar():
+ ttxpath = os.path.join(DATA_DIR, "TestTTF_normalizeLocation.ttx")
+ ttf = TTFont()
+ ttf.importXML(ttxpath)
+ return ttf
+
+
+@pytest.mark.parametrize(
+ "userLocation, expectedNormalizedLocation",
+ [
+ ({}, {"wght": 0.0}),
+ ({"wght": 100}, {"wght": -1.0}),
+ ({"wght": 250}, {"wght": -0.75}),
+ ({"wght": 400}, {"wght": 0.0}),
+ ({"wght": 550}, {"wght": 0.75}),
+ ({"wght": 625}, {"wght": 0.875}),
+ ({"wght": 700}, {"wght": 1.0}),
+ ],
+)
+def test_font_normalizeLocation(
+ testFont_fvar_avar, userLocation, expectedNormalizedLocation
+):
+ normalizedLocation = testFont_fvar_avar.normalizeLocation(userLocation)
+ assert expectedNormalizedLocation == normalizedLocation
+
+
+def test_font_normalizeLocation_no_VF():
+ ttf = TTFont()
+ with pytest.raises(TTLibError, match="Not a variable font"):
+ ttf.normalizeLocation({})
+
+
+def test_getGlyphID():
+ font = TTFont()
+ font.importXML(os.path.join(DATA_DIR, "TestTTF-Regular.ttx"))
+
+ assert font.getGlyphID("space") == 3
+ assert font.getGlyphID("glyph12345") == 12345 # virtual glyph
+ with pytest.raises(KeyError):
+ font.getGlyphID("non_existent")
+ with pytest.raises(KeyError):
+ font.getGlyphID("glyph_prefix_but_invalid_id")
+
+
+def test_spooled_tempfile_may_not_have_attribute_seekable():
+ # SpooledTemporaryFile only got a seekable attribute on Python 3.11
+ # https://github.com/fonttools/fonttools/issues/3052
+ font = TTFont()
+ font.importXML(os.path.join(DATA_DIR, "TestTTF-Regular.ttx"))
+ tmp = tempfile.SpooledTemporaryFile()
+ font.save(tmp)
+ # this should not fail
+ _ = TTFont(tmp)
+
+
+def test_unseekable_file_lazy_loading_fails():
+ class NonSeekableFile:
+ def __init__(self):
+ self.file = io.BytesIO()
+
+ def read(self, size):
+ return self.file.read(size)
+
+ def seekable(self):
+ return False
+
+ f = NonSeekableFile()
+ with pytest.raises(TTLibError, match="Input file must be seekable when lazy=True"):
+ TTFont(f, lazy=True)
+
+
+def test_unsupported_seek_operation_lazy_loading_fails():
+ class UnsupportedSeekFile:
+ def __init__(self):
+ self.file = io.BytesIO()
+
+ def read(self, size):
+ return self.file.read(size)
+
+ def seek(self, offset):
+ raise io.UnsupportedOperation("Unsupported seek operation")
+
+ f = UnsupportedSeekFile()
+ with pytest.raises(TTLibError, match="Input file must be seekable when lazy=True"):
+ TTFont(f, lazy=True)