Опубликован: 10.04.2015 | Уровень: для всех | Доступ: платный | ВУЗ: Компания ALT Linux
Лекция 10:

Графика в Lazarus

< Лекция 9 || Лекция 10: 12

Данная глава посвящена графическим средствам языка. Рассмотрены основные процедуры и функции работы с графикой. Приведён пример построения графика функции.

10.1 Средства рисования в Lazarus

При разработке проекта, в котором можно рисовать, в распоряжении программиста находится полотно (холст) — свойство Canvas, карандаш — свойство Pen, и кисть — свойство Brush.

Свойством Canvas обладают следующие компоненты:

  • форма (класс Tform);
  • таблица (класс TSringGrid);
  • растровая картинка (класс Timage);
  • принтер (класс TPrinter).

При рисовании компонента, обладающего свойством Canvas, сам компонент рассматривается как прямоугольная сетка, состоящая из отдельных точек, называемых пикселями. Положение пикселя характеризуется его вертикальной (X) и горизонтальной (Y) координатами. Левый верхний пиксель имеет координаты (0,0). Вертикальная координата возрастает сверху вниз, горизонтальная — слева направо. Общее количество пикселей по вертикали определяется свойством Height, а по горизонтали — свойством Weight. Каждый пиксель может иметь свой цвет. Для доступа к любой точке полотна используется свойство Pixels[X,Y]:TColor. Это свойство определяет цвет пикселя с координатами X(integer), Y(integer).

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

Компонент. Canvas. Pixels [X,Y] : = Color;

где Colorпеременная или константа типа Tcolor.

Таблица 10.1. Значение свойств Color
Константа Цвет Константа Цвет
clBlack Чёрный clSilve Серебристый
clMaroon Каштановый clRed Красный
clGreen Зелёный clLime Салатовый
clOlive Оливковый clBlue Синий
clNavy Тёмно-синий clFuchsia Ярко-розовый
clPurple Розовый clAqua Бирюзовый
clTeal Лазурный clWhite Белый
clGray Серый

Определены следующие константы цветов (табл. 10.1).

Цвет любого пикселя можно получить с помощью следующего оператора присваивания:

Color :=Компонент. Canvas. Pixels [X,Y ];

где Colorпеременная типа Tcolor.

Класс цвета точки Tcolor определяется как длинное целое longint. Переменные этого типа занимают в памяти четыре байта. Четыре байта переменных этого типа содержат информацию о долях синего (B), зелёного (G) и красного (R) цветов и устроены следующим образом: $00BBGGRR.

Для рисования используются методы класса TСanvas, позволяющие изобразить фигуру (линию, прямоугольник и т. д.) или вывести текст в графическом режиме, и три класса, определяющие инструменты вывода фигур и текстов:

  • TFont (шрифты);
  • TPen (карандаш, перо);
  • TBrush (кисть).

Класс TFONT. Можно выделить следующие свойства соответствующего объекта Canvas.TFont:

  • Name (тип string) — имя используемого шрифта.
  • Size (тип integer) — размер шрифта в пунктах (points). Пункт — это единица измерения шрифта, равная 0,353 мм или 1/72 дюйма.
  • Style — стиль начертания символов, который может быть обычным, полужирным (fsBold), курсивным (fsItalic), подчёркнутым (fsUnderline) и перечёркнутым (fsStrikeOut). В программе можно комбинировать необходимые стили, например, чтобы установить стиль "полужирный курсив" необходимо написать следующий оператор: Объект. Canvas. Font. Style : = [ fsItalic, fsBold ]
  • Color (тип Tcolor) — цвет символов.
  • Charset (тип 0..255) — набор символов шрифта. Каждый вид шрифта, определяемый его именем, поддерживает один или более наборов символов. В табл. 10.2 приведены некоторые значения Charset.
Таблица 10.2. Значения свойства Charset
Константа Значение Описание
ANSI_CHARSET 0 Символы ANSI
DEFAULT_CHARSET 1 Задаётся по умолчанию. Шрифт выбирается только по его имени Name и размеру Size. Если описанный шрифт недоступен в системе, он будет заменён другим
SYMBOL_CHARSET 2 Стандартный набор символов
MAC_CHARSET 77 Символы Macintosh
GREEK_CHARSET 161 Греческие символы
RUSSIAN_CHARSET 204 Символы кириллицы
EASTEUROPE_CHARSET 238 Включает диалектические знаки (знаки, добавляемые к буквам и характеризующие их произношение) для восточно-европейских языков

Класс TPEN. Карандаш (перо) используется как инструмент для рисования точек, линий, контуров геометрических фигур. Основные свойства объекта Canvas.TPen:

  • Color (тип Tcolor) — определяет тип линии;
  • Width (тип Integer) — задаёт толщину линии в пикселях;
  • Style — даёт возможность выбрать вид линии. Это свойство может принимать значение, указанное в таблице 10.3.
    Таблица 10.3. Виды линий
    Значение Описание
    psSolid Сплошная линия
    psDash Штриховая линия
    psDot Пунктирная линия
    psDashDot Штрихпунктирная линия
    psDashDodDot Линия, чередующая штрих и два пунктира
    psClear Нет линии
  • Mode — определяет, каким образом взаимодействуют цвета пера и полотна. Выбор значения этого свойства позволяет получать различные эффекты. Возможные значения Mode приведены в табл. 10.4. По умолчанию вся линия вычерчивается цветом, определяемым значением Pen.Color, но можно определять инверсный цвет линии по отношению к цвету фона. В этом случае независимо от цвета фона, даже если цвет линии и фона одинаков, линия будет видна.
Таблица 10.4. Возможные значения свойства Mode
Режим Операция Цвет пикселя
pmBlack Black Всегда чёрный
pmWhite White Всегда белый
pmNop Неизменный
pmNot Not Screen Инверсный цвет по отношению к цвету фона
pmCopy Pen Цвет, указанный в свойствах Color пера Pen (это значение принято по умолчанию)
pmNotCopy Not Pen Инверсия цвета пера
pmMergePenNot Pen or Not Pen Дизъюнкция цвета пера и инверсного цвета фона
pmMaskPenNot Pen and Not Screen Конъюнкция цвета пера и инверсного цвета фона
pmMergeNotPen Not Pen or Screen Дизъюнкция цвета фона и инверсного цвета пера
PmMaskNotPen Not Pen and Screen Конъюнкция цвета фона и инверсного цвета пера
pmMerge Pen or Screen Дизъюнкция цвета пера и цвета фона
pmNotMerge Not (Pen or Screen) Инверсия режима pmMerge
pmMask Pen and Screen Конъюнкция цвета пера и цвета фона
pmNotMask Not (Pen and Screen) Инверсия режима pmMask
pmXor Pen xor Screen Операция xor над цветом пера и цветом фона
pmNotXor Not (Pen xor Screen) Инверсия режима pmXor

Класс TBRUSH. Кисть (Canvas.Brush) используется методами, обеспечивающими вычерчивание замкнутых фигур для заливки. Кисть обладает двумя основными свойствами:

  • Color (тип Tcolor) — цвет закрашивания замкнутой области;
  • Style (тип TBrushStyle) — определяет стиль заполнения области (bsSolid — сплошное заполнение, bsClear — прозрачное, bsHorizontal — горизонтальные линии, bsVertical — вертикальные линии, bsFDiagonal, bsBDiagonal — диагональные линии, bsCross — решётка, bsDiagCross — диагональная решетка).

Класс TCANVAS. Этот класс является основным инструментом для рисования графики. Рассмотрим его наиболее часто используемые методы.

procedure MoveTo(X, Y : integer );

Метод MoveTo изменяет текущую позицию пера на позицию, заданную точкой (X,Y). Текущая позиция хранится в переменной PenPos типа Tpoint. Определение типа TPoint следующее:

type TPoint =record
	X : longint;
	Y: longint;
end;

Текущую позицию пера можно считывать с помощью свойства PenPos следующим образом:

X:=PenPos.X;
Y:=PenPos.Y;

procedure LineTo (X, Y : integer);

Метод LineTo соединяет прямой линией текущую позицию пера и точку с координатами (X,Y). При этом текущая позиция пера перемещается в точку с координатами (X,Y).

Рассмотрим работу процедуры на примере. Расположим на форме кнопку и рассмотрим процедуру обработки события TForm1.Button1Click, которая рисует прямые линии:

procedure TfForm1. Button1Click ( Sender : TObject )
begin
	Form1. Canvas. LineTo ( 30, 50 );
end;

В результате щелчка по кнопке на форме будет нарисована прямая линия, соединяющая точку с координатами (0,0) и точку с координатами (30,50). При повторном щелчке по кнопке процедура продолжит рисовать эту же линию.

Теперь перепишем процедуру обработки события следующим образом:

procedure TForm1. Button1Click ( Sender : TObject )
begin
	Form1. Canvas. LineTo ( Canvas. PenPos. x+30, Canvas. PenPos. y +50);
end;

При первом щелчке по кнопке на экране прорисуется аналогичная линия. Но при повторном щелчке процедура рисует линию, которая соединяет текущую точку с точкой, получившейся из текущей добавлением к координате X числа 30, а к координате Y — числа 50. Т. е. при повторном щелчке по кнопке процедура соединяет прямой линией точки (30,50) и (60,100). При третьем щелчке по кнопке будут соединяться прямой линией точки (60,100) и (90,150) и т. д.

procedure PolyLine ( const Points array of TPoint );

Метод PolyLine рисует ломаную линию, координаты вершин которой определяются массивом Points.

Рассмотрим работу процедуры на примере. Расположим на форме кнопки Рисовать и Выход и запишем следующие операторы процедур обработки события:

procedure TForm1. Button1Click ( Sender : TObject );
var temp : array [ 1.. 2 5 ] of TPoint;
	i : byte;
	j : integer;
begin
	j : = 1;
	for i :=1 to 25 do
	begin
//вычисление координат вершин ломаной линии
		temp [ i ]. x:=25+( i _ 1) _ 10;
		temp [ i ]. y:=150 _ j _ ( i _ 1) _ 5;
		j :=- j;
	end;
	Form1. Canvas. Polyline ( temp );
end;
procedure TForm1. Button2Click ( Sender : TObject );
begin
	Form1. Close;
end;

После запуска программы и щелчка по кнопке Рисовать окно формы будет выглядеть, как на рисунке 10.1.

procedure Ellipse (X1, Y1, X2, Y2 : integer );

Метод Ellipse вычерчивает на холсте эллипс или окружность. X1, Y1, X2, Y2 — это координаты прямоугольника, внутри которого вычерчивается эллипс. Если прямоугольник является квадратом, то вычерчивается окружность.

procedure Arc (X1, Y1, X2, Y2, X3, Y3, X4, Y4 : integer );

Метод Arc вычерчивает дугу эллипса. X1, Y1, X2, Y2 — это координаты, определяющие эллипс, частью которого является дуга; X3, Y3координаты, определяющие начальную точку дуги; X4, Y4координаты, определяющие конечную точку дуги. Дуга рисуется против часовой стрелки.

procedure Rectangle (X1, Y1, X2, Y2 : integer );

Метод Rectangle рисует прямоугольник. X1, Y1, X2, Y2координаты верхнего левого и нижнего правого углов прямоугольника.

Пример использования процедуры PolyLine

Рис. 10.1. Пример использования процедуры PolyLine

procedure RoundRect (X1, Y1, X2, Y2, X3, Y3 : integer );

Это метод вычерчивания прямоугольника со скруглёнными углами. X1, Y1, X2, Y2координаты верхнего левого и нижнего правого углов прямоугольника, а X3, Y3 — размер эллипса, одна четверть которого используется для вычерчивания скругленного угла.

procedure PolyGon ( const Points array of TPoint );

Метод PolyGon рисует замкнутую фигуру (многоугольник) по множеству угловых точек, заданному массивом Points. При этом первая точка соединяется прямой линией с последней. Этим метод PolyGon отличается от метода Poliline, который не замыкает конечные точки. Рисование осуществляется текущим пером Pen, а внутренняя область фигуры закрашивается текущей кистью Brush.

procedure Pie (X1, Y1, X2, Y2, X3, Y3, X4, Y4 : integer );

Метод Pie рисует замкнутую фигуру — сектор окружности или эллипса — с помощью текущих параметров пера Pen, внутренняя область закрашивается текущей кистью Brush. Точки (X1,Y1) и (X2,Y2) задают прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящей через его его центр и точку (X3,Y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (X4,Y4). Дуга рисуется против часовой стрелки от начальной до конечной точки. Рисуются прямые, ограничивающие сегмент и проходящие через центр эллипса и точки (X3,Y3) и (X4,Y4).

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

Рис. 10.2. Пример использования методов рисования фигур

Создадим форму, установим ей размеры Heigth — 500, Weight — 500. Внизу разместим кнопку, зададим ей свойство Caption — "Рисовать". При запуске программы и щелчке по этой кнопке на форме прорисуются различные фигуры (см. рис. 10.2). Ниже приведён листинг программы, демонстрирующий работу перечисленных методов. Результат работы программы приведен на рис. 10.2.

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
	Classes, SysUtils, LResources, Forms, Controls, Graphics,
	Dialogs, StdCtrls;
type
	{ TForm1 }
	TForm1 = class (TForm)
	Button1 : TButton;
	procedure Button1Click ( Sender : TObject );
private
	{ private declarations }
public
	{ public declarations }
end;
var
	Form1 : TForm1;
implementation
{ TForm1 }
procedure TForm1. Button1Click ( Sender : TObject );
var t : array [ 1.. 5 ] of TPoint;
begin
	//рисование линии
	Form1. Canvas. LineTo ( 500, 500 );
//изменяем цвет и толщину линии
	Form1. Canvas. Pen. Color := clMaroon;
	Form1. Canvas. Pen. Width:= 5;
//рисование прямоугольника
	Form1. Canvas. R e c tan gle ( 50, 50, 200, 200 );
	Form1. Canvas. Pen. Color := clolive;
//рисование эллипса
	Form1. Canvas. Ellipse ( 50, 50, 100, 200 );
//рисование прямоугольника со скруглёнными углами
	Form1. Canvas. RoundRect ( 250, 250, 400, 400, 30, 30 );
//рисование сектора окружности
	Form1. Canvas. Pie ( 300, 300, 400, 400, 350, 350, 500, 500 );
//формирование массива координат вершин пятиугольника
	t [ 1 ]. x :=250; t [ 1 ]. y := 10;
	t [ 2 ]. x :=350; t [ 2 ]. y := 15;
	t [ 3 ]. x :=400; t [ 3 ]. y := 50;
	t [ 4 ]. x :=300; t [ 4 ]. y :=150;
	t [ 5 ]. x :=250; t [ 5 ]. y :=100;
	Form1. Canvas. Polygon ( t );
	Form1. Canvas. TextOut ( 10, 10, ’это вывели текст ’ );
end;
initialization
	{$I unit1.lrs}
end.

procedure TextOut (X, Y : integer; const Text : String );

Эта функция пишет строку текста Text, начиная с позиции с координатами (X,Y). Текущая позиция PenPos пера Pen перемещается в конец выведенного текста. Надпись выводится в соответствии с текущими установками шрифта Font, фон надписи определяется установками текущей кисти. Для выравнивания позиции текста на канве можно использовать методы, позволяющие определить высоту и длину текста в пикселях — TextExtent, TextHeight и TextWidth. Рассмотрим эти функции.

function TextExtent ( const Text : String ) : Tsize;

Эта функция возвращает структуру типа Tsize, содержащую длину и высоту в пикселях текста Text, который предполагается написать на канве текущим шрифтом.

type
Tsize = record
	cx : longint;
	cx : longint;
end;

function TextHeight ( const Text : String ) : integer;

Функция возвращает высоту в пикселях текста Text, который предполагается написать на канве текущим шрифтом.

function TextWidth ( const Text : String ) : integer;

Функция возвращает длину в пикселях текста Text, который предполагается написать на канве текущим шрифтом. Это позволяет перед выводом текста на канву определить размер надписи и расположить её и другие элементы изображения наилучшим образом.

Если цвет кисти в момент вывода текста отличается от того, которым закрашена канва, то текст будет выведен в цветной прямоугольной рамке, но её размеры будут точно равны размерам надписи.

Мы рассмотрели основные функции рисования. Теперь можно перейти непосредственно к рисованию. Но перед этим следует заметить, что если вы свернёте окно с графикой, а затем его восстановите, то картинка на форме исчезнет. Изменение размеров окна также может испортить графическое изображение в нём. Для решения этой проблемы существуют процедуры обработки событий Объект.FormPaint и Объект.FormResize. Процедура Объект.FormPaint выполняется после появления формы на экране, а процедура Объект.FormResize — после изменения размера формы. Следовательно, все операторы рисования нужно помещать внутрь Объект.FormPaint и дублировать в процедуре Объект.FormResize.

< Лекция 9 || Лекция 10: 12
Юрий Шутиков
Юрий Шутиков

По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. 
 

Евгений Силуков
Евгений Силуков

Еще в декабре выполнил тест №1, а его все так и не проверили.

Aalbaz Turaew
Aalbaz Turaew
Азербайджан, Баку
Руфия Биккулова
Руфия Биккулова
Россия, р.п. Старая Кулатка, УлГПУ имени И.Н. Ульянова, 2005