我有一个可以进行文本渲染的c#应用程序,这与一个简单的所见即所得文本编辑器不相上下。
我使用TextRenderer.DrawText将文本呈现到屏幕上,使用GetTextExtentPoint32测量文本,这样我就可以在同一行上定位不同的字体样式/大小。
在Vista中,这一切都运行得很好。然而,在XP中,Arial的渲染方式不同,某些字符,如'o‘和'b’,比在Vista中占据了更大的宽度。GetTextExtentPoint32似乎像在Vista中一样测量字符串,但宽度更小。最终的结果是,每隔一段时间,一串文本就会与其前面的文本重叠,因为前面的文本会被测量为比屏幕上实际显示的文本小。
此外,我的文本渲染代码完全模仿了ie的文本渲染(仅限于简单的格式和英语),而且ie文本渲染在vista和xp之间似乎是一致的--这就是我注意到不同字符大小变化的原因。
有谁知道是怎么回事吗?
简而言之,TextRenderer.DrawText和GetTextExtentPoint32在xp for Arial中并不匹配。DrawText似乎比Vista中绘制的某些字符更大和/或更小,但GetTextExtentPoint32似乎像在Vista中一样测量文本(这似乎与在xp和vista上ie中的文本渲染相匹配)。希望这是有意义的。
注:不幸的是,TextRenderer.MeasureString的速度或准确性不足以满足我的需求。我试着用它,但不得不把它拔出来。
发布于 2010-04-08 20:22:57
感谢你抽出时间回复我,阿德里安。
我的理解是,TextRenderer.DrawText实际上包装了对GDI的调用,完全绕过了GDI+文本呈现。这就是为什么我对GetTextExtentPoint32没有欺骗输出感到困惑的原因。
我想我找到了问题所在。事实证明,如果您将System.Drawing.Text.TextRenderingHint.ClearTypeGridFit,或其他值设置为Graphics.TextRenderingHint,则会导致某些字体中的某些字符增大或减小大小。这似乎在XP中比在Vista中更真实。我还没有在Vista中看到过这种情况。无论如何,看起来GetTextExtentPoint32要么无法识别差异,要么我在进行调用时没有设置某种标志。
我的解决方案是只使用系统默认的textrenderinghint设置。
发布于 2010-04-09 12:08:50
实际上,文本渲染器的DrawText和MeasureString都是基于DrawTextEx的(这是User32,而不是Gdi函数)。因此,您可以考虑使用对此函数的本机编组调用,而不是MeauseString,因为它会执行一些额外的计算(特别是当您使用不带HDC的函数覆盖时)。
另外,也许这个post也会对你有帮助。
发布于 2010-04-08 19:36:43
我不是C#爱好者,但我相信.NET渲染是建立在GDI+之上的。我也很确定GDI+会使用不加提示的缩放来进行自己的字体渲染。
另一方面,GetTextExtentPoint32
是GDI的一部分。GDI使用大小调整提示,这可能会影响字符的宽度,具体取决于字体大小。通常情况下,小尺寸的GDI文本看起来会有一点吸气,但它不会线性缩放。
你必须始终如一地使用一种或另一种模型来获得像素完美的结果。
可能还有其他因素在起作用,使得这一点在XP上比在Vista上更明显,但根本问题都存在于两者中。这些其他因素可能包括DPI设置、DPI缩放、ClearType或抗锯齿设置、字体链接(如果您正在混合其他字母表中的脚本)、字体替换(尤其是在打印中),甚至可能是不同版本的Arial。我甚至不确定GDI+是否使用与GDI相同的默认映射模式。
https://stackoverflow.com/questions/2597971
复制