Почему FONTSIGNATURE не отражает lfCharSet? - PullRequest
1 голос
/ 14 июня 2010

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

1 голос
/ 16 июня 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...