代理项和增补字符

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 引入了对基本输入、输出和简单补充字符排序的支持。 但是,并非所有系统组件都与补充字符兼容。

 

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

  • OpenType 字体 cmap 表的格式 12 直接支持 4 字节字符代码。 有关详细信息,请参阅 OpenType 字体规范
  • Windows支持启用代理项的输入法编辑器 (IME)
  • Windows GDI API 支持字体格式 12 cmap 表,以便可以正确显示代理项。
  • Uniscribe API 支持补充字符。
  • Windows控件(包括“编辑”和“富编辑”)支持补充字符。
  • HTML 引擎支持包含用于显示的补充字符、通过 Outlook Express) 编辑 (以及表单提交的 HTML 页面。
  • 操作系统排序表支持补充字符。

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

UTF-16 将补充字符作为代理项对处理。 操作系统处理代理项配对与处理非同步标记的方式类似。 在显示时,代理项配对通过 Uniscribe 显示为一个字形,由 Unicode 标准规定。

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

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

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

由于表示补充字符的代理项机制定义良好,因此应用程序可以包含用于处理 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]

字符集