by Stephan Grieger - GUI Computing
In my previous article on building a ruler for the print preview window, I discussed how to build the horizontal bar only. The horizontal bar was the easiest as the text is also horizontal. However the vertical ruler has the text rotated 90 degrees. The first solution is to use a custom control to rotate the text but then the effect slows down and begins to flicker. The second solution is to use a font that can rotate the text, though I've not found one yet. That leaves only one solution, the API.
Now you may say, but there's no API that will rotate text. Correct, there isn't. However, that doesn't stop us from creating a new font that is rotated. Now before you tell me it's to complicated to build an entire font, we're not going to design a font from scratch. What we are going to do is utilise an existing font to build another one.
The API calls you will need are as follows (Page numbers refer to Daniel Appleman's API Bible) :
In the API help file that comes shipped with Visual Basic are the following type declarations :
Rect
LogFont
The LogFont structure is a little complex, so let me just explain what each of the components do.
lfHeight | The height of the font in logical units. |
lfWidth | The width of the font in logical units. |
lfEscapement | Specifies the angle of the text. Refer to page 436 for a full description. |
lfOrientation | Unused. |
lfWeight | Specifies the weight of the font. This number ranges from 100 to 900. 100 is light. |
lfItalic | Specifies whether the font is italic or not. Non zero specifies italic. |
lfUnderline | Non zero for underlining. |
lfStrikeout | Non zero for strikeout. |
lfCharSet | Valid constants are ANSI_CHARSET, DEFAULT_CHARSET, SYMBOL_CHARSET, OEM_CHARSET. |
lfOutprecision | Provides guidelines to help the GDI find a matching font. |
lfClipPrecision | Defines the guidelines for clipping text when the characters are slightly outside the clipping region. |
lfQuality | One of the following constants. DEFAULT_QUALITY, DRAFT_QUALITY, PROOF_QUALITY. |
lpPitchAndFamily | a combination of the following constants. DEFAULT_PITCH, FIXED_PITCH, VARIABLE_PITCH, FF_DECORATIVE, FF_MODERN, FF_ROMAN, FF_SCRIPT, FF_SWISS, FF_DONTCARE. |
lfFaceName | Specifies the name of the font to be used. |
OK, So the Code at Last...
First step is to create the font, then select that new font as the font that we want to use for printing and print the text.
If FontToUse <'> 0 Then di% = DeleteObject(FontToUse%) lf.lfHeight = 20 lf.lfWidth = 10 lf.lfEscapement = 2700 lf.lfWeight = 400 lf.lfItalic = Chr$(0) lf.lfItalic = Chr$(0) lf.lfUnderline = Chr$(0) lf.lfStrikeOut = Chr$(0) lf.lfOutPrecision = Chr$(2) lf.lfClipPrecision = Chr$(1) lf.lfQuality = Chr$(0) lf.lfPitchAndFamily = Chr$(0) lf.lfCharSet = Chr$(0) lf.lfFaceName = "Arial" & Chr$(0)
Now that we've set up the structure for the font we need to create it :
FontToUse = CreateFontIndirect(lf)
Now select the new font as the one to use.
oldhdc = SelectObject (PictureControl.hDC, Rect)
Print the text to the control.
di% = TextOut(PictureControl.hDC, 100, 0, "Rotate Text", 11) di% = SelectObject(PictureControl.hDC, oldhdc)
The 2700 value used as the escapement will rotate the text 90 degrees. The
text is pointing the wrong way but all we need to do is flip it the right way.