Почему FONTSIGNATURE не отражает lfCharSet?

Я перечисляю шрифты 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, И так далее. Все идет нормально.

Но шрифт подписи (pMetrics->ntmFontSig) поле для всех версий Arial одинаково. Фактически, подпись шрифта утверждает, что все эти версии Arial поддерживают латиницу-1, иврит, арабский и другие.

Я знаю наборы символов строк, которые я пытаюсь нарисовать, поэтому я пытаюсь создать соответствующий шрифт на основе сигнатур шрифтов. Поскольку подписи шрифтов всегда совпадают, я всегда выбираю "западный" шрифт даже при отображении текста на иврите или арабском языке. Я использую низкоуровневые API Uniscribe, поэтому я не получаю преимущества от связывания шрифтов Windows, и все же мой код работает.

Есть ли lfCharSet на самом деле несут какой-то смысл или это устаревший артефакт? Должен ли я просто установить lfCharSet в DEFAULT_CHARSET и перестать беспокоиться обо всех вариациях сценария каждого лица?

В моих целях меня интересуют только шрифты TrueType и OpenType.

1 ответ

Решение

Я думаю, что нашел ответ. Шрифты, которые перечисляются несколько раз, являются "большими" шрифтами. Большие шрифты - это отдельные шрифты, которые включают глифы для нескольких скриптов или кодовых страниц.

Unicode часть FONTSIGNATURE (fsUsb) представляет все поддиапазоны Unicode, которые может обрабатывать шрифт. Это не зависит от набора символов. Если вы используете API широких символов, вы можете использовать все включенные глифы в шрифте, независимо от того, какой набор символов был указан при создании шрифта.

Часть кодовой страницы FONTSIGNATURE (fsCsb) представляет кодовые страницы, которые может обрабатывать шрифт. Я считаю, что это важно только тогда, когда шрифт не является "большим" шрифтом. В этом случае fsUsb маски будут все нули, а fsCsb определит соответствующий набор символов. В этих случаях важно получить lfCharSet исправить в LOGFONT,

При создании экземпляра "большого" шрифта и использовании API широких символов, очевидно, не имеет значения, какой lfCharSet вы указываете.

Другие вопросы по тегам