我们需要:
在WinForms应用程序中,该应用程序也将图形和图像渲染到相同的图形上下文。
我们遇到过四种技术。我们尝试使用前两个,并在几个月的时间内遇到了所描述的问题。
据称独立于决议的文本。但是根据this question和其他来源 - 由于质量问题,应该避免使用这项技术。
MSDN表示调用Graphics.MeasureString以及StringFormat.GenericTypographic
和TextRenderingHint.AntiAlias
会产生准确的字符串测量。但是,根据我们和其他人的经验,情况并非如此 - 我们没有得到准确的字符串测量。
结果:由于字符串测量不准确而无法使用。
这是为了克服GDI +的局限性而引入的。然而,这引入了自己的局限性:
结果:由于这些原因不可用
致电GetTextExtentExPoint
进行文字测量,并DrawText
/ DrawTextEx
/ ExtTextOut
进行渲染。
我们还没有尝试过。
这看起来很有希望,因为它可以与其他技术(包括GDI / GDI +)互操作,所以我们的其他图形渲染可能不会改变。但是,它仅适用于Windows Vista和更新的Windows版本。这是目前的问题,因为Windows XP仍然具有重要的安装基础。
根据要求,哪些技术可以使用?
注意:关于这个话题有很多错误的信息,所以请在这个领域有专业知识的情况下回答这个问题。 另外,请不要建议WPF - 这不是我们正在考虑使用的东西。
答案 0 :(得分:4)
据推测,MeasureCharacterRanges
功能比MeasureString
更准确。
答案 1 :(得分:3)
如果您必须同时定位屏幕和打印机,那么在决定使用哪个渲染引擎之前,您需要对您的方法做出一些决定。以下是一些可能性:
在所有情况下,最佳可能的近似可能是通过每一步的非常仔细的近似来完成的,这可以为每个设备提供最高的保真度,但代价是匹配的准确性,或者您可以渲染到位图并缩放到设备,它提供较低的保真度,但最好的近似其他空间。
我用GDI完成了核心打印预览。这很难,但可以进行常规布局。但如果你正在处理任意变换,尤其是+/- 90度以外的旋转,那几乎是不可能的。
很容易犯下微妙的错误,并相信你得到的测量结果是错误的。
当笔划宽度与dpi处于同一数量级时,字体提示会使字体缩放变为非线性,因此如果某些文本的宽度为w
,则双倍宽度字体的大小可能不完全是2*w
。
字体替换在许多打印机驱动程序中很常见。即使您选择TrueType或OpenType字体,您也可能不在打印机上获得与屏幕上相同的字体。
非方形像素在某些打印机中很常见。当你做的不是轴对齐的事情时,这些甚至可能会破坏正常的光栅化器。
Kerning可能会令人惊讶。不要假设宽度('a')+宽度('b')==宽度(“ab”)。
很容易实现舍入错误。有时你必须知道底层光栅化器使用的舍入规则。
在错误的环境中进行测量太常见了。不要尝试在屏幕上下文中进行测量并应用转换来获取打印机单元。如果您需要打印机单元,请在打印机上下文中进行测量。
我今天的观点是,如果您只需要打印预览,那么您应该在打印机单元中布局一个尺寸适合页面的位图,并根据DPI的比例将位图缩放到屏幕。这是最简单的事情,它会产生很好的效果。但目前尚不清楚一个好的硬拷贝和打印预览是否真的是你所追求的。
答案 2 :(得分:3)
我有类似的要求,并遇到了与文本渲染和缩放相同的问题。由于许多原因,即使我尝试使用WPF(.NET 3.5)也是一场噩梦。
我最终使用GDI + graphics.DrawString
,尽管被“弃用”,但却有一个有趣的技巧来获得准确的文本测量。
static public RectangleF MeasureInkBox(Graphics graphics, string text, Font font)
{
var bounds = new RectangleF();
using (var textPath = new GraphicsPath())
{
textPath.AddString(
text,
font.FontFamily,
(int)font.Style,
font.Size,
new PointF(0, 0),
StringFormat.GenericTypographic );
bounds = textPath.GetBounds();
}
return bounds;
}
速度和质量令人满意。此外,graphics.DrawString
是使用winforms打印文本的推荐方法。
由于字距调整,测量单个字符位置可能会非常棘手,但我想这个方法稍微复杂一点就可以完成这项工作。例如,对于“Hello”,它将测量“H”,然后是“He”,然后是Hel“,依此类推。它不应该显着降低性能,特别是如果你在接收单击单词时飞行它。” / p>