Most of us used DrawText or TextOut functions of GDI to draw text with different fonts and colors. Have you ever tried to rotate text using GDI?
OK. Let’s see how we can do that. Windows GDI provides option to specify the angle for a row of text and again we can set angle even for the characters in the same string. Where we can set this information. The thing is that, we’ve to create a new font using CreateFont or modify the existing font setting by Getting the current font.
We can employ CreateFontIndirect function to create the font by specifying log font structure which contains the detailed font specification. Still I’ve not disclosed how to do that.
There are two different fields in the LOGFONT structure. They’re lfEscapement and lfOrientation
Here’s the description of these fields from MSDN
When the graphics mode is set to GM_COMPATIBLE, lfEscapement specifies both the escapement and orientation. You should set lfEscapement and lfOrientation to the same value.
Windows 95/98/Me: The lfEscapement member specifies both the escapement and orientation. You should set lfEscapement and lfOrientation to the same value.
The reason why we’re using LOGFONT is it’s so detailed. If you use CFont::CreatePointFont API, you will not be able to specify the Escapement and Orientation.I hope now you’re comfortable to go directly to the code. This is a modified version of the example presented in MSDN
[sourcecode language='cpp']
void DrawRotatedText(CString strDraw,
CRect rc, HDC hDC,
int nAngleLine = 0,
bool bEnableAngleChar = false,
int nAngleChar = 0,
LPCTSTR lpStrFontName = _T(“Arial”),
int nFontSize = 12 )
{
LOGFONT lf = { 0 };
_tcscpy_s(lf.lfFaceName, LF_FACESIZE, lpStrFontName);
lf.lfWeight = FW_NORMAL;
// Set the background mode to transparent for the
// text-output operation.
int nOldBkMode = SetBkMode(hDC, TRANSPARENT);
// Specify the angle to draw line
lf.lfEscapement = nAngleLine*10;
int nOldGMode;
if( bEnableAngleChar ) // Enable character angle
{
// Set graphics mode to advance to enable orientation
nOldGMode = SetGraphicsMode( hDC, GM_ADVANCED );
// Specify the angle of characters
lf.lfOrientation = nAngleChar*10;
}
else // Draw in normal mode
{
nOldGMode = SetGraphicsMode( hDC, GM_COMPATIBLE );
}
lf.lfHeight = -MulDiv(nFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
// Select the new font created
HFONT hFont = reinterpret_cast
HFONT hPrevFont = reinterpret_cast
// Draw text to screen
TextOut(hDC, rc.right / 2, rc.bottom / 2, strDraw, strDraw.GetLength());
SelectObject(hDC, hPrevFont);
DeleteObject(hFont);
// Restore old values
SetBkMode( hDC, nOldBkMode );
SetGraphicsMode( hDC, nOldGMode );
}
[/sourcecode]
I hope the comments in the code is enough to explain the logic to apply the angle for entire row of text and for characters.
The function takes 8 parameters and 5 of them are default.
| Parameter | Description |
| CString strDraw | Specify the string to draw |
| CRect rc | Rectangle to draw the text |
| HDC hDC | Device context for drawing |
| int nAngleLine | Escapement Angle (angle for entire line), in degrees |
| bool bEnableAngleChar | Enables angle for character. If this flag is enabled, nAngleChar value will be accepted. If this value if false, both the escapement and angle will be same. |
| int nAngleChar | Orientation angle (angle for characters), in degrees |
| LPCTSTR lpStrFontName | Name of the font. Default font will be Arial |
| int nFontSize | Font size |
