} // 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); if (OnlyScriptList) { return; //for preview script-list and feature list only } //----------------------- //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 FeatureList CreateFrom(BinaryReader reader, long beginAt) { //https://www.microsoft.com/typography/otspec/chapter2.htm //FeatureList table //Type Name Description //USHORT FeatureCount Number of FeatureRecords in this table //struct FeatureRecord[FeatureCount] Array of FeatureRecords-zero-based (first feature has FeatureIndex = 0)-listed alphabetically by FeatureTag //FeatureRecord //Type Name Description //Tag FeatureTag 4-byte feature identification tag //Offset Feature Offset to Feature table-from beginning of FeatureList reader.BaseStream.Seek(beginAt, SeekOrigin.Begin); // FeatureList featureList = new FeatureList(); ushort featureCount = reader.ReadUInt16(); FeatureRecord[] featureRecords = new FeatureRecord[featureCount]; for (int i = 0; i < featureCount; ++i) { //read script record featureRecords[i] = new FeatureRecord( reader.ReadUInt32(), //feature tag reader.ReadInt16()); //offset } //read each feature table FeatureTable[] featureTables = featureList.featureTables = new FeatureTable[featureCount]; for (int i = 0; i < featureCount; ++i) { FeatureRecord frecord = featureRecords[i]; (featureTables[i] = FeatureTable.CreateFrom(reader, beginAt + frecord.offset)).FeatureTag = frecord.featureTag; } return(featureList); }