1from fontTools.ttLib.tables import otTables as ot 2from .table_builder import TableUnbuilder 3 4 5def unbuildColrV1(layerList, baseGlyphList): 6 layers = [] 7 if layerList: 8 layers = layerList.Paint 9 unbuilder = LayerListUnbuilder(layers) 10 return { 11 rec.BaseGlyph: unbuilder.unbuildPaint(rec.Paint) 12 for rec in baseGlyphList.BaseGlyphPaintRecord 13 } 14 15 16def _flatten_layers(lst): 17 for paint in lst: 18 if paint["Format"] == ot.PaintFormat.PaintColrLayers: 19 yield from _flatten_layers(paint["Layers"]) 20 else: 21 yield paint 22 23 24class LayerListUnbuilder: 25 def __init__(self, layers): 26 self.layers = layers 27 28 callbacks = { 29 ( 30 ot.Paint, 31 ot.PaintFormat.PaintColrLayers, 32 ): self._unbuildPaintColrLayers, 33 } 34 self.tableUnbuilder = TableUnbuilder(callbacks) 35 36 def unbuildPaint(self, paint): 37 assert isinstance(paint, ot.Paint) 38 return self.tableUnbuilder.unbuild(paint) 39 40 def _unbuildPaintColrLayers(self, source): 41 assert source["Format"] == ot.PaintFormat.PaintColrLayers 42 43 layers = list( 44 _flatten_layers( 45 [ 46 self.unbuildPaint(childPaint) 47 for childPaint in self.layers[ 48 source["FirstLayerIndex"] : source["FirstLayerIndex"] 49 + source["NumLayers"] 50 ] 51 ] 52 ) 53 ) 54 55 if len(layers) == 1: 56 return layers[0] 57 58 return {"Format": source["Format"], "Layers": layers} 59 60 61if __name__ == "__main__": 62 from pprint import pprint 63 import sys 64 from fontTools.ttLib import TTFont 65 66 try: 67 fontfile = sys.argv[1] 68 except IndexError: 69 sys.exit("usage: fonttools colorLib.unbuilder FONTFILE") 70 71 font = TTFont(fontfile) 72 colr = font["COLR"] 73 if colr.version < 1: 74 sys.exit(f"error: No COLR table version=1 found in {fontfile}") 75 76 colorGlyphs = unbuildColrV1( 77 colr.table.LayerList, 78 colr.table.BaseGlyphList, 79 ) 80 81 pprint(colorGlyphs) 82