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".
140 lines
3.8 KiB
Python
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)
|