Класс TCanvas в Delphi включает далеко не все возможности Windows по выводу текста. Например, нет средств вывода вертикального текста или вывода текста под углом. Рассмотрим средства API, позволяющие решить эту и некоторые другие проблемы. Замечу, что на полноту информации я не претендую и опускаю некоторые функции, которые я не применял в своей практике.
Начнем наше знакомство со средствами API с очень важного типа: type TLogFont = record LfHeight: Integer; LfWidth: Integer; LfEscapment: Integer; LfOrientation: Integer; LfWeight: Integer; LfItalic: Byte; LfUnderline: Byte; LfStrikeOut:Byte; LfCharSet: Byte; LfOutPrecision: Byte; LfClipPrecision: Byte; LfQuality: Byte; LfPitchAndFamily: Byte; LfFaceName: PChar ; end;
Отдельные поля записи TLogFont имеют следующий смысл:
LfHeight - высота шрифта в пунктах (1 пункт = 1/72 дюйма); если больше 0, определяет высоту "знакоместа" (с учетом выступающих над заглавным символом элементов в буквах Е, И), если меньше нуля - высоту "чистого" символа, если 0 - высоту выбирает Windows;
LfWidth - средняя ширина символа; если 0, ширину устанавливает Windows;
LfEscapment - угол наклона базовой линии текста в десятых долях градуса относительно горизонтального направления; положительные значения - поворот по часовой стрелке; отрицательное - против; в Windows 95/98 совпадает c LfOrientation;
LfOrientation - угол наклона символов по отношению к базовой линии; в Windows NT для шрифтов True Type может отличаться от LfEscapment; для этого следует установить режим устройства отображения равным gm_Advanced (по умолчанию устанавливается gm_Compatible);
LfWeight - плотность шрифта: fm_DontCare=0 - плотность выбирает Windows; fm_Thin=100 - очень тонкий шрифт; fm_ExtraLight=200 - очень светлый; fm_Light=300 - светлый; fm_Normal=400 - нормальный; fm_Medium=500 - утолщенный; fm_SemiBold=600 - полужирный; fm_Bcld=700 - жирный; fm_ExtraBold=800 - усиленный; fm_Heavy=900 - тяжелый;
LfItalic, LfUnderiine, LfStrikeOut - ненулевое значение означает соответственно наклонный, перечеркнутый и подчеркнутый шрифт;
LfCharSet - набор символов: ANSI_CharSet=0, Default_CharSet=l, Symbol_CharSet=2, ShiftJis_CharSet=128, OEM_CharSet=255;
LfOutprecision - точность представления шрифта; рекомендуется Out__TT_Prec (выбирает True Type и векторные шрифты, если есть несколько разновидностей одноименных шрифтов) или Out_TT_Only_Prec (только True Type);
LfClipprecision - определяет точность отсечения надписи границами области прорисовки (Clip_Character_Precis, Clip_Embedded, Clip_Mask, Clip_TT_Always, Clip_Default_Precis - рекомендуется, Clip_LH_Angles, Clip_Stroke_Precis);
LfQuality - определяет качество прорисовки (Default_Quality, draft_Quality, Proof_Quality);
LfPitchAndFamily - в четырех младших разрядах указывается тип шрифта, в четырех старших его семейство;
LfFaceName - имя гарнитуры шрифта.
Следующий код показывает пример заполнения структуры LF типа TLogFont параметрами шрифта: // Определяем параметры нового шрифта FillChar(LF, SizeOf(LF), 0) ; with LF do begin lfHeight := 20; // высота lfWeight := fw_Normal; // жирность lfUnderline := 1; // режим подчеркивания включен lfEscapement := 450; // выводим под 45 градусов к горизонтали StrPCopy(lfFaceName, 'Courier New Cyr'); // за базу берем шрифт Courier end;
Переменная LF должна быть до этого описана как TLogFont.
Сам шрифт создается примерно так (для формы Form1): with Form1.Canvas do begin // Создаем шрифт Fnt := CreateFontIndirect(LF) ; // Присваиваем его дескриптор шрифту канвы Font.Handle := Fnt; end
Переменная Fnt должна иметь тип HFont.
Приведу пример кода вывода текста под углом (метод Paint для формы Form1): procedure TForm1.FormPaint(Sender: TObject); var LF: TLogFont; Fnt: HFont; const Text = 'Это текст, написанный методами API'; begin // Определяем параметры нового шрифта FillChar(LF, SizeOf(LF), 0) ; with LF do begin lfHeight := 20; lfWeight := fw_Normal; lfUnderline := 1; lfEscapement := 450; StrPCopy(lfFaceName, 'Courier New Cyr'); end; with Form1.Canvas do begin // Создаем шрифт Fnt := CreateFontIndirect(LF) ; // Присваиваем его дескриптор шрифту канвы Font.Handle := Fnt; // Выводим текст TextOut(0, 300, Text); DeleteObject(Fnt); // Удаляем шрифт end; end;
Надеюсь, приведенные примеры достаточно ясно отражают суть использования API для вывода текста. Функции работы с фоном я опустил и некоторые другие - не хочу писать о том, чего сам не использовал. Я написал компонент Дельфи, использующий API для вывода текста, который можно скачать ниже.