.net TextRenderer.MeasureText似乎会增大字体大小

.net TextRenderer.MeasureText似乎会增大字体大小,.net,.net,据我所知,当您使用TextRenderer.MeasureText查找字符宽度时,在我的情况下,如果是固定宽度CourierNew字符,当字体大小有十进制分量时,我会得到奇怪的结果,例如11.3而不是11.0或12.0 乙二醇 (我对长字符串的长度求平均值,以考虑填充。) 结果 emSize = 11.0 -> width = 9.008 emSize = 12.0 -> width = 10.008 emSize = 11.3 -> width = 10.008 emSize

据我所知,当您使用
TextRenderer.MeasureText
查找字符宽度时,在我的情况下,如果是固定宽度
CourierNew
字符,当字体大小有十进制分量时,我会得到奇怪的结果,例如11.3而不是11.0或12.0

乙二醇

(我对长字符串的长度求平均值,以考虑填充。)

结果

emSize = 11.0 -> width = 9.008
emSize = 12.0 -> width = 10.008
emSize = 11.3 -> width = 10.008
emSize = 11.7 -> width = 10.008

我是否做错了什么,或者这是预期的行为?

textrender.MeasureText()
返回的值唯一相关的事情是,当文本由
textrender.DrawText()呈现时,了解文本大小。因此,真正的问题是:
MeasureText()
返回的大小是否与调用
DrawText()
方法时发生的情况相匹配。事实上,他们做到了:

上面是一个简单程序(下面的代码)的输出,该程序以四种不同的字体大小以四种不同的方式呈现一个十位数的示例字符串。前两组使用
TextRenderer.DrawText()
渲染,而后两组使用
Graphics.DrawString()
渲染

请注意,当使用
TextRenderer
时,四种大小中的三种渲染完全相同。所以,当然,当你测量文本时,测量的宽度也会完全相同

对于使用的两种渲染方法中的每一种,渲染实际上都会执行两次,一次使用
图形
对象的默认设置,然后再次使用
图形.textrendinghint
设置为
抗锯齿
。有趣的是,至少在我的计算机上,设置
AntiAlias
会使
TextRenderer
输出看起来更好,而使用
Graphics.DrawString()
方法会使输出看起来更差(事实上,当设置为
SystemDefault
的默认值时,它看起来很像
TextRenderer
输出)

但更重要的是,请注意,
TextRenderer
不使用分数字体大小进行缩放,而
Graphics.DrawString()
则使用分数字体大小进行缩放。这两种渲染方法根本不同。如果要使用分数字体大小,则需要使用支持分数字体大小的渲染方法。而
textrender
不是这样


代码示例:
在Visual Studio中全新的Windows窗体项目中,您可以将这些成员添加到
Form1
类中,以生成上述输出:

private readonly IReadOnlyList<float> _emSizes = new[] { 11.0f, 11.3f, 11.7f, 12.0f };
private const string _text = "0123456789";

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    int y = _DrawTextExamples(e.Graphics, _text, 0, _emSizes) + 10;

    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    y = _DrawTextExamples(e.Graphics, _text, y, _emSizes) + 10;
    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
    y = _DrawTextExamplesWithDrawString(e.Graphics, _text, y, _emSizes) + 10;
    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    y = _DrawTextExamplesWithDrawString(e.Graphics, _text, y, _emSizes) + 10;
}

private int _DrawTextExamples(Graphics g, string text, int y, IReadOnlyList<float> emSizes)
{
    Point pt = new Point(0, y);

    foreach (float emSize in emSizes)
    {
        using (Font font = new Font("Courier New", emSize))
        {
            Size size = TextRenderer.MeasureText(g, text, font);
            TextRenderer.DrawText(g, text, font, pt, Color.Black);
            pt.X += size.Width + 20;
            TextRenderer.DrawText(g, $"emSize: {emSize}, width: {size.Width}", font, pt, Color.Black);
            pt = new Point(0, pt.Y + size.Height);
        }
    }

    return pt.Y;
}

private int _DrawTextExamplesWithDrawString(Graphics g, string text, int y, IReadOnlyList<float> emSizes)
{
    PointF pt = new Point(0, y);

    foreach (float emSize in emSizes)
    {
        using (Font font = new Font("Courier New", emSize))
        {
            SizeF size = g.MeasureString(text, font);
            g.DrawString(text, font, Brushes.Black, pt);
            pt.X += size.Width + 20;
            g.DrawString($"emSize: {emSize}, width: {size.Width}", font, Brushes.Black, pt);
            pt = new PointF(0, pt.Y + size.Height);
        }
    }

    return (int)pt.Y + 1;
}
private readonly-IReadOnlyList\u emsize=new[]{11.0f、11.3f、11.7f、12.0f};
私有常量字符串_text=“0123456789”;
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
基础漆(e);
int y=_DrawTextExamples(如图形、文字、0、_emSizes)+10;
e、 Graphics.TextRenderingHint=System.Drawing.Text.TextRenderingHint.AntiAlias;
y=_DrawTextExamples(如图形、文字、y、emSizes)+10;
e、 Graphics.TextRenderingHint=System.Drawing.Text.TextRenderingHint.SystemDefault;
y=\u DrawTextExamplesWithDrawString(例如图形、\u文本、y、\u emSizes)+10;
e、 Graphics.TextRenderingHint=System.Drawing.Text.TextRenderingHint.AntiAlias;
y=\u DrawTextExamplesWithDrawString(例如图形、\u文本、y、\u emSizes)+10;
}
private int\u DrawTextExamples(图形g、字符串文本、int y、IReadOnlyList emSizes)
{
点pt=新点(0,y);
foreach(emSizes中的浮动emSize)
{
使用(字体=新字体(“Courier new”,emSize))
{
Size Size=TextRenderer.MeasureText(g,text,font);
DrawText(g,text,font,pt,Color.Black);
pt.X+=尺寸宽度+20;
DrawText(g,$“emSize:{emSize},宽度:{size.width}”,字体,字体,颜色,黑色);
pt=新点(0,pt.Y+尺寸高度);
}
}
返回点Y;
}
private int\u DrawTextExamplesWithDrawString(图形g、字符串文本、int y、IReadOnlyList emSizes)
{
点f pt=新点(0,y);
foreach(emSizes中的浮动emSize)
{
使用(字体=新字体(“Courier new”,emSize))
{
SizeF size=g.MeasureString(文本、字体);
g、 抽绳(文本、字体、画笔、黑色、pt);
pt.X+=尺寸宽度+20;
g、 抽绳($“emSize:{emSize},宽度:{size.width}”,字体,画笔.黑色,pt);
pt=新点f(0,pt.Y+尺寸高度);
}
}
返回(整数)点Y+1;
}
private readonly IReadOnlyList<float> _emSizes = new[] { 11.0f, 11.3f, 11.7f, 12.0f };
private const string _text = "0123456789";

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    int y = _DrawTextExamples(e.Graphics, _text, 0, _emSizes) + 10;

    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    y = _DrawTextExamples(e.Graphics, _text, y, _emSizes) + 10;
    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
    y = _DrawTextExamplesWithDrawString(e.Graphics, _text, y, _emSizes) + 10;
    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    y = _DrawTextExamplesWithDrawString(e.Graphics, _text, y, _emSizes) + 10;
}

private int _DrawTextExamples(Graphics g, string text, int y, IReadOnlyList<float> emSizes)
{
    Point pt = new Point(0, y);

    foreach (float emSize in emSizes)
    {
        using (Font font = new Font("Courier New", emSize))
        {
            Size size = TextRenderer.MeasureText(g, text, font);
            TextRenderer.DrawText(g, text, font, pt, Color.Black);
            pt.X += size.Width + 20;
            TextRenderer.DrawText(g, $"emSize: {emSize}, width: {size.Width}", font, pt, Color.Black);
            pt = new Point(0, pt.Y + size.Height);
        }
    }

    return pt.Y;
}

private int _DrawTextExamplesWithDrawString(Graphics g, string text, int y, IReadOnlyList<float> emSizes)
{
    PointF pt = new Point(0, y);

    foreach (float emSize in emSizes)
    {
        using (Font font = new Font("Courier New", emSize))
        {
            SizeF size = g.MeasureString(text, font);
            g.DrawString(text, font, Brushes.Black, pt);
            pt.X += size.Width + 20;
            g.DrawString($"emSize: {emSize}, width: {size.Width}", font, Brushes.Black, pt);
            pt = new PointF(0, pt.Y + size.Height);
        }
    }

    return (int)pt.Y + 1;
}