123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- from fontTools.misc import sstruct
- from fontTools.misc.textTools import tobytes, tostr, 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, str):
- 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))
|