Text Formatting


Some of the overloaded versions of the Graphics object’s DrawString method take additional parameters that help format the text. The first of these parameters is a layout rectangle. This is a RectangleF structure that indicates the area where the text should be drawn. The second parameter is a StringFormat object that determines how the text is formatted.

The following code draws text inside a rectangle. It begins by defining the layout rectangle, text, and font. It then creates a StringFormat object. It sets the object’s Alignment property to Center to position each line of text centered horizontally in the layout rectangle. It sets the object’s LineAlignment property to Near. That makes the text align vertically to the near vertical edge of the rectangle (its top). The program calls DrawString to draw the text and then uses DrawRectangle to display the layout rectangle.

Tip 

The Alignment and LineAlignment properties both can take the values Near, Center, and Far. Using these values for both properties can make the properties somewhat confusing. On systems that draw right to left and top to bottom, the values are relative to a point in the upper-left corner of the text, so Near means left/top, Center means center/center, and Far means right/bottom.

  Private Sub Form1_Paint(ByVal sender As Object, _  ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint     Dim layout_rect As New RectangleF(10, 10, _         Me.ClientSize.Width - 20, Me.ClientSize.Height - 20)     Dim txt As String = "The quick brown fox jumps over the lazy dog."     Using big_font As New Font("Times New Roman", 30, FontStyle.Bold)         Using string_format As New StringFormat             string_format.Alignment = StringAlignment.Center             string_format.LineAlignment = StringAlignment.Near             e.Graphics.DrawString(txt, big_font, Brushes.Black, _                 layout_rect, string_format)             e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(layout_rect))         End Using ' string_format     End Using ' big_font End Sub 

Figure 22-3 shows the result. Notice that the text is centered horizontally and aligned to the top of the layout rectangle.

image from book
Figure 22-3: The DrawString method can use a layout rectangle and a StringFormat object to format text.

The StringFormat object provides several other properties and methods that you can use to position text. The following table describes the most useful of these.

Open table as spreadsheet

Property or Method

Purpose

Alignment

Determines the text’s horizontal alignment. This can be Near (left), Center (middle), or Far (right).

FormatFlags

Gets or sets flags that modify the StringFormat object’s behavior. See the section “FormatFlags” later in this chapter for more information.

GetTabStops

Returns an array of Singles, giving the positions of tab stops. See the section “Tab Stops” later in this chapter for more information.

HotkeyPrefix

Determines how the hotkey prefix character is displayed. (In a menu caption or label, the hotkey is underlined to show that pressing Alt-<hotkey> performs some special action. For example, in most applications Alt-F opens the File menu. A program specifies a control’s hotkey character by placing an ampersand in front of it. For example, “&File” is displayed as “File.”) If HotkeyPrefix is Show, any character that follows an ampersand is drawn as an underlined hotkey (a double ampersand is drawn as a single ampersand). If this is None, any ampersands are drawn as ampersands. If this is Hide, hotkey ampersands are hidden.

LineAlignment

Determines the text’s vertical alignment. This can be Near (top), Center (middle), or Far (bottom).

SetMeasureableCharacterRanges

Sets an array of CharacterRange structures representing ranges of characters that will later be measured by the Graphics object’s MeasureCharacterRanges method.

SetTabStops

Sets an array of Singles giving the positions of tab stops. See the section “Tab Stops” later in this chapter for more information.

Trimming

Determines how the text is trimmed if it cannot fit in the layout rectangle. See the section “Trimming” later in this chapter for more information.

The following sections describe some of the more complex formatting issues in greater detail.

FormatFlags

The StringFormat object’s FormatFlags property determines the object’s behavior. This property can take a bitwise combination of the values described in the following table.

Open table as spreadsheet

FormatFlags Value

Purpose

DirectionRightToLeft

Indicates that the text is drawn from right to left.

DirectionVertical

Indicates that the text is drawn vertically.

FitBlackBox

Indicates that no character should extend beyond the layout rectangle. If this is not set, some characters in certain fonts may stick out a bit.

LineLimit

If the last line displayed in the layout rectangle is too tall to fit, this flag indicates that it should be omitted. By default, that line is clipped to show whatever parts will fit.

MeasureTrailingSpaces

Indicates that the Graphics object’s MeasureString method should include spaces at the ends of lines. By default, it does not.

NoClip

Indicates that parts of characters that hang over the layout rectangle are not clipped.

NoFontFallback

If a character is missing from the selected font, the GDI+ normally looks for an equivalent character in another font. This flag prevents that and forces the character to be displayed as the font’s missing character glyph (usually an open square).

NoWrap

Indicates that text should not be wrapped.

Figure 22-4 shows the difference between the default, NoClip, and LineLimit flags. If the last visible line won’t fit within the layout rectangle, the default behavior is to clip the line to show whatever fits. If FormatFlags is NoClip, that line is displayed entirely. If FormatFlags is LineLimit, the line is omitted entirely.

image from book
Figure 22-4: The NoClip and LineLimit flags change how a StringFormat object handles the text’s last displayed line.

The following code uses the DirectionVertical flag. After defining a string, font, and layout rectangle, it creates a StringFormat object. It sets the object’s Alignment and LineAlignment properties to center the text and then sets its FormatFlags property to the combination of the values DirectionVertical and DirectionRightToLeft. Then the program draws the text as usual.

  Private Sub Form1_Paint(ByVal sender As Object, _  ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint     Dim txt As String = "The quick brown fox jumps over the lazy dog."     Dim layout_rect As New RectangleF(0, 0, _         Me.ClientSize.Width - 1, Me.ClientSize.Height - 1)     Using the_font As New Font("Times New Roman", 30, _         FontStyle.Bold, GraphicsUnit.Pixel)         Using string_format As New StringFormat             string_format.Alignment = StringAlignment.Center             string_format.LineAlignment = StringAlignment.Center             string_format.FormatFlags = _                 StringFormatFlags.DirectionVertical Or _                 StringFormatFlags.DirectionRightToLeft             e.Graphics.TextRenderingHint = _                 System.Drawing.Text.TextRenderingHint.AntiAliasGridFit             e.Graphics.DrawString(txt, the_font, Brushes.Black, _                 layout_rect, string_format)         End Using ' string_format     End Using ' the_font End Sub 

Figure 22-5 shows the result.

image from book
Figure 22-5: Setting the StringFormat object’s FormatFlags property to DirectionVertical produces vertical text.

This example sets the FormatFlags property to DirectionVertical plus DirectionRightToLeft. If you omit the second flag, the lines of text are drawn left to right. That means the line “The quick” appears on the left and the subsequent lines appear moving to the right, so the lines are drawn in the reverse of the order that you might expect.

Note that you can also draw vertical text by applying a transformation to the Graphics object that translates the text to the origin, rotates it, and translates the text back to where it belongs.

The following code demonstrates this technique. It defines its layout rectangle, text, and font. It uses the form’s width to define the rectangle’s height and the form’s height to define the rectangle’s width, so the rectangle will fit the form after it is rotated. The code creates a StringFormat object to center the text and applies the transformations to the Graphics object. Finally, the code draws the text. The result is similar to the text produced by the previous example.

  Private Sub Form1_Paint(ByVal sender As Object, _  ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint     ' Define the layout rectangle. It's slightly smaller     ' than the form rotated 90 degrees so the rotated     ' text will fit the form nicely.     Dim rect_wid As Integer = Me.ClientSize.Height - 20     Dim rect_hgt As Integer = Me.ClientSize.Width - 20     Dim layout_rect As New RectangleF( _         (Me.ClientSize.Width - rect_wid) \ 2, _         (Me.ClientSize.Height - rect_hgt) \ 2, _         rect_wid, rect_hgt)     ' Define the text and font.     Dim txt As String = "The quick brown fox jumps over the lazy dog."     Using the_font As New Font("Times New Roman", 30, _         FontStyle.Bold, GraphicsUnit.Pixel)         ' Set the StringFormat to center the text.         Using string_format As New StringFormat             string_format.Alignment = StringAlignment.Center             string_format.LineAlignment = StringAlignment.Center             ' Translate to the origin, rotate, and translate back.             e.Graphics.TranslateTransform( _                 -Me.ClientSize.Width \ 2, _                 -Me.ClientSize.Height \ 2, _                 MatrixOrder.Append)             e.Graphics.RotateTransform(90, MatrixOrder.Append)             e.Graphics.TranslateTransform( _                 Me.ClientSize.Width \ 2, _                 Me.ClientSize.Height \ 2, _                 MatrixOrder.Append)             ' Draw the text and layout rectangle.             e.Graphics.TextRenderingHint = _                 System.Drawing.Text.TextRenderingHint.AntiAliasGridFit             e.Graphics.DrawString(txt, the_font, Brushes.Black, _                 layout_rect, string_format)             e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(layout_rect))         End Using ' string_format     End Using ' the_font End Sub  

This approach is a bit more complicated than the previous method of setting the StringFormat object’s FormatFlags property to DirectionVertical, but it gives you more flexibility. Simply by changing the rotation transformation, you can draw text at any angle, not just rotated 90 degrees. Figure 22-6 shows this program with the angle of rotation changed from 90 to 60 degrees.

image from book
Figure 22-6: Transformations can produce text rotated at any angle.

Tab Stops

The StringFormat object’s GetTabStops and SetTabStops methods let you get and set an array of Singles that determine the position of the layout rectangle’s tab stops. Each entry in the array gives the distance between two tab stops. For example, the values {50, 50, 50} specify tab stops 50, 100, and 150 pixels from the left edge of the layout rectangle.

The following code shows how to use the SetTabStops method. It starts by creating a font, layout rectangle, and StringFormat object. It sets two tab stops 60 and 140 (60 + 80) pixels from the left edge of the layout rectangle. It then draws the rectangle and draws vertical lines showing the positions of the tab stops.

The program generates some random data, separating values on each row with Tab characters and separating each row with Carriage Return/Line Feed pairs. Finally, the program draws the text.

  Private Sub Form1_Paint(ByVal sender As Object, _  ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint     Dim layout_rect As New RectangleF(10, 10, _         Me.ClientSize.Width - 20, Me.ClientSize.Height - 20)     ' Define the font, layout rectangle, and StringFormat.     Using the_font As New Font("Times New Roman", 15, _         FontStyle.Regular, GraphicsUnit.Pixel)         Using string_format As New StringFormat             ' Set the tab stops.             Dim tab_stops() As Single = {60, 80}             string_format.SetTabStops(0, tab_stops)             ' Draw the layout rectangle and tab stops.             e.Graphics.DrawRectangle(Pens.White, Rectangle.Round(layout_rect))             Dim x As Single = layout_rect.X             For i As Integer = 0 To tab_stops.Length - 1                 x += tab_stops(i)                 e.Graphics.DrawLine(Pens.White, _                     x, layout_rect.Top, x, layout_rect.Bottom)             Next i             ' Generate some random values.             Dim rnd As New Random             Dim txt As String = "Alpha" & vbTab & "Gamma" & _                 vbTab & "Value" & vbCrLf             For r As Integer = 1 To 10                 txt &= rnd.Next(10, 99) & vbTab & _                     rnd.NextDouble.ToString("0.000000") & vbTab & _                     rnd.NextDouble.ToString("0.00") & vbCrLf             Next r             ' Draw the text.             e.Graphics.TextRenderingHint = _                 System.Drawing.Text.TextRenderingHint.AntiAliasGridFit             e.Graphics.DrawString(txt, the_font, Brushes.Black, _                 layout_rect, string_format)         End Using ' string_format     End Using ' the_font End Sub 

Figure 22-7 shows the result.

image from book
Figure 22-7: The SetTabStops method lets you easily align text.

Trimming

Normally, a string is wrapped as necessary until its layout rectangle is full. If there is still text that has not been displayed, the Trimming property determines how that text is handled. The following table describes the values this property can take.

Open table as spreadsheet

Trimming Value

Purpose

Character

The text is trimmed to the nearest character.

EllipsisCharacter

The text is trimmed to the nearest character and an ellipsis is displayed at the end of the line.

EllipsisPath

The center of the line is removed and replaced with an ellipsis. This is sometimes a good choice when displaying file paths because it shows the beginning of the path and the file name. This method keeps as much of the last backslash (\) delimited part of the text as possible (it assumes that this is a file name).

EllipsisWord

The text is trimmed to the nearest word and an ellipsis is displayed at the end of the line.

None

The text is not trimmed. Instead, it is wrapped to the next line, which is hidden because it is below the bottom of the layout rectangle. If the last visible line contains a word break, the line will wrap after the last word that fits. That makes this seem similar to the Word setting.

Word

The text is trimmed to the nearest word.

The following code draws samples of the Trimming values. The form’s Paint event handler calls subroutine DrawSample to draw samples of text that contain backslash (\) or space-delimited strings.

Subroutine DrawSample draws the name of the indicated Trimming value. It draws the sample text using the Trimming value in a specified layout rectangle, and then draws the rectangle so that you can see it. The routine finishes by incrementing its parameter Y, so the next sample is drawn below this one.

  Public Class Form1     Private Sub Form1_Load(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles MyBase.Load         Me.ResizeRedraw = True     End Sub     Private Sub Form1_Paint(ByVal sender As Object, _       ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint         Dim layout_rect As RectangleF         e.Graphics.TextRenderingHint = _             System.Drawing.Text.TextRenderingHint.AntiAliasGridFit         Dim txt As String         Using the_font As New Font("Times New Roman", 30, _             FontStyle.Bold, GraphicsUnit.Pixel)             layout_rect = New RectangleF(100, 0, 180, 70)             txt = "ABC\DEF\GHI\JKL\MNO\PQR\STU\VWX\YZ"             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.Character)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.EllipsisCharacter)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.EllipsisPath)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.EllipsisWord)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.None)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.Word)             layout_rect.X += layout_rect.Width + 10             layout_rect.Y = 0             txt = "ABC DEF GHI JKL MNO PQR STU VWX YZ"             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.Character)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.EllipsisCharacter)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.EllipsisPath)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.EllipsisWord)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.None)             DrawSample(e.Graphics, txt, the_font, layout_rect, _                 StringTrimming.Word)         End Using ' the_font     End Sub     Private Sub DrawSample(ByVal gr As Graphics, ByVal txt As String, _       ByVal the_font As Font, ByRef layout_rect As RectangleF, _       ByVal string_trimming As StringTrimming)         Using string_format As New StringFormat             string_format.Trimming = string_trimming             gr.DrawString(string_trimming.ToString, Me.Font, _                 Brushes.Black, 0, layout_rect.Y + 5)             gr.DrawString(txt, the_font, Brushes.Black, layout_rect, _                 string_format)             gr.DrawRectangle(Pens.Black, Rectangle.Round(layout_rect))             layout_rect.Y += layout_rect.Height + 10         End Using ' string_format     End Sub End Class 

Figure 22-8 shows the results.

image from book
Figure 22-8: The StringFormat object’s Trimming property determines how text is trimmed.




Visual Basic 2005 with  .NET 3.0 Programmer's Reference
Visual Basic 2005 with .NET 3.0 Programmer's Reference
ISBN: 470137053
EAN: N/A
Year: 2007
Pages: 417

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