My question comes from a rather interesting problem I have been dealing with for the past few days. I recently asked a question regarding Writing a custom
Observed difference is due to using different WinAPI text rendering functions and their behavior. Specifically character kerning
In typography, kerning (less commonly mortising) is the process of adjusting the spacing between characters in a proportional font, usually to achieve a visually pleasing result. Kerning adjusts the space between individual letter forms, while tracking (letter-spacing) adjusts spacing uniformly over a range of characters.
The DrawText function draws formatted text in the specified rectangle. It formats the text according to the specified method (expanding tabs, justifying characters, breaking lines, and so forth).
Canvas.TextOut
)ExtTextOut
declaration:
BOOL ExtTextOut(
_In_ HDC hdc,
_In_ int X,
_In_ int Y,
_In_ UINT fuOptions,
_In_ const RECT *lprc,
_In_ LPCTSTR lpString,
_In_ UINT cbCount,
_In_ const INT *lpDx
);
If the lpDx parameter is NULL, the ExtTextOut function uses the default spacing between characters. The character-cell origins and the contents of the array pointed to by the lpDx parameter are specified in logical units. A character-cell origin is defined as the upper-left corner of the character cell.
Basically DrawText
will automatically draw formatted text and that includes adjusting spacing between characters (kerning), while ExtTextOut
will by default use default spacing between characters (no-kerning). If you want to adjust spacing between characters you will have to calculate and provide kerning array (lpDx
) parameter.
Those differences are especially visible with some character combinations like T
and small letters that visually fit under T
, or AV
where one V
fits over A
. Different fonts also have different default kernings and that is reason why some fonts have visually same rendering using both functions and some not. Kerning also depends on font size. For instance characters AV
rendered with Arial
at 9 pt
will have same output with both functions, while Arial
at 12 pt
will result in different outputs.
First line in following image is drawn with no-kerning using ExtTextOut
and second line with automatic kerning using DrawText
.