为什么FONTSIGNATURE不反映lfCharSet?

时间:2010-06-14 19:25:22

标签: windows fonts gdi uniscribe

我正在枚举像这样的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"HEBREW_CHARSET。第三次致电"Arabic"ARABIC_CHARSET。等等。到目前为止,非常好。

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

我知道我想要绘制的字符串的字符集,所以我试图根据字体签名实例化一个合适的字体。因为字体签名总是匹配,所以即使显示希伯来语或阿拉伯语文本,我也总是选择“西方”字体。我使用的是低级Uniscribe API,所以我没有得到Windows字体链接的好处,但我的代码似乎有效。

lfCharSet实际上是否具有任何意义,还是遗留神器?我应该将lfCharSet设置为DEFAULT_CHARSET并停止担心每张脸的所有脚本变体吗?

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

1 个答案:

答案 0 :(得分:1)

我想我找到了答案。多次枚举的字体为"big" fonts。大字体是单字体,包括多个脚本或代码页的字形。

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

FONTSIGNATUREfsCsb)的代码页部分代表字体可以处理的代码页。我相信这只有在字体不是“大”字体时才有意义。在这种情况下,fsUsb掩码将全为零,fsCsb将指定适当的字符集。在这些情况下,让lfCharSet更正LOGFONT

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