1

我正在枚举这样的 Windows 字体:

LOGFONTW lf = {0};
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfFaceName[0] = L'\0';
lf.lfPitchAndFamily = 0;
::EnumFontFamiliesEx(hdc, &lf,
                     reinterpret_cast<FONTENUMPROCW>(FontEnumCallback),
                     reinterpret_cast<LPARAM>(this), 0);

我的回调函数有这个签名:

int CALLBACK FontEnumerator::FontEnumCallback(const ENUMLOGFONTEX *pelf,
                                              const NEWTEXTMETRICEX *pMetrics,
                                              DWORD font_type,
                                              LPARAM context);

对于 TrueType 字体,我通常会多次获取每个人脸名称。例如,对于多个呼叫,我将获取pelf->elfFullNamepelf->elfLogFont.lfFaceName设置为"Arial". 更仔细地查看其他字段,我发现每个调用都针对不同的脚本。例如,在第一次调用pelf->elfScript时将是"Western"并且pelf->elfLogFont.lfCharSet将是 的数字等价物ANSI_CHARSET。在第二次通话中,我得到"Hebrew"and HEBREW_CHARSET。第三次通话"Arabic"ARABIC_CHARSET。等等。到现在为止还挺好。

但是所有版本的 Arial 的字体签名( pMetrics->ntmFontSig) 字段都是相同的。事实上,字体签名声称所有这些版本的 Arial 都支持 Latin-1、希伯来语、阿拉伯语等。

我知道我要绘制的字符串的字符集,所以我试图根据字体签名实例化适当的字体。因为字体签名总是匹配的,所以我总是选择“西方”字体,即使在显示希伯来语或阿拉伯语文本时也是如此。我正在使用低级别的 Uniscribe API,所以我没有从 Windows 字体链接中受益,但我的代码似乎可以工作。

是否lfCharSet真的有任何意义,还是它是一个遗留物?我应该设置lfCharSetDEFAULT_CHARSET停止担心每张脸的所有脚本变化吗?

出于我的目的,我只关心 TrueType 和 OpenType 字体。

4

1 回答 1

1

我想我找到了答案。多次枚举的字体是“大”字体。大字体是包含多个脚本或代码页的字形的单一字体。

FONTSIGNATURE( )的 Unicode 部分fsUsb表示字体可以处理的所有 Unicode 子范围。这与字符集无关。如果使用宽字符 API,则可以使用字体中包含的所有字形,而不管创建字体时指定了哪个字符集。

FONTSIGNATURE( )的代码页部分fsCsb表示字体可以处理的代码页。我相信这仅在字体不是“大”字体时才有意义。在这种情况下,fsUsb掩码将全为零,并且fsCsb将指定适当的字符集。在这些情况下,重要的是lfCharSetLOGFONT.

lfCharSet在实例化“大”字体并使用宽字符 API 时,您指定哪个显然无关紧要。

于 2010-06-16T19:47:26.653 回答