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); }
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); }
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); }