代码之家  ›  专栏  ›  技术社区  ›  Adrian McCarthy

为什么fontSignature不反映lfcharset?

  •  1
  • Adrian McCarthy  · 技术社区  · 16 年前

    我列举的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->elfFullName pelf->elfLogFont.lfFaceName 设置为 "Arial" . 仔细观察其他字段,我发现每个调用都是针对不同的脚本的。例如,在第一次呼叫时 pelf->elfScript "Western" pelf->elfLogFont.lfCharSet 将是与 ANSI_CHARSET . 第二个电话,我接到 "Hebrew" HEBREW_CHARSET . 第三电话 "Arabic" ARABIC_CHARSET . 等等。到目前为止,一切都很好。

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

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

    lfCharSet 实际上有任何意义,或者它是一件遗产?我应该刚开始吗 LFACSET DEFAULT_CHARSET 别再担心每张脸上的文字变化了?

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

    1 回复  |  直到 13 年前
        1
  •  1
  •   Adrian McCarthy    16 年前

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

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

    的代码页部分 字体签名 ( fsCsb )表示字体可以处理的代码页。我认为只有当字体不是“大”字体时,这才是重要的。在这种情况下, FSUBB 掩码将全部为零,并且 FSCSB 将指定适当的字符集。在这些情况下,重要的是 lfCharSet 正确的 LOGFONT .

    当实例化“大”字体并使用宽字符API时,显然不需要考虑哪一个 LFACSET 您指定。