Home > Net >  Draw a smooth string
Draw a smooth string

Time:08-09

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.

Result

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);

Desired Result

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.

  • Related