// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
namespace SixLabors.Fonts.Tables.AdvancedTypographic.Variations {
///
/// Implements reading the font variations table `HVAR`.
/// The HVAR table is used in variable fonts to provide variations for horizontal glyph metrics values.
/// This can be used to provide variation data for advance widths in the 'hmtx' table.
///
///
internal class HVarTable : Table
{
///
/// The table name identifier for the HVAR table.
///
internal const string TableName = "HVAR";
///
/// Initializes a new instance of the class.
///
/// The item variation store containing delta data.
/// The optional delta-set index mapping for advance widths.
/// The optional delta-set index mapping for left side bearings.
/// The optional delta-set index mapping for right side bearings.
public HVarTable(
ItemVariationStore itemVariationStore,
DeltaSetIndexMap[]? advanceWidthMapping,
DeltaSetIndexMap[]? lsbMapping,
DeltaSetIndexMap[]? rsbMapping)
{
this.ItemVariationStore = itemVariationStore;
this.AdvanceWidthMapping = advanceWidthMapping;
this.LsbMapping = lsbMapping;
this.RsbMapping = rsbMapping;
}
///
/// Gets the item variation store containing the variation delta data.
///
public ItemVariationStore ItemVariationStore { get; }
///
/// Gets the optional delta-set index mapping for advance widths.
///
public DeltaSetIndexMap[]? AdvanceWidthMapping { get; }
///
/// Gets the optional delta-set index mapping for left side bearings.
///
public DeltaSetIndexMap[]? LsbMapping { get; }
///
/// Gets the optional delta-set index mapping for right side bearings.
///
public DeltaSetIndexMap[]? RsbMapping { get; }
///
/// Loads the HVAR table from the specified font reader.
///
/// The font reader.
/// The , or if the table is not present.
public static HVarTable? Load(FontReader reader)
{
if (!reader.TryGetReaderAtTablePosition(TableName, out BigEndianBinaryReader? binaryReader))
{
return null;
}
using (binaryReader)
{
return Load(binaryReader);
}
}
///
/// Loads the HVAR table from the specified binary reader.
///
/// The big-endian binary reader positioned at the start of the HVAR table.
/// The .
public static HVarTable Load(BigEndianBinaryReader reader)
{
// Horizontal metrics variations table
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Type | Name | Description |
// +==========================+========================================+=========================================================================+
// | uint16 | majorVersion | Major version number of the font variations table — set to 1. |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | uint16 | minorVersion | Minor version number of the font variations table — set to 0. |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | itemVariationStoreOffset | Offset in bytes from the start of this table to the |
// | | | item variation store table. |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | advanceWidthMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for advance widths (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | lsbMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for left side bearings (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | rsbMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for right side bearings (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
ushort major = reader.ReadUInt16();
ushort minor = reader.ReadUInt16();
uint itemVariationStoreOffset = reader.ReadOffset32();
uint advanceWidthMappingOffset = reader.ReadOffset32();
uint lsbMappingOffset = reader.ReadOffset32();
uint rsbMappingOffset = reader.ReadOffset32();
if (major != 1)
{
throw new NotSupportedException("Only version 1 of hvar table is supported");
}
ItemVariationStore itemVariationStore = ItemVariationStore.Load(reader, itemVariationStoreOffset);
DeltaSetIndexMap[]? advanceWidthMapping = DeltaSetIndexMap.Load(reader, advanceWidthMappingOffset);
DeltaSetIndexMap[]? lsbMapping = DeltaSetIndexMap.Load(reader, lsbMappingOffset);
DeltaSetIndexMap[]? rsbMapping = DeltaSetIndexMap.Load(reader, rsbMappingOffset);
return new HVarTable(itemVariationStore, advanceWidthMapping, lsbMapping, rsbMapping);
}
}
}