protected override void ReadContentFrom(BinaryReader reader) { //------------------------------------------- // GPOS/GSUB Header // The GPOS/GSUB table begins with a header that contains a version number for the table. Two versions are defined. // Version 1.0 contains offsets to three tables: ScriptList, FeatureList, and LookupList. // Version 1.1 also includes an offset to a FeatureVariations table. // For descriptions of these tables, see the chapter, OpenType Layout Common Table Formats . // Example 1 at the end of this chapter shows a GPOS/GSUB Header table definition. // // GPOS/GSUB Header, Version 1.0 // Value Type Description // uint16 MajorVersion Major version of the GPOS/GSUB table, = 1 // uint16 MinorVersion Minor version of the GPOS/GSUB table, = 0 // Offset16 ScriptList Offset to ScriptList table, from beginning of GPOS/GSUB table // Offset16 FeatureList Offset to FeatureList table, from beginning of GPOS/GSUB table // Offset16 LookupList Offset to LookupList table, from beginning of GPOS/GSUB table // // GPOS/GSUB Header, Version 1.1 // Value Type Description // uint16 MajorVersion Major version of the GPOS/GSUB table, = 1 // uint16 MinorVersion Minor version of the GPOS/GSUB table, = 1 // Offset16 ScriptList Offset to ScriptList table, from beginning of GPOS/GSUB table // Offset16 FeatureList Offset to FeatureList table, from beginning of GPOS/GSUB table // Offset16 LookupList Offset to LookupList table, from beginning of GPOS/GSUB table // Offset32 FeatureVariations Offset to FeatureVariations table, from beginning of GPOS/GSUB table (may be NULL) long tableStartAt = reader.BaseStream.Position; MajorVersion = reader.ReadUInt16(); MinorVersion = reader.ReadUInt16(); ushort scriptListOffset = reader.ReadUInt16(); // from beginning of table ushort featureListOffset = reader.ReadUInt16(); // from beginning of table ushort lookupListOffset = reader.ReadUInt16(); // from beginning of table uint featureVariations = (MinorVersion == 1) ? reader.ReadUInt32() : 0; // from beginning of table //----------------------- //1. scriptlist ScriptList = ScriptList.CreateFrom(reader, tableStartAt + scriptListOffset); //----------------------- //2. feature list FeatureList = FeatureList.CreateFrom(reader, tableStartAt + featureListOffset); //----------------------- //3. lookup list ReadLookupListTable(reader, tableStartAt + lookupListOffset); //----------------------- //4. feature variations if (featureVariations > 0) { ReadFeatureVariations(reader, tableStartAt + featureVariations); } }
public static ScriptList CreateFrom(BinaryReader reader, long beginAt) { // https://www.microsoft.com/typography/otspec/chapter2.htm // // ScriptList table // Type Name Description // uint16 ScriptCount Number of ScriptRecords // struct ScriptRecord[ScriptCount] Array of ScriptRecords // -listed alphabetically by ScriptTag // ScriptRecord // Type Name Description // Tag ScriptTag 4-byte ScriptTag identifier // Offset16 Script Offset to Script table-from beginning of ScriptList reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); ushort scriptCount = reader.ReadUInt16(); ScriptList scriptList = new ScriptList(); // Read records (tags and table offsets) uint[] scriptTags = new uint[scriptCount]; ushort[] scriptOffsets = new ushort[scriptCount]; for (int i = 0; i < scriptCount; ++i) { scriptTags[i] = reader.ReadUInt32(); scriptOffsets[i] = reader.ReadUInt16(); } // Read each table and add it to the dictionary for (int i = 0; i < scriptCount; ++i) { ScriptTable scriptTable = ScriptTable.CreateFrom(reader, beginAt + scriptOffsets[i]); scriptTable.scriptTag = scriptTags[i]; scriptList.Add(Utils.TagToString(scriptTags[i]), scriptTable); } return(scriptList); }