Behdad Esfahbod 8413c108d2 Move sstruct under fontTools.misc
Our footprint in the Python module namespace is all under
fontTools now.  User code importing sstruct should be updated
to say "from fontTools.misc import sstruct".
2013-09-17 16:59:39 -04:00

140 lines
3.8 KiB
Python

import DefaultTable
from fontTools.misc import sstruct
from types import StringType
from fontTools.misc.textTools import safeEval, num2binary, binary2num
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:
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:
try:
value = safeEval(value)
except OverflowError:
value = long(value)
setattr(self, name, value)
def compile(self, ttFont):
if self.UV == 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 = 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 + self.psFontName
data = data + "\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, StringType):
continue
gmapRecord.fromXML(element, ttFont)
else:
value = attrs["value"]
if name == "PSFontName":
self.psFontName = value
else:
try:
value = safeEval(value)
except OverflowError:
value = long(value)
setattr(self, name, value)