private IGlyphTransformationTable ParseSingleSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.SingleSubstitutionSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); switch (format) { case 1: return(new DeltaSubstitutionTable { Coverage = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))), GlyphIdDelta = (short)table.Format1DeltaGlyphId(fontTable.Wrapped), LookupFlags = lookupFlags }); case 2: var coverage = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); return(new SimpleReplacementSubstitutionTable { Coverage = coverage, ReplacementGlyphIds = coverage.CoveredGlyphIds.Keys .Select(coverageIndex => (ushort)table.Format2SubstituteGlyphId(fontTable.Wrapped, coverageIndex)).ToList(), LookupFlags = lookupFlags }); default: throw new UnknownTableFormatException(type, format); } }