Topic : Using Fonts in MFC
Author : Unknown
Page : 1 Next >>
Go to page :


Font


Font is another very important GDI object, every application deals with font. Usually a system contains some default fonts that can be used by all the applications. Besides these default fonts, we can also install fonts provided by the thirty party. For word processing applications, using font is a complex issue. There are many things we need to take care. For example, when creating this type of applications, we need to think about the following issues: how to display a font with different styles; how to change the text alignment; how to add special effects to characters.

1 Outputting Text Using Different Fonts

When we implement a font dialog box, all the available fonts contained in the system will be listed in it. We can select font size, font name, special styles, and text color.

Like other GDI objects such as pen and brush, we need to create font with specific styles and select it into a DC in order to use it for outputting text. In MFC, the class that can be used to implement font is CFont. To create a font, we can call either CFont::CreateFont(...) or CFont::CreateFontIndirect(...), whose formats are listed as follows:

(Code omitted)

The first function has many parameters and the second one needs only a LOGFONT type pointer. The results of the two member functions are exactly the same, every style we need to specify for a font in the first function has a corresponding member in structure LOGFONT:

typedef struct tagLOGFONT{

LONG lfHeight;

LONG lfWidth;

LONG lfEscapement;

LONG lfOrientation;

LONG lfWeight;

BYTE lfItalic;

BYTE lfUnderline;

BYTE lfStrikeOut;

BYTE lfCharSet;

BYTE lfOutPrecision;

BYTE lfClipPrecision;

BYTE lfQuality;

BYTE lfPitchAndFamily;

TCHAR lfFaceName[LF_FACESIZE];

} LOGFONT;


Here, member lfFaceName specifies the font name; lfHeight and lfWidth specify font size; lfWeight, lfItalic, lfUnderline and lfStrikeOut specify font styles. Besides these styles, there are two other styles that can be specified: lfEscapement and lfOrientation.

Under Windows 95, lfEscapement and lfOrientation must be assigned the same value when a font is being created. If they are non-zero, the text will have an angle with respect to the horizontal border of the window when it is displayed (Figure 9-1). To display text this way, we must assign the angle to both lfEscapement and lfOrientation when creating the font, the unit of the angle is one tenth of a degree. Please note that only True Type fonts can have such orientation.

After a font is created, it can be selected into DC for outputting text. After the text output is over, it must be selected out of the DC. This procedure is exactly the same with other GDI objects.

Sample 1\GDI demonstrates how to create and use a font with specified styles. It is a standard SDI application generated by Application Wizard. In the sample, the user can choose any available font in the system and set its styles (bold, italic, underline, etc). The face name of the font will be displayed in the client window using the selected font, and the user can also set the escapement of the font.

Two variables are added to class CGDIDoc: CGDIDoc::m_fontDraw and CGDIDoc::m_colorFont. The first variable is declared as a CFont type variable, it will be used to create the font. The second variable is declared as a COLORREF type variable, it will be used to store the color of the text.

Besides font color, we also need to consider the background color of the text. A text can be displayed with either a transparent or opaque background. In the latter case, we can set the background to different colors. In order to display text in different styles, another Boolean type variable CGDIDoc:: m_bTransparentBgd is declared, it will be used to indicate if the background is transparent or opaque.

The following is the modified class CGDIDoc:

(Code omitted)

Besides the three new member variables, there are also three new member functions added to the class. These functions allow the information stored in CGDIDoc to be accessible outside the class, they are CGDIDoc ::GetCurrentFont(), CGDIDoc::GetFontColor() and CGDIDoc::GetBgdStyle().

The above variables are initialized in the constructor of class CGDIDoc:

(Code omitted)

When a DC is created, it selects the default font, pen, brush and other GDI objects. So here we create a DC that does not belong to any window, and call function CDC::GetCurrentFont() to obtain its currently selected font (which is the default font). Then function CFont::GetLogFont(...) is called to retrieve the font information, which is stored in a LOGFONT type object. With this object, we can create a system default font by calling function CFont::CreateFontIndirect(...). By default, the font color is set to black and the text background mode is set to transparent.

We need to provide a way of letting user modify the font styles. This can be easily implemented by using a font common dialog box. In the sample, two commands are added to the application: Font | Select and Font | Escapement and Orientation, whose IDs are ID_FONT_SELECT and ID_FONT_STYLE respectively. Also, message handlers are added through using Class Wizard, the corresponding functions are CGDIDoc::OnFontStyle() and CGDIDoc::OnFontSelect().

Function CGDIDoc::OnFontSelect() lets the user select a font, set its styles, and specify the text color. It is impelemented as follows:

(Code omitted)

A font common dialog is implemented to let the user pick up a font. If a font is selected, function CFontDialog::GetCurrentFont(...) is called to retrieve the information of the font, which is stored in a LOGFONT type object. Because member m_fontDraw is already initialized, we need to delete the old font before creating a new one. The font is created by calling function CFont::CreateFontIndirect(...). After this the color of the font is retrieved by calling function CFontDialog::GetColor(), and stored in the variable CGDIDoc::m_colorFont. Finally function CDocument::UpdateAllViews(...) is called to update the client window of the application.

Since font common dialog box does not contain escapement and orientation choices, we have to implement an extra dialog box to let the user set them. In the sample, dialog template IDD_DIALOG_STYLE is added for this purpose. Within this template, besides the default "OK" and "Cancel" buttons, there are two other controls included in the dialog box: edit box IDC_EDIT_ESP, which allows the user to set escapement angle; check box IDC_CHECK, which allows the user to select text background style (transparent or opaque). A new class CStyleDlg is added for this dialog template, within which two variables m_lEsp (long type) and m_bBgdStyle (Boolean type) are declared. Both of them are added through using Class Wizard, and are associated with controls IDC_EDIT_ESP and IDC_CHECK respectively.

Command Font | Escapement and Orientation is implemented as follows:

(Code omitted)

First function CFont::GetLogFont(...) is called to retrieve the information of the current font, which is then stored in a LOGFONT type object. Before the dialog box is invoked, its members CStyleDlg::m_lEsp and CStyleDlg::m_bBgdStyle are initialized so that the current font's escapement angle and background style will be displayed in the dialog box. After function CDialog::DoModal() is called, the new value of CStyleDlg::m_lEsp is stored back to members lfEscapement and lfOrientation of structure LOGFONT, and the new value of CStyleDlg::m_bBgdStyle is stored to variable CGDIDoc::m_bTransparentBgd. Then the old font is deleted and the new font is created. Finally, function CGDIDoc::UpdateAllViews(...) is called to update the client window.

When we call function CDocument::UpdateAllViews(...), the associated view's member function OnDraw(...) will be called automatically. So we need to modify this function to display the font specified by variable CGDIDoc::m_fontDraw. The following is the implementation of function CGDIView::OnDraw():

(Code omitted)

First, function CGDIDoc::GetCurrentFont() is called to retrieve the currently selected font from the document, then function CFont::GetLogFont(...) is called to retrieve the information of this font (the face name of the font will be used as the output string). Next, the font is selected into the target DC. Also, CGDIDoc::GetFontColor() is called to retrieve the current font color, and CDC::SetTextColor(...) is called to set the text foreground color. Then, CGDIDoc::GetBgdStyle(...) is called to see if the text should be drawn with an opaque or transparent background, and CDC::SetBkMode(...) is called to set the background style. Next, the text background color is set to the inverse of the foreground color by calling function CDC::SetBkColor(...) (If text background style is transparent, this operation has no effect). Finally, function CDC::TextOut(...) is called to display font's face name in the client window, and the font is selected out of the DC.

The default font displayed in the client window should be "System", which is not a True Type font. To see how a text can be displayed with different escapement angles, we need to choose a True Type font such as "Arial". Please note that the unit of the escapement angle is on tenth of a degree, so if we want to display the text vertically, escapement angle should be set to 900.

2 Enumerating Fonts in the System

Font Types

There are three type of fonts in Windows( system: raster font, vector font and True Type font. The difference among them is how the character glyph is stored for each type of fonts. For raster fonts, the glyph is simply a bitmap; for vector fonts, the glyph is a collection of end points that define the line segments; for true type fonts, the glyph is a collection of line and curve commands. The

Page : 1 Next >>