Я перечисляю шрифты 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.