O_S_2f_2.py revision 859967e5218bed974d05ddec93996b9aea2782a5
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport DefaultTable 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerimport sstruct 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerfrom fontTools.misc.textTools import safeEval, num2binary, binary2num 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner# panose classification 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerpanoseFormat = """ 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bFamilyType: B 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bSerifStyle: B 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bWeight: B 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bProportion: B 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bContrast: B 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bStrokeVariation: B 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bArmStyle: B 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bLetterForm: B 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bMidline: B 17478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer bXHeight: B 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer""" 19eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall 20d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallclass Panose: 2101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 2201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor def toXML(self, writer, ttFont): 2301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor formatstring, names, fixes = sstruct.getformat(panoseFormat) 24aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar for name in names: 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer writer.simpletag(name, value=getattr(self, name)) 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer writer.newline() 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 28aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor def fromXML(self, (name, attrs, content), ttFont): 29aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor setattr(self, name, safeEval(attrs["value"])) 30aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor 31aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor 32aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor# 'sfnt' OS/2 and Windows Metrics table - 'OS/2' 334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 341060aff23f72135f8b50034a1e80f16725ebc56cTed KremenekOS2_format_0 = """ 351060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek > # big endian 361060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek version: H # version 371060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek xAvgCharWidth: h # average character width 383fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor usWeightClass: H # degree of thickness of strokes 393fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor usWidthClass: H # aspect ratio 403fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor fsType: h # type flags 413fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySubscriptXSize: h # subscript horizontal font size 423fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySubscriptYSize: h # subscript vertical font size 433fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySubscriptXOffset: h # subscript x offset 443fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySubscriptYOffset: h # subscript y offset 453fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySuperscriptXSize: h # superscript horizontal font size 463fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySuperscriptYSize: h # superscript vertical font size 473fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySuperscriptXOffset: h # superscript x offset 483fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor ySuperscriptYOffset: h # superscript y offset 493fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor yStrikeoutSize: h # strikeout size 503fd95ce225393fe4a3623e429766a8c3f487ff9dDouglas Gregor yStrikeoutPosition: h # strikeout position 51b4609806e9232593ece09ce08b630836e825865cDouglas Gregor sFamilyClass: h # font family class and subclass 52063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor panose: 10s # panose classification number 53063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor ulUnicodeRange1: l # character range 544548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis ulUnicodeRange2: l # character range 55063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor ulUnicodeRange3: l # character range 56be9af1288881110e406b87914162eaa59f1e5918Lang Hames ulUnicodeRange4: l # character range 57be9af1288881110e406b87914162eaa59f1e5918Lang Hames achVendID: 4s # font vendor identification 58be9af1288881110e406b87914162eaa59f1e5918Lang Hames fsSelection: H # font selection flags 59be9af1288881110e406b87914162eaa59f1e5918Lang Hames fsFirstCharIndex: H # first unicode character index 60be9af1288881110e406b87914162eaa59f1e5918Lang Hames fsLastCharIndex: H # last unicode character index 614548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis usTypoAscender: H # typographic ascender 62b4609806e9232593ece09ce08b630836e825865cDouglas Gregor usTypoDescender: H # typographic descender 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump usTypoLineGap: H # typographic line gap 643b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer usWinAscent: H # Windows ascender 65be9af1288881110e406b87914162eaa59f1e5918Lang Hames usWinDescent: H # Windows descender 663b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer""" 67f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall 68be9af1288881110e406b87914162eaa59f1e5918Lang HamesOS2_format_1_addition = """ 694548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis ulCodePageRange1: l 704548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis ulCodePageRange2: l 711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump""" 72ba0a9006dbc4814e1e35f82812cb5a1dad65e8b8Argyrios Kyrtzidis 731eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpOS2_format_2_addition = OS2_format_1_addition + """ 74b4609806e9232593ece09ce08b630836e825865cDouglas Gregor sxHeight: h 75b4609806e9232593ece09ce08b630836e825865cDouglas Gregor sCapHeight: h 76b4609806e9232593ece09ce08b630836e825865cDouglas Gregor usDefaultChar: H 77063daf6e196c51f162e0485478355d8e280eef5cDouglas Gregor usBreakChar: H 78b4609806e9232593ece09ce08b630836e825865cDouglas Gregor usMaxContex: H 79b4609806e9232593ece09ce08b630836e825865cDouglas Gregor""" 80b4609806e9232593ece09ce08b630836e825865cDouglas Gregor 81b4609806e9232593ece09ce08b630836e825865cDouglas Gregorbigendian = " > # big endian\n" 82b4609806e9232593ece09ce08b630836e825865cDouglas Gregor 83b4609806e9232593ece09ce08b630836e825865cDouglas GregorOS2_format_1 = OS2_format_0 + OS2_format_1_addition 84b4609806e9232593ece09ce08b630836e825865cDouglas GregorOS2_format_2 = OS2_format_0 + OS2_format_2_addition 85b4609806e9232593ece09ce08b630836e825865cDouglas GregorOS2_format_1_addition = bigendian + OS2_format_1_addition 864548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios KyrtzidisOS2_format_2_addition = bigendian + OS2_format_2_addition 871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass table_O_S_2f_2(DefaultTable.DefaultTable): 90b4609806e9232593ece09ce08b630836e825865cDouglas Gregor 914548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis """the OS/2 table""" 92be9af1288881110e406b87914162eaa59f1e5918Lang Hames 93be9af1288881110e406b87914162eaa59f1e5918Lang Hames def decompile(self, data, ttFont): 94be9af1288881110e406b87914162eaa59f1e5918Lang Hames dummy, data = sstruct.unpack2(OS2_format_0, data, self) 95be9af1288881110e406b87914162eaa59f1e5918Lang Hames if self.version == 1: 96be9af1288881110e406b87914162eaa59f1e5918Lang Hames sstruct.unpack(OS2_format_1_addition, data, self) 97be9af1288881110e406b87914162eaa59f1e5918Lang Hames elif self.version == 2: 98be9af1288881110e406b87914162eaa59f1e5918Lang Hames sstruct.unpack(OS2_format_2_addition, data, self) 99be9af1288881110e406b87914162eaa59f1e5918Lang Hames elif self.version <> 0: 1004548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis from fontTools import ttLib 1014548ca2912e5f2b78a20e50c58d8a1a9c5e9e67cArgyrios Kyrtzidis raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version 102b4609806e9232593ece09ce08b630836e825865cDouglas Gregor self.panose = sstruct.unpack(panoseFormat, self.panose, Panose()) 103b4609806e9232593ece09ce08b630836e825865cDouglas Gregor 10488a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor def compile(self, ttFont): 10588a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor panose = self.panose 10688a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor self.panose = sstruct.pack(panoseFormat, self.panose) 10788a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor if self.version == 0: 10888a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor data = sstruct.pack(OS2_format_0, self) 10988a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor elif self.version == 1: 11088a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor data = sstruct.pack(OS2_format_1, self) 11188a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor elif self.version == 2: 11288a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor data = sstruct.pack(OS2_format_2, self) 11388a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor else: 1143b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer from fontTools import ttLib 115f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall raise ttLib.TTLibError, "unknown format for OS/2 table: version %s" % self.version 1163b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer self.panose = panose 11788a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor return data 1181817bd483b538fd3f4530649f5cb900bad9e8a76Chris Lattner 1191817bd483b538fd3f4530649f5cb900bad9e8a76Chris Lattner def toXML(self, writer, ttFont): 1201817bd483b538fd3f4530649f5cb900bad9e8a76Chris Lattner if self.version == 1: 12188a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor format = OS2_format_1 12288a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor elif self.version == 2: 12388a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor format = OS2_format_2 124b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek else: 125ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie format = OS2_format_0 126b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek formatstring, names, fixes = sstruct.getformat(format) 127b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek for name in names: 12888a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor value = getattr(self, name) 129007a9b1c632bfaac20e41c60cbe07fdc6d0e647cChandler Carruth if type(value) == type(0L): 130007a9b1c632bfaac20e41c60cbe07fdc6d0e647cChandler Carruth value = int(value) 131007a9b1c632bfaac20e41c60cbe07fdc6d0e647cChandler Carruth if name=="panose": 132007a9b1c632bfaac20e41c60cbe07fdc6d0e647cChandler Carruth writer.begintag("panose") 133007a9b1c632bfaac20e41c60cbe07fdc6d0e647cChandler Carruth writer.newline() 1340cf3c0eecbff007cea2750c113894b47d9e09f33David Blaikie value.toXML(writer, ttFont) 135007a9b1c632bfaac20e41c60cbe07fdc6d0e647cChandler Carruth writer.endtag("panose") 1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump elif name in ("ulUnicodeRange1", "ulUnicodeRange2", 13788a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor "ulUnicodeRange3", "ulUnicodeRange4", 13888a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor "ulCodePageRange1", "ulCodePageRange2"): 13988a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor writer.simpletag(name, value=num2binary(value)) 14088a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor elif name in ("fsType", "fsSelection"): 141e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne writer.simpletag(name, value=num2binary(value, 16)) 142e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne elif name == "achVendID": 143e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne writer.simpletag(name, value=repr(value)[1:-1]) 144e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne else: 145e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne writer.simpletag(name, value=value) 146e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne writer.newline() 147e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne 1483b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer def fromXML(self, (name, attrs, content), ttFont): 1493b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer if name == "panose": 1503b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer self.panose = panose = Panose() 151e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne for element in content: 152e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne if type(element) == type(()): 153e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne panose.fromXML(element, ttFont) 154e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne elif name in ("ulUnicodeRange1", "ulUnicodeRange2", 155e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne "ulUnicodeRange3", "ulUnicodeRange4", 156e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne "ulCodePageRange1", "ulCodePageRange2", 157e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne "fsType", "fsSelection"): 158e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne setattr(self, name, binary2num(attrs["value"])) 159e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne elif name == "achVendID": 160e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) 161e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne else: 162e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne setattr(self, name, safeEval(attrs["value"])) 163e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne 164e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne 165e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne