Home User Manual Discussion Forum Search

Graphics.MeasureString() Pattern

Pattern for Graphics.MeasureString().

If you measure a string using Graphics.MeasureString(), you will not get the actual length of the string.  The length returned will be too long by about 4%.  There are many places in the code where a fudge factor is applied to compensate for this.  There is a better way. http://msdn.microsoft.com/en-us/library/6xe5hazb.aspx explains:

The MeasureString method is designed for use with individual strings and includes a small amount of extra space before and after the string to allow for overhanging glyphs. Also, the DrawString method adjusts glyph points to optimize display quality and might display a string narrower than reported by MeasureString. There are two suggested ways of obtaining metrics suitable for adjacent strings in layout (for example, when implementing formatted text):

1. Use the MeasureCharacterRanges method.

2. Use one of the MeasureString methods that takes a StringFormat, and pass GenericTypographic. Also, ensure the TextRenderingHint for the Graphics is AntiAlias.

I have been trying #2, GenericTypographic above, to measure the size rectangle needed for a paragraph. It has the following problems.  The measured height is a few pixels too short because it does not measure the lower-case characters that hang down below the bottom row.  The word wrap is also different when measuring versus when drawing.  This is a serious problem because the measurement then ends up short a row about 30% of the time.  The use of AntiAlias for the Graphics object results in really ugly drawing.  I have not tried switching to AntiAlias just for MeasureString and then back again for drawing, but I'm not optimistic.

So this is a very complex issue and needs to be approached with great care.  If a 4% error is acceptable, the it's just fine to use MeasureString without following the extra steps listed above.  For example, when centering a heading on a page, a small error is not important.  For printer/screen issues and complex layout, I will almost always need to be involved.

At http://blogs.msdn.com/b/jfoscoding/archive/2005/10/13/480632.aspx, it describes a third possible solution:

3. Use TextRenderer.MeasureText().

 

Open Dental Software 1-503-363-5432