1from __future__ import print_function, division, absolute_import 2from fontTools.misc.py23 import * 3from fontTools.misc import sstruct 4from fontTools.misc.textTools import safeEval, readHex 5from . import DefaultTable 6import sys 7import array 8 9GPKGFormat = """ 10 > # big endian 11 version: H 12 flags: H 13 numGMAPs: H 14 numGlyplets: H 15""" 16# psFontName is a byte string which follows the record above. This is zero padded 17# to the beginning of the records array. The recordsOffsst is 32 bit aligned. 18 19 20class table_G_P_K_G_(DefaultTable.DefaultTable): 21 22 def decompile(self, data, ttFont): 23 dummy, newData = sstruct.unpack2(GPKGFormat, data, self) 24 25 GMAPoffsets = array.array("I") 26 endPos = (self.numGMAPs+1) * 4 27 GMAPoffsets.fromstring(newData[:endPos]) 28 if sys.byteorder != "big": GMAPoffsets.byteswap() 29 self.GMAPs = [] 30 for i in range(self.numGMAPs): 31 start = GMAPoffsets[i] 32 end = GMAPoffsets[i+1] 33 self.GMAPs.append(data[start:end]) 34 pos = endPos 35 endPos = pos + (self.numGlyplets + 1)*4 36 glyphletOffsets = array.array("I") 37 glyphletOffsets.fromstring(newData[pos:endPos]) 38 if sys.byteorder != "big": glyphletOffsets.byteswap() 39 self.glyphlets = [] 40 for i in range(self.numGlyplets): 41 start = glyphletOffsets[i] 42 end = glyphletOffsets[i+1] 43 self.glyphlets.append(data[start:end]) 44 45 def compile(self, ttFont): 46 self.numGMAPs = len(self.GMAPs) 47 self.numGlyplets = len(self.glyphlets) 48 GMAPoffsets = [0]*(self.numGMAPs + 1) 49 glyphletOffsets = [0]*(self.numGlyplets + 1) 50 51 dataList =[ sstruct.pack(GPKGFormat, self)] 52 53 pos = len(dataList[0]) + (self.numGMAPs + 1)*4 + (self.numGlyplets + 1)*4 54 GMAPoffsets[0] = pos 55 for i in range(1, self.numGMAPs +1): 56 pos += len(self.GMAPs[i-1]) 57 GMAPoffsets[i] = pos 58 gmapArray = array.array("I", GMAPoffsets) 59 if sys.byteorder != "big": gmapArray.byteswap() 60 dataList.append(gmapArray.tostring()) 61 62 glyphletOffsets[0] = pos 63 for i in range(1, self.numGlyplets +1): 64 pos += len(self.glyphlets[i-1]) 65 glyphletOffsets[i] = pos 66 glyphletArray = array.array("I", glyphletOffsets) 67 if sys.byteorder != "big": glyphletArray.byteswap() 68 dataList.append(glyphletArray.tostring()) 69 dataList += self.GMAPs 70 dataList += self.glyphlets 71 data = bytesjoin(dataList) 72 return data 73 74 def toXML(self, writer, ttFont): 75 writer.comment("Most of this table will be recalculated by the compiler") 76 writer.newline() 77 formatstring, names, fixes = sstruct.getformat(GPKGFormat) 78 for name in names: 79 value = getattr(self, name) 80 writer.simpletag(name, value=value) 81 writer.newline() 82 83 writer.begintag("GMAPs") 84 writer.newline() 85 for gmapData in self.GMAPs: 86 writer.begintag("hexdata") 87 writer.newline() 88 writer.dumphex(gmapData) 89 writer.endtag("hexdata") 90 writer.newline() 91 writer.endtag("GMAPs") 92 writer.newline() 93 94 writer.begintag("glyphlets") 95 writer.newline() 96 for glyphletData in self.glyphlets: 97 writer.begintag("hexdata") 98 writer.newline() 99 writer.dumphex(glyphletData) 100 writer.endtag("hexdata") 101 writer.newline() 102 writer.endtag("glyphlets") 103 writer.newline() 104 105 def fromXML(self, name, attrs, content, ttFont): 106 if name == "GMAPs": 107 if not hasattr(self, "GMAPs"): 108 self.GMAPs = [] 109 for element in content: 110 if isinstance(element, basestring): 111 continue 112 itemName, itemAttrs, itemContent = element 113 if itemName == "hexdata": 114 self.GMAPs.append(readHex(itemContent)) 115 elif name == "glyphlets": 116 if not hasattr(self, "glyphlets"): 117 self.glyphlets = [] 118 for element in content: 119 if isinstance(element, basestring): 120 continue 121 itemName, itemAttrs, itemContent = element 122 if itemName == "hexdata": 123 self.glyphlets.append(readHex(itemContent)) 124 else: 125 setattr(self, name, safeEval(attrs["value"])) 126