JTalton's picture

TextureFont - Text kerning & measurements [fixed]

Nice job on the font code! It is quite nice.


Text kerning may not be correct.
Since the font is packed one character at a time into a texture and then reassembled, the reassembled text probably does not have any text kerning.
The way I've seen this fixed is to render a whole string at a time, and draw it as a single quad.

TextureFont.MeasureString() does not properly return the size of the string.
This could either be caused by:
a) The Graphics.DrawString() not having StringFormat.GenericTypographic as a parameter, or
b) Since the font is being packed one character at a time into a texture, the rendering will not have the same kerning as Graphics.Drawstring().

In the past I have written font code using the TrueType library that creates a complete string at a time.
I have taken the Graphics.DrawString and Graphics.MeasureString and done the same in my own code.

It would be interesting to compare the .NET library font rendering to the TrueType library rendering.
It would also be interesting to compare the current implementation to a string at a time implementation to see kerning differences.
I may put together a comparison.

I am not 100% certain that the .NET font rendering does any kerning.

TKFontTest.png13.5 KB
Program.txt2.17 KB
Fonts.png84.13 KB
Fonts.txt9.03 KB


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler.'s picture

Text kerning may not be correct.
You are correct in that the font texture do not have any kerning applied (that would actually be impossible), however kerning is applied during string assembly.

TextureFont.MeasureString() does not properly return the size of the string.
Evidence? :)

Actually it does use the StringFormat.GenericTypographic parameter, which results in proper kerning information. This is quite evident in this picture. Try running "Tutorial 03: Fonts" and "Tutorial 04: Text" for a live demonstration.

If you have a test case where kerning is not applied (or is applied incorrectly), I'll do my best to correct the problem. I agree that text rendering is not perfect yet (there are some artifactsl), but as far as I can see kerning works as it should.

JTalton's picture

I'll take a look at the code that puts the strings back together (just for my own sanity). Thanks!

I wrote a widget and the widgets width was the size of TextureFont.MeasureString(), but when I drew the text it would be larger than that size.
TextureFont.MeasureString() does use StringFormat.GenericTypographic.
The Graphics.DrawString() calls in the code were not using StringFormat.GenericTypographic.

I was thinking that that may be why I was seeing a difference. I'll make a test app and send it to you to show the problem.

JTalton's picture

I attached a screenshot of the problem and the code to the post. The grey area is the area MeasureString returns for the string.

JTalton's picture

Attached another screen shot of the problem.

I ended up writing my own code to handle text rendering, but it suffers from the same problem.

Searching on the net there are a a lot of pages that talk about the inaccuracy of Graphics.MeasureString.
There is a new class called TextRenderer for .NET 2.0 that gives better accuracy, but it is located in the System.Windows.Forms namespace.

My old text renderer that was based on FreeType using the SDL bindings did not have these problems.
I guess I am going to go back to that code.

the Fiddler's picture

Just a ping that I haven't forgotten this issue and will work on a fix.

Right now, there is a workaround: instead of calling MeasureString to measure the whole string at once, iterate and add the widths of succesive character pairs. This will provide the correct result, but it requires that you keep a handle to the actual System.Drawing.Font.

Edit: Ok, I'm working on the issue, and will fix it in the next version.

the Fiddler's picture

Fixed as of revision 1108.