diff options
Diffstat (limited to 'Lib/fontTools/ttLib/tables/otTables.py')
-rw-r--r-- | Lib/fontTools/ttLib/tables/otTables.py | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index 7f42921d..008909bd 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -1324,24 +1324,34 @@ class CompositeMode(IntEnum): HSL_LUMINOSITY = 26 -class Paint(getFormatSwitchingBaseTableClass("uint8")): +class PaintFormat(IntEnum): + PaintColrLayers = 1 + PaintSolid = 2 + PaintVarSolid = 3, + PaintLinearGradient = 4 + PaintVarLinearGradient = 5 + PaintRadialGradient = 6 + PaintVarRadialGradient = 7 + PaintSweepGradient = 8 + PaintVarSweepGradient = 9 + PaintGlyph = 10 + PaintColrGlyph = 11 + PaintTransform = 12 + PaintVarTransform = 13 + PaintTranslate = 14 + PaintVarTranslate = 15 + PaintRotate = 16 + PaintVarRotate = 17 + PaintSkew = 18 + PaintVarSkew = 19 + PaintComposite = 20 + - class Format(IntEnum): - PaintColrLayers = 1 - PaintSolid = 2 - PaintLinearGradient = 3 - PaintRadialGradient = 4 - PaintGlyph = 5 - PaintColrGlyph = 6 - PaintTransform = 7 - PaintTranslate = 8 - PaintRotate = 9 - PaintSkew = 10 - PaintComposite = 11 +class Paint(getFormatSwitchingBaseTableClass("uint8")): def getFormatName(self): try: - return self.__class__.Format(self.Format).name + return PaintFormat(self.Format).name except ValueError: raise NotImplementedError(f"Unknown Paint format: {self.Format}") @@ -1357,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 |