otTables.py revision 64b5c80e80444a124da335e8d4d208bffcf2737b
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, all are populated with
5converter objects from otConverters.py.
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#
19# For each subtable format there is a class. However, we don't really distinguish
20# between "field name" and "format name": often these are the same. Yet there's
21# a whole bunch of fields with different names. The following dict is a mapping
22# from "format name" to "field name". _buildClasses() uses this to create a
23# subclass for each alternate field name.
24#
25_equivalents = {
26	'MarkArray': ("Mark1Array",),
27	'LangSys': ('DefaultLangSys',),
28	'Coverage': ('MarkCoverage', 'BaseCoverage', 'LigatureCoverage', 'Mark1Coverage',
29			'Mark2Coverage', 'BacktrackCoverage', 'InputCoverage',
30			'LookaheadCoverage'),
31	'ClassDef': ('ClassDef1', 'ClassDef2', 'BacktrackClassDef', 'InputClassDef',
32			'LookaheadClassDef', 'GlyphClassDef', 'MarkAttachClassDef'),
33	'Anchor': ('EntryAnchor', 'ExitAnchor', 'BaseAnchor', 'LigatureAnchor',
34			'Mark2Anchor', 'MarkAnchor'),
35	'Device': ('XPlaDevice', 'YPlaDevice', 'XAdvDevice', 'YAdvDevice',
36			'XDeviceTable', 'YDeviceTable', 'DeviceTable'),
37	'Axis': ('HorizAxis', 'VertAxis',),
38	'MinMax': ('DefaultMinMax',),
39	'BaseCoord': ('MinCoord', 'MaxCoord',),
40	'JstfLangSys': ('DefJstfLangSys',),
41	'JstfGSUBModList': ('ShrinkageEnableGSUB', 'ShrinkageDisableGSUB', 'ExtensionEnableGSUB',
42			'ExtensionDisableGSUB',),
43	'JstfGPOSModList': ('ShrinkageEnableGPOS', 'ShrinkageDisableGPOS', 'ExtensionEnableGPOS',
44			'ExtensionDisableGPOS',),
45	'JstfMax': ('ShrinkageJstfMax', 'ExtensionJstfMax',),
46}
47
48
49def _buildClasses():
50	import new, re
51	from otData import otData
52
53	formatPat = re.compile("([A-Za-z0-9]+)Format(\d+)$")
54	namespace = globals()
55
56	# populate module with classes
57	for name, table in otData:
58		baseClass = BaseTable
59		m = formatPat.match(name)
60		if m:
61			# XxxFormatN subtable, we only add the "base" table
62			name = m.group(1)
63			baseClass = FormatSwitchingBaseTable
64		if not namespace.has_key(name):
65			# the class doesn't exist yet, so the base implementation is used.
66			cls = new.classobj(name, (baseClass,), {})
67			namespace[name] = cls
68
69	for base, alts in _equivalents.items():
70		base = namespace[base]
71		for alt in alts:
72			namespace[alt] = new.classobj(alt, (base,), {})
73
74	global lookupTypes
75	lookupTypes = {
76		'GSUB': {
77			1: SingleSubst,
78			2: MultipleSubst,
79			3: AlternateSubst,
80			4: LigatureSubst,
81			5: ContextSubst,
82			6: ChainContextSubst,
83			7: ExtensionSubst,
84		},
85		'GPOS': {
86			1: SinglePos,
87			2: PairPos,
88			3: CursivePos,
89			4: MarkBasePos,
90			5: MarkLigPos,
91			6: MarkMarkPos,
92			7: ContextPos,
93			8: ChainContextPos,
94			9: ExtensionPos,
95		},
96	}
97	lookupTypes['JSTF'] = lookupTypes['GPOS']  # JSTF contains GPOS
98	for lookupEnum in lookupTypes.values():
99		for enum, cls in lookupEnum.items():
100			cls.LookupType = enum
101
102	# add converters to classes
103	from otConverters import buildConverters
104	for name, table in otData:
105		m = formatPat.match(name)
106		if m:
107			# XxxFormatN subtable, add converter to "base" table
108			name, format = m.groups()
109			format = int(format)
110			cls = namespace[name]
111			if not hasattr(cls, "converters"):
112				cls.converters = {}
113				cls.convertersByName = {}
114			converters, convertersByName = buildConverters(table[1:], namespace)
115			cls.converters[format] = converters
116			cls.convertersByName[format] = convertersByName
117		else:
118			cls = namespace[name]
119			cls.converters, cls.convertersByName = buildConverters(table, namespace)
120
121
122_buildClasses()
123