Advanced Typography in GDI+


This article has been excerpted from book "Graphics Programming with GDI+".

Beside 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.

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 families and add to the combo box


for
(int i =0; i < fontFamilies.Length; i++)
{
        comboBox1.Items.Add(FontFamilies[i].Name);
}


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 Windows\Fonts directory. On our test machine, all fonts are installed in the directory C:\WinNT\Fonts. You can also browse and add fonts from other location 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.15 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


using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Drawing.Text;
using
System.Linq;
using
System.IO;
using
System.Text;
using
System.Windows.Forms;

namespace
WindowsFormsApplication1
{
    public partial class Form1 :
Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs 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 output of the application. All the available fonts in the private collection are listed.

Figure 5.18.gif

FIGURE 5.18: Using a private font collection

Conclusion

Hope the article would have helped you in understanding Advanced Typography in GDI+. Read other articles on GDI+ on the website.

bookGDI.jpg This book teaches .NET developers how to work with GDI+ as they develop applications that include graphics, or that interact with monitors or printers. It begins by explaining the difference between GDI and GDI+, and covering the basic concepts of graphics programming in Windows.


Similar Articles
Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.