Coverage for /usr/lib/python3/dist-packages/fontTools/ttLib/tables/V_O_R_G_.py: 14%

111 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1from fontTools.misc.textTools import bytesjoin, safeEval 

2from . import DefaultTable 

3import struct 

4 

5 

6class table_V_O_R_G_(DefaultTable.DefaultTable): 

7 

8 """This table is structured so that you can treat it like a dictionary keyed by glyph name. 

9 

10 ``ttFont['VORG'][<glyphName>]`` will return the vertical origin for any glyph. 

11 

12 ``ttFont['VORG'][<glyphName>] = <value>`` will set the vertical origin for any glyph. 

13 """ 

14 

15 def decompile(self, data, ttFont): 

16 self.getGlyphName = ( 

17 ttFont.getGlyphName 

18 ) # for use in get/set item functions, for access by GID 

19 ( 

20 self.majorVersion, 

21 self.minorVersion, 

22 self.defaultVertOriginY, 

23 self.numVertOriginYMetrics, 

24 ) = struct.unpack(">HHhH", data[:8]) 

25 assert ( 

26 self.majorVersion <= 1 

27 ), "Major version of VORG table is higher than I know how to handle" 

28 data = data[8:] 

29 vids = [] 

30 gids = [] 

31 pos = 0 

32 for i in range(self.numVertOriginYMetrics): 

33 gid, vOrigin = struct.unpack(">Hh", data[pos : pos + 4]) 

34 pos += 4 

35 gids.append(gid) 

36 vids.append(vOrigin) 

37 

38 self.VOriginRecords = vOrig = {} 

39 glyphOrder = ttFont.getGlyphOrder() 

40 try: 

41 names = [glyphOrder[gid] for gid in gids] 

42 except IndexError: 

43 getGlyphName = self.getGlyphName 

44 names = map(getGlyphName, gids) 

45 

46 for name, vid in zip(names, vids): 

47 vOrig[name] = vid 

48 

49 def compile(self, ttFont): 

50 vorgs = list(self.VOriginRecords.values()) 

51 names = list(self.VOriginRecords.keys()) 

52 nameMap = ttFont.getReverseGlyphMap() 

53 try: 

54 gids = [nameMap[name] for name in names] 

55 except KeyError: 

56 nameMap = ttFont.getReverseGlyphMap(rebuild=True) 

57 gids = [nameMap[name] for name in names] 

58 vOriginTable = list(zip(gids, vorgs)) 

59 self.numVertOriginYMetrics = len(vorgs) 

60 vOriginTable.sort() # must be in ascending GID order 

61 dataList = [struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable] 

62 header = struct.pack( 

63 ">HHhH", 

64 self.majorVersion, 

65 self.minorVersion, 

66 self.defaultVertOriginY, 

67 self.numVertOriginYMetrics, 

68 ) 

69 dataList.insert(0, header) 

70 data = bytesjoin(dataList) 

71 return data 

72 

73 def toXML(self, writer, ttFont): 

74 writer.simpletag("majorVersion", value=self.majorVersion) 

75 writer.newline() 

76 writer.simpletag("minorVersion", value=self.minorVersion) 

77 writer.newline() 

78 writer.simpletag("defaultVertOriginY", value=self.defaultVertOriginY) 

79 writer.newline() 

80 writer.simpletag("numVertOriginYMetrics", value=self.numVertOriginYMetrics) 

81 writer.newline() 

82 vOriginTable = [] 

83 glyphNames = self.VOriginRecords.keys() 

84 for glyphName in glyphNames: 

85 try: 

86 gid = ttFont.getGlyphID(glyphName) 

87 except: 

88 assert 0, ( 

89 "VORG table contains a glyph name not in ttFont.getGlyphNames(): " 

90 + str(glyphName) 

91 ) 

92 vOriginTable.append([gid, glyphName, self.VOriginRecords[glyphName]]) 

93 vOriginTable.sort() 

94 for entry in vOriginTable: 

95 vOriginRec = VOriginRecord(entry[1], entry[2]) 

96 vOriginRec.toXML(writer, ttFont) 

97 

98 def fromXML(self, name, attrs, content, ttFont): 

99 if not hasattr(self, "VOriginRecords"): 

100 self.VOriginRecords = {} 

101 self.getGlyphName = ( 

102 ttFont.getGlyphName 

103 ) # for use in get/set item functions, for access by GID 

104 if name == "VOriginRecord": 

105 vOriginRec = VOriginRecord() 

106 for element in content: 

107 if isinstance(element, str): 

108 continue 

109 name, attrs, content = element 

110 vOriginRec.fromXML(name, attrs, content, ttFont) 

111 self.VOriginRecords[vOriginRec.glyphName] = vOriginRec.vOrigin 

112 elif "value" in attrs: 

113 setattr(self, name, safeEval(attrs["value"])) 

114 

115 def __getitem__(self, glyphSelector): 

116 if isinstance(glyphSelector, int): 

117 # its a gid, convert to glyph name 

118 glyphSelector = self.getGlyphName(glyphSelector) 

119 

120 if glyphSelector not in self.VOriginRecords: 

121 return self.defaultVertOriginY 

122 

123 return self.VOriginRecords[glyphSelector] 

124 

125 def __setitem__(self, glyphSelector, value): 

126 if isinstance(glyphSelector, int): 

127 # its a gid, convert to glyph name 

128 glyphSelector = self.getGlyphName(glyphSelector) 

129 

130 if value != self.defaultVertOriginY: 

131 self.VOriginRecords[glyphSelector] = value 

132 elif glyphSelector in self.VOriginRecords: 

133 del self.VOriginRecords[glyphSelector] 

134 

135 def __delitem__(self, glyphSelector): 

136 del self.VOriginRecords[glyphSelector] 

137 

138 

139class VOriginRecord(object): 

140 def __init__(self, name=None, vOrigin=None): 

141 self.glyphName = name 

142 self.vOrigin = vOrigin 

143 

144 def toXML(self, writer, ttFont): 

145 writer.begintag("VOriginRecord") 

146 writer.newline() 

147 writer.simpletag("glyphName", value=self.glyphName) 

148 writer.newline() 

149 writer.simpletag("vOrigin", value=self.vOrigin) 

150 writer.newline() 

151 writer.endtag("VOriginRecord") 

152 writer.newline() 

153 

154 def fromXML(self, name, attrs, content, ttFont): 

155 value = attrs["value"] 

156 if name == "glyphName": 

157 setattr(self, name, value) 

158 else: 

159 setattr(self, name, safeEval(value))