G_M_A_P_.py revision b774f9f684c5a0f91f5fa177c9a461968789123f
1from . import DefaultTable 2from fontTools.misc import sstruct 3from fontTools.misc.textTools import safeEval, num2binary, binary2num 4 5GMAPFormat = """ 6 > # big endian 7 tableVersionMajor: H 8 tableVersionMinor: H 9 flags: H 10 recordsCount: H 11 recordsOffset: H 12 fontNameLength: H 13""" 14# psFontName is a byte string which follows the record above. This is zero padded 15# to the beginning of the records array. The recordsOffsst is 32 bit aligned. 16 17GMAPRecordFormat1 = """ 18 > # big endian 19 UV: L 20 cid: H 21 gid: H 22 ggid: H 23 name: 32s 24""" 25 26 27 28class GMAPRecord: 29 def __init__(self, uv = 0, cid = 0, gid = 0, ggid = 0, name = ""): 30 self.UV = uv 31 self.cid = cid 32 self.gid = gid 33 self.ggid = ggid 34 self.name = name 35 36 def toXML(self, writer, ttFont): 37 writer.begintag("GMAPRecord") 38 writer.newline() 39 writer.simpletag("UV", value=self.UV) 40 writer.newline() 41 writer.simpletag("cid", value=self.cid) 42 writer.newline() 43 writer.simpletag("gid", value=self.gid) 44 writer.newline() 45 writer.simpletag("glyphletGid", value=self.gid) 46 writer.newline() 47 writer.simpletag("GlyphletName", value=self.name) 48 writer.newline() 49 writer.endtag("GMAPRecord") 50 writer.newline() 51 52 53 def fromXML(self, name, attrs, content, ttFont): 54 value = attrs["value"] 55 if name == "GlyphletName": 56 self.name = value 57 else: 58 setattr(self, name, safeEval(value)) 59 60 61 def compile(self, ttFont): 62 if self.UV == None: 63 self.UV = 0 64 nameLen = len(self.name) 65 if nameLen < 32: 66 self.name = self.name + "\0"*(32 - nameLen) 67 data = sstruct.pack(GMAPRecordFormat1, self) 68 return data 69 70 def __repr__(self): 71 return "GMAPRecord[ UV: " + str(self.UV) + ", cid: " + str(self.cid) + ", gid: " + str(self.gid) + ", ggid: " + str(self.ggid) + ", Glyphlet Name: " + str(self.name) + " ]" 72 73 74class table_G_M_A_P_(DefaultTable.DefaultTable): 75 76 dependencies = [] 77 78 def decompile(self, data, ttFont): 79 dummy, newData = sstruct.unpack2(GMAPFormat, data, self) 80 self.psFontName = newData[:self.fontNameLength] 81 assert (self.recordsOffset % 4) == 0, "GMAP error: recordsOffset is not 32 bit aligned." 82 newData = data[self.recordsOffset:] 83 self.gmapRecords = [] 84 for i in range (self.recordsCount): 85 gmapRecord, newData = sstruct.unpack2(GMAPRecordFormat1, newData, GMAPRecord()) 86 gmapRecord.name = gmapRecord.name.strip('\0') 87 self.gmapRecords.append(gmapRecord) 88 89 90 def compile(self, ttFont): 91 self.recordsCount = len(self.gmapRecords) 92 self.fontNameLength = len(self.psFontName) 93 self.recordsOffset = 4 *(((self.fontNameLength + 12) + 3) /4) 94 data = sstruct.pack(GMAPFormat, self) 95 data = data + self.psFontName 96 data = data + "\0" * (self.recordsOffset - len(data)) 97 for record in self.gmapRecords: 98 data = data + record.compile(ttFont) 99 return data 100 101 102 def toXML(self, writer, ttFont): 103 writer.comment("Most of this table will be recalculated by the compiler") 104 writer.newline() 105 formatstring, names, fixes = sstruct.getformat(GMAPFormat) 106 for name in names: 107 value = getattr(self, name) 108 writer.simpletag(name, value=value) 109 writer.newline() 110 writer.simpletag("PSFontName", value=self.psFontName) 111 writer.newline() 112 for gmapRecord in self.gmapRecords: 113 gmapRecord.toXML(writer, ttFont) 114 115 def fromXML(self, name, attrs, content, ttFont): 116 if name == "GMAPRecord": 117 if not hasattr(self, "gmapRecords"): 118 self.gmapRecords = [] 119 gmapRecord = GMAPRecord() 120 self.gmapRecords.append(gmapRecord) 121 for element in content: 122 if isinstance(element, str): 123 continue 124 name, attrs, content = element 125 gmapRecord.fromXML(name, attrs, content, ttFont) 126 else: 127 value = attrs["value"] 128 if name == "PSFontName": 129 self.psFontName = value 130 else: 131 setattr(self, name, safeEval(value)) 132