示例#1
0
            public static LookupType3Format1SubTable Load(BigEndianBinaryReader reader, long offset, LookupFlags lookupFlags)
            {
                // Cursive Attachment Positioning Format1.
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Type               |  Name                           | Description                                          |
                // +====================+=================================+======================================================+
                // | uint16             | posFormat                       | Format identifier: format = 1                        |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Offset16           | coverageOffset                  | Offset to Coverage table,                            |
                // |                    |                                 | from beginning of CursivePos subtable.               |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | uint16             | entryExitCount                  | Number of EntryExit records.                         |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | EntryExitRecord    | entryExitRecord[entryExitCount] | Array of EntryExit records, in Coverage index order. |
                // +--------------------+---------------------------------+------------------------------------------------------+
                ushort coverageOffset   = reader.ReadOffset16();
                ushort entryExitCount   = reader.ReadUInt16();
                var    entryExitRecords = new EntryExitRecord[entryExitCount];

                for (int i = 0; i < entryExitCount; i++)
                {
                    entryExitRecords[i] = new EntryExitRecord(reader, offset);
                }

                var entryExitAnchors = new EntryExitAnchors[entryExitCount];

                for (int i = 0; i < entryExitCount; i++)
                {
                    entryExitAnchors[i] = new EntryExitAnchors(reader, offset, entryExitRecords[i]);
                }

                var coverageTable = CoverageTable.Load(reader, offset + coverageOffset);

                return(new LookupType3Format1SubTable(coverageTable, entryExitAnchors, lookupFlags));
            }
            public static LookupType4Format1SubTable Load(BigEndianBinaryReader reader, long offset, LookupFlags lookupFlags)
            {
                // MarkBasePosFormat1 Subtable.
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Type               |  Name                           | Description                                          |
                // +====================+=================================+======================================================+
                // | uint16             | posFormat                       | Format identifier: format = 1                        |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Offset16           | markCoverageOffset              | Offset to markCoverage table,                        |
                // |                    |                                 | from beginning of MarkBasePos subtable.              |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Offset16           | baseCoverageOffset              | Offset to baseCoverage table,                        |
                // |                    |                                 | from beginning of MarkBasePos subtable.              |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | uint16             | markClassCount                  | Number of classes defined for marks.                 |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Offset16           | markArrayOffset                 | Offset to MarkArray table,                           |
                // |                    |                                 | from beginning of MarkBasePos subtable.              |
                // +--------------------+---------------------------------+------------------------------------------------------+
                // | Offset16           | baseArrayOffset                 | Offset to BaseArray table,                           |
                // |                    |                                 | from beginning of MarkBasePos subtable.              |
                // +--------------------+---------------------------------+------------------------------------------------------+
                ushort markCoverageOffset = reader.ReadOffset16();
                ushort baseCoverageOffset = reader.ReadOffset16();
                ushort markClassCount     = reader.ReadUInt16();
                ushort markArrayOffset    = reader.ReadOffset16();
                ushort baseArrayOffset    = reader.ReadOffset16();

                var markCoverage   = CoverageTable.Load(reader, offset + markCoverageOffset);
                var baseCoverage   = CoverageTable.Load(reader, offset + baseCoverageOffset);
                var markArrayTable = new MarkArrayTable(reader, offset + markArrayOffset);
                var baseArrayTable = new BaseArrayTable(reader, offset + baseArrayOffset, markClassCount);

                return(new LookupType4Format1SubTable(markCoverage, baseCoverage, markArrayTable, baseArrayTable, lookupFlags));
            }
 private LookupType8Format1SubTable(
     CoverageTable coverageTable,
     ChainedSequenceRuleSetTable[] seqRuleSetTables,
     LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.coverageTable    = coverageTable;
     this.seqRuleSetTables = seqRuleSetTables;
 }
示例#4
0
 public LookupType7Format2SubTable(
     CoverageTable coverageTable,
     ClassDefinitionTable classDefinitionTable,
     ClassSequenceRuleSetTable[] sequenceRuleSetTables,
     LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.coverageTable         = coverageTable;
     this.classDefinitionTable  = classDefinitionTable;
     this.sequenceRuleSetTables = sequenceRuleSetTables;
 }
示例#5
0
 public LookupType5Format1SubTable(
     CoverageTable markCoverage,
     CoverageTable ligatureCoverage,
     MarkArrayTable markArrayTable,
     LigatureArrayTable ligatureArrayTable,
     LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.markCoverage       = markCoverage;
     this.ligatureCoverage   = ligatureCoverage;
     this.markArrayTable     = markArrayTable;
     this.ligatureArrayTable = ligatureArrayTable;
 }
 public LookupType6Format1SubTable(
     CoverageTable mark1Coverage,
     CoverageTable mark2Coverage,
     MarkArrayTable mark1ArrayTable,
     Mark2ArrayTable mark2ArrayTable,
     LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.mark1Coverage   = mark1Coverage;
     this.mark2Coverage   = mark2Coverage;
     this.mark1ArrayTable = mark1ArrayTable;
     this.mark2ArrayTable = mark2ArrayTable;
 }
 public LookupType4Format1SubTable(
     CoverageTable markCoverage,
     CoverageTable baseCoverage,
     MarkArrayTable markArrayTable,
     BaseArrayTable baseArrayTable,
     LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.markCoverage   = markCoverage;
     this.baseCoverage   = baseCoverage;
     this.markArrayTable = markArrayTable;
     this.baseArrayTable = baseArrayTable;
 }
示例#8
0
        private static bool AppendCoverageGlyphRecords(
            FontTable table,
            ushort lookupIndex,
            CoverageTable coverage,
            GlyphLookupRecord[] records,
            ref int recordCount,
            ref int maxLookupGlyph
            )
        {
            switch (coverage.Format(table))
            {
            case 1:
                ushort glyphCount = coverage.Format1GlyphCount(table);

                for (ushort i = 0; i < glyphCount; i++)
                {
                    ushort glyph = coverage.Format1Glyph(table, i);

                    if (!AppendGlyphRecord(glyph, lookupIndex, records, ref recordCount, ref maxLookupGlyph))
                    {
                        // We've failed to add another record.
                        return(false);
                    }
                }

                break;

            case 2:

                ushort rangeCount = coverage.Format2RangeCount(table);

                for (ushort i = 0; i < rangeCount; i++)
                {
                    ushort firstGlyph = coverage.Format2RangeStartGlyph(table, i);
                    ushort lastGlyph  = coverage.Format2RangeEndGlyph(table, i);

                    for (int glyph = firstGlyph; glyph <= lastGlyph; glyph++)
                    {
                        if (!AppendGlyphRecord((ushort)glyph, lookupIndex, records, ref recordCount, ref maxLookupGlyph))
                        {
                            // We've failed to add another record.
                            return(false);
                        }
                    }
                }

                break;
            }

            return(true);
        }
 private LookupType8Format2SubTable(
     ChainedClassSequenceRuleSetTable[] sequenceRuleSetTables,
     ClassDefinitionTable backtrackClassDefinitionTable,
     ClassDefinitionTable inputClassDefinitionTable,
     ClassDefinitionTable lookaheadClassDefinitionTable,
     CoverageTable coverageTable,
     LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.sequenceRuleSetTables         = sequenceRuleSetTables;
     this.backtrackClassDefinitionTable = backtrackClassDefinitionTable;
     this.inputClassDefinitionTable     = inputClassDefinitionTable;
     this.lookaheadClassDefinitionTable = lookaheadClassDefinitionTable;
     this.coverageTable = coverageTable;
 }
        private void ExtractDataFromSingleSubstTableFormat1Table(Dictionary <List <int>, int> glyphSubstitutionMap,
                                                                 LookupTypeSingleSubstFormat1 singleSubstTableFormat1)
        {
            CoverageTable coverageTable = singleSubstTableFormat1.CoverageTable;

            for (int i = 0; i < coverageTable.Size; i++)
            {
                int coverageGlyphId   = coverageTable.GetGlyphId(i);
                int substituteGlyphId = coverageGlyphId + singleSubstTableFormat1.DeltaGlyphID;
                PutNewSubstitutionEntry(glyphSubstitutionMap, substituteGlyphId,
                                        new List <int> {
                    coverageGlyphId
                });
            }
        }
            public static LookupType2Format1SubTable Load(BigEndianBinaryReader reader, long offset, LookupFlags lookupFlags)
            {
                // Pair Adjustment Positioning Subtable format 1.
                // +-------------+------------------------------+------------------------------------------------+
                // | Type        |  Name                        | Description                                    |
                // +=============+==============================+================================================+
                // | uint16      | posFormat                    | Format identifier: format = 1                  |
                // +-------------+------------------------------+------------------------------------------------+
                // | Offset16    | coverageOffset               | Offset to Coverage table, from beginning of    |
                // |             |                              | PairPos subtable.                              |
                // +-------------+------------------------------+------------------------------------------------+
                // | uint16      | valueFormat1                 | Defines the types of data in valueRecord1 —    |
                // |             |                              | for the first glyph in the pair (may be zero). |
                // +-------------+------------------------------+------------------------------------------------+
                // | uint16      | valueFormat2                 | Defines the types of data in valueRecord2 —    |
                // |             |                              | for the second glyph in the pair (may be zero).|
                // +-------------+------------------------------+------------------------------------------------+
                // | uint16      | pairSetCount                 | Number of PairSet tables                       |
                // +-------------+------------------------------+------------------------------------------------+
                // | Offset16    | pairSetOffsets[pairSetCount] | Array of offsets to PairSet tables.            |
                // |             |                              | Offsets are from beginning of PairPos subtable,|
                // |             |                              | ordered by Coverage Index.                     |
                // +-------------+------------------------------+------------------------------------------------+
                ushort      coverageOffset = reader.ReadOffset16();
                ValueFormat valueFormat1   = reader.ReadUInt16 <ValueFormat>();
                ValueFormat valueFormat2   = reader.ReadUInt16 <ValueFormat>();
                ushort      pairSetCount   = reader.ReadUInt16();

                using Buffer <ushort> pairSetOffsetsBuffer = new(pairSetCount);
                Span <ushort> pairSetOffsets = pairSetOffsetsBuffer.GetSpan();

                reader.ReadUInt16Array(pairSetOffsets);

                var pairSets = new PairSetTable[pairSetCount];

                for (int i = 0; i < pairSetCount; i++)
                {
                    reader.Seek(offset + pairSetOffsets[i], SeekOrigin.Begin);
                    pairSets[i] = PairSetTable.Load(reader, offset + pairSetOffsets[i], valueFormat1, valueFormat2);
                }

                var coverageTable = CoverageTable.Load(reader, offset + coverageOffset);

                return(new LookupType2Format1SubTable(coverageTable, pairSets, lookupFlags));
            }
        private void ExtractDataFromSingleSubstTableFormat2Table(
            Dictionary <List <int>, int> glyphSubstitutionMap,
            LookupTypeSingleSubstFormat2 singleSubstTableFormat2)
        {
            CoverageTable coverageTable = singleSubstTableFormat2.CoverageTable;

            if (coverageTable.Size != singleSubstTableFormat2.SubstituteGlyphIDs.Length)
            {
                throw new ArgumentException(
                          "The no. coverage table entries should be the same as the size of the substituteGlyphIDs");
            }

            for (int i = 0; i < coverageTable.Size; i++)
            {
                int coverageGlyphId   = coverageTable.GetGlyphId(i);
                int substituteGlyphId = coverageGlyphId
                                        + singleSubstTableFormat2.SubstituteGlyphIDs[i];
                PutNewSubstitutionEntry(glyphSubstitutionMap, substituteGlyphId,
                                        new List <int> {
                    coverageGlyphId
                });
            }
        }
示例#13
0
 public LookupType7Format1SubTable(CoverageTable coverageTable, SequenceRuleSetTable[] seqRuleSetTables, LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.seqRuleSetTables = seqRuleSetTables;
     this.coverageTable    = coverageTable;
 }
示例#14
0
            public static LookupType7Format2SubTable Load(BigEndianBinaryReader reader, long offset, LookupFlags lookupFlags)
            {
                CoverageTable coverageTable = TableLoadingUtils.LoadSequenceContextFormat2(reader, offset, out ClassDefinitionTable classDefTable, out ClassSequenceRuleSetTable[] classSeqRuleSets);

                return(new LookupType7Format2SubTable(coverageTable, classDefTable, classSeqRuleSets, lookupFlags));
            }
示例#15
0
        private static CoverageTable GetSubtablePrincipalCoverage(
            FontTable table,
            OpenTypeTags tableTag,
            ushort lookupType,
            int subtableOffset
            )
        {
            Debug.Assert(tableTag == OpenTypeTags.GSUB || tableTag == OpenTypeTags.GPOS);

            CoverageTable coverage = CoverageTable.InvalidCoverage;

            switch (tableTag)
            {
            case OpenTypeTags.GSUB:
                if (lookupType == 7)
                {
                    ExtensionLookupTable extension =
                        new ExtensionLookupTable(subtableOffset);

                    lookupType     = extension.LookupType(table);
                    subtableOffset = extension.LookupSubtableOffset(table);
                }

                switch (lookupType)
                {
                case 1:         //SingleSubst
                    SingleSubstitutionSubtable singleSubst =
                        new SingleSubstitutionSubtable(subtableOffset);

                    return(singleSubst.GetPrimaryCoverage(table));

                case 2:         //MultipleSubst
                    MultipleSubstitutionSubtable multipleSub =
                        new MultipleSubstitutionSubtable(subtableOffset);
                    return(multipleSub.GetPrimaryCoverage(table));

                case 3:         //AlternateSubst
                    AlternateSubstitutionSubtable alternateSub =
                        new AlternateSubstitutionSubtable(subtableOffset);
                    return(alternateSub.GetPrimaryCoverage(table));

                case 4:         //Ligature subst
                    LigatureSubstitutionSubtable ligaSub =
                        new LigatureSubstitutionSubtable(subtableOffset);
                    return(ligaSub.GetPrimaryCoverage(table));

                case 5:         //ContextualSubst
                    ContextSubtable contextSub =
                        new ContextSubtable(subtableOffset);
                    return(contextSub.GetPrimaryCoverage(table));

                case 6:         //ChainingSubst
                    ChainingSubtable chainingSub =
                        new ChainingSubtable(subtableOffset);
                    return(chainingSub.GetPrimaryCoverage(table));

                case 7:         //Extension lookup
                    // Ext.Lookup processed earlier. It can't contain another ext.lookups in it
                    break;

                case 8:         //ReverseCahiningSubst
                    ReverseChainingSubtable reverseChainingSub =
                        new ReverseChainingSubtable(subtableOffset);
                    return(reverseChainingSub.GetPrimaryCoverage(table));
                }

                break;

            case OpenTypeTags.GPOS:
                if (lookupType == 9)
                {
                    ExtensionLookupTable extension =
                        new ExtensionLookupTable(subtableOffset);

                    lookupType     = extension.LookupType(table);
                    subtableOffset = extension.LookupSubtableOffset(table);
                }

                switch (lookupType)
                {
                case 1:         //SinglePos
                    SinglePositioningSubtable singlePos =
                        new SinglePositioningSubtable(subtableOffset);
                    return(singlePos.GetPrimaryCoverage(table));

                case 2:         //PairPos
                    PairPositioningSubtable pairPos =
                        new PairPositioningSubtable(subtableOffset);
                    return(pairPos.GetPrimaryCoverage(table));

                case 3:         // CursivePos
                    CursivePositioningSubtable cursivePos =
                        new CursivePositioningSubtable(subtableOffset);
                    return(cursivePos.GetPrimaryCoverage(table));

                case 4:         //MarkToBasePos
                    MarkToBasePositioningSubtable markToBasePos =
                        new MarkToBasePositioningSubtable(subtableOffset);
                    return(markToBasePos.GetPrimaryCoverage(table));

                case 5:         //MarkToLigaturePos
                    // Under construction
                    MarkToLigaturePositioningSubtable markToLigaPos =
                        new MarkToLigaturePositioningSubtable(subtableOffset);
                    return(markToLigaPos.GetPrimaryCoverage(table));

                case 6:         //MarkToMarkPos
                    MarkToMarkPositioningSubtable markToMarkPos =
                        new MarkToMarkPositioningSubtable(subtableOffset);
                    return(markToMarkPos.GetPrimaryCoverage(table));

                case 7:         // Contextual
                    ContextSubtable contextPos =
                        new ContextSubtable(subtableOffset);
                    return(contextPos.GetPrimaryCoverage(table));

                case 8:         // Chaining
                    ChainingSubtable chainingPos =
                        new ChainingSubtable(subtableOffset);
                    return(chainingPos.GetPrimaryCoverage(table));

                case 9:         //Extension lookup
                    // Ext.Lookup processed earlier. It can't contain another ext.lookups in it
                    break;
                }

                break;
            }

            return(CoverageTable.InvalidCoverage);
        }
示例#16
0
        private static void ComputeTableCache(
            IOpenTypeFont font,
            OpenTypeTags tableTag,
            int maxCacheSize,
            ref int cacheSize,
            ref GlyphLookupRecord[] records,
            ref int recordCount,
            ref int glyphCount,
            ref int lastLookupAdded
            )
        {
            FontTable table = font.GetFontTable(tableTag);

            if (!table.IsPresent)
            {
                return;
            }

            FeatureList featureList;
            LookupList  lookupList;

            Debug.Assert(tableTag == OpenTypeTags.GSUB || tableTag == OpenTypeTags.GPOS);

            switch (tableTag)
            {
            case OpenTypeTags.GSUB:
            {
                GSUBHeader header = new GSUBHeader();
                featureList = header.GetFeatureList(table);
                lookupList  = header.GetLookupList(table);
                break;
            }

            case OpenTypeTags.GPOS:
            {
                GPOSHeader header = new GPOSHeader();
                featureList = header.GetFeatureList(table);
                lookupList  = header.GetLookupList(table);
                break;
            }

            default:
            {
                Debug.Assert(false);
                featureList = new FeatureList(0);
                lookupList  = new LookupList(0);
                break;
            }
            }

            // Estimate number of records that can fit into cache using ratio of approximately
            // 4 bytes of cache per actual record. Most of fonts will fit into this value, except
            // some tiny caches and big EA font that can have ratio of around 5 (theoretical maximum is 8).
            //
            // If actual ratio for particluar font will be larger than 4, we will remove records
            // from the end to fit into cache.
            //
            // If ratio is less than 4 we actually can fit more lookups, but for the speed and because most fonts
            // will fit into cache completely anyway we do not do anything about this here.
            int maxRecordCount = maxCacheSize / 4;

            // For now, we will just allocate array of maximum size.
            // Given heuristics above, it wont be greater than max cache size.
            //
            records = new GlyphLookupRecord[maxRecordCount];

            //
            // Now iterate through lookups and subtables, filling in lookup-glyph pairs list
            //
            int lookupCount = lookupList.LookupCount(table);
            int recordCountAfterLastLookup = 0;

            //
            // Not all lookups can be invoked from feature directly,
            // they are actions from contextual lookups.
            // We are not interested in those, because they will
            // never work from high level, so do not bother adding them to the cache.
            //
            // Filling array of lookup usage bits, to skip those not mapped to any lookup
            //
            BitArray lookupUsage = new BitArray(lookupCount);

            for (ushort feature = 0; feature < featureList.FeatureCount(table); feature++)
            {
                FeatureTable featureTable = featureList.FeatureTable(table, feature);

                for (ushort lookup = 0; lookup < featureTable.LookupCount(table); lookup++)
                {
                    ushort lookupIndex = featureTable.LookupIndex(table, lookup);

                    if (lookupIndex >= lookupCount)
                    {
                        // This must be an invalid font. Just igonoring this lookup here.
                        continue;
                    }

                    lookupUsage[lookupIndex] = true;
                }
            }
            // Done with lookup usage bits

            for (ushort lookupIndex = 0; lookupIndex < lookupCount; lookupIndex++)
            {
                if (!lookupUsage[lookupIndex])
                {
                    continue;
                }

                int  firstLookupRecord = recordCount;
                int  maxLookupGlyph    = -1;
                bool cacheIsFull       = false;

                LookupTable lookup        = lookupList.Lookup(table, lookupIndex);
                ushort      lookupType    = lookup.LookupType();
                ushort      subtableCount = lookup.SubTableCount();

                for (ushort subtableIndex = 0; subtableIndex < subtableCount; subtableIndex++)
                {
                    int subtableOffset = lookup.SubtableOffset(table, subtableIndex);

                    CoverageTable coverage = GetSubtablePrincipalCoverage(table, tableTag, lookupType, subtableOffset);

                    if (coverage.IsInvalid)
                    {
                        continue;
                    }

                    cacheIsFull = !AppendCoverageGlyphRecords(table, lookupIndex, coverage, records, ref recordCount, ref maxLookupGlyph);

                    if (cacheIsFull)
                    {
                        break;
                    }
                }

                if (cacheIsFull)
                {
                    break;
                }

                lastLookupAdded            = lookupIndex;
                recordCountAfterLastLookup = recordCount;
            }

            // We may hit storage overflow in the middle of lookup. Throw this partial lookup away
            recordCount = recordCountAfterLastLookup;

            if (lastLookupAdded == -1)
            {
                // We did not succeed adding even single lookup.
                return;
            }

            // We now have glyph records for (may be not all) lookups in the table.
            // Cache structures should be sorted by glyph, then by lookup index.
            Array.Sort(records, 0, recordCount);

            cacheSize  = -1;
            glyphCount = -1;

            // It may happen, that records do not fit into cache, even using our heuristics.
            // We will remove lookups one by one from the end until it fits.
            while (recordCount > 0)
            {
                CalculateCacheSize(records, recordCount, out cacheSize, out glyphCount);

                if (cacheSize <= maxCacheSize)
                {
                    // Fine, we now fit into max cache size
                    break;
                }
                else
                {
                    // Find last lookup index
                    int lastLookup = -1;
                    for (int i = 0; i < recordCount; i++)
                    {
                        int lookup = records[i].Lookup;

                        if (lastLookup < lookup)
                        {
                            lastLookup = lookup;
                        }
                    }

                    Debug.Assert(lastLookup >= 0); // There are lookups, so there was an index

                    // Remove it
                    int currentRecord = 0;
                    for (int i = 0; i < recordCount; i++)
                    {
                        if (records[i].Lookup == lastLookup)
                        {
                            continue;
                        }

                        if (currentRecord == i)
                        {
                            continue;
                        }

                        records[currentRecord] = records[i];
                        currentRecord++;
                    }

                    recordCount = currentRecord;

                    // Do not forget update lastLookupAdded variable
                    lastLookupAdded = lastLookup - 1;
                }
            }

            if (recordCount == 0)
            {
                // We can't fit even single lookup into the cache
                return;
            }

            Debug.Assert(cacheSize > 0);  // We've calcucalted them at least ones, and
            Debug.Assert(glyphCount > 0); // if there is no records, we already should've exited
        }
示例#17
0
 public LookupType3Format1SubTable(CoverageTable coverageTable, EntryExitAnchors[] entryExitAnchors, LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.coverageTable    = coverageTable;
     this.entryExitAnchors = entryExitAnchors;
 }
示例#18
0
 public LookupSubTable(int substFormat, CoverageTable coverageTable)
 {
     this.substFormat   = substFormat;
     this.coverageTable = coverageTable;
 }
 public LookupTypeSingleSubstFormat2(int substFormat, CoverageTable coverageTable, int[] substituteGlyphIDs)
     : base(substFormat, coverageTable)
 {
     ;
     this.substituteGlyphIDs = substituteGlyphIDs;
 }
 public LookupType2Format1SubTable(CoverageTable coverageTable, PairSetTable[] pairSets, LookupFlags lookupFlags)
     : base(lookupFlags)
 {
     this.coverageTable = coverageTable;
     this.pairSets      = pairSets;
 }
 public LookupTypeSingleSubstFormat1(int substFormat, CoverageTable coverageTable, short deltaGlyphID)
     : base(substFormat, coverageTable)
 {
     this.deltaGlyphID = deltaGlyphID;
 }
示例#22
0
 public LookupTypeLigatureSubstitutionSubstFormat1(int substFormat, CoverageTable coverageTable, LigatureSetTable[] ligatureSetTables)
     : base(substFormat, coverageTable)
 {
     this.ligatureSetTables = ligatureSetTables;
 }