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);
        }