From f518e5a704c580b644bd136794914a4fdf3dc846 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Wed, 15 Nov 2023 12:20:24 +0000 Subject: [PATCH] [OS/2] don't error getting/setting codepages if version=0 return empty set, or set the bits and bump the version to match --- Lib/fontTools/ttLib/tables/O_S_2f_2.py | 4 ++++ Tests/ttLib/tables/O_S_2f_2_test.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Lib/fontTools/ttLib/tables/O_S_2f_2.py b/Lib/fontTools/ttLib/tables/O_S_2f_2.py index b4126b835..edff91f58 100644 --- a/Lib/fontTools/ttLib/tables/O_S_2f_2.py +++ b/Lib/fontTools/ttLib/tables/O_S_2f_2.py @@ -343,6 +343,8 @@ class table_O_S_2f_2(DefaultTable.DefaultTable): def getCodePageRanges(self): """Return the set of 'ulCodePageRange*' bits currently enabled.""" bits = set() + if self.version < 1: + return bits ul1, ul2 = self.ulCodePageRange1, self.ulCodePageRange2 for i in range(32): if ul1 & (1 << i): @@ -361,6 +363,8 @@ class table_O_S_2f_2(DefaultTable.DefaultTable): ul2 |= 1 << (bit - 32) else: raise ValueError(f"expected 0 <= int <= 63, found: {bit:r}") + if self.version < 1: + self.version = 1 self.ulCodePageRange1, self.ulCodePageRange2 = ul1, ul2 def recalcCodePageRanges(self, ttFont, pruneOnly=False): diff --git a/Tests/ttLib/tables/O_S_2f_2_test.py b/Tests/ttLib/tables/O_S_2f_2_test.py index a05c70240..71388560b 100644 --- a/Tests/ttLib/tables/O_S_2f_2_test.py +++ b/Tests/ttLib/tables/O_S_2f_2_test.py @@ -8,6 +8,7 @@ class OS2TableTest(unittest.TestCase): def makeOS2_cmap(mapping): font = TTFont() font["OS/2"] = os2 = newTable("OS/2") + os2.version = 4 font["cmap"] = cmap = newTable("cmap") st = getTableModule("cmap").CmapSubtable.newSubtable(4) st.platformID, st.platEncID, st.language = 3, 1, 0 @@ -64,6 +65,11 @@ class OS2TableTest(unittest.TestCase): def test_getCodePageRanges(self): table = table_O_S_2f_2() + # version 0 doesn't define these fields so by definition defines no cp ranges + table.version = 0 + self.assertEqual(table.getCodePageRanges(), set()) + # version 1 and above do contain ulCodePageRange1 and 2 fields + table.version = 1 table.ulCodePageRange1 = 0xFFFFFFFF table.ulCodePageRange2 = 0xFFFFFFFF bits = table.getCodePageRanges() @@ -72,6 +78,7 @@ class OS2TableTest(unittest.TestCase): def test_setCodePageRanges(self): table = table_O_S_2f_2() + table.version = 4 table.ulCodePageRange1 = 0 table.ulCodePageRange2 = 0 bits = set(range(64)) @@ -84,6 +91,16 @@ class OS2TableTest(unittest.TestCase): with self.assertRaises(ValueError): table.setCodePageRanges([255]) + def test_setCodePageRanges_bump_version(self): + # Setting codepage ranges on a OS/2 table version 0 automatically makes it + # a version 1 table + table = table_O_S_2f_2() + table.version = 0 + self.assertEqual(table.getCodePageRanges(), set()) + table.setCodePageRanges({0, 1, 2}) + self.assertEqual(table.getCodePageRanges(), {0, 1, 2}) + self.assertEqual(table.version, 1) + def test_recalcCodePageRanges(self): font, os2, cmap = self.makeOS2_cmap( {ord("A"): "A", ord("Ά"): "Alphatonos", ord("Б"): "Be"}