GDI + - 为什么MeasureString函数失败并使用Courier字体?

时间:2017-09-02 16:12:40

标签: fonts gdi+ gdi fallback

我正在使用RAD Studio XE7。在几个项目中,我使用公共代码来获取文本周围的边框(以像素为单位),使用GDI + MeasureString函数:

// configure the font to use. NOTE be careful, the SVG font size matches with the
// GDI font HEIGHT property, and not with the font SIZE
std::auto_ptr<TFont> pTextFont(new TFont());
pTextFont->Name   =  fontFamily;
pTextFont->Height = -fontSize;
std::auto_ptr<Gdiplus::Font> pFont(new Gdiplus::Font(pCanvas->Handle, pTextFont->Handle));

// char range is required to extract the first char bounds
Gdiplus::CharacterRange charRange;
charRange.First  = 0;
charRange.Length = 1;

// configure the text format
std::auto_ptr<Gdiplus::StringFormat> pTextFormat(new Gdiplus::StringFormat());
pTextFormat->SetAlignment(Gdiplus::StringAlignmentNear);
pTextFormat->SetLineAlignment(Gdiplus::StringAlignmentNear);
pTextFormat->SetFormatFlags(Gdiplus::StringFormatFlagsNoWrap);
pTextFormat->SetTrimming(Gdiplus::StringTrimmingNone);
pTextFormat->SetMeasurableCharacterRanges(1, &charRange);

Gdiplus::RectF boundingBox;
Gdiplus::RectF viewBoxF(viewBox);

// measure the rect surrounding the text
if (pGraphics->MeasureString(text.c_str(), text.length(), pFont.get(), viewBoxF,
        pTextFormat.get(), &boundingBox) != Gdiplus::Ok)
{
    // error is handled here
}

这个函数在几种情况下效果很好,但是有时MeasureString会莫名其妙地失败,将InvalidParameter作为错误消息返回,例如字体参数如下:

pTextFont->Name   =  L"Courier";
pTextFont->Height = -16;

我首先想到的可能是字体后备问题。我尝试实现以下解决方案以获取后备字体:How to automatically choose most suitable font for different language?

然而,这并没有解决我的问题:

  1. 在上面提到的情况下,返回的后备字体也是Courier,这意味着我的系统在某种程度上认为这个字体是有效的(除非字体后备代码本身被破坏,但我认为情况并非如此)
  2. 对于用Delphi编写的另一个项目,我翻译了上面的代码,我面对完全相同的问题
  3. GDI(不是GDI +)似乎可以通过SelectObject和DrawText等函数使用此字体(使用DrawText和DT_CALCRECT测量时返回的rect似乎有效)
  4. 另一方面,GDI +似乎无法对字体(在pFont中实例化的字体)做些什么。绘图功能也失败
  5. 有人可以向我解释我做错了什么?

1 个答案:

答案 0 :(得分:0)

与我的想法相反,GDI + 不支持所有已安装的字体,如DrawString函数备注(https://msdn.microsoft.com/en-us/library/windows/desktop/ms535991(v=vs.85).aspx)中所述:

  

请注意,GDI +不支持PostScript字体或OpenType字体   没有TrueType轮廓。

似乎Courier字体属于那种不能使用的字体&#34;因为&#34;与GDI +。因此,如果我的绘图因GDI +失败,我需要使用GDI,或者提供替换字体。