说说 TeX 的字体 (1)

“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 的老工具。谢谢大家的支持,今天我们就讲到这里,请关注我们下次的连载。

ConTeXt 配置小记

刚刚更新了 MikTeX 中的 ConTeXt,版本是 2005-07-12,发现了一些问题。

首先是 fmt 文件无法生成了,似乎是 ConTeXt 需求的容量超过了 TeX 原本配置可以提供的。解决方法是修改 `localtexmf/miktex/config/miktex.ini` 文件,把
`trie_op_size=2048` 增大一些,比如 `trie_op_size=4096` 即可。

然后用 `texexec –make en` 重新生成 fmt 文件。

然后是用 `texfont` 安装字体的问题。原本 `afm2tfm` 编译时应该加入了 Kpathsea 库支持的,也就是能够自动找到 texmf 下的文件,但 MikTeX 下现在这个 `afm2tfm` 并没有加入 Kpathsea 库,一旦使用 `-p` 参数就会崩溃。

幸好 `texfont` 不需要真的使用 `afm2tfm` 生成的文件,它只需要从 `afm2tfm` 的输出内容中截取一个字体的名称就可以了,所以可以对 `texmf/scripts/context/perl/texfont.pl` 作如下修改:

my $command = “afm2tfm “$file” texfont.tfm”;
print “$command\n” if $trace;
$font = `$command`;
UnLink “texfont.tfm”;
# ($rawfont,$cleanfont,$restfont) = split(/\s/,$font)
($rawfont,$cleanfont) = split(/\s/,$font)

(注释掉的内容为原来的代码,可以依此找到应该修改的位置)

`texfont` 的另一个问题是不能自动刷新文件名数据库,原因是 `mktexlsr` 给加上了目录参数,而 MikTeX 下的 `mktexlsr` 其实是 `initexmf` 的一个别名,不支持目录参数的。可以简单的去掉 `texfont.pl` 中 `mktexlsr` 出现后的参数,也可以不管,安装字体后手动刷新文件名数据库。

另外,texfont 其实是一个很方便的工具,就算不用 ConTeXt,用这个工具来安装 Type 1 和 Open Type 字体也比 fontinst 方便得多,就是目前用得人不多,遇到问题的时候需要自己调整一下。

Microsoft New Fonts

Microsoft 将在 2006 年随新的操作系统及其他的桌面软件一起提供六套新的字体,被称为 ClearType Font Collection 的这六个字体:Calibri, Cambria, Candara, Consolas, Constantia 和 Corbel 尽管在今年三月的 The Next Big Thing in Online Type 已为人所知,但直到最近 Vista Beta 1 的发布我们才能够真正试用这六套字体。

这六套字体的版权中都标着 Microsoft Corporation,说明是 Microsoft 自己开发的,而非购买自其他的公司,其中 Constantia 和 Corbel 是 2003 年做的,其他的都是 2004 年的。

这六套字体全部以 TrueType 格式提供,但实际上采用的是 OpenType 的技术 (关于 Type1, TrueType 和 OpenType 的关系,详见此文),属于 TrueType Open Font,我没有装 Vista,所以无从得知“优化的”Clear Type 是什么意思,但新的 TrueType 字体对 Web 和其他工作的帮助是显见的,Web 上增加可以使用的新的字体,程序开发可以使用新的等宽字体 (比如 gVim, 原本不支持 Type1 字体)……


和微软往常的习惯一样,这些字体每个 Family 也只提供了 Regular, Bold, Italic, Bold Italic 四种 Style,没有提供 Small Caps 或者 Text Figure。其中 Cambria 没有提供连字 (ligature),Consolas 是等宽字体,当然不能有连字,其他的四套字体都提供了连字。

我制作了一份简单的文档,选取其中部分字体和几套其他的字体比较。

FrameMaker Tips

FrameMaker 是 TeX 以外我最喜欢的排版软件了,虽然界面有点寒碜,但简单直接,不像 InDesign 那么麻烦 (况且 InDesign CS2 实在是太慢了…),中文支持也不错,除了 OpenType 的支持有点限制,实在是很方便的。这里写点我使用中记下来的小技巧。

1. FrameMaker 7.0 以上才有比较好的中文支持,所以建议使用 7.0 或者 7.1 版本。不需要是多语言的版本。
2. 中文字体和英文字体一般是不能混合选择的,如果你希望一段话中,汉字使用黑体,英文使用 Myriad,就得自己创建 combined font,FrameMaker 默认已经创建了两个,FMSongti 和 FMHeiti,在菜单中选择 Format->Document->Combined Fonts…,就可以 Add 自由选择 Asian Font 和 Western Font 的字体了,此后在 Paragraph Designer 的 Default Font 中选择你新建的这个字体即可。
3. 默认的配置是,只有某些特殊的情况下才压缩汉字的标点符号,例如句号和引号的距离,但可以在 Paragraph Designer 的 Asian->Asian Punctuation 中选择 Always Squeeze 解决这个问题。
4. 必须先创建一个颜色,然后才能使用它,你可以在 View->Color->Definitions 里选择,当然,你可以自己设置 RGB 值,不过最简单的是在 Color Libraries 中选择。此外,基于某个已有的颜色创建 Print As: Tint 类型的颜色也是很方便的,你可以调整百分比,创建采用相同基色,但更淡的颜色。

Web 与排版学上的字体问题

关于字体的讨论,其实无论是国外还是国内,都已经有不少,可是我发现绝大部分的内容或者有失偏颇,或者不够全面,下面我试图将自己一段时间内的观点总结一下,以求提出一个比较容易接受的 CSS 字体选择的建议。

## 事关大小

字体的大小总是一个困扰人的问题,用绝对单位还是用相对单位?或者具体来说,用什么单位?ex? em? pt? px? 百分比? 让我们看看 CSS 2.1 Spec 中的说明:

1. 相对大小包括:em, ex, px
2. 绝对大小包括:in, cm, mm, pt, pc
3. em 就是相对 `font-size` 制定的大小而言的,例如 `margin: 1.2em` 就是指设置 1.2 个字符宽度的 margin,当 em 本身用于 `font-size` 时,指的是它所继承元素的相对大小。
4. 百分比也是相对 `font-size` 而言的。

因此我认为,em 和百分比都不适合设置字体的大小,因为相互变动的因素太多了,修改一个地方就有可能影响很多其他的地方。ex 是根据拉丁字母的 x 的高度而言的,这不适合汉字的大小,所以也否决了。px 是根据当前显示设备的解析度而言的,同一个 px 对应不同的设备——比如屏幕或纸张——实际的大小会有一定差异。

所以我认为,如果网页中应该存在作为绝对参照系的长度,那么 pt 和 px 应该是首选,其他的长度根据这个绝对参照系,按照百分比或者 em 来变动。

下面谈谈网页和印刷中大小造成的差异。99% 的网页是用来在屏幕上阅读的,而问题在于,屏幕的解析度要比纸张低得多,所以如果直接把字体按照纸张上印刷的那个大小显示,肯定是看不清的,仅就英文字体而言,许多细微的点划、衬线都没法在那么低的解析度下表现出来,所以我们只能用专门设计给屏幕显示的字体。

这些字体的优劣是很难评述的,有一种看法认为,尽管纸张印刷中都倾向于有衬线 (serif) 的字体比无衬线 (sans-serif) 的要易读,但屏幕上无衬线的字体反而要好一些。所以微软把 Verdana 吹捧为了最适合网页使用的字体。我通常也偏向于使用 Verdana、Arial 多于 Times、Georgia。

对于中文字体的情况有所不同,中文字体在屏幕上的清晰显示依赖的是点阵字体,或者简单的说,就是微软随 Windows 提供的宋体和新宋体 (simsun & nsimsun),这套字体是华康公司 (Dynalab) 设计的,对 9pt 到 12pt 左右的字体都设计了对应的点阵字体。其中使用得最广泛的是 9pt, 10.5pt 和 12pt 的字体:

常用的中文字体

那么比这个大小要大的汉字呢?就要依赖操作系统的字体圆整 (anti-alias,以下简称 aa) 技术了,一般大家认为,Mac OS X 和 Linux 下的 AA 要比 Windows 的 ClearType 好很多。然而不管怎么说,用太大的汉字是比较危险的。
Continue reading “Web 与排版学上的字体问题”