mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-12 10:19:07 +00:00
173 lines
8.9 KiB
C#
173 lines
8.9 KiB
C#
//Apache2, 2016-present, WinterDev
|
|
//https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-table-and-language-system-record
|
|
|
|
using System.IO;
|
|
|
|
namespace Typography.OpenFont.Tables
|
|
{
|
|
//Script Table and Language System Record
|
|
//A Script table identifies each language system that defines how to use the glyphs in a script for a particular language.
|
|
//It also references a default language system that defines how to use the script's glyphs in the absence of language-specific knowledge.
|
|
|
|
//A Script table begins with an offset to the Default Language System table (DefaultLangSys),
|
|
//which defines the set of features that regulate the default behavior of the script.
|
|
//Next, Language System Count (LangSysCount) defines the number of language systems (excluding the DefaultLangSys) that use the script.
|
|
//In addition, an array of Language System Records (LangSysRecord) defines each language system (excluding the default)
|
|
//with an identification tag (LangSysTag) and an offset to a Language System table (LangSys).
|
|
//The LangSysRecord array stores the records alphabetically by LangSysTag.
|
|
|
|
//If no language-specific script behavior is defined, the LangSysCount is set to zero (0), and no LangSysRecords are allocated.
|
|
//-----------------------
|
|
//Script table
|
|
//Type Name Description
|
|
//Offset16 defaultLangSys Offset to DefaultLangSys table-from beginning of Script table-may be NULL
|
|
//uint16 langSysCount Number of LangSysRecords for this script-excluding the DefaultLangSys
|
|
//LangSysRecord langSysRecords[langSysCount] Array of LangSysRecords-listed alphabetically by LangSysTag
|
|
|
|
//-----------------------
|
|
//LangSysRecord
|
|
//Type Name Description
|
|
//Tag langSysTag 4-byte LangSysTag identifier
|
|
//Offset16 langSysOffset Offset to LangSys table-from beginning of Script table
|
|
//-----------------------
|
|
//
|
|
//Language System Table
|
|
//-----------------------
|
|
//The Language System table (LangSys) identifies language-system features
|
|
//used to render the glyphs in a script. (The LookupOrder offset is reserved for future use.)
|
|
|
|
//Optionally, a LangSys table may define a Required Feature Index (ReqFeatureIndex) to specify one feature as required
|
|
//within the context of a particular language system. For example, in the Cyrillic script,
|
|
//the Serbian language system always renders certain glyphs differently than the Russian language system.
|
|
|
|
//Only one feature index value can be tagged as the ReqFeatureIndex.
|
|
//This is not a functional limitation, however, because the feature and lookup definitions in OpenType
|
|
//Layout are structured so that one feature table can reference many glyph substitution and positioning lookups.
|
|
//When no required features are defined, then the ReqFeatureIndex is set to 0xFFFF.
|
|
|
|
//All other features are optional. For each optional feature,
|
|
//a zero-based index value references a record (FeatureRecord) in the FeatureRecord array,
|
|
//which is stored in a Feature List table (FeatureList).
|
|
//The feature indices themselves (excluding the ReqFeatureIndex) are stored in arbitrary order in the FeatureIndex array.
|
|
//The FeatureCount specifies the total number of features listed in the FeatureIndex array.
|
|
|
|
//Features are specified in full in the FeatureList table, FeatureRecord, and Feature table,
|
|
//which are described later in this chapter.
|
|
//Example 2 at the end of this chapter shows a Script table, LangSysRecord, and LangSys table used for contextual positioning in the Arabic script.
|
|
|
|
//---------------------
|
|
//LangSys table
|
|
//Type Name Description
|
|
//Offset16 lookupOrder = NULL (reserved for an offset to a reordering table)
|
|
//uint16 requiredFeatureIndex Index of a feature required for this language system- if no required features = 0xFFFF
|
|
//uint16 featureIndexCount Number of FeatureIndex values for this language system-excludes the required feature
|
|
//uint16 featureIndices[featureIndexCount] Array of indices into the FeatureList-in arbitrary order
|
|
//---------------------
|
|
public class ScriptTable
|
|
{
|
|
public uint scriptTag { get; internal set; }
|
|
public LangSysTable defaultLang { get; private set; }// be NULL
|
|
public LangSysTable[] langSysTables { get; private set; }
|
|
|
|
public string ScriptTagName => Utils.TagToString(this.scriptTag);
|
|
|
|
public static ScriptTable CreateFrom(BinaryReader reader, long beginAt)
|
|
{
|
|
reader.BaseStream.Seek(beginAt, SeekOrigin.Begin);
|
|
//---------------
|
|
//Script table
|
|
//Type Name Description
|
|
//Offset16 defaultLangSys Offset to DefaultLangSys table-from beginning of Script table-may be NULL
|
|
//uint16 langSysCount Number of LangSysRecords for this script-excluding the DefaultLangSys
|
|
//LangSysRecord langSysRecords[langSysCount] Array of LangSysRecords-listed alphabetically by LangSysTag
|
|
|
|
//---------------
|
|
ScriptTable scriptTable = new ScriptTable();
|
|
ushort defaultLangSysOffset = reader.ReadUInt16();
|
|
ushort langSysCount = reader.ReadUInt16();
|
|
LangSysTable[] langSysTables = scriptTable.langSysTables = new LangSysTable[langSysCount];
|
|
for (int i = 0; i < langSysCount; ++i)
|
|
{
|
|
//-----------------------
|
|
//LangSysRecord
|
|
//Type Name Description
|
|
//Tag langSysTag 4-byte LangSysTag identifier
|
|
//Offset16 langSysOffset Offset to LangSys table-from beginning of Script table
|
|
//-----------------------
|
|
|
|
langSysTables[i] = new LangSysTable(
|
|
reader.ReadUInt32(), // 4-byte LangSysTag identifier
|
|
reader.ReadUInt16()); //offset
|
|
}
|
|
|
|
//-----------
|
|
if (defaultLangSysOffset > 0)
|
|
{
|
|
scriptTable.defaultLang = new LangSysTable(0, defaultLangSysOffset);
|
|
reader.BaseStream.Seek(beginAt + defaultLangSysOffset, SeekOrigin.Begin);
|
|
scriptTable.defaultLang.ReadFrom(reader);
|
|
}
|
|
|
|
|
|
//-----------
|
|
//read actual content of each table
|
|
for (int i = 0; i < langSysCount; ++i)
|
|
{
|
|
LangSysTable langSysTable = langSysTables[i];
|
|
reader.BaseStream.Seek(beginAt + langSysTable.offset, SeekOrigin.Begin);
|
|
langSysTable.ReadFrom(reader);
|
|
}
|
|
|
|
return scriptTable;
|
|
}
|
|
|
|
#if DEBUG
|
|
public override string ToString()
|
|
{
|
|
return Utils.TagToString(this.scriptTag);
|
|
}
|
|
#endif
|
|
|
|
public class LangSysTable
|
|
{
|
|
//The Language System table (LangSys) identifies language-system features
|
|
//used to render the glyphs in a script. (The LookupOrder offset is reserved for future use.)
|
|
//
|
|
public uint langSysTagIden { get; private set; }
|
|
internal readonly ushort offset;
|
|
|
|
//
|
|
public ushort[] featureIndexList { get; private set; }
|
|
public ushort RequiredFeatureIndex { get; private set; }
|
|
|
|
public LangSysTable(uint langSysTagIden, ushort offset)
|
|
{
|
|
this.offset = offset;
|
|
this.langSysTagIden = langSysTagIden;
|
|
}
|
|
public void ReadFrom(BinaryReader reader)
|
|
{
|
|
//---------------------
|
|
//LangSys table
|
|
//Type Name Description
|
|
//Offset16 lookupOrder = NULL (reserved for an offset to a reordering table)
|
|
//uint16 requiredFeatureIndex Index of a feature required for this language system- if no required features = 0xFFFF
|
|
//uint16 featureIndexCount Number of FeatureIndex values for this language system-excludes the required feature
|
|
//uint16 featureIndices[featureIndexCount] Array of indices into the FeatureList-in arbitrary order
|
|
//---------------------
|
|
|
|
ushort lookupOrder = reader.ReadUInt16();//reserve
|
|
RequiredFeatureIndex = reader.ReadUInt16();
|
|
ushort featureIndexCount = reader.ReadUInt16();
|
|
featureIndexList = Utils.ReadUInt16Array(reader, featureIndexCount);
|
|
|
|
}
|
|
public bool HasRequireFeature => RequiredFeatureIndex != 0xFFFF;
|
|
public string LangSysTagIdenString => (langSysTagIden == 0) ? "" : Utils.TagToString(langSysTagIden);
|
|
#if DEBUG
|
|
public override string ToString() => LangSysTagIdenString;
|
|
#endif
|
|
|
|
}
|
|
}
|
|
} |