Text (Part  1)

Text in GDI+ is easy to use and looks great. GDI+ takes advantage of text rendering options that provide clear and readable type with a number of layout options.

There are three main concepts that are important to understanding rudimentary typography for GDI+ and Windows Forms applications. These are the measurement systems involved, the way fonts are used and the way formatting works. Figure 1 shows some common typography terms in relation to various fonts.

Figure 1. A typography primer.

Measurements

Font sizes are usually expressed in points. The font size is the height of the fonts bounding em square. Em is pronounced like the letter "M". Traditionally the uppercase M was the largest single character in  in the typeface. This may not be the case anymore but the name has stuck. The Font object is the GDI+ container for a font which is created from a FontFamily that contains the description for the font.

Text layout is usually performed in points or at least some real-world layout method. The article on coordinate systems explains the standard measurements. It is important to remember that layouts in pixels are subject to unwanted variations because the pixel size on a screen is different to that of a printer. It's a good idea therefore to use a real-world measurement system. Because Points are all about printers measurements, these are the obvious choice for text layout coordinates. There's nothing to prevent you using other coordinates but you need to be aware of all the intricacies of the relationships between those systems and the size of the type.

Rendering fonts is an incredibly complex subject and it would be impossible to deal with it in detail in this article but in general, a font file is a complex description of a collection of glyphs that describe the characters in the font. Some characters use more than one glyph and it's even possible that the glyphs used for each character might change depending on the character that precedes of follows it. When you create a font by specifying the font family and size, the system creates descriptions of all the glyphs in the font that are adapted for the size and resolution of the output device. This is how a true-type font can maintain it's quality at 10 points or 1/7th of an inch in height and look good at 144 points or 2 inches high. Figure 2 illustrates this by showing the difference between 10 and 36 point type.

10 Point Verdana

18 Point Verdana

36 Point Verdana

Figure 2. Font rendering at different sizes.

You can clearly see that the quality of the 10 point type is good even though the number of pixels used to display the type is low. When there are more pixels available the renderer uses a set of glyphs that have been constructed to take advantage of that extra resolution so the font quality is good at all sizes. This is because whenever you create a font object, the resolution, size and other details are taken into account to give the best possible result.

Using fonts

The first step is to create a Font object using the desired typeface. This can be accomplished in several ways but the simplest constructor for a font requires nothing more than a font-family name and a size.

Font fn=new Font("Times New Roman",10);
Dim fn As New Font("Times New Roman",10)

This creates a font with the default parameters and sets the size to 10 points in height. When a font is created you can use it to draw a string onto any Graphics object using the DrawString method. DrawString has several overloads that enable you to place text at a particular position or in a destination rectangle with various formatting options. The simplest option is to use the world coordinates and the currently selected page units to position the text. The following listing prints "Hello World!" on the form. Figure 3 shows the application at work.

    private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

    {

      Font fn=new Font("Times New Roman",10);

 

      e.Graphics.DrawString("Hello World!",fn,Brushes.Black,10,10);

 

      fn.Dispose();

    }

 

 

  Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

    Dim fn As New Font("Times New Roman", 10)

    e.Graphics.DrawString("Hello World!", fn, Brushes.Black, 10, 10)

    fn.Dispose()

  End Sub

 

Figure 3. Simple text display.

The text in this example is located with its top-left corner at the declared position. No formatting is provided so there is no limit to the limit that the right side of the text might be placed and depends only on the length of the string. GDI+ provides several ways that a paragraph of text might be formatted into a given area.

Formatting.

There are two factors that control the placement of formatted text. The destination rectangle and the StringFormat object used to specify the formatting parameters. A simple paragraph of text can be formatted into a given rectangle quite simply and the StringFormat object enables you to chose the horizontal and vertical alignment plus some other options that affect the way text is seen. There are three basic formats. Near, Center and Far. These are so called because some languages require right alignment and right to left reading orientation for normal text so the equivalent of a left-aligned paragraph in a Western European language would be right aligned in a language such as Hebrew. Therefore the alignments are called Near for alignment to the starting side of the page and Far for alignment toward the ending side of the page. Figure 4 shows a paragraph of text formatted into the centre of the client rectangle of a form.

 

Figure 4. Formatted text.

When the application shown in Figure 4 is resized the text is automatically redrawn to fit a rectangle that is 20 pixels smaller in both height and width than the client rectangle of the form. The text is centred horizontally by using a StringFormat object with the Alignment property set to StringAlignment.Center. It is also centred vertically by setting the VerticalAlignment property of the StringFormat object to StringAlignment.Center.

In addition to the physical alignment, the StringFormat object can be made to display an ellipsis character "..." whenever it cannot fit the text string into the box specified. This is controlled by the StringFormat.Trimming property and the StringTrimming enumeration members. StringFormat is complex enough to warrant an article on its own later in this series.

The code shown in the following listing is the Paint handler for the form shown in Figure 4. Note that in order to make this application re-draw its text as the window is resized, the form specifies a control style setting of ControlStyles.ResizeRedraw in the constructor of the form

 

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

{

  Font fn=new Font("Times New Roman",10);

  string str= "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla facilisi. " +

  "Quisque dolor leo, sollicitudin a, porta vel, faucibus id, nunc. Suspendisse mollis nonummy " +

  "tellus. Sed auctor pulvinar odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices " +

  "posuere cubilia Curae; Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin lorem lacus, "   +

  "mattis et, cursus ut, viverra faucibus, purus. Sed feugiat mauris quis velit. Etiam iaculis hendrerit "  +

  "urna. Vivamus volutpat dui vel est. Sed dictum est in metus. Nullam facilisis aliquet turpis. " +

  "Duis varius enim ut orci. Donec lorem ligula, pellentesque ac, sodales at, ornare non, lacus. Vivamus rutrum aliquam leo. ";

  StringFormat sf=(StringFormat)StringFormat.GenericTypographic.Clone();

  sf.Alignment=StringAlignment.Center;

  sf.LineAlignment=StringAlignment.Center;

  sf.Trimming=StringTrimming.EllipsisWord;

  e.Graphics.DrawString(str, fn, Brushes.Black,

                        new RectangleF(10,10,this.ClientRectangle.Width-20,this.ClientRectangle.Height-20),

                        sf);

  fn.Dispose()

}

 

  Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

    Dim fn As New Font("Times New Roman", 10)

    Dim str As String = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla facilisi. " & _

    "Quisque dolor leo, sollicitudin a, porta vel, faucibus id, nunc. Suspendisse mollis nonummy " & _

    "tellus. Sed auctor pulvinar odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices " & _

    "posuere cubilia Curae; Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin lorem lacus, " & _

    "mattis et, cursus ut, viverra faucibus, purus. Sed feugiat mauris quis velit. Etiam iaculis hendrerit " & _

    "urna. Vivamus volutpat dui vel est. Sed dictum est in metus. Nullam facilisis aliquet turpis. " & _

    "Duis varius enim ut orci. Donec lorem ligula, pellentesque ac, sodales at, ornare non, lacus. Vivamus rutrum aliquam leo. "

    Dim sf As StringFormat = CType(StringFormat.GenericTypographic.Clone(), StringFormat)

    sf.Alignment = StringAlignment.Center

    sf.LineAlignment = StringAlignment.Center

    e.Graphics.DrawString(str, fn, Brushes.Black, New RectangleF(10, 10, Me.ClientRectangle.Width - 20, Me.ClientRectangle.Height - 20), sf)

    fn.Dispose()

  End Sub

 

Summary

So far in this article you've seen that fonts are managed in a Font object, that they are usually measured in Points and that they may be drawn with or without formatting using the DrawString method and optional StringFormat objects. The subject of typography is so complex that it cannot be dealt with in any depth in this series of articles however later in the series you'll see a lot more information on text formatting and why the image in Figure 1 is of such importance.

Return to the Beginners Guide index.