开发者

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

开发者 https://www.devze.com 2023-02-01 10:52 出处:网络
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:

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 work开发者_如何学Gos 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.


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.


The options make a difference and the large the font the larger the impact. Here is the settings that worked best for us - your mileage may vary. (Code is weird because we use this in J#):

private static System.Drawing.StringFormat createStringFormat()
{

    System.Drawing.StringFormat fmt = new System.Drawing.StringFormat (System.Drawing.StringFormat.get_GenericTypographic());
    fmt.set_Trimming(System.Drawing.StringTrimming.None);
    fmt.set_FormatFlags(System.Drawing.StringFormatFlags.MeasureTrailingSpaces | System.Drawing.StringFormatFlags.NoWrap);
    return fmt;
}


Font hinting.

The fonts that Windows uses are hinted, meaning that they may not be exactly the size that the font specifies.

http://blogs.msdn.com/b/cjacks/archive/2006/05/11/595525.aspx

0

精彩评论

暂无评论...
验证码 换一张
取 消