OpenType 變數字型
本主題描述 OpenType 變數字型、其在 DirectWrite 和 Direct2D 中的支援,以及如何在應用程式中使用這些字型。
什麼是 OpenType 變數字型?
OpenType 字型格式規格1.8 版引進了稱為OpenType 字型變化之格式的新延伸模組。 使用這些延伸模組的字型稱為 OpenType 變數字型。 OpenType 變數字型是單一字型,可在不同設計之間使用連續插補,全都定義于單一字型內,以類似數個字型的行為。
OpenType 變數字型可以定義其設計沿著一或多個獨立軸的連續變化,例如粗細或寬度:
字型開發人員會決定一組要用於指定字型的變化軸。 這些軸可以包含一組已知的 (或「已註冊」) 變化軸,例如粗細和寬度,但也可以包含由字型開發人員定義的任意自訂變化軸。
藉由為字型選取一組變化軸,字型開發人員會定義字型設計變化的抽象、n 維空間。 文字引擎可以在該連續空間內指定任何位置或「實例」,以配置和轉譯文字。
字型開發人員也可以選取並指派名稱給設計變化空間內的特定實例;這些稱為「具名實例」。 例如,粗細變化的字型可支援非常淺和非常繁重的筆劃之間的連續變化,而字型開發人員已選取該持續性的特定粗細,並為其指派名稱,例如 「Light」、「Regular」 和 「Semibold」。
OpenType 變數字型格式會使用傳統 OpenType 字型中找到的資料表,以及一些其他資料表,描述不同實例各種資料項目的值如何變更。 格式會將一個變化實例指定為「預設實例」,它會使用傳統資料表來取得預設值。 所有其他實例相依于預設資料加上其他差異資料。 例如,'glyf' 資料表可以有標準字元圖形的 Bezier 曲線描述,這是用於預設實例的圖形,而 'spr' 資料表將描述如何調整其他實例的 Bezier 控制點。 同樣地,其他字型值可以有一個名義值加上差異資料,描述這些值在不同實例的變更方式;例如,x 高度和其他全字型度量,或圖像特定的標記錨定位置和 Kerning 調整。
因為變數字型可以支援一組任意的變化軸,所以它們需要字型系列的可延伸模型,更直接反映字型設計工具如何建立字型系列:字型系列是由系列名稱和固定的特定設計特性所定義,而任一數字 (由字型開發人員決定,) 設計可能會有所不同的方式。 一個字型系列可以使用粗細的變體來建立,但不同的字型系列可能會使用 x-height、serif-size、「funkiness」 或任何字型開發人員想要的變體來建立。 在此模型中,最好使用一般或「慣用」或「印刷樣式」、系列名稱加上一組索引鍵/值組來描述字型臉部選取專案,每一組都代表一種變化和特定值,一般變化種類為可延伸集合。 這個字型系列一般概念可以套用至傳統、非變數字型,以及變數字型。 例如,在此一般印刷樣式系列模型中,系列 「Selawik VF」 可能會有重量、光學大小和 serif 設計的變化,例如「半光橫幅 Sans」。
不過,某些現有的軟體實作包括現有的DirectWrite API,可能設計成假設字型系列模型更有限。 例如,某些應用程式可能假設字型系列最多可以有一般、粗體、斜體和粗體斜體變體。 現有的 IDWriteFontCollection 和 IDWriteFontFamily 介面假設權數/延展/樣式 (「WSS」) 系列模型,允許使用 DWRITE_FONT_WEIGHT、 DWRITE_FONT_STRETCH 或 DWRITE_FONT_STYLE 列舉來指定系列內的變體作為參數。 採用上述範例時,光學大小和 serif 軸不會被視為 WSS 模型中變化的家族內部軸。
變數字型的完整支援需要 API,以可能由字型決定的數個參數來指定系列成員。 但是,現有的 API 設計可能會藉由將變數字型中定義的具名實例投影到更有限的字型系列模型中,以提供變數字型的部分支援。 在上一個範例中,「Selawik VF Semilight Banner Sans」 可以投影到 WSS 模型中,做為 「Selawik VF Banner Sans」 系列,而 「Semilight」 是加權變體。
如需另一個範例,請考慮印刷字型系列,例如 Sitka,其粗細和光學大小變化。 系列中的具名變體包括 Sitka Text Regular 和 Sitka Banner Bold (加上許多其他) 。 印刷樣式系列名稱是 「Sitka」,而印刷樣式系列模型中這些變體的臉部名稱會是 「Text Regular」 和 「Banner Bold」。 四個成員和 WSS 系列模型不允許在系列內進行光學大小變化,因此必須將光學大社區別視為家族層級的差異。 下表說明如何在 WSS 系列模型中處理 Sitka 印刷樣式系列中的字型選擇:
印刷樣式系列模型
WSS 系列模型
系列
臉部
系列
臉部
錫特卡
文字一般
Sitka 文字
定期
錫特卡
橫幅粗體
Sitka 橫幅
粗體
錫特卡
標題斜體
Sitka Caption
斜體
從印刷樣式系列模型到 WSS 系列模型的名稱投影可以套用至非變數字型,以及變數字型的具名實例。 不過,對於來引數字型之連續設計變化空間的其他非具名實例,則無法這麼做。 基於這個理由,支援可變字型的完整功能需要 API 設計來參考印刷樣式系列中的臉部,以不受限制的一組變化軸和軸值。
DirectWrite中的 OpenType 變數字型支援
自發行Windows 10 Creators Update開始,OpenType 變數字型格式仍然非常新,而且字型廠商、平臺和應用程式仍在實作新格式的過程中。 此更新會以 DirectWrite 提供此格式的初始實作。
DirectWrite內部已更新以支援 OpenType 變數字型。 使用目前的 API,這可支援變數字型的任何具名實例。 這項支援可用於完整的工作流程,從具名實例的列舉、具名實例的選取範圍、用於版面配置和成形,到轉譯和列印。 為了受益于也針對特定作業使用 GDI 文字 Interop 的應用程式,現有的 GDI API 中也新增了類似的支援。
在Windows 10 Creators Update中,DirectWrite不支援使用可變字型連續變化功能的任意實例。
在許多作業中,變數字型之具名實例DirectWrite的行為無法與非變數字型的行為區別。 而且,由於使用現有的DirectWrite API 提供支援,因此變數字型的具名實例甚至可以在許多現有的DirectWrite應用程式中運作,而不需要進行任何變更。 不過,在某些情況下,可能會套用例外狀況:
- 如果應用程式直接處理特定作業的字型資料。 例如,如果應用程式直接從字型檔案讀取圖像大綱資料,以建立特定的視覺效果。
- 如果應用程式針對特定作業使用協力廠商程式庫。 例如,如果應用程式使用DirectWrite進行版面配置,則取得最終圖像索引和位置,但接著會使用協力廠商程式庫進行轉譯。
- 如果應用程式將字型資料內嵌至檔,或以其他方式將字型資料傳遞至下游程式。
如果使用不支援變數字型的實作來執行作業,這些作業可能不會產生預期的結果。 例如,字元位置可能會針對變數字型的一個具名實例進行計算,但字元可能會轉譯為假設不同的具名實例。 視應用程式實作而定,結果可能會在某些內容中運作,但不適用於其他程式庫可使用的其他內容。 例如,文字可能會在螢幕上正確顯示,但列印時則不會顯示。 如果只使用DirectWrite實作端對端工作流程,則可以預期變數字型的具名實例的正確行為。
由於現有的DirectWrite API 支援使用權數/延展/樣式模型的臉部選取,因此使用其他變化軸的字型具名實例,將會從一般印刷樣式系列模型投影到 WSS 模型,如上所述。 這依賴變數字型,包括「style attributes」 ('STAT') 資料表與座標軸值子資料工作表,DWrite 會用來區分臉部名稱標記,這些標記會指定權數、延展性或樣式屬性與與其他變化軸相關的標記。
如果變數字型不包含 'STAT' 表格,OpenType 規格的變數字型需要,則DirectWrite會將字型視為僅包含預設實例的非變數字型。
如果字型包含 'STAT' 資料表,但不包含適當的座標軸值子資料工作表,可能會導致非預期的結果,例如有多個臉部具有相同臉部名稱的臉部。 目前不支援這類字型。
OpenType 規格允許以兩種格式的其中一種格式來表示圖像大綱資料:使用 'glyf' 資料表、使用 TrueType 大綱和提示格式,或使用 'CFF' 表格,其使用精簡字型格式 (「CFF」) 標記法。 在具有 TrueType 外框的變數字型中,會繼續使用 'glyf' 資料表,並以提供大綱變化資料的 'spr' 資料表補充。 這表示具有 TrueType 外框之變數字型的預設實例只會使用傳統 OpenType 資料表,而舊版軟體不支援任何變數字型。 不過,在具有 CFF 外框的變數字型中,'CFF' 資料表被 'CFF2' 資料表取代,它會封裝預設大綱資料和單一資料表中的相關聯變化資料。 CFF 資料是由用於 TrueType 資料的個別轉譯器處理,而 'CFF2' 資料表需要具有 'CFF2' 支援的已更新 CFF 轉譯器。 舊版 CFF 轉譯器無法處理 'CFF2' 資料表。 對於具有 CFF 大綱資料的變數字型,這表示即使預設實例在舊版軟體中也無法運作。
在Windows 10 Creators Update中,DirectWrite不支援使用 'CFF2' 資料表的 CFF 大綱資料變數字型。
使用 OpenType 變數字型
OpenType 變數字型很容易使用,請記住上述目前的限制:
- 目前僅支援變數字型的具名實例。
- 目前僅支援使用 TrueType 字元外框資料的變數字型, (不支援 CFF 外框) 。
- 對於使用粗細、延展或樣式以外之設計座標軸的字型,具名實例會投影到 WSS 系列模型,這可能會導致某些具名實例顯示為個別系列 (,如同過去非變數字型) 發生的情況一樣。 若要支援這項功能,變數字型必須具有包含適當軸值子資料工作表的 'STAT' 資料表。
- DirectWrite API 支援變數字型的具名實例,但如果某些作業是在不支援變數字型的較舊實作中執行,這些作業可能會產生不正確的結果。
- 某些DirectWrite API 會在選取臉部時使用DWRITE_FONT_WEIGHT、DWRITE_FONT_STRETCH和DWRITE_FONT_STYLE列舉來指定權數、延展和樣式屬性。 如果變數字型使用對應的變化軸,但有許多具名實例需要更精細的資料細微性,則並非所有具名實例都可以在這些 API 中選取。
符合這些需求的 OpenType 變數字型可以像其他 OpenType 字型一樣從 Windows 殼層安裝,也可以在應用程式所建立的自訂字型集中使用。
在系統中安裝時,變數字型的所有具名實例都會包含在呼叫 IDWriteFontFamily3::GetSystemFontSet 方法所傳回的字型集中。 請注意,字型集是不含系列群組階層的一般清單,但集合中的每個專案都有以 WSS 系列模型為基礎的系列名稱屬性。 字型集可以使用 IDWriteFontSet::GetMatchingFonts 方法來篩選特定變數字型具名實例。 不過,如果使用採用 familyName 的 GetMatchingFonts 多載,則指定的 familyName 必須使用符合 WSS 字型系列模型的名稱。 使用 IDWriteFontSet::GetPropertyValues 方法來取得字型集中發生之 WSS 相容系列名稱的完整清單DWRITE_FONT_PROPERTY_ID_FAMILY_NAME。
同樣地,變數字型的所有具名實例都會在 IDWriteFactory::GetSystemFontCollection 方法所傳回的字型集合中表示。 由於字型集合的元素是以 WSS 模型為基礎的字型系列,因此變數字型的具名實例可以在集合中表示為兩個或多個字型系列的成員。 如果使用 IDWriteFontCollection::FindFamilyName 方法,familyName 參數必須是 WSS 相容的系列名稱。 若要從字型集合尋找所有與 WSS 相容的系列名稱,應用程式可以迴圈查看每個系列,並呼叫 IDWriteFontFamily::GetFamilyNames,不過取得對應的字型集和使用 GetPropertyValues 方法可能比較容易,如上所述。
使用自訂字型時,可以使用自訂 字型集 主題中所述的各種方法來建立字型集。 若要將變數字型新增至自訂字型集,建議使用 IDWriteFontSetBuilder1::AddFontFile 方法,因為它支援變數字型,而且會在單一呼叫中新增變數字型的所有具名實例。 目前沒有任何方法可以使用 IDWriteFontSetBuilder::AddFontFaceReference 方法,將自訂變數字型的個別具名實例新增至字型集,因為無法建立字型臉部參考,以指定變數字型檔案中的具名實例。 這表示目前沒有任何方法可將自訂字型的具名實例新增至已指派自訂屬性的自訂字型集。 這表示自訂變數字型目前無法與遠端字型的DirectWrite API 搭配使用。 如果變數字型的具名實例包含在系統字型集中,則每個具名實例的字型臉部參考已存在,而且這些字型可以新增至自訂字型集,包括使用自訂屬性值。 如需詳細資訊,請參閱自訂字型集主題。
使用變數字型時,DirectWrite DWRITE_FONT_WEIGHT和DWRITE_FONT_STRETCH列舉會與 OpenType 規格中定義的粗細和寬度變化軸緊密連接,但不同。 首先,任何變化座標軸的數值小數位數一律支援小數值,而 fontWeight 和 fontStretch 則使用整數。 OpenType 粗細軸小數位數使用範圍從 1 到 1000 的值,fontWeight 也支援此值。 因此,從變化粗細軸值變更為 fontWeight 相當小:針對具名實例報告的 fontWeight 可能會從用來定義字型內具名實例的精確值四捨五入。 DirectWrite fontStretch 和 OpenType 寬度座標軸小數位數之間的差異更大:DirectWrite使用 1 到 9 的值,遵循 OpenType OS/2 資料表的usWidthClass值,而 OpenType 寬度座標軸小數位數則使用正值來代表一般寬度的百分比。 OpenType 規格中的 usWidthClass 檔提供值 1 到 9 與正常百分比值的對應。 從寬度座標軸值轉換時,針對具名實例所報告的 fontStretch 值可能會涉及四捨五入。
建立 IDWriteTextFormat時,必須指定字型集合和 WSS 相容的字型屬性, (系列名稱、粗細、延展和樣式) 。 這也適用于在 IDWriteTextLayout 文字範圍上設定字型格式設定屬性時。 屬性可以從IDWriteFontFace3 物件或 IDWriteFont和代表特定具名實例的IDWriteFontFamily物件取得。 如上所述,GetWeight 和 GetStretch 方法所傳回的值可能會針對用來定義具名實例的實際座標軸值四捨五入,但DirectWrite會將屬性組合對應回所需的具名實例。
同樣地,如果應用程式使用 IDWriteFontFallbackBuilder 來建立自訂字型後援資料,則會使用 WSS 相容的系列名稱來指定字元範圍對應。 DirectWrite內的字型後援是以DirectWrite在後援系列中選取最符合起始系列變體的變體為基礎。 對於涉及權數、延展和樣式以外維度的變體,DirectWrite目前無法在後援系列中選取這類變體,除非特別建立自訂後援資料,以提供具有特定非 WSS 屬性之系列的後援對應,例如 「Caption」 光學大小變體。