Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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 image = new Bitmap(1, 1))
        {
            using (var g = Graphics.FromImage(image))
            {
                result = g.MeasureString(s, font);
            }
        }

        return result;
    }
}

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

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);

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top