예제 #1
0
        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);
            }
        }
예제 #2
0
        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
            });
        }
예제 #3
0
        private IGlyphTransformationTable ParseMarkToBasePositioningTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags)
        {
            var     type   = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.MarkToBasePositioningSubtable");
            dynamic table  = new AccessPrivateWrapper(type.Instantiate(subTableOffset));
            ushort  format = table.Format(fontTable.Wrapped);

            if (format != 1)
            {
                throw new UnknownTableFormatException(type, format);
            }

            dynamic markArrayTable = new AccessPrivateWrapper(table.Marks(fontTable.Wrapped));
            dynamic baseArrayTable = new AccessPrivateWrapper(table.Bases(fontTable.Wrapped));

            return(new MarkToBasePositioningTable
            {
                MarkCoverage = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.MarkCoverage(fontTable.Wrapped))),
                BaseCoverage = (ICoverageTable)this.ParseCoverageTable(fontTable, new AccessPrivateWrapper(table.BaseCoverage(fontTable.Wrapped))),
                MarkAnchorPoints = this.GetEnumerableFromInternalList(
                    () => fontTable.GetUShort(markArrayTable.offset),
                    i =>
                    new Tuple <ushort, AnchorPoint>(
                        (ushort)markArrayTable.Class(fontTable.Wrapped, i),
                        (AnchorPoint)this.ParseAnchor(fontTable, new AccessPrivateWrapper(markArrayTable.MarkAnchor(fontTable.Wrapped, i)))
                        )).ToList(),
                BaseAnchorPoints = this.GetEnumerableFromInternalList(
                    () => fontTable.GetUShort(baseArrayTable.offset),
                    i => this.GetEnumerableFromInternalList(
                        () => table.ClassCount(fontTable.Wrapped),
                        j => (AnchorPoint)this.ParseAnchor(fontTable, new AccessPrivateWrapper(baseArrayTable.BaseAnchor(fontTable.Wrapped, i, table.ClassCount(fontTable.Wrapped), j)))
                        ).ToList()
                    ).ToList(),
                LookupFlags = lookupFlags
            });
        }
예제 #4
0
        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
            });
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        protected IGlyphTransformationTable ParseChainingSubstitutionTable(int subTableOffset, dynamic fontTable, LookupFlags lookupFlags)
        {
            var     type   = typeof(GlyphTypeface).Assembly.GetType("MS.Internal.Shaping.ChainingSubtable");
            dynamic table  = new AccessPrivateWrapper(type.Instantiate(subTableOffset));
            ushort  format = table.Format(fontTable.Wrapped);

            switch (format)
            {
            case 1:
                return(this.ParseGlyphChainingSubstitutionTable(subTableOffset, fontTable, lookupFlags));

            case 2:
                return(this.ParseClassChainingSubstitutionTable(subTableOffset, fontTable, lookupFlags));

            case 3:
                return(this.ParseCoverageChainingSubstitutionTable(subTableOffset, fontTable, lookupFlags));

            default:
                throw new UnknownTableFormatException(type, format);
            }
        }
예제 #9
0
        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
            });
        }