problem with TextRenderer.MeasureText

2019-01-24 16:52发布

问题:

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

回答1:

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


回答2:

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


回答3:

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.