在文字处理软件里输入 Hello,给它换成手写字体,再复制到一个纯文本输入框,接收它的应用通常会保留字母,却不会保留字体。现在复制 ℋℯ𝓁𝓁ℴ,它的外观往往还能留下来。
第二个例子并没有携带字体信息。它使用的是一组不同的 Unicode 字符。
字符和字形不是一回事
Unicode 给抽象的字符分配编号;字体和排版系统负责把字符画成屏幕上的字形。无论字体把 A 画成衬线体、圆体还是毛笔字,它仍然是 U+0041。
用 CSS 把 Arial 换成 Georgia,只会改变字形设计,不会改变底层文字。花体生成器走的是另一条路:它会把 A 替换成 𝐀(数学粗体大写 A)或 𝔄(数学 Fraktur 大写 A)之类的字符。
所以结果才能通过纯文本剪贴板传播。也正因为如此,把所有结果都叫“字体”虽然方便,却不够准确。
Unicode 为什么会收录带样式的字母?
这些字符最大的来源是 **Mathematical Alphanumeric Symbols(数学字母数字符号)**区块。在数学中,字母的样式可以携带含义:粗体字母、手写体字母和双线体字母即使都像同一个拉丁字母,也可能表示不同类型的对象。
因此 Unicode 编码了多组数学字母:
- 粗体和斜体拉丁、希腊字母;
- 手写体和粗手写体;
- Fraktur 和粗 Fraktur;
- 双线体字母与数字;
- 无衬线和等宽数学字母。
这些字符的任务,是在纯文本公式里保存语义差异。Unicode 规范还明确提醒,不应把它们简单当作普通文章的排版样式。社交简介和昵称中的用法,是人们对技术字符集的创造性再利用,而不是它最初的设计目的。
为什么有些花体字母表会“缺字”?
仔细观察手写体或双线体字母表,你可能会发现少数字母的代码点不和其他字母待在一起。
ℂ、ℍ、ℕ、ℙ、ℚ、ℝ、ℤ 等字符,在完整数学字母表加入 Unicode 之前,就已经存在于较早的 **Letterlike Symbols(字母式符号)**区块中。Unicode 不会只为了让表格整齐而重复编码同一个字符,所以新的数学字母区块留下了一些空位,软件则回头使用旧代码点。
视觉上的字母表是连续的,代码点地址却不是。
其他“字体”样式使用了什么办法?
并不是每一种生成结果都来自数学字母:
Hello使用的是东亚计算环境遗留下来的全角兼容字符。ᴛɪɴʏ借用了国际音标字母和修饰字母,拼成近似的小型大写。Hₑₗₗₒ使用并不完整的下标字符集合。- 圆圈字和方框字来自带圈字母数字。
- 倒置文字会寻找外形像旋转拉丁字母的其他字符来代替。
这些字符集本来就不是完整的装饰字体。缺少某些字母、大小不一、平台支持不均,都是把不同用途的字符拼成视觉样式后产生的结果。
正规化可能让普通字母重新出现
Unicode 有几种正规化形式。兼容正规化 NFKC 或 NFKD,可以把许多数学字母、全角字符、带圈字符和上下标字符映射回较普通的等价形式。例如,软件应用 NFKC 后,𝐇 可能会变成 H。
这对搜索、比较、内容审核和安全处理很有帮助,也意味着某个平台完全可能把你粘贴的花体保存成较普通的版本。
实际使用要付出什么代价?
花体字确实是文字,但“是文字”并不保证它在任何地方都表现一致。
- 系统缺少合适字体时,字符可能显示成方框。
- 搜索和 @ 提及不一定把花体字母当成普通字母。
- 屏幕阅读器可能朗读冗长的 Unicode 名称,甚至逐字拼读。
- 用户名、网址和账号恢复信息会更难核对。
- 原本没有数学含义的内容可能被赋予了数学语义。
更稳妥的做法,是把花体用于简短、装饰性的展示文字。账号、链接、联系方式和重要说明仍使用普通字符。很多时候,“一个花体名字 + 一行普通文字解释”会比整段花体更好读。
最有用的理解方式是“替换”,不是“排版”:花体生成器改变的是你输入了哪些字符,而不是用哪个字体文件把它们画出来。