2013-09-19 20:02:17 -04:00
|
|
|
# Copyright 2013 Google, Inc. All Rights Reserved.
|
|
|
|
#
|
|
|
|
# Google Author(s): Behdad Esfahbod
|
|
|
|
|
2013-11-27 17:27:45 -05:00
|
|
|
from fontTools.misc.py23 import *
|
|
|
|
from fontTools.misc.textTools import safeEval
|
2013-11-27 02:34:11 -05:00
|
|
|
from . import DefaultTable
|
2013-07-24 12:31:50 -04:00
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def decompile(self, data, ttFont):
|
2020-02-10 13:45:44 +00:00
|
|
|
from .otBase import OTTableReader
|
|
|
|
from . import otTables
|
|
|
|
|
|
|
|
reader = OTTableReader(data, tableTag=self.tableTag)
|
|
|
|
tableClass = getattr(otTables, self.tableTag)
|
|
|
|
table = tableClass()
|
|
|
|
table.decompile(reader, ttFont)
|
|
|
|
|
2013-07-24 12:31:50 -04:00
|
|
|
self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID
|
2020-02-10 13:45:44 +00:00
|
|
|
self.version = table.Version
|
2013-07-24 12:31:50 -04:00
|
|
|
assert (self.version == 0), "Version of COLR table is higher than I know how to handle"
|
2020-02-10 13:45:44 +00:00
|
|
|
|
2020-02-11 13:46:45 +00:00
|
|
|
self.ColorLayers = colorLayerLists = {}
|
|
|
|
|
2020-02-10 13:45:44 +00:00
|
|
|
layerRecords = table.LayerRecordArray.LayerRecord
|
|
|
|
numLayerRecords = len(layerRecords)
|
|
|
|
for baseRec in table.BaseGlyphRecordArray.BaseGlyphRecord:
|
|
|
|
baseGlyph = baseRec.BaseGlyph
|
|
|
|
firstLayerIndex = baseRec.FirstLayerIndex
|
|
|
|
numLayers = baseRec.NumLayers
|
2013-07-24 12:31:50 -04:00
|
|
|
assert (firstLayerIndex + numLayers <= numLayerRecords)
|
|
|
|
layers = []
|
2020-02-10 13:45:44 +00:00
|
|
|
for i in range(firstLayerIndex, firstLayerIndex+numLayers):
|
|
|
|
layerRec = layerRecords[i]
|
|
|
|
layers.append(LayerRecord(layerRec.LayerGlyph, layerRec.PaletteIndex))
|
2020-02-11 13:46:45 +00:00
|
|
|
colorLayerLists[baseGlyph] = layers
|
2013-07-24 12:31:50 -04:00
|
|
|
|
|
|
|
def compile(self, ttFont):
|
2020-02-10 13:45:44 +00:00
|
|
|
from .otBase import OTTableWriter
|
|
|
|
from . import otTables
|
|
|
|
|
2013-12-04 21:28:50 -05:00
|
|
|
ttFont.getReverseGlyphMap(rebuild=True)
|
2013-07-24 12:31:50 -04:00
|
|
|
|
2020-02-10 13:45:44 +00:00
|
|
|
tableClass = getattr(otTables, self.tableTag)
|
|
|
|
table = tableClass()
|
|
|
|
|
|
|
|
table.Version = self.version
|
|
|
|
|
|
|
|
table.BaseGlyphRecordArray = otTables.BaseGlyphRecordArray()
|
|
|
|
table.BaseGlyphRecordArray.BaseGlyphRecord = baseGlyphRecords = []
|
|
|
|
table.LayerRecordArray = otTables.LayerRecordArray()
|
|
|
|
table.LayerRecordArray.LayerRecord = layerRecords = []
|
|
|
|
|
|
|
|
for baseGlyph in sorted(self.ColorLayers.keys(), key=ttFont.getGlyphID):
|
|
|
|
layers = self.ColorLayers[baseGlyph]
|
|
|
|
|
|
|
|
baseRec = otTables.BaseGlyphRecord()
|
|
|
|
baseRec.BaseGlyph = baseGlyph
|
|
|
|
baseRec.FirstLayerIndex = len(layerRecords)
|
|
|
|
baseRec.NumLayers = len(layers)
|
|
|
|
baseGlyphRecords.append(baseRec)
|
|
|
|
|
2013-07-24 12:31:50 -04:00
|
|
|
for layer in layers:
|
2020-02-10 13:45:44 +00:00
|
|
|
layerRec = otTables.LayerRecord()
|
|
|
|
layerRec.LayerGlyph = layer.name
|
|
|
|
layerRec.PaletteIndex = layer.colorID
|
|
|
|
layerRecords.append(layerRec)
|
2013-07-24 12:31:50 -04:00
|
|
|
|
2020-02-10 13:45:44 +00:00
|
|
|
writer = OTTableWriter(tableTag=self.tableTag)
|
|
|
|
table.compile(writer, ttFont)
|
|
|
|
return writer.getAllData()
|
2013-07-24 12:31:50 -04:00
|
|
|
|
|
|
|
def toXML(self, writer, ttFont):
|
|
|
|
writer.simpletag("version", value=self.version)
|
|
|
|
writer.newline()
|
2020-02-11 13:30:20 +00:00
|
|
|
for baseGlyph in sorted(self.ColorLayers.keys(), key=ttFont.getGlyphID):
|
|
|
|
writer.begintag("ColorGlyph", name=baseGlyph)
|
2013-07-24 12:31:50 -04:00
|
|
|
writer.newline()
|
2020-02-11 13:30:20 +00:00
|
|
|
for layer in self.ColorLayers[baseGlyph]:
|
2013-07-24 12:31:50 -04:00
|
|
|
layer.toXML(writer, ttFont)
|
|
|
|
writer.endtag("ColorGlyph")
|
|
|
|
writer.newline()
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, name, attrs, content, ttFont):
|
2013-07-24 12:31:50 -04:00
|
|
|
if not hasattr(self, "ColorLayers"):
|
|
|
|
self.ColorLayers = {}
|
|
|
|
self.getGlyphName = ttFont.getGlyphName # for use in get/set item functions, for access by GID
|
|
|
|
if name == "ColorGlyph":
|
|
|
|
glyphName = attrs["name"]
|
|
|
|
for element in content:
|
2013-11-27 23:37:57 -05:00
|
|
|
if isinstance(element, basestring):
|
2013-07-24 12:31:50 -04:00
|
|
|
continue
|
|
|
|
layers = []
|
|
|
|
for element in content:
|
2013-11-27 23:37:57 -05:00
|
|
|
if isinstance(element, basestring):
|
2013-07-24 12:31:50 -04:00
|
|
|
continue
|
|
|
|
layer = LayerRecord()
|
2013-11-27 03:19:32 -05:00
|
|
|
layer.fromXML(element[0], element[1], element[2], ttFont)
|
2013-07-24 12:31:50 -04:00
|
|
|
layers.append (layer)
|
2019-03-03 13:12:50 +01:00
|
|
|
self[glyphName] = layers
|
2013-11-27 02:33:03 -05:00
|
|
|
elif "value" in attrs:
|
2013-11-27 04:00:15 -05:00
|
|
|
setattr(self, name, safeEval(attrs["value"]))
|
2013-07-24 12:31:50 -04:00
|
|
|
|
|
|
|
def __getitem__(self, glyphSelector):
|
2013-11-27 05:17:37 -05:00
|
|
|
if isinstance(glyphSelector, int):
|
2013-07-24 12:31:50 -04:00
|
|
|
# its a gid, convert to glyph name
|
|
|
|
glyphSelector = self.getGlyphName(glyphSelector)
|
|
|
|
|
2013-11-27 02:33:03 -05:00
|
|
|
if glyphSelector not in self.ColorLayers:
|
2013-07-24 12:31:50 -04:00
|
|
|
return None
|
2015-04-26 02:01:01 -04:00
|
|
|
|
2013-07-24 12:31:50 -04:00
|
|
|
return self.ColorLayers[glyphSelector]
|
|
|
|
|
|
|
|
def __setitem__(self, glyphSelector, value):
|
2013-11-27 05:17:37 -05:00
|
|
|
if isinstance(glyphSelector, int):
|
2013-07-24 12:31:50 -04:00
|
|
|
# its a gid, convert to glyph name
|
|
|
|
glyphSelector = self.getGlyphName(glyphSelector)
|
|
|
|
|
|
|
|
if value:
|
|
|
|
self.ColorLayers[glyphSelector] = value
|
2013-11-27 02:33:03 -05:00
|
|
|
elif glyphSelector in self.ColorLayers:
|
2013-07-24 12:31:50 -04:00
|
|
|
del self.ColorLayers[glyphSelector]
|
|
|
|
|
2014-05-14 13:51:10 -06:00
|
|
|
def __delitem__(self, glyphSelector):
|
|
|
|
del self.ColorLayers[glyphSelector]
|
|
|
|
|
2013-11-28 14:26:58 -05:00
|
|
|
class LayerRecord(object):
|
2013-07-24 12:31:50 -04:00
|
|
|
|
2015-04-26 00:54:30 -04:00
|
|
|
def __init__(self, name=None, colorID=None):
|
2013-07-24 12:31:50 -04:00
|
|
|
self.name = name
|
|
|
|
self.colorID = colorID
|
|
|
|
|
|
|
|
def toXML(self, writer, ttFont):
|
|
|
|
writer.simpletag("layer", name=self.name, colorID=self.colorID)
|
|
|
|
writer.newline()
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, eltname, attrs, content, ttFont):
|
2013-07-24 12:31:50 -04:00
|
|
|
for (name, value) in attrs.items():
|
|
|
|
if name == "name":
|
2013-11-27 05:17:37 -05:00
|
|
|
if isinstance(value, int):
|
2013-07-24 12:31:50 -04:00
|
|
|
value = ttFont.getGlyphName(value)
|
|
|
|
setattr(self, name, value)
|
|
|
|
else:
|
2013-11-27 04:00:15 -05:00
|
|
|
setattr(self, name, safeEval(value))
|