private IGlyphTransformationTable ParseReverseChainingSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.ReverseChainingSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); if (format != 1) { throw new UnknownTableFormatException(type, format); } var result = new ReverseChainingContextSubstitutionTable { Coverage = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.InputCoverage(fontTable.Wrapped))) }; int currentOffset = table.offset + table.offsetBacktrackGlyphCount; ushort lookbackCount = table.GlyphCount(fontTable.Wrapped, currentOffset); currentOffset += 2; result.LookbackCoverages = this.GetEnumerableFromInternalList( () => lookbackCount, i => (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped, currentOffset))) ).ToList(); currentOffset += 2 * lookbackCount; ushort lookaheadCount = table.GlyphCount(fontTable.Wrapped, currentOffset); currentOffset += 2; result.LookaheadCoverages = this.GetEnumerableFromInternalList( () => lookaheadCount, i => (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped, currentOffset))) ).ToList(); currentOffset += 2 * lookaheadCount; ushort glyphCount = table.GlyphCount(fontTable.Wrapped, currentOffset); currentOffset += 2; result.SubstituteGlyphIds = this.GetEnumerableFromInternalList( () => glyphCount, i => (ushort)table.Glyph(fontTable.Wrapped, currentOffset) ).ToList(); result.LookupFlags = lookupFlags; return(result); }
public void CompileTransformation_ReverseChainingContextSubsitutionTable_CallsBuilderCorrectly() { /* Replaces 104 in (101|201) (102|202) (103|203) (104|204) (105|205) (106|206) (107|208) for 304 and 204 in the same context for 404. */ var table = new ReverseChainingContextSubstitutionTable { Coverage = new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 104, 204 }) }, LookbackCoverages = new [] { new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 103, 203 }) }, new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 102, 202 }) }, new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 101, 201 }) } }, LookaheadCoverages = new[] { new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 105, 205 }) }, new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 106, 206 }) }, new ListCoverageTable { CoveredGlyphIdList = new HashSet <ushort>(new ushort[] { 107, 207 }) } }, SubstituteGlyphIds = new ushort[] { 304, 404 }, LookupFlags = LookupFlags.IgnoreLigatures }; var expected = new IEnumerable <ITransition>[] { new[] { (ITransition) new SetTransition { GlyphIdSet = new HashSet <ushort> { 107, 207 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 106, 206 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 105, 205 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 104, 204 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 103, 203 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 102, 202 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 101, 201 }, HeadShift = 3, LookupFlags = LookupFlags.IgnoreLigatures }, new SimpleTransition { GlyphId = 104, HeadShift = 3, LookupFlags = LookupFlags.IgnoreLigatures, Action = new SubstitutionAction { ReplacedGlyphCount = 1, ReplacementGlyphIds = new ushort[] { 304 } } } }, new[] { (ITransition) new SetTransition { GlyphIdSet = new HashSet <ushort> { 107, 207 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 106, 206 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 105, 205 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 104, 204 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 103, 203 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 102, 202 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 101, 201 }, HeadShift = 3, LookupFlags = LookupFlags.IgnoreLigatures }, new SimpleTransition { GlyphId = 204, HeadShift = 3, LookupFlags = LookupFlags.IgnoreLigatures, Action = new SubstitutionAction { ReplacedGlyphCount = 1, ReplacementGlyphIds = new ushort[] { 404 } } } }, new[] { (ITransition) new SetTransition { GlyphIdSet = new HashSet <ushort> { 107, 207 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 106, 206 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 105, 205 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 104, 204 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 103, 203 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 102, 202 }, HeadShift = -1, LookupFlags = LookupFlags.IgnoreLigatures }, new SetTransition { GlyphIdSet = new HashSet <ushort> { 101, 201 }, HeadShift = 3, LookupFlags = LookupFlags.IgnoreLigatures }, new AlwaysTransition { HeadShift = 3, LookupFlags = LookupFlags.IgnoreLigatures } } }; this.TestCompileTransformation(table, expected, ProcessingDirection.EndToStart); }