Try out my new app: MealPlan, a simple weekly meal planning tool for the iPad.

Rendering Text Using the .NET Framework

The .NET framework uses GDI+ for the System.Drawing namespace, and this namespace has a whole new way of drawing text. Rather than using the venerable TextOut and ExtTextOut functions, there’s Graphics.DrawString() and Graphics.MeasureString().

The problem with these is that text kerning is measured differently – more accurately – but in a way that is often incompatible with the way app developers want to use these functions.

Specifically, adding a character to a string can change the position of the characters before it. This means if you’re writing an editor and using Graphics.DrawString() to render text with a proportional font, the string will kind of jump around as the user types.

ExtTextOut wasn’t smart enough to do this sort of kerning, so you don’t have this problem. Unfortunately the .NET framework doesn’t have any text drawing function that you can fall back on, so the only way to get the old behaviour is through P/Invoke to the ExtTextOut function in GDI.

This means turning your simple DrawString call:

g.DrawString(line.Text, f, Brushes.Black, new Point(0, line.Y));

into

// Initialize destRect to something suitable
RectangleF destRect = new RECT();

IntPtr dc = g.GetHdc();
ExtTextOut(dc, 0, line.Y, 0, ref destRect, line.Text, (uint)line.Text.Length, null);
g.ReleaseHdc();

You also need to declare the signature of ExtTextOut for P/Invoke; the code for that is here (and the code for RECT is here).

Update: The .NET Framework 2.0 is now released. With 2.0 Microsoft acknowledged the need for the original functionality, and added a new class, TextRenderer. This class adds methods for DrawString and MeasureString, so the code snippet above can be replaced with:

TextRenderer.DrawText(g, line.Text, font, new Point(0, line.Y), Color.Black);

Much nicer.

Leave a Reply