Шрифты и 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 аналогично использованию других объектов. Для этого необходимо:
Следующий пример показывает вывод слова 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, о чем речь пойдет позже.
|