public static LigatureAttachTable ReadFrom(BinaryReader reader, ushort classCount) { LigatureAttachTable table = new LigatureAttachTable(); ushort componentCount = reader.ReadUInt16(); ComponentRecord[] componentRecs = new ComponentRecord[componentCount]; table.records = componentRecs; for (int i = 0; i < componentCount; ++i) { componentRecs[i] = new ComponentRecord( Utils.ReadInt16Array(reader, classCount)); } return(table); }
public void ReadFrom(BinaryReader reader, ushort classCount) { long startPos = reader.BaseStream.Position; ushort ligatureCount = reader.ReadUInt16(); short[] offsets = Utils.ReadInt16Array(reader, ligatureCount); ligatures = new LigatureAttachTable[ligatureCount]; for (int i = 0; i < ligatureCount; ++i) { //each ligature table reader.BaseStream.Seek(startPos + offsets[i], SeekOrigin.Begin); ligatures[i] = LigatureAttachTable.ReadFrom(reader, classCount); } }
public static LigatureAttachTable ReadFrom(BinaryReader reader, ushort classCount) { LigatureAttachTable table = new LigatureAttachTable(); ushort componentCount = reader.ReadUInt16(); ComponentRecord[] componentRecs = new ComponentRecord[componentCount]; table.records = componentRecs; for (int i = 0; i < componentCount; ++i) { componentRecs[i] = new ComponentRecord( Utils.ReadInt16Array(reader, classCount)); } return table; }
public override bool TryUpdatePosition( FontMetrics fontMetrics, GPosTable table, GlyphPositioningCollection collection, Tag feature, ushort index, int count) { // Mark-to-Ligature Attachment Positioning. // Implements: https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-5-mark-to-ligature-attachment-positioning-subtable ushort glyphId = collection[index][0]; if (glyphId == 0) { return(false); } int markIndex = this.markCoverage.CoverageIndexOf(glyphId); if (markIndex < 0) { return(false); } // Search backward for a base glyph. int baseGlyphIndex = index; while (--baseGlyphIndex >= 0) { GlyphShapingData data = collection.GetGlyphShapingData(baseGlyphIndex); if (!AdvancedTypographicUtils.IsMarkGlyph(fontMetrics, data.GlyphIds[0], data)) { break; } } if (baseGlyphIndex < 0) { return(false); } ushort baseGlyphId = collection[baseGlyphIndex][0]; int ligatureIndex = this.ligatureCoverage.CoverageIndexOf(baseGlyphId); if (ligatureIndex < 0) { return(false); } // We must now check whether the ligature ID of the current mark glyph // is identical to the ligature ID of the found ligature. // If yes, we can directly use the component index. If not, we attach the mark // glyph to the last component of the ligature. LigatureAttachTable ligatureAttach = this.ligatureArrayTable.LigatureAttachTables[ligatureIndex]; GlyphShapingData markGlyph = collection.GetGlyphShapingData(index); GlyphShapingData ligGlyph = collection.GetGlyphShapingData(baseGlyphIndex); int compIndex = ligGlyph.LigatureId > 0 && ligGlyph.LigatureId == markGlyph.LigatureId && markGlyph.LigatureComponent > 0 ? Math.Min(markGlyph.LigatureComponent, ligGlyph.CodePointCount) - 1 : ligGlyph.CodePointCount - 1; MarkRecord markRecord = this.markArrayTable.MarkRecords[markIndex]; AnchorTable baseAnchor = ligatureAttach.ComponentRecords[compIndex].LigatureAnchorTables[markRecord.MarkClass]; AdvancedTypographicUtils.ApplyAnchor(collection, index, baseAnchor, markRecord, baseGlyphIndex); return(true); }