// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.Fonts.Unicode;
using SixLabors.Fonts.WellKnownIds;
using System.Collections.Generic;
using System.Linq;
namespace SixLabors.Fonts.Tables.General.CMap {
///
/// Format 0 is a simple byte encoding subtable that maps character codes 0–255 to glyph indices.
///
///
internal sealed class Format0SubTable : CMapSubTable
{
///
/// Initializes a new instance of the class.
///
/// The language code for Macintosh platform subtables.
/// The platform identifier.
/// The platform-specific encoding identifier.
/// The array of glyph indices indexed by character code.
public Format0SubTable(ushort language, PlatformIDs platform, ushort encoding, byte[] glyphIds)
: base(platform, encoding, 0)
{
this.Language = language;
this.GlyphIds = glyphIds;
}
///
/// Gets the language code for Macintosh platform subtables.
///
public ushort Language { get; }
///
/// Gets the array of glyph indices indexed by character code.
///
public byte[] GlyphIds { get; }
///
public override bool TryGetGlyphId(CodePoint codePoint, out ushort glyphId)
{
int b = codePoint.Value;
if (b >= this.GlyphIds.Length)
{
glyphId = 0;
return false;
}
glyphId = this.GlyphIds[b];
return true;
}
///
public override bool TryGetCodePoint(ushort glyphId, out CodePoint codePoint)
{
for (int i = 0; i < this.GlyphIds.Length; i++)
{
if (this.GlyphIds[i] == glyphId)
{
codePoint = new CodePoint(i);
return true;
}
}
codePoint = default;
return false;
}
///
public override IEnumerable GetAvailableCodePoints()
=> Enumerable.Range(0, this.GlyphIds.Length);
///
/// Loads one or more instances from the specified encoding records and reader.
///
/// The encoding records that share this subtable.
/// The binary reader positioned after the format field.
/// An enumerable of instances, one per encoding record.
public static IEnumerable Load(IEnumerable encodings, BigEndianBinaryReader reader)
{
// format has already been read by this point skip it
ushort length = reader.ReadUInt16();
ushort language = reader.ReadUInt16();
int glyphsCount = length - 6;
// char 'A' == 65 thus glyph = glyphIds[65];
byte[] glyphIds = reader.ReadBytes(glyphsCount);
foreach (EncodingRecord encoding in encodings)
{
yield return new Format0SubTable(language, encoding.PlatformID, encoding.EncodingID, glyphIds);
}
}
}
}