Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleDraw rainbow shaded text in Visual Basic .NET
DescriptionThis example shows how to draw rainbow shaded text in Visual Basic .NET.
Keywordscolor, rainbow, text, string, VB.NET
CategoriesGraphics, VB.NET
 
The following code draws the text when the form repaints. It starts by creating a big font.

Next the code gets some information about the font's dimensions. See my book Visual Basic 2005 Programmer's Reference for a detailed discussion but briefly these values are:

internal_leading
Space above the characters that is still considered part of the character's height
em_height
The height of the characters from below the internal_leading to the bottom of the descenders (for example, where g and j descend below the baseline)
ascent
The height of the characters from the baseline to the top of the drawing area including the internal leading
descent
The distance the characters may extend below the baseline
cell_height
The total height of the text from bottom to top including the internal leading and descent
line_spacing
The distance between the top of one line of text and the top of the next line of text
external_leading
The distance between the bottom of one line of text (including descent) and the top of the next line of text (including internal leading)

After calculating the font metrics, the code determines where the actual text will be drawn. The text in this example doesn't use descenders so the text goes from below the internal leading to the baseline. However real fonts often leave extra space below the internal leading, drop below the baseline, and otherwise violate their metrics slightly. The ways this happens depends on the particular font and its characteristics (bold, italic, and so forth). This example fudges the drawing area down a bit to get a better fit to the actual text.

The code makes a linear gradient brush to fill the text area. It shades the colors red, orange, yellow, green, blue, and indigo (violet looked too pale) over this area. The code maps red and indigo to two positions at the ends of the region so the top of the characters is a bit extra red and the bottom is a tad extra indigo.

Finally, the code draws the text using the rainbow brush. Extra debugging code draws the text's drawing area, internal leading line, baseline, and descent line.

 
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.PaintEventArgs) Handles _
    MyBase.Paint
    Const TXT As String = "RAINBOW!"
    Dim the_font As New Font("Times New Roman", 150, _
        FontStyle.Bold, GraphicsUnit.Pixel)

    ' Get font metrics.
    ' (See my book "Visual Basic 2005 Programmer's
    ' Reference"
    '  page 609 for more information on font metrics.
    '  See http://www.vb-helper.com/vb_prog_ref.htm 
    '  for more about the book.)
    Dim em_height As Integer = _
        the_font.FontFamily.GetEmHeight(FontStyle.Bold)
    Dim em_height_pix As Single = the_font.Size
    Dim design_to_pixels As Single = the_font.Size / _
        em_height
    Dim ascent As Integer = _
        the_font.FontFamily.GetCellAscent(FontStyle.Bold)
    Dim ascent_pix As Single = ascent * design_to_pixels
    Dim descent As Integer = _
        the_font.FontFamily.GetCellDescent(FontStyle.Bold)
    Dim descent_pix As Single = descent * design_to_pixels
    Dim cell_height_pix As Single = ascent_pix + descent_pix
    Dim internal_leading_pix As Single = cell_height_pix - _
        em_height_pix
    Dim line_spacing As Integer = _
        the_font.FontFamily.GetLineSpacing(FontStyle.Bold)
    Dim line_spacing_pix As Single = line_spacing * _
        design_to_pixels
    Dim external_leading_pix As Single = line_spacing_pix - _
        cell_height_pix

    ' See how big the text is.
    Dim text_size As SizeF = e.Graphics.MeasureString(TXT, _
        the_font)
    Dim x0 As Integer = CInt((Me.ClientSize.Width - _
        text_size.Width) / 2)
    Dim y0 As Integer = CInt((Me.ClientSize.Height - _
        text_size.Height) / 2)

    ' Get the Y coordinates that the brush should span.
    Dim brush_y0 As Integer = CInt(y0 + _
        internal_leading_pix)
    Dim brush_y1 As Integer = CInt(y0 + ascent_pix)

    ' Fudge the brush down a smidgen.
    brush_y0 += CInt(internal_leading_pix)
    brush_y1 += 5

    ' Make a brush to color the area.
    Dim the_brush As New LinearGradientBrush( _
        New Point(x0, brush_y0), _
        New Point(x0, brush_y1), _
        Color.Red, Color.Violet)
    Dim color_blend As New ColorBlend
    color_blend.Colors = New Color() {Color.Red, Color.Red, _
        Color.Orange, Color.Yellow, Color.Green, _
        Color.Blue, Color.Indigo, Color.Indigo}
    color_blend.Positions = New Single() {0, 1 / 7, 2 / 7, _
        3 / 7, 4 / 7, 5 / 7, 6 / 7, 1}
    the_brush.InterpolationColors = color_blend

    ' Draw the text.
    e.Graphics.DrawString(TXT, the_font, the_brush, x0, y0)

#If False Then
    ' Debugging statements.
    ' Fill a rainbow rectangle for reference.
    e.Graphics.FillRectangle(the_brush, x0, brush_y0, 10, _
        brush_y1 - brush_y0)

    ' Outline the text area.
    e.Graphics.DrawRectangle(Pens.Blue, x0, y0, _
        text_size.Width, text_size.Height)

    ' Draw the internal leading line.
    Dim y As Single
    y = y0 + internal_leading_pix
    e.Graphics.DrawLine(Pens.Red, x0, y, x0 + _
        text_size.Width, y)

    ' Draw the internal baseline.
    y = y0 + ascent_pix
    e.Graphics.DrawLine(Pens.Red, x0, y, x0 + _
        text_size.Width, y)

    ' Draw the internal descent line.
    y = y0 + cell_height_pix
    e.Graphics.DrawLine(Pens.Red, x0, y, x0 + _
        text_size.Width, y)
#End If

    the_brush.Dispose()
    the_font.Dispose()
End Sub
 
 
Copyright © 1997-2006 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated