123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- from fontTools.misc import sstruct
- from fontTools.misc.textTools import bytesjoin, safeEval, readHex
- from . import DefaultTable
- import sys
- import array
- GPKGFormat = """
- > # big endian
- version: H
- flags: H
- numGMAPs: H
- numGlyplets: 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.
- class table_G_P_K_G_(DefaultTable.DefaultTable):
- def decompile(self, data, ttFont):
- dummy, newData = sstruct.unpack2(GPKGFormat, data, self)
- GMAPoffsets = array.array("I")
- endPos = (self.numGMAPs + 1) * 4
- GMAPoffsets.frombytes(newData[:endPos])
- if sys.byteorder != "big":
- GMAPoffsets.byteswap()
- self.GMAPs = []
- for i in range(self.numGMAPs):
- start = GMAPoffsets[i]
- end = GMAPoffsets[i + 1]
- self.GMAPs.append(data[start:end])
- pos = endPos
- endPos = pos + (self.numGlyplets + 1) * 4
- glyphletOffsets = array.array("I")
- glyphletOffsets.frombytes(newData[pos:endPos])
- if sys.byteorder != "big":
- glyphletOffsets.byteswap()
- self.glyphlets = []
- for i in range(self.numGlyplets):
- start = glyphletOffsets[i]
- end = glyphletOffsets[i + 1]
- self.glyphlets.append(data[start:end])
- def compile(self, ttFont):
- self.numGMAPs = len(self.GMAPs)
- self.numGlyplets = len(self.glyphlets)
- GMAPoffsets = [0] * (self.numGMAPs + 1)
- glyphletOffsets = [0] * (self.numGlyplets + 1)
- dataList = [sstruct.pack(GPKGFormat, self)]
- pos = len(dataList[0]) + (self.numGMAPs + 1) * 4 + (self.numGlyplets + 1) * 4
- GMAPoffsets[0] = pos
- for i in range(1, self.numGMAPs + 1):
- pos += len(self.GMAPs[i - 1])
- GMAPoffsets[i] = pos
- gmapArray = array.array("I", GMAPoffsets)
- if sys.byteorder != "big":
- gmapArray.byteswap()
- dataList.append(gmapArray.tobytes())
- glyphletOffsets[0] = pos
- for i in range(1, self.numGlyplets + 1):
- pos += len(self.glyphlets[i - 1])
- glyphletOffsets[i] = pos
- glyphletArray = array.array("I", glyphletOffsets)
- if sys.byteorder != "big":
- glyphletArray.byteswap()
- dataList.append(glyphletArray.tobytes())
- dataList += self.GMAPs
- dataList += self.glyphlets
- data = bytesjoin(dataList)
- 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(GPKGFormat)
- for name in names:
- value = getattr(self, name)
- writer.simpletag(name, value=value)
- writer.newline()
- writer.begintag("GMAPs")
- writer.newline()
- for gmapData in self.GMAPs:
- writer.begintag("hexdata")
- writer.newline()
- writer.dumphex(gmapData)
- writer.endtag("hexdata")
- writer.newline()
- writer.endtag("GMAPs")
- writer.newline()
- writer.begintag("glyphlets")
- writer.newline()
- for glyphletData in self.glyphlets:
- writer.begintag("hexdata")
- writer.newline()
- writer.dumphex(glyphletData)
- writer.endtag("hexdata")
- writer.newline()
- writer.endtag("glyphlets")
- writer.newline()
- def fromXML(self, name, attrs, content, ttFont):
- if name == "GMAPs":
- if not hasattr(self, "GMAPs"):
- self.GMAPs = []
- for element in content:
- if isinstance(element, str):
- continue
- itemName, itemAttrs, itemContent = element
- if itemName == "hexdata":
- self.GMAPs.append(readHex(itemContent))
- elif name == "glyphlets":
- if not hasattr(self, "glyphlets"):
- self.glyphlets = []
- for element in content:
- if isinstance(element, str):
- continue
- itemName, itemAttrs, itemContent = element
- if itemName == "hexdata":
- self.glyphlets.append(readHex(itemContent))
- else:
- setattr(self, name, safeEval(attrs["value"]))
|