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