blob: afa8c4dc0f4284f54dbf97d1b1ec29fd0cb430ff [file] [log] [blame]
from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc.textTools import safeEval
from . import DefaultTable
GMAPFormat = """
> # big endian
tableVersionMajor: H
tableVersionMinor: H
flags: H
recordsCount: H
recordsOffset: H
fontNameLength: H
"""
# psFontName is a byte string which follows the record above. This is zero padded
# to the beginning of the records array. The recordsOffsst is 32 bit aligned.
GMAPRecordFormat1 = """
> # big endian
UV: L
cid: H
gid: H
ggid: H
name: 32s
"""
class GMAPRecord(object):
def __init__(self, uv=0, cid=0, gid=0, ggid=0, name=""):
self.UV = uv
self.cid = cid
self.gid = gid
self.ggid = ggid
self.name = name
def toXML(self, writer, ttFont):
writer.begintag("GMAPRecord")
writer.newline()
writer.simpletag("UV", value=self.UV)
writer.newline()
writer.simpletag("cid", value=self.cid)
writer.newline()
writer.simpletag("gid", value=self.gid)
writer.newline()
writer.simpletag("glyphletGid", value=self.gid)
writer.newline()
writer.simpletag("GlyphletName", value=self.name)
writer.newline()
writer.endtag("GMAPRecord")
writer.newline()
def fromXML(self, name, attrs, content, ttFont):
value = attrs["value"]
if name == "GlyphletName":
self.name = value
else:
setattr(self, name, safeEval(value))
def compile(self, ttFont):
if self.UV is None:
self.UV = 0
nameLen = len(self.name)
if nameLen < 32:
self.name = self.name + "\0"*(32 - nameLen)
data = sstruct.pack(GMAPRecordFormat1, self)
return data
def __repr__(self):
return "GMAPRecord[ UV: " + str(self.UV) + ", cid: " + str(self.cid) + ", gid: " + str(self.gid) + ", ggid: " + str(self.ggid) + ", Glyphlet Name: " + str(self.name) + " ]"
class table_G_M_A_P_(DefaultTable.DefaultTable):
dependencies = []
def decompile(self, data, ttFont):
dummy, newData = sstruct.unpack2(GMAPFormat, data, self)
self.psFontName = tostr(newData[:self.fontNameLength])
assert (self.recordsOffset % 4) == 0, "GMAP error: recordsOffset is not 32 bit aligned."
newData = data[self.recordsOffset:]
self.gmapRecords = []
for i in range (self.recordsCount):
gmapRecord, newData = sstruct.unpack2(GMAPRecordFormat1, newData, GMAPRecord())
gmapRecord.name = gmapRecord.name.strip('\0')
self.gmapRecords.append(gmapRecord)
def compile(self, ttFont):
self.recordsCount = len(self.gmapRecords)
self.fontNameLength = len(self.psFontName)
self.recordsOffset = 4 * (((self.fontNameLength + 12) + 3) // 4)
data = sstruct.pack(GMAPFormat, self)
data = data + tobytes(self.psFontName)
data = data + b"\0" * (self.recordsOffset - len(data))
for record in self.gmapRecords:
data = data + record.compile(ttFont)
return data
def toXML(self, writer, ttFont):
writer.comment("Most of this table will be recalculated by the compiler")
writer.newline()
formatstring, names, fixes = sstruct.getformat(GMAPFormat)
for name in names:
value = getattr(self, name)
writer.simpletag(name, value=value)
writer.newline()
writer.simpletag("PSFontName", value=self.psFontName)
writer.newline()
for gmapRecord in self.gmapRecords:
gmapRecord.toXML(writer, ttFont)
def fromXML(self, name, attrs, content, ttFont):
if name == "GMAPRecord":
if not hasattr(self, "gmapRecords"):
self.gmapRecords = []
gmapRecord = GMAPRecord()
self.gmapRecords.append(gmapRecord)
for element in content:
if isinstance(element, basestring):
continue
name, attrs, content = element
gmapRecord.fromXML(name, attrs, content, ttFont)
else:
value = attrs["value"]
if name == "PSFontName":
self.psFontName = value
else:
setattr(self, name, safeEval(value))