19.5.3. Заливка областей изображения

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

Bar( X1, Y1, X2, Y2 : Integer )

рисует прямоугольник, внутренняя область которого залита по текущему шаблону. Она обычно используется в деловой графике для построения столбчатых диаграмм. Параметры (X1,Y1) и (X2,Y2) — координаты верхнего левого и правого нижнего углов прямоугольника. Еще более наглядное представление информации при рисовании диаграмм позволяет получить процедура

Bar3D( X1,Y1, X2,Y2 : Integer; D3 : Word; Top : Boolean )

Она рисует параллелепипед, лицевая сторона которого заливается по текущему шаблону, а глубина задается в пикселах параметром D3. Параметр Top задает режим отображения верхней плоскости: True — отображать, False — не отображать. Этот параметр необходим для того, например, чтобы можно было рисовать столбцы, стоящие друг на друге. В модуле Graph определены две константы для нее:

CONST

TopOn = True; { верхняя плоскость нужна }

TopOff = False; { верхняя плоскость не нужна }

Следующие «заполняющие» процедуры работают с секторами окружностей и эллипсов. Рисование сектора эллипса, который будет залит цветом по текущему шаблону, осуществляется процедурой

Sector( X, Y : Integer;

StartAngle, EndAngle, XRadius, YRadius : Word )

Параметры процедуры имеют тот же смысл, что и в процедурах Arc, Ellipse (см. разд. 19.4.3). Для задания кругового сектора надо задавать YRadius с учетом коэффициента сжатия:

- 440 -

VAR

R, А, В : Word; { R - радиус кругового сектора }

BEGIN

...

GetAspectRatio( А, В );

Sector( 100, 100, 0, 90, R, R*LongInt( A ) div В );

...

END.

Этого же эффекта можно достичь, используя процедуру

PieSlice( X, Y : Integer;

StartAngle, EndAngle, Radius : Word )

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

К рассмотренным процедурам примыкает еще одна:

FillEllipse( X, Y : Integer; XRadius, YRadius : Word )

Она рисует эллипс текущим цветом и заполняет его по установленному шаблону. Параметры этой процедуры имеют такой же смысл, как и параметры описанной в разд. 19.4.3 процедуры Ellipse.

Заполнение более сложных геометрических фигур, в том числе и неправильной формы, производится процедурой

FillPoly( NumPoints : Word; VAR PolyPoints )

Ее параметры имеют такое же назначение, как и в процедуре DrawPoly (см. разд. 19.4.4). Единственное отличие в том, что координаты первой и последней вершины многоугольника могут не совпадать. Однако все равно они будут соединены линией, и внутренность фигуры будет залита (рис. 19.23).

| USES Graph; { подключен модуль Graph }

| {$I initgraf.pas} { процедура инициализации} CONST

| our_figure : Array [1..4] of PointType =

| ((x : 319; y : 40), { Задание координат концов}

| ( x : 398; y : 146), { отрезков, являющихся сто- }

| ( x : 240; y : 146), { ронами нашей геометричес- }

| ( x : 400; y : 40 )); { кой фигуры }

Рис. 19.23

- 441 -

| BEGIN GrInit; { инициализация графики }

| SetFillStyle(InterleaveFill, Red); { задание шаблона }

| FillPoly( SizeOf(our_figure) div SizeOf( PointType ), our_figure );

| { рисование заданной фигуры }

| ReadLn; { пауза до нажатия ввода }

| CloseGraph { закрытие графики }

| END.

Рис. 19.23 (окончание)

Обратите внимание на то, как в этом примере вычисляется количество точек многоугольника. Функция SizeOf (our_figure) возвращает размер константы our_figure в байтах, a SizeOf (PointType) — размер памяти, занимаемый одним элементом типа PointType. И, наконец, можно сказать, универсальная процедура

FloodFill( X, Y : Integer; Border : Word )

Она заливает всю область вокруг точки (X,Y), ограниченную линиями цвета Border. Например, если точка (X,Y) находится внутри области, ограниченной окружностью, то вся область будет залита по шаблону и цветом, установленными процедурами SetFillPattern или SetFillStyle. Если же точка будет находиться вне этой области, то залитым будет весь экран за исключением этой области. Обратите внимание на то, что если область не замкнута сплошной линией или границами экрана, то по шаблону заполнится весь экран. Следует помнить, что использование очень редкого заполнения шаблона на маленьких областях чревато некорректной работой процедуры (рисунок шаблона может не проявиться). Вообще говоря, авторы языка Турбо Паскаль, исходя из требований переносимости программ в последующие его версии, рекомендуют не пользоваться описанной процедурой и заменять ее, где это возможно, процедурой FillPoly, работающей более корректно.