I'm trying to create a simple "Avatar" user control in WinForms that draws a string in the middle of the control. However, I can't figure out a way to draw a smooth text. Here's the code:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
e.Graphics.FillEllipse(_backgroundBrush, 0, 0, Width, Height);
var fontSize = Width / 3 * 2;
if(Font.Size != fontSize)
{
Font = new Font(_fontFamily, fontSize, _fontStyle, GraphicsUnit.Pixel);
}
var stringSize = e.Graphics.MeasureString(_initials, Font);
var location = new Point((int)((Size.Width - stringSize.Width) / 2),
(int)((Size.Height - stringSize.Height) / 2));
e.Graphics.DrawString(_initials, Font, _foregroundBrush, location);
}
I made the font size a little bit bigger to show what I mean. In the image below, as you can see the M is broken into several parts rather than a smooth line.
Update:
Based on the comment from @GyörgyKőszeg, I changed to TextRenderer
and it's now looking like it should.
//e.Graphics.DrawString(_initials, Font, _foregroundBrush, location);
TextRenderer.DrawText(e.Graphics, _initials, Font, location, _foregroundColor);
CodePudding user response:
Converting my comment to an answer upon request:
Use TextRenderingHint.ClearTypeGridFit
for the desired result.
And if possible use TextRenderer.DrawText
instead of Graphics.DrawString
whenever possible. TextRenderer.DrawText
uses GDI text rendering instead of GDI and it is the preferred way of rendering text since .NET Framework 2.0 (even by controls if UseCompatibleTextRendering
is false).
And please also note that you should use TextRenderer.MeasureText
instead of Graphics.MeasureString
because they may return different sizes.