// 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); } } }