【问题标题】:MeasureString() pads the text on the left and the rightMeasureString() 在左边和右边填充文本
【发布时间】:2010-09-12 05:35:06
【问题描述】:

我在 C++ 中使用 GDI+。 (这个问题也可能存在于 C# 中)。

我注意到,每当我调用 Graphics::MeasureString() 或 Graphics::DrawString() 时,字符串的左右两侧都会填充空白。

例如,如果我使用的是 Courier 字体(不是斜体!)并且我测量“P”我得到 90,但“PP”给我 150。我希望等宽字体的宽度正好是两倍“PP”。

我的问题是:这是预期的还是记录在案的行为,我该如何禁用它?

RectF Rect(0,0,32767,32767);
RectF Bounds1, Bounds2;
graphics->MeasureString(L"PP", 1, font, Rect, &Bounds1);
graphics->MeasureString(L"PP", 2, font, Rect, &Bounds2);
margin = Bounds1.Width * 2 - Bounds2.Width;

【问题讨论】:

    标签: gdi+ drawstring


    【解决方案1】:

    这是设计使然,该方法不使用实际字形来测量宽度,因此会在悬垂的情况下添加一点填充。

    MSDN 建议如果您需要更高的准确性,请使用不同的方法:

    要获得适合布局中相邻字符串的指标(例如,在实现格式化文本时),请使用MeasureCharacterRanges 方法或采用StringFormatMeasureString 方法之一,并传递GenericTypographic。另外,确保GraphicsTextRenderingHintAntiAlias

    【讨论】:

    • 这会删除水平填充,但不会删除垂直填充。呃。
    【解决方案2】:

    根据这篇 kb 文章 Why text appears different when drawn with GDIPlus versus GDI

    ,听起来它也可能与提示有关

    【讨论】:

      【解决方案3】:

      确实这是设计使然,但已接受答案上的链接实际上并不完美。问题是当您真正想要使用的是像素(整数)时,在所有这些方法中使用浮点数。

      TextRenderer class 用于此目的,并适用于真实尺寸。请参阅此 link from msdn 了解如何使用它。

      【讨论】:

      • 我使用 TextRenderer 类获得了更好的结果。
      • TextRenderer 正是我在类似情况下所需要的
      【解决方案4】:

      TextRenderer 非常适合获取字体大小。但是在绘图循环中,与 graphics.DrawString() 相比,使用 TextRenderer.DrawText 的速度非常慢。

      由于字符串的宽度是问题所在,最好结合使用 TextRenderer.MeasureText 和 graphics.DrawString..

      【讨论】:

        【解决方案5】:

        追加StringFormat.GenericTypographic 将解决您的问题:

        graphics->MeasureString(L"PP", 1, font, width, StringFormat.GenericTypographic);
        

        将相同的属性应用于DrawString

        【讨论】:

        • GenericTypographic 非常适合我,因为无论如何我都在控件中使用自己的边距。
        • 几乎完美,但小填充是必要的。
        猜你喜欢
        • 2015-02-15
        • 1970-01-01
        • 2012-09-25
        • 2016-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        相关资源
        最近更新 更多