多換一,也就是將多個字符轉換成一個字符也是相當常用的一種方式,基本用於處理連字,語法為
substitute <glyph sequence> by <glyph>;
以標準連字功能而言,我們可以定義一系列和 f
有關的字符對,讓使用者在輸入他們的時候,將輸入的字符轉成對應的連字,
feature liga {
sub f f by f_f;
sub f i by f_i;
} liga;
要特別注意的是,AFDKO 和多數的語言一樣,會由上往下執行替換規則。雖然規格上 AFDKO 有要求軟體處理 理想 的連字排序,但實際上多數的軟體不會自動排列順序,所以在編寫規則的時候,必須考慮指定執行的順序。
以下面的規則來說,我們必須要優先處理 ffi
轉 f_f_i
的連字,所以 ffi
規則要寫在最上面。
# 正確的順序
feature liga {
sub f f i by f_f_i;
sub f f by f_f;
sub f i by f_i;
} liga;
反之,如果順序寫反了,把 ffi
置於最後,則軟體在執行第一條規則時, ffi
就會優先被轉成 [f_f]i
,接下來的規則就無法觸發了。
# 錯誤的順序
feature liga {
sub f f by f_f;
sub f i by f_i;
sub f f i by f_f_i;
} liga;
除了連字系列的 feature 之外,另一個例子是 frac 特性,可以將數字、slash(/
)、數字,合併成一個分數的樣子
feature frac {
substitute [one one.oldstyle] [slash fraction] [two two.oldstyle] by onehalf;
...
} frac;
在這裡,我們使用方括號進行枚舉,因此,上面的規則等價於下面的表達式
feature frac {
substitute one slash two by onehalf;
substitute one.oldstyle slash two by onehalf;
substitute one fraction two by onehalf;
substitute one.oldstyle fraction two by onehalf;
substitute one slash two.oldstyle by onehalf;
substitute one.oldstyle slash two.oldstyle by onehalf;
substitute one fraction two.oldstyle by onehalf;
substitute one.oldstyle fraction two.oldstyle by onehalf;
} frac;
連字的設計對歐文來說或許非必要(沒有 f_i
這類的還是看得懂,只是很醜而已),但對於許多文字的表示至關重要,尤其是婆羅米系文字,常常會出現複子音或是母音變形的現象。
以柬埔寨語使用的高棉文(Khmer)為例,當一個詞出現兩個以上的子音的時候,第二個之後的子音需要被「折疊」到第一個子音之下。
在柬埔寨的國名 កម្ពុជា
[k / m-p-ou / ch-ea] 裡,第二個字母便出現了 [m-p-] 這樣的雙子音。此時對輸入法而言,兩個子音之間透過 子音附加符(U+17D2
)連接在一起,會將後面的 [p-] 子音「折疊」到第一個 [m-] 子音之下,折疊的 [p-] 子音會以附加型(subscript form)出現。
而在高棉文的 ខ្មែរ
[Kh-m-e-r] 裡,此時的 [m-] 子音為第二子音,在輸入時會位於子音附加符之後,所以會被折疊到 [k-] 子音的下面,並以附加型表示。
相較於母音可以使用附加符號的去組合(類似 ccmp),附加型的子音會變形,因此可以透過連字的判斷,當「子音附加符」與子音出現時,便將後面的子音轉成附加型。
feature blwf {
sub uni17D2 uni1796 by uni1796.below; # p-
sub uni17D2 uni1798 by uni1798.below; # m-
...
} blwf;
在婆羅米系的文字裡,很常會看到同樣的發音、樣貌卻完全不同的附加型,這可以說是婆羅米系文字的一大特色,也是數位時代必須要解決的問題之一。
和處理歐文較為單純的 ccmp 和 liga 相比,OpenType 裡面有提供更複雜的 pref(置前形式)、blwf(置下形式)、abvf(置上形式)、pstf(置後形式)、pres(置前替代形式)、blws(置下替代形式)、abvs(置上替代形式)、psts(置後替代形式)等 feature 可以對字母進行操作,其原理都是 LookupType 4: Ligature substitution 的替換,和 ccmp 與 liga 的邏輯是一樣的。