背景

LiYanrui posted @ Jun 19, 2009 08:03:39 PM in Dream of TeX with tags ConTeXt luatex tex , 5540 阅读

TeX 相关软件中文字体嵌入一个存在已久的问题水落石出,兼谈不拘小节的中文字体设计中 Wang Yue 谈到了这样的问题:

中文字体设计不拘小节也让我也想到了另一个问题,用先前,中文用户使用 XeTeX,需要频繁地切换中英文字体,后来 XeTeX 开发者不得不提供了一个机制来让字体切换变得不那么折腾。而我和 ConTeXt 开发者交流中文排版问题,还要煞费苦心地讲怎么切换,需要编程实现复杂的虚拟字体机制来实现。这个都归罪于中文字体普遍地缺乏高质量的英文部分,仔细看看 simsun 或者 simhei 的英文部分,就可以看出有多么夸张了。

如果说这个问题的原因是中国的字体公司,向来没有很好的英文字体设计基础,同时对这个问题也不加以重视,那么中文标点的设计,就没有丝毫的可以开罪的地方了,这个问题直接导致用户和开发者都非常为难。我们知道,高质量的中文排版,标点并不是占据一个中文字符的位置,而要比中文字符略小。 同时,标点之间需要存在压缩,比如逗号后紧紧跟随的关门引号,需要使用类似 kerning 的特性把两个 glyph 的距离减小。另外,类似破折号和省略号, 其实应该放在一个 glyph 中而不应该分开。而现在所有的中文字体的糟糕程度,竟然到所有的标点符号都占用一个中文字符距离的程度。本来这个问题如果中文 字体设计得当,使用默认的排版算法,就基本上能够解决一般的中文的排版问题,而现在糟糕的设计就使得排版软件的设计难上加难。首先我们需要重新定义一系列 的新算法和新规则,然后需要手工赋值去确定标点的大小和两个标点连在一起时候的压缩程度。更麻烦的是,不同字体中的相同的 glyph,比如逗号或者句号, 往往会在这个 box 的不同的位置,大小也会千差万别。调好了中易宋体的冒号和开门引号,把相同的数值使用到中易的隶书中,顿时两个符号就会挤在一起,这就 使得如果不针对每一个字体仔细调整,高质量的中文排版就几乎不可能。

我是受了 Wang Yue 几篇文章忽悠才开始使用 ConTeXt MkIV(下面简称 MkIV)的,迄今为止一年又半载。期间,看见了 MkIV 的效率以及 CJK 文字支持的诸多进步。比如,现在利用 MkIV 的 fallback 字体机制,已经很好地解决了中西文字体混合的问题,也就是说用设计比较专业的英文字体去替换中文字体所包含的英文字符部分。此外 Wolfgang Schuster 实现了 simplefonts 模块,提供了类似 XeLaTeX 的 fontspec 宏包那样的功能,简化了 ConTeXt 字体配置过程。但是,对于中文标点符号的处理,迄今也未有解决。虽然 Hans 多次许诺将来会解决这个问题,但是我们不知道他说的将来是什么时候了。

为了让 ConTeXt 对中文支持的更好一些,我想自己动手解决这个问题。假如将来 Hans 真的兑现了他所说的,提供了很好的中文支持,大不了我就扔掉这块工作。

一开始,我不知道该从哪里入手,在 ConTeXt 的 base 目录里 grep 了好长时间,发现有关中文断行以及标点处理的代码集中在 font-otf.lua 文件里,当时我对这个文件进行了一些 hack,只得到到了轻微的改善,不过我却受到了鼓舞,打消了对 ConTeXt 的畏惧。后来 Hans 对 CJK 文字的处理进行了调整,原先在 font-otf.lua 文件里的 CJK 文字处理部分的代码被重新改写了,并且放在了 scrp-ini.lua 和 scrp-cjk.lua 文件中,我对这两个文件继续 hack,工作成果见 http://bbs.ctex.org/viewthread.php?tid=48562。在此期间,把学习 MkIV 过程中胡乱写的一些笔记整理了一下,挂在了 http://bbs.ctex.org/viewthread.php?tid=45237。我不是一个有耐心的人,做什么事情都是三分钟热度,再加上 MkIV 层出不穷的 bug,所以有一段时间对 MkIV 的喜欢的热度也退却了很多。

在 hack MkIV 的时候,我感觉 MkIV 对中文标点的处理方式很脏,太依赖具体的字体。像 scrp-cjk.lua 文件中的许多参数,对 AdobeSongStd-Light.otf 字体是适合的,但是换成 simsun.ttc 就不行了,具体见 http://bbs.ctex.org/viewthread.php?tid=47559。仅仅是因为这个看似很小的问题,我还几次都想回到 XeTeX + xeCJK 的环境里。如果 OpenOffice.org 在排版方面不是那么废柴,我甚至都可以放弃 TeX。

再后来,看到 Wang Yue 频率较高的宣扬利用 bbox 来解决中文标点间距压缩问题,说这样就可以做到不依赖具体的字体。一开始,我对此是不以为然的,而且我也没法以之为然,因为那时我只是比较浅薄地知道 scrp-cjk.lua,其它的我都不知道。直到后来,孙文昌(CTeX 论坛的 mytex)老师给出了一个示例(见 http://bbs.ctex.org/viewthread.php?tid=49757)之时,我才大致明白所谓 bbox 的解决方式是怎么一回事。另外,Wang Yue 精简 ConTeXt Minimals,作了一个 mini luatex 包,我从他那里学会了如何生成 luatex 格式文件,如何在 tex 文件里加载自己写的 lua 程序。

我对 LuaTeX 和 MkIV 的认识就是这样私有似无地累积起来了,直到有一天我感觉可以从 LuaTeX 的层面上来实现对中文的单独处理,这样我就可以摆脱 Hans 的那套目前有些残废的中文支持方式,不必再担心他每一次升级 beta 版本而让我没法再用中文。虽然事实上还是有隐患,因为 Hans 为 LuaTeX 分离出来的字体处理部分,也就是 luatex-fonts-merged.lua 文件,它也是不稳定的,但是至少要比 MkIV 稳定。这段时间,我一直在折腾这件事情,随着最后一个有关标点边界对齐问题得到了解决,现在整套方案终于有了一个大概的眉目。

现在,打算正式开始解决这个问题。在此过程中,我会再重新整理一下思路,以连载的形式记录整个过程,希望能够对喜欢 LuaTeX与 MkIV 的同学有所帮助。

Yue Wang 说:
2009年6月20日 19:20

赞连载。
我现在精力没那么旺盛了,连载不动了@@


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter