为什么 TextRenderer.MeasureText 在 C# 中使用较大字体时无法正确测量文本?

发布于 2024-10-09 18:43:59 字数 1080 浏览 0 评论 0原文

我正在做的是获取字符串的像素大小并将其转换为百分之一英寸(即像素/DPI = 英寸,英寸 * 100 = 百分之一英寸)。这是我的代码:

private static SizeF TextSize(string text, Font txtFnt)
{
    SizeF txtSize = new SizeF();

    // The size returned is 'Size(int width, int height)' where width and height
    // are the dimensions of the string in pixels
    Size s = System.Windows.Forms.TextRenderer.MeasureText(text, txtFnt);

    // Value based on normal DPI settings of 96
    txtSize.Width = (float)Math.Ceiling((float)s.Width / 96f * 100f); 
    txtSize.Height = (float)Math.Ceiling((float)s.Height / 96f * 100f);

    return txtSize;
}

现在,使用 Arial 字体,对于小于 12 的字体,这一切都可以正常工作,但之后字符开始被截断,因为计算的大小小于实际大小。我知道我的 DPI 设置设置为 96。我的字体都定义为相同的字体大小变化:

Font myFont = new Font("Arial", <font size>, FontStyle.Regular, GraphicsUnit.Point);

我相信我必须使用 GraphicsUnit.Point 因为我正在绘制自定义控件字符串,但是 GraphicsUnit 重要吗?

MeasureText 函数是否工作正常,或者还有其他问题吗?

编辑

我正在绘制自定义打印预览控件。打印预览控件中的单位是“英寸/100”(因此进行转换)。我相信文本、图像等是用打印机图形对象绘制的,但我不完全确定。

What I am doing is getting the pixel size of a string and converting it to hundredths of an inch (ie. pixels/DPI = inches, inches * 100 = hundredths of an inch). Here is my code:

private static SizeF TextSize(string text, Font txtFnt)
{
    SizeF txtSize = new SizeF();

    // The size returned is 'Size(int width, int height)' where width and height
    // are the dimensions of the string in pixels
    Size s = System.Windows.Forms.TextRenderer.MeasureText(text, txtFnt);

    // Value based on normal DPI settings of 96
    txtSize.Width = (float)Math.Ceiling((float)s.Width / 96f * 100f); 
    txtSize.Height = (float)Math.Ceiling((float)s.Height / 96f * 100f);

    return txtSize;
}

Now, using Arial font this all works fine for fonts smaller that 12, but after that characters start getting cut off because the calculated size is smaller that the actual size. I know that my DPI settings are set at 96. My fonts are all defined the same with the variation in font size:

Font myFont = new Font("Arial", <font size>, FontStyle.Regular, GraphicsUnit.Point);

I believe that I have to use GraphicsUnit.Point because of the custom control I am drawing the strings to, but does the GraphicsUnit matter?

Is the MeasureText function even working correctly, or is there something else going on?

EDIT

I am drawing to a custom print preview control. The units in the print preview control are 'Inches/100' (hence the conversion). I believe the text, images, etc are drawn with the Printer graphics object, but I'm not entirely sure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻风 2024-10-16 18:43:59

很久以前,我遇到了类似的问题,特别是测量文本框内的文本。问题的关键在于:绘制文本有两种主要方法。 Win32 API 和 System.Drawing。如果您尝试测量文本框中的文本,它将使用 Win32 API 进行绘制,并且您还需要使用 Win32 API 来测量它。如果您测量由 System.Drawing 绘制的文本,则使用 .net 的测量结果将匹配。

基本上,表单文本框使用 Win32 API 进行布局和绘制,并且测量也需要来自 Win32。

您没有具体说明您在测量什么以及在哪里测量,因此这个答案可能不适用。

A loong time ago I ran into a similar problem, specifically measuring text INSIDE a textbox. The crux of the matter is this: There are two primary ways of drawing text. The Win32 API and System.Drawing. If you attempt to measure text inside a textbox, it will be drawn using the Win32 API and you will also need to measure it using the Win32 API. If you measure text drawn by System.Drawing, then your measurements using .net will match up.

Basically, a Forms textbox uses the Win32 API to layout and draw and measurements also need to come from Win32.

You didn't say what specifically you were measuring and where, so this answer may not even apply.

真心难拥有 2024-10-16 18:43:59

这些选项会产生影响,字体越大影响越大。以下是最适合我们的设置 - 您的里程可能会有所不同。 (代码很奇怪,因为我们在 J# 中使用它):

private static System.Drawing.StringFormat createStringFormat()
{

    System.Drawing.StringFormat fmt = new System.Drawing.StringFormat (System.Drawing.StringFormat.get_GenericTypographic());
    fmt.set_Trimming(System.Drawing.StringTrimming.None);
    fmt.set_FormatFlags(System.Drawing.StringFormatFlags.MeasureTrailingSpaces | System.Drawing.StringFormatFlags.NoWrap);
    return fmt;
}

The options make a difference and the large the font the larger the impact. Here is the settings that worked best for us - your mileage may vary. (Code is weird because we use this in J#):

private static System.Drawing.StringFormat createStringFormat()
{

    System.Drawing.StringFormat fmt = new System.Drawing.StringFormat (System.Drawing.StringFormat.get_GenericTypographic());
    fmt.set_Trimming(System.Drawing.StringTrimming.None);
    fmt.set_FormatFlags(System.Drawing.StringFormatFlags.MeasureTrailingSpaces | System.Drawing.StringFormatFlags.NoWrap);
    return fmt;
}
一直在等你来 2024-10-16 18:43:59

字体提示。

Windows 使用的字体是有提示的,这意味着它们可能不完全是字体指定的大小。

http://blogs.msdn.com/b/cjacks /archive/2006/05/11/595525.aspx

Font hinting.

The fonts that Windows uses are hinted, meaning that they may not be exactly the size that the font specifies.

http://blogs.msdn.com/b/cjacks/archive/2006/05/11/595525.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文