如何在复杂脚本中获取上下文形状输入的字符?

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

想象一下,您需要在文本框中输入用户的确切字符,默认情况下,当您将String转换为CharArray时,它会将每个字符转换为隔离格式。

(因为当用户通过键盘输入字符时,它处于隔离状态,当它在屏幕上显示时,它将被转换为正确的格式;这只是猜测。因为如果你使用确切的字符代码来创建字符串,它会生成正确的数组)。

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

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

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

  • 更多Uniscribe之谜 (解释字形与字符之间的差异)
  • 微软Bhasha,字形处理: Uniscribe
  • MSDN: 复杂的脚本意识
  • 埋藏在Mozilla代码中的代码是使用Uniscribe 处理复杂脚本呈现的代码 。 还有其他代码可以扫描系统中的字体列表并读取每种字体的cmap表 。 (来自http://www.siao2.com/2005/12/06/500485.aspx的评论)。
  • 整理出来: 他说塑造了吗? 它不在剧本中!

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; } 

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

考虑到混淆的可能性,我想我想要将这些字符串保存在资源中,或者使用unicode转义硬编码:

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

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

这是一个疯狂的猜测,但String.Normalize()在这里有帮助吗? 我不清楚这是否仅涵盖了人物构成或是否包括位置forms。