Example: Enumerating Font Families


In this section, you work through a quick example, EnumFontFamilies, which lists all the font families available on the system and illustrates them by displaying the name of each family using an appropriate font (the 10-point regular version of that font family). Figure 30-16 shows the result of running EnumFontFamilies.

image from book
Figure 30-16

Of course, the results that you get will depend on the fonts you have installed on your computer.

For this example you, as usual, create a standard C# Windows Application, EnumFontFamilies. You start off by adding an extra namespace to be searched. You will be using the InstalledFontCollection class, which is defined in System.Drawing.Text.

 using System; using System.Drawing; using System.Drawing.Text; 

You then add the following constant to the Form1 class:

  private const int margin = 10; 

margin is the size of the left and top margin between the text and the edge of the document - it stops the text from appearing right at the edge of the client area.

This is designed as a quick-and-easy way of showing off font families; therefore, the code is crude and in many instances doesn’t do things the way you ought to in a real application. For example, here you hard-code an estimated value for the document size of (200,1500) and set the AutoScrollMinSize property to this value using the Visual Studio 2005 properties window. Normally, you would have to examine the text to be displayed to work out the document size. You do that in the next section.

Here is the OnPaint() method:

 protected override void OnPaint(PaintEventArgs e) {    base.OnPaint(e);    int verticalCoordinate = margin;    Point topLeftCorner;    InstalledFontCollection insFont = new InstalledFontCollection();    FontFamily [] families = insFont.Families;    e.Graphics.TranslateTransform(AutoScrollPosition.X,                                  AutoScrollPosition.Y);    foreach (FontFamily family in families)    {       if (family.IsStyleAvailable(FontStyle.Regular))       {          Font f = new Font(family.Name, 12);          topLeftCorner = new Point(margin, verticalCoordinate);          verticalCoordinate += f.Height;          e.Graphics.DrawString (family.Name, f,                                 Brushes.Black,topLeftCorner);          f.Dispose();       }    } } 

In this code, you start off by using an InstalledFontCollection object to obtain an array that contains details of all the available font families. For each family, you instantiate a 12-point Font. You use a simple constructor for Font - there are many more that allow additional options to be specified. The constructor takes two parameters, the name of the family and the size of the font:

  Font f = new Font(family.Name, 12); 

This constructor builds a font that has the regular style. To be on the safe side, however, you first check that this style is available for each font family before attempting to display anything using that font. This is done using the FontFamily.IsStyleAvailable() method. This check is important, because not all fonts are available in all styles:

  if (family.IsStyleAvailable(FontStyle.Regular)) 

FontFamily.IsStyleAvailable() takes one parameter, a FontStyle enumeration. This enumeration contains a number of flags that might be combined with the bitwise OR operator. The possible flags are Bold, Italic, Regular, Strikeout, and Underline.

Finally, note that you use a property of the Font class, Height, which returns the height needed to display text of that font, in order to work out the line spacing:

 Font f = new Font(family.Name, 12); topLeftCorner = new Point(margin, verticalCoordinate); verticalCoordinate += f.Height; 

Again, to keep things simple, this version of OnPaint() reveals some bad programming practices. For a start, you haven’t bothered to check what area of the document actually needs drawing - you just try to display everything. Also, instantiating a Font is, as remarked earlier, a computationally intensive process, so you really ought to save the fonts rather than instantiating new copies every time OnPaint() is called. As a result of the way the code has been designed, you might note that this example actually takes a noticeable time to paint itself. To try to conserve memory and help the garbage collector out you do, however, call Dispose() on each font instance after you have finished with it. If you didn’t, after 10 or 20 paint operations, there’d be a lot of wasted memory storing fonts that are no longer needed.




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net