Ryand
Ryand

Reputation: 436

GDI+ DrawString() on Windows 8 truncating string

The following code displays the same string differently between Windows 7 (and previous versions of Windows) and Windows 8:

Graphics graphics(ps.hdc);

std::unique_ptr<StringFormat> format(StringFormat::GenericDefault()->Clone());
Font font(L"Segoe UI", static_cast<Gdiplus::REAL>(17.5), FontStyleBold, UnitPixel);     
format->SetTrimming(StringTrimmingNone);
std::wstring name("rt");
RectF rectName;
graphics.MeasureString(name.c_str(), -1, &font, PointF(20, 20), format.get(), &rectName);           

graphics.DrawString(name.c_str(), -1, &font, rectName, format.get(), &SolidBrush(Color()));

graphics.DrawRectangle(&Pen(Color(255, 0, 0)), rectName);

In Windows 7, I get the string 'rt' inside the rectangle as it should appear. In Windows 8, the only the first letter 'r' appears. This only seems to happen with certain character pairs. For example, the string 're' displays correctly in both operating systems. The rectangle returned from MeasureString() appears to be the same in both Windows 7 and Windows 8. Is there any explanation for this difference?

Upvotes: 1

Views: 1354

Answers (1)

Sean Cline
Sean Cline

Reputation: 7199

MeasureString is known to fudge the numbers at times in the name of efficiency. It will do some guess-work and then pad the RectF it populates so that to [hopefully] make it big enough for DrawString to work. I suspect that something has either changed with respect to font rendering, or maybe the system's hinting settings are different and that is causing trouble when it comes time for DrawString to actually fit the text in the RectF.

.NET's Measure string method actually documents this as such in this MSDN:

The MeasureString method is designed for use with individual strings and includes a small amount of extra space before and after the string to allow for overhanging glyphs. Also, the DrawString method adjusts glyph points to optimize display quality and might display a string narrower than reported by MeasureString.

As a workaround, you can ask MeasureString to do some more precise glyph measurements by using

std::unique_ptr<StringFormat> format(StringFormat::GenericTypographic()->Clone());

instead of

std::unique_ptr<StringFormat> format(StringFormat::GenericDefault()->Clone());

Upvotes: 1

Related Questions