На этом шаге мы рассмотрим некоторые API-функции, применяемые
при работе с графикой.
Класс TCanvas инкапсулирует лишь наиболее популярные приемы
работы с чертежными инструментами. В этом
разделе перечисляются некоторые функции Windows, которые не
инкапсулирует класс
TCanvas и которые способны значительно разнообразить текстовый
вывод (именно он наиболее
обеднен узкими рамками TCanvas).
Перечислим некоторые функции API.
Таблица 1. Некоторые функции
API
Функция | Описание |
---|---|
function CreateFont (Font: TLogFont): hFont; | Создает новый шрифт на основе данных в параметре Font. Назначение полей структуры TLogFont смотрите после таблицы. |
function DrawText (DC: hDC; pText: PChar; var Rect: TRect; Format: UINT): Integer; | В прямоугольнике Rect выводит многострочный текст, на который указывает pText. Параметр Format используется для форматирования (смотри таблицу 2). |
function ExtTextOut (DC: hDC; X, Y: Integer; Options: Integer; Rect: TRect; pText: PChar; Count: Integer; PX: PInteger): Bool; | Выводит текст с нестандартными межсимвольными расстояниями:
|
function GetBkColor (DC: hDC): TColor; | Возвращает цвет фона. |
function GetBkMode (DC: hDC): Integer; | Возвращает режим прорисовки фона: Opaque - фон прорисовывается заново при выводе текста; Transparent - фон не прорисовывается. |
function GetTextAlign (DC: hDC): Integer; | Возвращает выравнивание текста. |
function GetTextCharacterExtra (DC: hDC): Integer; | Возвращает межсимвольное расстояние. |
function SetBkColor (DC: hDC; Color: TColor): TColor; | Устанавливает новый цвет фона и возвращает старый, если обращение успешно. |
function SetBkMode (DC: hDC; Mode: Integer): Integer; | Устанавливает новый режим прорисовки фона и возвращает старый, если операция успешна. |
function SetTextAlign (DC: hDC; Flags: Integer): Integer; | Устанавливает новое выравнивание текста и возвращает старое, если вызов успешен. |
function SetTextCharacterExtra (DC: hDC; CharExtra: Integer): Integer; | Устанавливает новое межсимвольное расстояние и возвращает старое, если вызов успешен. |
Отдельные поля структуры TLogFont для функции
CreateFontIndirect имеют следующий
смысл:
- lfHeight - высота шрифта в пунктах (1 пункт = 1/72 дюйма). Если
значение больше
0, то определяет высоту "знакоместа" (с учетом выступающих над заглавным
символом элементов в буквах Е, И).
Если значение меньше нуля - высоту "чистого" символа. Если 0 - высоту
выбирает Windows; - lfWidth - средняя ширина символа; если 0, ширину устанавливает
Windows; - lfEscapment - угол наклона базовой линии текста в десятых долях
градуса относительно горизонтального
направления. Положительные значения - поворот по часовой стрелке (в
Windows 95/98 совпадает c lfOrientation); - lfOrientation - угол наклона символов по отношению к базовой линии;
в Windows NT
для шрифтов TrueType может отличаться от 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_Bold (700) - жирный;
- fm_ExtraBold (800) - усиленный;
- fm_Heavy(900) - тяжелый;
- lfItalic, lfUnderline, lfStrikeOut - ненулевые значения задают
соответственно наклонный, перечеркнутый и подчеркнутый шрифт; - lfCharSet - набор символов (ANSI_CharSet (или 0),
Default_CharSet (1), Symbol_CharSet (2); ShiftJis_CharSet
(128); OEM_CharSet (255)); - lfOutPrecision - точность представления шрифта. Рекомендуется
значение
OUT_TT_PRECIS (выбирает TrueType и векторные шрифты, если
есть несколько разновидностей одноименных
шрифтов) или OUT_TT_ONLY_PRECIS (выбирает только
TrueType шрифты); - 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 - имя гарнитуры шрифта.
Приведем пример использования некоторых рассмотренных конструкций.
Пусть, например, нужно создать приложение,
при выполнении которого на экране появляется следующее изображение:
Рис.1. Внешний вид приложения
Вот как реализован этот пример:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormPaint(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormPaint(Sender: TObject); var X: Integer; LF: TLogFont; Fnt: HFont; const Text = 'Лучшая в мире система программирования'; 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; // Выводим текст под углом +45 градусов. TextOut(0, 300, Text); X:= TextWidth(Text) ; DeleteObject(Fnt); // Удаляем ненужный шрифт. // Изменяем параметры шрифта. with LF do begin lfHeight := 90; lfEscapement := -900; lfWeight := fw_Heavy; StrPCopy(LF.lfFaceName, 'Arial Cyr'); end; Fnt:=CreateFontIndirect(LF); // Создаем новый шрифт. Font.Handle := Fnt; Font.Color := clRed; // Выводим снаклоном -90 градусов. TextOut(X-10, 10, 'Delphi 6'); DeleteObject(Fnt); // Удаляем ненужный шрифт. end; end; end.
Текст этого примера можно взять здесь.
Параметр Format функции DrawText может содержать один или
несколько флагов,
перечисленных в таблице 2.
Таблица 2. Возможные значения
параметра Format функции DrawText
Параметр | Описание |
---|---|
dtBottom | Текст прижимается к нижней части области Rect. |
dtCalcRect | Разрешает динамически изменять размеры области Rect. |
dtCenter | Текст центрируется по горизонтали. |
dtEditControl | Функция дублирует свойства отображения многострочного тестового редактора. В частности, таким же способом вычисляется средняя ширина символа и не показывается частично видимая последняя строка. |
dtExpandTabs | Символы табуляции заменяются пробелами. |
dtExternalLeading | В высоту строки включается высота межстрочного интервала. |
dtLeft | Текст прижимается к левой части области Rect. |
dtNoClip | Текст не отсекается границами Rect. |
dtNoPrefix | Символы & не заменяются подчеркиванием. |
dtRight | Текст прижимается к правой части области Rect. |
dtSingleLine | Весь текст выводится единственной строкой, символы перехода на новую строку игнорируются. |
dtTabsStop | Символы табуляции не заменяются пробелами. |
dtTop | Текст прижимается к верхней части области Rect. |
dtVCenter | Текст центрируется по вертикали. |
dtWordBreak | Разрешает переход на новую строку при достижении правой границы Rect; разрыв строки - на границе слова; символы перевода строки также переводят вывод на следующую строку. |
Если установлен флаг dtCalcRect, функция изменяет высоту и ширину
прямоугольника так,
чтобы вывести весь текст, но сам текст не выводится. Если в тексте несколько
строк, ширина
вывода не меняется. Функция возвращает истинную высоту прямоугольника
вывода.
Параметр Options функции ExtTextOut может быть комбинацией
следующих значений:
- ETO_СLIPPED - текст будет отсекаться границами Rect;
- ETO_GLIPH_INDEX - блокирует обработку языковым драйвером;
- ETO_OPAQUE - фон перерисовывается заново;
- ETO_RTLREADING - вывод для чтения справа налево.
При выводе текста стандартными методами TCanvas всегда заново
прорисовывается фон
символов (цвет фона возвращает функция GetBkColor). Если цвет фона
символов отличается
от фона канвы, вывод сопровождается неприятными побочными эффектами.
Конечно, с помощью
функции SetBkColor можно установить цвет формы совпадающим с
цветом канвы, однако
это не всегда возможно. Ясно, что установить переменный цвет функцией
SetBkColor невозможно.
Более того, заглавные надписи программ Setup.exe также традиционно
выводятся утолщенным
наклонным шрифтом Times New Roman белыми буквами с черной тенью.
Реализовать такой
эффект достаточно просто: нужно вообще отказаться от прорисовки фона,
установив
с помощью функции SetBkMode режим Transparent, и вывести
надпись дважды:
первый раз черным цветом, а второй - белым, сместив вторую надпись немного
влево и
вверх относительно первой:
Рис.2. Внешний вид приложения
Следующий листинг иллюстрирует сказанное:
procedure TForm1.FormPaint(Sender: TObject); var Y: Integer; Blue: Byte; const Text = 'Фон для программы Setup.exe'; begin with Form1.Canvas do begin for Y := 0 to Form1.Height-1 do begin //Уменьшаем интенсивность цвета с ростом ординаты Y. Blue := Round($FF*(Form1.Height-Y)/Form1.Height); Pen.Color := RGB(0, 0, Blue); // Формируем цвет. MoveTo(0, Y); // Чертим линию. LineTo(Form1.Width-1, Y) ; end; Font.Size := 32; Font.Style := [fsBold, fsItalic, fsUnderline]; Font.Name := 'Times New Roman'; // Это обращение накладывает текст на фон. SetBkMode(Handle, Transparent); // Сначала выводим тень надписи. Font.Color := clBlack; TextOut(40, 30, Text); // Теперь саму надпись. Font.Color := clWhite; TextOut(36, 26, Text); end; end;
Текст этого примера можно взять здесь.
Примечание. Любая заливка фона, в том числе его прорисовка,
реализуется с
помощью кисти. Поэтому отказаться от прорисовки фона текста можно, если
установить стиль
кисти bsClear. Вместо SetBkMode (Handle, Transparent); можно
использовать
Brush.Style:=bsClear;.
На следующем шаге мы рассмотрим такое понятие, как области.