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