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

风流意气都作罢 提交于 2020-01-02 04:43:05

问题


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.


回答1:


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.




回答2:


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



回答3:


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



来源:https://stackoverflow.com/questions/4556885/why-does-textrenderer-measuretext-not-measure-text-correctly-using-larger-fonts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!