【发布时间】:2021-06-13 22:15:49
【问题描述】:
我在处理高棉文本时遇到了一个有趣的问题。
文本“កើ”是 Unicode 中长度为 2 的字符串。有关字符代码,请参见下面的片段。
let textbox = document.getElementById('textbox');
let info = document.getElementById('info');
let text = "កើ"
textbox.setAttribute('value', text);
info.innerHTML = "length: " + text.length + "<br>codes: " + text.split('').map(c => c.charCodeAt(0))
<input id="textbox" type="text" style="font-size:80px; width: 2em;"/>
<div id="info"></div>
文本渲染器似乎由三个字形组成这个文本,或者用连字替换这三个字符。到目前为止,这很奇特,但并不出人意料。
这是令人费解的事情:当我使用Khmer font from Google Fonts 在http://www.corvelsoftware.co.uk/crowbar/ 的Crowbar 文本整形调试器中键入此文本时,可以看到这两个字符映射到三个字形。但这两个字符似乎在映射之前就变成了三个字符。角色 6081 凭空出现。
我深入研究了字体文件的内部结构,cmap 表中只有一个子表,它将字符代码映射到 glpyh id。此表的格式为 4,非常标准,只允许一对一映射,因此在 cmap 处理期间没有插入额外的字形。
此外,如果仅将两个原始字符代码映射到字形,则生成的文本看起来会有所不同,因此第三个字符似乎是必要的。
我在这里遗漏了哪一步将字符之前的第三个字符添加到字形 id 映射?似乎对文本进行了一些我不知道的预处理。
【问题讨论】:
-
这似乎是一门科学。这里有一篇文章详细描述了如何创建高棉字体:docs.microsoft.com/en-us/typography/script-development/khmer 这实际上是在进行一些预处理,例如在元音之前添加一个字符。
-
我不知道所有细节,但第一阶段是规范化字符串。 Unicode 代码点有不同的规范化。他们很可能只是做一个分解,因为单独处理变音符号要好得多(他们遵循其他规则)
-
@GiacomoCatenazzi 谢谢,我会调查的。字符串有一个 Javascript normalize() 函数。但到目前为止,我无法做到我所希望的。
-
你应该检查整形引擎,例如harfbuzz.github.io(很少有其他:Microsoft 之一,Mac 和 SIL 之一)。这些翻译字符串(和字体信息)的位置和字形。这是一个复杂的话题,我还没有掌握。
-
我还建议在typedrawers.com 上询问这个问题,因为这是所有字体人都在闲逛的地方。
标签: unicode character-encoding truetype opentype