TextRenderer.测量文本和图形.度量字符串大小不匹配



这不是一个舍入问题。差异~ 5+像素

测试用例字符串:"MACD (26,12,9) -0.000016"

e.Graphics.MeasureString("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width)
TextRenderer.MeasureText("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width)
结果总是:
139.3942
134

为什么大小有这么大的差异?我只需要油漆方法外的字符串的宽度的圆。但是它应该匹配MeasureString,反之亦然

TextRenderer使用GDI来渲染文本,而Graphics使用GDI+。两者使用略微不同的方法来布局文本,因此大小不同。

您应该使用哪一个取决于最终将用于实际绘制文本的内容。如果你用GDI+ Graphics.DrawString画,用Graphics.MeasureString测量。如果您使用GDI TextRenderer.DrawText进行绘图,请使用TextRenderer.MeasureText进行测量。

如果文本将显示在Windows窗体控件中,如果UseCompatibleTextRendering设置为false(这是默认值),则使用TextRenderer

阅读你的问题的字里行间,你似乎在使用TextRenderer,因为你在Paint事件之外没有Graphics实例。如果是这种情况,您可以自己创建一个来进行测量:

using( Graphics g = someControl.CreateGraphics() )
{
    SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont);
}

如果您无法访问控件来创建图形实例,您可以使用此控件为屏幕创建一个,这对于测量目的来说很好。

using( Graphics g = Graphics.FromHwnd(IntPtr.Zero) )
{
     SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont);
}

我让下面的类在paint事件之外使用MeasureString,它工作得很好。

public interface ITextMeasurer
    {
        SizeF MeasureString(string text, Font font, StringFormat format);
    }
    public class TextMeasurer : ITextMeasurer
    {
        private readonly Image _fakeImage;
        private readonly Graphics _graphics;
        public TextMeasurer()
        {
            _fakeImage = new Bitmap(1, 1);
            _graphics = Graphics.FromImage(_fakeImage);
        }
        public SizeF MeasureString(string text, Font font, StringFormat format)
        {
            return _graphics.MeasureString(text, font, int.MaxValue, format);
        }
    }

最新更新