XeTeX 的一个中文处理脚本

其实这个东西早就该写了,只不过我既是一个懒人,也是一个看不惯不完美东西的人,所以一直不好意思去写。

For the impatient: [脚本在这里](http://www.newsmth.net/att.php?s.460.239183.807.py)

[XeTeX](http://scripts.sil.org/xetex) 是 Johnathan Kew 一开始在 Mac OS X 上开发的一套 TeX 系统的扩展,主要的特点是使用 ATSUI 支持了操作系统 native 的字体,而后使用 ICU 加入了对 complex scripts 等多语言排版的直接支持,算是 TeX 世界中很振奋人心的更新,我也一直在关注着,因为没有 Mac 用,所以不大了解详情。

直到最近 Johnathan 公布了 Linux 系统下的 XeTeX,结合 fontconfig 和 freetype、ICU 一起支持了 Linux 系统下的 native fonts 和多语言排版,并在 Jin Wan Cho (dvipdfmx 的作者之一) 的帮助下扩展了 dvipdfmx,支持 xetex 的“.xdv”输出。所以近期在我的 Arch Linux 上,好好把玩了一阵子 XeTeX (中间的经历,在 [newsmth](http://www.newsmth.net/) 的 [TeX](http://www.newsmth.net/bbsdoc.php?board=TeX) 版和朋友们提过),虽然发现有诸多不便,但仍然觉得这是一个很值得发展的东西。

最大的不便在于 mixed scripts typesetting,即所谓多种语言混杂的排版,因为目前 XeTeX (其实 TeX 也是,只不过无论 [CJK](http://cjk.ffii.org/) 还是 [CCT](ftp://ftp.cc.ac.cn/pub/cct/) 都用一种比较特别的方法绕过了这个问题,此处按下不表) 无论是哪一段文字,都只有唯一的一种字体,你无法给它指定一个复合字体 (combined font),而复合字体的概念在 DTP 软件中是很常见的 (比如 FrameMaker, InDesign, Scribus 都支持),这就造成了混杂排版的困难:每当语言变化了,就必须手动切换字体,比如用 XeLaTeX,通常使用的是 Will Robertson 写的 fontspec 来选择字体,设置正文的字体用:

\setromanfont[字体特性]{字体名称}

上面这里推荐使用汉字的字体,才能比较好的处理中文的断行 (考虑标点符号的避头尾)。

\XeTeXlinebreaklocale=”zh”
\XeTeXlinebreakskip=0pt plus 1pt

然后定义一个英文字体,比如:

\newfontinstance\rmfont{Garamond Premr Pro}
\newcommand{\nc}[1]{{\rmfont #1}}

这样在文档中写的时候是:

中文啦啦啦 \nc{blahblahblah} 中文啦啦啦 \nc{blahblahblah}

一行字还不觉得,英文多了就会很麻烦。目前在 XeTeX 的 mail list 上,已经多次有人 (包括我 ^^|) 提到了这个问题,其实反复思考,这真的不是一个很容易处理的问题,尤其是不仅仅考虑中文和英文两种语言,而是数十种相互字符集范围有交叠的语言时,设计就更费斟酌了,Johnathan 表示他在关注这个问题,但还没有到集中力量解决它的时候,所以我才在这里贴这么一个很 dirty 的 script,其实发现这个问题以后,我反复想了几天,即分析了 XeTeX 的源代码,也去信和 CCT 的作者张林波老师讨论了,最后才决定采用预处理这个方法,觉得这是目前最不伤筋动骨,又能迅速解决问题的方法。

这个脚本就是用来处理中英文混杂的排版,在英文前后自动插入 \nc{} 用于切换字体,你可以在 preamble 定义 \nc 代表的字体。处理时,最 tricky 的部分是中文的标点,其实这一部分在 Unicode 中的代码分布是 [Fullwidth Latin Characters](http://www.unicode.org/charts/PDF/UFF00.pdf) 部分,根本不属于汉字部分。

这是用 Python 写的一个很简单的小工具,从 `\begin{document}` 开始处理,到 `\end{document}` 结束,目前还*不支持*任何命令,所以在正文部分如果有 `\title{中文标题}` 这样的东西,别指望它能正确处理。

此外还有一个功能是在两行连续的中文之间插入 % 以保证源文件中的手动换行不会导致输出结果中出现空白。

这还是一个非常非常 experimental 的东西。欢迎测试,我希望有时间认真写一个 tokenizer 作这个处理,现在的处理是基本上不依赖上下文的,所以能力很弱。另外,还可能在以后加上标点符号的 kerning 处理,类似 CJKpunct 的功能。

当然,我很希望有更多中文的 XeTeX 爱好者和我一同来完成这个工作,:)

FreeType 2.2.1 的一点测试

最近 [FreeType 2.2.1](http://download.savannah.gnu.org/releases/freetype/)
刚刚发布,尽管由于 API 的变化 (许多内部函数被隐藏起来了),多数的 distro
并未把系统使用的 FreeType 升级到这一版本——我相信要过很长一段时间才有可能这
么做。但使用源代码编译的版本,我做了一点小小的对比分析。

因为精力有限,只对 FreeType 2.1.10 (目前绝大多数发行版正在使用的版本)
进行了比较,试图给出基于 FreeType 的程序 (如 fontconfig) 应当如何配置字体
才能获得最好的效果的一点建议。而事实上,font rasterizer (字体光栅化工具)
必须和其他的 rasterizer 比较才能看出明显的区别来,例如 ATSUI, Win32 GDI
等等。

同时,我也只对随 Windows 附的 simsun.ttc 做了测试。如果你有兴趣,欢迎分享
更多的测试结果。

测试的截图在 [flickr](http://www.flickr.com/photos/jjgod/tags/freetype/) 上。

经过比较,我们可以给出这样一些建议:

1. 必须打开 anti-alias,gamma 才会起作用。
2. gamma = 0.0 时启用 sRGB (次像素反锯齿) 模式,这种模式要比默认的
gamma = 1.0 显示得更清晰锐利一些。
3. 绝大多数情况下,打开 hinting 能达到更好的效果。
4. 小于 12px 的情况下,关闭 anti-alias,打开 hinting 能使字体勉强可读,
但仍然建议绝对不要使用这么小的字体。
5. 12px 以上,即 12-16px, 18px 的汉字必须使用嵌入的 bitmap。事实上,AA +
hinting 的汉字要到 28px 以上才可以称为比较可读。

Why Cairo?

因为想写一个 lightweight & fast 的文本布局引擎,这两天在留意一些新的图形 API。其实有些都不算很新了,像 [Anti-Grain Geometry](http://www.antigrain.com/)、[Amanith](http://www.amanith.org) 和 [Xara](http://www.xaraxtreme.org/)。

曾被誉为“Linux 图形未来希望”的 [cairo](http://www.cairographics.org) 广受诟病的是它的效率,尽管从一开始 cairo 便宣称将会利用 glitz 这样的 backend 实现硬件加速的矢量图形绘制,从而达到软件绘制无法达到的效果。结果现在戏剧性的是,cairo 比所有这些用软件绘制的引擎都慢得多

所以才有人写了这么一篇 [Why Cairo?](http://weblogs.mozillazine.org/tor/archives/2006/04/why_cairo.html),意思大概说得很清楚了,Mozilla 选用 cairo 的借口现在看来是非常苍白无力的,比如说 cairo 引以为傲的“bring vector graphics to print”有多少人需要把网页输出到 PDF/PS?如果最基本的页面渲染都做不到高效,谈何页面印刷的高效?

所以我觉得啊,rendering model 好当然不错,cross-platform 性能好也很好,但 cairo 是不是中 gnome 社群的毒太深了?什么东西都来搞个 backend,结果最后每个 backend 都半死不活的,没错,也许某天 David Reveman 搞定了 xgl 腾出手来整 glitz 了,可 David Reveman 就算搞定了 glitz,也未必能在 win32 下用啊。

… 今天测试的结果是,pango 用 cairo 作 backend,cairo 用 win32 backend,结果渲染一行字 (4 个字母),要半秒钟。嗯,没看错,就是 0.5s。

效率还是很重要的呀,虽然某位大人物说过:

预优化是万恶之源。

Layout Engine 的文档

真的是.. a mess,估计就像 pango maillist 上有的人说的,有能力使用 layout engine 的人都能够直接看 reference 写程序,没能力的都去用 GUI Toolkit 提供的 high-level API 了。

最近看的几个 layout engine 包括:[Uniscribe](http://www.microsoft.com/typography/developers/uniscribe/), [Graphite](http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&cat_id=RenderingGraphite), [Pango](http://www.pango.org) 和 [ICU](http://icu.sourceforge.net/userguide/layoutEngine.html)。最惨的是它们的定位和功能还不一样,有些相互之间还有牵扯。

就是这样居然还有人能把 Graphite, ICU 和 ATSUI 集成起来[给 TeX 用](http://scripts.sil.org/xetex),考虑到 TeX 还是用 WEB (Pascal 的 literate programming 版本) 语言写成的,这真是让人崇拜得五体投地的[强者](http://www.unicode.org/iuc/iuc22/b051.html)啊。

(看了一下强者的 biography,原来自从我出生开始就在 SIL 工作了.. 那么这样我比较不自卑一点。)

更新:看完这篇 [mail](http://mail.gnome.org/archives/gtk-i18n-list/2004-December/msg00010.html),我又很高兴了 🙂

Segoe UI 之争

Segoe UI

Microsoft 在 (或者将在) Windows Media Center Edition, Windows Vista 和 Office 2007 中替代 Tahoma 作为界面和菜单的默认字体的就是现在看到的这个 Segoe UI。毫无疑问,它可以和 Tahoma 区分得很清楚,取代 Tahoma 的尖刻的圆角和 Trebuche MS 有几分相似——wikipedia 上是[这么](http://en.wikipedia.org/wiki/Segoe_UI)说的。

然而 [Linotype](http://www.linotype.com) 公司声称它与 Linotype 的 FrutigerNext 是一模一样的。看下面的对比,真的是几乎一模一样啊 (黑色的是 60pt 的 FruitigerNext,灰色的是 56pt 的 Segoe UI):

FrutigerNext and Segoe UI comparison

Wikipedia 上还提到,Microsoft 在 2004 年尝试在欧盟将 Segoe 和 Segoe Italic 注册为原创性字体设计,Linotype 提出了抗议,在 2006 年二月,欧盟拒绝了 Microsoft 的注册请求。Microsoft 承认 Segoe 和 Frutiger 是一样的,但却声称 Linotype 在 2004 年以前没卖过 Frutiger 和 FrutigerNext (这个理由真 faint),这个说法还是被欧盟拒绝了。

那么现在究竟 Microsoft 会不会撤掉他们[预先说好](http://blogs.msdn.com/jensenh/archive/2005/11/16/493388.aspx)要在 Vista 和 Office 2007 中出现的这个字体呢?或者 Microsoft 与 Linotype 达成和解,同意给每份 Vista 的 copy 支付一个美分的授权费用?(先前 Microsoft 是在 Reader 软件中为 Frutiger Linotype 这个字体支付的授权费用。)

Frutiger Linotype and FrutigerNext

在网页上的比较可能会比较符合 Microsoft 的心思,不过我的测试是发现 Frutiger Linotype 和 Segoe UI 的效果差不多 (难道 Vista 上 ClearType 的改进又会带来变数?),但 Frutiger Linotype 的 descenders 明显一点,Segoe UI 的 ascenders 明显一点,相比起来 Segoe UI 不那么“扁”,看起来会更顺眼。

Frutiger Linotype in Firefox

Segoe UI in Firefox

引用一份 FrutigerNext 的小册子上说的:

1970 年初,当巴黎计划建设 Roissy Charles de Gaulle 机场时,他们发现机场的信号标识需要一个清晰可辨的字体。导航系统的设计落到了 Adrian Frutiger 的头上,结果是……太成功了,不仅导航系统需要这个新的字体,许多常规的书籍印刷同样需要。1977 年,这个字体以 Frutiger 的名字命名,进入了 Linotype Library。它不仅为机场信号,更为所有希望在字号较小时达到清晰可辨的字体设立了一个标准。

……创造出一个既有吸引力又富动感的字体。经过加强的 ascenders 和 descenders 更显可读性,小写字母和数字在一行上排布得很整齐。Linotype Frutiger NEXT 在 Frutiger 的基础上,使笔画与宽度更为协调,各种粗细的版本放在一起显得更为融洽而不突兀。

从传统的字体设计角度上来说,Segoe UI 当然和 Frutiger/Next 脱不了干系,可是如果从纯技术角度上来说,我们不妨反思这样一个问题:字体的版权应当如何保护,类似 Microsoft 这样,为 ClearType 所优化的 hinting 算不算版权中的一部分呢?