搭建论坛交流论坛读者文摘 → [转帖]IT中文环境的血泪史


  共有4175人关注过本帖树形打印

主题:[转帖]IT中文环境的血泪史

帅哥哟,离线,有人找我吗?
海天一色
  1楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:技师 帖子:400 积分:1109 威望:1 精华:11 注册:2004-7-26 9:23:56
[转帖]IT中文环境的血泪史  发帖心情 Post By:2007-7-13 9:41:41

操作系统、编程语言、应用乱码

Linux一开始不支持双位语言,BeOS也不支持中文,我们必须用一些奇门遁甲的方式,辛苦地让这些OS上面显示中文。当中文显示出来的剎那,感动得都快掉泪了。
身为一个中文计算机使用者,我有过太多的无奈,这些无奈是西方人无法体会的。大多数知名的编程语言、操作系统、应用软件,都是西方人开发的,他们往往一开始的时候不会把中日韩(CJK)的语言需求当一回事。

操作系统
二十多年前,为了要让计算机具有快速的「正体」中文环境,每次开机后都必须插入中文磁盘,花一段时间安装倚天中文(或大千、零壹、天龙中文),而且都是16 或24的点阵字型(bitmap font),只要把字放大,就其丑无比。为了要加速中文的加载与显示,必须安装超贵的倚天汉卡,而早期的倚天汉卡只能使用在单色模式。当时,欧美的电 脑使用者,根本不需要这么麻烦,人家开机后就可以直接用计算机了,令我们感到羡慕。
后来Windows 3.x时代,可以方便地使用中文,但是文件名称不能使用中文,进入Windows 95之后才解除此限制,微软平台上的中文问题也渐渐变得比较少了。但其它平台还是存在这个问题,Linux一开始不支持双位语言,BeOS也不支持中 文,我们必须用一些奇门遁甲的方式,辛苦地让这些OS上面显示中文。当中文显示出来的剎那,感动得都快掉泪了。
正体中文的编码最常用的是Big-5,这是一种双字节字符集(Double-Byte Character Set,DBCS),但是不同平台的Big-5字集还不太一样。当我把在Windows平台上写好的文章交给MacOS的排版人员,最后一定要仔细校对排 版后的输出。因为两者的Big-5字集有些小差异,所以有些中文字可能会不一样。

编程语言
经过这段时间大家的努力,现在,至少主流的OS都不会有中文的问题了。但是程序环境可不见得如此,正体中文版Windows上使用CP950编 码,这是混合Big-5和ASCII的变动长度编码方式。对于这种变动长度的编码方式,如果程序环境没有特别处理,常常会发生问题。著名的「许、功、盖」 问题就是如此,这几个中文字的第二个字节都是ASCII的反斜线(\),刚好是某些程序语言的特殊字符,或者脱字序列(Escape Sequence)字符,所以会出现问题,根据这样来推估,还有相当多字都会出问题,包括「厩、琵、崤、泪、豹」。
不同的程序环境可能会有不同的特殊字符。甲语言出问题的可能是「许、功、盖」,乙语言出问题的可能是「扁、夏、抬」,所以每个语言必须用不同的方式处理特殊字符的问题。
幸好我们开始有Unicode,早期的Unicode是16位的,后来又扩充到32位。许多号称支持Unicode的平台,其实并没有 100%支持Unicode。至少在Windows上,当我测试Unicode的中文组字功能时,发现是行不通的。例如:「2FF1 4E95 86D9」无法呈现正确组合出来的1个中文字,而是3个中文字。这是因为Windows API的TextOut() 函式与DrawText() 函式(以及相关函式)没有处理中文组字。
Java虽然一开始就支持Unicode,但是前几年在AWT/Swing上显示的中文很不美观,程序设计上也会遇到一些问题。我就常常收到读 者的E-mail,询问如何在Java上解决特定的中文问题。这几年下来,这些问题似乎在Java上都已经渐渐消失了。.NET平台上的语言对于DBCS 与Unicode的支持也不错。但是Java和.NET毕竟都是跨国大公司的产品,所以有考虑到DBCS与Unicode,是很自然的。Ruby就比较特 别了,由于Ruby是日本人设计的编程语言,所以Ruby一开始就有考虑到东亚的语言。

应用软件与中文乱码
平台有支持中文,编程语言兼容于中文,但开发出来的应用程序却不见得如此,所以有的应用程序只要遇到中文,一律变成乱码,但是这样的例子已经越来越少了。
之所以会看到乱码,就是「编码」和「译码」的方式不同所造成的。比方说,用DBCS的中文编码,却用ASCII译码,把每个中文字当作两个「扩充ASCII」字符显示;或者,把简体中文GB2312编码的内容,当作正体中文Big-5译码显示,当然会看到不知所云的内容。
就算程序支持多种编码,也会因为收到的内容没有标示编码,而造成译码错误。我的Office 2003收件匣,只要收到简体中文标题的邮件,标题就会呈现乱码。没想到几个月后,我养成一种功力,我可以从邮件标题的中文乱码解读出简体中文一些常用词 汇。比方说,当我看到邮件标题为「绊珂汜斓疑」,我就知道其实这几个正体中文字编码对应到简体中文是「蔡先生你好」。我考虑把这项了不起的「阅读乱码」华加入我的履历表中。

字体文件体积
解决了中文编码,至于中文字体又是一个问题。在Windows上,一个不算美观的中文TrueType字体需要约4 MB,像「隶书」这种每个笔画「要断不断」的字体,档案就更大一些,接近10 MB,而专业印刷(而非屏幕显示)所使用的字体,由于相当细致,字体档案也就更大得多。
中文字体档案内有大量重复的信息,相当浪费。例如以「木」为左边部首的中文字,恐怕不下一百个,每个字的 glyph数据都重复描述「木」的外框, 这是相当大的浪费。我粗估,如果压缩得当,搭配自动调整笔画宽松的算法,原本13,000字的5~10MB字体文件,可以压缩到100 kB。甚至可以让算法搭配各种参数组合,只需要少数参数资料,就可以产生不同的字体。我估计,多一个字体可能只需要多10kB,而不是多100kB(因 为字的组成数据可以重复运用)。
目前,只有嵌入式系统会注意到中文字体档案的大小,而在一般PC上我们不会把这当一回事。事实上,为了保持 文件显示效果的一致,有时候我们会嵌入 字体。如果字体太大,或者使用太多字体,可能也会造成文件档案变大。大多数允许嵌入字体的档案格式(例如:PDF),都只允许嵌入文件中有真正使用到的文 字。但尽管如此,只要有嵌入字体的档案,多个几MB是免不了的。
把形音义同时纳入考虑,可以解决中文字体太大,以及输入法的一些问题。有一些单位在做这样的研究,我也有看到不错的产品,但似乎还有相当大的改进空间。
发明仓颉输入法,人称中文计算机之父的朱邦复,似乎也有做过相关的研究。只可惜他最近沈迷于「中文诗词动画」的研究,请恕我无知,我不知道以目前来说,中文诗词动画的重要性何在?
我之所以对中文字体的压缩这么执着,其实是有原因的。我在清华大学资讯工程研究所就读时,我们实验室是「视 讯通讯实验室」。对于视讯通讯来说,压 缩(compression)相当重要。每天看学长埋首在数据的压缩上,只要比别人的方法节省几个bit,就可以乐翻天,准备写论文发表。有一天,我跟教 授说:「我们每天在实验室为这些bit斤斤计较,以后进入社会,一定会成为很节俭的人。」

字体美观
如果你研究一下TrueType字体的glyph,你会发现,大多数的中文是以「笔画外框」来描述,但英文字体是以「视觉外框」来描 述。例如,英 文字体对加号(+)的外框描述是一气呵成,只需要一个figure;但是大多数中文字体的「十」却是两个figure,一个描述「竖」、一个描述「横」, 在竖与横的交界处,可能会发生问题。许多软件在显示中文字时,没有处理填色的问题,所以常常会造成两个笔画交错的地方反倒没有上色,那是因为预定的 Fill Rule采用Even-Odd,没有改成Non-Zero。除非是绘图软件,否则一般的软件不会允许我们更改字体的Fill Rule。我常常在夜市之类的地方,看到摊贩自己用Office软件和打印机做出来的简易海报,「珍珠奶茶买二送一」上面大大的中文字,每个笔画交错的地 方都没有上色,整张海报怪异到不行,这都要怪软件。
中英文字夹杂出现时,许多软件并没有注意到两者之间要有空格才美观。Microsoft Word有注意到这一点,但是许多排版软件没有注意到这一点。所以我之前在出版社工作时,我们必须先把稿件中,英文和中文的交界处加上空白,然后才排版。 幸好我们不必手动加空格,而是写了一个简单的程序来作这件事。
有一些软件(包括Acrobat Reader和早期的Java),不是使用OS的API来绘制中文,而是取出字体档案中的glyph数据自行绘制(附带一提,这些程序由于没有使用 Windows显示文字的API,所以像译点通这类API hook的程序就会无法侦测出光标位置的文字)。这个时候,很容易就会忽略了每个字的「hint」,当字体很小时,有些笔画可能会消失(比方说Times New Roman字体的e,中间的横线会消失,看起来很像c)。不过这不是中文字体的问题,这是所有字体都会遇到的问题。
正体中文字的笔画可能相当多,如果字体很小,笔画又不适当缩减,在屏幕上很可能会呈现一团黑,比方说,在Big-5字集中,笔画最多的一个字是「龘」,也就是将「品」这个字的每个「口」都用「龙」取代。
有些西方的字体变化,套用到中文是不恰当的,最明显的例子是:中文字不该出现斜体字。英文字加上斜体,可以吸引注意,但中文字加上斜体,只会变得相当难以辨识,但许多人似乎都没有意识到这一点。

中文输入与造字
以前我的美国籍英文老师看到我输入中文时,都啧啧称奇。中文字有上万个,但键盘只有约100颗按键,对于许多不知道何谓IME软件(让使用者不安装中文输入法,也能使用简单的拼音输入法输入中文)的西方人来说,如何输入中文字,一直是一个神秘难解的谜团。

中文输入
想输入CJK(中日韩)文字,必须利用IME进行字的组合。常见的输入法包括键盘、手写、语音。微软的键盘输入法越来越好,我个人认为微软新注音输入法的质量,已经比一家号称「自然就是美」的输入法更好用了(至少新注音的错字比较少)。我认为微软语音输入法的质量也快要赶上IBM,手写输入法的辨识率也相当高。经过数十年来的研发,中文输入法已经不再是个问题了。
甚至再这样发展下去,中文的语音输入法或许可以超越英文的语音输入法,中文语音的辨识应该比英文更容易,因为除了「儿化音」之外,中文几乎都是一个字一个音节,而英文字,连断字都会有问题,例如「I Scream」和「Ice Cream」的发音是一样的。虽然现在的中文语音输入法已经算很实用。但是,对于大量输入文字的作家以及上班族来说,还是打字比较实际。我曾经在翻译一本书的期间,使用语音输入法,当时我每天喋喋不休,嘴巴很酸,喉咙很渴,这些是我事先没预料到的,我认为语音输入法厂商应该要在产品上加注警语,提醒消费者长时间使用,可能有口渴、嘴酸的症状。于是,没多久,我又走回键盘输入的老路。
至于手写输入,速度太慢,恐怕只有在掌上装置等不方便使用键盘的地方,才适合将就着用。以上一期提到的「龘」(三个龙)这个字来说,笔画是48画,假设写3笔画需要1秒,那么写出这个字就需要16秒,加上写完后停顿让计算机辨识的时间,我们需要18秒才能输入这个字。如果是讲话连珠炮似的张小燕来用语音输入法,或者像莫扎特这种手指头特别灵活的神童用键盘输入法,恐怕18秒已经足以让他们写出一篇作文了。
IME,是CJK(中日韩)文字独有的特色,但是很少有程序会好好使用它。有的时候,你不希望IME出现的时候,IME却一直跳出来干扰你。如果你是软件开发者,我建议你可以去看看IME相关的API,Flex和.NET都有这样的API,如果这些API没有你要的功能,你可以直接呼叫Win32的IME相关API。最近Windows平台开始提供整合各种输入接口的API:Text Service Framework,也值得参考。

中文造字
有许多怪异的中文字,只会出现在人的名字中。而且很可能造了这个字,就只给某一个人用,只要这个人一挂掉,这个字就没有人用了。武则天就创立了不少怪字,其中最有名的是「曌」(上「明」下「空」),人家是女皇帝,我们拿她没辄,只好眼睁睁地看她胡搞。如果武则天生长于现代,我会帮武姑娘写推荐信,请她到Unicode.org上班,一方面可以借重她的长才,二方面可以让Unicode.org的老板叫她收敛一点。
为什么名字中会出现这么多的怪字,那是因为中国人是很迷信的民族,连名字都是迷信的一环。孩子出生了,为了他的命运着想,会去找大师命名,大师说:「这个孩子的生肖和出生时辰缺『龙』,所以名字中要多写几个『龙』;天格和地格的笔画加总必须为质数,长大以后才能成为杰出的科学家。」然后这个大师会在红纸上用毛笔写一个名字给你,很可能名字中的字是不存在的,新的字就被创立了。早期没有计算机化,所以姓名的登记都是用书写的方式,所以随便创造的字,也可以在户政事务所登记成功。
Unicode有大量奇特的中文字,我常常怀疑,这些字的使用频率,一年有没有到达一次。但是这些奇特的字,有些是古书上的字,不见得没有存在的必要。幸好Unicode有组字功能,例如,假设武姑娘想建立「曌」这个字,但是Unicode不存在这个字,她不用跺脚插腰发姑娘脾气,可以直接用三个Unicode的code point来表示「曌」,第一个code point表示「这个字是由上下两个部分所组成」,第二个code point表示「上面部分是明」,第三个code point表示「下面部分是空」。这种造字方式可以套迭(nested),所以可以造出相当复杂的字。
但是先别兴奋,「中文组字」虽然是Unicode的标准,但目前Windows不支持,所以你无法在Windows上面看到自己造出来的字。(但是我最近用REBOL写的程序不使用OS的文字输出,而是用自己的文字输出引擎,有支持中文组字。)


蔡学镛-专职作家
清华大学资讯工程硕士,曾任华硕集团软件工程师、元智大学信息系讲师、美商欧莱礼出版社技术编辑、台湾微软特约专栏作家,程序员杂志专栏作家。


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部

返回版面帖子列表

[转帖]IT中文环境的血泪史








签名