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