[otTables] switch to generic table traversal for Paint.traverse
This commit is contained in:
parent
7433c5dbb9
commit
17f431b9c2
@ -9,6 +9,7 @@ import copy
|
|||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import itertools
|
import itertools
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
|
from fontTools.ttLib.tables.otTraverse import dfs_base_table
|
||||||
from fontTools.misc.roundTools import otRound
|
from fontTools.misc.roundTools import otRound
|
||||||
from fontTools.misc.textTools import bytesjoin, pad, safeEval
|
from fontTools.misc.textTools import bytesjoin, pad, safeEval
|
||||||
from .otBase import (
|
from .otBase import (
|
||||||
@ -21,6 +22,7 @@ from .otBase import (
|
|||||||
from fontTools.feaLib.lookupDebugInfo import LookupDebugInfo, LOOKUP_DEBUG_INFO_KEY
|
from fontTools.feaLib.lookupDebugInfo import LookupDebugInfo, LOOKUP_DEBUG_INFO_KEY
|
||||||
import logging
|
import logging
|
||||||
import struct
|
import struct
|
||||||
|
from typing import TYPE_CHECKING, Iterator, List, Optional, Set
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -1557,41 +1559,47 @@ class Paint(getFormatSwitchingBaseTableClass("uint8")):
|
|||||||
xmlWriter.endtag(tableName)
|
xmlWriter.endtag(tableName)
|
||||||
xmlWriter.newline()
|
xmlWriter.newline()
|
||||||
|
|
||||||
def getChildren(self, colr):
|
def iterPaintSubTables(self, colr: COLR) -> Iterator[BaseTable.SubTableEntry]:
|
||||||
if self.Format == PaintFormat.PaintColrLayers:
|
if self.Format == PaintFormat.PaintColrLayers:
|
||||||
# https://github.com/fonttools/fonttools/issues/2438: don't die when no LayerList exists
|
# https://github.com/fonttools/fonttools/issues/2438: don't die when no LayerList exists
|
||||||
layers = []
|
layers = []
|
||||||
if colr.LayerList is not None:
|
if colr.LayerList is not None:
|
||||||
layers = colr.LayerList.Paint
|
layers = colr.LayerList.Paint
|
||||||
return layers[self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers]
|
yield from (
|
||||||
|
BaseTable.SubTableEntry(name="Layers", value=v, index=i)
|
||||||
|
for i, v in enumerate(
|
||||||
|
layers[self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if self.Format == PaintFormat.PaintColrGlyph:
|
if self.Format == PaintFormat.PaintColrGlyph:
|
||||||
for record in colr.BaseGlyphList.BaseGlyphPaintRecord:
|
for record in colr.BaseGlyphList.BaseGlyphPaintRecord:
|
||||||
if record.BaseGlyph == self.Glyph:
|
if record.BaseGlyph == self.Glyph:
|
||||||
return [record.Paint]
|
yield BaseTable.SubTableEntry(name="BaseGlyph", value=record.Paint)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
raise KeyError(f"{self.Glyph!r} not in colr.BaseGlyphList")
|
raise KeyError(f"{self.Glyph!r} not in colr.BaseGlyphList")
|
||||||
|
|
||||||
children = []
|
|
||||||
for conv in self.getConverters():
|
for conv in self.getConverters():
|
||||||
if conv.tableClass is not None and issubclass(conv.tableClass, type(self)):
|
if conv.tableClass is not None and issubclass(conv.tableClass, type(self)):
|
||||||
children.append(getattr(self, conv.name))
|
value = getattr(self, conv.name)
|
||||||
|
yield BaseTable.SubTableEntry(name=conv.name, value=value)
|
||||||
|
|
||||||
return children
|
def getChildren(self, colr) -> List["Paint"]:
|
||||||
|
# this is kept for backward compatibility (e.g. it's used by the subsetter)
|
||||||
|
return [p.value for p in self.iterPaintSubTables(colr)]
|
||||||
|
|
||||||
def traverse(self, colr: COLR, callback):
|
def traverse(self, colr: COLR, callback):
|
||||||
"""Depth-first traversal of graph rooted at self, callback on each node."""
|
"""Depth-first traversal of graph rooted at self, callback on each node."""
|
||||||
if not callable(callback):
|
if not callable(callback):
|
||||||
raise TypeError("callback must be callable")
|
raise TypeError("callback must be callable")
|
||||||
stack = [self]
|
|
||||||
visited = set()
|
for path in dfs_base_table(
|
||||||
while stack:
|
self, iter_subtables_fn=lambda paint: paint.iterPaintSubTables(colr)
|
||||||
current = stack.pop()
|
):
|
||||||
if id(current) in visited:
|
paint = path[-1].value
|
||||||
continue
|
callback(paint)
|
||||||
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
|
# For each subtable format there is a class. However, we don't really distinguish
|
||||||
|
Loading…
x
Reference in New Issue
Block a user