O_S_2f_2.py revision 4acb76de2ef06f9dbf431a52abe0c6da7c5f2a8a
17842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport DefaultTable 27842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport sstruct 37842e56b97ce677b83bdab09cda48bc2d89ac75aJustfrom fontTools.misc.textTools import safeEval, num2binary, binary2num 422dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvrfrom types import TupleType 522dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvr 67842e56b97ce677b83bdab09cda48bc2d89ac75aJust 77842e56b97ce677b83bdab09cda48bc2d89ac75aJust# panose classification 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust 97842e56b97ce677b83bdab09cda48bc2d89ac75aJustpanoseFormat = """ 10859967e5218bed974d05ddec93996b9aea2782a5Just bFamilyType: B 11859967e5218bed974d05ddec93996b9aea2782a5Just bSerifStyle: B 12859967e5218bed974d05ddec93996b9aea2782a5Just bWeight: B 13859967e5218bed974d05ddec93996b9aea2782a5Just bProportion: B 14859967e5218bed974d05ddec93996b9aea2782a5Just bContrast: B 15859967e5218bed974d05ddec93996b9aea2782a5Just bStrokeVariation: B 16859967e5218bed974d05ddec93996b9aea2782a5Just bArmStyle: B 17859967e5218bed974d05ddec93996b9aea2782a5Just bLetterForm: B 18859967e5218bed974d05ddec93996b9aea2782a5Just bMidline: B 19859967e5218bed974d05ddec93996b9aea2782a5Just bXHeight: B 207842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 217842e56b97ce677b83bdab09cda48bc2d89ac75aJust 227842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass Panose: 237842e56b97ce677b83bdab09cda48bc2d89ac75aJust 247842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, writer, ttFont): 257842e56b97ce677b83bdab09cda48bc2d89ac75aJust formatstring, names, fixes = sstruct.getformat(panoseFormat) 267842e56b97ce677b83bdab09cda48bc2d89ac75aJust for name in names: 277842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=getattr(self, name)) 287842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust def fromXML(self, (name, attrs, content), ttFont): 317842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval(attrs["value"])) 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 337842e56b97ce677b83bdab09cda48bc2d89ac75aJust 347842e56b97ce677b83bdab09cda48bc2d89ac75aJust# 'sfnt' OS/2 and Windows Metrics table - 'OS/2' 357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 367842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_0 = """ 37859967e5218bed974d05ddec93996b9aea2782a5Just > # big endian 38859967e5218bed974d05ddec93996b9aea2782a5Just version: H # version 39859967e5218bed974d05ddec93996b9aea2782a5Just xAvgCharWidth: h # average character width 40859967e5218bed974d05ddec93996b9aea2782a5Just usWeightClass: H # degree of thickness of strokes 41859967e5218bed974d05ddec93996b9aea2782a5Just usWidthClass: H # aspect ratio 42859967e5218bed974d05ddec93996b9aea2782a5Just fsType: h # type flags 43859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptXSize: h # subscript horizontal font size 44859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptYSize: h # subscript vertical font size 45859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptXOffset: h # subscript x offset 46859967e5218bed974d05ddec93996b9aea2782a5Just ySubscriptYOffset: h # subscript y offset 47859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptXSize: h # superscript horizontal font size 48859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptYSize: h # superscript vertical font size 49859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptXOffset: h # superscript x offset 50859967e5218bed974d05ddec93996b9aea2782a5Just ySuperscriptYOffset: h # superscript y offset 51859967e5218bed974d05ddec93996b9aea2782a5Just yStrikeoutSize: h # strikeout size 52859967e5218bed974d05ddec93996b9aea2782a5Just yStrikeoutPosition: h # strikeout position 53859967e5218bed974d05ddec93996b9aea2782a5Just sFamilyClass: h # font family class and subclass 54859967e5218bed974d05ddec93996b9aea2782a5Just panose: 10s # panose classification number 5504985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange1: L # character range 5604985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange2: L # character range 5704985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange3: L # character range 5804985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulUnicodeRange4: L # character range 59859967e5218bed974d05ddec93996b9aea2782a5Just achVendID: 4s # font vendor identification 60859967e5218bed974d05ddec93996b9aea2782a5Just fsSelection: H # font selection flags 61859967e5218bed974d05ddec93996b9aea2782a5Just fsFirstCharIndex: H # first unicode character index 62859967e5218bed974d05ddec93996b9aea2782a5Just fsLastCharIndex: H # last unicode character index 636146b084c29234a873c31e3bfaee5df2d015e63ajvr sTypoAscender: h # typographic ascender 646146b084c29234a873c31e3bfaee5df2d015e63ajvr sTypoDescender: h # typographic descender 656146b084c29234a873c31e3bfaee5df2d015e63ajvr sTypoLineGap: h # typographic line gap 66859967e5218bed974d05ddec93996b9aea2782a5Just usWinAscent: H # Windows ascender 67859967e5218bed974d05ddec93996b9aea2782a5Just usWinDescent: H # Windows descender 687842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 697842e56b97ce677b83bdab09cda48bc2d89ac75aJust 707842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_1_addition = """ 7104985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulCodePageRange1: L 7204985bfdded4d445c67524b018965df1f4a4c313fcoiffie ulCodePageRange2: L 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust 757842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_2_addition = OS2_format_1_addition + """ 76859967e5218bed974d05ddec93996b9aea2782a5Just sxHeight: h 77859967e5218bed974d05ddec93996b9aea2782a5Just sCapHeight: h 78859967e5218bed974d05ddec93996b9aea2782a5Just usDefaultChar: H 79859967e5218bed974d05ddec93996b9aea2782a5Just usBreakChar: H 80859967e5218bed974d05ddec93996b9aea2782a5Just usMaxContex: H 817842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 827842e56b97ce677b83bdab09cda48bc2d89ac75aJust 837842e56b97ce677b83bdab09cda48bc2d89ac75aJustbigendian = " > # big endian\n" 847842e56b97ce677b83bdab09cda48bc2d89ac75aJust 857842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_1 = OS2_format_0 + OS2_format_1_addition 867842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_2 = OS2_format_0 + OS2_format_2_addition 877842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_1_addition = bigendian + OS2_format_1_addition 887842e56b97ce677b83bdab09cda48bc2d89ac75aJustOS2_format_2_addition = bigendian + OS2_format_2_addition 897842e56b97ce677b83bdab09cda48bc2d89ac75aJust 907842e56b97ce677b83bdab09cda48bc2d89ac75aJust 917842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass table_O_S_2f_2(DefaultTable.DefaultTable): 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust 937842e56b97ce677b83bdab09cda48bc2d89ac75aJust """the OS/2 table""" 947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data, ttFont): 967842e56b97ce677b83bdab09cda48bc2d89ac75aJust dummy, data = sstruct.unpack2(OS2_format_0, data, self) 97481fb094956023aa7b158d6ed1582931bdcad1bfJust if self.version == 1 and not data: 98481fb094956023aa7b158d6ed1582931bdcad1bfJust # workaround for buggy Apple fonts 99481fb094956023aa7b158d6ed1582931bdcad1bfJust self.version = 0 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.version == 1: 1014170cfd5e9e14094883c4676f8a172e7915c9cc4jvr sstruct.unpack2(OS2_format_1_addition, data, self) 1024acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr elif self.version in (2, 3, 4): 1034170cfd5e9e14094883c4676f8a172e7915c9cc4jvr sstruct.unpack2(OS2_format_2_addition, data, self) 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif self.version <> 0: 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust from fontTools import ttLib 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = sstruct.unpack(panoseFormat, self.panose, Panose()) 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust def compile(self, ttFont): 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust panose = self.panose 1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = sstruct.pack(panoseFormat, self.panose) 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.version == 0: 1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(OS2_format_0, self) 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif self.version == 1: 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(OS2_format_1, self) 1164acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr elif self.version in (2, 3, 4): 1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust data = sstruct.pack(OS2_format_2, self) 1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust from fontTools import ttLib 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version 1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = panose 1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust return data 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, writer, ttFont): 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.version == 1: 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = OS2_format_1 1274acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr elif self.version in (2, 3, 4): 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = OS2_format_2 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust format = OS2_format_0 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust formatstring, names, fixes = sstruct.getformat(format) 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust for name in names: 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = getattr(self, name) 1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust if type(value) == type(0L): 1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = int(value) 1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust if name=="panose": 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.begintag("panose") 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust value.toXML(writer, ttFont) 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.endtag("panose") 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name in ("ulUnicodeRange1", "ulUnicodeRange2", 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulUnicodeRange3", "ulUnicodeRange4", 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulCodePageRange1", "ulCodePageRange2"): 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=num2binary(value)) 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name in ("fsType", "fsSelection"): 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=num2binary(value, 16)) 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name == "achVendID": 1487842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=repr(value)[1:-1]) 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.simpletag(name, value=value) 1517842e56b97ce677b83bdab09cda48bc2d89ac75aJust writer.newline() 1527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1537842e56b97ce677b83bdab09cda48bc2d89ac75aJust def fromXML(self, (name, attrs, content), ttFont): 1547842e56b97ce677b83bdab09cda48bc2d89ac75aJust if name == "panose": 1557842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.panose = panose = Panose() 1567842e56b97ce677b83bdab09cda48bc2d89ac75aJust for element in content: 15722dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvr if type(element) == TupleType: 1587842e56b97ce677b83bdab09cda48bc2d89ac75aJust panose.fromXML(element, ttFont) 1597842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name in ("ulUnicodeRange1", "ulUnicodeRange2", 1607842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulUnicodeRange3", "ulUnicodeRange4", 1617842e56b97ce677b83bdab09cda48bc2d89ac75aJust "ulCodePageRange1", "ulCodePageRange2", 1627842e56b97ce677b83bdab09cda48bc2d89ac75aJust "fsType", "fsSelection"): 1637842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, binary2num(attrs["value"])) 1647842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif name == "achVendID": 1657842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) 1667842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 1677842e56b97ce677b83bdab09cda48bc2d89ac75aJust setattr(self, name, safeEval(attrs["value"])) 1687842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1697842e56b97ce677b83bdab09cda48bc2d89ac75aJust 170