Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/fontTools/ttLib/ttCollection.py: 24%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

74 statements  

1from fontTools.ttLib.ttFont import TTFont 

2from fontTools.ttLib.sfnt import readTTCHeader, writeTTCHeader 

3from io import BytesIO 

4import struct 

5import logging 

6 

7log = logging.getLogger(__name__) 

8 

9 

10class TTCollection(object): 

11 """Object representing a TrueType Collection / OpenType Collection. 

12 The main API is self.fonts being a list of TTFont instances. 

13 

14 If shareTables is True, then different fonts in the collection 

15 might point to the same table object if the data for the table was 

16 the same in the font file. Note, however, that this might result 

17 in suprises and incorrect behavior if the different fonts involved 

18 have different GlyphOrder. Use only if you know what you are doing. 

19 """ 

20 

21 def __init__(self, file=None, shareTables=False, **kwargs): 

22 fonts = self.fonts = [] 

23 if file is None: 

24 return 

25 

26 assert "fontNumber" not in kwargs, kwargs 

27 

28 closeStream = False 

29 if not hasattr(file, "read"): 

30 file = open(file, "rb") 

31 closeStream = True 

32 

33 tableCache = {} if shareTables else None 

34 

35 header = readTTCHeader(file) 

36 for i in range(header.numFonts): 

37 font = TTFont(file, fontNumber=i, _tableCache=tableCache, **kwargs) 

38 fonts.append(font) 

39 

40 # don't close file if lazy=True, as the TTFont hold a reference to the original 

41 # file; the file will be closed once the TTFonts are closed in the 

42 # TTCollection.close(). We still want to close the file if lazy is None or 

43 # False, because in that case the TTFont no longer need the original file 

44 # and we want to avoid 'ResourceWarning: unclosed file'. 

45 if not kwargs.get("lazy") and closeStream: 

46 file.close() 

47 

48 def __enter__(self): 

49 return self 

50 

51 def __exit__(self, type, value, traceback): 

52 self.close() 

53 

54 def close(self): 

55 for font in self.fonts: 

56 font.close() 

57 

58 def save(self, file, shareTables=True): 

59 """Save the font to disk. Similarly to the constructor, 

60 the 'file' argument can be either a pathname or a writable 

61 file object. 

62 """ 

63 if not hasattr(file, "write"): 

64 final = None 

65 file = open(file, "wb") 

66 else: 

67 # assume "file" is a writable file object 

68 # write to a temporary stream to allow saving to unseekable streams 

69 final = file 

70 file = BytesIO() 

71 

72 tableCache = {} if shareTables else None 

73 

74 offsets_offset = writeTTCHeader(file, len(self.fonts)) 

75 offsets = [] 

76 for font in self.fonts: 

77 offsets.append(file.tell()) 

78 font._save(file, tableCache=tableCache) 

79 file.seek(0, 2) 

80 

81 file.seek(offsets_offset) 

82 file.write(struct.pack(">%dL" % len(self.fonts), *offsets)) 

83 

84 if final: 

85 final.write(file.getvalue()) 

86 file.close() 

87 

88 def saveXML(self, fileOrPath, newlinestr="\n", writeVersion=True, **kwargs): 

89 from fontTools.misc import xmlWriter 

90 

91 writer = xmlWriter.XMLWriter(fileOrPath, newlinestr=newlinestr) 

92 

93 if writeVersion: 

94 from fontTools import version 

95 

96 version = ".".join(version.split(".")[:2]) 

97 writer.begintag("ttCollection", ttLibVersion=version) 

98 else: 

99 writer.begintag("ttCollection") 

100 writer.newline() 

101 writer.newline() 

102 

103 for font in self.fonts: 

104 font._saveXML(writer, writeVersion=False, **kwargs) 

105 writer.newline() 

106 

107 writer.endtag("ttCollection") 

108 writer.newline() 

109 

110 writer.close() 

111 

112 def __getitem__(self, item): 

113 return self.fonts[item] 

114 

115 def __setitem__(self, item, value): 

116 self.fonts[item] = value 

117 

118 def __delitem__(self, item): 

119 return self.fonts[item] 

120 

121 def __len__(self): 

122 return len(self.fonts) 

123 

124 def __iter__(self): 

125 return iter(self.fonts)