swfit 开发 ! 阿拉伯语言和英文排序为难题简单理解。

518 阅读8分钟

1.iOS控件渲染文字方式。

iOS控件lable 等,在渲染文字的时候。 区分文字的类型分为 LTR 和 RTL 两种。 其中代表性的是 中文+英文 是 LTR 的, 阿拉伯语是 RTL 的。 再来解释下 LTR 和 RTL 是什么意思。 这俩单词缩写是指 我们iOS控件在渲染文字的时候这一段整体文字的排列顺序。 什么意思呢。 比如我们的英文 abcdedfgh . 这么一段文字。 我们我们再给控件赋值的时候.我们正常理解的 "abcdedfgh" . 的顺序是 从左往右侧读的。 最左侧的是 a。最右侧的是h。 所以在label 上显示的时候 也是 abcdedfgh . a在左侧,h在最右侧。 这样排列显示在lable 是的文字我们称之为LTR的文字。 但是阿拉伯语言就不一样了。 我举个例子。"اصوات الهدايا" 我们看到的是 这个样子. 这段文字中。 第一个字符其实是最右边的那个树杠。阿语开始读写是从右侧往左侧读写的。我们把 这个字符串赋值给label 。会看到也是这个排列"اصوات الهدايا"。但是注意 虽然lable上排列好像和我们再文本上输出是一样的。但是绘制原理是不一样的。他是先去绘制那个最右侧的树岗,然后依次往左侧找字符绘制的。一行文字 没有什么效果。 如果是超过一行了就看出区别了。超过一行。下一行最右侧的字符是上一行最左侧的字符的下一个字符。纯阿语和纯英语的字符串在lable上显示是这个样子的。和字符串显示在文本里面是一样的。

总结lable在对文字渲染的时候。简单理解为判断字符串第一个字符是英文还是阿拉伯语。如果是英语 就从左取字符到最右侧字符。按照lable 从左到右的显示出来。 而如果第一个字符是阿拉伯语。其实是 从最右侧去取阿拉伯第一个字符到最左侧字符,然后再lable 上从lable右侧一个个渲染在屏幕上。 貌似上面是一样的。其实不一样。考虑一下这种case 。 多行。 两行的情况。 如果全是英文。英文字符串是在把字符从左侧往右侧放置, 放不下了。换到下一行再放剩下的字符串。 而阿拉伯语言是 从最右侧往左侧的。一行放不下的时候。是视觉上左侧的字符换到下一行。而且放不下的那个字符是下一行的最右侧的字符。再往左侧显示。而英语是第一行放不下的字符放到第二行是放在右侧的。

2. 再说一下 混排的情况。
先说一个概念。那就是 我们上述说的 RTL LTR 是指 英语和阿语的情况。它不是指一个字符排列。而是一块字符串的排列。 什么意思呢?比如一个字符串 是英文+阿语+英文的。 我们所说的RTL 是指分为三段来说的 英文 这一段是RTL 的 阿语是 LTR 的, 后面的英文又是RTL的。一个字符串里面 首先是 把这个大字符串分成几部分。都是英文的一部分。 都是阿语的一部分。然后再去考虑lable渲染排列方式的。不是说 我有个字符串组成是 英文+阿语+英文 的。 我一看 这是英文开头的。 那么整个字符串都是 RTL 的。 中间的阿语也会被强制改为 RTL 的。 不是这样的。他是分成三部分的。每一部分,使用各自的规则显示在屏幕上。 显示的时候是一块一块显示的。
3. 来说一下 英阿混排的情况。
3.1 英语+阿语 "abc" + "اصوات الهدايا"

这种情况 比较简单。ios控件看到 字符串开头是abc 那么 把abc 作为一个整体。先从左侧开始渲染 abc 。 然后遇到了 "اصوات الهدايا" 。 先去从右侧读取字符串树杠,往左侧读,然后和开始的abc 一起显示到屏幕上。 这里要理解一个概念。就是字符串的substring整体去判断LTR 还是 RTL 。并不是我们容易理解为 我一看是 abc 开头。 那么 是RTL的。 所以 后面的阿语 也得 RTL的 。就是容易理解 把 阿语的第一个字符就接着abc 后面 取渲染了。 (阿语的第一个字符是 树杠最右侧的字符 不是视觉上看到的最左侧的那个字符)

3.2 英语+阿语+英语 "abwodowaodoawdasdasdasodwodowc" + "اصوات الهدايا" + "def"

这种排列组合其实和英语+阿语 是一样的。首先系统看到的是 英文字符串。 从左往右放置内容。 放完英文。 再来看中间的阿语。 遇到了阿语这一块 ,采用从右侧开始绘制内容。就会从 阿语的字符串 最后一个字符 ,从右侧开始绘制 往左侧找字符。 最后放置在 英文字符串后面。 这里有个特殊点 就是正好阿语这个子字符串换行了的情况。 我们按照正常理解 阿语的最后一个字符 树杠 按照之前讲的概念 从最右侧渲染 。然后由于换行了。我们理当理解为 那就放到第二行呗。 其实不是这样的。 系统是 把抛去英文的位置 剩下的位置开始绘制阿语。 比如还剩下 三个字符的阿语。 那么 上述例子就是 系统会把 "اصوات الهدايا" 子字符串的最右侧的三个字符 放在第一行。然后剩余的阿语字符串放到第二行去展示。

3.2 阿语 + 英语

如果开始是阿语 那就有些特殊了。 因为阿语在系统上绘制是从右往左绘制的。如果判断第一个字符是阿语。那就会从右往左绘制了。 绘制完成阿语后,接着绘制英语。 英语就接在阿语后面也就是阿语绘制完了之后再其左侧在展示英语

3.3 阿语 + 英语 + 英语

同理。按照一块一块的逻辑去排列。 首先根据第一块 确定这一行的整体排列

最后介绍下 不可见字符 Unicode双向文本控制字符

\u{200f} \u{200e} \u{200c} 这里面主要介绍三个不可见字符

  • \u{200f} :用于在文本中指定一个点,该点之后的文本应当从右至左显示
  • \u{200e} :用于在文本中指定一个点,该点之后的文本应当从左至右显示
  • \u{200c} :终止前面最近的LRE或RLE文本嵌入

光看介绍有点懵。 并且解释的概念,对开发并没有什么用处。 我们一般情况下 都是成对使用的

  • \u{200f} + substring + \u{200c}

  • \u{200e} + substring + \u{200c} 这两对一起使用。 \u{200c}好解释 。就是 恢复之前的排列方式。就是理解为取消掉\u{200f}\u{200e} 设置的作用。恢复到之前设置的方式。 然后着重讲一下 \u{200f}\u{200e}

  • 反正我是这么理解的 。 \u{200f} 强制右侧。 \u{200e} 强制左侧。我们把 一个字符串 分为 \u{200f}修饰的字符串 和 \u{200f}之前的字符串。 \u{200f} 的作用是 把我修饰的字符串 放在 \u{200f}之前的字符串作为一个整体的 它的 左侧去。

  • \u{200e} 恰好相反, 是把 \u{200e}修饰的字符串 显示在 \u{200e} 之前的整体字符串的右侧。

  • 最后 说 具体展示substring 字符串 是看它本身是什么字符串。 看其显示。

举几个例子。

  • 1 "\u{200f}ABC\u{202c}" +  "\u{200e}bcd\u{202c}" + "\u{200f}EFG\u{202c}" + "\u{200f}efg\u{202c}" 在这里 首先我们看ABC\u{200f}修饰代表ABC强制右向左排列(这里不是说ABC从右向左显示为CBA,只是指ABC这个整体是右向左的排列方式,以及后续内容是右向左的方式)。然后后面跟着bcd 是用\u{200e}修饰的。说明其是整体按照 左向右方式。同时也理解为 bcd 作为一个整体渲染的时候,它是放在它前面的字符串 ABC 的整体右侧。再来看EFG 这个字符串是用\u{200f}修饰。它的作用是让EFG作为一个整体享受右向左的方式。因为最开始的ABC开的头是右侧向左侧方式,所以此时的EFG其方式是右向左的,而前面ABC是右向左的,所以EFG放在了 ABC左侧 示在它前面整体的左侧的。也就是 EFG 会显示在ABC 的左侧。目前为止 渲染显示结果为EFGABCbcd 最后看 efg同样其被 \u{200f}修饰 同理 它渲染显示是在整体的最左侧。 最终结果为 efgEFGABCbcd.

  • 2 . "\u{200f}ABC\u{202c}" +  "\u{200e}bcd\u{202c}" + "\u{200f}EFG\u{202c}" + "efg" 这个理解 较上面结果就是 最后的"efg"没有修饰了。 此时按照efg之前的 子字符串 EFG 渲染完成。此时 efg 要么再 EFG 左侧 要不在EFG右侧。 总之是 跟这EFG走的。