diff options
Diffstat (limited to 'Tests/ttLib/tables/_m_o_r_x_test.py')
-rw-r--r-- | Tests/ttLib/tables/_m_o_r_x_test.py | 873 |
1 files changed, 430 insertions, 443 deletions
diff --git a/Tests/ttLib/tables/_m_o_r_x_test.py b/Tests/ttLib/tables/_m_o_r_x_test.py index d65619ca..eae3efc0 100644 --- a/Tests/ttLib/tables/_m_o_r_x_test.py +++ b/Tests/ttLib/tables/_m_o_r_x_test.py @@ -9,131 +9,131 @@ import unittest # The test case has therefore been adapted from the example 'mort' table in # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html MORX_NONCONTEXTUAL_DATA = deHexStr( - '0002 0000 ' # 0: Version=2, Reserved=0 - '0000 0001 ' # 4: MorphChainCount=1 - '0000 0001 ' # 8: DefaultFlags=1 - '0000 0058 ' # 12: StructLength=88 - '0000 0003 ' # 16: MorphFeatureCount=3 - '0000 0001 ' # 20: MorphSubtableCount=1 - '0004 0000 ' # 24: Feature[0].FeatureType=4/VertSubst, .FeatureSetting=on - '0000 0001 ' # 28: Feature[0].EnableFlags=0x00000001 - 'FFFF FFFF ' # 32: Feature[0].DisableFlags=0xFFFFFFFF - '0004 0001 ' # 36: Feature[1].FeatureType=4/VertSubst, .FeatureSetting=off - '0000 0000 ' # 40: Feature[1].EnableFlags=0x00000000 - 'FFFF FFFE ' # 44: Feature[1].DisableFlags=0xFFFFFFFE - '0000 0001 ' # 48: Feature[2].FeatureType=0/GlyphEffects, .FeatSetting=off - '0000 0000 ' # 52: Feature[2].EnableFlags=0 (required for last feature) - '0000 0000 ' # 56: Feature[2].EnableFlags=0 (required for last feature) - '0000 0024 ' # 60: Subtable[0].StructLength=36 - '80 ' # 64: Subtable[0].CoverageFlags=0x80 - '00 00 ' # 65: Subtable[0].Reserved=0 - '04 ' # 67: Subtable[0].MorphType=4/NoncontextualMorph - '0000 0001 ' # 68: Subtable[0].SubFeatureFlags=0x1 - '0006 0004 ' # 72: LookupFormat=6, UnitSize=4 - '0002 0008 ' # 76: NUnits=2, SearchRange=8 - '0001 0000 ' # 80: EntrySelector=1, RangeShift=0 - '000B 0087 ' # 84: Glyph=11 (parenleft); Value=135 (parenleft.vertical) - '000D 0088 ' # 88: Glyph=13 (parenright); Value=136 (parenright.vertical) - 'FFFF 0000 ' # 92: Glyph=<end>; Value=0 -) # 96: <end> + "0002 0000 " # 0: Version=2, Reserved=0 + "0000 0001 " # 4: MorphChainCount=1 + "0000 0001 " # 8: DefaultFlags=1 + "0000 0058 " # 12: StructLength=88 + "0000 0003 " # 16: MorphFeatureCount=3 + "0000 0001 " # 20: MorphSubtableCount=1 + "0004 0000 " # 24: Feature[0].FeatureType=4/VertSubst, .FeatureSetting=on + "0000 0001 " # 28: Feature[0].EnableFlags=0x00000001 + "FFFF FFFF " # 32: Feature[0].DisableFlags=0xFFFFFFFF + "0004 0001 " # 36: Feature[1].FeatureType=4/VertSubst, .FeatureSetting=off + "0000 0000 " # 40: Feature[1].EnableFlags=0x00000000 + "FFFF FFFE " # 44: Feature[1].DisableFlags=0xFFFFFFFE + "0000 0001 " # 48: Feature[2].FeatureType=0/GlyphEffects, .FeatSetting=off + "0000 0000 " # 52: Feature[2].EnableFlags=0 (required for last feature) + "0000 0000 " # 56: Feature[2].EnableFlags=0 (required for last feature) + "0000 0024 " # 60: Subtable[0].StructLength=36 + "80 " # 64: Subtable[0].CoverageFlags=0x80 + "00 00 " # 65: Subtable[0].Reserved=0 + "04 " # 67: Subtable[0].MorphType=4/NoncontextualMorph + "0000 0001 " # 68: Subtable[0].SubFeatureFlags=0x1 + "0006 0004 " # 72: LookupFormat=6, UnitSize=4 + "0002 0008 " # 76: NUnits=2, SearchRange=8 + "0001 0000 " # 80: EntrySelector=1, RangeShift=0 + "000B 0087 " # 84: Glyph=11 (parenleft); Value=135 (parenleft.vertical) + "000D 0088 " # 88: Glyph=13 (parenright); Value=136 (parenright.vertical) + "FFFF 0000 " # 92: Glyph=<end>; Value=0 +) # 96: <end> assert len(MORX_NONCONTEXTUAL_DATA) == 96 MORX_NONCONTEXTUAL_XML = [ '<Version value="2"/>', '<Reserved value="0"/>', - '<!-- MorphChainCount=1 -->', + "<!-- MorphChainCount=1 -->", '<MorphChain index="0">', ' <DefaultFlags value="0x00000001"/>', - ' <!-- StructLength=88 -->', - ' <!-- MorphFeatureCount=3 -->', - ' <!-- MorphSubtableCount=1 -->', + " <!-- StructLength=88 -->", + " <!-- MorphFeatureCount=3 -->", + " <!-- MorphSubtableCount=1 -->", ' <MorphFeature index="0">', ' <FeatureType value="4"/>', ' <FeatureSetting value="0"/>', ' <EnableFlags value="0x00000001"/>', ' <DisableFlags value="0xFFFFFFFF"/>', - ' </MorphFeature>', + " </MorphFeature>", ' <MorphFeature index="1">', ' <FeatureType value="4"/>', ' <FeatureSetting value="1"/>', ' <EnableFlags value="0x00000000"/>', ' <DisableFlags value="0xFFFFFFFE"/>', - ' </MorphFeature>', + " </MorphFeature>", ' <MorphFeature index="2">', ' <FeatureType value="0"/>', ' <FeatureSetting value="1"/>', ' <EnableFlags value="0x00000000"/>', ' <DisableFlags value="0x00000000"/>', - ' </MorphFeature>', + " </MorphFeature>", ' <MorphSubtable index="0">', - ' <!-- StructLength=36 -->', + " <!-- StructLength=36 -->", ' <TextDirection value="Vertical"/>', ' <ProcessingOrder value="LayoutOrder"/>', - ' <!-- MorphType=4 -->', + " <!-- MorphType=4 -->", ' <SubFeatureFlags value="0x00000001"/>', - ' <NoncontextualMorph>', - ' <Substitution>', + " <NoncontextualMorph>", + " <Substitution>", ' <Lookup glyph="parenleft" value="parenleft.vertical"/>', ' <Lookup glyph="parenright" value="parenright.vertical"/>', - ' </Substitution>', - ' </NoncontextualMorph>', - ' </MorphSubtable>', - '</MorphChain>', + " </Substitution>", + " </NoncontextualMorph>", + " </MorphSubtable>", + "</MorphChain>", ] MORX_REARRANGEMENT_DATA = deHexStr( - '0002 0000 ' # 0: Version=2, Reserved=0 - '0000 0001 ' # 4: MorphChainCount=1 - '0000 0001 ' # 8: DefaultFlags=1 - '0000 0078 ' # 12: StructLength=120 (+8=128) - '0000 0000 ' # 16: MorphFeatureCount=0 - '0000 0001 ' # 20: MorphSubtableCount=1 - '0000 0068 ' # 24: Subtable[0].StructLength=104 (+24=128) - '80 ' # 28: Subtable[0].CoverageFlags=0x80 - '00 00 ' # 29: Subtable[0].Reserved=0 - '00 ' # 31: Subtable[0].MorphType=0/RearrangementMorph - '0000 0001 ' # 32: Subtable[0].SubFeatureFlags=0x1 - '0000 0006 ' # 36: STXHeader.ClassCount=6 - '0000 0010 ' # 40: STXHeader.ClassTableOffset=16 (+36=52) - '0000 0028 ' # 44: STXHeader.StateArrayOffset=40 (+36=76) - '0000 004C ' # 48: STXHeader.EntryTableOffset=76 (+36=112) - '0006 0004 ' # 52: ClassTable.LookupFormat=6, .UnitSize=4 - '0002 0008 ' # 56: .NUnits=2, .SearchRange=8 - '0001 0000 ' # 60: .EntrySelector=1, .RangeShift=0 - '0001 0005 ' # 64: Glyph=A; Class=5 - '0003 0004 ' # 68: Glyph=C; Class=4 - 'FFFF 0000 ' # 72: Glyph=<end>; Value=0 - '0000 0001 0002 0003 0002 0001 ' # 76: State[0][0..5] - '0003 0003 0003 0003 0003 0003 ' # 88: State[1][0..5] - '0001 0003 0003 0003 0002 0002 ' # 100: State[2][0..5] - '0002 FFFF ' # 112: Entries[0].NewState=2, .Flags=0xFFFF - '0001 A00D ' # 116: Entries[1].NewState=1, .Flags=0xA00D - '0000 8006 ' # 120: Entries[2].NewState=0, .Flags=0x8006 - '0002 0000 ' # 124: Entries[3].NewState=2, .Flags=0x0000 -) # 128: <end> + "0002 0000 " # 0: Version=2, Reserved=0 + "0000 0001 " # 4: MorphChainCount=1 + "0000 0001 " # 8: DefaultFlags=1 + "0000 0078 " # 12: StructLength=120 (+8=128) + "0000 0000 " # 16: MorphFeatureCount=0 + "0000 0001 " # 20: MorphSubtableCount=1 + "0000 0068 " # 24: Subtable[0].StructLength=104 (+24=128) + "80 " # 28: Subtable[0].CoverageFlags=0x80 + "00 00 " # 29: Subtable[0].Reserved=0 + "00 " # 31: Subtable[0].MorphType=0/RearrangementMorph + "0000 0001 " # 32: Subtable[0].SubFeatureFlags=0x1 + "0000 0006 " # 36: STXHeader.ClassCount=6 + "0000 0010 " # 40: STXHeader.ClassTableOffset=16 (+36=52) + "0000 0028 " # 44: STXHeader.StateArrayOffset=40 (+36=76) + "0000 004C " # 48: STXHeader.EntryTableOffset=76 (+36=112) + "0006 0004 " # 52: ClassTable.LookupFormat=6, .UnitSize=4 + "0002 0008 " # 56: .NUnits=2, .SearchRange=8 + "0001 0000 " # 60: .EntrySelector=1, .RangeShift=0 + "0001 0005 " # 64: Glyph=A; Class=5 + "0003 0004 " # 68: Glyph=C; Class=4 + "FFFF 0000 " # 72: Glyph=<end>; Value=0 + "0000 0001 0002 0003 0002 0001 " # 76: State[0][0..5] + "0003 0003 0003 0003 0003 0003 " # 88: State[1][0..5] + "0001 0003 0003 0003 0002 0002 " # 100: State[2][0..5] + "0002 FFFF " # 112: Entries[0].NewState=2, .Flags=0xFFFF + "0001 A00D " # 116: Entries[1].NewState=1, .Flags=0xA00D + "0000 8006 " # 120: Entries[2].NewState=0, .Flags=0x8006 + "0002 0000 " # 124: Entries[3].NewState=2, .Flags=0x0000 +) # 128: <end> assert len(MORX_REARRANGEMENT_DATA) == 128, len(MORX_REARRANGEMENT_DATA) MORX_REARRANGEMENT_XML = [ '<Version value="2"/>', '<Reserved value="0"/>', - '<!-- MorphChainCount=1 -->', + "<!-- MorphChainCount=1 -->", '<MorphChain index="0">', ' <DefaultFlags value="0x00000001"/>', - ' <!-- StructLength=120 -->', - ' <!-- MorphFeatureCount=0 -->', - ' <!-- MorphSubtableCount=1 -->', + " <!-- StructLength=120 -->", + " <!-- MorphFeatureCount=0 -->", + " <!-- MorphSubtableCount=1 -->", ' <MorphSubtable index="0">', - ' <!-- StructLength=104 -->', + " <!-- StructLength=104 -->", ' <TextDirection value="Vertical"/>', ' <ProcessingOrder value="LayoutOrder"/>', - ' <!-- MorphType=0 -->', + " <!-- MorphType=0 -->", ' <SubFeatureFlags value="0x00000001"/>', - ' <RearrangementMorph>', - ' <StateTable>', - ' <!-- GlyphClassCount=6 -->', + " <RearrangementMorph>", + " <StateTable>", + " <!-- GlyphClassCount=6 -->", ' <GlyphClass glyph="A" value="5"/>', ' <GlyphClass glyph="C" value="4"/>', ' <State index="0">', @@ -142,91 +142,91 @@ MORX_REARRANGEMENT_XML = [ ' <Flags value="MarkFirst,DontAdvance,MarkLast"/>', ' <ReservedFlags value="0x1FF0"/>', ' <Verb value="15"/><!-- ABxCD ⇒ DCxBA -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="1"/>', ' <Flags value="MarkFirst,MarkLast"/>', ' <Verb value="13"/><!-- ABxCD ⇒ CDxBA -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', ' <Flags value="MarkFirst"/>', ' <Verb value="6"/><!-- xCD ⇒ CDx -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="0"/>', ' <Flags value="MarkFirst"/>', ' <Verb value="6"/><!-- xCD ⇒ CDx -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="1"/>', ' <Flags value="MarkFirst,MarkLast"/>', ' <Verb value="13"/><!-- ABxCD ⇒ CDxBA -->', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="1">', ' <Transition onGlyphClass="0">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="2">', ' <Transition onGlyphClass="0">', ' <NewState value="1"/>', ' <Flags value="MarkFirst,MarkLast"/>', ' <Verb value="13"/><!-- ABxCD ⇒ CDxBA -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="2"/>', ' <Verb value="0"/><!-- no change -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="0"/>', ' <Flags value="MarkFirst"/>', ' <Verb value="6"/><!-- xCD ⇒ CDx -->', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="0"/>', ' <Flags value="MarkFirst"/>', ' <Verb value="6"/><!-- xCD ⇒ CDx -->', - ' </Transition>', - ' </State>', - ' </StateTable>', - ' </RearrangementMorph>', - ' </MorphSubtable>', - '</MorphChain>', + " </Transition>", + " </State>", + " </StateTable>", + " </RearrangementMorph>", + " </MorphSubtable>", + "</MorphChain>", ] @@ -266,83 +266,77 @@ MORX_REARRANGEMENT_XML = [ # # TODO: Ask Apple to fix “Example 1” in the ‘morx’ specification. MORX_CONTEXTUAL_DATA = deHexStr( - '0002 0000 ' # 0: Version=2, Reserved=0 - '0000 0001 ' # 4: MorphChainCount=1 - '0000 0001 ' # 8: DefaultFlags=1 - '0000 00B4 ' # 12: StructLength=180 (+8=188) - '0000 0000 ' # 16: MorphFeatureCount=0 - '0000 0001 ' # 20: MorphSubtableCount=1 - '0000 00A4 ' # 24: Subtable[0].StructLength=164 (+24=188) - '80 ' # 28: Subtable[0].CoverageFlags=0x80 - '00 00 ' # 29: Subtable[0].Reserved=0 - '01 ' # 31: Subtable[0].MorphType=1/ContextualMorph - '0000 0001 ' # 32: Subtable[0].SubFeatureFlags=0x1 - '0000 0006 ' # 36: STXHeader.ClassCount=6 - '0000 0014 ' # 40: STXHeader.ClassTableOffset=20 (+36=56) - '0000 0038 ' # 44: STXHeader.StateArrayOffset=56 (+36=92) - '0000 005C ' # 48: STXHeader.EntryTableOffset=92 (+36=128) - '0000 0074 ' # 52: STXHeader.PerGlyphTableOffset=116 (+36=152) - + "0002 0000 " # 0: Version=2, Reserved=0 + "0000 0001 " # 4: MorphChainCount=1 + "0000 0001 " # 8: DefaultFlags=1 + "0000 00B4 " # 12: StructLength=180 (+8=188) + "0000 0000 " # 16: MorphFeatureCount=0 + "0000 0001 " # 20: MorphSubtableCount=1 + "0000 00A4 " # 24: Subtable[0].StructLength=164 (+24=188) + "80 " # 28: Subtable[0].CoverageFlags=0x80 + "00 00 " # 29: Subtable[0].Reserved=0 + "01 " # 31: Subtable[0].MorphType=1/ContextualMorph + "0000 0001 " # 32: Subtable[0].SubFeatureFlags=0x1 + "0000 0006 " # 36: STXHeader.ClassCount=6 + "0000 0014 " # 40: STXHeader.ClassTableOffset=20 (+36=56) + "0000 0038 " # 44: STXHeader.StateArrayOffset=56 (+36=92) + "0000 005C " # 48: STXHeader.EntryTableOffset=92 (+36=128) + "0000 0074 " # 52: STXHeader.PerGlyphTableOffset=116 (+36=152) # Glyph class table. - '0006 0004 ' # 56: ClassTable.LookupFormat=6, .UnitSize=4 - '0005 0010 ' # 60: .NUnits=5, .SearchRange=16 - '0002 0004 ' # 64: .EntrySelector=2, .RangeShift=4 - '0032 0004 ' # 68: Glyph=50; Class=4 - '0034 0004 ' # 72: Glyph=52; Class=4 - '0050 0005 ' # 76: Glyph=80; Class=5 - '00C9 0004 ' # 80: Glyph=201; Class=4 - '00CA 0004 ' # 84: Glyph=202; Class=4 - 'FFFF 0000 ' # 88: Glyph=<end>; Value=<filler> - + "0006 0004 " # 56: ClassTable.LookupFormat=6, .UnitSize=4 + "0005 0010 " # 60: .NUnits=5, .SearchRange=16 + "0002 0004 " # 64: .EntrySelector=2, .RangeShift=4 + "0032 0004 " # 68: Glyph=50; Class=4 + "0034 0004 " # 72: Glyph=52; Class=4 + "0050 0005 " # 76: Glyph=80; Class=5 + "00C9 0004 " # 80: Glyph=201; Class=4 + "00CA 0004 " # 84: Glyph=202; Class=4 + "FFFF 0000 " # 88: Glyph=<end>; Value=<filler> # State array. - '0000 0000 0000 0000 0000 0001 ' # 92: State[0][0..5] - '0000 0000 0000 0000 0000 0001 ' # 104: State[1][0..5] - '0000 0000 0000 0000 0002 0001 ' # 116: State[2][0..5] - + "0000 0000 0000 0000 0000 0001 " # 92: State[0][0..5] + "0000 0000 0000 0000 0000 0001 " # 104: State[1][0..5] + "0000 0000 0000 0000 0002 0001 " # 116: State[2][0..5] # Entry table. - '0000 0000 ' # 128: Entries[0].NewState=0, .Flags=0 - 'FFFF FFFF ' # 132: Entries[0].MarkSubst=None, .CurSubst=None - '0002 0000 ' # 136: Entries[1].NewState=2, .Flags=0 - 'FFFF FFFF ' # 140: Entries[1].MarkSubst=None, .CurSubst=None - '0000 0000 ' # 144: Entries[2].NewState=0, .Flags=0 - 'FFFF 0000 ' # 148: Entries[2].MarkSubst=None, .CurSubst=PerGlyph #0 - # 152: <no padding needed for 4-byte alignment> - + "0000 0000 " # 128: Entries[0].NewState=0, .Flags=0 + "FFFF FFFF " # 132: Entries[0].MarkSubst=None, .CurSubst=None + "0002 0000 " # 136: Entries[1].NewState=2, .Flags=0 + "FFFF FFFF " # 140: Entries[1].MarkSubst=None, .CurSubst=None + "0000 0000 " # 144: Entries[2].NewState=0, .Flags=0 + "FFFF 0000 " # 148: Entries[2].MarkSubst=None, .CurSubst=PerGlyph #0 + # 152: <no padding needed for 4-byte alignment> # Per-glyph lookup tables. - '0000 0004 ' # 152: Offset from this point to per-glyph lookup #0. - + "0000 0004 " # 152: Offset from this point to per-glyph lookup #0. # Per-glyph lookup #0. - '0006 0004 ' # 156: ClassTable.LookupFormat=6, .UnitSize=4 - '0004 0010 ' # 160: .NUnits=4, .SearchRange=16 - '0002 0000 ' # 164: .EntrySelector=2, .RangeShift=0 - '0032 0258 ' # 168: Glyph=50; ReplacementGlyph=600 - '0034 0259 ' # 172: Glyph=52; ReplacementGlyph=601 - '00C9 025A ' # 176: Glyph=201; ReplacementGlyph=602 - '00CA 0384 ' # 180: Glyph=202; ReplacementGlyph=900 - 'FFFF 0000 ' # 184: Glyph=<end>; Value=<filler> - -) # 188: <end> + "0006 0004 " # 156: ClassTable.LookupFormat=6, .UnitSize=4 + "0004 0010 " # 160: .NUnits=4, .SearchRange=16 + "0002 0000 " # 164: .EntrySelector=2, .RangeShift=0 + "0032 0258 " # 168: Glyph=50; ReplacementGlyph=600 + "0034 0259 " # 172: Glyph=52; ReplacementGlyph=601 + "00C9 025A " # 176: Glyph=201; ReplacementGlyph=602 + "00CA 0384 " # 180: Glyph=202; ReplacementGlyph=900 + "FFFF 0000 " # 184: Glyph=<end>; Value=<filler> +) # 188: <end> assert len(MORX_CONTEXTUAL_DATA) == 188, len(MORX_CONTEXTUAL_DATA) MORX_CONTEXTUAL_XML = [ '<Version value="2"/>', '<Reserved value="0"/>', - '<!-- MorphChainCount=1 -->', + "<!-- MorphChainCount=1 -->", '<MorphChain index="0">', ' <DefaultFlags value="0x00000001"/>', - ' <!-- StructLength=180 -->', - ' <!-- MorphFeatureCount=0 -->', - ' <!-- MorphSubtableCount=1 -->', + " <!-- StructLength=180 -->", + " <!-- MorphFeatureCount=0 -->", + " <!-- MorphSubtableCount=1 -->", ' <MorphSubtable index="0">', - ' <!-- StructLength=164 -->', + " <!-- StructLength=164 -->", ' <TextDirection value="Vertical"/>', ' <ProcessingOrder value="LayoutOrder"/>', - ' <!-- MorphType=1 -->', + " <!-- MorphType=1 -->", ' <SubFeatureFlags value="0x00000001"/>', - ' <ContextualMorph>', - ' <StateTable>', - ' <!-- GlyphClassCount=6 -->', + " <ContextualMorph>", + " <StateTable>", + " <!-- GlyphClassCount=6 -->", ' <GlyphClass glyph="A" value="4"/>', ' <GlyphClass glyph="B" value="4"/>', ' <GlyphClass glyph="C" value="5"/>', @@ -353,107 +347,107 @@ MORX_CONTEXTUAL_XML = [ ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="2"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="1">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="2"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="2">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="0"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="2"/>', ' <MarkIndex value="65535"/>', ' <CurrentIndex value="65535"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <PerGlyphLookup index="0">', ' <Lookup glyph="A" value="A.swash"/>', ' <Lookup glyph="B" value="B.swash"/>', ' <Lookup glyph="X" value="X.swash"/>', ' <Lookup glyph="Y" value="Y.swash"/>', - ' </PerGlyphLookup>', - ' </StateTable>', - ' </ContextualMorph>', - ' </MorphSubtable>', - '</MorphChain>', + " </PerGlyphLookup>", + " </StateTable>", + " </ContextualMorph>", + " </MorphSubtable>", + "</MorphChain>", ] @@ -482,91 +476,84 @@ MORX_CONTEXTUAL_XML = [ # # TODO: Ask Apple to fix “Example 2” in the ‘morx’ specification. MORX_LIGATURE_DATA = deHexStr( - '0002 0000 ' # 0: Version=2, Reserved=0 - '0000 0001 ' # 4: MorphChainCount=1 - '0000 0001 ' # 8: DefaultFlags=1 - '0000 00DA ' # 12: StructLength=218 (+8=226) - '0000 0000 ' # 16: MorphFeatureCount=0 - '0000 0001 ' # 20: MorphSubtableCount=1 - '0000 00CA ' # 24: Subtable[0].StructLength=202 (+24=226) - '80 ' # 28: Subtable[0].CoverageFlags=0x80 - '00 00 ' # 29: Subtable[0].Reserved=0 - '02 ' # 31: Subtable[0].MorphType=2/LigatureMorph - '0000 0001 ' # 32: Subtable[0].SubFeatureFlags=0x1 - + "0002 0000 " # 0: Version=2, Reserved=0 + "0000 0001 " # 4: MorphChainCount=1 + "0000 0001 " # 8: DefaultFlags=1 + "0000 00DA " # 12: StructLength=218 (+8=226) + "0000 0000 " # 16: MorphFeatureCount=0 + "0000 0001 " # 20: MorphSubtableCount=1 + "0000 00CA " # 24: Subtable[0].StructLength=202 (+24=226) + "80 " # 28: Subtable[0].CoverageFlags=0x80 + "00 00 " # 29: Subtable[0].Reserved=0 + "02 " # 31: Subtable[0].MorphType=2/LigatureMorph + "0000 0001 " # 32: Subtable[0].SubFeatureFlags=0x1 # State table header. - '0000 0007 ' # 36: STXHeader.ClassCount=7 - '0000 001C ' # 40: STXHeader.ClassTableOffset=28 (+36=64) - '0000 0040 ' # 44: STXHeader.StateArrayOffset=64 (+36=100) - '0000 0078 ' # 48: STXHeader.EntryTableOffset=120 (+36=156) - '0000 0090 ' # 52: STXHeader.LigActionsOffset=144 (+36=180) - '0000 009C ' # 56: STXHeader.LigComponentsOffset=156 (+36=192) - '0000 00AE ' # 60: STXHeader.LigListOffset=174 (+36=210) - + "0000 0007 " # 36: STXHeader.ClassCount=7 + "0000 001C " # 40: STXHeader.ClassTableOffset=28 (+36=64) + "0000 0040 " # 44: STXHeader.StateArrayOffset=64 (+36=100) + "0000 0078 " # 48: STXHeader.EntryTableOffset=120 (+36=156) + "0000 0090 " # 52: STXHeader.LigActionsOffset=144 (+36=180) + "0000 009C " # 56: STXHeader.LigComponentsOffset=156 (+36=192) + "0000 00AE " # 60: STXHeader.LigListOffset=174 (+36=210) # Glyph class table. - '0002 0006 ' # 64: ClassTable.LookupFormat=2, .UnitSize=6 - '0003 000C ' # 68: .NUnits=3, .SearchRange=12 - '0001 0006 ' # 72: .EntrySelector=1, .RangeShift=6 - '0016 0014 0004 ' # 76: GlyphID 20..22 [a..c] -> GlyphClass 4 - '0018 0017 0005 ' # 82: GlyphID 23..24 [d..e] -> GlyphClass 5 - '001C 001A 0006 ' # 88: GlyphID 26..28 [g..i] -> GlyphClass 6 - 'FFFF FFFF 0000 ' # 94: <end of lookup> - + "0002 0006 " # 64: ClassTable.LookupFormat=2, .UnitSize=6 + "0003 000C " # 68: .NUnits=3, .SearchRange=12 + "0001 0006 " # 72: .EntrySelector=1, .RangeShift=6 + "0016 0014 0004 " # 76: GlyphID 20..22 [a..c] -> GlyphClass 4 + "0018 0017 0005 " # 82: GlyphID 23..24 [d..e] -> GlyphClass 5 + "001C 001A 0006 " # 88: GlyphID 26..28 [g..i] -> GlyphClass 6 + "FFFF FFFF 0000 " # 94: <end of lookup> # State array. - '0000 0000 0000 0000 0001 0000 0000 ' # 100: State[0][0..6] - '0000 0000 0000 0000 0001 0000 0000 ' # 114: State[1][0..6] - '0000 0000 0000 0000 0001 0002 0000 ' # 128: State[2][0..6] - '0000 0000 0000 0000 0001 0002 0003 ' # 142: State[3][0..6] - + "0000 0000 0000 0000 0001 0000 0000 " # 100: State[0][0..6] + "0000 0000 0000 0000 0001 0000 0000 " # 114: State[1][0..6] + "0000 0000 0000 0000 0001 0002 0000 " # 128: State[2][0..6] + "0000 0000 0000 0000 0001 0002 0003 " # 142: State[3][0..6] # Entry table. - '0000 0000 ' # 156: Entries[0].NewState=0, .Flags=0 - '0000 ' # 160: Entries[0].ActionIndex=<n/a> because no 0x2000 flag - '0002 8000 ' # 162: Entries[1].NewState=2, .Flags=0x8000 (SetComponent) - '0000 ' # 166: Entries[1].ActionIndex=<n/a> because no 0x2000 flag - '0003 8000 ' # 168: Entries[2].NewState=3, .Flags=0x8000 (SetComponent) - '0000 ' # 172: Entries[2].ActionIndex=<n/a> because no 0x2000 flag - '0000 A000 ' # 174: Entries[3].NewState=0, .Flags=0xA000 (SetComponent,Act) - '0000 ' # 178: Entries[3].ActionIndex=0 (start at Action[0]) - + "0000 0000 " # 156: Entries[0].NewState=0, .Flags=0 + "0000 " # 160: Entries[0].ActionIndex=<n/a> because no 0x2000 flag + "0002 8000 " # 162: Entries[1].NewState=2, .Flags=0x8000 (SetComponent) + "0000 " # 166: Entries[1].ActionIndex=<n/a> because no 0x2000 flag + "0003 8000 " # 168: Entries[2].NewState=3, .Flags=0x8000 (SetComponent) + "0000 " # 172: Entries[2].ActionIndex=<n/a> because no 0x2000 flag + "0000 A000 " # 174: Entries[3].NewState=0, .Flags=0xA000 (SetComponent,Act) + "0000 " # 178: Entries[3].ActionIndex=0 (start at Action[0]) # Ligature actions table. - '3FFF FFE7 ' # 180: Action[0].Flags=0, .GlyphIndexDelta=-25 - '3FFF FFED ' # 184: Action[1].Flags=0, .GlyphIndexDelta=-19 - 'BFFF FFF2 ' # 188: Action[2].Flags=<end of list>, .GlyphIndexDelta=-14 - + "3FFF FFE7 " # 180: Action[0].Flags=0, .GlyphIndexDelta=-25 + "3FFF FFED " # 184: Action[1].Flags=0, .GlyphIndexDelta=-19 + "BFFF FFF2 " # 188: Action[2].Flags=<end of list>, .GlyphIndexDelta=-14 # Ligature component table. - '0000 0001 ' # 192: LigComponent[0]=0, LigComponent[1]=1 - '0002 0003 ' # 196: LigComponent[2]=2, LigComponent[3]=3 - '0000 0004 ' # 200: LigComponent[4]=0, LigComponent[5]=4 - '0000 0008 ' # 204: LigComponent[6]=0, LigComponent[7]=8 - '0010 ' # 208: LigComponent[8]=16 - + "0000 0001 " # 192: LigComponent[0]=0, LigComponent[1]=1 + "0002 0003 " # 196: LigComponent[2]=2, LigComponent[3]=3 + "0000 0004 " # 200: LigComponent[4]=0, LigComponent[5]=4 + "0000 0008 " # 204: LigComponent[6]=0, LigComponent[7]=8 + "0010 " # 208: LigComponent[8]=16 # Ligature list. - '03E8 03E9 ' # 210: LigList[0]=1000, LigList[1]=1001 - '03EA 03EB ' # 214: LigList[2]=1002, LigList[3]=1003 - '03EC 03ED ' # 218: LigList[4]=1004, LigList[3]=1005 - '03EE 03EF ' # 222: LigList[5]=1006, LigList[6]=1007 -) # 226: <end> + "03E8 03E9 " # 210: LigList[0]=1000, LigList[1]=1001 + "03EA 03EB " # 214: LigList[2]=1002, LigList[3]=1003 + "03EC 03ED " # 218: LigList[4]=1004, LigList[3]=1005 + "03EE 03EF " # 222: LigList[5]=1006, LigList[6]=1007 +) # 226: <end> assert len(MORX_LIGATURE_DATA) == 226, len(MORX_LIGATURE_DATA) MORX_LIGATURE_XML = [ '<Version value="2"/>', '<Reserved value="0"/>', - '<!-- MorphChainCount=1 -->', + "<!-- MorphChainCount=1 -->", '<MorphChain index="0">', ' <DefaultFlags value="0x00000001"/>', - ' <!-- StructLength=218 -->', - ' <!-- MorphFeatureCount=0 -->', - ' <!-- MorphSubtableCount=1 -->', + " <!-- StructLength=218 -->", + " <!-- MorphFeatureCount=0 -->", + " <!-- MorphSubtableCount=1 -->", ' <MorphSubtable index="0">', - ' <!-- StructLength=202 -->', + " <!-- StructLength=202 -->", ' <TextDirection value="Vertical"/>', ' <ProcessingOrder value="LayoutOrder"/>', - ' <!-- MorphType=2 -->', + " <!-- MorphType=2 -->", ' <SubFeatureFlags value="0x00000001"/>', - ' <LigatureMorph>', - ' <StateTable>', - ' <!-- GlyphClassCount=7 -->', + " <LigatureMorph>", + " <StateTable>", + " <!-- GlyphClassCount=7 -->", ' <GlyphClass glyph="a" value="4"/>', ' <GlyphClass glyph="b" value="4"/>', ' <GlyphClass glyph="c" value="4"/>', @@ -578,106 +565,106 @@ MORX_LIGATURE_XML = [ ' <State index="0">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', ' <Flags value="SetComponent"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="6">', ' <NewState value="0"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="1">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', ' <Flags value="SetComponent"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="6">', ' <NewState value="0"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="2">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', ' <Flags value="SetComponent"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="3"/>', ' <Flags value="SetComponent"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="6">', ' <NewState value="0"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="3">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', ' <Flags value="SetComponent"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="3"/>', ' <Flags value="SetComponent"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="6">', ' <NewState value="0"/>', ' <Flags value="SetComponent"/>', ' <Action GlyphIndexDelta="-25"/>', ' <Action GlyphIndexDelta="-19"/>', ' <Action GlyphIndexDelta="-14"/>', - ' </Transition>', - ' </State>', - ' <LigComponents>', + " </Transition>", + " </State>", + " <LigComponents>", ' <LigComponent index="0" value="0"/>', ' <LigComponent index="1" value="1"/>', ' <LigComponent index="2" value="2"/>', @@ -687,8 +674,8 @@ MORX_LIGATURE_XML = [ ' <LigComponent index="6" value="0"/>', ' <LigComponent index="7" value="8"/>', ' <LigComponent index="8" value="16"/>', - ' </LigComponents>', - ' <Ligatures>', + " </LigComponents>", + " <Ligatures>", ' <Ligature glyph="adf" index="0"/>', ' <Ligature glyph="adg" index="1"/>', ' <Ligature glyph="adh" index="2"/>', @@ -697,84 +684,84 @@ MORX_LIGATURE_XML = [ ' <Ligature glyph="aeg" index="5"/>', ' <Ligature glyph="aeh" index="6"/>', ' <Ligature glyph="aei" index="7"/>', - ' </Ligatures>', - ' </StateTable>', - ' </LigatureMorph>', - ' </MorphSubtable>', - '</MorphChain>', + " </Ligatures>", + " </StateTable>", + " </LigatureMorph>", + " </MorphSubtable>", + "</MorphChain>", ] # Taken from the `morx` table of the second font in DevanagariSangamMN.ttc # on macOS X 10.12.6; manually pruned to just contain the insertion lookup. MORX_INSERTION_DATA = deHexStr( - '0002 0000 ' # 0: Version=2, Reserved=0 - '0000 0001 ' # 4: MorphChainCount=1 - '0000 0001 ' # 8: DefaultFlags=1 - '0000 00A4 ' # 12: StructLength=164 (+8=172) - '0000 0000 ' # 16: MorphFeatureCount=0 - '0000 0001 ' # 20: MorphSubtableCount=1 - '0000 0094 ' # 24: Subtable[0].StructLength=148 (+24=172) - '00 ' # 28: Subtable[0].CoverageFlags=0x00 - '00 00 ' # 29: Subtable[0].Reserved=0 - '05 ' # 31: Subtable[0].MorphType=5/InsertionMorph - '0000 0001 ' # 32: Subtable[0].SubFeatureFlags=0x1 - '0000 0006 ' # 36: STXHeader.ClassCount=6 - '0000 0014 ' # 40: STXHeader.ClassTableOffset=20 (+36=56) - '0000 004A ' # 44: STXHeader.StateArrayOffset=74 (+36=110) - '0000 006E ' # 48: STXHeader.EntryTableOffset=110 (+36=146) - '0000 0086 ' # 52: STXHeader.InsertionActionOffset=134 (+36=170) - # Glyph class table. - '0002 0006 ' # 56: ClassTable.LookupFormat=2, .UnitSize=6 - '0006 0018 ' # 60: .NUnits=6, .SearchRange=24 - '0002 000C ' # 64: .EntrySelector=2, .RangeShift=12 - '00AC 00AC 0005 ' # 68: GlyphID 172..172 -> GlyphClass 5 - '01EB 01E6 0005 ' # 74: GlyphID 486..491 -> GlyphClass 5 - '01F0 01F0 0004 ' # 80: GlyphID 496..496 -> GlyphClass 4 - '01F8 01F6 0004 ' # 88: GlyphID 502..504 -> GlyphClass 4 - '01FC 01FA 0004 ' # 92: GlyphID 506..508 -> GlyphClass 4 - '0250 0250 0005 ' # 98: GlyphID 592..592 -> GlyphClass 5 - 'FFFF FFFF 0000 ' # 104: <end of lookup> + "0002 0000 " # 0: Version=2, Reserved=0 + "0000 0001 " # 4: MorphChainCount=1 + "0000 0001 " # 8: DefaultFlags=1 + "0000 00A4 " # 12: StructLength=164 (+8=172) + "0000 0000 " # 16: MorphFeatureCount=0 + "0000 0001 " # 20: MorphSubtableCount=1 + "0000 0094 " # 24: Subtable[0].StructLength=148 (+24=172) + "00 " # 28: Subtable[0].CoverageFlags=0x00 + "00 00 " # 29: Subtable[0].Reserved=0 + "05 " # 31: Subtable[0].MorphType=5/InsertionMorph + "0000 0001 " # 32: Subtable[0].SubFeatureFlags=0x1 + "0000 0006 " # 36: STXHeader.ClassCount=6 + "0000 0014 " # 40: STXHeader.ClassTableOffset=20 (+36=56) + "0000 004A " # 44: STXHeader.StateArrayOffset=74 (+36=110) + "0000 006E " # 48: STXHeader.EntryTableOffset=110 (+36=146) + "0000 0086 " # 52: STXHeader.InsertionActionOffset=134 (+36=170) + # Glyph class table. + "0002 0006 " # 56: ClassTable.LookupFormat=2, .UnitSize=6 + "0006 0018 " # 60: .NUnits=6, .SearchRange=24 + "0002 000C " # 64: .EntrySelector=2, .RangeShift=12 + "00AC 00AC 0005 " # 68: GlyphID 172..172 -> GlyphClass 5 + "01EB 01E6 0005 " # 74: GlyphID 486..491 -> GlyphClass 5 + "01F0 01F0 0004 " # 80: GlyphID 496..496 -> GlyphClass 4 + "01F8 01F6 0004 " # 88: GlyphID 502..504 -> GlyphClass 4 + "01FC 01FA 0004 " # 92: GlyphID 506..508 -> GlyphClass 4 + "0250 0250 0005 " # 98: GlyphID 592..592 -> GlyphClass 5 + "FFFF FFFF 0000 " # 104: <end of lookup> # State array. - '0000 0000 0000 0000 0001 0000 ' # 110: State[0][0..5] - '0000 0000 0000 0000 0001 0000 ' # 122: State[1][0..5] - '0000 0000 0001 0000 0001 0002 ' # 134: State[2][0..5] + "0000 0000 0000 0000 0001 0000 " # 110: State[0][0..5] + "0000 0000 0000 0000 0001 0000 " # 122: State[1][0..5] + "0000 0000 0001 0000 0001 0002 " # 134: State[2][0..5] # Entry table. - '0000 0000 ' # 146: Entries[0].NewState=0, .Flags=0 - 'FFFF ' # 150: Entries[0].CurrentInsertIndex=<None> - 'FFFF ' # 152: Entries[0].MarkedInsertIndex=<None> - '0002 0000 ' # 154: Entries[1].NewState=0, .Flags=0 - 'FFFF ' # 158: Entries[1].CurrentInsertIndex=<None> - 'FFFF ' # 160: Entries[1].MarkedInsertIndex=<None> - '0000 ' # 162: Entries[2].NewState=0 - '2820 ' # 164: .Flags=CurrentIsKashidaLike,CurrentInsertBefore - # .CurrentInsertCount=1, .MarkedInsertCount=0 - '0000 ' # 166: Entries[1].CurrentInsertIndex=0 - 'FFFF ' # 168: Entries[1].MarkedInsertIndex=<None> + "0000 0000 " # 146: Entries[0].NewState=0, .Flags=0 + "FFFF " # 150: Entries[0].CurrentInsertIndex=<None> + "FFFF " # 152: Entries[0].MarkedInsertIndex=<None> + "0002 0000 " # 154: Entries[1].NewState=0, .Flags=0 + "FFFF " # 158: Entries[1].CurrentInsertIndex=<None> + "FFFF " # 160: Entries[1].MarkedInsertIndex=<None> + "0000 " # 162: Entries[2].NewState=0 + "2820 " # 164: .Flags=CurrentIsKashidaLike,CurrentInsertBefore + # .CurrentInsertCount=1, .MarkedInsertCount=0 + "0000 " # 166: Entries[1].CurrentInsertIndex=0 + "FFFF " # 168: Entries[1].MarkedInsertIndex=<None> # Insertion action table. - '022F' # 170: InsertionActionTable[0]=GlyphID 559 -) # 172: <end> + "022F" # 170: InsertionActionTable[0]=GlyphID 559 +) # 172: <end> assert len(MORX_INSERTION_DATA) == 172, len(MORX_INSERTION_DATA) MORX_INSERTION_XML = [ '<Version value="2"/>', '<Reserved value="0"/>', - '<!-- MorphChainCount=1 -->', + "<!-- MorphChainCount=1 -->", '<MorphChain index="0">', ' <DefaultFlags value="0x00000001"/>', - ' <!-- StructLength=164 -->', - ' <!-- MorphFeatureCount=0 -->', - ' <!-- MorphSubtableCount=1 -->', + " <!-- StructLength=164 -->", + " <!-- MorphFeatureCount=0 -->", + " <!-- MorphSubtableCount=1 -->", ' <MorphSubtable index="0">', - ' <!-- StructLength=148 -->', + " <!-- StructLength=148 -->", ' <TextDirection value="Horizontal"/>', ' <ProcessingOrder value="LayoutOrder"/>', - ' <!-- MorphType=5 -->', + " <!-- MorphType=5 -->", ' <SubFeatureFlags value="0x00000001"/>', - ' <InsertionMorph>', - ' <StateTable>', - ' <!-- GlyphClassCount=6 -->', + " <InsertionMorph>", + " <StateTable>", + " <!-- GlyphClassCount=6 -->", ' <GlyphClass glyph="g.172" value="5"/>', ' <GlyphClass glyph="g.486" value="5"/>', ' <GlyphClass glyph="g.487" value="5"/>', @@ -793,211 +780,205 @@ MORX_INSERTION_XML = [ ' <State index="0">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="0"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="1">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="0"/>', - ' </Transition>', - ' </State>', + " </Transition>", + " </State>", ' <State index="2">', ' <Transition onGlyphClass="0">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="1">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="2">', ' <NewState value="2"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="3">', ' <NewState value="0"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="4">', ' <NewState value="2"/>', - ' </Transition>', + " </Transition>", ' <Transition onGlyphClass="5">', ' <NewState value="0"/>', ' <Flags value="CurrentIsKashidaLike,CurrentInsertBefore"/>', ' <CurrentInsertionAction glyph="g.559"/>', - ' </Transition>', - ' </State>', - ' </StateTable>', - ' </InsertionMorph>', - ' </MorphSubtable>', - '</MorphChain>', + " </Transition>", + " </State>", + " </StateTable>", + " </InsertionMorph>", + " </MorphSubtable>", + "</MorphChain>", ] class MORXNoncontextualGlyphSubstitutionTest(unittest.TestCase): - @classmethod def setUpClass(cls): cls.maxDiff = None - glyphs = ['.notdef'] + ['g.%d' % i for i in range (1, 140)] - glyphs[11], glyphs[13] = 'parenleft', 'parenright' - glyphs[135], glyphs[136] = 'parenleft.vertical', 'parenright.vertical' + glyphs = [".notdef"] + ["g.%d" % i for i in range(1, 140)] + glyphs[11], glyphs[13] = "parenleft", "parenright" + glyphs[135], glyphs[136] = "parenleft.vertical", "parenright.vertical" cls.font = FakeFont(glyphs) def test_decompile_toXML(self): - table = newTable('morx') + table = newTable("morx") table.decompile(MORX_NONCONTEXTUAL_DATA, self.font) self.assertEqual(getXML(table.toXML), MORX_NONCONTEXTUAL_XML) def test_compile_fromXML(self): - table = newTable('morx') + table = newTable("morx") for name, attrs, content in parseXML(MORX_NONCONTEXTUAL_XML): table.fromXML(name, attrs, content, font=self.font) - self.assertEqual(hexStr(table.compile(self.font)), - hexStr(MORX_NONCONTEXTUAL_DATA)) + self.assertEqual( + hexStr(table.compile(self.font)), hexStr(MORX_NONCONTEXTUAL_DATA) + ) class MORXRearrangementTest(unittest.TestCase): - @classmethod def setUpClass(cls): cls.maxDiff = None - cls.font = FakeFont(['.nodef', 'A', 'B', 'C']) + cls.font = FakeFont([".nodef", "A", "B", "C"]) def test_decompile_toXML(self): - table = newTable('morx') + table = newTable("morx") table.decompile(MORX_REARRANGEMENT_DATA, self.font) self.assertEqual(getXML(table.toXML), MORX_REARRANGEMENT_XML) def test_compile_fromXML(self): - table = newTable('morx') + table = newTable("morx") for name, attrs, content in parseXML(MORX_REARRANGEMENT_XML): table.fromXML(name, attrs, content, font=self.font) - self.assertEqual(hexStr(table.compile(self.font)), - hexStr(MORX_REARRANGEMENT_DATA)) + self.assertEqual( + hexStr(table.compile(self.font)), hexStr(MORX_REARRANGEMENT_DATA) + ) class MORXContextualSubstitutionTest(unittest.TestCase): - @classmethod def setUpClass(cls): cls.maxDiff = None - g = ['.notdef'] + ['g.%d' % i for i in range (1, 910)] - g[80] = 'C' - g[50], g[52], g[201], g[202] = 'A', 'B', 'X', 'Y' - g[600], g[601], g[602], g[900] = ( - 'A.swash', 'B.swash', 'X.swash', 'Y.swash') + g = [".notdef"] + ["g.%d" % i for i in range(1, 910)] + g[80] = "C" + g[50], g[52], g[201], g[202] = "A", "B", "X", "Y" + g[600], g[601], g[602], g[900] = ("A.swash", "B.swash", "X.swash", "Y.swash") cls.font = FakeFont(g) def test_decompile_toXML(self): - table = newTable('morx') + table = newTable("morx") table.decompile(MORX_CONTEXTUAL_DATA, self.font) self.assertEqual(getXML(table.toXML), MORX_CONTEXTUAL_XML) def test_compile_fromXML(self): - table = newTable('morx') + table = newTable("morx") for name, attrs, content in parseXML(MORX_CONTEXTUAL_XML): table.fromXML(name, attrs, content, font=self.font) - self.assertEqual(hexStr(table.compile(self.font)), - hexStr(MORX_CONTEXTUAL_DATA)) + self.assertEqual(hexStr(table.compile(self.font)), hexStr(MORX_CONTEXTUAL_DATA)) class MORXLigatureSubstitutionTest(unittest.TestCase): - @classmethod def setUpClass(cls): cls.maxDiff = None - g = ['.notdef'] + ['g.%d' % i for i in range (1, 1515)] - g[20:29] = 'a b c d e f g h i'.split() - g[1000:1008] = 'adf adg adh adi aef aeg aeh aei'.split() - g[1008:1016] = 'bdf bdg bdh bdi bef beg beh bei'.split() - g[1500:1507] = 'cdf cdg cdh cdi cef ceg ceh'.split() - g[1511] = 'cei' + g = [".notdef"] + ["g.%d" % i for i in range(1, 1515)] + g[20:29] = "a b c d e f g h i".split() + g[1000:1008] = "adf adg adh adi aef aeg aeh aei".split() + g[1008:1016] = "bdf bdg bdh bdi bef beg beh bei".split() + g[1500:1507] = "cdf cdg cdh cdi cef ceg ceh".split() + g[1511] = "cei" cls.font = FakeFont(g) def test_decompile_toXML(self): - table = newTable('morx') + table = newTable("morx") table.decompile(MORX_LIGATURE_DATA, self.font) self.assertEqual(getXML(table.toXML), MORX_LIGATURE_XML) def test_compile_fromXML(self): - table = newTable('morx') + table = newTable("morx") for name, attrs, content in parseXML(MORX_LIGATURE_XML): table.fromXML(name, attrs, content, font=self.font) - self.assertEqual(hexStr(table.compile(self.font)), - hexStr(MORX_LIGATURE_DATA)) + self.assertEqual(hexStr(table.compile(self.font)), hexStr(MORX_LIGATURE_DATA)) class MORXGlyphInsertionTest(unittest.TestCase): - @classmethod def setUpClass(cls): cls.maxDiff = None - cls.font = FakeFont(['.notdef'] + ['g.%d' % i for i in range (1, 910)]) + cls.font = FakeFont([".notdef"] + ["g.%d" % i for i in range(1, 910)]) def test_decompile_toXML(self): - table = newTable('morx') + table = newTable("morx") table.decompile(MORX_INSERTION_DATA, self.font) self.assertEqual(getXML(table.toXML), MORX_INSERTION_XML) def test_compile_fromXML(self): - table = newTable('morx') + table = newTable("morx") for name, attrs, content in parseXML(MORX_INSERTION_XML): table.fromXML(name, attrs, content, font=self.font) - self.assertEqual(hexStr(table.compile(self.font)), - hexStr(MORX_INSERTION_DATA)) + self.assertEqual(hexStr(table.compile(self.font)), hexStr(MORX_INSERTION_DATA)) class MORXCoverageFlagsTest(unittest.TestCase): - @classmethod def setUpClass(cls): cls.maxDiff = None - cls.font = FakeFont(['.notdef', 'A', 'B', 'C']) - - def checkFlags(self, flags, textDirection, processingOrder, - checkCompile=True): - data = bytesjoin([ - MORX_REARRANGEMENT_DATA[:28], - bytechr(flags << 4), - MORX_REARRANGEMENT_DATA[29:]]) + cls.font = FakeFont([".notdef", "A", "B", "C"]) + + def checkFlags(self, flags, textDirection, processingOrder, checkCompile=True): + data = bytesjoin( + [ + MORX_REARRANGEMENT_DATA[:28], + bytechr(flags << 4), + MORX_REARRANGEMENT_DATA[29:], + ] + ) xml = [] for line in MORX_REARRANGEMENT_XML: - if line.startswith(' <TextDirection '): + if line.startswith(" <TextDirection "): line = ' <TextDirection value="%s"/>' % textDirection - elif line.startswith(' <ProcessingOrder '): + elif line.startswith(" <ProcessingOrder "): line = ' <ProcessingOrder value="%s"/>' % processingOrder xml.append(line) - table1 = newTable('morx') + table1 = newTable("morx") table1.decompile(data, self.font) self.assertEqual(getXML(table1.toXML), xml) if checkCompile: - table2 = newTable('morx') + table2 = newTable("morx") for name, attrs, content in parseXML(xml): table2.fromXML(name, attrs, content, font=self.font) self.assertEqual(hexStr(table2.compile(self.font)), hexStr(data)) @@ -1034,17 +1015,22 @@ class MORXCoverageFlagsTest(unittest.TestCase): # Note that the lower 4 bits of the first byte are already # part of the Reserved value. We test the full round-trip # to encoding and decoding is quite hairy. - data = bytesjoin([ - MORX_REARRANGEMENT_DATA[:28], - bytechr(0x8A), bytechr(0xBC), bytechr(0xDE), - MORX_REARRANGEMENT_DATA[31:]]) - table = newTable('morx') + data = bytesjoin( + [ + MORX_REARRANGEMENT_DATA[:28], + bytechr(0x8A), + bytechr(0xBC), + bytechr(0xDE), + MORX_REARRANGEMENT_DATA[31:], + ] + ) + table = newTable("morx") table.decompile(data, self.font) subtable = table.table.MorphChain[0].MorphSubtable[0] self.assertEqual(subtable.Reserved, 0xABCDE) xml = getXML(table.toXML) self.assertIn(' <Reserved value="0xabcde"/>', xml) - table2 = newTable('morx') + table2 = newTable("morx") for name, attrs, content in parseXML(xml): table2.fromXML(name, attrs, content, font=self.font) self.assertEqual(hexStr(table2.compile(self.font)[28:31]), "8abcde") @@ -1059,16 +1045,17 @@ class UnsupportedMorxLookupTest(unittest.TestCase): self.assertRaisesRegex = self.assertRaisesRegexp def test_unsupportedLookupType(self): - data = bytesjoin([ - MORX_NONCONTEXTUAL_DATA[:67], - bytechr(66), - MORX_NONCONTEXTUAL_DATA[69:]]) - with self.assertRaisesRegex(AssertionError, - r"unsupported 'morx' lookup type 66"): - morx = newTable('morx') - morx.decompile(data, FakeFont(['.notdef'])) + data = bytesjoin( + [MORX_NONCONTEXTUAL_DATA[:67], bytechr(66), MORX_NONCONTEXTUAL_DATA[69:]] + ) + with self.assertRaisesRegex( + AssertionError, r"unsupported 'morx' lookup type 66" + ): + morx = newTable("morx") + morx.decompile(data, FakeFont([".notdef"])) -if __name__ == '__main__': +if __name__ == "__main__": import sys + sys.exit(unittest.main()) |