Draw rainbow text in C#

example

This program’s Paint event handler uses the Graphics object’s DrawString method to draw some rainbow text. The brush it uses to draw the text is a LinearGradientBrush filled with a rainbow of colors.

The trickiest part is figuring out exactly where the text will actually appear so the colors cover it nicely. If you define the brush so the colors fill an area that’s too big, the text may not use all of the colors.

To figure out where the text will appear, the code use the FontInfo class described in the post Get font metrics in C#. See that post for detail. It then uses the font metrics to calculate where the brush’s colors must start and end.

The following code shows the example’s Paint event handler.

// Draw the rainbow text.
private void Form1_Paint(object sender, PaintEventArgs e)
{
    const string Txt = "RAINBOW!";

    // Make the result smoother.
    e.Graphics.TextRenderingHint =
        TextRenderingHint.AntiAliasGridFit;

    // Make a font.
    using (Font the_font = new Font("Times New Roman", 75,
        FontStyle.Bold, GraphicsUnit.Pixel))
    {
        // Get the font's metrics.
        FontInfo font_info = new FontInfo(e.Graphics, the_font);

        // See how big the text is.
        SizeF text_size = e.Graphics.MeasureString(Txt, the_font);
        int x0 =
            (int)((this.ClientSize.Width - text_size.Width) / 2);
        int y0 =
            (int)((this.ClientSize.Height - text_size.Height) / 2);

        // Get the Y coordinates that the brush should span.
        int brush_y0 = (int)(y0 + font_info.InternalLeadingPixels);
        int brush_y1 = (int)(y0 + font_info.AscentPixels);

        // Fudge the brush down a smidgen.
        brush_y0 += (int)(font_info.InternalLeadingPixels);
        brush_y1 += 5;

        // Make a brush to color the area.
        using (LinearGradientBrush the_brush =
            new LinearGradientBrush(
                new Point(x0, brush_y0),
                new Point(x0, brush_y1),
                Color.Red, Color.Violet))
        {
            Color[] colors = new Color[]
            {
                Color.FromArgb(255, 0, 0),
                Color.FromArgb(255, 0, 0),
                Color.FromArgb(255, 128, 0),
                Color.FromArgb(255, 255, 0),
                Color.FromArgb(0, 255, 0),
                Color.FromArgb(0, 255, 128),
                Color.FromArgb(0, 255, 255),
                Color.FromArgb(0, 128, 255),
                Color.FromArgb(0, 0, 255),
                Color.FromArgb(0, 0, 255),
            };
            int num_colors = colors.Length;
            float[] blend_positions = new float[num_colors];
            for (int i = 0; i < num_colors; i++)
            {
                blend_positions[i] = i / (num_colors - 1f);
            }

            ColorBlend color_blend = new ColorBlend();
            color_blend.Colors = colors;
            color_blend.Positions = blend_positions;
            the_brush.InterpolationColors = color_blend;

            // Draw the text.
            e.Graphics.DrawString(Txt,
                the_font, the_brush, x0, y0);
        }
    }
}

The code starts by setting the Graphics object's TextRenderingHint to produce smooth text. It then creates the font it will use, and uses the FontInfo class to get the font's metrics.

Next the program uses Graphics.MeasureString to determine where the string will be drawn. It uses that position plus the font metrics to decide where the brush should be to fill the text nicely.

In practice fonts often leave extra space below the internal leading, drop below the baseline, and otherwise violate their metrics slightly. The details depend 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. (I don't know how a program can learn about those violations automatically. If spacing is critical, you may need to add a little extra room just to be safe.)

Next the code makes a linear gradient brush to fill the text area. It creates an array of colors for the brush to use and then makes an array of blend positions to determine where the colors should appear in the gradient. The blend positions range from 0.0 (the color is at the start of the gradient) to 1.0 (the color is at the end of the gradient). This example spaces the colors evenly between 0.0 and 1.0.

The code creates a ColorBlend to represent the color gradient, associates it with the brush, and then uses the brush to draw the text.


Download Example   Follow me on Twitter   RSS feed




This entry was posted in drawing, fonts, graphics, strings and tagged , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *