6

我有执行文本渲染的 ac# 应用程序,与简单的所见即所得文本编辑器相当。

我正在使用 TextRenderer.DrawText 将文本呈现到屏幕上,并使用 GetTextExtentPoint32 来测量文本,以便我可以在同一行上放置不同的字体样式/大小。

在 Vista 中,这一切都很好。然而,在 XP 中,Arial 的呈现方式有所不同,某些字符(如 'o' 和 'b')比 Vista 中占用更多的宽度。GetTextExtentPoint32 似乎像在 Vista 中一样测量字符串,但宽度更小。最终结果是,由于前面的文本被测量为小于屏幕上的实际大小,因此不时会出现一行文本与其前面的文本重叠。

此外,我的文本渲染代码完全模仿了 ie 的文本渲染(仅用于简单格式和英语语言),并且 ie 文本渲染似乎在 vista 和 xp 之间是一致的——这就是我注意到不同字符大小变化的方式。

有人对发生的事情有任何想法吗?

简而言之,TextRenderer.DrawText 和 GetTextExtentPoint32 在 xp 中与 Arial 不匹配。DrawText 似乎比在 Vista 中绘制的某些字符更大和/或更小,但 GetTextExtentPoint32 似乎正在像在 Vista 中一样测量文本(这似乎与 xp 和 vista 上的 ie 中的文本呈现相匹配)。希望这是有道理的。

注意:不幸的是 TextRenderer.MeasureString 不够快或不够准确,无法满足我的要求。我试过用它,不得不把它撕掉。

4

3 回答 3

2

感谢您抽出宝贵时间回复阿德里安。

我的理解是 TextRenderer.DrawText 实际上包装了对 GDI 的调用,完全绕过了 GDI+ 文本渲染。这就是为什么我对 GetTextExtentPoint32 与输出不一致感到困惑的原因。

我想我发现了这个问题。事实证明,如果将 Graphics.TextRenderingHint 设置为 System.Drawing.Text.TextRenderingHint.ClearTypeGridFit 或其他值,它会导致某些字体中的某些字符大小增加或减小。这在 XP 中似乎比在 Vista 中更真实。我还没有看到它在Vista中发生。无论如何,看起来 GetTextExtentPoint32 要么无法识别差异,要么我在拨打电话时没有设置某种标志。

我的解决方案是只使用系统默认的 textrenderinghint 设置。

于 2010-04-08T20:22:57.457 回答
1

实际上,TextRenderer 的 DrawText 和 MeasureString 都是基于DrawTextEx(这是 User32,而不是 Gdi 函数)。因此,您可以考虑使用本机编组调用此函数而不是 MeauseString,因为它会执行一些额外的计算(特别是如果您使用没有 HDC 的函数覆盖)。

另外,也许这篇文章对您也有帮助。

于 2010-04-09T12:08:49.927 回答
0

我不是 C# 人,但我相信 .NET 渲染是建立在 GDI+ 之上的。我也很确定 GDI+ 会进行自己的字体渲染,它使用无提示的缩放。

GetTextExtentPoint32另一方面,它是 GDI 的一部分。GDI 使用大小提示,它会根据字体大小影响字符的宽度。一般而言,小尺寸的 GDI 文本看起来会有点吸引人,但它不会线性缩放。

您必须始终使用一种或另一种模型才能获得像素完美的结果。

可能还有其他因素在起作用,这在 XP 上比在 Vista 上更明显,但两者都存在根本问题。这些其他因素可能包括 DPI 设置、DPI 缩放、ClearType 或抗锯齿设置、字体链接(如果您正在混合来自其他字母的脚本)、字体替换(尤其是在打印中),甚至可能是不同版本的 Arial。我什至不确定 GDI+ 是否使用与 GDI 相同的默认映射模式。

另请参阅我对打印预览的回答

于 2010-04-08T19:36:42.560 回答