在上一节里面,我们讨论了什么是双向文字以及两个重要的概念:逻辑顺序(Logical order)和视觉顺序(Visual order)。本章我们详细了解下,Bidi算法。
Bidi的算法 在“Unicode Standard Annex #9”中具体描述了UniBidi的具体实现。UniBidi的核心的逻辑包含3个方面: 按照语言信息,识别字符类型(分为强类型、弱类型和中性类型)字符重新排序分析镜像 在具体的实现过程中,UniBidi首先把文字按照段落划分,然后再根据条件划分为行,最后对每行进行双向文字的识别和处理。除UniBidi 外,还有四种其他的算法,分别是ICU 、PGBA算法、FriDidi算法和HaBi算法。ICU 是Unicode 国际化组件,它是由IBM维护开源项目,是一个跨平台的多文件处理函数库。ICU布局引擎是ICU中独立的模块结构,用于处理复杂的文本语言。ICU 和UniBidi很相似,它实际上采用了UniBidi的字符重排算法。 PGBA 算法主要对隐式的文本进行双向文字的处理,它不采用Unicode的显示标注,不能对这些标注进行处理,它的特点是功能比较多,但是使用不方便,不具备通用性。 FriDidi是另外一个和UniBidi很相似的算法,本质就是一个具有图形界面的UniBidi算法。HaBi也是一样,实际上就是用Haskell98来描述UniBidi而已。综上所述,Unicode 的Bidi算法是目前最主要是双向文字处理算法。接下来我们详细分析Bidi算法,了解其优缺点。
基本概念 UniBidi扩展了目前已采用的一些现有实现中的隐式模型,并为特殊情况添加了显式的格式码。在大多数情况下,没有必要再包含额外的文本信息来获取正确的显示顺序。然而,在双向文本的情况下,对于有些情况,一个隐式的双向排序不足以产生可以理解的文本。为了处理这些情况,则定义一个方向格式码的最小的集合,来控制渲染时字符的顺序。这样则可以对显示顺序进行精确的控制以完成清晰的互换,并可以确保用于像文件名或者标签这样的简单项目的纯文本总是可以被正确的排序来显示。
方向格式码仅仅被用来改变文本的显示顺序。在其他所有方面它们应该被忽略掉——它们不影响文本的比较或者断字,解析,或数值分析。每个字符都有一个隐式双向类型。双向类型left-to-right和 right-to-left被称为强类型,具有这些类型的字符被称为强方向字符。与数字相关的双向类型被称为弱类型,具有这些类型的字符被称为弱方向字符。除了方向格式码,剩下的双向类型和字符被称为中性。此算法在文本中依据字符的隐式双向类型以达到对文本的合理的排序显示。
当使用双向文本的时候,字符仍然解释为逻辑顺序,只有显示时会被影响。双向文本的显示顺序依赖于文本中字符的方向属性。注意,有一些重要的安全问题与双向文本相关联:请参考[UTR36]来获取更多信息。
方向格式码 三种类型的显式方向格式码被用于修改标准隐式Unicode双向算法(UBA)。此外,还有隐式方向格式码,right-to-left和left-to-right标记。所有这些格式码的效果被限制在当前段落;因此,他们的影响将被一个段落分割符终止。
这些格式码都具有Bidi_Control属性,它们被细分为三组:
隐式方向格式码
LRM, RLM, ALM
显式方向嵌入和重写格式码
LRE, RLE, LRO, RLO, PDF
显式方向隔断格式码
LRI, RLI, FSI, PDI
虽然术语嵌入用于一些显式格式码,但在嵌入格式码范围内的文本并不独立于周围的文本。嵌入的字符会影响外围字符的顺序,反之亦然。但这又不同于隔断格式码的情况。被隔断的字符不会影响它外围字符的顺序,反之也一样。一个隔断的作用相当于在周围字符的排序中
作为一个整体和中性字符的作用差不多。而一个嵌入或者重写大概类似于一个强字符的效果。
方向隔断格式码是在Unicode6.3后推出的,很显然,方向嵌入对它们周围的文本通常有过于强的影响,因而很难于成功使用。新的格式码被推出不是为了改变现有的行为,因为这样做对那些依赖旧的行为的现有的文档可能有不良影响。然而,在新的文档中鼓励使用方向隔断而不是方向嵌入一旦目标平台都支持它们。
双向字符类型
类别
类型
描述
常用范围
强类型
L
Left-to-Right
LRM,大部分字母、音节,汉字象形文字,非欧洲或非阿拉伯数字, ...
R
Right-to-Left
RLM,希伯来字母,以及相关的标点符号
AL
Right-to-Left Arabic
ALM,阿拉伯语,Thaana,和叙利亚字母,大多数特殊脚本的标点符号, ...
弱类型
EN
European Number
西欧数字,东亚阿拉伯 - 印度数字, ...
ES
European Number Separator
加号,减号
ET
European Number Terminator
度的符号, 货币符号, ...
AN
Arabic Number
阿拉伯 - 印度数字,阿拉伯语小数点和千位分隔符, ...
CS
Common Number Separator
冒号, 逗号, 句号, 无中断空格 ...
NSM
Nonspacing Mark
字符标记Mn(Nonspacing_Mark)和Me(Enclosing_Mark)在Unicode字符数据库中
BN
Boundary Neutral
默认 ignorables,非字符和控制字符,除了那些显式授予的其他类型。
中性类型
B
Paragraph Separator
段落分隔符,合适的换行函数,更高级别确定段落的协议
S
Segment Separator
制表符
WS
Whitespace
空格,图空格,行分隔符,换页,常用标点符号的空格, ...
ON
Other Neutrals
所有其他字符,包括对象替换字符
显式格式码
LRE
Left-to-Right Embedding
LRE
LRO
Left-to-Right Override
LRO
RLE
Right-to-Left Embedding
RLE
RLO
Right-to-Left Override
RLO
Pop Directional Format
LRI
Left-to-Right Isolate
LRI
RLI
Right-to-Left Isolate
RLI
FSI
First Strong Isolate
FSI
PDI
Pop Directional Isolate
PDI
下节将详细介绍,显示方向嵌入和显示方向重新写以及终止显式方向嵌入和重写。