2014-01-14 15:07:50 +08:00
|
|
|
from __future__ import print_function, division, absolute_import
|
2013-11-27 17:27:45 -05:00
|
|
|
from fontTools.misc.py23 import *
|
2013-09-17 16:59:39 -04:00
|
|
|
from fontTools.misc import sstruct
|
2013-11-27 15:16:28 -05:00
|
|
|
from fontTools.misc.textTools import safeEval
|
2013-11-27 17:27:45 -05:00
|
|
|
from . import DefaultTable
|
2006-10-21 13:27:25 +00:00
|
|
|
|
|
|
|
GMAPFormat = """
|
|
|
|
> # big endian
|
|
|
|
tableVersionMajor: H
|
|
|
|
tableVersionMinor: H
|
|
|
|
flags: H
|
|
|
|
recordsCount: H
|
|
|
|
recordsOffset: H
|
|
|
|
fontNameLength: H
|
|
|
|
"""
|
2015-04-26 02:01:01 -04:00
|
|
|
# psFontName is a byte string which follows the record above. This is zero padded
|
2006-10-21 13:27:25 +00:00
|
|
|
# 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
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2013-11-28 14:26:58 -05:00
|
|
|
class GMAPRecord(object):
|
2015-04-26 00:54:30 -04:00
|
|
|
def __init__(self, uv=0, cid=0, gid=0, ggid=0, name=""):
|
2006-10-21 13:27:25 +00:00
|
|
|
self.UV = uv
|
|
|
|
self.cid = cid
|
|
|
|
self.gid = gid
|
|
|
|
self.ggid = ggid
|
|
|
|
self.name = name
|
2015-04-26 00:54:30 -04:00
|
|
|
|
2006-10-21 13:27:25 +00:00
|
|
|
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()
|
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, name, attrs, content, ttFont):
|
2006-10-21 13:27:25 +00:00
|
|
|
value = attrs["value"]
|
|
|
|
if name == "GlyphletName":
|
|
|
|
self.name = value
|
|
|
|
else:
|
2013-11-27 04:00:15 -05:00
|
|
|
setattr(self, name, safeEval(value))
|
2006-10-21 13:27:25 +00:00
|
|
|
|
|
|
|
def compile(self, ttFont):
|
2013-12-04 16:31:44 -05:00
|
|
|
if self.UV is None:
|
2006-10-21 13:27:25 +00:00
|
|
|
self.UV = 0
|
2015-04-26 00:15:26 -04:00
|
|
|
nameLen = len(self.name)
|
2006-10-21 13:27:25 +00:00
|
|
|
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):
|
2015-04-26 02:01:01 -04:00
|
|
|
|
2006-10-21 13:27:25 +00:00
|
|
|
dependencies = []
|
2015-04-26 02:01:01 -04:00
|
|
|
|
2006-10-21 13:27:25 +00:00
|
|
|
def decompile(self, data, ttFont):
|
|
|
|
dummy, newData = sstruct.unpack2(GMAPFormat, data, self)
|
2013-11-28 06:43:47 -05:00
|
|
|
self.psFontName = tostr(newData[:self.fontNameLength])
|
2006-10-21 13:27:25 +00:00
|
|
|
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)
|
2015-04-26 00:15:26 -04:00
|
|
|
self.recordsOffset = 4 * (((self.fontNameLength + 12) + 3) // 4)
|
2006-10-21 13:27:25 +00:00
|
|
|
data = sstruct.pack(GMAPFormat, self)
|
2013-11-28 06:43:47 -05:00
|
|
|
data = data + tobytes(self.psFontName)
|
|
|
|
data = data + b"\0" * (self.recordsOffset - len(data))
|
2006-10-21 13:27:25 +00:00
|
|
|
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)
|
2015-04-26 02:01:01 -04:00
|
|
|
|
2013-11-27 03:19:32 -05:00
|
|
|
def fromXML(self, name, attrs, content, ttFont):
|
2006-10-21 13:27:25 +00:00
|
|
|
if name == "GMAPRecord":
|
|
|
|
if not hasattr(self, "gmapRecords"):
|
|
|
|
self.gmapRecords = []
|
|
|
|
gmapRecord = GMAPRecord()
|
|
|
|
self.gmapRecords.append(gmapRecord)
|
|
|
|
for element in content:
|
2013-11-27 23:37:57 -05:00
|
|
|
if isinstance(element, basestring):
|
2006-10-21 13:27:25 +00:00
|
|
|
continue
|
2013-11-27 03:19:32 -05:00
|
|
|
name, attrs, content = element
|
|
|
|
gmapRecord.fromXML(name, attrs, content, ttFont)
|
2006-10-21 13:27:25 +00:00
|
|
|
else:
|
|
|
|
value = attrs["value"]
|
|
|
|
if name == "PSFontName":
|
|
|
|
self.psFontName = value
|
2015-04-26 02:01:01 -04:00
|
|
|
else:
|
2013-11-27 04:00:15 -05:00
|
|
|
setattr(self, name, safeEval(value))
|