使用Delphi进行Unicode预编译和分解

时间:2011-08-21 07:18:40

标签: delphi svn unicode vcl delphi-xe2

Wikipedia entry for Subversion包含一个关于Unicode编码的不同方式问题的段落:

  

虽然Subversion将文件名存储为Unicode,但它没有指定是否   预复合或分解用于某些重音   字符(例如é)。因此,在运行的SVN客户端中添加的文件   某些操作系统(如OS X)使用分解编码,   而在其他操作系统(如Linux)上运行的客户端则使用   预编译编码,结果是那些重音   如果本地SVN客户端没有正确显示字符   使用与用于添加文件的客户端相同的编码

虽然这描述了Subversion客户端实现的一个特定问题,但我不确定基础Unicode组合问题是否也会出现在常规Delphi应用程序中。我想只有Delphi应用程序能够使用两种Unicode编码方式(可能在Delphi XE2中)时才会出现问题。如果是的话,Delphi的开发人员可以做些什么来避免它呢?

3 个答案:

答案 0 :(得分:6)

有一个小的显示问题,因为在Windows上使用的许多字体都不会以理想的方式呈现分解的形式,通过使用字母和变音符号的组合字形。相反,它回退到渲染字母,而不是将独立的变音标记覆盖在顶部,这通常会导致视觉上不那么令人愉悦,可能是不平衡的字形。

然而,这不是wiki引用的Subversion错误所引发的问题。检查包含组合或分解字符序列的SVN的文件名实际上是完全正确的; SVN既不知道也不关心组合,它只是按原样使用Unicode代码点。只要后端文件系统将文件名保留为与它们放入的状态相同的状态,一切都很好。

Windows和Linux都有文件系统,它们对组合同样无视。不幸的是,Mac OS X没有。在存储传入文件名之前,HFS +和UFS文件系统都会对分解形式执行“规范化”,因此您获取的文件名不一定与您输入的Unicode代码点序列相同。

正是这种[IMO:疯狂]行为混淆了SVN和许多其他程序 - 在OS X上运行时。由于Apple碰巧选择分解(NFD)作为其标准化形式,因此特别容易咬人,而大多数世界其他地方使用组合(NFC)字符。

(它甚至不是真正的NFD,而是一种不兼容Apple的变种。欢乐。)

应对此问题的最佳方法是,如果可以的话,永远不要依赖存储在其中的确切文件名。如果您只读取给定名称的文件,那很好,因为它将被标准化以匹配当时的文件系统。但是,如果您正在阅读目录列表并尝试将您在其中找到的文件名与您期望的文件名匹配 - 这正是Subversion所做的 - 您将会遇到不匹配。

为了可靠地进行文件名匹配,您必须检测到您在OS X上运行,并在进行比较之前手动将文件名和字符串规范化为某种正常形式(NFC或NFD)。您不应该在将这两种形式视为不同的其他操作系统上执行此操作。

答案 1 :(得分:1)

AFAICT,两种编码在显示时应该产生相同的结果,并且两者都是有效的Unicode,所以我不太明白那里的问题。如果遇到分解,显示例程应该能够处理。代码点é应按原样显示,而应仅在分解模式下显示为é

问题不是显示,IMO,它是比较,要么是相等的(如果两者都使用不同的编码则失败)或词法,即用于排序。正如大卫所说,这就是人们应该将其归一化为一种编码的原因。这样就不再有任何歧义了。

答案 2 :(得分:0)

任何处理文本的应用程序都可能出现同样的问题。如何避免它取决于应用程序正在执行什么操作,问题缺少具体细节。大多数情况下,我认为你通过规范化文本来解决这些问题。这涉及在遇到编码模糊时使用单个首选表示。