Модуль Graph у програмі Turbo Pascal

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати


Модуль Graph

Модуль Graph являє собою бібліотеку підпрограм, що забезпечує повне управління графічними режимами різних адаптерів дисплеїв: CGA, EGA, VGA і т.д. Бібліотека містить більше п'ятдесяти графічних процедур і функцій, як базових (малювання точок, ліній, кіл тощо), так і розширюють можливості базових (Багатокутники, заповнення фігур, виведення тексту та ін.)

Щоб запустити програму, яка використовує процедури модуля Graph, необхідно, щоб у робочому каталозі перебували соответстственно графічні драйвери (файли з розширенням. BGI), а якщо програма використовує ще й штрихові шрифти, то необхідно, щоб там же знаходилися файли шрифтів (з розширенням. CHR ).

Крім того, системі програмування (компілятору) повинен бути доступний модуль GRAPH. TPU (він не входить до складу файлу TURBO. TPL, а спочатку знаходиться в архіві BGI. ARC).

Файли BGI і зміст модуля Graph

Файл BGI - це графічний інтерфейс (Borland Graphic Interface) фірми Borland. Він забезпечує взаємодію програм з графічними пристроями. Перед роботою програми в графічних режимах дисплея процедура InitGraph визначає тип адаптера, представленого в ПК, і завантажує в пам'ять відповідний BGI-драйвер, в якому визначено можливі режими роботи.

Процедура CloseGraph вивантажує графічний драйвер з пам'яті і відновлює текстовий режим роботи відеоадаптера. У описуваному модулі присутні також процедури, що дозволяють виходити з графічного режиму без вивантаження драйвера (RestoreCRTMode) і повертатися назад (SetGraphMode).

Отже, в робочому каталозі можуть перебувати такі файли:

CGA. BGI

- Драйвер для IBM CGA, MCGA;

EGAVGA. BGI

- Драйвер для IBM EGA, VGA;

HERC. BGI

- Драйвер для Hercules;

ATT. BGI

- Драйвер для АТ & Т6300 (400 рядків);

PC 3270. BGI

- Драйвер для IBM 3270 PC;

IBM 8514. BGI

- Драйвер для IBM 8514.

Такий набір файлів необхідний при складанні програм, які будуть працювати практично на всіх ПК, сумісних з ПК фірми IBM. Якщо ж таке завдання не стоїть, то досить мати один файл, відповідний представленим у використовуваному ПК графічному адаптеру.

Всі процедури і функції модуля Graph можна розбити на функціональні групи:

  1. Управління графічними режимами і їх аналіз (DetectGraph, InitGraph, CloseGraph, GraphDefaults, ClearDevice, InstallUserDriver, RegisterBGIDriver, RestoreCRTMode, SetGraphMode, SetWrifeMode, GetGraphMode, GetModeRange, GetMaxMode, GetModeName, GetDriverName, GraphResuIt,, GraphErrorMsg).

  2. Малювання графічних примітивів і фігур:

    1. управління «поточним покажчиком» (MoveTo, MoveRel, GetMaxX, GetMaxY, GetX, GetY);

    2. власне малювання (Line, LineTo, LineRel, Arc, GetArcCoords, Circle, Sector, Ellipse, Rectangle, DrawPoly);

    3. стиль ліній і коефіцієнт стиснення зображення (SetLineStyle, GetLineSettings, SetAspeclRatio, GetAspectRatio).

  3. Управління квітами і шаблонами заповнення (SetColor, GetColor, SetBkColor, GetBkColor, GetMaxColor, GetPalette, GetPaletteSize, GetDefaultPalette, SetPalette, SetAllPalette, SetRGBPalette, SetFillStyle, SetFillPattern, GetFillPattern, GetFillSettings, SetGraphBufSize, FillPoly, FillEIIipse, FloodFill, PicSlice, Bar, Bar3D).

  4. Бітові операції (PutPixel, GetPixel, ImageSize, Getlmage, Putlmage).

  5. Управління сторінками (SetActivePage, SetVisualPage).

  6. Графічні вікна (вьюпорті) (SetViewPort, GetViewSettings, ClearViewPort).

  7. Управління висновком тексту (RegisterBGIFont, lnstallUserFont, OutText, OutTextXY, SetTextStyle, SetTextJustify, SetUserCharSize, GetTextSettings, GetTextHeight, TextWidth).

Управління графічними режимами. Ініціалізація і закриття графічного режиму

Процедура ініціалізації InitGraph. Найпростіша програма, яка використовує графіком, обов'язково повинна містити блок виклику процедур ініціалізації графічного режиму і звернення до процедури його закриття. Такий блок ініціалізує режим, перевіряє правильність переключення і, якщо всі операції пройшли успішно, допускає подальшу роботу програми. Процедура ініціалізації оголошена таким чином:

InitGraph (VAR GraphDriver; {тип адаптера}

VAR GraphMode Integer; {режим графіки}

DriverPath: String); {шлях до драйверу}

У модулі Graph визначені константи для завдання виду адаптера параметром GraphDriver перед викликом InitGraph (остання константа введена для виклику процедури GetModeRange вже після ініціалізації).

Detect

= 0;

{Автовизначення}

CGA

= 1;

{Адаптер CGA}

HCGA

= 2;

{Адаптер MCGA}

EGA

= 3;

{Адаптер EGA 256 K}

EGA64

= 4;

{Адаптер EGA 64 K}

EGAMono

= 5;

{EGA з моно - Дисплеєм}

IBM8514

= 6;

{Адаптер 8514}

НегсМопо

= 7;

{Адаптер Hercules}

А TT4 00

= 8;

{Для ПЕОМ AT & T}

VGA

= 9;

{Адаптер VGA}

РС3270

= 10;

{Адаптер 3270}

CurrentDriver

=- 128;

{Для GetModeRange}

Якщо параметру GraphDriver присвоїти значення константи Detect система включиться в режим автоопределсіія. Якщо можливо переключення системи в графічний режим, то ініціалізується відповідний BGI-драйвер і включається режим з максимальним дозволом. У параметрах GraphDriver і GraphMode при цьому будуть повернуті автоматично вибрані значення або код помилки.

Така установка параметрів процедури рекомендується в тих випадках, коли програма повинна працювати на різних ПК з різними відеоадаптерами. Однак цей метод передбачає наявність у пам'яті ПК або на диску одночасно всіх драйверів. Якщо програма велика, то наявність всіх драйверів в пам'яті може викликати труднощі.

Якщо ж параметр GraphDriver містить номер конкретного адаптера, то і другий параметр, GraphMode, повинен мати значення (номер) режиму, припустимого при цьому адаптері.

Всі інші графічні установки (положення поточного покажчика, палітра, колір, параметри графічного вікна і т.д.) при ініціалізації приймаються за замовчуванням.

Параметр DriverPath вказує шлях до каталогу, що містить файли з необхідними драйверами. Якщо в нього передається значення "(порожній рядок), то драйвери повинні знаходитися в поточному каталозі. Це ж значення має передаватися DriverPath, якщо необхідні BGI-файли перетворені за допомогою утиліти BINOBJ у файли типу. OBJ, а потім скомпоновані з програмою в ЕХЕ- файл.

Процедура CloseGraph. Для остаточного завершення роботи в графічному режимі необхідно завжди робити виклик процедури CloseGraph. Ця процедура не має параметрів. Вона очищає екран, переводить адаптер в текстовий режим, і, якщо можливо, вивантажує з пам'яті всі BGI-драйвери та штрихові шрифти. Наступний повернення в графічні режими можливий тільки через повторну ініціалізацію.

Обробка помилок ініціалізації

Процедура InitGraph повертає також і результат своєї роботи в параметрі GraphDriver. У разі помилки він може набувати значення, наведені в таблиці.

Значення

Пояснення

-2

Ні графічного адаптера

-3

Не знайдений файл драйвера

-4

Помилка в драйвері (в його коді)

-5

Не вистачає пам'яті для завантаження драйвера

-10

Неможливий режим для вибраного драйвера

-15

Немає такого драйвера

Якщо ж помилок при ініціалізації не виявлено, то в параметрі GraphDriver повертається номер адаптера з наведеного вище списку констант.

У модулі Graph реалізовано ще один спосіб перевірки результату проведення графічної операції. Він здійснюється за допомогою функції

GraphResult: Integer

Ця функція повертає код результату останнього дзвінка однієї з процедур або функцій, зазначених у таблиці.

Bar

Bar3D

ClearViewPort CloseGraph DetectGraph

DrawPoly FillPoly

FloodFill GetGraphMode

ImageSize InitGraph

InstallUserDriver InstallUserFont PieStice RegisterBGIdriver RegisterBGIfont SetAllPalette

SetFillPattern SetFillStyle SetGraphBufSize SetGraphMode SetLineStyle SetPalette SetText

Justify SetTextStyle

Таблиця кодів, які повертаються GraphResult, і розшифровка їх змісту наведена при описі функції GraphErrorMsg, тому що зазвичай ці функції використовуються спільно. Після одного виклику GraphResult наступний її виклик дасть нульове значення, тому для подальшого використання результатів тестування рекомендується зберігати значення цієї функції в будь-якої змінної.

Для швидкої видачі простого повідомлення про тип помилки графічної системи використовується функція, яка перетворює результат виклику функції GraphResult до повідомлення, яке можна вивести процедурою Write. Ця функція оголошена як:

GraphErrorMsg (ErrorCode: Integer): String;

Константи кодів помилок, визначені в модулі Graph, і відповідні їм повідомлення наведено в таблиці нижче.

Константа

Код

Повідомлення про помилку

Переклад і пояснення

grOk

0

No error

Помилки немає

grNoInitGraph

-1

(BGI) Graphics not installed (use InitGraph)

Графіка не ініціалізований

grNotDetected

-2

Graphics hardware not detcted

Графічний адаптер не знайдено

grFileNotFound

-3

Device driver file not detected

BGI-файлу немає у вказаному каталозі

grlnvalidDriver

-4

Invali device driver file

BGI-файл містить неправильний код

grNoLoadMem

-5

Not enough memory to load driver

Немає місця в ОЗУ для завантаження драйвера

grNoScanMem

-6

Out of memory in scan fill

При роботі процедури FillPoly не вистачає робочої пам'яті

grNoFloodMem

-7

Out of memory in flood fill

При роботі процедури FloodFill не вистачає робочої пам'яті

grFontNotFound

-8

Font file not found

CHR-файлу немає у вказаному каталозі

grNoFontMem

-9

Not enough memory to load font

Немає місця в ОЗУ для завантаження шрифту

grlnvalidMode

-10

Invalid Graphics mode for selected driver

Неможливий режим для вибраного драйвера

grError

-11

Graphics error

Помилка графіки

grIOError

-12

Graphics I / O error

Помилка вводу-виводу графіки

grInvalidFont

-13

Invalid font fite

У файлі шрифту неправильний код

grInvalidFontNum

-14

Invalid font number

Неіснуючий номер шрифту

grInvalidDeviceNum

-15

Invalid device number

Неіснуючий номер адаптера

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

Uses Graph;

Procedure GrInit;

Var

GraphDriver: Integer;

GraphMode: Integer;

ErrorCode: Integer;

Begin

GraphDriver: = Detect;

InitGraph (GraphDriver, GraphMode,'');

ErrorCode: = GraphResult;

if ErrorCode <> grOK then

begin

Writeln ('Помилка графіки: ', GraphErrorMsg (ErrorCode));

Writeln ('Програма зупинена ...');

Halt (1);

end;

Begin {Приклад ініціалізації}

GrInit;

Line (0, 0, GetMaxX, GetMaxY);

Readln;

CloseGraph;

E nd.

Надалі процедуру Grlnit краще записати в окремий файл (наприклад, INITGRAF. PAS) і використовувати директиву включення цього файлу при компіляції. Такий блок завжди включає стандартний графічний режим максимального дозволу.

Класифікація та аналіз графічних режимів

Можливі графічні режими для різних адаптерів наведені в таблиці. У другому стовпці наведено імена зумовлених констант, які можна передавати у процедури, що керують графічними режимами. Останній стовпець показує кількість повноекранних зображень, які можуть зберігатися в пам'яті відеоадаптера одночасно.

Драйвер

Ім'я константи режиму і її значення

Дозвіл екрана (у точках)

Палітра

Число відеосторінок

CGA

CGAC0 = 0

320x200

4 кольори

1


CGAC1 = 1

320x200

4 кольори

1


CGAC2 = 2

320x200

4 кольори

1


CGAC3 = 3

320x200

4 кольори

1


CGAHi = 4

640x200

2 кольори

1

MCGA

MCGAC 0 = 0

320x200

4 кольори

1


MCGAC1 = 1

320x200

4 кольори

1


MCGAC2 = 2

320x200

4 кольори

1


MCGAC3 = 3

320x200

4 кольори

1


MCGAMed = 4

640x200

2 кольори

1


MCGAHi = 5

640x480

2 кольори

1

EGA

EGALo = 0

640 x 200

16 кольорів

4


EGAHi = 1

640 x 350

16 кольорів

2

EGA64

EGA64Lo = 0

640x200

16 кольорів

1


EGA64Hi = 1

640x350

4 кольори

1

EGAMono

EGAMonoHi = 3

640x350

2 кольори

1 (2)

Herc

HercMonoHi = 0

720x348

2 кольори

2

АТТ

АТТ400С0 = 0

320x200

4 кольори

1


АТТ400С1 = 1

320x200

4 кольори

1


АТТ400С2 = 2

320x200

4 кольори

1


АТТ400СЗ = 3

320x200

4 кольори

1


ATT 400 Med = 4

640x200

2 кольори

1


АТТ400Н i = 5

640x400

2 кольори

1

VGA

VGALo = 0

640x200

16 кольорів

4


VGAMed = 1

640x350

16 кольорів

2


VGAHi = 2

640x480

16 кольорів

1

PC 3270

PC 3270 Hi = 0

720x350

2 кольори

1

IBM 8514


IBM 8514 Lo = 0

640x480

256 кольорів

1


IBM 8514 = 1

1024x768

256 кольорів

1

Для того щоб повністю використовувати можливості встановленого в ПК адаптера, необхідно скористатися інструкцією по роботі з ним.

Процедура DetectGraph. Для тестування графічного адаптера в модулі Graph оголошена процедура:

DetectGraph (VAR GraphDriver, GraphMode: Integer)

Ця процедура може бути викликана до ініціалізації графіки. Через формальний параметр GraphDriver повертається значення з першого стовпця таблиці зазначеної вище таблиці, а через параметр GraphMode - зазвичай останнє значення з відповідного розділу другого стовпця. Ці значення і рекомендується підставляти в якості фактичних параметрів в процедуру InitGraph. Після визначення GraphDriver автоматично стає доступним діапазон графічних режимів, реалізованих адаптером

Існує можливість маніпуляції режимами роботи графічного адаптера - за допомогою групи процедур та функцій, але вже після ініціалізації графіки. Але часто буває важливим спочатку визначити дозволені значення режимів.

Діапазони графічних режимів. Номер поточного графічного режиму для встановленого драйвера визначається функцією

GetGraphMode: Integer,

Функція

GetMaxMode: Word

повертає номер максимального режиму для графічного адаптера; таким чином, кожен драйвер підтримує діапазон режимів 0 ... GetMaxMode. Зазвичай цей же результат можна отримати з процедури

GetModeRange (GraphDriver: Integer; VAR LoMode, HiMode: Integer),

через параметри LoMode і HiMode, що повертає відповідно нижню і верхню межу режимів для драйвера GraphDriver. Але з ряду технічних міркувань краще користуватися функцією GetMaxMode, вважаючи мінімальний номер режиму рівним нулю.

Функції GetModeName і GetDriverName.

GetModeName (GraphMode: Word): String. Функція повертає рядок, в якій міститься послідовно через прогалини дозвіл, ім'я константи і іноді назву палітри, наприклад, '640x200 CGA '. Представлений приклад допоможе визначити, в яких графічних режимах може працювати використовувана ПЕОМ.

USES Graph;

{Підключений модуль Graph}

{$ I initgraf. pas}

{Процедура ініціалізації}

VAR


mode: Integer;


BEGIN


Grlnit;

{Ініціалізація}

for mode: = 0 to GetMaxMode do

{Показ всіх режимів}

OutTextXY (10, 10 + mode * 10, GetModeName (mode));

ReadLn;

{Пауза до натискання ...}

CloseGraph

{Закриття графіки}

END.


Функція GetDriverName: String дозволяє отримати ім'я драйвера. Її застосування обгрунтовано тільки в тому випадку, якщо у процедурі InitGraph мінлива GraphDriver визначена, як Detect.

Очищення екрану і перемикання режимів

Очищення графічного екрана. Дві наступні процедури виконують майже однакові дії, тільки перша з них є як би підмножиною другий:

ClearDevice

Ця процедура очищає графічний екран і встановлює вказівник позиції в (0, 0), а процедура

GraphDefaults крім очищення екрана встановлює ряд параметрів графічної системи:

  • графічне вікно стає рівним розміру екрану;

  • відновлюється системна колірна палітра;

  • перепризначена кольори основних ліній і фону екрану;

  • товщина і стиль ліній приймаються як за замовчуванням;

  • колір і шаблон заливки геометричних фігур і замкнуті х ламаних приймається як за замовчуванням;

  • встановлювати заново активний шрифт і його стиль.

Процедура GraphDefaults неявно викликається при ініціалізації графіки і виконує, no-суті, всі стартові установки графічних параметрів.

Переключення режимів. Воно здійснюється процедурою SetGraphMode (GraphMode: Integer)

Процедура перемикає систему у вказаний параметром GraphMode режим і очищує екран монітора. При цьому всі характеристики встановлюються за замовчуванням. Такі перемикання можливі тільки в рамках поточного драйвера.

Процедура RestoreCRTMode. При написанні деяких пакетів, які використовують і графічні, і текстові режими роботи, може використовуватися процедура RestoreCRTMode, яка повертає систему в текстовий режим, який працював до ініціалізації графіки. Здавалося б, вже є процедура з подібною дією - CloseGraph. Проте після неї повернення в графічний режим має проводитися через процедуру InitGraph, що досить складно. Якщо ж скористатися процедурою RestoreCRTMode, то повернення в графіку буде досить простим

USES Graph;

{Підключений модуль Graph}

{$ I Initgraf. Pas}

{Процедура ініціалізації}

CONST

{Константи - повідомлення}

graph _ str = 'Це графічний режим';

text _ str = 'А це текстовий режим';

graph _ back = 'А це знову графічний режим';

BEGIN


Grlnit;

{Ініціалізація графіки}

Line (0,0, GetMaxX, GetMaxY};

{Діагональ екрана}

OutTextXY (0,100, graph_str);

{Висновок першого повідомлення}

ReadLn;

{Пауза до натискання введення}

RestoreCRTMode;

{Відновлення текстового режиму}

Write {text_str);

{Висновок другого повідомлення}

ReadLn;

{Пауза до натискання введення}

SetGraphMode (GetGraphMode);

{Відновлення графічного режиму}

Une (0,0, GetMaxX, GetMaxY);

{Діагональ екрана}

OutTextXY (0,100, graph_back);

{Висновок третя повідомлення}

ReadLn;

{Пауза до натискання введення}

CloseGraph

{Закриття графіки}

End.


Зворотне перемикання здійснюється за допомогою функції GetGraphMode, яка повертає номер поточного графічного режиму. При роботі RestoreCRTMode вивантаження графічного драйвера не відбувається, тобто він залишається в пам'яті активним.

Системи координат і «поточний покажчик»

У растровій комп'ютерній графіці екран є прямокутний масив адресованих точок і будь-яке зображення на ньому утворюється як композиція світяться або погашених пікселів. Ці точки адресуються двома цілими - горизонтальним номером точки nx і вертикальним номером ny:

0 <= n х <= nx_max,

0 <= n у <= ny_max,

де nx _ max і ny _ max - кількість адресованих точок по горизонталі та по вертикалі мінус одиниця

У модулі Graph передбачена можливість програмного опитування максимальних адресованих координат екрана. Вона реалізована парою функцій

GetMaxX: Integer;

GetMaxY: Integer.

Повертані ними значення відповідають параметрам nx _ max і ny _ max, будуть відрізнятися для різних режимів і адаптерів. При адресації точок координатами, більшими, ніж ці значення, операція ігнорується.

Точка з адресою (0,0) зазвичай розташована в лівому верхньому кутку екрана дисплея. Координати (nx, ny) називають також координатами пристрою. Вони можуть приймати тільки цілі значення.

«Поточний покажчик» або, як його ще називають, графічний курсор виконує ті ж функції, що і курсор у текстовому режимі, проте є при цьому невидимим. Положення графічного курсору вказує на початкові координати зображення графічного примітиву, виведеного «від поточної позиції».

Графічні координати задають положення точки на екрані дисплея. Оскільки мінімальним елементом, до якого має доступ програміст, є піксель, природно як графічних координат використовувати порядкові номери пікселів. Допустимий діапазон зміни графічних координат складає [0, rx - 1] для X і [0, ry - 1] для Y-координати. Точкою відліку є верхній лівий кут екрану. Значення X - координати відлічуються зліва направо, а Y-координати - зверху вниз. Це відрізняє графічні координати від звичайних декартових координат, прийнятих в математиці, і служить джерелом помилок для початківця програміста.

Для правильного відображення графіка в декартовій системі координат на екрані необхідно врахувати наступне:

  1. Графічні координати приймають тільки цілочисельні значення.

  2. Графічні координати приймають, обмежені як знизу (нульовим значенням), так і зверху (значенням дозволу).

  3. Графічна координата Y відраховується зверху вниз.

Таким чином, геометричні декартові координати точки (X, Y) для відображення на екрані слід перерахувати в графічні (Xg, Yg) за формулами:

Xg = ë Sx * X û + dx,

Yg = ry-ë Sy * Y û - dy,

Де ë X û - Ціла частина X, Sx, Sy - масштабні множники, які обираються зі умови

rx = ë Sx * Xmax û +1

ry = ë Sx * Ymax û +1

Xmax, Ymax - максимальні значення геометричних координат.

Складові dx, dy забезпечують зсув відносно лівого верхнього кута екрану.

Зображення буде зміщено в центр екрану при dx = ë rx / 2 û, dy = ë ry / 2 û.

У графічному режимі поточний покажчик переміщається спеціальними процедурами.

Процедура MoveTo (х, у: Integer) переміщує його в точку екрану з координатами (х, у).

Процедура MoveRel (dx, dy: Integer) переміщує поточний покажчик на dx пікселів по горизонталі і відповідно на dy по вертикалі щодо останнього положення поточного покажчика. Позитивні значення dx і dy збільшують його координати, а негативні - зменшують.

У системі координат дисплея вісь Y направлена ​​вниз, тому, якщо покажчик треба перенести вгору, то прирощення dy має бути негативним.

Для визначення поточного положення графічного курсору використовуються функції

GetX: Integer;

GetY: Integer,

повертають положення покажчика відповідно по осі X і по осі Y. Позиціонування поточного покажчика та опитування його місцезнаходження працюють коректно, навіть якщо робота відбувається за межами координат пристрою.

Змінюють положення поточного покажчика також процедури LineTo, LineRel, OutText.

Всі процедури ініціалізації та очищення екрана (InitGraph, GraphDefaults, ClearDevice, SetGraphMode, SetViewPort і ClearViewPort) встановлюють поточний покажчик в положення (0,0).

Малювання графічних примітивів і фігур. Лінії і їх стилі

Процедура виведення лінії (відрізка) на екран (у поточному кольорі і стилі) визначена в наступному вигляді:

Line (Х1, Y1, Х 2, Y2: Integer)

Тут задаються координати початку (X 1, Y 1) і кінця (X 2, Y 2) відрізка. Можливі ще два методи малювання відрізків:

  1. З поточної крапки в крапку з заданими координатами (X, Y). Виконується процедурою

  2. LineTo (х, у: Integer)

  3. Щодо поточної позиції. Положення поточного покажчика приймається за початок «тимчасових» координат (0,0) і вказується місце розташування кінця відрізка в них. Така побудова робить процедура

  1. LineRel (dx, dy: Integer)

Координати-решт можуть перевищувати межі графічного вікна. При цьому частина відрізка може бути обрізана (але поточний покажчик переміститься в координати кінця відрізка).

У Турбо Паскалі можна керувати стилем ліній: задавати товщину, тип (суцільні лінії, пунктирні і т.п.). Для цього визначені такі типи і константи стилів зображуваних ліній:

TYPE

LineSettingsType = RECORD

LineStyle

: Word;

{Стиль (тип)}

Pattern

: Word;

{Шаблон типу}

Thickness

: Word;

{Товщина}

END;

CONST

{Для значень поля LineStyle:}

SolidLn

= 0

{Суцільна лінія}

DottedLn

= 1

{Точкова лінія}

CenterLn

= 2

{Штрихпунктирними лінія}

DashedLn

= 3

{Пунктирна лінія}

UserBitLn

= 4

{Тип лінії заданий явно шаблоном}

{Для значень поля Thickness:}

NormWidth = 1

{Товщина лінії в один піксел}

ThickWidth = 3

{Товщина лінії в три піксела}

Щоб отримати інформацію про поточний стилі лина, можна скориста аться процедурою

GetLineSettings (VAR LineType: LineSettingsType)

А щоб встановити новий стиль ліній, необхідно використовувати процедуру SetLineStyle (LineStyle, Pattern, Thickness: Word), підставивши в неї відповідні значення. Якщо параметр LineStyle не дорівнює UserBitLn, то значення параметра Pattern не грає ролі і зазвичай задається нулем.

Розглянемо докладно варіант, коли LineStyle одно UserBitLn. У цьому випадку при визначенні типу лінії керуються такими міркуваннями:

  1. Лінія являє собою сукупність відрізків, кожний з яких має довжину 16 пікселів. Якщо довжина лінії не ділиться на 16 без остачі, то останній відрізок обрізається.

  2. Можна задати шаблон-комбінацію шістнадцяти світяться або погашених пікселів. Його представляють як безліч одиниць і нулів: 1 - світиться, 0 - немає. Наприклад, дрібний рівномірний пунктир задається як 1100110011001100 - всього 16 розрядів.

Оскільки Турбо Паскаль не дозволяє працювати з числами, представленими в двійковій системі числення, необхідно перевести отримане число в десяткову (52428) або в шістнадцяткову ($ сссс) систему числення і підставити його фактичним параметром на місце Pattern при виклику SetLineStyle.

Uses Graph;

{Підключений модуль Graph}

{$ I Initgraf.pas}

{Процедура ініціалізації}

Var


x: Integer;


BEGIN


Grlrtit;

{Ініціалізація графіки}

X: = GetMaxX;

{Дозвіл екрану по X}

SetLineStyle (DottedLn, 0, NormWidth);

Line (0, 10, x, 10);

{Тонка суцільна лінія}

SetLineStyle (CenterLn, 0, NormWidth);

Line (0, 20, x, 20);

{Штрихпунктирними лінія}

SetLineStyle (UserBitLn, $ CCCC, NonriWidth);

Line {0, 30, x, 30);

{Лінія 1100110011001100}

SetLineStyle (UserBitLn, $ B38F, NormWidth);

Line (0, 40, x, 40);

{Лінія 1011001110001111}

SetLineStyle (UserBitLn, $ 4C70, NormWidth);

Line (0, 50, x, 50);

{Лінія 0100110001110000}

ReadLn;

{Пауза до натискання введення}

SetLineStyle (DottedLn, 0, ThickWidth);

Line (0. 10, x, 10);

{Товста суцільна лінія}

SetLineStyle (CenterLn, 0, ThickWidth);

Line (0, 20, x, 20);

{Штрих-пунктирна лінія}

SetLineStyle (UserBitLn, $ сссс, ThickWidth);

Line (0, 30, x, 30);

{Лінія 1100110011001100}

SetLineStyle (UserBitLn, $ B38F, ThickWidth);

Line (0, 40, x, 40);

{Лінія 1011001110001111}

SetLineStylef UserBitLn, $ 4С70, ThickWidth);

Line (0, 50, x, 50);

{Лінія 0100110001110000}

ReadLn;

{Пауза до натискання введення}

CloseGraph

{Закриття графіки}

END.


У цьому прикладі на екрані монітора малюється п'ять горизонтальних ліній різної товщини: дві намальовані з системного шаблоном, а три - за шаблоном, заданому нами.

Призначення стилю ліній впливає на дію всіх процедур, які виводять на екран відрізки або фігури, з них складаються. Процедури, що виводять на екран дуги, враховують тільки товщину, задану в стилі.

Коефіцієнт стиснення зображення

Якщо намалювати квадрат відрізками, наприклад

MoveTo (100, 100);

LineRel (20, 0); LineRel (0, 20);

LineRel (-20, 0); LineRel (0, -20);

то на екрані, швидше за все, виникне стислий прямокутник. Схожа картина буде спостерігатися, якщо «вручну» намалювати коло з допомогою відрізків прямих або точок: вийде еліпс. Це пов'язано з тим, що відношення висоти екрану до ширини не дорівнює відношенню його роздільної здатності по вертикалі до роздільної здатності по горизонталі. Для обліку цієї нерівності в графічному стандарті BGI вводиться спеціальний показник, званий коефіцієнтом стиснення зображення (aspect ratio). Його значення можуть мати широкий діапазон. Наприклад, для ПК IBM PC / XT / AT стандартні монітори мають відношення висоти екрану до його ширини, рівне 0,75. При цьому роздільча здатність адаптерів коливається від 640x200 для CGA до 1024x768 IBM 8514, і ставлення GetMaxY до GetMaxX може мінятися від 0,3125 (640x200) до 0,75 (640x480, 1024x768). Таким чином, на одиницю довжини осі екрану доводиться різну кількість пікселів по горизонталі й вертикалі, а оскільки всі операції проводяться з пікселями, то в результаті замість кола може вийти еліпс, горизонтальна піввісь якого дорівнює радіусу, а вертикальна - радіусу, поділене на коефіцієнт стиснення зображення .

У модулі Graph є дві процедури, які допомагають усунути незручність. Перша з них

GetAspectRatio (VAR А, В: Word)

повертає в змінних A і B значення, ставлення яких (А / В) відповідає коефіцієнту стиснення зображення. У модулі Graph немає жодного речового параметра (що підвищує швидкодію), тому всі нецілі значення представляються як відношення двох цілих.

Інша процедура,

SetAspectRatio (А, В: Word)

Дозволяє змінювати поточний коефіцієнт стиснення на коефіцієнт, що дорівнює (А / В). Перепризначення коефіцієнта стиснення впливає на роботу всіх процедур, які виводять окружності, еліпси, дуги і на значення параметрів, що повертаються при виклику процедури GetAspectRatio. Побудувати ж правильний квадрат можна, домножимо його вертикальний розмір на вихідний (системний) коефіцієнт стиснення.

{Побудова квадрата}

Program QuadroDem;

Uses Graph;

const l = 100;

Var

d, r, e: integer;

a, b: word;

Begin

d: = Detect;

InitGraph (d, r ,'');

e: = GraphResult;

if e <> grOk then

writeln (GraphErrorMsg (e))

else

begin

GetAspectRatio (a, b);

Rectangle (20,20, round (l * (b / a)), l);

readln;

CloseGraph;

end

End.

Кола, еліпси і дуги

Для зображення кіл використовується процедура

Circle (x, у: Integer; Radius: Word)

Тут (X, Y) - координати центру кола, Radius - її радіус. Результатом її роботи буде окружність, якщо коефіцієнт зображення відповідає прийнятому BGI-драйвером для поточного графічного режиму. В іншому випадку на екрані з'явиться еліпс, витягнутий по вертикалі (коефіцієнт стиснення більше прийнятого за замовчуванням) або по горизонталі (коефіцієнт менше прийнятого).

У модулі Graph представлені процедури малювання еліпсів, дуг, секторів і процедура, що дозволяє малювати сектор, залитий за заданим шаблоном. Всі вони запитують параметри StartAngle і EndAngle, які позначають початковий і кінцевий кут дуги. На малюнку зображена система графічних координат, в якій ми працюємо.



Позитивний напрямок осі X (зліва направо) прийнято за 0 °, негативне напрямок осі Y - за 90 °, тобто кути відміряються від позитивного напрямку осі X проти годинникової стрілки. Всі значення цих параметрів дають у градусах.

Нижче перераховані процедури розглянутого класу:

Малювання дуги радіусу Radius з центру з координатами (X, Y) від кута StartAngle до EndAngle:

Arc (X, Y: Integer; StartAngle, EndAngle, Radius: Word)

При зміні коефіцієнта стиснення зображення вид виведених дуг буде відрізнятися від правильних кіл.

Малювання еліптичної дуги з аналогічними параметрами:

Ellipse (X, Y: Integer; StartAngle, EndAngle, XRadius, YRadius: Word)

де XRadius і YRadius - розміри горизонтальної і вертикальної півосей відповідно. Осі еліпса можуть бути тільки паралельні осям X і Y. Для зображення повного еліпса треба задавати кути 0 ° і 360 °. Значення коефіцієнта стиснення зображення не впливає на його вигляд.

Кутові параметри дуже незручні для нашої системи координат - ми можемо визначити координати початку і кінця дуг окружності або еліпса не інакше, як тільки використовуючи відомі тригонометричні вирази. Але в подібних обчисленнях немає необхідності, оскільки ці координати все одно відомі усередині процедур Arc, Ellips, Sector і PieSlice.

Витягти кінцеві координати дуг дозволяє процедура

GetArcCoords (VAR ArcCoords: ArcCoordsType)

Тип ArcCoordsType оголошений в модулі Graph таким чином:

TYPE

ArcCoordsType = RECORD

X, Y

: Integer;

{Центр}

XStart, YStart

: Integer;

{Початок}

XEnd, YEnd

: Integer;

{Кінець}

END;

Розглянута процедура повертає результати останнього виклику процедури малювання дуги або сектора.

Побудова прямокутників і ламаних

Для побудови прямокутника досить викликати процедуру Rectangle (Х1, Y 1, Х2, Y 2: Integer), яка зобразить на екрані прямокутник з діагоналлю (X 1, Y 1) - (X 2, Y 2). Для малювання квадрата треба вибрати висоту прямокутника так, щоб вона дорівнювала твору ширини на коефіцієнт стиснення зображення.

Щоб побудувати фігури з великою кількістю вершин (в тому числі і незамкнуті), можна скористатися процедурою

DrawPoly (NumPoints: Word; VAR PolyPoints)

Вона дозволяє малювати на екрані дисплея будь-яку ламану, задану набором координат деякої безлічі точок. Це може бути як складна геометрична фігура, так і таблична математична функція. Параметр NumPoints - це кількість точок ламаної (зауважимо, що якщо необхідно намалювати замкнутий багатокутник з N вершинами, то значення NumPoints повинно бути на одиницю більше числа N, а координата (N +1)-ї точки повинна бути такою ж, як координата першої) . Під безтипових параметром PolyPoints розуміється будь-яка змінна, що складається з наборів двокомпонентних записів. Поля кожного запису повинні містити координати X-і Y черговий точки. У модулі Graph введено такий тип:

TYPE

PointType = RECORD

X, Y: Integer; {координати точки}

END;

Зазвичай набір точок організується як масив із записів типу PointType (і саме до такої структури наводиться значень параметра PolyPoint при роботі процедури DrawPoly). Приклад побудови графіка функції за допомогою процедури DrawPoly наведено далі.

USES Graph;

{Підключений модуль Graph}

{$ I initgraf. pas}

{Процедура ініціалізації}

CONST


Pi * 3.14151828;

{Константа Pi (заміщає функцію)}

Pi 2 = 2 * Pi;

{Різні похідні від Pi ...}

Pi001 = 0.01 * Pi;


VAR


angle: Real;


sine_func: Array [1.201] of PointType;

{Масив точок}

maxy, i: Integer;


BEGIN

Grlnit;

{Ініціалізація графіки}

maxy: = GetMaxY div 2;

{Середина екрану по осі Y}

angle: = 0.0;

{Завдання стартових значень}

i: = 0;

{Лічильник точок у sine _ func}

repeat

{Цикл заповнення sine_func}

Inc (i);


sine_func [i]. x: = Round (100 * angle) + 10;

sine_func [i]. y: = Round (100 * Sin (angle)) + maxy;

angle: = angle + Pi001;


until angle> Pi2;


DrawPoly (i, sine_func);

{Малювання графіка синуса}

ReadLn;

{Пауза до натискання введення}

CloseGraph

{Закриття графіки}

END.


За допомогою DrawPoly можна вивести графік частини функції. Для цього достатньо вказати при переданому масиві номер n перших елемента, що розглядається (тобто точки), а в першому параметрі - кількість розглянутих точок, починаючи з n-й, наприклад

DrawPoly (20, sine _ func [100]);

Такий виклик виведе ламану лінію по точках з номерами 100, 101 ,..., 119.

При виведенні кількості точок, порівнянного із значенням GetMaxX, і при несплошном стилі лінії може виявитися, що крок між сусідніми точками відповідає ширині пробілу між пунктиром. У підсумку лінія може взагалі не виявитися на екрані. Треба або зменшити кількість точок, або обрати суцільний тип лінії.

Управління квітами і шаблонами заливки (заповнення)

Розглянемо процедури, що керують кольоровою гамою зображення на дисплеї, що не тільки визначає ступінь чіткості і привабливості зображення, але і в кінцевому підсумку може впливати на фізіологічний стан користувача.

Завдання типу заливки

У модулі Graph передбачені процедури, за допомогою яких можна заповнити (залити) певним «візерунком» будь-яку замкнуту область зображення. Вид «візерунка» задається так званим шаблоном заливки. У Турбо Паскалі зумовлений ряд стандартних шаблонів, але крім того, є можливість конструювати власні.

Призначення шаблону заповнення (заливки) проводиться процедурою

SetFillStyle (Pattern: Word; Color: Word)

де параметр Pattern визначає вид шаблону заливки, a Color - його колір. Усі дозволені значення параметра Pattern зумовлені в модулі Graph у вигляді констант:

CONST

EmptyFill

= 0

{Суцільна заливка кольором фону}

SolidFill

= 1

{Суцільна заливка поточним кольором}

LineFill

= 2

{Заливка типу ===}

LtSlashFill

= 3

{Заливка типу / / /}

SlashFill

= 4

{Заливка жирними лініями типу / / /}

BkSlashFill

= 5

{Заливка жирними лініями типу \ \ \}

LtBkSlashFill

= 6

{Заливка типу \ \ \}

HatchFill

= 7

{Заливка рідкісної штрихуванням}

XHatchFill

= 8

{Заливка частою штрихуванням}

InterleaveFill

= 9

{Заливка переривчастою лінією}

WideDotFill

= 10

{Заливка рідкісними точками}

CloseDotFill

= 11

{Заливка частими точками}

UserFill

= 12

{Заливка, певна програмістом}

Константа UserFill використовується для визначення типу заливки, який попередньо був заданий у програмі. Для завдання свого нового шаблону необхідно скористатися процедурою

SetFillPattern (PattMatrix: FillPatternType; Color: Word)

передавши їй у параметрі PattMatrix матрицю шаблону заливки і вказавши колір параметром Color. Ця процедура по дії аналогічна SetFillStyle, але встановлює тільки «саморобні» шаблони. Процедура SetFillStyle зручніше, особливо в додатках ділової графіки (гістограми, кругові діаграми тощо). Задаючи хоча б раз новий шаблон, ми автоматично пов'язуємо його із значенням UserFill і далі можемо маніпулювати всіма тринадцятьма шаблонами. Якщо ж поставити UserFill, не визначивши перед цим новий шаблон, то функція GraphResult поверне значення -11 (grError) і всі установки виду шаблону і кольору залишаться колишніми. За замовчуванням встановлюється шаблон SolidFill і колір с. номером, максимальним для поточного графічного режиму.

В обох процедурах призначення шаблону мінлива Color визначає колір, яким виповнюється шаблон. Колір фону при цьому залишається незмінним.

{Демонстрація стандартних типів штрихування}

Program FillStDem;

Uses CRT, Graph;

Var

d, r, e, i, j, x, y: integer;

Begin

d: = Detect;

InitGraph (d, r ,'');

e: = GraphResult;

if e <> grOk then

writeln (GraphErrorMsg (e))

else

begin

SetGraphMode (0);

x: = GetMaxX div 9;

y: = GetMaxY div 7;

for j: = 0 to 2 do

for i: = 0 to 3 do

begin

Rectangle ((2 * i) * x, (2 * j +1) * y,

(2 * i +1) * x, (2 * j +2) * y);

SetFillStyle (i + j * 4, j +1);

Bar ((2 * i) * x +1, (2 * j +1) * y +1,

(2 * i +1) * x-1, (2 * j +2) * y-1);

end;

readln;

CloseGraph;

end

End.

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

Розглянемо процедури, безпосередньо реалізують заливку. Є цілий ряд процедур, які змальовують графічні фігури і відразу ж заповнюють їх за заданим шаблоном. Перша них - процедура

Bar (X 1, Y 1, X 2, Y 2: Integer)

малює прямокутник, внутрішня область якого залита за поточним шаблоном. Вона зазвичай використовується в діловій графіці для будови стовпчастих діаграм. Параметри (X 1, Y 1) і (X 2, Y 2) - координати верхнього лівого і правого нижнього кутів прямокутника. Ще більш наочне уявлення інформації при малюванні діаграм дозволяє отримати процедура

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

Вона малює паралелепіпед, лицьова сторона якого заливається за поточним шаблоном, а глибина задається в пікселах параметром D 3. Параметр Тор задає режим відображення верхній площині: True - відображати, False - не відображати. Цей параметр необхідний для того, щоб можна було малювати стовпці, що стоять один на одному. У модулі Graph визначені дві константи для неї:

CONST

TopOn = True;

{Верхня площина потрібна}

TopOff = False;

{Верхня площина не потрібна}

{Побудова паралелепіпеда}

Program Bar3Dem;

Uses CRT, Graph;

Var

d, r, e: integer;

Begin

d: = Detect;

InitGraph (d, r ,'');

e: = GraphResult;

if e <> grOk then

writeln (GraphErrorMsg (e))

else

begin

Bar3d (80,100,120,180,15, TopOn);

Bar3d (150,150,190,180,15, TopOff);

Bar3d (230, 50,250,150,15, TopOn);

Bar3d (220,150,260,180,15, TopOn);

Bar3d (300,150,340,180,15, TopOff);

Bar3d (300, 50,340,150,15, TopOn);

readln;

CloseGraph;

end

End.

Наступні «заповнюють» процедури працюють з секторами кіл і еліпсів. Малювання сектора еліпса, який буде залитий кольором за поточним шаблоном, здійснюється процедурою

Sector (X, Y: Integer; StartAngle, EndAngle, XRadius, YRadius: Word)

Параметри процедури мають той же зміст, що й у процедурах Arc, Ellipse. для завдання кругового сектору треба задавати YRadius з урахуванням коефіцієнта стиснення:

VAR

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

BEGIN

GetAspectRatio (А, В);

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

END.

Цього ж ефекту можна досягти, використовуючи процедуру

PieSlice (X, Y: Integer; StartAngle, EndAngle, Radius: Word)

яка малює сектор, кульовий площа якого заливається за поточним шаблоном заповнення.

процедура

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

малює еліпс поточним кольором і заповнює його за встановленим шаблоном. Параметри цієї процедури мають такий же зміст, як і параметри процедури Ellipse.

Заповнення більш складних геометричних фігур, у тому числі і неправильної форми, проводиться процедурою

FillPoly (NumPoints: Word; VAR PolyPoints)

Її параметри мають таке ж призначення, як і в процедурі DrawPoly. Єдина відмінність в тому, що координати першої та останньої вершини багатокутника можуть не збігатися. Проте все одно вони будуть з'єднані лінією, і нутро фігури буде залита.

USES Graph;

{Підключений модуль Graph}

{$ I initgraf.pas}

{Процедура ініціалізації}

CONST

our_ figure: Array [1 .. 4] of PointType =


(X: 319; y: 40),

{Завдання координат решт}

(X: 398; y: 146),

{Відрізків, які є сторонами}

(X: 240; в: 146),

{Геометричній}

(X: 400; у: 40));

{Фігури}

BEGIN


Grlnit;

{Ініціалізація графіки}

SetFiUStyle (InterleaveFill, Red);

{Завдання шаблону}

{Малювання заданої фігури}

FillPoly (SizeOf (our.figure) div SizeOf (PointType), our_figure);

ReadLn;


CloseGraph


END.


Функція SizeOf (our _ figure) повертає розмір константи our _ figure в байтах, a SizeOf (PointType) - розмір пам'яті, займаний одним елементом типу PointType. І, нарешті, універсальна процедура

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

Вона заливає всю область навколо точки (X, Y), обмежену лініями кольору Border. Наприклад, якщо точка (X, Y) знаходиться всередині області, обмеженої колом, то вся область буде залита за шаблоном і кольором, встановленими процедурами SetFillPattern або SetFillStyle. Якщо ж точка буде знаходитися поза цією областю, то залитим буде весь екран за винятком цієї області. Якщо область не замкнута суцільною лінією або межами екрану, то за шаблоном заповниться весь екран.

Опитування й установка квітів пера і фону

Різні адаптери підтримують різну кількість квітів, що виводяться одночасно на екран в графічному режимі. Але для всіх BGI-драйверів воно обмежене діапазоном 0 .. 15. Нумерація і назви кольорів збігаються з тими, які були наведені для текстових квітів, а імена констант, що позначають кольори (за винятком Blink), продубльовані в модулі Graph.

Максимальний номер кольору, що сприймається даними адаптером у поточному графічному режимі, може бути отриманий за допомогою функції

GetMaxColor: Word

На екрані завжди розрізняються колір фону і колір пера. Всі процедури зображення фігур, якщо не містять в собі явної установки кольору, малюють ці фігури кольором пера (як символи в текстовому режимі). Цей колір встановлюється процедурою

SetColor (Color: Word)

Колір фону - завжди єдиний у полі екрану. Він може бути змінений процедурою

SetBkColor (Color: Word)

Після використання цієї процедури колір екрану одразу ж змінюється на заданий. Параметр Color не повинен перевищувати поточне значення GetMaxColor. Кольором фону може бути будь-який з дозволених квітів, в тому числі і яскравий. За замовчуванням і при реініціалізаціі графіки колір фону дорівнює 0 (Black), а колір пера дорівнює значенню функції GetMaxColor.

Завжди можна опитати поточні установки кольору.

Функція GetColor: Word повертає значення поточного кольору пера, а функція GetBkColor: Word повертає поточний колір тла.

Управління палітрою

Палітра та її аналіз. Максимальний набір кольорів, підтримуваних одночасно BGI-драйвером, називається палітрою і може складатися з 16 кольорів, пронумерованих від 0 до 15 (так буде, наприклад, для графічних адаптерів EGA, VGA).

Ці шістнадцять квітів використовуються за замовчуванням в режимах 640x480 для VGA, 640x350, 640x200 і 320x200 для EGA як у текстовому, так і в графічному режимах.

Числа від 0 до 15, які використовуються для позначення кольорів, визначають колірні атрибути або, як їх ще називають, «програмні» кольору. Кожному програмного кольором присвоюється «апаратний» колір з так званої повної палітри. Наприклад, для адаптера EGA, виводить одночасно до 16 кольорів, програмні кольори обираються з повної палітри в 64 кольори, наявної в цьому адаптері. А в адаптері VGA апаратна палітра містить 256 кольорів. Для управління відповідністю між програмними та апаратними квітами в модулі Graph передбачено ряд процедур, що охоплюють практично всі можливі операції з палітрою.

Розглянемо процедури, за допомогою яких можна отримати системну інформацію про неї. У модулі Graph визначений тип для опису палітри:

CONST

MaxColors = 15; {максимальний програмний номер кольору}

TYPE PaletteType = RECORD

Size

: Byte;

{Розмір програмної палітри}

Colors: Array [0 .. MaxColors] of Shortlnt;

END;

Поле Size містить кількість квітів у палітрі, а поле Colors містить діючі кольору в перших Size елементах масиву. Процедури GetPalette і GetDefaultPalette повертають у фактичних параметрах значення типу PaletteType:

GetDefaultPalette (VAR Palette: PaletteType);

GetPalette (VAR Palette: PaletteType);

Вони відрізняються один від одного тим, що перша процедура повертає набір кольорів, який встановлюється при ініціалізації графічного режиму, тобто за замовчуванням, а друга процедура повертає поточний набір кольорів.

Функція GetPaletteSize: Word

повертає результат типу Word, який показує, яка кількість квітів входить в поточну програмну палітру. У принципі, ця функція повертає значення, рівне GetMaxColor +1.

Установка палітри. Для установки палітри в модулі Graph представлені три процедури різної складності. Процедура

SetPalette (ColorNum: Word; Color: Shortlnt)

управляє лише одним кольором у палітрі. ColorNum - це номер програмного кольору, Color - номер апаратного кольору, який буде під ним розумітися.

Наприклад, виклик SetPalette (0, Red) робить червоний колір першим кольором палітри. Параметр Color може перевищувати максимальний програмний номер кольору, але тільки на адаптерах EGA (0 .. 63) і VGA. При некоректному виклику процедури функція GraphResult поверне значення grError.

Бітові графічні операції

Опитування пікселів. Турбо Паскаль дозволяє організувати прямий доступ до кожного пікселя екрану з допомогою функції

GetPixel (X, Y: Integer).

Ця функція повертає значення типу Word - номер кольору пікселя з координатами (X, Y). Оскільки зазвичай номер кольору лежить в діапазоні 0 .. 15, значущим є тільки молодший байт.

Управління пікселями полягає в можливості призначити колір будь пікселу екрану. Процедура

PutPixel (X, Y: integer; Color: Word); запалює на екрані в точці з координатами X, Y пікселів кольору Color.

Управління відеосторінок

Пам'ять відеоадаптерів розділена на так звані сторінки, або відеосторінки. За умовчанням в графічному режимі дії проводяться з нульовою сторінкою, тому практично в усіх попередніх прикладах було видно, як малюються на екрані фігури. Однак якщо направити вивід зображень на ненульову сторінки (за умови, що така доступна в поточному режимі відеоадаптера, то на екрані нічого не з'явиться, оскільки за замовчуванням видимої є нульова сторінка. Якщо ж після цього дати команду вважати видимої «приховану» сторінку, то вона з'явиться на екрані буквально миттєво (конкретно: за один прямий прохід променя в кінескопа). Виконати всі це дозволяють дві процедури:

SetVisualPage (Page: Word)

яка встановлює «видимої» на екрані відеосторінок номер Page, і процедура

SetActivePage (Page: Word)

встановлює перенаправлення всіх графічних операцій на сторінку номер Page (тобто робить активною). Активність не тотожна видимості сторінки на екрані.

Розглянемо приклад використання цих процедур.

(* Приклад тільки для адаптерів EGA і VGA! *)

USES Graph, CRT;

{Використовується Graph і CRT}

{$ I initgraf. pas}

{Процедура ініціалізації}

PROCEDURE Forms (kadr: Byte);

{Малювання кадрів 0 .. 3}

CONST


Radius: Array [0 .. 3] of Integer = (20, 40, 60, 60);

VAR


r, rr: Integer;

{Радіуси еліпсів в кадрах}

BEGIN


r: = Radius [kadr];

{Максимальний радіус}

rr: = 0;

{Радіус вкладеного еліпса}

repeat


Ellipse (GetMaxX div 2, GetMaxY div 2,0,360, r, rr);

Inc (rr, 5);


until rr> = r;


END;


PROCEDURE AnimEGAVGA;

{Процедура зміни кадрів}

CONST ms = 60;

{Затримка між кадрами, мс}

VAR i: Byte;

{Параметр циклів зміни}

BEGIN


repeat

{Цикл до натиснення клавіші ...}

for i: = 0 to 3 do begin

{Зміна відеосторінок: прямо}

SetVisualPage (i);

Delay (ms);


end;


for i: = 3 downto 0 do begin

{... І назад}

SetVisualPage (i);

Delay (ms);


end;


until KeyPressed;

{Умова закінчення показу}

END;


VAR

(* ОСНОВНА ЧАСТИНА Приклад *)

i: Byte;

{Параметр (номер кадру)}

BEGIN

Grlnit;

{Ініціалізація графіки}

SetGraphMode (EGALo);

{Режим EGA, 640x200, 4 стор.}

for i: = 3 downto 0 do begin

{Цикл заповнення сторінок}

SetVisualPage (Succ (i) mod 4);

{Бачимо "пустоту"}

SetActivePage (i);

{І готуємо кадр}

Forms (i)

{Малюнок кадру}

end; {for}


AnimEGAVGA;

{Початок пожвавлення кадрів}

CloseGraph


END.


Тут показано використання процедур SetActivePage і SetVisualPage для алгоритму «кадрової» мультиплікації. Особливість її полягає в тому, що всі кадри (тут їх чотири) спочатку записуються на відповідні сторінки, а потім проводиться послідовне перемикання відображення сторінок на дисплей процедурою SetVisualPage.

Графічні вікна

У системі BGI-графіки вводиться термін «viewport». Спеціальний словник дає наступне роз'яснення: «вьюпорті - це область перегляду, вікно екрану, в комп'ютерній графіці - частина простору відображення, в якій зображується і проглядається частина модельованого об'єкта». Ми будемо використовувати термін «графічне вікно». При утворенні графічного вікна виходить як би «екран в екрані» заданого розміру. У модулі Graph для опису графічного вікна оголошений наступний тип і дві константи:

TYPE ViewPortType = RECORD

X1, Y1, X2, Y2: Integer;

{Кордону вікна}

Clip: Boolean;

{Режим відсікання)

END;

CONST

ClipOn = True;

{Відсікання по межі вікна включено}

ClipOff = False;

{Відсікання по межі вікна вимкнено}

Тут перші елементи запису - це координати прямокутної області (графічного вікна), як їх прийнято ставити, a Clip - це параметр, який вказує графічній системі, що робити з зображенням, що потрапили за межі цієї області. Clip може приймати два значення. Значення ClipOn вказує на те, що всі елементи зображення обрізаються по межах графічного вікна, a ClipOff вказує на те, що всі малюється без змін.

Оголошення графічного вікна виробляється процедурою

SetViewPort (Х1, Y 1, Х2, Y 2: Integer; ClipMode: Boolean)

вхідні параметри відповідають полям запису типу ViewPortType. Після виконання цієї процедури всі поточні установки стануть ставитися до вікна. Поточний покажчик (графічний курсор) встановиться в його лівий верхній кут, і туди ж переноситься початок системи координат дисплея. Іншими словами, ми отримали локальний систему координат пристрою. Якщо параметри процедудури задані неправильно, то функція GraphResult поверне помилку grError (-11).

Призначення графічного вікна можна використовувати для переміщення початку системи координат. Так, якщо задати вікно викликом

SetViewPort (GetMaxX div 2, GetMaxY div 2, GetMaxX, GetMaxY, ClipOff);

отримуємо систему координат з початком у центрі екрану. При цьому стане «видимої» адресація негативних координат. Графічне вікно не міняє масштабу системи координат, а лише вибирає систему відліку адресованих пікселів. Для опитування поточних параметрів графічного вікна служить процедура

GetViewSettings {VAR ViewSettings: ViewPortType)

Якщо скористатися нею відразу ж після ініціалізації графічного режиму, то виявиться, що графічним вікном є весь екран. Це говорить про те, що для системи байдуже, яке графічне пристрій відображає результат, оскільки графічне вікно є деякий універсальний інтерфейс між графічною програмною системою і графічним пристроєм виводу.

Для очищення робочого простору графічного вікна в модулі Graph існує спеціальна процедура

ClearViewPort

Вона працює в такий спосіб:

  1. встановлює колір заповнення рівний поточному кольором фону;

  2. викликає процедуру Ваг з тими ж значеннями координат; що і у процедури SetViewPort, викликаної перед цим;

  1. переміщує поточний покажчик в точку (0,0).

{Ілюстрація дейсвія режиму "відсічення"}

Program ClipOn_Off;

Uses Graph;

Var d, e, r: integer;

Const

x11 = 0; y11 = 40; x12 = 120; y12 = 85;

x21 = 200; y21 = y11; x22 = 320; y22 = y12;

Begin

d: = Detect; InitGraph (d, r ,'');

e: = GraphResult;

if e <> grOk then

writeln (GraphErrorMsg (e))

else

begin

writeln ('ClipOn: ClipOff');

Rectangle (x11, y11, x12, y12);

Rectangle (x21, y21, x22, y22);

SetViewPort (x11, y11, x12, y12, ClipOn);

Circle (20,20,60);

SetViewPort (x21, y21, x22, y22, ClipOff);

Circle (20,20,60);

readln;

CloseGraph;

end

End.

Виведення тексту

Виведення тексту в графічному режимі має ряд відмінностей від подібних дій у текстовому режимі. Основна відмінність полягає в тому, що всі дії проводяться тільки із строковими константами та змінними. Вся числова інформація повинна попередньо перетворюватися в строкову процедурою Str. Інша відмінність - у тому, що можна використовувати різні шрифти.

Вибір шрифту і стилю

У комплектах постачання пакету Турбо Паскаль є файли з розширенням. CHR. Це набір штрихових шрифтів, які можуть бути використані для виводу інформації. Оскільки вони побудовані не матричним способом (як зроблені стандартні шрифти для текстового режиму), а векторним, стають можливими маніпуляції розмірами шрифтів без втрати якості їх зображення.

Всього з пакетом Турбо Паскаль поставляється чотири шрифту (хоча можна, використовуючи окремий спеціальний пакет, самостійно розширити їх набір). Крім того, доступний системний матричний шрифт 8x8 для графічних режимів (завжди доступні символи з ASCII-кодами від 0 до 127 і символи з кодами від 128 до 255 за умови, що їх матриці завантажені в пам'ять ПЕОМ). Для позначення цих п'яти шрифтів введені константи:

CONST

DefaultFont

= 0;

{Матричний шрифт 8x8 (за замовчуванням)}

TriplexFont

= 1;

{Напівжирний шрифт}

SmallFont

= 2;

{Світлий шрифт (тонке накреслення)}

SansSerifFont

= 3;

{Книжкова гарнітура (рубаний шрифт)}

GothicFont

= 4;

{Готичний шрифт}

DefaultFont - це матричний шрифт 8x8. Якщо не приймати ніяких дій зі зміни шрифту, то буде прийнятий саме він.

Активізація будь-якого з названих шрифтів здійснюється процедурою

SetTextStyle (Font, Direction: Word; CharSize: Word)

Тут параметр Font - номер шрифту (наприклад, одна з описаних вище констант), Direction - розташування тексту (за замовчуванням приймається горизонтальне). Можливі лише дві орієнтації тексту, позначені константами:

CONST

HorizDir

= 0;

{Горизонтальна, зліва направо}

VertDir

= 1;

{Вертикальна, знизу вгору}

При значенні Direction, рівному VertDir, всі символи будуть повернені проти годинникової стрілки на 90 ° і виводяться знизу вгору. Якщо задати Direction = 2, то букви будуть повернені так само, як і при Direction = VertDir, але висновок рядка буде проводитися горизонтально, зліва направо.

Розмір кожного символу встановлюється параметром CharSize, діапазон зміни якого складає від 1 до 10. Стандартне значення CharSize для матричного шрифту 8x8 дорівнює одиниці, а для штрихових шрифтів - чотирьом.

При кожному виклику процедурою SetTextStyle будь-якого шрифту він читається з диска і завантажується в пам'ять.

Щоб визначити результат читання файлу шрифту з диска і завантаження його до пам'яті, можна перевірити значення функції CraphResult. Перелік значень, що повертаються нею у цьому випадку, наведений у таблиці.

GraphResult

Сенс значення

0

Успішне виконання операції

-8

Файл CHR не знайдено

-9

Не вистачає пам'яті для завантаження вибранногошріфта

-11

Помилка графіки

-12

Помилка вводу-виводу графіки

-13

Неправильне вміст файлу шрифту

-14

Неправильний номер шрифту

{Демонстрація шрифтів}

Program SetStDem;

Uses Graph;

const

text: array [1 .. 4] of string [14] =

('TripLexFont', 'SmallFont', 'SansSerifFont', 'GothicFont');

s4 = ​​', size 4';

s5 = 'and 5';

Var

d, r, e, i: integer;

Begin

d: = Detect;

InitGraph (d, r ,'');

e: = GraphResult;

if e <> grOk then

writeln (GraphErrorMsg (e))

else

begin

SetTextStyle (DefaultFont, HorizDir, 1);

OutText ('DefaultFont, size 1');

SetTextStyle (0,0,2);

OutText ('and 2');

for i: = 1 to 4 do begin

SetTextStyle (i, 0,4);

Moveto (10, i * 40);

OutText (text [i] + s4);

SetTextStyle (i, 0,5);

Outtext (s5);

end;

for i: = 1 to 4 do begin

SetTextStyle (i, 1,4);

Moveto (GetMaxX div 2 + i * 40-20,0);

OutText (text [i]);

end;

readln;

CloseGraph;

end

End.

Безпосередній висновок рядків

Для виведення тексту є дві процедури. Перша - OutText (TextString: String) виводить на графічний екран рядок TextString, орієнтовану щодо позиції поточного покажчика, а друга OutTextXY (X, Y: Integer; TextString: String} виводить рядок, орієнтовану щодо координат (X, Y). Шрифт попередньо може бути встановлений викликом SetTextStyle (за умовчанням приймається DefaultFont). Розглянемо орієнтування рядка щодо стартової точки. Існує кілька варіантів орієнтування. Вони задаються процедурою SetTextJustify (Horizontal, Vertical: Word), параметри якої можуть приймати одне з трьох оголошених в модулі Graph значень:

CONST

{- Для горизонтального орієнтування (Horizontal) -}

LeftText

= 0;

{Координата X задає лівий край рядка}

Center - Text

= 1;

{Координата X задає середину рядка}

RightText

= 2;

{Координата X задає правий край рядка}

{- Для вертикального орієнтування (Vertical): -}

BottomText

= 0;

{Координата Y задає нижній край рядка}

CenterText

= 1;

{Координата Y задає середину рядка}

TopText

= 2;

{Координата Y задає верхній край}

Ця процедура дозволяє орієнтувати виведену рядок щодо стартовою координати за встановленою схемою. За умовчанням параметри орієнтування відповідають LeftText, TopText.

Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Реферат
233.5кб. | скачати


Схожі роботи:
Основні відомості про алгоритмічну мову Turbo Pascal Графіка Pascal
Turbo Pascal
Оператори Turbo Pascal 7
Модульне програмування Turbo Pascal
Файли в мові Turbo Pascal
Записи у мові Turbo Pascal
Процедури та функції в Turbo Pascal
Типи даних в Turbo Pascal
Мова програмування Turbo Pascal
© Усі права захищені
написати до нас