Перечисление установленных шрифтов
В некоторых случаях приложение должно иметь возможность перечислить доступные шрифты и выбрать наиболее подходящий для конкретной операции. Приложение может перечислить доступные шрифты, вызвав функцию EnumFonts или EnumFontFamilies. Эти функции отправляют сведения о доступных шрифтах в функцию обратного вызова, которую предоставляет приложение. Функция обратного вызова получает информацию в структурах LOGFONT и NEWTEXTMETRIC. (Структура NEWTEXTMETRIC содержит сведения о шрифте TrueType. Когда функция обратного вызова получает сведения о шрифте, отличном от TrueType, информация содержится в структуре TEXTMETRIC.) Используя эти сведения, приложение может ограничить выбор пользователя только теми шрифтами, которые доступны.
Функция EnumFontFamilies аналогична функции EnumFonts, но включает некоторые дополнительные функции. EnumFontFamilies позволяет приложению использовать преимущества стилей, доступных с помощью шрифтов TrueType. Новые и обновленные приложения должны использовать EnumFontFamilies вместо EnumFonts.
Шрифты TrueType организованы вокруг имени шрифта (например, Courier New) и стилей (например, курсив, полужирный и очень полужирный). Функция EnumFontFamilies перечисляет все стили, связанные с указанным именем семейства, а не просто полужирными и курсивными атрибутами. Например, если система включает шрифт TrueType с именем Courier New Extra-Bold, EnumFontFamilies перечисляет его с другими шрифтами Courier New. Возможности EnumFontFamilies полезны для шрифтов с множеством или необычными стилями и для шрифтов, пересекающих международные границы.
Если приложение не предоставляет имя шрифта, функции EnumFonts и EnumFontFamilies предоставляют сведения об одном шрифте в каждом доступном семействе. Чтобы перечислить все шрифты в контексте устройства, приложение может указать NULL для имени шрифта, скомпилировать список доступных шрифтов, а затем перечислить каждый шрифт в каждом шрифте.
В следующем примере используется функция EnumFontFamilies для получения количества доступных семейств шрифтов raster, vector и TrueType.
UINT uAlignPrev;
int aFontCount[] = { 0, 0, 0 };
char szCount[8];
HRESULT hr;
size_t * pcch;
EnumFontFamilies(hdc, (LPCTSTR) NULL,
(FONTENUMPROC) EnumFamCallBack, (LPARAM) aFontCount);
uAlignPrev = SetTextAlign(hdc, TA_UPDATECP);
MoveToEx(hdc, 10, 50, (LPPOINT)NULL);
TextOut(hdc, 0, 0, "Number of raster fonts: ", 24);
itoa(aFontCount[0], szCount, 10);
hr = StringCchLength(szCount, 9, pcch);
if (FAILED(hr))
{
// TODO: write error handler
}
TextOut(hdc, 0, 0, szCount, *pcch);
MoveToEx(hdc, 10, 75, (LPPOINT)NULL);
TextOut(hdc, 0, 0, "Number of vector fonts: ", 24);
itoa(aFontCount[1], szCount, 10);
hr = StringCchLength(szCount, 9, pcch);
if (FAILED(hr))
{
// TODO: write error handler
}
TextOut(hdc, 0, 0, szCount, *pcch);
MoveToEx(hdc, 10, 100, (LPPOINT)NULL);
TextOut(hdc, 0, 0, "Number of TrueType fonts: ", 26);
itoa(aFontCount[2], szCount, 10);
hr = StringCchLength(szCount, 9, pcch);
if (FAILED(hr))
{
// TODO: write error handler
}
TextOut(hdc, 0, 0, szCount, *pcch);
SetTextAlign(hdc, uAlignPrev);
BOOL CALLBACK EnumFamCallBack(LPLOGFONT lplf, LPNEWTEXTMETRIC lpntm, DWORD FontType, LPVOID aFontCount)
{
int far * aiFontCount = (int far *) aFontCount;
// Record the number of raster, TrueType, and vector
// fonts in the font-count array.
if (FontType & RASTER_FONTTYPE)
aiFontCount[0]++;
else if (FontType & TRUETYPE_FONTTYPE)
aiFontCount[2]++;
else
aiFontCount[1]++;
if (aiFontCount[0] || aiFontCount[1] || aiFontCount[2])
return TRUE;
else
return FALSE;
UNREFERENCED_PARAMETER( lplf );
UNREFERENCED_PARAMETER( lpntm );
}
В этом примере используются две маски, RASTER_FONTTYPE и TRUETYPE_FONTTYPE, чтобы определить тип перечисляемого шрифта. Если задан RASTER_FONTTYPE бит, шрифт — это растровый шрифт. Если задан TRUETYPE_FONTTYPE бит, шрифт является шрифтом TrueType. Если ни один бит не установлен, шрифт является векторным. Третья маска, DEVICE_FONTTYPE, устанавливается, если устройство (например, лазерный принтер) поддерживает скачивание шрифтов TrueType; Оно равно нулю, если устройство является адаптером дисплея, принтером dot-matrix или другим растрового устройства. Приложение также может использовать маску DEVICE_FONTTYPE для различания шрифтов, предоставленных GDI, от шрифтов, предоставленных устройством. Система может имитировать полужирные, курсивные, подчеркивание и зачеркивающие атрибуты для шрифтов, предоставленных GDI, но не для шрифтов, предоставленных устройством.
Приложение также может проверить биты 1 и 2 в элементе tmPitchAndFamily структуры NEWTEXTMETRIC для идентификации шрифта TrueType. Если бит 1 равен 0 и бит 2 равен 1, шрифт является шрифтом TrueType.
Векторные шрифты классифицируются как OEM_CHARSET вместо ANSI_CHARSET. Некоторые приложения определяют векторные шрифты с помощью этих сведений, проверяя элемент tmCharSet структуры NEWTEXTMETRIC. Эта классификация обычно предотвращает маппер шрифтов от выбора векторных шрифтов, если они не запрашиваются специально. (Большинство приложений больше не используют векторные шрифты, так как их росчерки являются одними строками, и они занимают больше времени, чем шрифты TrueType, которые предлагают многие из одинаковых функций масштабирования и поворота, которые требуют векторных шрифтов.)