otTables.py revision d4d151390d1288f8d2df30f6dfa26a309c7334da
1"""fontTools.ttLib.tables.otTables -- A collection of classes representing the various
2OpenType subtables.
3
4Most are constructed upon import from data in otData.py. Most smartness is contained
5in otBase.BaseTable.
6"""
7
8from otBase import BaseTable, FormatSwitchingBaseTable
9
10
11class LookupOrder(BaseTable):
12	"""Dummy class; this table isn't defined, but is used, and is always NULL."""
13
14class FeatureParams(BaseTable):
15	"""Dummy class; this table isn't defined, but is used, and is always NULL."""
16
17
18_equivalents = [
19	('MarkArray', ("Mark1Array",)),
20	('LangSys', ('DefaultLangSys',)),
21	('Coverage', ('MarkCoverage', 'BaseCoverage', 'LigatureCoverage', 'Mark1Coverage',
22			'Mark2Coverage', 'BacktrackCoverage', 'InputCoverage',
23			'LookaheadCoverage')),
24	('ClassDef', ('ClassDef1', 'ClassDef2', 'BacktrackClassDef', 'InputClassDef',
25			'LookaheadClassDef', 'GlyphClassDef', 'MarkAttachClassDef')),
26	('Anchor', ('EntryAnchor', 'ExitAnchor', 'BaseAnchor', 'LigatureAnchor',
27			'Mark2Anchor', 'MarkAnchor')),
28	('Device', ('XPlaDevice', 'YPlaDevice', 'XAdvDevice', 'YAdvDevice',
29			'XDeviceTable', 'YDeviceTable', 'DeviceTable')),
30	('Axis', ('HorizAxis', 'VertAxis',)),
31	('MinMax', ('DefaultMinMax',)),
32	('BaseCoord', ('MinCoord', 'MaxCoord',)),
33	('JstfLangSys', ('DefJstfLangSys',)),
34	('JstfGSUBModList', ('ShrinkageEnableGSUB', 'ShrinkageDisableGSUB', 'ExtensionEnableGSUB',
35			'ExtensionDisableGSUB',)),
36	('JstfGPOSModList', ('ShrinkageEnableGPOS', 'ShrinkageDisableGPOS', 'ExtensionEnableGPOS',
37			'ExtensionDisableGPOS',)),
38	('JstfMax', ('ShrinkageJstfMax', 'ExtensionJstfMax',)),
39]
40
41
42def _buildClasses():
43	import new, re
44	from otData import otData
45
46	formatPat = re.compile("([A-Za-z0-9]+)Format(\d+)$")
47	namespace = globals()
48
49	# populate module with classes
50	for name, table in otData:
51		baseClass = BaseTable
52		m = formatPat.match(name)
53		if m:
54			# XxxFormatN subtable, we only add the "base" table
55			name = m.group(1)
56			baseClass = FormatSwitchingBaseTable
57		if not namespace.has_key(name):
58			cls = new.classobj(name, (baseClass,), {})
59			namespace[name] = cls
60
61	for base, alts in _equivalents:
62		base = namespace[base]
63		for alt in alts:
64			namespace[alt] = new.classobj(alt, (base,), {})
65
66	global lookupTypes
67	lookupTypes = {
68		'GSUB': {
69			1: SingleSubst,
70			2: MultipleSubst,
71			3: AlternateSubst,
72			4: LigatureSubst,
73			5: ContextSubst,
74			6: ChainContextSubst,
75			7: ExtensionSubst,
76		},
77		'GPOS': {
78			1: SinglePos,
79			2: PairPos,
80			3: CursivePos,
81			4: MarkBasePos,
82			5: MarkLigPos,
83			6: MarkMarkPos,
84			7: ContextPos,
85			8: ChainContextPos,
86			9: ExtensionPos,
87		},
88	}
89	lookupTypes['JSTF'] = lookupTypes['GPOS']  # JSTF contains GPOS
90
91	# add converters to classes
92	from otConverters import buildConverterList
93	for name, table in otData:
94		m = formatPat.match(name)
95		if m:
96			# XxxFormatN subtable, add converter to "base" table
97			name, format = m.groups()
98			format = int(format)
99			cls = namespace[name]
100			if not hasattr(cls, "converters"):
101				cls.converters = {}
102				cls.convertersByName = {}
103			converters, convertersByName = buildConverterList(table[1:], namespace)
104			cls.converters[format] = converters
105			cls.convertersByName[format] = convertersByName
106		else:
107			cls = namespace[name]
108			cls.converters, cls.convertersByName = buildConverterList(table, namespace)
109
110
111_buildClasses()
112