diff --git a/Lib/fontTools/misc/testTools.py b/Lib/fontTools/misc/testTools.py
index 86fa2ea87..4b0cd0813 100644
--- a/Lib/fontTools/misc/testTools.py
+++ b/Lib/fontTools/misc/testTools.py
@@ -38,6 +38,14 @@ def parseXML(xmlSnippet):
return reader.root[2]
+def parseXmlInto(font, parseInto, xmlSnippet):
+ parsed_xml = [e for e in parseXML(xmlSnippet.strip()) if not isinstance(e, str)]
+ for name, attrs, content in parsed_xml:
+ parseInto.fromXML(name, attrs, content, font)
+ parseInto.populateDefaults()
+ return parseInto
+
+
class FakeFont:
def __init__(self, glyphs):
self.glyphOrder_ = glyphs
diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py
index 1955ceb41..b077d4f13 100644
--- a/Lib/fontTools/ttLib/tables/otTables.py
+++ b/Lib/fontTools/ttLib/tables/otTables.py
@@ -1516,7 +1516,11 @@ class Paint(getFormatSwitchingBaseTableClass("uint8")):
def getChildren(self, colr):
if self.Format == PaintFormat.PaintColrLayers:
- return colr.LayerList.Paint[
+ # https://github.com/fonttools/fonttools/issues/2438: don't die when no LayerList exists
+ layers = []
+ if colr.LayerList is not None:
+ layers = colr.LayerList.Paint
+ return layers[
self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers
]
diff --git a/Tests/ttLib/tables/otTables_test.py b/Tests/ttLib/tables/otTables_test.py
index b1697761b..ffaadd28c 100644
--- a/Tests/ttLib/tables/otTables_test.py
+++ b/Tests/ttLib/tables/otTables_test.py
@@ -1,4 +1,4 @@
-from fontTools.misc.testTools import getXML, parseXML, FakeFont
+from fontTools.misc.testTools import getXML, parseXML, parseXmlInto, FakeFont
from fontTools.misc.textTools import deHexStr, hexStr
from fontTools.misc.xmlWriter import XMLWriter
from fontTools.ttLib.tables.otBase import OTTableReader, OTTableWriter
@@ -687,6 +687,33 @@ def test_splitMarkBasePos():
]
+class ColrV1Test(unittest.TestCase):
+ def setUp(self):
+ self.font = FakeFont(['.notdef', 'meh'])
+
+ def test_traverseEmptyPaintColrLayersNeedsNoLayerList(self):
+ colr = parseXmlInto(self.font, otTables.COLR(),
+ '''
+
+
+
+
+
+
+
+
+
+
+ ''')
+ paint = colr.BaseGlyphList.BaseGlyphPaintRecord[0].Paint
+
+ # Just want to confirm we don't crash
+ visited = []
+ paint.traverse(colr, lambda p: visited.append(p))
+ assert len(visited) == 1
+
+
+
if __name__ == "__main__":
import sys
sys.exit(unittest.main())