OpenType™ Layout通用表格式

OpenType Layout由5個表組成:Glyph置換表(GSUB),Glyph定位表(GPOS ),基線表(BASE),

Justification表 (JSTF),和Glyph定義表(GDEF)。這些表使用了一些相同的數據格式 數組

本章將解釋一下在全部的OpenType Layout表中都會用到的約定(conventions ),並描述一下通用表格式。另外的章節會提供關於 GSUBGPOSBASEJSTFGDEF表,完整而詳細的信息。 app

概覽

OpenType Layout表爲適當的定位和置換glyphs提供了排版信息,及許多語言環境下精確排版所需的操做(operations)。Script,language system,排版feature,和lookup組織而成了OpenType Layout數據 ide

Scripts定義在最頂層。一個script是用於以書寫形式表現一個或多個語言的一些glyphs(參見Figure 2a)。好比,一個script-Latin-用來書寫英語,法語,德語,和許多其餘的語言。與此相反,三個scripts-Hiragana,Katakana和Kanji-用來書寫日語。經過OpenType Layout,多個script也能夠用單獨一個字庫來支持。 佈局


Figure 2a. Latin,Kanji和Arabic scripts裏的Glyph
字體

一個language system可能會修改一個script中的glyphs的功能或者外觀以表現一個特定的語言。好比,德語language system中使用了eszet連字符,但法語和英語中則沒有使用(參見Figure 2b)。Arabic script爲書寫波斯語和烏爾都語languages而包含有不一樣的glyphs。在OpenType Layout中,language systems是在script內定義的。 ui


Figure 2b. English,French和German language systems的不一樣之處 this

一個language system定義了features,它們是使用glyphs來表現一個語言的排版規則。好比「vert」 feature,用於在日語中置換垂直的glyphs, 「liga」 feature用來協助完成使用連字符對分開的多個glyphs的置換操做,「mark」 feature用來在阿拉伯語中調整音節符號相對於基glyphs的位置(參見Figure 2c)。在缺乏特定於語言的規則的狀況下,則默認的language system features應用於整個script。好比Arabic script的一個默認的language system feature,基於一個glyph在單詞中的位置,來置換字首的,字中的和字尾的glyph形式。 編碼


Figure 2c. A ligature glyph feature substitutes the <etc> ligature for individual glyphs, and a mark feature positions diacritical marks above an Arabic ligature glyph. spa

Features經過lookup數據來實現,文字處理客戶端會使用這些數據來置換和定位glyphs。Lookups描述了一個操做會影響到的glyphs,應用於這些glyphs的操做的類型,及做爲結果輸出的glyph。 設計

表的組織

兩種OpenType Layout表,GSUB和GPOS,使用相同的數據格式來描述glyphs的排版功能,及他們支持的language和scripts:一個ScriptList表,一個FeatureList和一個LookupList表。在GSUB中,那些表定義了glyph置換數據。在GPOS中,他們則定義了glyph定位數據。本章將會描述這些通用的表格式。

ScriptList肯定了一個字庫中的scripts,其中每一個script由一個包含有script和language-system數據的Script表來描繪。Language system表引用features,這些features則定義在FeatureList中。每個feature表引用lookup數據,而lookup 數據則定義在LookupList中,而且描述瞭如何,什麼時候,及何地來實現那個feature。

Figure 2d. 置換表和定位表的scripts,language systems,features,和lookups的關係

注意: 和JSTF表中的數據也由script和language system組織而成。然而,其數據格式則與GSUB和GPOS中的不一樣,並且他們不包含有一個FeatureList或者LookupList。BASE和JSTF數據格式在BASE和JSTF章節中有描述。

用於置換和定位glyphs的信息在Lookup子表中定義。依賴於lookup是不是GSUB或者GPOS表的一部分,每個子都表提供了一種類型的信息。好比,一個GSUB lookup可能詳細說明了將被置換的glyphs及置換髮生的上下文,而一個GPOS lookup則可能詳述爲kerning而作的glyph 位置調整。OpenType Layout具備7種類型的GSUB lookups(在GSUB一章中詳述),及9種類型的GPOS lookups(在GPOS一章中描述)。

每一個子表(除了一個擴展LookupType子表外)包含一個Coverage表,其中列出了引發一個glyph置換或定位操做的glyphs。Coverage表的格式將在本章中描述。

一些置換或定位操做可能會應用於glyphs的羣組或類別。GSUB和GPOS Lookup子表使用Class Definition表來給glyphs分配類別。本章包含一個對於Class Definition表的格式的描述。

Lookup子表也可能包含設備表,將會在本章中描述,來爲特定的輸出大小和分辨率調整放縮輪廓glyph的座標。本章也會描述OpenType Layout中使用的數據類型。在本章的末尾會提供一些用於說明通用數據格式的示例的表和列表。

Scripts和Languages

三種表及他們相關的表記錄適用於scripts和languages:Script List表(ScriptList)和它的script記錄(ScriptRecord),Script表和它的language system記錄(LangSysRecord)和Language System表(LangSys)。

Script List 表和Script記錄

OpenType Layout字庫可能包含一個或多個glyphs的羣組,用於渲染多種scripts,這些scripts在一個ScriptList中枚舉出來。GSUB和GPOS表都定義有Script List表(ScriptList):

  • GSUB表使用ScriptList表來訪問應用於一個script的glyph置換features。更多詳情,請參考, Glyph置換表(GSUB)這一章。
  • GPOS表使用ScriptList表來訪問應用於一個script的glyph定位features。更多詳情,請參考, Glyph定位表(GSUB)這一章。

一個ScriptList表包含有字庫中的glyphs將會表現的scripts的個數(ScriptCount),及一個記錄的數組(ScriptRecord),字庫中定義有script-specific features的script每一個一個數組項(一個沒有script-specific feature的script不須要一個ScriptRecord)。

若是ScriptList表中出現了一個script tag爲'DFLT'(默認)的Script表,則它必須具備一個非空的DefaultLangSys,並且其LangSysCount 必須等於0。被格式化的script沒有一個明確的項時,應該使用'DFLT' Script表。

ScriptRecord數組是以標識script的一個ScriptTag的字母順序來存儲記錄的。每個ScriptRecord由一個ScriptTag和一個Script表偏移組成。

本章結尾的例子1顯示了一個使用了3個script的日語字庫的 ScriptList表和ScriptRecords.

ScriptList table

Type Name Description
uint16 ScriptCount ScriptRecords的個數
struct ScriptRecord
[ScriptCount]
ScriptRecords的數組
-依據ScriptTag的字母順序列出

ScriptRecord

Type Name Description
Tag ScriptTag 4-byte ScriptTag 標識符
Offset Script 到Script表的偏移-自ScriptList的起始位置算起

Script 表和Language System記錄

一個Script表肯定了每一個language system,而language system定義瞭如何爲一個特定的語言使用一個script的glyphs。它也引用了一個默認的language system,其中定義了缺乏關於特定語言的知識的狀況下如何使用script的glyph的方法。

一個Script表以一個到默認的Language System表(DefaultLangSys)的偏移量開始,其中定義了管理script的默認行爲的feature的集合。接下來是,Language System Count (LangSysCount)定義了使用了script的language systems的個數(DefaultLangSys除外)。此外,一個Language System Records(LangSysRecord)數組定義了每一個language system(除了默認的),其中每一個language system經過一個標識tag(LangSysTag)和一個到Language System表(LangSys)的偏移來定義。LangSysRecord 數組以LangSysTag的字母順序來存儲記錄。

若是沒有定義language-specific script行爲,則LangSysCount 被設爲0,而且不分配LangSysRecords。

Script table

Type Name Description
Offset DefaultLangSys 到DefaultLangSys表的偏移-從Script表的起始位置算起-可能爲null
uint16 LangSysCount 這個script的LangSysRecords的個數-DefaultLangSys除外
struct LangSysRecord
[LangSysCount]
LangSysRecords的數組-以LangSysTag的字母順序列出

LangSysRecord

Type Name Description
Tag LangSysTag 4-byte LangSysTag 標識符
Offset LangSys 到LangSys表的偏移-自Script表的起始位置算起

Language System表

Language System表 (LangSys)肯定了用於渲染一個script中的glyph的language-system features。(LookupOrder偏移保留用於將來使用。)

可選地,一個LangSys定義一個Required Feature Index (ReqFeatureIndex)來指定一個feature,做爲一個特定的language system上下文中必須的feature。好比,在Cyrillic script中,Serbian language system老是以一種不一樣於Russian language system的方式來渲染某些glyphs。

只有一個feature索引值能夠被標記爲ReqFeatureIndex。然而,這不是一個功能限制,因爲OpenType Layout中的feature和lookup定義是結構化的,於是一個feature表能夠引用許多的glyph置換或者定位lookups。當沒有定義必須的feature時,則ReqFeatureIndex被設爲0xFFFF。

全部其餘的feature都是可選的。對於每個可選的feature,一個基於0的索引值引用了一個存儲於Feature List表(FeatureList)的FeatureRecord 數組中的記錄(FeatureRecord)。在FeatureIndex中,feature索引自己(除ReqFeatureIndex外)是以優先級順序存儲的。FeatureCount描述了FeatureIndex 數組中列出的features的總個數。

Feature是的完整的描述在FeatureList表,FeatureRecord和Feature 表中,他們將會在本章稍後的部分介紹。本章結尾處的例子2顯示了一個用於在Arabic script中進行上下文的定位的Script表,LangSysRecord和LangSys表。

LangSys table

Type Name Description
Offset LookupOrder = NULL (reserved for an offset to a reordering table)
uint16 ReqFeatureIndex Index of a feature required for this language system- if no required features = 0xFFFF
uint16 FeatureCount Number of FeatureIndex values for this language system-excludes the required feature
uint16 FeatureIndex[FeatureCount] Array of indices into the FeatureList-in arbitrary order

Features和Lookups

Features 定義了OpenType Layout字庫的功能,他們都有一個有意義的名字,以便於向文字處理客戶端傳遞必定的含義。考慮一個名稱爲「liga」的feature,它被用於建立連字符。因爲它的名字,客戶端而瞭解到feature是作什麼的,並能夠肯定是否應用它。更多信息,請參考「OpenType Layout Registered Features」一章。字庫建立者可使用這些features,也能夠建立他們本身的。在選中了使用哪些features以後,客戶端收集來自於選中的features的全部的lookups。多個lookups可能被用於爲不一樣的置換和定位行爲定義所需的數據,也可能被用於控制那些行爲的順序和效果。

爲了實現features,一個客戶端以LookupList中定義lookups的順序來應用這些lookups。做爲結果,在GSUB或者GPOS表中,在文字處理的過程當中,來自於不一樣的features可能會被交替應用。當客戶端定位了一個目標glyph或glyph上下文,並執行了一個置換(若是描述了的話)或者一個定位(若是描述了的話)的話,一個lookup就結束了。

注意:置換(GSUB) lookups老是在定位(GPOS) lookups以前發生。TrueType中的lookup 定序機制依賴於字庫,並用於決定文本處理操做的適當的順序。

Lookup數據定義在一個或多個子表中,其中子表裏包含有關於特定的glyph及將會在這些glyphs上執行的操做的信息。每一中類型的lookup具備一個或多個對應的子表定義。一個子表的格式的選擇依賴於兩個因素:將被應用於一個操做的信息的精確內容,和所須要的存儲效率。(關於全部的lookup 類型及子表的完整定義,請參考本文檔的GSUB和GPOS章節。)

OpenType Layout features定義了字庫中glyphs佈局所需的特定信息。他們不編碼一個特別的script的特別的語言或排版中常規上固定不變的信息。一個給定的語言的全部的字庫間將重複出現的信息屬於那個語言的文字處理程序,而不是字庫。

Feature List表

GSUB和GPOS表的表頭包含有到Feature List表(FeatureList)的偏移,其中Feature List表枚舉了一個字庫中全部的features。一個特定的FeatureList中的Features不限於任何單一的script。一個FeatureList中包含有用於渲染字庫中全部scripts的glyphs的GSUB或GPOS features的完整列表。FeatureList表在一個記錄(FeatureRecord)的數組中枚舉features,並說明了features的總個數(FeatureCount)。每個feature必須有一個FeatureRecord,其中FeatureRecord由一個標識了feature的FeatureTag和一個到Feature表(下面描述)的偏移量組成。FeatureRecord數組是按FeatureTag名字的字母順序來安排的。

注意:一個LangSys表的FeatureIndex數組中所存儲的值是被用來定位一個FeatureList表的FeatureRecord數組中的記錄的。

FeatureList table

Type Name Description
uint16 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

Feature表

一個Feature表定義了一個具備一個或多個lookups的feature。客戶端使用lookups來置換或定位glyphs。

GSUB表中定義的Feature表包含有到glyph置換lookups的引用,而GPOS表中定義的feature表包含有到glyph定位lookups的引用。若是一個文字處理操做同時須要glyph置換和定位,則GSUB和GPOS表中必須各定義一個Feature表,而且這兩個表必須使用相同的FeatureTags。

一個Feature表由一個指向了Feature參數(FeatureParams)表的偏移(若是爲這個feature定義了一個的話 - 參見下面的段落中的說明),feature的lookups個數(LookupCount),和一個按優先級順序排列的指向了LookupList(LookupListIndex)裏的索引的數組組成。LookupList索引是指向了 到Lookup表的偏移量的數組 裏的引用。

Feature參數表的格式是特定於一個feature的,而且必須在OpenType Layout Tag Registry的Feature Tags部分中feature的項裏描述。Feature參數表的長度必須隱式地或顯式地在Feature參數表中描述。Feature表中FeatureParams成員記錄了相對於Feature表起始處的偏移。若是不須要一個Feature參數表,則FeatureParams成員必須被設爲NULL。

爲了識別一個GSUB或GPOS表中的features,一個文字處理客戶端會讀取一個給定的LangSys表中所引用的每個FeatureRecord的FeatureTag。而後選擇它想要實現的features,並使用LookupList來提取選中的features的Lookup索引值。接下來,客戶端以LookupList順序來安排這些索引。最後,客戶端應用lookup數據來置換或定位glyphs。本章結尾處的示例3顯示了用於置換兩種語言裏的連字符的FeatureList和Feature表。

Feature table

Type Name Description
Offset FeatureParams = NULL (reserved for offset to FeatureParams)
uint16 LookupCount Number of LookupList indices for this feature
uint16 LookupListIndex
[LookupCount]
Array of LookupList indices for this feature -zero-based (first lookup is LookupListIndex = 0)

Lookup List表

GSUB和GPOS表的表頭包含有到Lookup List表(LookupList)的偏移,其中Lookup List表用於glyph置換(GSUB表)和glyph定位(GPOS表)。LookupList表包含有一個指向Lookup表(Lookup)的偏移量的數組。字庫開發者在Lookup數組中以必定的順序來定義Lookup,以此來控制一個文字處理客戶端應用lookup數據來執行glyph置換和定位操做的順序。LookupCount說明了數組中的Lookup表偏移量的總個數。本章末尾處的示例4顯示了LookupList表中的三個連字符lookups。

LookupList table

Type Name Description
uint16 LookupCount Number of lookups in this table
Offset Lookup[LookupCount] Array of offsets to Lookup tables-from beginning of LookupList -zero based (first lookup is Lookup index = 0)

Lookup表

一個Lookup表(Lookup)定義了用於實現一個feature的一個置換或定位行爲的特定的條件,類型和結果。好比,一個置換操做須要一個被替換的目標glyph索引的列表,一個替換的glyphs索引的列表,和一個替換行爲的類型的描述。

由lookup是不是一個GSUB或GPOS表的一部分決定,每一個Lookup表可能只包含一種類型的信息(LookupType)。GSUB支持吧中LookupTypes,GPOS支持九中LookupTypes(關於LookupTypes的詳細信息,參見本文檔的GSUB和GPOS章節)。

每個LookupType經過一個或多個子表來定義,並且每個子表的定義提供了一種不一樣的表現格式。格式由一個操做所需的信息的內容和所需的存儲效率決定。當glyph信息的以多餘一種的格式表示作好時,一個單獨的lookup可能包含多餘一個的子表,只要全部的子表具備相同的LookupType。好比,一個給定的lookup中,一個glyph索引數組用於表示目標glyphs的一個集合可能最好,而對於另外一個目標glyphs的集合可能glyph索引範圍格式更好。

在文字處理過程當中,一個客戶端在移向下一個lookup以前,會爲字串中的每個glyph應用一個lookup。在客戶端執行了置換/定位操做以後,則對於一個glyph的lookup即結束。爲了移向「下一個」 glyph,典型地,客戶端會跳過全部參與了lookup操做的glyphs:被替換/定位的glyphs,還有爲操做的造成了一個上下文的任何其餘glyphs。然而,成對定位操做(好比,kerning)的狀況下,一個序列中的「下一個」glyph多是被定位的對的第二個glyph(更多詳情請參考成對定位lookup)。

一個Lookup表包含一個LookupType,由一個整數來描述,,定義了lookup中存儲的信息的類型。LookupFlag描述了幫助一個文字處理客戶端置換或定位glyphs的lookup修飾。SubTableCount說明了SubTable的總個數。SubTable數組描述了偏移量,由Lookup表的開始處計算,每一個SubTable都在SubTable數組中枚舉出來。

Lookup table

Type Name Description
uint16 LookupType Different enumerations for GSUB and GPOS
uint16 LookupFlag Lookup qualifiers
uint16 SubTableCount Number of SubTables for this lookup
Offset SubTable
[SubTableCount]
Array of offsets to SubTables-from beginning of Lookup table
unit16 MarkFilteringSet Index (base 0) into GDEF mark glyph sets structure. This field is only present if bit UseMarkFilteringSet of lookup flags is set.

LookupFlag使用兩字節的數據:

  • 首四位中的每一位均可以被設置來描述一些對一個glyph串應用一個lookup的額外的信息。LookupFlag枚舉表提供了關於這些位的使用的詳細信息。
  • 第五位表示Lookup表中的MarkFilteringSet成員的存在。
  • 接下來的三位保留,留給將來使用。
  • 高位字節設置用於說明mark attachment的類型。

LookupFlag bit enumeration

Type Name Description
0x0001 RightToLeft This bit relates only to the correct processing of the cursive attachment lookup type (GPOS lookup type 3). When this bit is set, the last glyph in a given sequence to which the cursive attachment lookup is applied, will be positioned on the baseline. 
Note: Setting of this bit is not intended to be used by operating systems or applications to determine text direction. 
0x0002 IgnoreBaseGlyphs If set, skips over base glyphs
0x0004 IgnoreLigatures If set, skips over ligatures
0x0008 IgnoreMarks If set, skips over all combining marks
0x0010 UseMarkFilteringSet If set, indicates that the lookup table structure is followed by a MarkFilteringSet field. The layout engine skips over all mark glyphs not in the mark filtering set indicated.
0x00E0 Reserved For future use (Set to zero)
0xFF00 MarkAttachmentType If not zero, skips over all marks of attachment type different from specified.

IgnoreBaseGlyphs,IgnoreLigatures或者IgnoreMarks引用了GDEF表中Glyph Class Definition表中定義的base glyph,連字符(ligatures)和marks。若是這些標記中的任何一個被設置了,則必須有一個Glyph Class Definition表出現。若是這些標記中的任何一個被設置了,則lookups必須忽略具備各自類型的glyphs;即,必須像這些glyphs沒有出現同樣處理其餘的glyphs

若是MarkAttachmentType非零,則GDEF表中的Mark Attachment Class Definition表中必須定義mark attachment類別。當處理glyph序列時,一個lookup必須忽略不在指定的mark attachment類別裏的任何的mark glyphs;只處理特定類型的marks。

若是任何lookup設置了UseMarkFilteringSet標記,則Lookup頭必須包含MarkFilteringSet成員,而且GDEF表中必需要有一個MarkGlyphSetsTable。lookup必須忽略任何不屬於指定的mark glyph集合的mark glyphs;而只處理特定的mark glyph集合中的glyphs。

若是指定了一個mark filtering集合,這將代替lookup標記中的任何的mark attachment type 指示。若是設置了IgnoreMarks位,這將代替任何的mark filtering集合或者mark attachment type 指示。

好比,在Arabic文本中,一個字符串可能具備模式base mark base。那個字串可能被轉換爲一個由兩個部分組成的連字符,每一個base字符一個,combining mark glyph則在第一個組件上。爲了產生這個連字符,字庫開發者將設置連字符置換lookup的IgnoreMarks位,來告訴客戶端忽略mark,先置換連字符glyph,而後經過後來的GPOS lookup數據定位mark glyph。另外,一個沒有設置IgnoreMarks位的lookup能夠被用於描述一個三組件的連字符glyph,由第一個base glyph,mark glyph,和第二個base glyph組成。

另外的一個例子,用於建立帶有一個top mark的base glyph連字符的lookup,能夠經過設定mark attachment類型爲只包含top marks的類別而跳過全部的bottom marks。

Coverage表

一個lookup中的每一個子表(除了擴展LookupType子表外)引用一個Coverage表(Coverage),該表詳述了子表中所描述的一個置換或定位操做所影響到的全部的glyphs。GSUB,GPOS和GDEF表均依賴於這個coverage的概念。若是一個glyph沒有出如今一個Coverage表中,則客戶端可跳過那個子表,並當即移向下一個子表。

一個Coverage表以兩種方式經過glyph 索引(GlyphIDs)來描述glyphs:

  • 以glyph集合中的獨立的glyph索引的列表的形式。
  • 以連續索引的範圍的形式。範圍的格式給出了一個起始glyph和結束glyph索引對的數字來表示表所覆蓋的連續的glyphs。

在一個Coverage表中,一個格式碼(CoverageFormat)以一個整數的形式說明了格式:1 = 列表,而2 = 範圍。

一個Coverage表爲每個覆蓋的glyph定義了一個惟一的索引值(CoverageIndex)。這個惟一的值說明了Coverage表中覆蓋的glyph的位置。客戶端使用Coverage Index來在子表中爲每個glyph查找值。

Coverage格式1

Coverage格式1由一個格式碼(CoverageFormat),所覆蓋的glyphs的個數(GlyphCount),後接一個glyph索引的數組(GlyphArray)組成。glyph索引的排列必須是數值順序的,以方便列表的二分搜索。當在Coverage表中發現了一個glyph時,則它在GlyphArray中的位置決定了返回的Coverage Index-第一個glyph的Coverage Index = 0,最後一個glyph的Coverage Index = GlyphCount - 1.

本章末尾處的示例5顯示了一個Coverage表,它使用了格式1來列出字庫中全部的lowercase descender glyphs的GlyphIDs。

CoverageFormat1 table: Individual glyph indices

Type Name Description
uint16 CoverageFormat Format identifier-format = 1
uint16 GlyphCount Number of glyphs in the GlyphArray
GlyphID GlyphArray[GlyphCount] Array of GlyphIDs-in numerical order

Coverage Format 2

格式2有一個格式碼(CoverageFormat),glyph索引範圍的個數(RangeCount),後面接着一個記錄(RangeRecords)的數組組成。每一個RangeRecords由一個起始glyph索引(Start),一個結束glyph索引(End),及與範圍的Start glyph相關聯的Coverage Index組成。範圍必須是按照GlyphID的順序排序的,而且他們必須是有區別的,沒有重疊的。

第一個範圍的Coverage Indexes以0值開始,而且每個連續的範圍的Start Coverage Indexes經過將前一個範圍的長度(End GlyphID - Start GlyphID + 1)加上數組索引而求得。這樣就能夠經過公式迅速地計算任何範圍中任何glyph的Coverage Index了:Coverage Index (GlyphID) = StartCoverageIndex + GlyphID - Start GlyphID。

本章結尾處的示例6顯示了一個Coverage表,它使用了格式2來描述字庫中的一個數字glyphs的範圍。

CoverageFormat2 table: Range of glyphs

Type Name Description
uint16 CoverageFormat Format identifier-format = 2
uint16 RangeCount Number of RangeRecords
struct RangeRecord
[RangeCount]
Array of glyph ranges-ordered by Start GlyphID

RangeRecord

Type Name Description
GlyphID Start First GlyphID in the range
GlyphID End Last GlyphID in the range
uint16 StartCoverageIndex Coverage Index of first GlyphID in range

類別定義表

在OpenType Layout中,用索引值表示glyphs。爲了高效並簡單的表示,一個字庫開發者能夠將glyph索引分紅組以造成類別。分配的類別值的含義在不一樣的lookup子表中是不一樣的。好比,在GSUB和GPOS表中,類被被用於描述glyph上下文。GDEF表也使用glyph 類別的概念。

考慮一個置換行爲,它只置換一個glyph串中的lowercase ascender glyphs。爲了更簡單的描述置換的適當的上下文,字庫開發者可能會將字庫的lowercase glyphs分爲兩個類別,一個包含ascenders,另外一個包含沒有ascenders的glyphs。

一個字庫開發者能夠給任何glyph分配任何的類別,每個類別經過一個稱爲類別值的整數來識別。一個Class Definition表(ClassDef)經過類別值來爲glyph索引分組,由Class 1開始,而後是Class 2,等等。全部那些沒有分配類別的glyphs落入Class 0。一個給定的類別定義表中,字庫中的每一個glyph都精確的屬於一個類別。

ClassDef表可能具備兩種格式中的一種:一種是將一個連續的glyph索引範圍分配不一樣的類別,另外一種是連續的glyph索引的組放進相同的類別。

Class Definition Table Format 1

第一種類別定義格式(ClassDefFormat1)描述了一個連續的glyph索引的範圍和一個對應的glyph類別值的列表。這個表在給每一個glyph分配不一樣的類別時頗有用,由於沒個類別的glyph索引沒有辦法被分組在一塊兒。

一個ClassDef 格式1表以一個格式標識符(ClassFormat)開始。表所覆蓋的glyph索引(GlyphIDs)的範圍由兩個值來描述:第一個glyph的GlyphID(StartGlyph),及將會被分配類別值的連續GlyphIDs(包括第一個)的個數(GlyphCount)。ClassValueArray列出了給每一個GlyphID分配的類別值,以StartGlyph的類別值開始,後面以與GlyphIDs相同的順序排序。任何沒有被包含在所覆蓋的GlyphIDs範圍的glyph自動地歸爲類別0。

本章結尾處的示例7使用格式1來給一個字庫中的lowercase,x-height,ascender,和descender glyphs分配類別值。

ClassDefFormat1 table: Class array

Type Name Description
uint16 ClassFormat Format identifier-format = 1
GlyphID StartGlyph First GlyphID of the ClassValueArray
uint16 GlyphCount Size of the ClassValueArray
uint16 ClassValueArray[GlyphCount] Array of Class Values-one per GlyphID

Class Definition Table Format 2

第二種類別定義格式(ClassDefFormat2)定義了分別屬於相同的類別的多個glyph索引的組。各個組以連續順序(範圍不能重疊)由glyph 索引的分離的範圍組成。

ClassDef 格式2表包含一個格式標識符(ClassFormat),定義了組及其分配的類別值的ClassRangeRecords的個數(ClassRangeCount),及以每一個記錄(ClassRangeRecord)中的第一個glyph的GlyphID排序的ClassRangeRecords 數組組成。

每一個ClassRangeRecord由一個Start glyph索引,一個End glyph索引,和一個類別值組成。範圍內的全部的GlyphIDs,從Start到End都包括,構成了類別值所描述的類別。沒有一個ClassRangeRecord 覆蓋的任何glyph假設屬於類別0。

本章結尾處的示例8使用了格式2來爲Arabic script裏四種類型的glyphs分配類別值。

ClassDefFormat2 table: Class ranges

Type Name Description
uint16 ClassFormat Format identifier-format = 2
uint16 ClassRangeCount Number of ClassRangeRecords
struct ClassRangeRecord
[ClassRangeCount]
Array of ClassRangeRecords-ordered by Start GlyphID

ClassRangeRecord

Type Name Description
GlyphID Start First GlyphID in the range
GlyphID End Last GlyphID in the range
uint16 Class Applied to all glyphs in the range

設備表

字庫中的glyphs都是由字庫開發者專門以設計單位定義。字體縮放增長或這減少一個glyph的大小,並將它round到最接近的整數pixel上。然而,精確的glyph定位經常須要調整這些縮放和rounded的值。微調(Hinting),應用於glyph輪廓的點上,是這個問題的一個有效的解決方案,但它可能須要字庫開發者來從新設計或re-hint glyphs。

另外一個解決方案-由GPOS,BASE,JSTF和GDEF所使用的-是使用設備表描述校訂值以便於調整縮放的設計單位。一個設備表給由StartSize和EndSize所描述的大小的範圍應用校訂值,大小範圍描述了須要調整的最小的和最大的pixel-per-em(ppem)大小。因爲這種調整經常都是很小的(一個pixel或兩個),校訂值能夠被壓縮進每大小一個的2-,4-或者8-bit的representation。兩位能夠表示一個範圍在{-2, -1, 0, or 1}的數,4位能夠表示一個範圍在{-8 to 7}的數,8位則能夠表示一個範圍爲{-128 to 127}的數。設備表爲校訂值說明了三種數據—2-,4-,或8-bit值—格式中的一種(DeltaFormat)。一個單獨的設備表爲某一大小範圍的調整提供增量信息。

Type Name Description
1 2 Signed 2-bit value, 8 values per uint16
2 4 Signed 4-bit value, 4 values per uint16
3 8 Signed 8-bit value, 2 values per uint16

2-,4-,或8-bit有符號值會被打包進uint16的高位優先的數字裏。好比,DeltaFormat爲2(4-bit 值),則一個值爲{1, 2, 3, -1}的數組將會由一個DeltaValue 0x123F來表示。

DeltaValue數組列出了在目標範圍內每一個ppem大小下,glyph上特定的點或整個glyph所需調整的像素數。在數組中,第一個索引位置描述了須要校訂的最小的ppem大小下,座標所須要加或減的像素數,第二個索引位置描述了下一個ppem大小下,座標所須要加或減的像素數,以此方式定義範圍內每一個ppem大小的信息。

本章結尾處的示例9描述了一個設備表來爲一個匹配的script定義的最小的擴展值。

Device table

Type Name Description
uint16 StartSize Smallest size to correct-in ppem
uint16 EndSize Largest size to correct-in ppem
uint16 DeltaFormat Format of DeltaValue array data: 1, 2, or 3
uint16 DeltaValue[ ]

Array of compressed data

通用表的例子

本章的剩餘部分將描述和說明全部的通用表格式的例子。

Done

相關文章
相關標籤/搜索