我在 C# 中使用 StringBuilder 附加一些文本,可以是英语(从左到右)或阿拉伯语(从右到左)
stringBuilder.Append("(");
stringBuilder.Append(text);
stringBuilder.Append(") ");
stringBuilder.Append(text);
如果 text = "A",则输出为 "(A) A"
但如果 text = "بتث",则输出为 "(بتث) بتث"
有任何想法吗?
我在 C# 中使用 StringBuilder 附加一些文本,可以是英语(从左到右)或阿拉伯语(从右到左)
stringBuilder.Append("(");
stringBuilder.Append(text);
stringBuilder.Append(") ");
stringBuilder.Append(text);
如果 text = "A",则输出为 "(A) A"
但如果 text = "بتث",则输出为 "(بتث) بتث"
有任何想法吗?
当被要求渲染从右到左的文本、阿拉伯语或希伯来语时,这是 Windows 文本渲染引擎中的一个众所周知的缺陷。它有一个难以解决的问题,当语言中没有好的替代词可用时,人们往往会求助于西方单词和标点符号。例如品牌和公司名称。渲染器试图通过查看代码点来猜测正确的渲染顺序,拉丁字符集中的字符显然必须从左到右渲染。
但它在标点符号上摸索,括号是最明显的。您必须明确说明它知道要做什么,您必须使用 Unicode 从右到左标记,U+200F
或\u200f
在 C# 代码中。相反,如果您知道需要 LTR 渲染,请使用从左到右标记,U+200E
.
使用AppendFormat
而不是仅仅Append
:
stringBuilder.AppendFormat("({0}) {0}", text)
这可能会解决问题,但它可能 - 您需要查看text
值 - 它可能嵌入了 LTR/RTL 标记字符。这些需要在值中删除或更正。
我有一个类似的问题,我设法通过创建一个检查 Unicode 中每个 Char 的函数来解决它。如果它来自页面 FE,那么我在其后添加 202C,如下所示。没有这个,它会根据我的需要混合 RTL 和 LTF。
string us = string.Format("\uFE9E\u202C\uFE98\u202C\uFEB8\u202C\uFEC6\u202C\uFEEB\u202C\u0020\u0660\u0662\u0664\u0668 Aa1");