Example: Enumerating Font Families

 
Chapter 19 - Graphics with GDI+
bySimon Robinsonet al.
Wrox Press 2002
  

In this section, we will 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). When the sample is run it will look something like this:

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

For this sample we have as usual created a standard C# Windows Application - this time named EnumFontFamilies . We start off by adding an extra namespace to be searched. We will be using the InstalledFontCollection class, which is defined in System.Drawing.Text .

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

We then add the following constant to the Form1 class:

   private const int margin = 10;   

margin will be 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 cases doesn't do things the way you ought to in a real application. For example, I've just hard-coded in a guessed value for the document size of (200,1500) and set the AutoScrollMinSize property to this value using the Visual Studio .NET Properties window. Normally you would have to examine the text to be displayed to work out the document size. We will 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, 10);     topLeftCorner = new Point(margin, verticalCoordinate);     verticalCoordinate += f.Height;     e.Graphics.DrawString (family.Name, f,     Brushes.Black,topLeftCorner);     f.Dispose();     }     }     }   

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

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

This constructor constructs a font that has the regular style. To be on the safe side, however, we 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, and 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 may be combined with the bitwise OR operator. The possible flags are Bold , Italic , Regular , Strikeout , and Underline .

Finally, note that we 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, 10);                topLeftCorner = new Point(margin, verticalCoordinate);   verticalCoordinate += f.Height;   

Again, to keep things simple, our version of OnPaint() reveals some bad programming practices. For a start, we haven't bothered to check what area of the document actually needs drawing - we just try to display everything. Also, instantiating a Font is, as remarked earlier, a computationally intensive process, so we 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 may notice that this example actually takes a noticeable time to paint itself. In order to try to conserve memory and help the garbage collector out we do, however, call Dispose() on each font instance after we have finished with it. If we didn't, then after 10 or 20 paint operations, there'd be a lot of wasted memory storing fonts that are no longer needed.

  


Professional C#. 2nd Edition
Performance Consulting: A Practical Guide for HR and Learning Professionals
ISBN: 1576754359
EAN: 2147483647
Year: 2002
Pages: 244

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