为什么 Unicode 有「私用区字符不会在无此字体其他电脑上显示」的规定?

  • ~2.82K 字
  1. 1. 电脑是怎么渲染字符的
    1. 1.1. 存储:Unicode
    2. 1.2. 显示:字体渲染引擎
  2. 2. 理解私用区
  3. 3. 私用区的应用
    1. 3.1. Apple 标志
    2. 3.2. Fira Code 字体
    3. 3.3. Twitter 的 Chirp 字体
  4. 4. 题外话

题目描述:

也就是说,例如私用区的生造汉字、符号等,仅自己电脑能显示,其他电脑如果不装载此私用区就无法显示,是技术不足,还是另有隐情?

原文链接:https://www.zhihu.com/question/12008172105/answer/1971686708467728921


从题主的问法可以看出来,题主对 Unicode 只是略有了解。我企图通过这个回答,来简述一些计算机字符渲染原理的基础知识。

要回答这个问题,首先要明确一点,就是「私用区字符不会在无此字体其他电脑上显示」这个问题,Unicode 不背锅。

要理解这一点,先要理解电脑是怎么渲染字符的。

电脑是怎么渲染字符的

存储:Unicode

高中信息技术课老师一定强调过,在计算机内部,所有数据都是以二进制存储的,所以你在知乎上看到的每个字,在计算机内部都是 0 和 1 的排列。

例如,题主昵称中的「稻」在以 UTF-8 编码的情况下就表示为 1110 0111 1010 1000 1011 1011。8 位二进制是 1 个字节,「稻」字占用了 3 个字节。

实际上,UTF-8 编码中有些部分是填充格式用的,计算机读到这种格式就知道这是一个 Unicode 字符。这里不展开讲,总之有用的部分我已经加粗标出,它是 0111 1010 0011 1011。

因为 4 位二进制恰好是 1 位 16 进制,人们常常也用 16 进制来表示二进制内容。再加上前缀「U+」表明这是一个 Unicode 码位,就是通行的表示 Unicode 码位的方式:U+7A3B。

显示:字体渲染引擎

电脑的操作系统得到 7A3B 这个码位之后,并不能直接把码位给你,因为你并不认识这个码位对应的是什么字,更别说目测二进制了。

操作系统中的字体渲染引擎会在用户指定的或系统安装的所有字体中找到提供这个码位的合适的字体,从中提取出字形数据。字形数据储存了一个字符「应该长什么样」,如果字体中有这个字形,字体渲染引擎会把它渲染在屏幕上,你才能看到对应的字。


总之,Unicode 只规定码位应当是什么,例如 U+7A3B 是「稻」字;而字体文件才负责规定「稻」字长什么样。对于私用区字符,因为 Unicode 里面根本没有规定具体的实现,自然就是各个字体随意发挥。事实上,如果有哪款不符合规范的字体把「稻」做成别的字形,或者根本不做「稻」字,题主的昵称就会得到私用区字符的待遇。

理解私用区

在 Unicode 中,私人使用区(英语:Private Use Areas,PUA)指其解释未在 Unicode 标准中指定,而是由合作用户之间的私人协议决定其用途的一系列码位。目前定义了三个私人使用区:一个在基本多语言平面(U+E000-U+F8FF)中,另外两个几乎包含了整个第 15 和第 16 平面(分别为 U+F0000-U+FFFFD,U+100000-U+10FFFD)。

(摘自 https://zh.wikipedia.org/wiki/私人使用区)

总之,私用区就是一块预留的区域,字体制作者可以按喜好去使用,在不同的字体中自由分配,Unicode 也不管辖它具体是什么用途。

根据我推测的题主的喜好,我做如下不太恰当的比喻:如果把每套字体当作不同玩家的原神世界,各国(平面)的地图(字符集)已经被米哈游(Unicode 协会)安排好了用处,但留出了尘歌壶(私用区)。而每个玩家可以自由安排尘歌壶世界,并不受到米哈游的制约。因为每个玩家的尘歌壶世界(不同字体的私用区)各有千秋,所以尘歌壶中每个坐标(码位)放置的东西也不同。当不同的玩家在各自不同的尘歌壶世界中位于同一坐标(不同字体调用同一码位),所看到的东西(字符)也不能保证是一样的。

考虑到私用区很大,而且和字体绑定,所以它被使用得不多,一般字体中私用区码位的内容都是空的,才有了题主所见的「私用区字符不会在无此字体其他电脑上显示」这一情况。如果恰好两款字体都使用的私用区的同一码位,也是被允许的情况,此时用户就会看到张冠李戴的效果了。

这是 Unicode 刻意留出的自由,允许组织在不申请官方编号的前提下进行内部编码。而代价就是私用区字符的字形必须随字体文件一起分发和安装,否则就没法正常显示了。

私用区的应用

使用私用区字符大都是为了在不干扰标准编码的前提下,插入自定义符号或图形。

因为不知道题主是在哪里看到这句话的,我不能针对性地解释,所以我在下面举出其他例子,供后来者参考。

Apple 标志

在 Apple 设备上,「」(U+F8FF)会显示成苹果标志。如果 Apple 产品的用户在文档中输入这个字符,并发送给一个没有安装 Apple 系统的用户时,接收方电脑的字体文件没有 U+F8FF 这个码位,就无法显示,在一些较老的设备上似乎会显示为藏文字符。

Fira Code 字体

在广受欢迎的编程字体 Fira Code 中,就有私用区字符:

Fira Code is the first programming font to offer dedicated glyphs to render progress bars:

Fira Code 是首款提供专用字形来渲染进度条的编程字体:

Fira Code progress bar

In action:

Fira Code progress bar animated

We hope more programming fonts will adopt this convention and ship their own versions.

我们希望更多编程字体能够采用这种规范,并发布自己的版本。

(摘自 https://github.com/tonsky/FiraCode)

可以看到,Fira Code 漂亮的进度条就是通过在私用区的 U+EE00-U+EE0B 码位放置符号来达成的。

Twitter 的 Chirp 字体

又如,字符「」(U+EA00)位于私用区,在 Twitter 上会显示成漂亮的推特小鸟标志,这是因为它被包括在 Twitter 官方客户端所使用的 Chirp 字体中。如果通过一些不带 Chirp 字体的第三方客户端去查看,就看不到了,这是因为系统默认字体往往在 U+EA00 处没有对应的字形。顺便一提,Chirp 字体可以支持显示 Apple 标志,这也是私用区字符与字体相关的好处,安装了相应的字体就能显示。


题外话

知乎推给我这个题,我其实是不想答的,因为显然其他答主能回答得更好,我算是鲁班门前弄大斧。但我翻了一下回答,看到多数回答都在阴阳怪气,终究还是忍不住了。浅答一下,也算整理整理自己关于 Unicode 的知识,还请其他答主海涵,友好交流,有问题请指出。

从本题的其他回答也能看出,知乎的环境正在变得越来越差。这其实是很好的一道题,其他回答不懂装懂还乱比喻,不知道在阴阳怪气什么。

分享这一刻
让朋友们也来瞅瞅!