Почему 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
вы указываете.