Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Графический интерфейс GDI в Microsoft Windows

© Александр Фролов, Григорий Фролов
Том 14, М.: Диалог-МИФИ, 1993, 288 стр.

[Назад] [Содеожание] [Дальше]

5.4. Получение информации о шрифте

В программном интерфейсе GDI имеется несколько функций, с помощью которых приложение может получить различную информацию о шрифте, выбранном в контекст отображения. Наибольший интерес представляют метрики шрифта, о которых мы рассказывали в 11 томе "Библиотеки системного программиста", однако для масштабируемых шрифтов True Type можно получить и другую информацию.

Определение метрик шрифта

Для удобства мы напомним вам методику определения метрик шрифта.

Метрику шрифта , выбранного в контекст отображения, можно определить с помощью функции GetTextMetrics :

BOOL WINAPI GetTextMetrics(HDC hdc, TEXTMETRIC FAR* lptm);

Параметр hdc указывает контекст отображения или устройства, для которого требуется получить информацию о метрике шрифта. В качестве этого параметра можно использовать значение, возвращаемое функцией BeginPaint или GetDC.

Параметр lptm является дальним указателем на структуру типа TEXTMETRIC, в которую будет записана информация о метриках шрифта, выбранного в указанный контекст устройства.

В случае успешного завершения функция возвращает значение TRUE, в противном случае - FALSE.

Структура TEXTMETRIC описана в файле windows.h следующим образом:

typedef struct tagTEXTMETRIC
{
  int    tmHeight;
  int    tmAscent;
  int    tmDescent;
  int    tmInternalLeading;
  int    tmExternalLeading;
  int    tmAveCharWidth;
  int    tmMaxCharWidth;
  int    tmWeight;
  BYTE   tmItalic;
  BYTE   tmUnderlined;
  BYTE   tmStruckOut;
  BYTE   tmFirstChar;
  BYTE   tmLastChar;
  BYTE   tmDefaultChar;
  BYTE   tmBreakChar;
  BYTE   tmPitchAndFamily;
  BYTE   tmCharSet;
  int    tmOverhang;
  int    tmDigitizedAspectX;
  int    tmDigitizedAspectY;
} TEXTMETRIC;

Параметры, имеющие отношение к вертикальным размерам букв, представлены на рис. 5.5.

Рис. 5.5. Метрики шрифта

Отсчет всех размеров выполняется от так называемой базовой линии шрифта. Для размеров используются логические единицы, которые зависят от режима отображения, установленного в контексте устройства.

Общая высота букв находится в поле tmHeight структуры TEXTMETRIC. Эта высота складывается из двух компонент - tmAscent и tmDescent. Компонента tmAscent представляет собой высоту букв от базовой линии с учетом таких элементов, как тильда в букве "Й". Компонента tmDescent определяет пространство, занимаемое буквами ниже базовой линии. Сумма tmAscent и tmDescent в точности равна tmHeight.

Величина tmInternalLeading определяет размер выступающих элементов букв и может быть равна нулю.

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

Для ширины букв в структуре TEXTMETRIC есть два поля с именами tmAveCharWidth и tmMaxCharWidth. Поле tmAveCharWidth содержит среднее значение ширины строчных букв шрифта. Это значение приблизительно соответствует ширине латинской буквы "x". Поле tmMaxCharWidth определяет ширину самой широкой буквы в шрифте. Для шрифта с фиксированной шириной букв поля tmAveCharWidth и tmMaxCharWidth содержат одинаковые значения, которые зависят от самого шрифта.

Поле tmWeight определяет жирность шрифта. Может находиться в пределах от 0 до 1000. Файл windows.h содержит определение символических констант для этого поля:

Константа Значение
FW_DONTCARE 0
FW_THIN 100
FW_EXTRALIGHT 200
FW_ULTRALIGHT 200
FW_LIGHT 300
FW_NORMAL 400
FW_REGULAR 400
FW_MEDIUM 500
FW_SEMIBOLD 600
FW_DEMIBOLD 600
FW_BOLD 700
FW_EXTRABOLD 800
FW_ULTRABOLD 800
FW_BLACK 900
FW_HEAVY 900

Поля tmItalic, tmUnderlined, tmStruckOut определяют, соответственно, является ли шрифт наклонным, подчеркнутым или перечеркнутым.

Поля tmFirstChar и tmLastChar определяют, соответственно, коды первого и последнего символа, определенных в шрифте.

Если приложение пытается вывести символ, код которого отсутствует в шрифте, вместо него будет выведен символ с кодом, расположенным в поле tmDefaultChar.

Поле tmBreakChar содержит код символа, который используется для переноса слов с одной строки на другую при выравнивании текста.

Поле tmPitchAndFamily содержит код семейства шрифта. В нем могут находится следующие флаги, соответствующие четырем младшим битам:

Значение Описание
TMPF_FIXED_PITCH Шрифт с фиксированной шириной букв
TMPF_VECTOR Векторный шрифт или масштабируемый шрифт True Type
TMPF_TRUETYPE Шрифт True Type
TMPF_DEVICE Шрифт устройства вывода, например, принтерный шрифт

Одновременно может быть установлено несколько флагов с префиксом имени TMPF.

Старшие четыре бита описывают семейство шрифта:

Константа Описание
FF_DECORATIVE Шрифт, содержащий маленькие рисунки (пиктограммы). Примером такого шрифта может послужить шрифт Wingdings, поставляемый в составе Windows
FF_DONTCARE Семейство шрифта не имеет значения или неизвестно
FF_MODERN Семейство Modern. Фиксированная ширина символов, могут быть засечки (но могут и не быть)
FF_ROMAN Семейство Roman. Переменная ширина букв, есть засечки
FF_SCRIPT Семейство Script. Рукописный шрифт
FF_SWISS Семейство Swiss. Переменная ширина букв, нет засечек

В поле tmCharSet находится код используемого набора символов:

Константа Значение Описание
ANSI_CHARSET 0 Набор символов в кодировке ANSI
DEFAULT_CHARSET 1 Не используется при отображении шрифтов. Определяется при необходимости запросить шрифт с заданным именем и размером шрифта. Следует использовать с осторожностью, так как если указанного шрифта нет, GDI может выделить шрифт с любым набором символов
SYMBOL_CHARSET 2 Символьный шрифт, такой как Wingdings
SHIFTJIS_CHARSET 128 Шрифт, в котором для представления символов используется двухбайтовая кодировка. Нужен для работы с японской версией Windows
OEM_CHARSET 255 Набор символов в кодировке OEM

В поле tmOverhang содержится величина, на которую увеличивается ширина символов для синтезированных (эмулированных) шрифтов, например, наклонных или жирных шрифтов, полученных изменением нормального шрифта. Шрифты True Type обычно не используют это поле для наклонных и жирных шрифтов (в нем находится нулевое значение), так как такие шрифты считаются отдельными шрифтами, и не получаются изменением нормального шрифта True Type.

Поля tmDigitizedAspectX и tmDigitizedAspectY содержат значения, которые можно использовать для определения отношения масштабов устройства отображения по горизонтали и вертикали.

Функция EnumFontFamilies

В тех случаях, когда вас не устраивают возможности диалоговой панели "Font", создаваемой функцией ChooseFont, придется использовать для выбора шрифтов список, создаваемый с помощью функции EnumFontFamilies . Эту функцию можно также использовать для получения информации о шрифте.

Приведем прототип функции EnumFontFamilies:

int EnumFontFamilies(
  HDC hdc,           // идентификатор контекста отображения
  LPCSTR lpszFamily, // адрес имени семейства шрифта
  FONTENUMPROC fntenmprc, // адрес функции обратного вызова
  LPARAM lParam);         // произвольные данные

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

Через параметр lpszFamily передается адрес строки, закрытой двоичным нулем, содержащей название шрифта, для которого требуется получить информацию. Если этот параметр указан как NULL, выбирается один произвольный шрифт для каждого семейства шрифтов.

Параметр fntenmprc задает адрес функции обратного вызова, полученный с помощью функции MakeProcInstance.

Приложение может передать функции обратного вызова произвольные 32-разрядные данные через параметр lParam.

Функция обратного вызова должна быть определена следующим образом (для функции можно использовать любое имя):

int CALLBACK _export EnumFontFamProc(
  NEWLOGFONT FAR* lpnlf,    // адрес структуры NEWLOGFONT
  NEWTEXTMETRIC FAR* lpntm, // адрес структуры метрики 
                            // физического шрифта
  int FontType,             // тип шрифта
  LPARAM lParam); // адрес произвольных данных, переданных
                  // функции EnumFontFamilies через
                  // параметр lParam 

Когда функция EnumFontFamProc получает управление, через параметр lpnlf передается адрес структуры NEWLOGFONT , которая по непонятной причине не описана в файле windows.h. Эта структура аналогична структуре LOGFONT, но имеет в конце два дополнительных поля, определенных только для шрифтов True Type:

typedef struct tagNEWLOGFONT
{
  int  lfHeight;
  int  lfWidth;
  int  lfEscapement;
  int  lfOrientation;
  int  lfWeight;
  BYTE lfItalic;
  BYTE lfUnderline;
  BYTE lfStrikeOut;
  BYTE lfCharSet;
  BYTE lfOutPrecision;
  BYTE lfClipPrecision;
  BYTE lfQuality;
  BYTE lfPitchAndFamily;
  char lfFaceName[LF_FACESIZE];

BYTE lfFullName[2 * LF_FACESIZE];// только для True Type

  BYTE lfStyle[LF_FACESIZE];       // только для True Type
} NEWLOGFONT;

Поле lfFullName представляет собой массив, содержащий полное имя шрифта, которое состоит из названия шрифта и названия стиля.

В поле lfStyle находится название стиля шрифта.

Параметр lpntm функции EnumFontFamProc содержит адрес структуры NEWTEXTMETRIC , описывающей метрику шрифта:

typedef struct tagNEWTEXTMETRIC
{
   int   tmHeight;
   int   tmAscent;
   int   tmDescent;
   int   tmInternalLeading;
   int   tmExternalLeading;
   int   tmAveCharWidth;
   int   tmMaxCharWidth;
   int   tmWeight;
   BYTE  tmItalic;
   BYTE  tmUnderlined;
   BYTE  tmStruckOut;
   BYTE  tmFirstChar;
   BYTE  tmLastChar;
   BYTE  tmDefaultChar;
   BYTE  tmBreakChar;
   BYTE  tmPitchAndFamily;
   BYTE  tmCharSet;
   int   tmOverhang;
   int   tmDigitizedAspectX;
   int   tmDigitizedAspectY;

   // Дополнительные поля
   DWORD ntmFlags;
   UINT  ntmSizeEM;
   UINT  ntmCellHeight;
   UINT  ntmAvgWidth;
} NEWTEXTMETRIC;
typedef NEWTEXTMETRIC*       PNEWTEXTMETRIC;
typedef NEWTEXTMETRIC NEAR* NPNEWTEXTMETRIC;
typedef NEWTEXTMETRIC FAR*  LPNEWTEXTMETRIC;

Структура NEWTEXTMETRIC аналогична структуре TEXTMETRIC, за исключением четырех дополнительных полей, добавленных в конце. Эти поля описывают физические атрибуты шрифта True Type.

Поле ntmFlags может содержать значения NTM_REGULAR, NTM_BOLD или NTM_ITALIC, соответственно, для нормального, жирного или наклонного шрифта True Type.

Поле ntmSizeEM содержит ширину буквы "М", в единицах, использованных при разработке шрифта.

В поле ntmCellHeight находится высота шрифта в единицах, использованных при разработке шрифта.

Поле ntmAvgWidth содержит ширину шрифта в единицах, использованных при разработке шрифта.

Параметр FontType функции EnumFontFamProc определяет тип шрифта и может содержать одно из следующих значений:

Значение Описание
DEVICE_FONTTYPE Шрифт устройства вывода
RASTER_FONTTYPE Растровый шрифт
TRUETYPE_FONTTYPE Шрифт True Type

Через последний параметр функции EnumFontFamProc передаются 32-разрядные данные, указанные в параметре lParam функции EnumFontFamilies.

Если приложение собирается продолжить просмотр доступных шрифтов, функция EnumFontFamProc должна возвратить ненулевое значение. Если просмотр должен быть завершен, следует возвратить нуль.

[Назад] [Содеожание] [Дальше]