ImageSharp/SixLabors.Fonts/Tables/General/Kern/Format0SubTable.cs
2026-08-03 22:31:27 +02:00

54 lines
2.3 KiB
C#

// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
namespace SixLabors.Fonts.Tables.General.Kern {
internal sealed class Format0SubTable : KerningSubTable
{
private readonly KerningPair[] pairs;
public Format0SubTable(KerningPair[] pairs, KerningCoverage coverage)
: base(coverage)
=> this.pairs = pairs;
public static Format0SubTable Load(BigEndianBinaryReader reader, in KerningCoverage coverage)
{
// Type | Field | Description
// -------|---------------|--------------------------------------------------------
// uint16 | nPairs | This gives the number of kerning pairs in the table.
// uint16 | searchRange | The largest power of two less than or equal to the value of nPairs, multiplied by the size in bytes of an entry in the table.
// uint16 | entrySelector | This is calculated as log2 of the largest power of two less than or equal to the value of nPairs.
// | | This value indicates how many iterations of the search loop will have to be made. (For example, in a list of eight items, there would have to be three iterations of the loop).
// uint16 | rangeShift | The value of nPairs minus the largest power of two less than or equal to nPairs, and then multiplied by the size in bytes of an entry in the table.
ushort pairCount = reader.ReadUInt16();
ushort searchRange = reader.ReadUInt16();
ushort entrySelector = reader.ReadUInt16();
ushort rangeShift = reader.ReadUInt16();
KerningPair[] pairs = new KerningPair[pairCount];
for (int i = 0; i < pairCount; i++)
{
pairs[i] = KerningPair.Read(reader);
}
return new Format0SubTable(pairs, coverage);
}
protected override bool TryGetOffset(ushort index1, ushort index2, out short offset)
{
int index = this.pairs.AsSpan().BinarySearch(new KerningPair(index1, index2, 0));
if (index >= 0)
{
ref KerningPair pair = ref this.pairs[index];
offset = pair.Offset;
return true;
}
offset = 0;
return false;
}
}
}