Managed Extensions: Using GDI+ to Draw 3D Text
Welcome to this week's installment of .NET Tips & Techniques! Each week, award-winning Architect and Lead Programmer Tom Archer demonstrates how to perform a practical .NET programming task using either C# or Managed C++ Extensions.
In a previous article, Managed Extensions: Using GDI+ Brushes to Draw Text, I presented step-by-step instructions as well as a demo application that illustrated how to draw 2D text using GDI+ objects. This week, I take it a step further and show you how to render 3D text in order to accomplish the following effects:
- Shadowed text
- Blocked text
- Embossed text
- Engraved text
Note: In order to test these code snippets, first simply drag a PictureBox from the Toolbox onto a Form in a Managed Extensions Windows Forms application and name the PictureBox variable picText. Then copy and paste the desired snippet into your application to have the text rendered onto the PictureBox.
Steps to Rendering Shadowed Text
To achieve a shadowed appearance, you simply draw the shadowed text twice: first at the desired depth and then the foreground text. For example, the following code draws sample text on a window (represented by the Graphics object, g) where the text has a shadow version of itself drawn five pixels in the background:
// Assumes a PictureBox on the form named picText
// with this code being the picText object's
// Paint method
private:
System::Void picText_Paint(
System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
// Test string
String* textToDisplay = S"Test string";
// Obtain Graphics object
Graphics* g = e->Graphics;
// Create a Font object, Times New Roman, 25pt
System::Drawing::Font* font =
new System::Drawing::Font("Times New Roman",
Convert::ToSingle(25),
FontStyle::Regular);
// Obtain the size of the text to be rendered
SizeF textSize = g->MeasureString(textToDisplay, font);
// Text will be centered on PictureBox control
Single x = (picText->Width - textSize.Width) / 2;
Single y = (picText->Height - textSize.Height) / 2;
// Clear background
g->Clear(Color::White);
// Draw the shadow text
g->DrawString(textToDisplay,
font,
SystemBrushes::ControlLight,
x + 5, y + 5);
// Draw the foreground text
g->DrawString(textToDisplay, font, SystemBrushes::ControlText, x, y);
}
Steps to Rendering Blocked Text
To get the blocked-text effect, repeatedly draw the text starting at the desired depth and moving one pixel at a time up to the foreground text. Obviously, you have to decide in which direction this repeated drawing occurs. I personally draw blocked text with the light source from the upper right. This means using a for loop and subtracting the offset depth from the X dimension. To move the light source to the upper left, simply increment the offset:
// Assumes a PictureBox on the form named picText
// with this code being the picText object's
// Paint method
private:
System::Void picText_Paint(
System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
// Test string
String* textToDisplay = S"Test string";
// Get drawing surface for PictureBox and clear background
Graphics* g = e->Graphics;
// Create a Font object
System::Drawing::Font* font = new System::Drawing::Font("Times New Roman", Convert::ToSingle(25), FontStyle::Regular);
// Obtain the size of the text to be rendered
SizeF textSize = g->MeasureString(textToDisplay, font);
// Text will be centered on Picture Box control
Single x = (picText->Width - textSize.Width) / 2;
Single y = (picText->Height - textSize.Height) / 2;
// Clear background
g->Clear(Color::White);
// Print the background text multiple times starting
// at the furthest point in the background up to
// the foreground text
for (int i = Convert::ToInt32(5); i >= 0; i--)
{
g->DrawString(textToDisplay,
font,
SystemBrushes::ControlLight,
x - i, y + i);
}
// Draw the foreground text
g->DrawString(textToDisplay, font, SystemBrushes::ControlText, x, y);
}
0 Comments (click to add your comment)
Networking Solutions
