如何从 CFont 对象获取自动计算的字体宽度?
我使用固定大小的字体(例如:“Courier New”)。当我通过调用 CFont::CreateFont 函数初始化 CFont 对象时,我只想指定字体高度。
CFont Font;
Font.CreateFont( nFontHeight, 0, 0, 0, 0, false, false,
0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
FIXED_PITCH|FF_MODERN, _T("Courier New") );
根据文档,字体宽度将自动计算。我需要自动计算的值来进行其他计算。
GetLogFont 函数没有用,因为 CFont 似乎只保存我们给出的值,即 width = 0,并且仅在第一次使用时才计算该值。 (请查看Microsoft 文档)
另一种选择是使用单个字符的 CDC::GetTextExtent。但在这种情况下,即使在高度上,我也可以看到一些细微的差异。例如,当我指定 -32 作为高度时,GetTextExtent 返回 33 作为 y 值。
有什么方法可以得到正确的计算宽度吗?
I'm using a fixed size font ( eg: "Courier New" ). When I initialize the CFont object by calling CFont::CreateFont function, I want to specify only the font height.
CFont Font;
Font.CreateFont( nFontHeight, 0, 0, 0, 0, false, false,
0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
FIXED_PITCH|FF_MODERN, _T("Courier New") );
As per documentation, font width will be calculated automatically. I need that automatically calculated value for some other calculation.
GetLogFont Function is useless as it seems CFont only holds the value we give that is width = 0 and it calculates the value only when it is used for first time. ( Please check the Microsoft documentation )
Another option was to use CDC::GetTextExtent using a single character. But in that case also I could see some minor differences even in the height. For example, when I give -32 as height, GetTextExtent returns 33 for y value.
Is there any way to get the correct calculated width?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,如果您只想指定字体高度,通常需要使用
CreatePointFont
。其次,Windows 95/98/SE/Me 已经消亡了,随之而来的是使用 Microsoft 的“文本”宏(例如_T("whatever")
)的所有理由。如果您想要宽字符,请直接询问:然后,按照@MikMik的建议,您可以使用
GetTextMetrics
来获取宽度 - 但只有在您选择字体之后到 DC(GetTextMetrics
获取选择到 DC 中的字体的数据,而不仅仅是原始字体 - 特别是在小字体大小时,某些内容会进行调整以补偿输出设备的分辨率)。但请注意,即使对于固定宽度字体,字符串的宽度也不一定是
char_width * num_chars
。至少如果我没记错的话,即使是固定宽度的字体仍然可以调整字距,这意味着间距是根据一起出现的字符对来调整的。典型的例子是像AV
这样的一对。因为它们彼此相邻的线通常处于相同的角度(或至少非常接近相同),所以将调整间距以使它们更靠近 - 事实上,“V”的顶部将通常与“A”的底部重叠。即使每个单独的字符具有相同的宽度,字符串的宽度也可能会有所不同。顺便说一句,我不确定 Courier New 是否会这样做,但我相当确定至少有一些固定宽度字体可以这样做。
First of all, if you only want to specify the font height, you normally want to use
CreatePointFont
. Second, Windows 95/98/SE/Me are dead and gone -- and with them, essentially all reason to use Microsoft's "text" macros like_T("whatever")
. If you want wide characters, ask for them directly:Then, as suggested by @MikMik, you can use
GetTextMetrics
to get the width -- but only after you select the font into a DC (GetTextMetrics
gets the data for a font selected into a DC, not just for the raw font -- especially at small font sizes, some things get adjusted to compensate for the resolution of the output device).Note, however, that even for a fixed-width font, the width of a string is not necessarily
char_width * num_chars
. At least if I recall correctly, even a fixed-width font can still be kerned, which means the spacing is adjusted based on what pairs of characters occur together. The classic example is a pair likeAV
. Because the lines where they're next to each other are typically at the same angle (or at least very close to the same) the spacing will be adjusted to move them closer together -- in fact, the top of the "V" will often overlap with the bottom of the "A". The width of a string of characters can vary even though each individual character has the same width as every other.Offhand, I'm not sure that Courier New does that, but I'm reasonably certain at least a few fixed-width fonts do.
您尝试过 CDC::GetTextMetrics() 吗?我从未使用过它,但它似乎正是您正在寻找的。你可以得到平均和最大字符宽度,我想这对于 Courier New 来说应该是一样的。
Have you tried
CDC::GetTextMetrics()
? I've never used it, but it seems to be what you're looking for. You can get the average and maximum character width, which I guess should be the same for Courier New.