Pentru a executa un program ce contine apeluri la subrutine grafice, primul
pas consta in trecerea din mod text in mod grafic (operatie care
se numeste si initializarea (pornirea) modului grafic). e8n10nb
Initializarea modului grafic se poate face prin apelul procedurii InitGraph.
Prin aceasta procedura se pot identifica posibilitatile hardware disponibile
pe calculator (i.e. adaptorul disponibil), dupa care se va rezerva memorie pentru
a incarca driverul grafic potrivit, se vor initializa variabilele interne
ce definesc conditiile de afisare in respectivul mod grafic, se va comuta
echipamentul in acel mod grafic, se va sterge ecranul, apoi se va reveni
in programul apelant, fixandu-se valori corespunzatoare pentru driverul
grafic si modul grafic.
Daca procedura este utilizata in modul descris mai sus, biblioteca Graph
asigura detectarea celui mai bun mod grafic disponibil, adica cel cu cea mai
mare rezolutie si cea mai mare paleta de culori.
Procedura nu poate executa o detectare corecta pentru toate standardele grafice
existente. Astfel, modurile IBM 8514 si VESA nu pot fi detectate prin metoda
mentionata, fiind necesare masuri in consecinta (fixarea "manuala"
a modului grafic).Sintaxa procedurii de initializare a modului grafic este:
PROCEDURE InitGraph(var driver_grafic,mod_grafic: integer; cale:STRING)
Parametrii driver_grafic si mod_grafic sunt necesari pentru initializarea driverului
si a modului graphic.
Parametrul cale reprezinta un sir de caractere ce indica locul (directorul)
unde se afla fisierele cu extensia .BGI si .CHR.
Sirul nul (‘’) indica discul si directorul curent.Initializarea
modului grafic se poate face prin trei moduri diferite.
Primul si cel mai folosit mod de initializare este initializare prin autodetectare,
adica prin folosirea constantei Detect, definita de biblioteca GRAPH. Functionarea
acestui mod de pornire a modului grafic a fost evidentiata mai sus.
Cel de-al doilea mod de initializare este initializarea automata prin folosirea
apelului procedurii DetectGraph.
Cel de-al treilea mod de initializare al modului grafic este initializarea manuala
prin apelarea procedurii InitGraph cu parametrii corespunzator alesi. Initializarea
manuala se face prin indicarea driverului si modului grafic corespunzator. Aceasta
este o modalitate prin care se poate initializa driverul IBM8514.
Rutine ajutatoare pentru initializarea grafica
Procedura de initializare automata DetectGraph are urmatoarea sintaxa:
DetectGraph(Var driver_grafic,mod_grafic:integer)
Parametrii driver_grafic si mod_grafic au semnificatie identica cu cei folositi
la InitGraph .
Trecerea din modulul grafic in modul text se face prin CloseGraph, care
descarca driverul grafic din memorie, elibereaza spatiul alocat si restaureza
precedentul mod text.
PROCEDURE CloseGraph;
Tot pentru trecerea din modul grafic in modul text si invers se folosesc
procedurile complementare RestoreCrtMode si SetGraphMode.
PROCEDURE RestoreCrtMode;
PROCEDURE SetGraphMode(mod_grafic:integer);
RestoreCrtMode face trecerea in modul text fara eliberarea din memorie
a driverului grafic, astfel la o trecere ulterioara din modul text in
modul grafic secventa de potrivire a placii grafice cu tipul de monitor poate
fi ocolita prin folosirea procedurii SetGraphMode.
Prin folosirea RestoreCrtMode se va trece in modul text anterior, se sterge
ecranul, cursorul modului text anterior fiind pus in pozitia "home"
(linia 0, coloana 0, i.e. coltul stanga-sus). Astfel de manevre sunt necesare
programelor care combina frecvent modul grafic cu cel text si mai ales cand
aceste treceri nu trebuie sa ocupe un timp prea mare.
...ADetectie erori de initializareS
...A1S gE:= GraphResult;
...A2S IF gE <> grOk THEN
...A3S BEGIN
...Ainitializarea nu a fost corectaS
......A4S WRITELN('eroare grafica:', GraphErrorMsg(gE));
......A5S halt(1)
...A6S END;
...A7S xm:=getmaxx;A rezolutie pe xS
...A8S ym:=getmaxy;A rezolutia pe yS
...A9S cm:=getmaxcolor;A numar de culori (paleta)S
...Adesenare dreptunghi cu dimensiunile ecranuluiS
...rectangle(0,0,xm,ym);
...AAfisare mesajS
...outtextxy(20,ym DIV 2,'Bun venit in lumea graficii');
...ReadLn;
...CloseGraph
END.
Exemplul prezentat este un program didactic care deseneaza un dreptunghi de
dimensiune maxima a ecranului si afiseaza mesajul: "Bun venit in lumea
graficii".
Pentru a putea dispune de functiile grafice, programul trebuie sa apeleze biblioteca
GRAPH printr-o instructiune USES, imediat dupa antetul de program. In
partea de declaratii se observa variabilele (de tip intreg) gD pentru
driverul grafic, gM pentru modul grafic si gE pentru codul eventualelor erori
survenite. Secventa de initializare prin autodetectie se bazeaza pe valoarea
Detect, oferita ca parametru procedurii InitGraph.
Liniile 1-6 prezinta o secventa tipica de detectie si tratare a eventualelor
erori de initializare grafica. Liniile 7-9 prezinta modul de preluare (in
variabile globale) a caracteristicilor modului grafic curent, adica rezolutia
(orizontala si verticala) si numarul maxim de culori (paleta). Urmeaza apoi
trasarea dreptunghiului de incadrare maxima pe ecran, prin apelul la procedure
Rectangle si afisarea mesajului dorit in modul grafic prin OutTextXY.
Dupa ce toate operatiunile dorite in modul grafic s-au executat, modul
grafic este oprit prin rutina CloseGraph, revenindu-se in modul text existent
anterior (i.e. inainte de deschiderea modului grafic). Rezultatele executiei
programului X1 sunt prezentate in figura 1
Fig. 1) Ecran rezultat in urma executiei normale (fara erori) a programului
X1
(a fost decupata zona complet neagra!)
Trecerea din mod text in mod grafic si invers
Programul G4 este un exemplu de folosire al procedurilor RestoreCrtMode si SetGraphMode
ce fac trecerea din modul grafic in modul text si invers. Se reaminteste
faptul ca trecerea (repetata) in mod grafic prin aceasta metoda nu mai
face apel la InitGraph, si deci consuma un timp mult mai mic.PROGRAM G4;
...AExemplu pentru RestoreCrtModeS
USES Graph;
VAR gD,gM,gE: Integer;
...xm,ym,cm:word;
BEGIN
...gD:= Detect;
...InitGraph(gD,gM,'');
...ADetectia erorilor de initializareS
...gE:= GraphResult;
...IF gE<> grOk THEN
...BEGIN
......WriteLn('eroare grafica:', GraphErrorMsg(gE));
......halt(1)
...END;
...xm:=getmaxx; A rezolutie dupa x S
...ym:=getmaxy; A rezolutia dupa y S
...cm:=getmaxcolor;A numar de culori (paleta) S
...outtextxy(20,20,'Modul Grafic.Apasati <Enter>');
...readln;
...RestoreCrtMode;
...writeln('Modul Text.Apasati <Enter>');
...readln;
...SetGraphMode(gm);
...outtext('Inapoi in modul grafic.Pentru terminare','apasati <Enter>');
...readln;
...closegraph
END AG4S.
Ca si in exemplele anterioare, se trece in modul grafic prin folosirea
initializarii cu autodetectie. Dupa tratarea eventualelor erori de initializare
a modului grafic, se determina rezolutia ecranului si numarul maxim de culori.
Se va afisa mesajul (s-a decupat zona complet neagra):
Fig 2.
dupa care programul comuta in modul text, prin apelul procedurii RestoreCrtMode;
in modul text se va afisa mesajul:
Modul text. Apasati <Enter> Programul comuta inapoi in modul
grafic, prin apelul procedurii SetGraphMode, si afiseaza mesajul:
Fig 3.
In final, se trece in modul text, oprind modul grafic, prin apelul
lui CloseGraph.
Forme geometrice. Dreptunghiuri
Avand controlul asupra oricarui pixel de pe ecran si posibilitatea de
a trasa linii, desenarea de forme geometrice devine o problema relativ simpla.
Totusi, biblioteca GRAPH furnizeaza rutine specializate in desenarea diverselor
forme geometrice (elementare sau ceva mai complexe).
Pentru desenarea de dreptunghiuri avem la dispozitie procedura Rectangle. Dreptungiul
are coltul stanga sus la coordonatele (x1,y1), iar coltul dreapta jos
la coordonatele (x2,y2). Sintaxa procedurii este:
PROCEDURE Rectangle(x1,y1,x2,y2:integer );
Un apel Rectangle(0,0,100,100) nu va trasa (intotdeauna !) un patrat cu
latura de 100 de pixeli, deoarece dimensiunile unui pixel pe directia orizontala
si verticala sunt in general diferite. Pentru trasarea unui patrat coordonatele
se vor calcula luand in considerare factorul de forma (aspect ratio).Procedura
Bar coloreaza ("umple") o zona dreptunghiulara de ecran determinata
de coltul stanga sus prin coordonatele (x1,y1) si de coltul dreapta jos
prin coordonate (x2,y2). "Umplerea" se va face cu un anumit model,
utilizand o culoare stabilita (despre modelul de umplere si culoarea asociata
lui vom vorbi mai tarziu; culoarea de umplere este diferita de cea de
desenare linii !)
PROCEDURE Bar(x1,y1,x2,y2:integer) ;
PROCEDURE Bar3D(x1,y1,x2,y2:integer; grosime:word;top:boolean);
Procedura Bar3D creeaza un (pseudo)efect tridimensional, prin trasarea in
perspectiva a unui paralelipiped. Parametrii x1,y1 reprezinta coordonatele coltului
din stanga sus, iar x2,y2 coordonatele coltului din dreapta jos. Parametrul
grosime este o valoare ce controleaza iluzia de adancime (tridimensionala),
prin trasarea unor linii suplimentare in partea superioara si lateral-dreapta
a figurii. Parametrul de tip boolean este cel care inhiba (valoarea false sau
constanta predefinita TopOn) sau activeaza (valoarea true sau constanta predefinita
TopOff) trasarea conturului suplimentar amintit anterior (cel din partea superioara).
Colorarea (umplerea) figurii se face cu un model si o culoare fixate prin intermediul
procedurilor SetFillStyle (si, in cazuri speciale, SetFillPattern).
Exemplu: Programul X2 ilustreaza folosirea procedurii Bar3D, experimentand
parametrul top cu cele doua valori permise .
PROGRAM X2;
AExemplu pentru Bar3DS
USES Graph;
VAR gD, gM, gE: Integer;
BEGIN
...gD:= Detect;
...InitGraph(gD,gM,'');
...gE:= GraphResult;
...IF gE<>grok THEN
...BEGIN
......WriteLn('EROARE GRAFICA : ', GraphErrorMsg(gE));halt(1)
...END;
...setfillstyle(1,15);
...outtextxy(20,2,'Topoff');
...bar3d(20,20,65,60,10,topoff);
...outtextxy(140,2,'Topon');
...bar3d(140,20,185,60,10,topon);
...bar3d(30,80,105,120,10,topon);
...setfillstyle(2,15);
...bar3d(105,100,175,120,10,topon);
...readln;
...CloseGraph
END AX14S.
Fig.4. Ecran rezultat in urma executiei programului X2
Cercuri si arce de cerc
Rutina din biblioteca GRAPH dedicata desenarii arcelor de cerc este ARC, cu:
PROCEDURE Arc(x,y:integer;unghi_inceput,unghi_sfarsit,raza:word);
Parametrii procedurii Arc au semni ficatia (vezi si figura 11.16):
· parametrii x,y reprezinta coordonatele centrului cercului caruia ii
apartine arcul respectiv, cerc a carui raza este data de valoarea parametrului
raza;
· parametrii unghi_inceput si unghi_sfarsit reprezinta unghiu-rile
(masurate in grade) de la care se incepe si la care se sfarseste
trasarea arcului de cerc; unghiurile sunt masurate in sens trigonometric
(sensul invers sensului de rotatie al acelor ceasornicului).
Fig. 5. Parametrii procedurii ARC
Folosind formulele cunoscute din geometria analitica, se pot trasa arce de
cerc si cercuri avand la dispozitie numai rutinele de trasare linii sau
pe cele de afisare a unui pixel pe ecran.Pentru a desena un cerc putem folosi
enuntul :
ARC(x,y,0,360,raza); dar, biblioteca GRAPH pune la dispozitia utilizatorilor o subrutina specializata
in desenarea cercurilor, care este mai usor de utilizat. Procedura Circle
deseneaza un cerc avand centrul dat de valoarea parametrilor x,y (coordonate)
si raza data de valoarea parametrului raza:
PROCEDURE Circle(x,y:integer;raza:word);
Atat pentru procedura Arc, cat si pentru Circle se ia in considerare
(intern) factorul de forma astfel incat - indiferent de placa grafica
- figurile nu apar deformate.
Culoarea de afisare se controleza prin procedura SetColor, avand parametru
valoarea culorii dorite, procedura apelata inainte de apelul la procedurile
de trasare dorite.
Salvarea si pastrarea caracteristicilor arcului recent desenat in vederea
prelucrarilor ulterioare se realizeaza prin GetArcCoords, ce actualizeaza un
parametru de tip ArcCoordsType:
PROCEDURE GetArcCoords(Var c:ArcCoordsType);
...ArcCoordsType = RECORD
...x, y : integer;
...xstart, ystart : integer;
...xend, yend : integer
END;
ArcCoordsType este un tip inregistrare (RECORD), ale carui campuri
au urmatoarele semnificatii: x,y - centrul cercului caruia ii apartine
arcul; xstart, ystart - coordonata pixelului de inceput al arcului; xend,
yend coordonata pixelului de sfarsit al arcului.
Exemplu: Programul X3 este un program care explica modul de folosire al procedurilor
Circle, Arc, GetArcCoords. Programul, dupa initializarea grafica, traseaza un
arc de cerc caruia i se salveaza caracteristicile intr-o variabila de
tip ArcCoordsType. Se traseaza apoi un cerc si se fac alte desene, dupa care
i se traseaza (arcul initial desenat) razele corespunzatoare inceputului
si sfarsitului arcului.
PROGRAM X3;
AExemplu pentru Arc, GetArcCoordsS
USES Graph;
VAR
...gD, gM, gE: Integer;
...a:arccoordstype;
BEGIN
...gD:= Detect;
...InitGraph(gD,gM,'');
...gE:= GraphResult;
...IF gE<>grOk THEN
...BEGIN
......WriteLn('EROARE GRAFICA : ', GraphErrorMsg(gE));
......halt(1)
...END;
...setcolor(yellow);
...arc(20,90,10,90,60);
...getarccoords(A);
...setcolor(cyan);
...circle(180,100,60);
...setcolor(red);
...ellipse(180,100,0,360,100,60);
...setcolor(magenta);
...WITH a DO
...BEGIN
......line(xstart,ystart,x,y);
......line(xend,yend,x,y)
...END;
...readln; CloseGraph END AX3S.
Fig.6. AProgram X3S
Notiunea de cursor grafic
O notiune specifica modului grafic este cursorul grafic sau "curent pointer",
notat CP. El este similar cu conceptul de cursor din modul text, dar, spre deosebire
de acesta, cursorul este invizibil in mod grafic. Pozitia acestui cursor
este importanta la trasarea liniilor, scrierea de text etc.
Pentru a determina pozitia curenta a cursorului grafic se folosesc functiile
GetX pentru coordonata orizontala si GetY pentru coordonata verticala.
Function GetX: integer;
Function GetY: integer;
Prin conventie, coltul stanga sus al ecranului are coordonatele (0,0)
si este pixelul in care este pozitionat cursorul imediat dupa initializarea
grafica. Valorile coordonatelor cresc spre dreapta si in jos (astfel,
pixelul din dreapta-jos are coordonatele cele mai mari pentru rezolutia de lucru
curenta).
Schimbarea pozitiei cursorului grafic poate surveni in urma executarii
unor rutine grafice. Vom specifica acest aspect in momentul prezentarii
respectivelor functii si proceduri.
Exista doua proceduri specializate pentru modificarea pozitiei cursorului, asemanatoare
lui GotoXY din biblioteca Crt. Procedura MoveTo schimba pozitia cursorului grafic,
noua pozitie fiind de coordonate x,y. Nu se traseaza linii si nici nu se efectueaza
vreo alta modificare pe ecran.
PROCEDURE MoveTo(x,y:integer);
Procedura MoveRel modifica pozitia cursorului grafic relativ la pozitia anterioara
a acestuia. Astfel, presupunand ca pozitia cursorului este x, y, in
urma executiei MoveRel (dx ,dy), pozitia cursorului va fi la coordonatele (x+dx,
y+dy).
PROCEDURE MoveRel(dx,dy:integer);
Exemplu: manevrarea cursorului grafic. Programul X4 exemplifica folosirea rutinelor
GetX, GetY, MoveTo, MoveRel.PROGRAM X4;
USES Graph;
VAR gd,gm,ge:integer;i:byte;
...x,xm,y:word;
BEGIN
...gD:= Detect;
...InitGraph(gD,gM,'');
...gE:= GraphResult;
...IF gE<>grOk THEN
...BEGIN
......WriteLn('EROARE GRAFICA :', GraphErrorMsg(gE));
......halt(1)
...END;
...xm:=getmaxx;
...rectangle(0,0,getmaxx,getmaxy);
...moveto(20,getmaxy-20);
...REPEAT
......x:=getx; y:=gety;
......rectangle(x,y,x+10,y-10);
......moverel(10,-10)
...UNTIL (x>xm-10) OR (y<20);
...readln;
...closegraph
END AX4S.
Programul traseaza pe ecran o scara, prin alaturarea unor dreptunghiuri. La
inceput, programul executa initializarea modului grafic prin autodetectie,
tratand apoi o eventuala eroare. Se fixeaza pozitia curenta a cursorului
(aproximativ) in coltul stanga jos al ecranului, prin apelul rutinei
MoveTo. Dupa aflarea pozitiei cursorului grafic, programul va desena un dreptunghi
incepand cu pozitia curenta. Pentru pregatirea urmatoarei iteratii,
se deplaseaza cursorul, relativ la pozitia curenta, prin MoveRel.
Figura rezultata in urma executiei programului X4 este prezentata mai
jos:
Fig. 7. Ecranul rezultat in urma executiei programului X4
Stilul de desenare al liniilor
In contextul bibliotecii GRAPH, linia trasata (prin oricare din cele trei
proceduri expuse mai sus) detine trei caracteristici referitoare la aspectul
grafic. Acestea sunt culoarea liniei, modelul liniei sau tipul (stilul) liniei
si grosimea liniei. Culoarea liniei se poate modifica prin procedura SetColor.
Modelul si grosimea liniei se pot schimba prin intermediul procedurii SetLineStyle
in care parametrul stil_linie trebuie sa fie o constanta din cele predefinite
de bibioteca GRAPH.
PROCEDURE SetLineStyle(stil_linie, model, grosime:word);
Parametrul model reprezinta modelul liniei (exprimat ca o succesiune de biti),
model dupa care se va trasa linia. Parametrul va fi ignorat pentru valori ale
parametrului stil_linie mai mici ca 4, deoarece pentru aceste stiluri exista
un model predefinit de biblioteca GRAPH.
Parametrul model este luat in considerare doar daca parametrul stil_linie
are valoarea 4.
Tabel A) Constante folosite cu SetLineStyle
ConstantaValoareObservatiiSolidLn 0linie continuaDottedLn 1linie punctataCenterLn
2linie punctDashedLn 3linie intreruptaUserBitLn 4stil utilizatorNormWidth 1grosime
normalaThickWidth 3grosime triplaPentru a proiecta un model pe biti in
vederea utilizarii unui nou model (personal), vom folosi o variabila de tip
word, in care se atribuie biti egali cu 1 pentru pixeli aprinsi, iar pentru
pixeli stinsi se vor atribui biti 0.
Fig.8. Proiectarea unui model pe biti $b6db
Parametrul grosime reprezinta grosimea liniei si poate avea doar valorile 1
(NormWidth) sau 3 (ThickWidth). Parametrul impune grosimea in pixeli a
liniei. Chiar daca se atribuie acestui parametru o alta valoare decat
cele doua permise (de exemplu 2), grosimea liniei va ramane tot cea anterioara
apelului procedurii SetLineStyle. La initializarea modului grafic stilul liniei
este linie continua (Solidln = 0), iar grosimea este NormWidth.
Pentru a determina caracteristicile liniei se va folosi procedura GetLineSettings,
care actualizeaza un parametru de tip LineSettings - o inregistrare in
care cele trei campuri componente corespund celor trei parametri din apelul
SetLineStyle:
PROCEDURE GetLineSettings(Var l:LineSettings);
...LineSettings = RECORD
...linestyle : word;
...pattern : word;
...thickness : word
END;
Exemplu: Programul X5 exemplifica folosirea procedurii SetLineStyle pentru a
afisa toate stilurile de linie, cu cele doua grosimi permise PROGRAM X5;
AExemplu pentru Line,SetLineStyleS
USES Graph;
VAR
...gD,gM,gE: Integer;
...xm,ym,cm:word;
...stil,model,x:word;
...s:STRINGa3i;
BEGIN
...gD:= Detect;
...InitGraph(gD,gM,'');
...A Detectare erori de initializare S
...gE:= GraphResult;
...IF gE<> grOk THEN
...BEGIN
......WriteLn('eroare grafica : ', GraphErrorMsg(gE));
......halt(1)
...END;
...xm:=getmaxx; A rezolutie dupa x S
...ym:=getmaxy; A rezolutia dupa y S
...cm:=getmaxcolor; A numar de culori S
...model:=$b6bd;
...A Afisarea stilurilor de lini cu grosimea 1 S
...outtextxy(50,20,'grosime = 1');
...outtextxy(1,30,'stil:');
...FOR stil:=0 TO 4 dO
...BEGIN
......setlinestyle(stil,model,1);
......x:=20*stil+50;
......str(stil:1,s);
......outtextxy(x,30,s);
......line(x,50,x,100)
...END;
...AAfisarea stilurilor de linie cu grosimea 3S
...x:=x+40;
...outtextxy(190,20,'grosime = 3');
...FOR stil:=0 TO 4 DO
...BEGIN
......setlinestyle(stil,model,3);
......x:=x+20;
......str(stil:1,s);
......outtextxy(x,30,s);
......line(x,50,x,100)
...END;
...readln;
...closegraph
END AX5S.
Fig. 9 Ecran rezultat in urma executiei programului X5