MeasureString()函数会在文本的左右两侧添加空白。

18

我在使用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;
5个回答

13

这将移除水平填充,但不会移除垂直填充。唉。 - BlueRaja - Danny Pflughoeft
我进行了所有的调整,情况有所改善,但是MeasureString返回的宽度值还是稍微小一些。为了弥补这个问题并得到正确的宽度,我不得不为字符串中的每个字符添加0.3333f。通过这样做,它几乎完美地工作了。你有什么想法,我可能错过了什么导致我需要进行这个手动调整?这与使用的字母无关 - 不管是窄的还是宽的;只是必须为字符串中的每个字符添加这个值。 - Damir Tenishev

6
这是设计上的问题,但是被接受答案中的链接实际上并不完美。问题在于所有这些方法中使用了浮点数,而你真正想要使用的是像素(整数)。 TextRenderer类 就是为此目的而设计的,并且可以使用真实的大小。请参阅这个来自msdn的链接 以了解如何使用它。

我使用TextRenderer类可以获得更好的结果。 - Bitterblue
TextRenderer正是我在类似情况下所需要的。 - Rob

5

添加StringFormat.GenericTypographic会解决您的问题:

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

将相同的属性应用于DrawString

GenericTypographic 对我来说很理想,因为我在控件中已经使用了自己的边距。 - Dwayne Robinson
几乎完美,但是小内边距是必要的。 - Slappy

1

0

TextRenderer在获取字体大小方面表现得非常出色。但在绘制循环中,与graphics.DrawString()相比,使用TextRenderer.DrawText极为缓慢。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接