2

在某些RightToLeft语言(如阿拉伯语、波斯语、乌尔都语等)中,每个字母可以有不同的形状。有孤立形式、初始形式和中间形式(您可以在任何 unicode 字体的窗口的字符映射表上找到它)。

假设您需要用户在文本框中输入的确切字符,默认情况下,当您将 String 转换为 CharArray 时,它会将每个字符转换为独立形式。

(因为当用户通过键盘输入字符时,它是孤立的形式,当它显示在屏幕上时,它会被转换为正确的格式;这只是一个猜测。因为如果你使用精确的字符代码来制作字符串,它将生成正确的数组)。

我的问题是,我们如何获得字符串的形式,即文本框中显示的形式。

如果.NET 中没有办法,那么这意味着我需要创建自己的类来转换这个 T_T

4

3 回答 3

3

Windows 使用Uniscribe为复杂的脚本执行上下文调整(可以应用于l-to-r以及r-to-l语言)。文本框中显示的文本基于字符输入 Uniscribe 后的字形信息。尽管 Unicode 标准为字符的每个孤立形式、初始形式、中间形式和最终形式定义了代码点,但并非所有字体都必须支持它们,但它们可能具有预成形字形或使用字形组合——Uniscribe 使用来自Windows 语言包,用于根据字体的 cmap 确定要使用的字形。以下是一些相关链接:

TextRenderer .DrawText ()方法通过 Win32 DrawTextExW()函数使用 Uniscribe,使用以下 P/Invoke:

[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern int DrawTextExW( HandleRef hDC
                                     ,string lpszString
                                     ,int nCount
                                     ,ref RECT lpRect
                                     ,int nFormat
                                     ,[In, Out] DRAWTEXTPARAMS lpDTParams);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
 {
   public int left;
   public int top;
   public int right;
   public int bottom;
 }

[StructLayout(LayoutKind.Sequential)]
public class DRAWTEXTPARAMS
{
  public int iTabLength;
  public int iLeftMargin;
  public int iRightMargin;
  public int uiLengthDrawn;
}
于 2009-07-23T07:08:02.097 回答
0

那么你是如何创建“错误”的字符串的呢?如果您只是将其放在字符串文字中,那么很可能只是输入法错误。如果在显示后复制“正确”字符串,然后将其粘贴到字符串文字中,会发生什么?您可能还想检查 Visual Studio 对源文件使用的编码。如果您没有将字符串作为文字放入源代码中,您将如何创建它?

考虑到混淆的可能性,我想要么将这些字符串保留在资源中,要么使用 unicode 转义对它们进行硬编码:

string text = "\ufb64\ufea0\ufe91\ufeea";

(然后可能会在之后发表评论,显示未转义的值;至少如果看起来正确,它不会误导。诚然,这两者很容易不同步......)

于 2009-07-23T05:23:36.737 回答
0

这有点疯狂,但 String.Normalize() 在这里有帮助吗?我不清楚这是否仅涵盖角色构成,或者是否还包括位置形式。

于 2009-07-23T06:27:57.463 回答