程序处理维语过程
前言
双向文本显示和字符连接是程序显示维语过程中遇到的两个问题.文本双向算法 能很好地处理字符串中包含有双向文本流混合时遇到的各种现实情况, 而维语基本字符转换到拓展区后能很好地处理字符连接问题.
文本双向算法
有过html
编程经验的小伙伴可能对<hdi>
和<hdo>
标签比较熟悉,关于这两个标签的使用, 网上有一些很不错的文字,可以自行百度;其目的在于如何良好地处理有右向左和左向右的文本混合在一起时在UI上呈现出理想的视觉效果.
当然,在游戏中,我们不能使用 html
的 <hdi>
和 <hdo>
标签来处理维语显示问题, 也不可能我们自己实现一次文本双向算法. 中东朋友们为了有更多好玩的游戏而在 fribidi 项目中对文本双向算法做了完备的实现, 这确实节省了我们很多的工作量.
字符连接问题
由于大部分字体渲染引擎不能很好地处理文本双向显示, 一般情况是, 字体渲染引擎能很好地处理文本流左向右的字符显示. 既然如此, 那么将翻译好的文本(完美引擎下的正常语序文本)进行一次翻转(即首尾颠倒,或叫双向文本转换), 就能正常显示双向文本了. 上面提到的 fribidi 项目帮我们实现了文本翻转问题, 但这也引入了一个新的问题.
由于维语的复杂结构(相对于英语等语言吧), 在不同位置显示不同的形态, 因此在进行文本翻转[双向文本转换]时需要对字符形态和一些特殊情况进行处理,项目维语基本区和拓展区字符转换 特殊字符处理做了一个完备的实现. 这里是 java
版的实现. 代码不多, 后续我们将翻译出更多语言版本的实现.
维语实际处理过程
通过上面的赘述, 你可能已经对处理过程有了一些思路. 通过我们自研团队的实践,以及在制作正确显示维语对比工具上的实践.我们得出了如下可行,有效的处理流程:
- 用维语基本区和拓展区字符转换工具 将基本区字符转换为拓展区字符 (解决字符连接问题)
- 用 fribidi 工具将上一步转换的字符串进行文本翻转 (解决文本方向问题)
代码实现
local label = cc.Label:create() // 将要显示的字符串 local content = 'ئۇيغۇر تىلى' // 工具方法将 基本区字符转换为拓展区字符 // UyBaseEx 来自 https://github.com/Alimjan2009/uyghur_convert_util/blob/master/UyBaseAndEx.java content = UyBaseEx.toEx(content) // 用 fribidi 进行文本翻转 // (翻译给的文本是右向左的, 翻转后为左向右的顺序, 然后按照左向右的顺序进行渲染即可) // 方法来自 https://sdk-doc.badambiz.com/chapter2-show_faq/ 4.2.2 节 content = g_uft8_fribidi_convert(content) // 进行渲染 label:setString(content)
处理结果检查
很多CP主要是技术团队,并不认识密密麻麻的蚂蚁文,也没有懂维语的同事进行正确性检查, 因此我们团队做了一个正确显示维语对比工具, 点击访问 方便CP团队进行正确性检查. 在输入框中贴入翻译出来的文本, 然后调节好对应的参数:图片区域的宽,高和字体的大小后,点击转换就可以在下方生成目标效果.
PS: 通过调节目标图片的宽度和高度以及字号大小等,可以模拟出换行效果
富文本处理
富文本一般为 html 代码和要显示的实际文本构成, 由于在过程1[基本区转拓展区]和过程2[fribidi 双向转换]时都仅仅对 阿拉伯字母(维语也包含其中)进行处理, 并不会影响诸如<p style="color:red">ئۇيغۇر تىلى</p>
中的 html 代码, 因此, 如果您的富文本使用 html 代码以及类似的方式实现的, 那么上面的处理过程同样适用于富文本. 值得一提的是,如果需要手动(代码)实现富文本换行, 那么处理富文本换行时需要做一些额外的工作了