otTables: add Paint.traverse method

paint graph traversal mostly adapted from rsheeter's https://github.com/googlefonts/nanoemoji/pull/233
This commit is contained in:
Cosimo Lupo 2021-02-05 17:17:34 +00:00
parent 4036512a27
commit 4dcc7f83d2
No known key found for this signature in database
GPG Key ID: 179A8F0895A02F4F

View File

@ -1367,6 +1367,40 @@ class Paint(getFormatSwitchingBaseTableClass("uint8")):
xmlWriter.endtag(tableName)
xmlWriter.newline()
def getChildren(self, colr):
if self.Format == PaintFormat.PaintColrLayers:
return colr.LayerV1List.Paint[
self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers
]
if self.Format == PaintFormat.PaintColrGlyph:
for record in colr.BaseGlyphV1List.BaseGlyphV1Record:
if record.BaseGlyph == self.Glyph:
return [record.Paint]
else:
raise KeyError(f"{self.Glyph!r} not in colr.BaseGlyphV1List")
children = []
for conv in self.getConverters():
if conv.tableClass is not None and issubclass(conv.tableClass, type(self)):
children.append(getattr(self, conv.name))
return children
def traverse(self, colr: COLR, callback):
"""Depth-first traversal of graph rooted at self, callback on each node."""
if not callable(callback):
raise TypeError("callback must be callable")
stack = [self]
visited = set()
while stack:
current = stack.pop()
if id(current) in visited:
continue
callback(current)
visited.add(id(current))
stack.extend(reversed(current.getChildren(colr)))
# For each subtable format there is a class. However, we don't really distinguish
# between "field name" and "format name": often these are the same. Yet there's