“TeX fonts are mess…”Ulrik Vieth 和 Taco Hoekwater 在 Euro TeX’99 的 presentation 中如是说。看到这行话的时候,Thunderbird 告诉我从 context 邮件列表发来了新邮件,正好是 Taco 回复我的一封,此时我正被郁闷的 afm2tfm 抓狂着。
或许生而迟钝,大概花了三四天的时间,我才把 TeX 字体的基本原理理清一个思路,原因很简单,没有哪篇文档愿意从头到尾说清楚,它们都只愿意把一小部分的内容说出来,而我的感觉正如刚刚打开了四十二章经的封皮,所不同之处只在于我不打算去找满清龙脉,只希望把 TeX 的字体从安装、到使用,直到最后生成一份可打印的文档这整个过程了解清楚。
当然下面要说的也只是一个简化以后的细节,我这里一不涉及中文的使用,二不涉及 PDF,三不涉及 plain TeX 和 LaTeX 以外的格式。但只要我涉及的部分,就尽量不删减任何过程。
下面的叙述中,我尽量给出一些可以实践的例子,当你发现某处你很希望实践,而我又没有给出例子,那你可以肯定一点:此文的作者确实是不懂这个。
### 字体是怎么来的
字体是怎么来的?一般而言,TeX 的字体是用 MetaFont 设计出来的,用 MetaFont 的语言描写曲线和点划,这些描述保存在 .mf 文件中,通过 MetaFont 生成 GF 格式,GF 即 Generic Font 的缩写。尔后你通过一个叫做 gftopk 的工具,生成一种叫做 PK 的格式 (packed font),这种 PK 字体是基于 MetaFont 的传统设计方式最终嵌入文档的字体。
为什么要先生成 gf 再转换成 pk?其实这两种格式都是位图 (bitmap) 格式而非矢量格式,也就是说没有优劣的区别,如果你非要问为什么,我也只能说是历史原因。
但这只是字形 (glyph) 文件,也就是单个的字符长得什么样子,那几个字符放在一起,它们的间距如何调整,而众所周知拉丁字母有个基线 (baseline),字符的基线若不对齐当然是很难看的,我们又在哪里指定这个基线呢?在字距 (metric) 文件中。
TeX 使用的字距文件,有两种格式,一种是二进制的,叫做 TFM (TeX font metric) 文件,另一种是我们可读的,叫做 PL (Property List ) 文件。两者之间可以通过 tftopl 和 pltotf 相互转换。系统地说,metric 文件描述的是每个字符的宽、高、深和斜体修正 (不明白什么是斜体修正?看 The TeXBook 第四章去),以及两个字符之间的间距调整 (kerning) 和连字 (ligature) (这两个概念先前我在 blog 上都提到过,请自行搜索)。
好,下面让我们来实践一下 (以 MikTeX 为例,其他发行版请自行调整):
$ kpsewhich ptmr8r.tfm (先找个 tfm 文件出来)
C:/CTeX/texmf/fonts/tfm/adobe/times/ptmr8r.tfm
$ tftopl C:/CTeX/texmf/fonts/tfm/adobe/times/ptmr8r.tfm ptmr8r.pl
…. (一堆输出信息,注意,编号是八进制的)
$ dir
….
2005-08-30 02:54 61,002 ptmr8r.pl
$ vim ptmr8r.pl (让我们找个文本编辑器打开这个文件)
…
(CHARACTER O 275
(CHARWD R 0.75)
(CHARHT R 0.677991)
(CHARDP R 0.007001)
)
上边就是一个编码 (我们以后再谈编码的问题) 为 275 (八进制) 的字符的宽度、高度和深度了。
事实上 TeX 排版中是不需要用到字形 (glyph) 文件的,也就是说,TeX 不需要知道这个字符的轮廓是什么样的,只需要知道给它留多大的空间就行了,所以你用 TeX 生成的 DVI 文件里只包含了 TFM 文件的信息,至于你预览 DVI 时看到的,其实是 DVI 阅读器提供的功能,它能够根据 TFM 的信息找到应该使用的 PK 文件,将它们载入。还是让我们实验一下,做个最简单的 TeX 文件 (下边 `$` 和 `*` 开头的都是用户的输入,括号内的不用输入):
$ tex (打开 tex 控制台)
This is TeX, Version 3.141592 (MiKTeX 2.4)
**\relax (先放松一下)
*\font\myfont=cmr10 at 12pt (定义一个字体)
*\myfont Hello, World! (用这个字体输入一段文本)
*\end (完成)
[1]
Output written on texput.dvi (1 page, 272 bytes).
Transcript written on texput.log.
搞定,让我们看看输出的文件:
$ yap texput.dvi
如果你有兴趣,还可以看看 YAP 的菜单中 `File->Document Properties` 提供的信息,里面描述了如何从一个 TFM 的名称映射到一个 PK 文件的。
OK,这就是 TeX 使用字体的传统过程,没有 PostScript,没有 PDF,没有 Adobe,有的只是 good old days 的老工具。谢谢大家的支持,今天我们就讲到这里,请关注我们下次的连载。