// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.IO;
namespace SixLabors.Fonts.Tables.AdvancedTypographic {
///
/// The MarkGlyphSets table allows the definition of sets of mark glyphs that can be used
/// in lookup flag mark filtering. This provides more flexibility than the MarkAttachmentType.
///
///
internal sealed class MarkGlyphSetsTable
{
///
/// Gets or sets the format identifier.
///
public ushort Format { get; internal set; }
///
/// Gets or sets the array of offsets to Coverage tables, from the beginning of the MarkGlyphSets table.
///
public uint[]? CoverageOffset { get; internal set; }
///
/// Gets the loaded Coverage tables for each mark glyph set.
///
public CoverageTable[]? Coverages { get; private set; }
///
/// Loads the from the binary reader at the specified offset.
///
/// The big endian binary reader.
/// Offset from the beginning of the GDEF table to the MarkGlyphSets table.
/// The .
public static MarkGlyphSetsTable Load(BigEndianBinaryReader reader, long offset)
{
reader.Seek(offset, SeekOrigin.Begin);
MarkGlyphSetsTable markGlyphSetsTable = new()
{
Format = reader.ReadUInt16()
};
ushort markSetCount = reader.ReadUInt16();
uint[] coverageOffsets = reader.ReadUInt32Array(markSetCount);
markGlyphSetsTable.CoverageOffset = coverageOffsets;
// Load the referenced Coverage tables now so we can use them during shaping.
// Coverage offsets are relative to the start of the MarkGlyphSets table.
CoverageTable[] coverages = new CoverageTable[markSetCount];
for (int i = 0; i < markSetCount; i++)
{
long covOffset = offset + coverageOffsets[i];
coverages[i] = CoverageTable.Load(reader, covOffset);
}
markGlyphSetsTable.Coverages = coverages;
return markGlyphSetsTable;
}
///
/// Determines whether the specified glyph is contained in the given mark glyph set.
///
/// The index of the mark glyph set.
/// The glyph identifier to look up.
/// if the glyph is in the set; otherwise, .
public bool Contains(ushort markGlyphSetIndex, ushort glyphId)
{
CoverageTable[]? coverages = this.Coverages;
if (coverages is null)
{
return false;
}
int i = markGlyphSetIndex;
if ((uint)i >= (uint)coverages.Length)
{
return false;
}
return coverages[i].CoverageIndexOf(glyphId) >= 0;
}
}
}