protected override void ReadContentFrom(BinaryReader reader) { gposTableStartAt = reader.BaseStream.Position; //------------------------------------------- // GPOS Header //The GPOS 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 Header table definition. //GPOS Header, Version 1.0 //Value Type Description //USHORT MajorVersion Major version of the GPOS table, = 1 //USHORT MinorVersion Minor version of the GPOS table, = 0 //Offset ScriptList Offset to ScriptList table, from beginning of GPOS table //Offset FeatureList Offset to FeatureList table, from beginning of GPOS table //Offset LookupList Offset to LookupList table, from beginning of GPOS table //GPOS Header, Version 1.1 //Value Type Description //USHORT MajorVersion Major version of the GPOS table, = 1 //USHORT MinorVersion Minor version of the GPOS table, = 1 //Offset ScriptList Offset to ScriptList table, from beginning of GPOS table //Offset FeatureList Offset to FeatureList table, from beginning of GPOS table //Offset LookupList Offset to LookupList table, from beginning of GPOS table //ULONG FeatureVariations Offset to FeatureVariations table, from beginning of GPOS table (may be NULL) this.MajorVersion = reader.ReadUInt16(); this.MinorVersion = reader.ReadUInt16(); ushort scriptListOffset = reader.ReadUInt16();//from beginning of GSUB table ushort featureListOffset = reader.ReadUInt16();//from beginning of GSUB table ushort lookupListOffset = reader.ReadUInt16();//from beginning of GSUB table uint featureVariations = (MinorVersion == 1) ? reader.ReadUInt32() : 0;//from beginning of GSUB table //----------------------- //1. scriptlist scriptList = ScriptList.CreateFrom(reader, gposTableStartAt + scriptListOffset); //----------------------- //2. feature list featureList = FeatureList.CreateFrom(reader, gposTableStartAt + featureListOffset); //----------------------- //3. lookup list ReadLookupListTable(reader, gposTableStartAt + lookupListOffset); //----------------------- //4. feature variations if (featureVariations > 0) { reader.BaseStream.Seek(this.Header.Offset + featureVariations, SeekOrigin.Begin); ReadFeaureVariations(reader); } }
public static ScriptList CreateFrom(BinaryReader reader, long beginAt) { reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); //https://www.microsoft.com/typography/otspec/chapter2.htm //ScriptList table //Type Name Description //USHORT ScriptCount Number of ScriptRecords //struct ScriptRecord //[ScriptCount] Array of ScriptRecords //-listed alphabetically by ScriptTag //ScriptRecord //Type Name Description //Tag ScriptTag 4-byte ScriptTag identifier //Offset Script Offset to Script table-from beginning of ScriptList ScriptList scriptList = new ScriptList(); ushort scriptCount = reader.ReadUInt16(); ScriptRecord[] scRecords = scriptList.scriptRecords = new ScriptRecord[scriptCount]; for (int i = 0; i < scriptCount; ++i) { //read script record scRecords[i] = new ScriptRecord( reader.ReadUInt32(), //tag reader.ReadInt16());//offset } //------------- ScriptTable[] scriptTables = scriptList.scriptTables = new ScriptTable[scriptCount]; //then read each for (int i = 0; i < scriptCount; ++i) { ScriptRecord scriptRecord = scRecords[i]; //move to ScriptTable scriptTable = ScriptTable.CreateFrom(reader, beginAt + scriptRecord.offset); scriptTable.scriptTag = scriptRecord.scriptTag; scriptTables[i] = scriptTable; } return scriptList; }