代理项和增补字符

Windows 应用程序通常使用 UTF-16 来表示 Unicode 字符数据。 使用 16 位允许直接表示 65,536 个唯一字符,但此基本多语言平面 (BMP) 几乎不足以涵盖人类语言中使用的所有符号。 Unicode 版本 4.1 包含超过 97,000 个字符,仅中文就包含超过 70,000 个字符。

Unicode 标准已建立 16 个额外的“平面”字符,每个“平面”的大小与 BMP 相同。 当然,BMP 以外的大多数码位尚未为其分配字符,但平面的定义使 Unicode 有可能定义 1,114,112 个字符 (即,在代码点 U+0000 到 U+10FFFF 范围内的 216 * 17 个字符) 。 为使 UTF-16 表示这一更大的字符集,Unicode 标准定义了“补充字符”。

关于补充字符

补充字符是位于 BMP 之外的字符,“代理项”是 UTF-16 代码值。 对于 UTF-16,需要“代理项对”来表示单个补充字符。 第一个 (高) 代理项是 U+D800 到 U+DBFF 范围内的 16 位代码值。 第二 (低) 代理项是 U+DC00 到 U+DFFF 范围内的 16 位代码值。 使用代理项机制,UTF-16 可以支持所有 1,114,112 个潜在的 Unicode 字符。 有关补充字符、代理项和代理项对的更多详细信息,请参阅 Unicode 标准

注意

Windows 2000 引入了对补充字符的基本输入、输出和简单排序的支持。 但是,并非所有系统组件都与补充字符兼容。

 

操作系统通过以下方式支持补充字符:

使用补充字符进行软件开发的一般准则

UTF-16 将补充字符作为代理项对进行处理。 操作系统处理代理项对的方式与处理 非速度标记的方式类似。 在显示时,代理项对通过 Uniscribe 显示为一个字形,如 Unicode Standard 规定。

Windows Vista 引入了三个新宏,以帮助识别 UTF-16 字符串中的代理项和代理项对。 它们是 IS_HIGH_SURROGATEIS_LOW_SURROGATEIS_SURROGATE_PAIR

如果应用程序支持 Unicode 并使用系统控件和标准 API 函数(如 ExtTextOutDrawText),则应用程序会自动支持补充字符。 因此,如果应用程序使用标准系统控件或使用常规 ExtTextOut 类型调用来显示,则补充字符应该无需任何特殊编码即可工作。

通过以自定义方式确定字形位置来实现自己的编辑支持的应用程序可以使用 Uniscribe 进行所有文本处理。 Uniscribe 具有单独的功能来处理复杂的脚本处理,例如文本显示、命中测试和光标移动。 应用程序必须专门调用 Uniscribe 函数才能获取这些高级功能。 请注意,使用 Uniscribe 函数的应用程序是完全多语言的,但这会增加性能损失。 因此,某些应用程序应自行处理补充字符。

由于用于表示补充字符的代理机制已明确定义,因此应用程序可以包含用于处理 UTF-16 代理文本处理的代码。 当应用程序遇到从较低保留代理项范围 (低代理项) 或高代理项 (高代理项) 的较高保留代理项范围中分离的 UTF-16 值时,该值必须是代理项对的一半。 因此,应用程序可以通过执行简单的范围检查来检测代理项对。 如果它在较低或较高范围内遇到 UTF-16 值,则必须向后或向前跟踪一个 16 位宽度才能获取字符的其余部分。 编写应用程序时,请记住 ,CharNextCharPrev 移动 16 位码位,而不是代理项对。

注意

独立代理项码位具有高代理项,而没有相邻的低代理项,反之亦然。 这些代码点无效,不受支持。 其行为未定义。

 

如果你正在开发字体或 IME 提供程序,请注意,Windows XP 之前的操作系统默认禁用补充字符支持。 默认情况下,Windows XP 和更高版本启用补充字符。 如果提供需要补充字符的字体和 IME 包,则应用程序必须设置以下注册表值:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\LanguagePack]
SURROGATE=(REG_DWORD)0x00000002

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\International\Scripts\42]
IEFixedFontName=[Surrogate Font Face Name]
IEPropFontName=[Surrogate Font Face Name]

字符集