How to Rotate Text using GDI

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

 

lfEscapement
Specifies the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line of a row of text.Windows NT/2000/XP: When the graphics mode is set to GM_ADVANCED, you can specify the escapement angle of the string independently of the orientation angle of the string’s characters.

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.

lfOrientation
Specifies the angle, in tenths of degrees, between each character’s base line and the x-axis of the device.

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


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>( CreateFontIndirect(&lf));
    HFONT hPrevFont = reinterpret_cast<HFONT>( SelectObject(hDC, hFont));

    // 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 );
}

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
Technorati Tags: ,,

Sharing my thoughts...

Respond to this post