Source code for fontTools.ttLib.tables.C_O_L_R_

# Copyright 2013 Google, Inc. All Rights Reserved.
# Google Author(s): Behdad Esfahbod

from fontTools.misc.textTools import safeEval
from . import DefaultTable

[docs]class table_C_O_L_R_(DefaultTable.DefaultTable): """This table is structured so that you can treat it like a dictionary keyed by glyph name. ``ttFont['COLR'][<glyphName>]`` will return the color layers for any glyph. ``ttFont['COLR'][<glyphName>] = <value>`` will set the color layers for any glyph. """ @staticmethod def _decompileColorLayersV0(table): if not table.LayerRecordArray: return {} colorLayerLists = {} layerRecords = table.LayerRecordArray.LayerRecord numLayerRecords = len(layerRecords) for baseRec in table.BaseGlyphRecordArray.BaseGlyphRecord: baseGlyph = baseRec.BaseGlyph firstLayerIndex = baseRec.FirstLayerIndex numLayers = baseRec.NumLayers assert firstLayerIndex + numLayers <= numLayerRecords layers = [] for i in range(firstLayerIndex, firstLayerIndex + numLayers): layerRec = layerRecords[i] layers.append(LayerRecord(layerRec.LayerGlyph, layerRec.PaletteIndex)) colorLayerLists[baseGlyph] = layers return colorLayerLists def _toOTTable(self, ttFont): from . import otTables from fontTools.colorLib.builder import populateCOLRv0 tableClass = getattr(otTables, self.tableTag) table = tableClass() table.Version = self.version populateCOLRv0( table, { baseGlyph: [(, layer.colorID) for layer in layers] for baseGlyph, layers in self.ColorLayers.items() }, glyphMap=ttFont.getReverseGlyphMap(rebuild=True), ) return table
[docs] def decompile(self, data, ttFont): from .otBase import OTTableReader from . import otTables # We use otData to decompile, but we adapt the decompiled otTables to the # existing COLR v0 API for backward compatibility. reader = OTTableReader(data, tableTag=self.tableTag) tableClass = getattr(otTables, self.tableTag) table = tableClass() table.decompile(reader, ttFont) self.version = table.Version if self.version == 0: self.ColorLayers = self._decompileColorLayersV0(table) else: # for new versions, keep the raw otTables around self.table = table
[docs] def compile(self, ttFont): from .otBase import OTTableWriter if hasattr(self, "table"): table = self.table else: table = self._toOTTable(ttFont) writer = OTTableWriter(tableTag=self.tableTag) table.compile(writer, ttFont) return writer.getAllData()
[docs] def toXML(self, writer, ttFont): if hasattr(self, "table"): self.table.toXML2(writer, ttFont) else: writer.simpletag("version", value=self.version) writer.newline() for baseGlyph in sorted(self.ColorLayers.keys(), key=ttFont.getGlyphID): writer.begintag("ColorGlyph", name=baseGlyph) writer.newline() for layer in self.ColorLayers[baseGlyph]: layer.toXML(writer, ttFont) writer.endtag("ColorGlyph") writer.newline()
[docs] def fromXML(self, name, attrs, content, ttFont): if name == "version": # old COLR v0 API setattr(self, name, safeEval(attrs["value"])) elif name == "ColorGlyph": if not hasattr(self, "ColorLayers"): self.ColorLayers = {} glyphName = attrs["name"] for element in content: if isinstance(element, str): continue layers = [] for element in content: if isinstance(element, str): continue layer = LayerRecord() layer.fromXML(element[0], element[1], element[2], ttFont) layers.append(layer) self.ColorLayers[glyphName] = layers else: # new COLR v1 API from . import otTables if not hasattr(self, "table"): tableClass = getattr(otTables, self.tableTag) self.table = tableClass() self.table.fromXML(name, attrs, content, ttFont) self.table.populateDefaults() self.version = self.table.Version
def __getitem__(self, glyphName): if not isinstance(glyphName, str): raise TypeError(f"expected str, found {type(glyphName).__name__}") return self.ColorLayers[glyphName] def __setitem__(self, glyphName, value): if not isinstance(glyphName, str): raise TypeError(f"expected str, found {type(glyphName).__name__}") if value is not None: self.ColorLayers[glyphName] = value elif glyphName in self.ColorLayers: del self.ColorLayers[glyphName] def __delitem__(self, glyphName): del self.ColorLayers[glyphName]
[docs]class LayerRecord(object): def __init__(self, name=None, colorID=None): = name self.colorID = colorID
[docs] def toXML(self, writer, ttFont): writer.simpletag("layer",, colorID=self.colorID) writer.newline()
[docs] def fromXML(self, eltname, attrs, content, ttFont): for (name, value) in attrs.items(): if name == "name": setattr(self, name, value) else: setattr(self, name, safeEval(value))