开发者

Possible bug with Graphics.DrawString and TextRenderingHint in .Net Winforms

开发者 https://www.devze.com 2023-01-18 12:51 出处:网络
Here\'s the OnPaint method of a control that simply inherits from control and provides a property to get/set the textrenderinghint:

Here's the OnPaint method of a control that simply inherits from control and provides a property to get/set the textrenderinghint:

 Private _mode as TextRenderingHint = SystemDefault.
 Public Property Mode as TextRenderingHint
    Get & Set _mode
 ...

 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim g = e.Graphics
    Dim savMode = g.Save
    g.TextRenderingHint = Me._mode
    g.DrawString(Me.Text, Me.Font, Brushes.Black, 0, 0)
    g.Restore(savMode)
    MyBase.OnPaint(e)
 End Sub

Now, if you place two of these on a form, leave the first as default and change the second to AntiAlias, it looks fine at design-time but when you run the开发者_StackOverflow社区 app, the first label's rendering mode has changed. Its as if the DrawString method has changed the systemdefault.

Here's some observations:

(1) If I explicity set the first control's mode to ClearTypeGridFit, which is the same as the default in my case, it fixes the problem.

(2) If you place a third control on the form and leave at the default mode, it fixes the problem.

(3) TextRenderer.DrawText doesn't replicate the problem.

(4) If I inherit label control and override the onpaint method to set the rendering mode, the problem is not replicated even though I set UseCompatibleTextRendering - which forces the label to render with DrawString instead of DrawText.

I'm on XP with cleartype enabled and using visual studio 2008 express edition.

ETA: I've tried it in C# and the same thing happens


This sounds like the issue we ran into before. In your app startup code, is there a call to Application.SetCompatibleTextRenderingDefault(true)? (Or it might be set to false, I forget).

If so, toggle the state of that bool to change the text rendering mode and it should work as expected.


I had a similar problem. I called this:

Image i = new Bitmap(size, size);
Graphics g = Graphics.FromImage(i);

// When this line is uncommented TextRenderingHint is broken for ALL other Graphics-Objects.
// Setting "g.TextRenderingHint" later works sometimes in unpredictable ways.
//g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
...

My startup code looked like this:

[STAThread]
static void Main(string[] args)
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

Then I tried what Judah Himango suggested and everything worked just fine.
This looks definitely like a bug to me!

So just make sure you call:

    Application.SetCompatibleTextRenderingDefault(true);

Worked for me!


This bug still seems to be present in .Net Framework 4.8. I found out that it can be solved, when the first call to DrawString() since application start is done with SystemDefault-TextRenderingHint:

using (Bitmap bmp = new Bitmap(1, 1))
using (Graphics gfx = Graphics.FromImage(bmp))
{
    // gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;    // bug
    gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;   // no bug
    gfx.DrawString("x", SystemFonts.DefaultFont, Brushes.Black, 0, 0);
}

So if this is done once in

[STAThread]
static void Main(string[] args)
{ .. }

every following call to DrawString works correct with or without setting TextRenderingHint before.

0

精彩评论

暂无评论...
验证码 换一张
取 消