王 震,刘汇丹,吴 健
(1. 中国科学院 软件研究所,北京 100190;2. 中国科学院大学,北京 100049)
世界上现存的语言文字有几千种,统一的国际标准使得这些文字可以在计算机中兼容共现。但许多文字在显示输出的过程中,往往表现出比拉丁文字或汉字复杂得多的特征,其字符与字形并不是一一对应而且变形规则相对复杂,这样的文字统称为“复杂文字”(complex script),其中包括阿拉伯文、印度文、蒙古文、维吾尔文、藏文等。在这些复杂文字中蒙古文是唯一从上到下竖写、各列从左到右排列的拼音文字,并且在一个词里各个字符是连写的。蒙古文的名义字符和变形显现字符之间是一对多关系[1]。蒙古文的编码模型在一定程度上不同于Unicode中的任何一种其他文字,其在很多方面是最复杂的[2]。正因为蒙古文在计算机处理中复杂的变形显现特性,到目前为止Windows操作系统本身对蒙古文显形的支持并不完善,现有的主流Linux发行版自身都不能支持蒙古文的正确显形。
2000年国际标准化组织ISO通过了国际标准ISO 10646(等同Unicode标准)的蒙古文编码[3],为蒙古文字字符集和编码的统一制定了标准。但是蒙古文变形显现字符集和控制字符使用规则尚无已经实施的统一标准,各个版本的字库和蒙古文变形引擎名义字符到控制字符的变形规则和处理并不统一。国家标准《GB 25914-2010信息技术 传统蒙古文名义字符、变形显现字符和控制字符使用规则》(以下简称《规则》)从2011年11月起开始实施,《规则》能解决蒙古文变形规则不统一的问题。这就需要按照该标准中的规则实现新的OpenType字库和蒙古文变形引擎。
本文按照《规则》中蒙古文变形规则,提出了一种通用高效的蒙古文变形显现模型,并分别在Linux两个主流的桌面环境KDE和GNOME的复杂文本布局引擎中实现了该模型。
由于复杂文字的字符与字形对应关系复杂,在处理时需要用到一些特殊的机制。复杂文本布局引擎就是操作系统中专门用来处理复杂文本布局和显示的部件。
复杂文本布局引擎的主要任务就是将Unicode文本字符串转变成用于显现的字形串[4],其对复杂文本的显示支持主要通过OpenType技术实现。目前常见的复杂文本布局引擎中包括Uniscribe、ICU、Pango、Qt、Harfbuzz等。
• Uniscribe是微软开发的在Windows下的文本布局引擎,它主要包括以下的部件: 把文字从输入次序重排成为显示次序、把文字按前后文做出适当的变换、按文字显示的方向做出字符的替换。
• ICU是IBM公司开发的用于正确显示Unicode编码对应的字形的文本布局引擎。它能够提供对复杂文本的处理,并能够加入新的代码来支持对新的复杂文本的处理[5]。
• Pango是一个开源的自由函数库,用于高质量的渲染国际化的文字。Pango被整合到多数Linux发行版中,Pango是模块化设计的,核心的Pango布局引擎能够用于处理不同的后端字体。同样,对于阿拉伯文、蒙古文等构成的复杂文本有相应的模块分别做处理。
• Qt库是Linux KDE的基础,在Qt3.3.2及Qt之前的版本中将复杂文本布局支持融入在其文本显示模块中,在Qt4中使用Harfbuzz布局引擎来对复杂文本布局做单独处理。
• Harfbuzz是一个新的OpenType布局引擎,已经在Pango和最新版本的Qt4和Firefox4中使用。按照其作者的说法,Harfbuzz将来可能完全取代Pango,成为KDE和GNOME的底层文本布局库。
不同平台上的复杂文本布局引擎不尽相同,但是这些引擎却有很多共同特点。这些引擎在处理一个复杂文本字符串的时候一般都要经过以下三个步骤。
(1) 字符串分条目
依据ISO标准化组织定义的双向算法将字符串分成多个条目(item),要求每个条目中的字符具有同样的文字和方向属性[5]。
(2) 条目内字符标注
对于条目内的字符按照字符属性、上下文关系对每个字符进行标注,主要是对每一个字符贴上对应的特征标签(features),便于在后面的操作中进行字形替换。
(3) 字形替换
先将字符映射成对应的字形,得到字形串与绑定在其上的标签值[5],然后通过查找OpenType的字形替换表(GSUB表),按照标签顺序进行字形替换,得到最终显示字形。
目前蒙古文变形引擎的实现一般是基于OpenType字库技术,在复杂文本布局引擎的基础之上增加一个蒙古文变形模块,以实现其对蒙古文的支持。自2000年蒙古文国际标准ISO 10646制定后[3],人们按照国际标准先后在不同的复杂文本布局引擎上研究、实现了多个蒙古文变形引擎。
董治江等对ICU的文字处理体系结构进行了研究,阐述了ICU支持国际标准的蒙古文、维文、藏文等少数民族文字的实现方法[6]。周扬荣等通过分析ICU的源码阐述了对复杂文本支持的设计思路和方法[5]。周扬荣等通过在OpenType字库中定义蒙古文对应特征标签(features),在蒙古文变形引擎中分析蒙古文字符串、给每个字符贴相应标签的标签算法得到正确字形[7]。OpenType字库解决了用TrueType字库对变形显现字符没有确定的码位的问题,并在此基础上实现了ICU对蒙古文的支持。姚延栋等在Qt3.3.2中实现了蒙古文变形引擎[8],依然是基于OpenType字库技术和标签算法实现。田寄远等在Pango中实现了蒙古文变形引擎,实现了GNOME平台编辑器中蒙古文的正确显形[9]。斯·劳格劳分析了Uniscribe对蒙古文等复杂文本做变形的处理流程[10],Uniscribe对复杂文本变形的实现机制也是基于OpenType技术。蒙古文变形的复杂性也是蒙古文操作系统实现中的一个难题,芮建武通过OpenType字库技术和Qt库等实现了基于KDE桌面环境的蒙古文操作系统[11]。
之前的蒙古文变形引擎通过相应的OpenType字库能对蒙古文选形正确,但是因为当时没有统一的可实施的标准,之前的引擎中蒙古文控制字符使用并不完全符合《规则》中的规定。另外,由于当时的蒙古文OpenType字库中定义的标签数量较多,周扬荣在ICU中实现的蒙古文变形引擎[8]和姚延栋在Qt3中实现的蒙古文变形引擎[6]都要将标签分三层分别处理。这使得蒙古文变形显现效率极低,Qt3中的蒙古文测试文本在拖动滚动条时能明显感受到屏幕刷新。本文按照《规则》中字符变形标准,利用简化特征标签数量的OpenType字库设计了一种通用高效的蒙古文变形模型。
蒙古文是一种拼音文字,在ISO 10646国际标准编码字符集中收录了传统蒙古文的7个元音、27个辅音、11个标点符号、10个数字和4个控制字符。但是由于ISO/IEC 10646标准制定规则的限制,该标准中只按蒙古文语音收入了抽象的蒙古文字符(称为名义字符)。蒙古文是复杂文字,同一个蒙古文字符的书写(显现形式)会根据其在词语中的位置不同、单词的词性等属性不同而发生变化,即呈现在人们面前的是该字符变化后的形式(称为显现字形)。由于ISO/IEC 10646标准中没有收入蒙古文显现字符,因此,在显示蒙古文时需要将蒙古文的名义字符根据上下文映射到其相应的显现字形。
蒙古文的正确显示大致会受到以下规则的制约[12]。
(1) 字符在词里的位置。很多蒙古文字符在词首、词中、词尾或者独立时各有不同的字形,主要通过单词的结构来确定;
(2) 自由变体选择符FVSn和元音间隔符MVS。在单词中配合FSVn和MVS可以正确指示蒙古文字符应该显示哪一个字形,或者在单独使用某个字符的一个字形时,可以通过在该字符前后加入相应的FSVn和控制字符得到字形;
(3) 音节、词性引起的变形。蒙古文的一个词语分为若干个音节,由元音和辅音组成的音节以及词性(阴性、中性、阳性)都会影响字形的变形。音节与音节之间的相互关系也有可能导致变形;
(4) NNBSP、ZWJ、ZWNJ等控制字符。这些控制字符虽然不是蒙古文字符,但是对于蒙古文变形却起着至关重要的作用,其对蒙古文字形显现的控制规则在《规则》中规定。
在ISO 10646国际标准中并没有包含蒙古文名义字符控制字符到变形显现字符的使用细则,也没有对蒙古文的合体字的使用做出详细说明。在新的国家标准GB 25914-2010中对这些都给出了详细说明。新标准中主要规定了以下两点。
(1) 蒙古文的变形显现字符如何通过控制字符和名义字符组合得到,标准中将所有的蒙古文变形显现字符出现一一做出规定;
(2) 强制性合体字和非强制性合体字列表
通过定义这些规则,明确了从名义字符和控制字符到蒙古文变形显现字符的映射。本文的蒙古文OpenType字库和蒙古文变形模型的设计以此为准。
OpenType字体是对TureType字体的升级,能够为“复杂文字”提供更好的支持。OpenType字库对复杂文本的支持主要是通过布局表来实现的,这些表包括字形定义表(GDEF)、字形替换表(GSUB)、字形定位表(GPOS)、基线调整表(BASE)、对齐表(JSRF)。在蒙古文变形中主要用到GSUB字形替换表,新的OpenType蒙古文字库按照《规则》中的规定将蒙古文字形的替换规则写入GSUB表,经过蒙古文变形引擎对字符贴标签后依次替换得到正确字形。
在符合新标准的OpenType字库中定义了如表1所示的特征标签(features),从中可以看到特征标签一共有7个,比之前实现的ICU和Qt3中蒙古文变形引擎时的标签数量大大减少。通过这7个标签就能够对所有的蒙古文字符依次进行特征标注,然后在GSUB表中查找替换就能够得到最终显现字形。
表1 蒙古文OpenType字库特征
4.2.1 基于OpenType的蒙古文变形引擎工作原理
正确的蒙古文变形显现结果是由蒙古文变形引擎与蒙古文OpenType字库相配合得到。蒙古文变形引擎是复杂文本布局引擎的一个模块,其主要工作是通过对蒙古文字符串分析并进行标注。
复杂文本布局引擎先对字符串条目化处理,然后对该条目所属的文字、语言进行判断,如果判断出该条目是蒙古文则调用蒙古文变形引擎。蒙古文变形模块对蒙古文字符串分析之后贴上特征标签(features)。复杂文本布局引擎在已经读入内存的OpenType字库的字形替换表(GSUB表)中查找替换规则,按照特征顺序依次应用替换规则,最终得到字形串。该流程大致如图1所示。
图1 复杂文本布局引擎通过OpenType字库得到字形流程
4.2.2 设计通用的蒙古文变形模型
由于复杂文本布局引擎在实现上有很多共同之处,都要经过字符串分条目、条目内字符标注、字形替换等操作。这些共性使得可以设计一种通用的蒙古文变形模型,可以有效地作用于不同的复杂文本布局引擎中。
蒙古文变形模型的核心工作是对蒙古文字符串进行标注,给每个蒙古文字符贴正确的特征标签,通过标签算法实现蒙古文字形选择。标签算法通过分析每一个蒙古文条目中的字符和其对应的上下文确定给其分配的特征标签[5-6],特征作用范围如表2所示。由于在OpenType字库的标签中只有词首(Init)、词中(Medi)、词尾(Fina)和独立(Isol)这4个标签是对单个字符标注,其他标签均作用于所有字符,这样就可以对条目化之后的蒙古文字符串只贴这4个标签,其他标签只需要对所有字符均应用就可以得到正确结果。
表2 特征标签作用范围
词首(Init)、词中(Medi)、词尾(Fina)和独立(Isol)这4类标签所表示的意义在表1中已经提及,一般来说在一个完整的蒙古文单词中如果不考虑控制字符的影响,通过单词边界就能很容易判断出字符在单词中的位置。这个过程可以类比英文单词,例如, “China”,“C”是词首,“a”是词尾,“h”,“i”,“n”是词中。
根据变形显现字符集和控制字符使用规则中的规定,蒙古文字符特征除了受字符在单词中的位置影响外,还受窄宽度无间断空格(NNBSP)、零宽度禁连接符(ZWNJ)、零宽度连接符(ZWJ)和元音间隔符(MVS)等控制字符的影响,它们的作用如表3所示。
表3 蒙古文控制字符对字符特征标签影响
可见,蒙古文字符的标注结果由其在词语中的位置和表3中的控制字符共同决定。在设计蒙古文变形模型的标签算法时,采用启发式的策略对蒙古文字符进行标注。根据上文分析,我们设计的蒙古文变形模型工作流程如图2所示。由于除了init, medi, fina, isol这4个标签外其他标签都要对所有字符标注,该模型中的标签算法只需要对条目化的蒙古文字符串做一次遍历就能够完成字符串的特征标注。该模型的标签算法时间效率很高,算法的时间复杂度为O(n),n为蒙古文字符串长度。
图2 蒙古文变形模型工作流程
KDE和GNOME是Linux操作系统的两大主流桌面环境,我们分别在这两个桌面平台下的文本布局引擎中测试蒙古文变形模型。
Qt库是Linux KDE桌面系统的核心库,Qt4是其现行版本。为了测试蒙古文变形模型的效果,我们在Qt4的底层文本布局引擎Harfbuzz中加入一个对蒙古文进行处理的模块。该模块中实现了HB_Mongolian_Shape函数,这个函数是蒙古文变形模块的接口,其职责是通过一个蒙古文字符串条目得到对应的OpenType字库中的字形索引。HB_Mongolian_Shape函数中调用了蒙古文变形模块中核心的getMongolianProperties函数,后者负责对蒙古文字符串进行标注。按照蒙古文变形模型中的规则,我们在getMongolianProperties函数中实现了标签算法,从而得到蒙古文的变形结果。
图3,4为Qt4.5.0中自带的文本编辑器使用蒙古文变形模型前后的显示对比。实验结果说明,我们的模型有效地作用于Qt4的底层文本布局引擎Harfbuzz。
图3 使用蒙古文变形模型前,Qt4中测试文本显示
图4 使用蒙古文变形模型后,Qt4中测试文本显示结果
Pango是Linux GNOME平台提供的文本布局引擎,为GNOME平台下的应用程序提供底层文本布局显示支持。Pango1.22.0复杂文本变形模块中包含了对阿拉伯文、藏文等复杂文本的单独处理,但并不包括蒙古文。我们在Pango1.22.0的module文件夹中加入单独对蒙古文进行处理的模块。其中函数mongolian_engine_shape提供蒙古文变形模块接口,并调用核心函数Mongolian_Assign_Properties。后者通过分析蒙古文字符串,获得字符串对应的标签,再遍历字符串通过每个字符的标签依次应用字形替换规则,得到对应的OpenType字库中对应的字形索引,最终得到字形串。
我们在Linux GNOME平台下使用pango-view测试Pango对蒙古文的显示结果的支持,前后对比结果如图5,6所示。实验结果表明,通过在Pango中加入蒙古文变形模型实现的蒙古文变形模块有效地实现了蒙古文的正确选形。
图5 使用蒙古文变形模型前,测试文本显示结果
图6 使用蒙古文变形模型后pango-view测试文本显示结果
在Linux GNOME平台上的很多应用程序(如Firefox,Gedit等)的文本布局显示都依赖于Pango。我们在Federa12下的Firefox-3.5.15中测试蒙古文网页显示情况,使用蒙古文变形模型前后的结果如图7,8所示。实验结果表明,蒙古文变形显现结果正确,进一步验证了该模型能有效地实现蒙古文变形显现。
图7 应用蒙古文变形模型前,GNOME平台上Firefox对蒙古文测试页面显示结果
图8 应用蒙古文变形模型后,GNOME平台上Firefox对蒙古文测试页面显示结果
本文以国家标准GB 25914-2010为依据,结合OpenType技术,提出了一种高效通用的蒙古文变形显现模型。该模型建立在对多种复杂文本布局引擎实现共性分析的基础上,对不同复杂文本布局引擎具有很好的通用性。在KDE平台下的Qt库和GNOME平台下的Pango库进行的实验均证明,该模型能对蒙古文文本实现正确显形。该模型的实现,为研制符合新标准的以GNOME或者KDE为桌面环境的蒙古文操作系统奠定了基础。目前GNOME平台下Pango库对蒙古文竖向显示尚不支持,这也是我们下一步的工作。
[1] 乌达巴拉,巩政.蒙古文OpenType字体制作技术[J].内蒙古大学学报(自然科学版),2006,37(5): 570-573.
[2] The Unicode Consortium. The Unicode Standard, Version 6.0.0, (Mountain View, CA: The Unicode Consortium,2011.ISBN 978-1-936213-01-6)[EB/OL]. http://www.unicode.org/versions/Unicode6.0.0/,2011:427-432.
[3] International Standard ISO/IEC10646-1 Second Edition.Information technology-Universal Multiple-Octet Coded Character Set(UCS)[S],2000.
[4] 董治江,吴健,钟义信.基于OpenType的复杂文本语言处理的研究与实现[J].计算机应用研究,2004(10):158-161.
[5] 周扬荣,贾彦民.复杂文本布局引擎机制及应用研究[J]. 中国科学院研究生院学报,2006,23(3): 390-395.
[6] 董治江,吴健,钟义信.在ICU中实现少数民族文字处理[J].中文信息学报,2004,18(2):66-72.
[7] 周扬荣,贾彦民,吴健.基于ICU的复杂文本布局引擎设计与跨平台应用研究[J].计算机应用研究,2007,2: 29-224.
[8] 姚延栋,吴健,孙玉芳,等.传统蒙古文变形显示机制研究与实现[J].中文信息学报,2005,18(5):84-89.
[9] 田寄远,赵小兵. Linux—GNOME平台下基于OpenType的蒙古文自动选形引擎的设计与实现[J].内蒙古大学学报,2009,40(3):320-325.
[10] 斯·劳格劳,敖其尔.Windows环境下蒙古文复杂文本处理的研究[J].内蒙古大学学报,2007,38(5):582-585.
[11] 芮建武,吴健,孙玉芳.国际化标准框架下蒙文操作系统的设计[J].计算机研究与发展,2006,43(4):716-721.
[12] 确精扎布.蒙古文编码[M].呼和浩特: 内蒙古大学出版社.2000.