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": 29 GMAPoffsets.byteswap() 30 self.GMAPs = [] 31 for i in range(self.numGMAPs): 32 start = GMAPoffsets[i] 33 end = GMAPoffsets[i+1] 34 self.GMAPs.append(data[start:end]) 35 pos = endPos 36 endPos = pos + (self.numGlyplets + 1)*4 37 glyphletOffsets = array.array("I") 38 glyphletOffsets.fromstring(newData[pos:endPos]) 39 if sys.byteorder != "big": 40 glyphletOffsets.byteswap() 41 self.glyphlets = [] 42 for i in range(self.numGlyplets): 43 start = glyphletOffsets[i] 44 end = glyphletOffsets[i+1] 45 self.glyphlets.append(data[start:end]) 46 47 48 def compile(self, ttFont): 49 self.numGMAPs = len(self.GMAPs) 50 self.numGlyplets = len(self.glyphlets) 51 GMAPoffsets = [0]*(self.numGMAPs + 1) 52 glyphletOffsets = [0]*(self.numGlyplets + 1) 53 54 dataList =[ sstruct.pack(GPKGFormat, self)] 55 56 pos = len(dataList[0]) + (self.numGMAPs + 1)*4 + (self.numGlyplets + 1)*4 57 GMAPoffsets[0] = pos 58 for i in range(1, self.numGMAPs +1): 59 pos += len(self.GMAPs[i-1]) 60 GMAPoffsets[i] = pos 61 gmapArray = array.array("I", GMAPoffsets) 62 if sys.byteorder != "big": 63 gmapArray.byteswap() 64 dataList.append(gmapArray.tostring()) 65 66 glyphletOffsets[0] = pos 67 for i in range(1, self.numGlyplets +1): 68 pos += len(self.glyphlets[i-1]) 69 glyphletOffsets[i] = pos 70 glyphletArray = array.array("I", glyphletOffsets) 71 if sys.byteorder != "big": 72 glyphletArray.byteswap() 73 dataList.append(glyphletArray.tostring()) 74 dataList += self.GMAPs 75 dataList += self.glyphlets 76 data = bytesjoin(dataList) 77 return data 78 79 def toXML(self, writer, ttFont): 80 writer.comment("Most of this table will be recalculated by the compiler") 81 writer.newline() 82 formatstring, names, fixes = sstruct.getformat(GPKGFormat) 83 for name in names: 84 value = getattr(self, name) 85 writer.simpletag(name, value=value) 86 writer.newline() 87 88 writer.begintag("GMAPs") 89 writer.newline() 90 for gmapData in self.GMAPs: 91 writer.begintag("hexdata") 92 writer.newline() 93 writer.dumphex(gmapData) 94 writer.endtag("hexdata") 95 writer.newline() 96 writer.endtag("GMAPs") 97 writer.newline() 98 99 writer.begintag("glyphlets") 100 writer.newline() 101 for glyphletData in self.glyphlets: 102 writer.begintag("hexdata") 103 writer.newline() 104 writer.dumphex(glyphletData) 105 writer.endtag("hexdata") 106 writer.newline() 107 writer.endtag("glyphlets") 108 writer.newline() 109 110 def fromXML(self, name, attrs, content, ttFont): 111 if name == "GMAPs": 112 if not hasattr(self, "GMAPs"): 113 self.GMAPs = [] 114 for element in content: 115 if isinstance(element, basestring): 116 continue 117 itemName, itemAttrs, itemContent = element 118 if itemName == "hexdata": 119 self.GMAPs.append(readHex(itemContent)) 120 elif name == "glyphlets": 121 if not hasattr(self, "glyphlets"): 122 self.glyphlets = [] 123 for element in content: 124 if isinstance(element, basestring): 125 continue 126 itemName, itemAttrs, itemContent = element 127 if itemName == "hexdata": 128 self.glyphlets.append(readHex(itemContent)) 129 else: 130 setattr(self, name, safeEval(value)) 131