TeX 主題選講:字體
來自專欄 All about TeXnique
original post: TeX 主題選講:字體
此篇基本上是譯文,原文是 Victor Eijkhout 所著的《TeX by Topic》的第四章。譯文項目參見:CTeX-org/tex-by-topic-cn。轉載請保留本段文字,尊重原作者和譯者版權。由於原著使用 GFDL,故而本文也被傳染地同樣使用 GFDL 許可,而不是本站默認的 BY-NC-SA 4.0 許可。
在文本模式下,TeX 會從「當前字體」中取用字元。本章討論 TeX 是如何識別不同字體的,以及字體都有哪些屬性。
所涉命令編目:
font
: 該命令可聲明一個用於指定字體的控制序列。fontname
: 字體的外部名字。
: 在特殊情況下,TeX 會使用空字體。這是空字體的名字。
ullfonthyphenchar
: 字體中連字元的序號。defaulthyphenchar
: 字體裝載時hyphenchar
的默認值。在 plain TeX 中,默認是`-
。fontdimen
: 該命令可訪問多種字體參數。/
: 傾斜校正原語。
: 忽略隱式邊界字元。
oboundary
字體
在 TeX 語境下,字體(font)這一術語指的是保存在外部文件中的一系列字元的集合。TeX 在運行時,會決定從哪一個字體中選取字元。而具體決策方式在文本模式和數學模式中又是不同的。
TeX 處理普通文本時會從「當前字體」中選取字元。通過字體聲明,TeX 會將外部字體文件與字體選擇命令聯繫起來。例如,下列聲明會使 TeX 裝載名為 myfont10.tfm
的字體文件。
fontMyFont=myfont10
此後,通過下列命令,我們就可以選擇使用該文件定義的字體了。
MyFont
當前字體的狀態是可查的:下列命令會產生當前字體對應的控制序列。
hefont
數學模式下,TeX 會忽略當前字體;轉而考察當前「字族」,其中有三個字體:正文字體(text style),角標字體(script style),雙重角標字體(scriptscript style)。
從不同物理字體文件中分別選取部分字元,可以組成的「虛擬字體」。在 TeX 看來,這種虛擬字體就像是真實字體一樣。
字體聲明
TeX 或 IniTeX 在執行時,必然在某處會建立內部字體選擇命令與外部字體文件名的聯繫。font 字體聲明的語法如下:
font<control sequence><equals><file name><at clause>
這裡,<at clause>
指的是:
注意,字體聲明僅在當前分組內生效。
用戶可以通過 <at clause>
指定字體的放大版本。<at clause>
有兩種形式:如果指定縮放比例 scaled
ff,則 TeX 會將該字體中的所有字元尺寸倍乘 f/1000f/1000;如果指定目標大小 at
ffpt
,而字體本身的設計大小是 ddpt
,則 TeX 會將該字體中的所有字元尺寸倍乘 f/df/d。注意,<at clause>
不會影響 TeX 從外部字體文件(.tfm
文件)中讀入字體的過程;它只是在尺寸上乘了一個固定的倍數。
這樣聲明字體後,使用定義得到的控制序列會將當前字體設置為控制序列相應的字體。
字體與 tfm 文件
TeX 所需的外部字體文件是 tfm
文件(TeX 字體尺寸文件,TeX Font Metrics File),這些文件不受 font
聲明中 <at clause>
的影響。如果 tfm
事先已裝載好(比如在構造格式文件時由 IniTeX 裝載),則再次聲明同一字體時,不依賴且無需重複載入 tfm
文件。
字體本身的設計大小由字體尺寸文件給出。例如,字體 cmr10
的設計大小是 10 點(point)。但實際上,字體中沒有多少字元大小是 10 點:左右圓括弧恰好是 10 點,但大寫字母明顯會小一點。
查詢當前字體及字體名
前文提到過,當前字體的字體選擇命令可通過 hefont
得到。這是下列語法的一個特例。
he<font>
此處,<font>
表示:
<fontdef token>
是由 font
定義的控制序列,或是預定義的
。至於
ullfont<family member>
的概念,則只與數學模式有關。
此外,外部字體文件名可用以下方式取得:
fontname<font>
該命令以字元串的形式(其中的字元記號分類碼均為 12,而空格記號的分類碼為 10)給出當前字體的文件名;若有相應的 <at clause>
則也一併給出。
例如,在如下聲明之後,
font enroman=cmr10 enroman
hefont
和 he enroman
會給出 enroman
;fontname enroman
則給出 cmr10
。
ullfont
TeX 將沒有任何字元的字體與定義為
。如果沒有指定任何字體,或是在數學模式中某一所需的字族成員未定義,則 TeX 會從空字體中取用字元。該控制序列屬於
ullfont<fontdef token>
:它與其它字體選擇命令的行為類似;但不與任何外部 tfm
文件相關聯。
字體信息
TeX 執行時所需的主要字體信息包括尺寸與字元。TeX 會在字體尺寸文件中尋找這些信息,這些文件的擴展名通常是 .tfm
。此類文件包含
- 全局信息:主要是
fontdiem
參數,還有其他一些信息 - 字元的尺寸以及傾斜校正(italic corrections)
- 字元的連字(ligature)及擠壓(kerning)指令
字體的設計大小也由 tfm
文件指定。
字體尺寸參數
文本字體至少得有 7 個 fontdimen
參數來描述字體尺寸(對於未指定的參數,TeX 會以零作為默認值);數學符號以及數學擴展字體還有更多的參數。文本字體的 7 個參數描述如下:
- 每點傾斜(slant per point);該參數用於確定重音符號正確的水平位置。
- 詞間空距(interword space):如果用戶沒有顯式設定
spaceskip
,則該參數會被當做詞間空距的默認值。 - 詞間拉伸(interword stretch):該參數是詞間距離的拉伸值部分。
- 詞間收縮(interword shrink):該參數是詞間距離的收縮值部分。
- x-高度(x-height):該參數是 TeX 內部單位(
<internal unit>
)ex
的值,通常是小寫字母「x」的高度。 - 方塊鉛空寬度(quad width):該參數是 TeX 內部單位
em
的值,它大約是大寫字母「M」的寬度。 - 額外空距(extra space):如果用戶沒有顯式設定
xspaceskip
,則該參數是在句子末尾處加在詞間空距之上的額外空距(當spacefactor
?2000?2000)。
譯註:英文單詞「quad」是傳統鉛印術中的術語,它來自義大利語單詞「quadratone」,意思是「大方塊」。
第 1 個和第 5 個參數純粹是字體的信息,因此改變它們沒什麼意義。其餘參數則可以用來調整相關空距;後續章節有關於第 2, 3, 4, 7 個參數的相關示例。
字體尺寸參數可用字體賦值語句(<font assignment>
)來修改,這種賦值語句屬於全局賦值語句(<global assignment>
):
fontdimen<number><font><equals><dimen>
<font>
的定義可見上文。
字元擠壓
通常,每個字元的邊界盒子(bounding box)彼此鄰接。但對於部分字元組合來說,它們之間的距離應該比邊界盒子鄰接的情況更近一些。這種情況稱為字元擠壓(kerning)。對於字體來說,字元擠壓的設計與字元形狀的設計同等重要。
舉個例子:
在 TeX 中,字元擠壓由 tfm
文件中的字體信息控制,因此不受用戶的影響。不過,tfm
文件是可以修改的。
kern
命令與字元擠壓現象沒什麼關係;它將在後續章節中介紹。
傾斜校正
TeX 原語 /
會向前一個字元或連字後面插入傾斜校正(italic correction)。考慮到邊界盒子(bounding box)的定義,這種修正是很有必要的:邊界盒子總是有豎直的邊,並且 TeX 將兩條豎直邊之間的距離當做是字元的寬度。然而,為了在斜體或義大利體中得到恰當的空距,字元會顯著突出其邊界盒子。當這種向外突出的字元後邊緊跟著一個非傾斜的字元時,就需要插入傾斜校正。
對比以下兩例:
這裡,有傾斜校正的版本的代碼如下。
{italic TeX/} has
各個字元傾斜校正的具體值由字體尺寸文件中的字體信息決定;對於 Computer Modern 字體來說,該值大約是字元向外突出邊界盒子距離的一半。傾斜校正與每點傾斜(fontdimen1
)是不一樣的;後者僅用於放置重音符號。
傾斜校正僅在 TeX 剛處理完一個字元或者連字時才會插入其後。因此,由於在下例中,在遇到傾斜校正原語之前 TeX 剛處理完行間膠水(而不是字元或者連字),下面對羅馬字族文本做的傾斜校正是不會生效的。
{italic Some text {/
oman not} emphasized}
連字
將字元序列替換為連字(ligatures)的過程是由字體 tfm
文件中的信息控制的。連字由字元(<character>
)命令組成:在某些字體里,諸如 fi
的字元序列會替換為「fi」。
傳統上,還有其它的連字,比如 ff
, ffi
, fl
以及 ffl
;在更古老的字體里,可能還有 ft
以及 st
,以及類似 fl
的連字:fk
和 fb
。
在 TeX 中,連字可由顯式字元記號、char
命令以及 <chardef token>
組成。例如,如果字體里有這樣的連字定義,charfchari
會被替換成連字「fi」。
我們有多種方式來限制不希望出現的連字。例如 halflife 中不希望出現的連字可以這樣避免:
half{}life, half{l}ife, half/life, 以及 halfhbox{}life
注意,使用傾斜校正原語避免不希望出現的連字的方案與其它方案的機理不完全一樣。
邊界連字(Boundary ligatures)
在 TeX3 中還有單詞邊界的概念:每個單詞都由左右兩個邊界字元界定。這樣的設定使 TeX 能夠實現一些語言中特殊的現象,例如在希臘語中位於詞尾的西格瑪(σσ)和位於其他位置的西格瑪是不一樣的。在單詞的前後添加
命令,可以抑制相應的邊界連字機制。
oboundary
譯註:這裡指的是通過邊界連字來實現一些語言中特殊的現象。
大致上,TeX 3 的連字機制比 TeX 2 要複雜得多。
推薦閱讀:
※【乾貨】最全免費可商用字體大集合(附字體包)
※【字體資訊】今天小米給一款字體辦了發布會,然而它的觀眾並不太關心
※iOS/OSX中文界面字體,思源黑體是比冬青黑體更好的選擇嗎?
※設計師必用:11款免費商用字體打包下載,快來下!
※sketch插件-FontRapid