Example #1
0
        public static bool ApplyChainedClassSequenceRule(
            SkippingGlyphIterator iterator,
            ChainedClassSequenceRuleTable rule,
            ClassDefinitionTable inputClassDefinitionTable,
            ClassDefinitionTable backtrackClassDefinitionTable,
            ClassDefinitionTable lookaheadClassDefinitionTable)
        {
            if (rule.BacktrackSequence.Length > 0 &&
                !MatchClassSequence(iterator, -rule.BacktrackSequence.Length, rule.BacktrackSequence, backtrackClassDefinitionTable))
            {
                return(false);
            }

            if (rule.InputSequence.Length > 0 &&
                !MatchClassSequence(iterator, 1, rule.InputSequence, inputClassDefinitionTable))
            {
                return(false);
            }

            if (rule.LookaheadSequence.Length > 0 &&
                !MatchClassSequence(iterator, 1 + rule.InputSequence.Length, rule.LookaheadSequence, lookaheadClassDefinitionTable))
            {
                return(false);
            }

            return(true);
        }
Example #2
0
 public static bool MatchClassSequence(
     SkippingGlyphIterator iterator,
     int increment,
     ushort[] sequence,
     ClassDefinitionTable classDefinitionTable)
 => Match(
     increment,
     sequence,
     iterator,
     (component, data) => component == classDefinitionTable.ClassIndexOf(data.GlyphIds[0]),
     default);
Example #3
0
        internal static CoverageTable LoadSequenceContextFormat2(BigEndianBinaryReader reader, long offset, out ClassDefinitionTable classDefTable, out ClassSequenceRuleSetTable[] classSeqRuleSets)
        {
            // https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-2-class-based-glyph-contexts
            // Context Positioning Subtable Format 2: Class-based Glyph Contexts.
            // +----------+----------------------------------------------+--------------------------------------------------------------------+
            // | Type     | Name                                         | Description                                                        |
            // +==========+==============================================+====================================================================+
            // | uint16   | format                                       | Format identifier: format = 2                                      |
            // +----------+----------------------------------------------+--------------------------------------------------------------------+
            // | Offset16 | coverageOffset                               | Offset to Coverage table, from beginning of                        |
            // |          |                                              | SequenceContextFormat2 table.                                      |
            // +----------+----------------------------------------------+--------------------------------------------------------------------+
            // | Offset16 | classDefOffset                               | Offset to ClassDef table, from beginning of                        |
            // |          |                                              | SequenceContextFormat2 table.                                      |
            // +----------+----------------------------------------------+--------------------------------------------------------------------+
            // | uint16   | classSeqRuleSetCount                         | Number of ClassSequenceRuleSet tables.                             |
            // +----------+----------------------------------------------+--------------------------------------------------------------------+
            // | Offset16 | classSeqRuleSetOffsets[classSeqRuleSetCount] | Array of offsets to ClassSequenceRuleSet tables, from beginning of |
            // |          |                                              | SequenceContextFormat2 table (may be NULL).                        |
            // +----------+----------------------------------------------+--------------------------------------------------------------------+
            ushort coverageOffset       = reader.ReadOffset16();
            ushort classDefOffset       = reader.ReadOffset16();
            ushort classSeqRuleSetCount = reader.ReadUInt16();

            using Buffer <ushort> classSeqRuleSetOffsetsBuffer = new(classSeqRuleSetCount);
            Span <ushort> classSeqRuleSetOffsets = classSeqRuleSetOffsetsBuffer.GetSpan();

            reader.ReadUInt16Array(classSeqRuleSetOffsets);

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

            classDefTable = ClassDefinitionTable.Load(reader, offset + classDefOffset);

            classSeqRuleSets = new ClassSequenceRuleSetTable[classSeqRuleSetCount];
            for (int i = 0; i < classSeqRuleSets.Length; i++)
            {
                ushort ruleSetOffset = classSeqRuleSetOffsets[i];
                if (ruleSetOffset > 0)
                {
                    classSeqRuleSets[i] = ClassSequenceRuleSetTable.Load(reader, offset + classSeqRuleSetOffsets[i]);
                }
            }

            return(coverageTable);
        }
Example #4
0
        internal static ChainedClassSequenceRuleSetTable[] LoadChainedSequenceContextFormat2(
            BigEndianBinaryReader reader,
            long offset,
            out CoverageTable coverageTable,
            out ClassDefinitionTable backtrackClassDefTable,
            out ClassDefinitionTable inputClassDefTable,
            out ClassDefinitionTable lookaheadClassDefTable)
        {
            // https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-2-class-based-glyph-contexts
            // ChainedSequenceContextFormat2
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | Type     | Name                                                       | Description                                                         |
            // +==========+============================================================+=====================================================================+
            // | uint16   | format                                                     | Format identifier: format = 2                                       |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | Offset16 | coverageOffset                                             | Offset to Coverage table, from beginning                            |
            // |          |                                                            | of ChainedSequenceContextFormat2 table                              |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | Offset16 | backtrackClassDefOffset                                    | Offset to ClassDef table containing                                 |
            // |          |                                                            | backtrack sequence context, from                                    |
            // |          |                                                            | beginning of ChainedSequenceContextFormat2 table                    |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | Offset16 | inputClassDefOffset                                        | Offset to ClassDef table containing input                           |
            // |          |                                                            | sequence context, from beginning of                                 |
            // |          |                                                            | ChainedSequenceContextFormat2 table                                 |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | Offset16 | lookaheadClassDefOffset                                    | Offset to ClassDef table containing                                 |
            // |          |                                                            | lookahead sequence context, from                                    |
            // |          |                                                            | beginning of ChainedSequenceContextFormat2 table                    |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | uint16   | chainedClassSeqRuleSetCount                                | Number of ChainedClassSequenceRuleSet tables                        |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            // | Offset16 | chainedClassSeqRuleSetOffsets[chainedClassSeqRuleSetCount] | Array of offsets to ChainedClassSequenceRuleSet tables,             |
            // |          |                                                            | from beginning of ChainedSequenceContextFormat2 table (may be NULL) |
            // +----------+------------------------------------------------------------+---------------------------------------------------------------------+
            ushort coverageOffset              = reader.ReadOffset16();
            ushort backtrackClassDefOffset     = reader.ReadOffset16();
            ushort inputClassDefOffset         = reader.ReadOffset16();
            ushort lookaheadClassDefOffset     = reader.ReadOffset16();
            ushort chainedClassSeqRuleSetCount = reader.ReadUInt16();

            ChainedClassSequenceRuleSetTable[] seqRuleSets = Array.Empty <ChainedClassSequenceRuleSetTable>();
            if (chainedClassSeqRuleSetCount != 0)
            {
                ushort[] chainedClassSeqRuleSetOffsets = new ushort[chainedClassSeqRuleSetCount];
                for (int i = 0; i < chainedClassSeqRuleSetCount; i++)
                {
                    chainedClassSeqRuleSetOffsets[i] = reader.ReadOffset16();
                }

                seqRuleSets = new ChainedClassSequenceRuleSetTable[chainedClassSeqRuleSetCount];
                for (int i = 0; i < seqRuleSets.Length; i++)
                {
                    if (chainedClassSeqRuleSetOffsets[i] > 0)
                    {
                        seqRuleSets[i] =
                            ChainedClassSequenceRuleSetTable.Load(reader, offset + chainedClassSeqRuleSetOffsets[i]);
                    }
                }
            }

            coverageTable          = CoverageTable.Load(reader, offset + coverageOffset);
            backtrackClassDefTable = ClassDefinitionTable.Load(reader, offset + backtrackClassDefOffset);
            inputClassDefTable     = ClassDefinitionTable.Load(reader, offset + inputClassDefOffset);
            lookaheadClassDefTable = ClassDefinitionTable.Load(reader, offset + lookaheadClassDefOffset);
            return(seqRuleSets);
        }
Example #5
0
        public static GlyphDefinitionTable Load(BigEndianBinaryReader reader)
        {
            // Header version 1.0
            // Type      | Name                     | Description
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // uint16    | majorVersion             | Major version of the GDEF table, = 1
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // uint16    | minorVersion             | Minor version of the GDEF table, = 0
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | glyphClassDefOffset      | Offset to class definition table for glyph type, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | attachListOffset         | Offset to attachment point list table, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | ligCaretListOffset       | Offset to ligature caret list table, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | markAttachClassDefOffset | Offset to class definition table for mark attachment type, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------

            // Header version 1.2
            // Type      | Name                     | Description
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // uint16    | majorVersion             | Major version of the GDEF table, = 1
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // uint16    | minorVersion             | Minor version of the GDEF table, = 0
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | glyphClassDefOffset      | Offset to class definition table for glyph type, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | attachListOffset         | Offset to attachment point list table, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | ligCaretListOffset       | Offset to ligature caret list table, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | markAttachClassDefOffset | Offset to class definition table for mark attachment type, from beginning of GDEF header (may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | markGlyphSetsDefOffset   | Offset to the table of mark glyph set definitions, from beginning of GDEF header (may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------

            // Header version 1.3
            // Type      | Name                     | Description
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // uint16    | majorVersion             | Major version of the GDEF table, = 1
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // uint16    | minorVersion             | Minor version of the GDEF table, = 0
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | glyphClassDefOffset      | Offset to class definition table for glyph type, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | attachListOffset         | Offset to attachment point list table, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | ligCaretListOffset       | Offset to ligature caret list table, from beginning of GDEF header(may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | markAttachClassDefOffset | Offset to class definition table for mark attachment type, from beginning of GDEF header (may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset16  | markGlyphSetsDefOffset   | Offset to the table of mark glyph set definitions, from beginning of GDEF header (may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            // Offset32  | itemVarStoreOffset       | Offset to the Item Variation Store table, from beginning of GDEF header (may be NULL).
            // ----------|--------------------------|--------------------------------------------------------------------------------------------------------
            ushort majorVersion = reader.ReadUInt16();
            ushort minorVersion = reader.ReadUInt16();

            ushort glyphClassDefOffset      = reader.ReadUInt16();
            ushort attachListOffset         = reader.ReadUInt16();
            ushort ligatureCaretListOffset  = reader.ReadUInt16();
            ushort markAttachClassDefOffset = reader.ReadUInt16();
            ushort markGlyphSetsDefOffset   = 0;
            uint   itemVarStoreOffset       = 0;

            switch (minorVersion)
            {
            case 0:
                break;

            case 2:
                markGlyphSetsDefOffset = reader.ReadUInt16();
                break;

            case 3:
                markGlyphSetsDefOffset = reader.ReadUInt16();
                itemVarStoreOffset     = reader.ReadUInt32();
                break;

            default:
                throw new InvalidFontFileException($"Invalid value for 'minor version' {minorVersion} of GDEF table. Should be '0', '2' or '3'.");
            }

            ClassDefinitionTable?classDefinitionTable   = glyphClassDefOffset is 0 ? null : ClassDefinitionTable.Load(reader, glyphClassDefOffset);
            AttachmentListTable? attachmentListTable    = attachListOffset is 0 ? null : AttachmentListTable.Load(reader, attachListOffset);
            LigatureCaretList?   ligatureCaretList      = ligatureCaretListOffset is 0 ? null : LigatureCaretList.Load(reader, ligatureCaretListOffset);
            ClassDefinitionTable?markAttachmentClassDef = markAttachClassDefOffset is 0 ? null : ClassDefinitionTable.Load(reader, markAttachClassDefOffset);
            MarkGlyphSetsTable?  markGlyphSetsTable     = markGlyphSetsDefOffset is 0 ? null : MarkGlyphSetsTable.Load(reader, markGlyphSetsDefOffset);

            var glyphDefinitionTable = new GlyphDefinitionTable()
            {
                GlyphClassDefinition   = classDefinitionTable,
                AttachmentListTable    = attachmentListTable,
                LigatureCaretList      = ligatureCaretList,
                MarkAttachmentClassDef = markAttachmentClassDef,
                MarkGlyphSetsTable     = markGlyphSetsTable
            };

            // TODO: read itemVarStore.
            return(glyphDefinitionTable);
        }