private IGlyphTransformationTable ParseLigatureSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.LigatureSubstitutionSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); if (format != 1) { throw new UnknownTableFormatException(type, format); } var ligatureSetTables = this.GetEnumerableFromInternalList( () => table.LigatureSetCount(fontTable.Wrapped), i => (dynamic) new AccessPrivateWrapper(table.LigatureSet(fontTable.Wrapped, i))).ToList(); var ligatures = ligatureSetTables .Select( ligatureSetTable => this.GetEnumerableFromInternalList( () => ligatureSetTable.LigatureCount(fontTable.Wrapped), i => (dynamic) new AccessPrivateWrapper(ligatureSetTable.Ligature(fontTable.Wrapped, i))) .Select( ligatureTable => new Ligature { LigatureGlyphId = (ushort)ligatureTable.LigatureGlyph(fontTable.Wrapped), ComponentGlyphIds = this.GetEnumerableFromInternalList( () => (ushort)(ligatureTable.ComponentCount(fontTable.Wrapped) - 1), i => (ushort)ligatureTable.Component(fontTable.Wrapped, (ushort)(i + 1))) }).ToList()).ToList(); return(new LigatureSubstitutionTable { Coverage = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))), LigatureSets = ligatures.ToList(), LookupFlags = lookupFlags }); }
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); }
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); } }
private IGlyphTransformationTable ParseMultipleSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.MultipleSubstitutionSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); if (format != 1) { throw new UnknownTableFormatException(type, format); } var coverageTable = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); var substitutionSequenceTables = this.GetEnumerableFromInternalList( () => (ushort)coverageTable.CoveredGlyphIds.Count, i => (dynamic) new AccessPrivateWrapper(table.Sequence(fontTable.Wrapped, i))).ToList(); var sequences = substitutionSequenceTables .Select( sequenceTable => this.GetEnumerableFromInternalList( () => sequenceTable.GlyphCount(fontTable.Wrapped), i => (ushort)sequenceTable.Glyph(fontTable.Wrapped, i))).ToList(); return(new MultipleSubstitutionTable { Coverage = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))), ReplacementSequences = sequences.ToList(), LookupFlags = lookupFlags }); }
private IGlyphTransformationTable ParseClassChainingSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.ClassChainingSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); var coverageTable = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); var ruleSetTables = this.GetEnumerableFromInternalList( () => (ushort)table.ClassSetCount(fontTable.Wrapped), i => (dynamic) new AccessPrivateWrapper(table.ClassSet(fontTable.Wrapped, i))).ToList(); var LookbackClassDefinition = fontTable.GetUShort(table.offset + table.offsetBacktrackClassDef) == 0 ? RangeGlyphClassDefinition.CreateEmptyClassDef() : this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.BacktrackClassDef(fontTable.Wrapped))); var ContextClassDefinitions = this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.InputClassDef(fontTable.Wrapped))); var LookaheadClassDefinition = fontTable.GetUShort(table.offset + table.offsetLookaheadClassDef) == 0 ? RangeGlyphClassDefinition.CreateEmptyClassDef() : this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.LookaheadClassDef(fontTable.Wrapped))); return(new ChainingClassContextTransformationTable { Coverage = coverageTable, LookbackClassDefinition = fontTable.GetUShort(table.offset + table.offsetBacktrackClassDef) == 0 ? RangeGlyphClassDefinition.CreateEmptyClassDef() : this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.BacktrackClassDef(fontTable.Wrapped))), ContextClassDefinitions = this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.InputClassDef(fontTable.Wrapped))), LookaheadClassDefinition = fontTable.GetUShort(table.offset + table.offsetLookaheadClassDef) == 0 ? RangeGlyphClassDefinition.CreateEmptyClassDef() : this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.LookaheadClassDef(fontTable.Wrapped))), TransformationRules = ruleSetTables .Select( ruleSetTable => ruleSetTable.IsNull ? Enumerable.Empty <ChainingContextTransformationRule>() : this.GetEnumerableFromInternalList( () => ruleSetTable.RuleCount(fontTable.Wrapped), i => (ChainingContextTransformationRule)this.ParseChainingTransformationRule( fontTable, new AccessPrivateWrapper(ruleSetTable.Rule(fontTable.Wrapped, i)), (Func <dynamic, int, ushort>)((ruleTable, index) => (ushort)ruleTable.ClassId(fontTable.Wrapped, index)), (ushort)i)).ToList()).ToList(), LookupFlags = lookupFlags }); }
private IGlyphTransformationTable ParseGlyphChainingSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.GlyphChainingSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); var coverageTable = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); var ruleSetTables = this.GetEnumerableFromInternalList( () => (ushort)coverageTable.CoveredGlyphIds.Count(), i => (dynamic) new AccessPrivateWrapper(table.RuleSet(fontTable.Wrapped, i))).ToList(); return(new ChainingGlyphContextTransformationTable { Coverage = coverageTable, TransformationRules = ruleSetTables .Select( ruleSetTable => this.GetEnumerableFromInternalList( () => ruleSetTable.RuleCount(fontTable.Wrapped), i => (ChainingContextTransformationRule)this.ParseChainingTransformationRule( fontTable, new AccessPrivateWrapper(table.Rule(fontTable.Wrapped, i)), (Func <dynamic, int, ushort>)((ruleTable, index) => (ushort)ruleTable.GlyphId(fontTable.Wrapped, index)), coverageTable.CoveredGlyphIds[i])).ToList()).ToList(), LookupFlags = lookupFlags }); }
private IGlyphTransformationTable ParseCursivePositioningTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.CursivePositioningSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); if (format != 1) { throw new UnknownTableFormatException(type, format); } var coverage = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); var coveredGlyphCount = coverage.CoveredGlyphIds.Count(); return(new CursivePositioningTable { Coverage = coverage, EntryExitRecords = this.GetEnumerableFromInternalList( () => (ushort)coveredGlyphCount, i => Tuple.Create( (AnchorPoint)this.ParseAnchor(fontTable, new AccessPrivateWrapper(table.EntryAnchor(fontTable.Wrapped, i))), (AnchorPoint)this.ParseAnchor(fontTable, new AccessPrivateWrapper(table.ExitAnchor(fontTable.Wrapped, i))) )).ToList(), LookupFlags = lookupFlags }); }
private IGlyphTransformationTable ParsePairPositioningTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.PairPositioningSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); var coverage = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); var coveredGlyphCount = coverage.CoveredGlyphIds.Count(); switch (format) { case 1: var pairSetTables = this.GetEnumerableFromInternalList( () => (ushort)coveredGlyphCount, i => (dynamic) new AccessPrivateWrapper(table.Format1PairSet(fontTable.Wrapped, i))).ToList(); return(new GlyphPairPositioningTable { Coverage = coverage, PairSets = pairSetTables.Select(pairSet => this.GetEnumerableFromInternalList( () => (ushort)pairSet.PairValueCount(fontTable.Wrapped), i => new PositioningPair { SecondGlyphID = (ushort)pairSet.PairValueGlyph(fontTable.Wrapped, i), FirstGlyphPositionChange = this.ParseValueRecord(fontTable, new AccessPrivateWrapper(pairSet.FirstValueRecord(fontTable.Wrapped, i, table.FirstValueFormat(fontTable.Wrapped)))), SecondGlyphPositionChange = this.ParseValueRecord(fontTable, new AccessPrivateWrapper(pairSet.SecondValueRecord(fontTable.Wrapped, i, table.SecondValueFormat(fontTable.Wrapped)))), }).ToList()).ToList(), LookupFlags = lookupFlags }); case 2: var class2Count = (ushort)table.Format2Class2Count(fontTable.Wrapped); return(new ClassPairPositioningTable { Coverage = coverage, FirstClassDef = this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.Format2Class1Table(fontTable.Wrapped))), SecondClassDef = this.ParseClassDef(fontTable, new AccessPrivateWrapper(table.Format2Class2Table(fontTable.Wrapped))), PairSets = (from i in Enumerable.Range(0, (ushort)table.Format2Class1Count(fontTable.Wrapped)) select (from j in Enumerable.Range(0, class2Count) select Tuple.Create( (GlyphPositionChange)this.ParseValueRecord(fontTable, new AccessPrivateWrapper(table.Format2FirstValueRecord(fontTable.Wrapped, class2Count, (ushort)i, (ushort)j))), (GlyphPositionChange)this.ParseValueRecord(fontTable, new AccessPrivateWrapper(table.Format2SecondValueRecord(fontTable.Wrapped, class2Count, (ushort)i, (ushort)j))) )).ToList()).ToList(), LookupFlags = lookupFlags }); default: throw new UnknownTableFormatException(type, format); } }
private IGlyphTransformationTable ParseSinglePositioningTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags) { var type = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.SinglePositioningSubtable"); dynamic table = new AccessPrivateWrapper(type.Instantiate(subTableOffset)); ushort format = table.Format(fontTable.Wrapped); switch (format) { case 1: return(new ConstantPositioningTable { Coverage = this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))), PositionChange = this.ParseValueRecord(fontTable, new AccessPrivateWrapper(table.Format1ValueRecord(fontTable.Wrapped))), LookupFlags = lookupFlags }); case 2: var coverage = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.Coverage(fontTable.Wrapped))); return(new IndividualChangePositioningTable { Coverage = coverage, PositionChanges = coverage.CoveredGlyphIds.Keys .Select(coverageIndex => (GlyphPositionChange)this.ParseValueRecord(fontTable, new AccessPrivateWrapper(table.Format2ValueRecord(fontTable.Wrapped, coverageIndex)))).ToList(), LookupFlags = lookupFlags }); default: throw new UnknownTableFormatException(type, format); } }