// 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 `VVAR`.
/// The VVAR table is used in variable fonts to provide variations for vertical glyph metrics values.
/// This can be used to provide variation data for advance heights in the 'vmtx' table.
///
///
internal class VVarTable : Table
{
///
/// The table name identifier for the VVAR table.
///
internal const string TableName = "VVAR";
///
/// Initializes a new instance of the class.
///
/// The item variation store containing delta data.
/// The optional delta-set index mapping for advance heights.
/// The optional delta-set index mapping for top side bearings.
/// The optional delta-set index mapping for bottom side bearings.
/// The optional delta-set index mapping for vertical origin Y coordinates.
public VVarTable(
ItemVariationStore itemVariationStore,
DeltaSetIndexMap[]? advanceWidthMapping,
DeltaSetIndexMap[]? tsbMapping,
DeltaSetIndexMap[]? bsbMapping,
DeltaSetIndexMap[]? vOrgMapping)
{
this.ItemVariationStore = itemVariationStore;
this.AdvanceWidthMapping = advanceWidthMapping;
this.TsbMapping = tsbMapping;
this.BsbMapping = bsbMapping;
this.VOrgMapping = vOrgMapping;
}
///
/// Gets the item variation store containing the variation delta data.
///
public ItemVariationStore ItemVariationStore { get; }
///
/// Gets the optional delta-set index mapping for advance heights.
///
public DeltaSetIndexMap[]? AdvanceWidthMapping { get; }
///
/// Gets the optional delta-set index mapping for top side bearings.
///
public DeltaSetIndexMap[]? TsbMapping { get; }
///
/// Gets the optional delta-set index mapping for bottom side bearings.
///
public DeltaSetIndexMap[]? BsbMapping { get; }
///
/// Gets the optional delta-set index mapping for Y coordinates of vertical origins.
///
public DeltaSetIndexMap[]? VOrgMapping { get; }
///
/// Loads the VVAR table from the specified font reader.
///
/// The font reader.
/// The , or if the table is not present.
public static VVarTable? Load(FontReader reader)
{
if (!reader.TryGetReaderAtTablePosition(TableName, out BigEndianBinaryReader? binaryReader))
{
return null;
}
using (binaryReader)
{
return Load(binaryReader);
}
}
///
/// Loads the VVAR table from the specified binary reader.
///
/// The big-endian binary reader positioned at the start of the VVAR table.
/// The .
public static VVarTable 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 | advanceHeightMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for advance heights (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | tsbMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for top side bearings (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | bsbMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for bottom side bearings (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
// | Offset32 | vOrgMappingOffset | Offset in bytes from the start of this table to the delta-set index |
// | | | mapping for Y coordinates of vertical origins (may be NULL). |
// +--------------------------+----------------------------------------+-------------------------------------------------------------------------+
ushort major = reader.ReadUInt16();
ushort minor = reader.ReadUInt16();
uint itemVariationStoreOffset = reader.ReadOffset32();
uint advanceHeightMappingOffset = reader.ReadOffset32();
uint tsbMappingOffset = reader.ReadOffset32();
uint bsbMappingOffset = reader.ReadOffset32();
uint vOrgMappingOffset = reader.ReadOffset32();
if (major != 1)
{
throw new NotSupportedException("Only version 1 of hvar table is supported");
}
ItemVariationStore itemVariationStore = ItemVariationStore.Load(reader, itemVariationStoreOffset);
DeltaSetIndexMap[]? advanceHeightMapping = DeltaSetIndexMap.Load(reader, advanceHeightMappingOffset);
DeltaSetIndexMap[]? tsbMapping = DeltaSetIndexMap.Load(reader, tsbMappingOffset);
DeltaSetIndexMap[]? bsbMapping = DeltaSetIndexMap.Load(reader, bsbMappingOffset);
DeltaSetIndexMap[]? vOrgMapping = DeltaSetIndexMap.Load(reader, vOrgMappingOffset);
return new VVarTable(itemVariationStore, advanceHeightMapping, tsbMapping, bsbMapping, vOrgMapping);
}
}
}