不使用图形对象来测量字符串?

发布于 2024-07-25 13:36:53 字数 272 浏览 3 评论 0原文

我使用像素作为字体的单位。 在一个地方,我正在执行点击测试来检查用户是否在屏幕上某些文本的边框内单击。 我需要为此使用类似 MeasureString 的东西。 不幸的是,执行命中测试的代码位于库深处,无法访问Graphics对象甚至Control

如何在不使用 Graphics 类的情况下获取给定字体的字符串的边界框? 当我的字体以像素为单位时,为什么还需要 Graphics 对象?

I am using pixels as the unit for my font. In one place, I am performing a hit test to check if the user has clicked within the bounding rectangle of some text on screen. I need to use something like MeasureString for this. Unfortunately, the code doing the hit test is deep within a library which does not have access to a Graphics object or even a Control.

How do I get the bounding box of a string given the font without using the Graphics class? Why do I even need a Graphics object when my font is in pixels?

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

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

发布评论

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

评论(5

回忆凄美了谁 2024-08-01 13:36:53

如果您有对 System.Windows.Forms 的引用,请尝试使用 TextRenderer 类。 有一个静态方法(MeasureText),它接受字符串和字体并返回大小。 MSDN 链接

If you have a reference to System.Windows.Forms, try using the TextRenderer class. There is a static method (MeasureText) which takes the string and font and returns the size. MSDN Link

记忆之渊 2024-08-01 13:36:53

您不需要使用用于渲染的图形对象来进行测量。 您可以创建一个静态实用程序类:

public static class GraphicsHelper
{
    public static SizeF MeasureString(string s, Font font)
    {
        SizeF result;
        using (var g = Graphics.FromHwnd(IntPtr.Zero))
        {
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            result = g.MeasureString(s, font, int.MaxValue, StringFormat.GenericTypographic);
        }

        return result;
    }
}

根据您的情况设置位图的 dpi 可能是值得的。

You don't need to use the graphics object that you are using to render to do the measuring. You could create a static utility class:

public static class GraphicsHelper
{
    public static SizeF MeasureString(string s, Font font)
    {
        SizeF result;
        using (var g = Graphics.FromHwnd(IntPtr.Zero))
        {
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            result = g.MeasureString(s, font, int.MaxValue, StringFormat.GenericTypographic);
        }

        return result;
    }
}

It might be worthwhile, depending on your situation to set the dpi of the bitmap as well.

脸赞 2024-08-01 13:36:53

@NerdFury 答案中的 MeasureString 方法将给出比预期更高的字符串宽度。您可以找到其他信息

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result = 
  g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic);

MeasureString method in @NerdFury answer will give a higher string width than expected.Additional info you can find here. If you want to measure only the physical length please add this two lines :

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result = 
  g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic);
意中人 2024-08-01 13:36:53

这个例子很好地说明了 FormattedText 的使用。 FormattedText 提供了在 Windows Presentation Foundation (WPF) 应用程序中绘制文本的低级控制。 您可以使用它来测量具有特定字体的字符串的宽度,而无需使用 Graphics 对象。

public static float Measure(string text, string fontFamily, float emSize)
{
    FormattedText formatted = new FormattedText(
        item, 
        CultureInfo.CurrentCulture, 
        System.Windows.FlowDirection.LeftToRight, 
        new Typeface(fontFamily), 
        emSize, 
        Brushes.Black);

    return formatted.Width;
}

包括WindowsBase 和PresentationCore 库。

This example does great job of illustrating the use of FormattedText. FormattedText provides low-level control for drawing text in Windows Presentation Foundation (WPF) applications. You can use it to measure the Width of a string with a particular Font without using a Graphics object.

public static float Measure(string text, string fontFamily, float emSize)
{
    FormattedText formatted = new FormattedText(
        item, 
        CultureInfo.CurrentCulture, 
        System.Windows.FlowDirection.LeftToRight, 
        new Typeface(fontFamily), 
        emSize, 
        Brushes.Black);

    return formatted.Width;
}

Include WindowsBase and PresentationCore libraries.

水晶透心 2024-08-01 13:36:53

这可能不是其他人的重复,但我的问题也是不需要的 Graphics 对象。 听完上面的挫败感后,我简单地尝试了:(

Size proposedSize = new Size(int.MaxValue, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.NoPadding;
Size ressize = TextRenderer.MeasureText(content, cardfont, proposedSize, flags);

其中“content”是要测量的字符串,cardfont是它所在的字体)

......并且很幸运。 我可以使用结果来设置 VSTO 中列的宽度。

This may not be but a repeat of others, but my problem was the unwanted Graphics object as well. After listening to the above frustrations I simply tried:

Size proposedSize = new Size(int.MaxValue, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.NoPadding;
Size ressize = TextRenderer.MeasureText(content, cardfont, proposedSize, flags);

(where 'content' is the string to measure and cardfont the font it is in)

... and was in luck. I could use the result to set the width of my column in VSTO.

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