Шрифты и GDI

В начало

Основные понятия

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

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

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

Масштабируемые шрифты TrueType лишины недостатков, характерных для первых двух типов. Эти шрифты состоят из изображений отдельных символов - глифов (glyph). Для внутреннего представления глифа в файле шрифта True Type используются описания контуров, причем один глиф может содержать несколько контуров. Масштабирование шрифта выполняется масштабированием составляющих контуров глифов или кусочков символов, каждый из которых сведен к легко масштабируемому примитиву (квадрат, круг, треугольник, элипс и т.п.).

Шрифты классифицируются по семействам (font family - Modern или шрифты с одинаковой шириной букв, Roman или шрифты с засечками и т.д).

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

Шрифты могут иметь нормальное (normal), жирное (bold) или наклонное (italic) начертание, быть подчеркнутыми или перечеркнутыми.

В начало

Структура LOGFONT и параметры шрифтов

Для того, чтобы написать строку текста заданным шрифтом, этот шрифт следует, подобно остальным объектам GDI, выбрать в контекст отображения, который по умолчанию содержит атрибуты системного шрифта. Приложение Windows имеет возможность задать характеристики шрифта в структуре LOGFONT и затем создать шрифт на основе данных характеристик и перенести его в DC для последующего использования функциями вывода текстов.

Структура LOGFONT определяет атрибуты шрифта:

typedef struct tagLOGFONT 
{   
 // высоту ячейки шрифта в логических единицах 
 LONG     lfHeight;        
 // ширина ячейки шрифта в логических единицах 
 LONG     lfWidth;         
 // угол между базовой линией шрифта и координатной осью 
 // X в десятых долях  градуса (угол в направлении 
 // против часовой стрелк (для True Type)
 LONG     lfEscapement;                       
 // ориентация символов шрифта                   
 LONG     lfOrientation;   
 // вес шрифта или жирность символов шрифта, число  от 0 до 1000. 
 LONG     lfWeight;        
 // начертания шрифта                         
 BYTE     lfItalic;       
 BYTE     lfUnderline; 
 BYTE     lfStrikeOut; 
 // набор символов 
 BYTE     lfCharSet;       
 // требуемая степень соответствия параметров шрифта 
 // 0-7 7 для шрифтов True Type
 BYTE     lfOutPrecision;  
 // способ, при помощи которого обрезается изображение символа
 BYTE     lfClipPrecision; 
 // качество шрифта, полученного при отображении
 BYTE     lfQuality;       
 // нужна ли фиксированная или переменна ширина  символов 
 BYTE     lfPitchAndFamily;
 //названием внешнего вида шрифта
 TCHAR    lfFaceName[LF_FACESIZE]; 
}LOGFONT; 

lfHeight, lfWidth - могут иметь положительные и отрицательные значения, а также нуль. Если указано нулевое значение, выбирается шрифт со значениями по умолчанию: для lfHeight - 12 пунктов и lfWidth - зависит он высоты шрифта. Положительные значения определяют высоту ячеек, соответствующую содержимому поля tmHeight структуры TEXTMETRICS. Абсолютная величина отрицательного значения определяет высоту символов.

lfCharSet - набор символов, может принимать значения:

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

Подробно рассматривать все параметры структуры нет необходимости - их предназначение всегда можно посмотреть в Help Builder, более подробно предназначение некоторых будет ясно из примера, приведенного ниже.

В начало

Пример создания и использования шрифтов

Использование шрифтов с функциями GDI аналогично использованию других объектов. Для этого необходимо:

  • задать характеристики шрифтов, в структуре LOGFONT;

  • создать шрифт на основе информации из LOGFONT;

  • получить контекст устройства отображения;

  • выбрать шрифт в контекст устройства;

  • определить вспомогательные параметры типа цвета текста, прозрачность и др.;

  • вывести текст;

  • освободить ресурсы.

Следующий пример показывает вывод слова Tекст c использованием описанных шагов:

void __fastcall
TForm1::Button1Click(TObject *Sender)
{
 // Старый и новый шрифт
 HFONT     hFont,hFontOld;
 // Структура определения шрифтов
 LOGFONT   tLf;
 tLf.lfUnderline=1;
 tLf.lfItalic=1;
 tLf.lfStrikeOut = 0;
 tLf.lfEscapement=0;
 tLf.lfOrientation=0;
 // Значение 700 из 1000
 tLf.lfWeight=FW_BOLD;
 tLf.lfCharSet=RUSSIAN_CHARSET;
 // Использовать True Type, даже если 
 // есть подходящий шрифт другого типа
 tLf.lfOutPrecision=4;
 // Использовать точность, заданную по умолчанию
 tLf.lfOutPrecision = OUT_DEFAULT_PRECIS;
 // Способ отсечения символа за пределами области
 tLf.lfClipPrecision = CLIP_DEFAULT_PRECIS; 
 // Нужен шрифт с переменной шириной символов семейства
 //  Roman. Переменная ширина букв c засечками
 tLf.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
 // Низкое качество. Допустимо масштабирование шрифтов,
 // синтезирование наклонных, жирных, перечеркнутых и т.п.
 tLf.lfQuality=DRAFT_QUALITY; 
 // Имя шрифта
 wsprintf(tLf.lfFaceName,"Times Nev Roman"); 
 // Желательные размеры шрифта
 tLf.lfHeight=50;
 tLf.lfWidth = 20;
 // Создаем шрифт
 hFont = CreateFontIndirect(&tLf);
 // Где будем писать, получаем HDC устройства
 HDC     hDc=GetDC(Handle);
 // HDC  hDc=CreateDC("DISPLAY",NULL,NULL,NULL);
 // Выбираем шрифт в контекст устройства
 hFontOld=(HFONT)SelectObject(hDc,hFont);
 // Дополнительные параметры текста
 SetTextColor(hDc, RGB(0,0,255));
 SetBkMode(hDc,TRANSPARENT);
 // Выводим текст
 TextOut(hDc,50,20,"Текст",5);
 //Возвращаем все на свои места
 SelectObject(hDc,hFontOld);
 DeleteDC(hDc);
 DeleteObject(hFont);
 DeleteObject(hFontOld);
}

Следует отметить функцию ChooseFont(), предназначенную для выбора одного из зарегистрированных в системе шрифтов. Эта функция выводит на экран диалоговую панель "Font", с помощью которой пользователь может выбрать шрифт, стиль шрифта, размер шрифта, цвет букв, может выбрать подчеркнутый или перечеркнутый шрифт. Эту функцию можно использовать для точной выборки шрифтов, зарегистрированных в системе в режиме диалога и в последующем корректировке отдельных параметров. Функция имеет только один параметр - указатель на структуру CHOOSEFONT;

 
BOOL ChooseFont
(
 LPCHOOSEFONT lpcf 
);

Функция ChooseFont() в Borland C++ Builder переопределена в компоненте TFontDialog, о чем речь пойдет позже.

В начало

В начало главы

В начало раздела

Домой