【问题标题】:GDI+ DrawString() on Windows 8 truncating stringWindows 8 上的 GDI+ DrawString() 截断字符串
【发布时间】:2012-11-15 03:36:00
【问题描述】:

以下代码在 Windows 7(和以前版本的 Windows)和 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);

在 Windows 7 中,我得到了矩形内的字符串 'rt',因为它应该出现。在 Windows 8 中,仅出现第一个字母“r”。这似乎只发生在某些字符对上。例如,字符串 're' 在两个操作系统中都能正确显示。从 MeasureString() 返回的矩形在 Windows 7 和 Windows 8 中似乎是相同的。对这种差异有什么解释吗?

【问题讨论】:

  • GDI+ 因文本渲染不一致而臭名昭著。 Windows 8 角度可能是不同的视频适配器 DPI 设置。

标签: winapi visual-c++ windows-8 gdi+ gdi


【解决方案1】:

MeasureString 有时会以效率的名义捏造数字。它会做一些猜测工作,然后填充它填充的 RectF,以便 [希望] 使其足够大以供 DrawString 工作。我怀疑字体渲染方面发生了一些变化,或者系统的提示设置不同,这会在 DrawString 实际适合 RectF 中的文本时造成麻烦。

.NET 的 Measure string 方法实际上在 this MSDN 中记录了这一点:

MeasureString 方法设计用于单个字符串 并在字符串前后包含少量额外空格 允许悬垂的字形。此外,DrawString 方法调整 字形点以优化显示质量并可能显示字符串 比 MeasureString 报告的要窄。

作为一种解决方法,您可以使用 MeasureString 进行一些更精确的字形测量

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

而不是

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

【讨论】:

  • 使用 GenericTypographic() 似乎解决了我的问题!我确定它是专门修复它的标志 StringFormatFlagsNoWrap 。似乎第二个字符实际上被包裹到下一行,但由于边界矩形的高度不够大,我看不到它。即使 MeasureString() 返回一个宽度足以在一行上显示字符串的矩形,为什么 Windows 8 的 DrawString() 换行到下一行仍然没有意义,但这似乎是一个很好的解决方法。谢谢!
猜你喜欢
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 2015-12-14
  • 1970-01-01
相关资源
最近更新 更多