Advanced Typography
Besides the text functionality defined in the System.Drawing namespace, the .NET Framework class library defines more advanced typography functionality in the System.Drawing.Text namespace. As usual, before using any of the System.Drawing.Text classes or other objects, you need to add a namespace reference to the project.
The System.Drawing.Text namespace provides three font collection classes: FontCollection, InstalledFontCollection, and PrivateFontCollection. The FontCollection class works as a base class for the other two classes and provides a property (Families) that returns an array containing a list of all font families in the collection.
The InstalledFontCollection class represents all the fonts installed on the system. The Families property returns a collection of all font families available on the system.
Note
Before using any of the System.Drawing.Text namespace classes, an application must add a reference to the namespace with the "using" directive:
using System.Drawing.Text;
Alternatively, you can qualify a class using the namespace as a prefix.
5.6.1 Getting All Installed Fonts on a System
As stated in the previous section, the InstalledFontCollection class represents all available font families on a system. The Families property returns an array of FontFamily type.
Listing 5.13 returns all available fonts on a system. To test this application, add a combo box to a form and write this code on the form-load event handler or a button or menu click event handler. using System.Drawing.Text Before executing this code, an application must add the following line:
using System.Drawing.Text
Listing 5.13 Using InstalledFontCollection to get all installed fonts on a system
// Create InstalledFontCollection object InstalledFontCollection sysFontCollection = new InstalledFontCollection(); // Get the array of FontFamily objects FontFamily[] fontFamilies = sysFontCollection.Families; // Read all font familes and add to the combo box for(int i = 0; i < fontFamilies.Length; ++i) { comboBox1.Items.Add(fontFamilies[i].Name); }
5.6.2 Private Font Collection
The PrivateFontCollection class is used to create a private collection of fonts, for use only by your application. A private collection may include the fonts available on a system, as well as fonts that are not installed on the system. Such a collection is useful when you want to use third-party fonts. The AddFontFile method is used to add a font file to the collection. The AddMemoryFont method reads fonts from system memory and adds them to the collection. The IsStyleAvailable method, which takes a FontStyle enumeration value, indicates whether a style is available.
Normally all system fonts are installed in your WindowsFonts directory. On our test machine, all fonts are installed in the directory C:WinNTFonts. You can also browse and add fonts from other locations to a private font collection by passing the full path of the font file in the AddFontFile method. For example, the following code snippet adds four fonts to a private font collection.
// Create a private font collection PrivateFontCollection pfc = new PrivateFontCollection(); // Add font files to the private font collection pfc.AddFontFile("tekhead.ttf"); pfc.AddFontFile("DELUSION.TTF"); pfc.AddFontFile("HEMIHEAD.TTF"); pfc.AddFontFile("C:\WINNT\Fonts\Verdana.ttf");
In this code we add four fonts to the private font collection. Verdana is available on all machines. The other three fonts can be downloaded from http://www.fontfreak.com (click Enter on site's home page to access naviagation area).
You can even add styles to an existing font. In Listing 5.14 we add four fonts to the private font collection with the AddFontFile method. Then we see if these font families have different styles. If not, we add new styles to the font families and draw text using the new fonts. In the end, we print out the font name on the form.
Listing 5.14 Using the PrivateFontCollection class
private void menuItem2_Click(object sender, System.EventArgs e) { Graphics g = this.CreateGraphics(); PointF pointF = new PointF(10, 20); string fontName; // Create a private font collection PrivateFontCollection pfc = new PrivateFontCollection(); // Add font files to the private font collection pfc.AddFontFile("tekhead.ttf"); pfc.AddFontFile("DELUSION.TTF"); pfc.AddFontFile("HEMIHEAD.TTF"); // MAKE SURE YOU HAVE THE Verdana.ttf FILE IN THE SPECIFIED // FOLDER, OR CHANGE THE FOLDER LOCATION pfc.AddFontFile("C:\WINNT\Fonts\Verdana.ttf"); // Return all font families from the collection FontFamily[] fontFamilies = pfc.Families; // Get font families one by one, // add new styles, and draw // text using DrawString for(int j = 0; j < fontFamilies.Length; ++j) { // Get the font family name fontName = fontFamilies[j].Name; if(fontFamilies[j].IsStyleAvailable( FontStyle.Italic) && fontFamilies[j].IsStyleAvailable( FontStyle.Bold) && fontFamilies[j].IsStyleAvailable( FontStyle.Underline) && fontFamilies[j].IsStyleAvailable( FontStyle.Strikeout) ) { // Create a font from the font name Font newFont = new Font(fontName, 20, FontStyle.Italic | FontStyle.Bold |FontStyle.Underline, GraphicsUnit.Pixel); // Draw string using the current font g.DrawString(fontName, newFont, new SolidBrush(Color.Red), pointF); // Set location pointF.Y += newFont.Height; } } // Dispose of object g.Dispose(); }
Note
You may need to change the directory path in Listing 5.14 to match your machine.
To test Listing 5.14, create a Windows application and insert the sample code on the form-paint, a button click, or a menu click event handler, and run the application. Figure 5.18 shows the ouput of the application. All the available fonts in the private font collection are listed.
Figure 5.18. Using a private font collection