Reputation: 2277
I have noticed strange behavior of Graphics.MeasureString at different resolutions.
For the default resolution (96x96) there is a linear relationship across the different font sizes I tested.
However, if I raise it to 512 x 512, the linear relationship disappears and something really strange happens when using measure string. (See 4 plots below)
If I leave the resolution at the default size for a graphics object, and measure the font size, here is the relationship between font size and the width of a string:
Graphics object, Default Resolution (96):
Font size (X-Axis), WIDTH of a particular string (Y-Axis)
Font size (X-Axis), HEIGHT of a particular string (Y-Axis)
However, if I change the resolution
Graphics object, 512 resolution:
Font size (X-Axis), WIDTH of a particular string (Y-Axis)
Font size (X-Axis), HEIGHT of a particular string (Y-Axis)
Anyone know why this might be happening?
Thanks you.
It should noted that I am using .NET 4 (Full Profile)
Code used to generate graphs (Change resolution for each type):
string str = "6 CN-3 Tie EomgVeo405- 2ss>era09rni IBne 20iopv Atdrsn - Ng72";
SizeF sizef = new SizeF(855, 14.000001f);
StringFormat stringFormat = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Near,
Trimming = StringTrimming.None,
FormatFlags = StringFormatFlags.NoClip,
};
Bitmap b = new Bitmap(901, 401);
//b.SetResolution(512, 512);
Graphics g = Graphics.FromImage(b);
for (float x = origFont.Size; x >= 0.5; x -= 0.1f)
{
var data = g.MeasureString(str, new Font("Microsoft Sans Serif", x), sizef, stringFormat);
Console.WriteLine(x + "\t" + data.Width + "\t" + data.Height);
}
Upvotes: 3
Views: 1618
Reputation: 2220
I believe this might be happening because of the hinting/grid fitting algorithms in GDI+. Font sizes in your tests are extremely small in terms of glyph legibility, and, because of that, the rendering engine tries to apply special transformations to each glyph to make it clearer. These transformations depend greatly on the target DPI.
It is also worth mentioning that major increase of the font size will lead to a more 'linear' dependency.
This article explains these mechanisms in more details with some examples.
Meanwhile, you can try to modify the Graphics.TextRenderingHint
property and/or try TextRenderer
instead of Graphics.DrawString
if that will help you with your issue.
Upvotes: 1
Reputation: 391336
This answer is a guess, but the evidence fits it perfectly.
What you're seeing is the string being wrapped onto two lines.
Let's assume the following:
This fits the start of your 512-resolution graph, everything increases linearly.
At some point, the width is sharply reduced by a certain amount, and at the same time the height doubles.
This means that a word was moved onto line 2, which doubled the height (2 lines vs. 1 before), and the string got a certain amount less wide since the last word on the line is now on the start of line 2.
From there on, the width slowly increases again as the part of the string still on line 1 linearly gets wider as the font-size increases. At the same time the height increases linearly, but now at double the rate as before the break, since 2 lines now get higher, vs. 1 before.
At some point, again, the last word on line 1 breaks the maximum width and is moved down on line 2, before the word that was previously alone there, and at that point, the width is again sharply reduced by a certain amount.
If you were to continue your graph, I predict that the width will continue its current pattern. The exact amount it dips down each time is proportional to the width of the word being moved. At the same time, at some point the 2nd line will need to be broken, in which case you get a 3x height and the height will then increase at 3x the pace, and so on.
Upvotes: 1