Title: Draw smooth text in a GraphicsPath in C#
You can set a Graphics object's TextRenderingHint property to AntiAliasGridFit to draw smooth text. However, if you place text in a GraphicsPath object and draw the GraphicsPath, then the TextRenderingHint property doesn't give you smooth text. Instead you need to set the Graphics object's SmoothingMode property when drawing the GraphicsPath. This example demonstrates these properties.
When the form loads, the following code gives the form a big font.
using System.Drawing.Text;
using System.Drawing.Drawing2D;
...
// Use a big font.
private void Form1_Load(object sender, EventArgs e)
{
this.AutoScaleMode = AutoScaleMode.None;
this.Font = new Font("Times New Roman", 30,
FontStyle.Bold, GraphicsUnit.Pixel);
}
This code sets the form's AutoScale property to None so the form doesn't resize itself when the code changes the font. It then sets the font to be 30 pixel Times New Roman bold. (I measure the font in pixels here so the font size matches the size used by the GraphicsPath described shortly.)
The following Paint event handler draws the sample text.
// Draw text samples.
private void Form1_Paint(object sender, PaintEventArgs e)
{
int y = 10;
e.Graphics.DrawString("DrawString Normal", this.Font,
Brushes.Blue, 10, y);
y += this.Font.Height;
e.Graphics.TextRenderingHint =
TextRenderingHint.AntiAliasGridFit;
e.Graphics.DrawString("DrawString Smooth", this.Font,
Brushes.Blue, 10, y);
y += this.Font.Height;
using (StringFormat string_format = new StringFormat())
{
string_format.Alignment = StringAlignment.Near;
string_format.LineAlignment = StringAlignment.Near;
using (GraphicsPath path = new GraphicsPath())
{
path.AddString("DrawPath Normal", this.Font.FontFamily,
(int)this.Font.Style, this.Font.Size, new Point(10, y),
string_format);
e.Graphics.FillPath(Brushes.Green, path);
y += this.Font.Height;
}
using (GraphicsPath path = new GraphicsPath())
{
path.AddString("DrawPath Smooth", this.Font.FontFamily,
(int)this.Font.Style, this.Font.Size, new Point(10, y),
string_format);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.FillPath(Brushes.Green, path);
y += this.Font.Height;
}
}
}
First the code draws some text while using the default value for TextRenderingHint. The result is pretty good.
Next the code sets TextRenderingHint to AntiAliasGridFit and draws some more text. This produces the best result but the result given by the default setting is also very good. In fact, you need to look very closely at the picture shown here to notice any difference at all. Look closely at the top of the D and S characters to see a slight difference.
Also notice that changing the TextRenderingHint changed the way the text was positioned so the text "DrawString" has a different width in the two samples. In general changing the drawing parameters may change the exact positioning of the text.
Next the program makes a StringFormat object, which is needed to draw text on a GraphicsPath. The code then makes a GraphicsPath object, adds sample text to it, and then draws the GraphicsPath. This first sample, which uses the default SmoothingMode value, produces a fairly ugly result.
Finally the program repeats these steps to draw another sample in a GraphicsPath, this time after setting SmoothingMode to AntiAlias. That result is excellent.
Again if you look closely you'll see that the character spacing has changed slightly. The text drawn by the GraphicsPath seems to use spacing similar to that used by DrawString with the default TextRenderingHint.
The moral is, if you want to draw smooth text in a GraphicsPath, you need to set SmoothingMode instead of TextRenderingHint.
Download the example to experiment with it and to see additional details.
|