using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
#pragma warning disable CS3001, CS3002, CS3003, CS1591
namespace FastReport.Fonts
{
///
/// Name table keep human friendly description about font properties, including font names, author and copyright notes
///
public class NameTableClass : TrueTypeTable, ICollection
{
#region "Structure dfinition"
public enum NameID
{
CopyrightNotice = 0,
FamilyName = 1,
SubFamilyName = 2,
UniqueID = 3,
FullName = 4,
Version = 5,
PostscriptName = 6,
Trademark = 7,
Manufacturer = 8,
Designer = 9,
Description = 10,
URL_Vendor = 11,
URL_Designer = 12,
LicenseDescription = 13,
LicenseInfoURL = 14,
PreferredFamily = 16,
PreferredSubFamily = 17,
CompatibleFull = 18,
SampleText = 19,
PostscriptCID = 20,
WWS_Family_Name = 21,
WWS_SubFamily_Name = 22
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct NamingTableHeader
{
[FieldOffset(0)]
public ushort TableVersion;
[FieldOffset(2)]
public ushort Count;
[FieldOffset(4)]
public ushort stringOffset;
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct NamingRecord
{
[FieldOffset(0)]
public ushort PlatformID;
[FieldOffset(2)]
public ushort EncodingID;
[FieldOffset(4)]
public ushort LanguageID;
[FieldOffset(6)]
public ushort NameID;
[FieldOffset(8)]
public ushort Length;
[FieldOffset(10)]
public ushort Offset;
}
public readonly struct LangTagReccord
{
public readonly ushort lenght;
public readonly ushort offset;
public LangTagReccord(ushort lenght, ushort offset)
{
this.lenght = lenght;
this.offset = offset;
}
};
#endregion
NamingTableHeader name_header;
int langTagCount = 0;
NamingRecord[] name_rec;
LangTagReccord[] tags;
Dictionary> names = new Dictionary>();
public Dictionary> NamesDict
{
get
{
return names;
}
}
public int Count
{
get
{
return name_header.Count;
}
}
public object SyncRoot
{
get
{
return null; // Names.SyncRoot;
}
}
public bool IsSynchronized
{
get
{
return true; // Names.IsSynchronized;
}
}
private void ChangeEndian()
{
name_header.TableVersion = SwapUInt16(name_header.TableVersion);
name_header.Count = SwapUInt16(name_header.Count);
name_header.stringOffset = SwapUInt16(name_header.stringOffset);
}
internal override void Load(FontStream stream)
{
stream.Position = this.Offset;
name_header.TableVersion = stream.ReadUInt16();
name_header.Count = stream.ReadUInt16();
name_header.stringOffset = stream.ReadUInt16();
name_rec = new NamingRecord[name_header.Count];
for (int i = 0; i < name_header.Count; i++)
{
name_rec[i].PlatformID = stream.ReadUInt16();
name_rec[i].EncodingID = stream.ReadUInt16();
name_rec[i].LanguageID = stream.ReadUInt16();
name_rec[i].NameID = stream.ReadUInt16();
name_rec[i].Length = stream.ReadUInt16();
name_rec[i].Offset = stream.ReadUInt16();
}
if (name_header.TableVersion == 1)
{
this.langTagCount = stream.ReadUInt16();
tags = new LangTagReccord[langTagCount];
for (int i = 0; i < this.langTagCount; i++)
{
tags[i] = new LangTagReccord(stream.ReadUInt16(), stream.ReadUInt16());
}
}
// Tables ready. Let's look into them
byte[] Temp;
string value;
int j;
for (int i = 0; i < name_header.Count; i++)
{
if (name_rec[i].PlatformID == 1)
{
Temp = new byte[name_rec[i].Length];
stream.Position = this.Offset + name_header.stringOffset + name_rec[i].Offset;
stream.Read(Temp, name_rec[i].Length);
value = Encoding.GetEncoding("utf-8").GetString(Temp);
}
else
{
Temp = new byte[name_rec[i].Length];
stream.Position = this.Offset + name_header.stringOffset + name_rec[i].Offset;
stream.Read(Temp, name_rec[i].Length);
value = Encoding.GetEncoding(1201).GetString(Temp);
}
NameID id = (NameID)name_rec[i].NameID;
List values;
if (!names.ContainsKey(id))
{
values = new List();
names.Add(id, values);
}
else
{
values = (List)names[id];
}
if (!values.Contains(value))
{
values.Add(value);
}
}
}
public void CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
public IEnumerator GetEnumerator()
{
return names.Keys.GetEnumerator();
}
public ICollection this[NameID Index]
{
get
{
ICollection rec = null;
if (names.ContainsKey(Index))
{
rec = names[Index] as ICollection;
}
return rec;
}
}
public NameTableClass(TrueTypeTable src) : base(src) { }
}
}
#pragma warning restore