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

101 statements  

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

1from fontTools.misc import sstruct 

2from fontTools.misc.textTools import safeEval 

3from . import DefaultTable 

4 

5maxpFormat_0_5 = """ 

6 > # big endian 

7 tableVersion: i 

8 numGlyphs: H 

9""" 

10 

11maxpFormat_1_0_add = """ 

12 > # big endian 

13 maxPoints: H 

14 maxContours: H 

15 maxCompositePoints: H 

16 maxCompositeContours: H 

17 maxZones: H 

18 maxTwilightPoints: H 

19 maxStorage: H 

20 maxFunctionDefs: H 

21 maxInstructionDefs: H 

22 maxStackElements: H 

23 maxSizeOfInstructions: H 

24 maxComponentElements: H 

25 maxComponentDepth: H 

26""" 

27 

28 

29class table__m_a_x_p(DefaultTable.DefaultTable): 

30 dependencies = ["glyf"] 

31 

32 def decompile(self, data, ttFont): 

33 dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self) 

34 self.numGlyphs = int(self.numGlyphs) 

35 if self.tableVersion != 0x00005000: 

36 dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self) 

37 assert len(data) == 0 

38 

39 def compile(self, ttFont): 

40 if "glyf" in ttFont: 

41 if ttFont.isLoaded("glyf") and ttFont.recalcBBoxes: 

42 self.recalc(ttFont) 

43 else: 

44 pass # CFF 

45 self.numGlyphs = len(ttFont.getGlyphOrder()) 

46 if self.tableVersion != 0x00005000: 

47 self.tableVersion = 0x00010000 

48 data = sstruct.pack(maxpFormat_0_5, self) 

49 if self.tableVersion == 0x00010000: 

50 data = data + sstruct.pack(maxpFormat_1_0_add, self) 

51 return data 

52 

53 def recalc(self, ttFont): 

54 """Recalculate the font bounding box, and most other maxp values except 

55 for the TT instructions values. Also recalculate the value of bit 1 

56 of the flags field and the font bounding box of the 'head' table. 

57 """ 

58 glyfTable = ttFont["glyf"] 

59 hmtxTable = ttFont["hmtx"] 

60 headTable = ttFont["head"] 

61 self.numGlyphs = len(glyfTable) 

62 INFINITY = 100000 

63 xMin = +INFINITY 

64 yMin = +INFINITY 

65 xMax = -INFINITY 

66 yMax = -INFINITY 

67 maxPoints = 0 

68 maxContours = 0 

69 maxCompositePoints = 0 

70 maxCompositeContours = 0 

71 maxComponentElements = 0 

72 maxComponentDepth = 0 

73 allXMinIsLsb = 1 

74 for glyphName in ttFont.getGlyphOrder(): 

75 g = glyfTable[glyphName] 

76 if g.numberOfContours: 

77 if hmtxTable[glyphName][1] != g.xMin: 

78 allXMinIsLsb = 0 

79 xMin = min(xMin, g.xMin) 

80 yMin = min(yMin, g.yMin) 

81 xMax = max(xMax, g.xMax) 

82 yMax = max(yMax, g.yMax) 

83 if g.numberOfContours > 0: 

84 nPoints, nContours = g.getMaxpValues() 

85 maxPoints = max(maxPoints, nPoints) 

86 maxContours = max(maxContours, nContours) 

87 elif g.isComposite(): 

88 nPoints, nContours, componentDepth = g.getCompositeMaxpValues( 

89 glyfTable 

90 ) 

91 maxCompositePoints = max(maxCompositePoints, nPoints) 

92 maxCompositeContours = max(maxCompositeContours, nContours) 

93 maxComponentElements = max(maxComponentElements, len(g.components)) 

94 maxComponentDepth = max(maxComponentDepth, componentDepth) 

95 if xMin == +INFINITY: 

96 headTable.xMin = 0 

97 headTable.yMin = 0 

98 headTable.xMax = 0 

99 headTable.yMax = 0 

100 else: 

101 headTable.xMin = xMin 

102 headTable.yMin = yMin 

103 headTable.xMax = xMax 

104 headTable.yMax = yMax 

105 self.maxPoints = maxPoints 

106 self.maxContours = maxContours 

107 self.maxCompositePoints = maxCompositePoints 

108 self.maxCompositeContours = maxCompositeContours 

109 self.maxComponentElements = maxComponentElements 

110 self.maxComponentDepth = maxComponentDepth 

111 if allXMinIsLsb: 

112 headTable.flags = headTable.flags | 0x2 

113 else: 

114 headTable.flags = headTable.flags & ~0x2 

115 

116 def testrepr(self): 

117 items = sorted(self.__dict__.items()) 

118 print(". . . . . . . . .") 

119 for combo in items: 

120 print(" %s: %s" % combo) 

121 print(". . . . . . . . .") 

122 

123 def toXML(self, writer, ttFont): 

124 if self.tableVersion != 0x00005000: 

125 writer.comment("Most of this table will be recalculated by the compiler") 

126 writer.newline() 

127 formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5) 

128 if self.tableVersion != 0x00005000: 

129 formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add) 

130 names = names + names_1_0 

131 for name in names: 

132 value = getattr(self, name) 

133 if name == "tableVersion": 

134 value = hex(value) 

135 writer.simpletag(name, value=value) 

136 writer.newline() 

137 

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

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