0

我们使用 Freetype 将单个字符渲染到纹理图集,然后从该纹理渲染到屏幕。但是,当我们渲染阿拉伯语时,字符并没有按应有的方式连接起来。它们看起来都像单独的角色,彼此相邻放置。例如,如果我们将相同的字符放入记事本中,它们确实会合并,但是如果我们在每个阿拉伯字符之间放置一个空格,它们就会分开并且看起来又像我们的渲染图。如果在记事本中删除空格,则删除空格两侧的字符会“更改”并连接在一起。很明显,放置在一起的字符组合会改变它们的外观。

那么,我们如何使用 freetype 实现阿拉伯语中的连词呢?我们是否可以使用 Freetype 将整个“单词”打印到位图,它会自动调整字形以连接在一起,或者我们可以将某种翻译应用于 utf8 字符列表,将它们转换为新的 utf8 字符来连接并排放置时向上?

谢谢

肖恩

4

2 回答 2

2

确实可以做一个阿拉伯文本渲染的简化实现。

首先,您需要将 UTF8 文本拆分为 Unicode 字符。欲了解更多信息: https ://en.wikipedia.org/wiki/UTF-8

获得 Unicode 序列后,您需要确定显示顺序。对于简单的阿拉伯文字,你可以假设它是从右到左,当你遇到从左到右的文字或数字时,你需要切换方向。一个字符的方向取决于它的 Bidi 类,它是Unicode 数据库 的UnicodeData.txt中的第 5 列: https ://www.unicode.org/reports/tr44/

通用 Bidi 算法并非微不足道,特别是因为可以插入 Unicode 字符以嵌入从左到右的文本。那里详细解释了所有内容: http ://www.unicode.org/reports/tr9/

之后,对于阿拉伯文本,您需要确定连字。字母根据它们的连接类型连接在一起,在ArabicShaping.txt(在 Unicode 数据库中)的第 3 列中定义。例如,如果您在 R 类型的字母(右连接)的右侧有一个 L 类型的字母(左连接),那么它们将连接在一起。

该算法很简单:对于每个阿拉伯字母,确定其连接类型。如果它可以加入,那么试着在左边和右边寻找一个字母,并检查它们的加入类型是否是互补的。

请注意,它们可能是非阿拉伯字母的字符。如果ArabicShaping.txt 中没有提到,前面提到的Bidi 类可以帮助您确定字符的连接类型。如果Bidi类是NSM(非间距标记)或者通用类是Cf,那么连接类型为T(透明),否则为U(非连接)。

左右检查时,跳过 T 类型的字符,直到找到另一种类型或到达文本末尾。请注意,如果您实现 Bidi 算法,则需要在 Bidi 隔离结束时停止。

一旦知道角色是否加入,就可以确定其呈现形式:初始、中间、最终、孤立。在UnicodeData.txt中,搜索它的代码点。它将是与此演示文稿(第 6 列)相对应的字符(第 1 列)。例如,“<initial> 067B”显示为字符 FB54。因此,您可以更换它。

Lam 后跟 Alef 有一个特殊情况。在这种情况下,字符被合并在一起。例如,“<isolated> 0644 0622”表示为字符 FEF5。请注意,您可能会在两者之间遇到非间距标记。如果你不处理它们,你可以丢弃它们。否则,您可以保留这些信息以备后用。

在这个阶段,您可以将 Unicode 字符数组转换回 UTF8 字符串并使用 FreeType 绘制它。请注意,非间距标记将不会正确放置。为此,您需要分别绘制每个字符并确定标记的位置。

于 2020-05-04T19:17:28.810 回答
0

例如,此处描述了 Freetype 工作级别(字形渲染)的整个过程。如您所见,这绝非简单。

Freetype 之上存在(几个)库,其目的是使该过程“简单”,或者至少更简单;但他们在更高的抽象层次上工作,所以你可能需要改变你的范式。Harfbuzz就是这样一个项目,它与 Freetype 密切相关。

于 2018-12-12T19:35:15.383 回答