// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
namespace SixLabors.Fonts.Tables.General.Kern {
///
/// Represents a kerning pair entry in the OpenType 'kern' table, mapping a pair of
/// glyph indices to a kerning offset value.
///
///
internal readonly struct KerningPair : IComparable
{
///
/// Initializes a new instance of the struct.
///
/// The glyph index for the left-hand glyph in the kerning pair.
/// The glyph index for the right-hand glyph in the kerning pair.
/// The kerning offset value in font design units.
internal KerningPair(ushort left, ushort right, short offset)
{
this.Left = left;
this.Right = right;
this.Offset = offset;
this.Key = CalculateKey(left, right);
}
///
/// Gets the composite key derived from the left and right glyph indices, used for fast lookup.
///
public uint Key { get; }
///
/// Gets the glyph index for the left-hand glyph in the kerning pair.
///
public ushort Left { get; }
///
/// Gets the glyph index for the right-hand glyph in the kerning pair.
///
public ushort Right { get; }
///
/// Gets the kerning offset value in font design units.
/// Positive values move glyphs apart; negative values move them closer together.
///
public short Offset { get; }
///
/// Calculates a composite lookup key from a pair of glyph indices.
///
/// The left glyph index.
/// The right glyph index.
/// A 32-bit key combining both glyph indices.
public static uint CalculateKey(ushort left, ushort right)
{
uint value = (uint)(left << 16);
return value + right;
}
///
/// Reads a from the specified binary reader.
///
/// The binary reader positioned at the start of the kerning pair data.
/// The parsed .
public static KerningPair Read(BigEndianBinaryReader reader)
// Type | Field | Description
// -------|-------|-------------------------------
// uint16 | left | The glyph index for the left-hand glyph in the kerning pair.
// uint16 | right | The glyph index for the right-hand glyph in the kerning pair.
// FWORD | value | The kerning value for the above pair, in FUnits.If this value is greater than zero, the characters will be moved apart.If this value is less than zero, the character will be moved closer together.
=> new KerningPair(reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadFWORD());
///
/// Compares this kerning pair to another based on the composite key.
///
/// The other kerning pair to compare to.
/// A value indicating the relative order of the kerning pairs.
public int CompareTo(KerningPair other)
=> this.Key.CompareTo(other.Key);
}
}