Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextRenderer.DrawText renders Arial differently on XP vs Vista

I have a c# application that does text rendering, something on par with a simple wysiwyg text editor.

I'm using TextRenderer.DrawText to render the text to the screen and GetTextExtentPoint32 to measure text so I can position different font styles/sizes on the same line.

In Vista this all works fine. In XP however, Arial renders differently, certain characters like 'o' and 'b' take up more width than in Vista. GetTextExtentPoint32 seems to be measuring the string as it would in Vista though, with the smaller widths. The end result is that every now and then a run of text will overlap the text preceding it because the preceding text gets measured as smaller than it actually is on the screen.

Also, my text rendering code mimics ie's text rendering exactly (for simple formatting and english language only) and ie text rendering seems to be consistent between vista and xp - that's how I noticed the change in size of the different characters.

Anyone have any ideas about what's going on?

In short, TextRenderer.DrawText and GetTextExtentPoint32 don't match up in xp for Arial. DrawText seems to draw certain characters larger and/or smaller than it does in Vista but GetTextExtentPoint32 seems to be measuring the text as it would in Vista (which seems to match the text rendering in ie on both xp and vista). Hope that makes sense.

Note: unfortunately TextRenderer.MeasureString isn't fast or accurate enough to meet my requirements. I tried using it and had to rip it out.

like image 840
Michael Avatar asked Apr 08 '10 06:04

Michael


2 Answers

Thanks for taking the time to respond Adrian.

My understanding is that TextRenderer.DrawText actually wraps a call to GDI, bypassing GDI+ text rendering completely. That's why I was confused about GetTextExtentPoint32 not jiving with the output.

I think I found the issue though. It turns out if you set Graphics.TextRenderingHint to System.Drawing.Text.TextRenderingHint.ClearTypeGridFit, or possibly other values, it causes some characters in some fonts to increase or decrease in size. This seems to be true more in XP than in Vista. I haven't seen it happen at all in Vista. Anyway, it looks like GetTextExtentPoint32 is either not capable of recognizing the difference or I am not setting some kind of flag when I make the call.

My solution is to just use the system default textrenderinghint settings.

like image 91
Michael Avatar answered Nov 12 '22 00:11

Michael


Actually both TextRenderer's DrawText and MeasureString based on DrawTextEx (and this is User32, not Gdi function). So you can consider using native marshalled calls to this function instead of MeauseString, because it doing some additional calculations (especially if you are using function override without HDC).

Also maybe this post will be helpful for you too.

like image 30
arbiter Avatar answered Nov 12 '22 01:11

arbiter