6

Hi I am using TextRenderer.MeasureText() method to measure the text width for a given font. I use Arial Unicode MS font for measuring the width, which is a Unicode font containing characters for all languages. The method returns different widths on different servers. Both machines have Windows 2003, and .net 3.5 SP1 installed.

Here is the code we used

using (Graphics g = Graphics.FromImage(new Bitmap(1, 1)))
{                
    width = TextRenderer.MeasureText(g, word, textFont, new Size(5, 5), TextFormatFlags.NoPadding).Width;
}

Any idea why this happens?

I use C# 2.0

casperOne
  • 73,706
  • 19
  • 184
  • 253
Amit
  • 25,106
  • 25
  • 75
  • 116
  • Why _what_ happens? You just posted some code and no problem description. – Oded Jan 22 '10 at 09:31
  • Hi the problem is, if u run the code on different machines, it returns different widths, so if I have multiple servers, each server will return a different width, which is not acceptable...And not all the machines return different values only some of them..! – Amit Jan 22 '10 at 09:34

3 Answers3

12
//--------------------------------------------------------------------------------------
// MeasureText always adds about 1/2 em width of white space on the right,
// even when NoPadding is specified. It returns zero for an empty string.
// To get the precise string width, measure the width of a string containing a
// single period and subtract that from the width of our original string plus a period.
//--------------------------------------------------------------------------------------

public static Size MeasureText(string Text, Font Font) {
  TextFormatFlags flags
    = TextFormatFlags.Left
    | TextFormatFlags.Top
    | TextFormatFlags.NoPadding
    | TextFormatFlags.NoPrefix;
  Size szProposed = new Size(int.MaxValue, int.MaxValue);
  Size sz1 = TextRenderer.MeasureText(".", Font, szProposed, flags);
  Size sz2 = TextRenderer.MeasureText(Text + ".", Font, szProposed, flags);
  return new Size(sz2.Width - sz1.Width, sz2.Height);
}
Bob Snyder
  • 121
  • 1
  • 2
11

MeasureText is not known to be accurate.

Heres a better way :

    protected int _MeasureDisplayStringWidth ( Graphics graphics, string text, Font font )
    {
        if ( text == "" )
            return 0;

        StringFormat format = new StringFormat ( StringFormat.GenericDefault );
        RectangleF rect = new RectangleF ( 0, 0, 1000, 1000 );
        CharacterRange[] ranges = { new CharacterRange ( 0, text.Length ) };
        Region[] regions = new Region[1];

        format.SetMeasurableCharacterRanges ( ranges );
        format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

        regions = graphics.MeasureCharacterRanges ( text, font, rect, format );
        rect = regions[0].GetBounds ( graphics );

        return (int)( rect.Right );
    }
Mongus Pong
  • 11,337
  • 9
  • 44
  • 72
1

We had a similar problem several years back. In our case, for some reason we had different versions of the same font installed on two different machines. The OS version was the same, but the font was different.

Since you normally don't deploy a system font with your application setup, measuring and output results may vary from one machine to another, based on the font version.

Since you say ...

And not all the machines return different values only some of them..!

...this is something I'd check for.

takrl
  • 6,356
  • 3
  • 60
  • 69