Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does TextRenderer.MeasureText not measure text correctly using larger fonts in C#?

What I am doing is getting the pixel size of a string and converting it to hundredths of an inch (ie. pixels/DPI = inches, inches * 100 = hundredths of an inch). Here is my code:

private static SizeF TextSize(string text, Font txtFnt)
{
    SizeF txtSize = new SizeF();

    // The size returned is 'Size(int width, int height)' where width and height
    // are the dimensions of the string in pixels
    Size s = System.Windows.Forms.TextRenderer.MeasureText(text, txtFnt);

    // Value based on normal DPI settings of 96
    txtSize.Width = (float)Math.Ceiling((float)s.Width / 96f * 100f); 
    txtSize.Height = (float)Math.Ceiling((float)s.Height / 96f * 100f);

    return txtSize;
}

Now, using Arial font this all works fine for fonts smaller that 12, but after that characters start getting cut off because the calculated size is smaller that the actual size. I know that my DPI settings are set at 96. My fonts are all defined the same with the variation in font size:

Font myFont = new Font("Arial", <font size>, FontStyle.Regular, GraphicsUnit.Point);

I believe that I have to use GraphicsUnit.Point because of the custom control I am drawing the strings to, but does the GraphicsUnit matter?

Is the MeasureText function even working correctly, or is there something else going on?

EDIT

I am drawing to a custom print preview control. The units in the print preview control are 'Inches/100' (hence the conversion). I believe the text, images, etc are drawn with the Printer graphics object, but I'm not entirely sure.

like image 528
Mike Webb Avatar asked Oct 24 '22 23:10

Mike Webb


1 Answers

A loong time ago I ran into a similar problem, specifically measuring text INSIDE a textbox. The crux of the matter is this: There are two primary ways of drawing text. The Win32 API and System.Drawing. If you attempt to measure text inside a textbox, it will be drawn using the Win32 API and you will also need to measure it using the Win32 API. If you measure text drawn by System.Drawing, then your measurements using .net will match up.

Basically, a Forms textbox uses the Win32 API to layout and draw and measurements also need to come from Win32.

You didn't say what specifically you were measuring and where, so this answer may not even apply.

like image 155
hova Avatar answered Nov 08 '22 12:11

hova