Title: Draw text with colors reversed in its upper and lower halves in C#
This example and the two that follow show how to draw text with an interesting visual effect. The idea is quite simple. Make two bitmaps showing the text with its different color schemes. Then use those images to fill different parts of the final output image.
The program uses the following DrawSplitText method to draw its text.
// Draw split text centered in the indicated rectangle.
private void DrawSplitText(Graphics gr,
string text, Font font, Rectangle rect,
Brush top_fg_brush, Brush bottom_fg_brush)
{
// Make bitmaps holding the text in different colors.
Bitmap bm_top = new Bitmap(rect.Width, rect.Height);
Bitmap bm_bottom = new Bitmap(rect.Width, rect.Height);
// Make a StringFormat to center text.
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
using (Graphics gr_top = Graphics.FromImage(bm_top))
{
gr_top.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
gr_top.FillRectangle(bottom_fg_brush, rect);
gr_top.DrawString(text, font, top_fg_brush, rect, sf);
}
using (Graphics gr_bottom = Graphics.FromImage(bm_bottom))
{
gr_bottom.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
gr_bottom.FillRectangle(top_fg_brush, rect);
gr_bottom.DrawString(text, font, bottom_fg_brush, rect, sf);
}
}
// Fill the top and bottom halves of the rectangle.
RectangleF top_rect = new RectangleF(
rect.X, rect.Y, rect.Width, rect.Height / 2f);
using (TextureBrush brush = new TextureBrush(bm_top))
{
gr.FillRectangle(brush, top_rect);
}
RectangleF bottom_rect = new RectangleF(
rect.X, top_rect.Bottom, rect.Width, rect.Height / 2f);
using (TextureBrush brush = new TextureBrush(bm_bottom))
{
gr.FillRectangle(brush, bottom_rect);
}
bm_top.Dispose();
bm_bottom.Dispose();
}
The method first makes two bitmaps (named bm_top and bm_bottom) that have the same size as the area where it should draw the text. It then makes a StringFormat object and sets its alignment properties so it centers text vertically and horizontally.
Next, the code creates a Graphics object for the upper bitmap bm_top. It sets the object's TextRenderingHint property to produce smooth text, fills the bitmap with the bottom bitmap's foreground brush bottom_fg_brush, and then draws the text on it using the top foreground brush top_fg_brush. The result looks like this:
The program repeats those steps to draw the bottom bitmap bm_bottom so it looks like this:
Now the program makes a rectangle top_rect that fills the upper half of the drawing area. It makes a TextureBrush that uses top_bm as its texture and uses it to fill the upper rectangle in original Graphics object. Here's the result at this point:
The method them repeats roughly the same steps to fill the bottom half of the drawing area with a TextureBrush that uses the bottom bitmap. That produces the final result shown at the top of this post.
The method finishes by disposing of the two bitmaps bm_top and bm_bottom. You could create those inside a using block to make the program dispose of them automatically, but that would make the level of indentation inconveniently deep. Either approach works as long as you remember to call the bitmaps' Dispose methods.
In my next two posts, I'll show how to draw text that is split in ways other than horizontally. Before you read them, you might want to download this example and see if you can split the text in new and interesting ways.
Download the example to experiment with it and to see additional details.
|