11ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 230e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import * 38413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbodfrom fontTools.misc import sstruct 47842e56b97ce677b83bdab09cda48bc2d89ac75aJustfrom fontTools.misc.textTools import safeEval, num2binary, binary2num 530e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom . import DefaultTable 6b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbodimport warnings 722dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvr 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust 97842e56b97ce677b83bdab09cda48bc2d89ac75aJust# panose classification 107842e56b97ce677b83bdab09cda48bc2d89ac75aJust 117842e56b97ce677b83bdab09cda48bc2d89ac75aJustpanoseFormat = """ 12859967e5218bed974d05ddec93996b9aea2782a5Just bFamilyType: B 13859967e5218bed974d05ddec93996b9aea2782a5Just bSerifStyle: B 14859967e5218bed974d05ddec93996b9aea2782a5Just bWeight: B 15859967e5218bed974d05ddec93996b9aea2782a5Just bProportion: B 16859967e5218bed974d05ddec93996b9aea2782a5Just bContrast: B 17859967e5218bed974d05ddec93996b9aea2782a5Just bStrokeVariation: B 18859967e5218bed974d05ddec93996b9aea2782a5Just bArmStyle: B 19859967e5218bed974d05ddec93996b9aea2782a5Just bLetterForm: B 20859967e5218bed974d05ddec93996b9aea2782a5Just bMidline: B 21859967e5218bed974d05ddec93996b9aea2782a5Just bXHeight: B 227842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 237842e56b97ce677b83bdab09cda48bc2d89ac75aJust 24e388db566b9ba42669c7e353db4293cf27bc2a5bBehdad Esfahbodclass Panose(object): 257842e56b97ce677b83bdab09cda48bc2d89ac75aJust 267842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, writer, ttFont): 277842e56b97ce677b83bdab09cda48bc2d89ac75aJust formatstring, names, fixes = sstruct.getformat(panoseFormat) 287842e56b97ce677b83bdab09cda48bc2d89ac75aJust for name in names: 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=getattr(self, name)) 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 317842e56b97ce677b83bdab09cda48bc2d89ac75aJust 323a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content, ttFont): 337842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval(attrs["value"])) 347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 367842e56b97ce677b83bdab09cda48bc2d89ac75aJust# 'sfnt' OS/2 and Windows Metrics table - 'OS/2' 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 387842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_0 = """ 39859967e5218bed974d05ddec93996b9aea2782a5Just > # big endian 40859967e5218bed974d05ddec93996b9aea2782a5Just version: H # version 41859967e5218bed974d05ddec93996b9aea2782a5Just xAvgCharWidth: h # average character width 42859967e5218bed974d05ddec93996b9aea2782a5Just usWeightClass: H # degree of thickness of strokes 43859967e5218bed974d05ddec93996b9aea2782a5Just usWidthClass: H # aspect ratio 44859967e5218bed974d05ddec93996b9aea2782a5Just fsType: h # type flags 45859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptXSize: h # subscript horizontal font size 46859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptYSize: h # subscript vertical font size 47859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptXOffset: h # subscript x offset 48859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptYOffset: h # subscript y offset 49859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptXSize: h # superscript horizontal font size 50859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptYSize: h # superscript vertical font size 51859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptXOffset: h # superscript x offset 52859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptYOffset: h # superscript y offset 53859967e5218bed974d05ddec93996b9aea2782a5Just yStrikeoutSize: h # strikeout size 54859967e5218bed974d05ddec93996b9aea2782a5Just yStrikeoutPosition: h # strikeout position 55859967e5218bed974d05ddec93996b9aea2782a5Just sFamilyClass: h # font family class and subclass 56859967e5218bed974d05ddec93996b9aea2782a5Just panose: 10s # panose classification number 5704985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange1: L # character range 5804985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange2: L # character range 5904985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange3: L # character range 6004985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange4: L # character range 61859967e5218bed974d05ddec93996b9aea2782a5Just achVendID: 4s # font vendor identification 62859967e5218bed974d05ddec93996b9aea2782a5Just fsSelection: H # font selection flags 63859967e5218bed974d05ddec93996b9aea2782a5Just fsFirstCharIndex: H # first unicode character index 64859967e5218bed974d05ddec93996b9aea2782a5Just fsLastCharIndex: H # last unicode character index 656146b084c29234a873c31e3bfaee5df2d015e63ajvr sTypoAscender: h # typographic ascender 666146b084c29234a873c31e3bfaee5df2d015e63ajvr sTypoDescender: h # typographic descender 676146b084c29234a873c31e3bfaee5df2d015e63ajvr sTypoLineGap: h # typographic line gap 68859967e5218bed974d05ddec93996b9aea2782a5Just usWinAscent: H # Windows ascender 69859967e5218bed974d05ddec93996b9aea2782a5Just usWinDescent: H # Windows descender 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust 727842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_1_addition = """ 7304985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulCodePageRange1: L 7404985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulCodePageRange2: L 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust 777842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_2_addition = OS2_format_1_addition + """ 78859967e5218bed974d05ddec93996b9aea2782a5Just sxHeight: h 79859967e5218bed974d05ddec93996b9aea2782a5Just sCapHeight: h 80859967e5218bed974d05ddec93996b9aea2782a5Just usDefaultChar: H 81859967e5218bed974d05ddec93996b9aea2782a5Just usBreakChar: H 82859967e5218bed974d05ddec93996b9aea2782a5Just usMaxContex: H 837842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 847842e56b97ce677b83bdab09cda48bc2d89ac75aJust 85aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier BertenOS2_format_5_addition = OS2_format_2_addition + """ 86aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten usLowerOpticalPointSize: H 87aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten usUpperOpticalPointSize: H 88aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten""" 89aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten 907842e56b97ce677b83bdab09cda48bc2d89ac75aJustbigendian = " > # big endian\n" 917842e56b97ce677b83bdab09cda48bc2d89ac75aJust 927842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_1 = OS2_format_0 + OS2_format_1_addition 937842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_2 = OS2_format_0 + OS2_format_2_addition 94aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier BertenOS2_format_5 = OS2_format_0 + OS2_format_5_addition 957842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_1_addition = bigendian + OS2_format_1_addition 967842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_2_addition = bigendian + OS2_format_2_addition 97aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier BertenOS2_format_5_addition = bigendian + OS2_format_5_addition 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table_O_S_2f_2(DefaultTable.DefaultTable): 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust """the OS/2 table""" 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data, ttFont): 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust dummy, data = sstruct.unpack2(OS2_format_0, data, self) 106b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.version == 1: 108b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod dummy, data = sstruct.unpack2(OS2_format_1_addition, data, self) 1094acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr elif self.version in (2, 3, 4): 110b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod dummy, data = sstruct.unpack2(OS2_format_2_addition, data, self) 111aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten elif self.version == 5: 112b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod dummy, data = sstruct.unpack2(OS2_format_5_addition, data, self) 11332c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.usLowerOpticalPointSize /= 20 11432c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.usUpperOpticalPointSize /= 20 115180ace6a5ff1399ec53bc696e8bef7cce6eef39aBehdad Esfahbod elif self.version != 0: 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust from fontTools import ttLib 117cd5aad92f23737ff93a110d5c73d624658a28da8Behdad Esfahbod raise ttLib.TTLibError("unknown format for OS/2 table: version %s" % self.version) 118b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod if len(data): 119f1e8c3e8a0bd12858e1ab361973c286eb7cad30aBehdad Esfahbod warnings.warn("too much 'OS/2' table data") 120b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod 1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = sstruct.unpack(panoseFormat, self.panose, Panose()) 1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def compile(self, ttFont): 1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust panose = self.panose 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = sstruct.pack(panoseFormat, self.panose) 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.version == 0: 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(OS2_format_0, self) 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif self.version == 1: 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(OS2_format_1, self) 1304acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr elif self.version in (2, 3, 4): 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(OS2_format_2, self) 132aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten elif self.version == 5: 133862b14722fd80a9cacf0fa7666da570fc4f4be56Behdad Esfahbod d = self.__dict__.copy() 134862b14722fd80a9cacf0fa7666da570fc4f4be56Behdad Esfahbod d['usLowerOpticalPointSize'] = int(round(self.usLowerOpticalPointSize * 20)) 135862b14722fd80a9cacf0fa7666da570fc4f4be56Behdad Esfahbod d['usUpperOpticalPointSize'] = int(round(self.usUpperOpticalPointSize * 20)) 136862b14722fd80a9cacf0fa7666da570fc4f4be56Behdad Esfahbod data = sstruct.pack(OS2_format_5, d) 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust from fontTools import ttLib 139cd5aad92f23737ff93a110d5c73d624658a28da8Behdad Esfahbod raise ttLib.TTLibError("unknown format for OS/2 table: version %s" % self.version) 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = panose 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust return data 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, writer, ttFont): 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.version == 1: 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = OS2_format_1 1464acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr elif self.version in (2, 3, 4): 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = OS2_format_2 148aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten elif self.version == 5: 149aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten format = OS2_format_5 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1517842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = OS2_format_0 1527842e56b97ce677b83bdab09cda48bc2d89ac75aJust formatstring, names, fixes = sstruct.getformat(format) 1537842e56b97ce677b83bdab09cda48bc2d89ac75aJust for name in names: 1547842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = getattr(self, name) 1557842e56b97ce677b83bdab09cda48bc2d89ac75aJust if name=="panose": 1567842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.begintag("panose") 1577842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 1587842e56b97ce677b83bdab09cda48bc2d89ac75aJust value.toXML(writer, ttFont) 1597842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.endtag("panose") 1607842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name in ("ulUnicodeRange1", "ulUnicodeRange2", 1617842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulUnicodeRange3", "ulUnicodeRange4", 1627842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulCodePageRange1", "ulCodePageRange2"): 1637842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=num2binary(value)) 1647842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name in ("fsType", "fsSelection"): 1657842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=num2binary(value, 16)) 1667842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name == "achVendID": 1677842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=repr(value)[1:-1]) 1687842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1697842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=value) 1707842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 1717842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1723a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content, ttFont): 1737842e56b97ce677b83bdab09cda48bc2d89ac75aJust if name == "panose": 1747842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = panose = Panose() 1757842e56b97ce677b83bdab09cda48bc2d89ac75aJust for element in content: 176b774f9f684c5a0f91f5fa177c9a461968789123fBehdad Esfahbod if isinstance(element, tuple): 1773a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod name, attrs, content = element 1783a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod panose.fromXML(name, attrs, content, ttFont) 1797842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name in ("ulUnicodeRange1", "ulUnicodeRange2", 1807842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulUnicodeRange3", "ulUnicodeRange4", 1817842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulCodePageRange1", "ulCodePageRange2", 1827842e56b97ce677b83bdab09cda48bc2d89ac75aJust "fsType", "fsSelection"): 1837842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, binary2num(attrs["value"])) 1847842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name == "achVendID": 1857842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) 1867842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1877842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval(attrs["value"])) 1887842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1897842e56b97ce677b83bdab09cda48bc2d89ac75aJust 190