14. Graph unit használata 14.1. Grafikus mód Turbo Pascalban írt programok az IBM PC képernyőjét kétfajta módban használhatják - szöveges módban, vagy - grafikus módban, azonban ezt a kétfajta módot csak felváltva lehet működtetni. A szöveges móddal már megismerkedtünk, most nézzük meg részletesebben a grafikus mód használatát is. 14.2. Graph unit A Graph unit tartalmazza a grafikus eljárásokat és függvényeket, amely nagymértékben segítik a felhasználók grafikus programjainak elkészítését. Az eljárások között van pont, vonal, kör, körív, ellipszis, ellipszisív, téglalap, poligon és téglatest rajzoló, de vannak olyan rutinok, melynek segítségével különböző színnel és mintával befesthetők az alakzatok. A rajzolásra felhasznált vonal vastagsága, színe és mintája is változtatható. Többfajta karakterkészlet áll rendelkezésre: a kirajzolandó szöveg mérete változtatható és a helyzete is beállítható. A grafikus képernyőnek is van kurzora (current pointer = CP, aktuális mutató vagy pointer, amely egy képpontra mutat ) hasonló a szöveges mód kurzorához, amely villog a képernyőn, ez azonban nem látszik. A grafikus kurzort is tudjuk mozgatni a képernyőn, ívek rajzolásánál lekérdezhetjük a koordinátáit. Csak akkor tudunk igazán tervezni rajzot, ha ismerjük ennek a grafikus kurzornak a helyét a képernyőn. Definiálhatunk ablakokat a képernyőn. Az ablak paramétereit beállíthatjuk úgy, hogy az ablakból kieső rajzok ne jelenjenek meg, ilyenkor vágás történik. A vágás nem vonatkozik az aktuális grafikus kurzorra. Az IBM PC többfajta grafikus hardverrel rendelkezhet, a Turbo Pascal grafikus programcsomagja támogatja ezeket a változatokat. 14.3. Grafikus vezérlők típusa Elöszőr tekintsük át a leggyakrabban használt grafikus vezérlő fajtákat, és csoportosítsuk ezeket a színkezelésük és felbontóképességük szerint. Színkezelésük szerint megkülönböztetünk: - monochrom (egyszínű, pl. papírfehér, zöld vagy narancssárga), - színes monitorokat. A felbontóképesség azt jelenti, hogy hány pontot tud kirajzolni vízszintes (oszlop) és függőleges (sor) irányban. Ez a két szám együtt adja a felbontást. A következő táblázat bemutatja a Turbo Pascal által támogatott vezérlők felbontását és a maximálisan használható színeinek számát. Vezérlő típusa Felbontás Színek száma Hercules 720x348 2 CGA (Color Graphics Adapter) 640x200 2 320x200 4 EGA (Enhanced Graphics Adapter) 640x350 16 VGA (Video Graphics Adapter) 640x480 16 IBM8514 640x480 256 PC3270 720x350 2 A monochrom grafikus képernyő a legtöbb feladat igényeit kielégíti, mivel a szoftverek nagy része monochrom monitor esetén is működik. A felbontása elég jó, a szemet kevésbé veszi igénybe és az ára is kedvező. Ez a képernyő a színeket nem tudja kezelni, mivel összesen két színe van, ebből az egyik a háttér szín. Fekete/fehér (black&white) esetén az egyik szín a fekete a háttér és a rajzolás színe a fehér vagy fordítva. A karakterek intenzitását tudjuk változtatni, amivel a megkülönböztetéseket programozhatjuk. A CGA képernyőnek kicsi a felbontása, hosszabb ideig kellemetlen rajta dolgozni. Újabban már nem is kapható. A CGA 320x200 felbontásban a 16 szín közül egyszerre csak meghatározott 4 színt lehet grafikus üzemmódban használni. Az EGA monitor 640x350 felbontásban 64 színnel rendelkezik, ebből 16 színt tud egyidejűleg megjeleníteni. A VGA monitor 640x480-as felbontásban 256 színnel rendelkezik, azonban közvetlenül csak 16 színt tudunk programozni. A Turbo Pascal grafikus rendszere két részből tevődik össze. A felhasználói felületet, amely hardver független, a GRAPH.TPU modul definíciói biztosítják. A grafikus vezérlő típusától függő részt a .BGI (Borland Graphics Interface) file-ok biztosítják. A Pascal grafikus programokhoz különféle file-ok szükségesek. Egyik legfon-tosabb file, amely az adott grafikus kártyához tartozó meghajtó szoftver, kiterjesztése .BGI. A Pascal a következő grafikus hardvereket támogatja: Grafikus hardver Grafikus meghajtó program CGA, MCGA CGA .BGI EGA, VGA EGAVGA .BGI Hercules egyszínű HERC .BGI IBM 3270 PC3270 .BGI IBM 8514 IBM8514 .BGI AT&T 6300 ATT .BGI A grafikus program fordításához a forrásprogram mellett szükséges, hogy a fordító program elérje a - standard unit-okat, a TURBO.TPL file-t, - a grafikus eljárásokat tartalmazó GRAPH.TPU file-t, - a grafikus meghajtó szoftvert, a grafikus kártyának megfelelő .BGI file-t, - karakterkészlet használata esetén .CHR kiterjesztésű file- okat. A .BGI és a .CHR file-oknak a grafikus programot tartalmazó alkönyvtárban kell lenniük, különben a program a futás közben hibajelzést ad. A FERDEHAJ.PAS példaprogram bemutatja ezeknek a file- oknak a programba való beszerkesztését. A rajzok készítéséhez meg kell ismerkednünk a képernyő koordinátarend- szerével. Bármely grafikus módot választjuk ki, a (0,0) koordinátapont a képernyő bal felső sarkában van. Az x koordinátaértékek (oszlopok) jobbra, az y koordinátaértékek (sorok) lefelé növekednek. A sorokban és az oszlopokban a pontok száma függ a grafikus kártyától (felbontásától), ezek értéke a programból lekérdezhető a GetMaxX és a GetMaxY függvényekkel. Nézzük meg az EGA koordinátarendszerét 640x350 pontos felbontás esetén. {EMBED MSDraw \* mergeformat|} 14.1. ábra Az EGA monitor EGAHi felbontása Egy (x,y) képernyőpont (pixel) helye a képernyőn az x-edik oszlopot és az y-adik sort jelenti. A grafikus eljárásokban a szögeket fokokban kell megadni. A szögek az óramutató járásával ellenkező irányban növekednek. A 0 fok 3 órának, 90 fok 12 órának és a 180 fok 9 órának felel meg. 14.4. A grafikus könyvtár eljárásainak és függvényeinek csoportosítása A grafikus eljárásokat és függvényeket az alábbi hét csoportba sorolhatjuk: - grafikus rendszert vezérlő, - rajzolás és festés, - képernyő és képernyő ablak kezelés, - szöveg kiírása képernyőre, - szín beállítása, - hibakezelés, - állapot lekérdezés. GRAFIKUS RENDSZERT VEZÉRLŐ CloseGraph lezárja a grafikus rendszert, DetectGraph ellenőrzi a harvert, eldönti, hogy milyen grafikus rendszert használjunk, ajánl egy grafikus módot, GraphDefaults az alapértelmezés szerint beállítja a grafikus változókat, GetGraphMode visszatér az aktuális grafikus móddal, GetModeRange visszatér a specifikált meghajtónak a legalacsonyabb és legmagasabb módjával, InitGraph inicializálja a grafikus rendszert, a hardvert grafikus módba helyezi, RestoreCrtMode visszatölti az eredeti, a grafikus üzemmód előtti képernyőmódot, SetGraphBufSize a belső grafikus puffer méretét határozza meg poligon rajzoláshoz, SetGraphMode beállítja a grafikus módot, törli a képernyőt és újratölti az összes adatot az alapértelmezés szerint. A grafikus programban az InitGraph eljárás tölti be a grafikus meghajtót és a rendszert grafikus módba helyezi. A grafikus módot CloseGraph eljárás hívásával kell lezárni, mielőtt a program befejezi a futását. RAJZOLÁS ÉS FESTÉS Rajzolás Arc körívet rajzol, Circle kört rajzol, DrawPoly poligon körvonalát rajzolja, Ellipse ellipszis ívet rajzol, GetArcCoords megadja a körív vagy ellipszis ív utolsó hívásának koordináta értékeit, GetAspectRatio visszatér a grafikus képernyő maximális méretével, amelyből az oldalarány számítható, GetLineSettings visszatér az aktuális vonal stílusával, mintájával és vastagságával, Line egyenest rajzol (x1,y1) és (x2,y2) pontok között, LineRel egyenest rajzol az aktuális grafikus kurzor pozíciótól az adott relatív távolságban lévő pontba, LineTo egyenest rajzol az aktuális grafikus kurzor pozíciótól az adott (x,y) pontba, MoveRel mozgatja a grafikus kurzort egy relatív távolsággal, MoveTo mozgatja a grafikus kurzort az (x,y) pontba, Rectangle téglalapot rajzol, SetAspectRatio változtatja a beépített arány faktort, SetLineStyle beállítja az aktuális vonal vastagságát és stílusát. Festés (kitöltés: Fill) Bar rajzol és befest egy téglalapot, Bar3D rajzol és befest egy téglatestet, FillEllipse rajzol és befest egy ellipszist, FillPoly rajzol és befest egy poligont, GetFillPattern visszatér a felhasználó által definiált mintával, GetFillSettings visszatér az aktuális festő mintával és színével, PieSlice rajzol és befest egy körcikket, Sector rajzol és befest egy ellipszis cikket, SetFillPattern kiválasztja a felhasználó által definiált festő mintát, SetFillStyle kiválasztja a festő mintát és a színt. KÉPERNYŐ ÉS KÉPERNYŐABLAK KEZELÉS Képernyő kezelése ClearDevice törli az aktív képernyőt (az aktív lapot), SetActivePage kijelöli az aktív lapot a grafikus outputra, SetVisualPage láthatóvá teszi az adott grafikus lapot, Képernyőablak kezelése ClearViewPort törli az aktuális képernyő ablakot, GetViewSettings visszaadja a képernyőablak információit, SetViewPort kijelöli az aktuális képernyő ablakot grafikus outputra, Kép kezelése GetImage a megadott képmező bittérképét elmenti egy pufferba, ImageSize megadja a tárolni kívánt téglalap alakú tartomány byte-jainak számát, PutImage a korábban tárolt képmező bittérképét a képernyőre helyezi. Képpont kezelése GetPixel visszatér az (x,y) képpont színével, PutPixel egy pontot rajzol az (x,y) pontba. SZÖVEGKIŒRÁS KÉPERNYŐRE GRAFIKUS MÓDBAN GetTextSettings visszatér az aktuális karakterkészlet típusával, irányával, méretével és helyzetével, Ž OutText az aktuális pozíciónál szöveget ír, OutTextXY a megadott pozíciónál szöveget ír, SetTextJustify szöveg helyzetének beállítása az OutText és OutTextXY eljárások számára, SetTextStyle beállítja az aktuális karakterkészlet, a kiírásának irányát és a karakterek méretét, SetUserCharSize beállítja a karakter szélesség és magasság faktorát, TextHeight megadja a szöveg képpontokban mért magasságát, TextWidth megadja a szöveg képpontokban mért szélességét. SZŒN BEÁLLŒTÁSA Szín információ vétele GetBkColor visszatér az aktuális háttér színével, GetColor visszatér az aktuális rajzolási színnel, GetDefaultPalette visszatér a paletta struktúrával, GetMaxColor visszatér a maximálisan használható szín értékével az aktuális grafikus módban, GetPaletteSize visszatér a paletta színeinek számával. Beállít egy vagy több színt SetAllPalette változtatja a paletta színeit a megadott színekkel, SetBkColor beállítja az aktuális háttérszínt, SetColor beállítja az aktuális rajzolási színt, SetPalette egy paletta színt változtat. HIBAKEZELÉS GraphErrorMsg visszatér a hibakódnak megfelelő üzenettel, GraphResult az utoljára végrehajtott grafikus művelet hibakódját adja vissza. ÁLLAPOT LEKÉRDEZÉSE GetArcCoords visszatér az utoljára rajzolt ív vagy ellipszis ív koordinátáinak értékével, GetAspectRatio visszatér a grafikus képernyő oldalarány értékeivel, GetBkColor visszatér az aktuális háttérszínnel, GetColor visszatér az aktuális rajz színével, GetDriverName visszatér az aktuális grafikus meghajtó nevével, GettFillPattern visszatér a felhasználó által definiált festő mintával, GetFillSettings visszatér az aktuális festő mintával és színével, GetGraphMode visszatér az aktuális grafikus móddal, GetLineSettings visszatér az aktuális vonal típusával, mintájával és vastagságával, GetMaxColor visszatér a maximálisan használható színek számával, GetMaxMode visszatér az aktuális meghajtó maximális grafikus módjainak számával, GetMaxX visszatér a maximális pontok számával x irányban, GetMaxY visszatér a maximális pontok számával y irányban, GetModeName visszatér az aktuális mód méretével, GetModeRange visszatér az adott meghajtó módhatáraival, GetPalette visszatér a palettával és méretével, GetPixel visszatér az (x,y) képpont színével, GetTextSettings visszatér az aktuális karakterkészlettel, irányával, méretével és helyzetével, GetViewSettings információt ad az aktuális képernyő ablakról, GetX visszatér az aktuális pozíció x koordináta értékével, GetY visszatér az aktuális pozíció y koordinátaértékével. Grafikus mód konstansai, változói és rekordjai Grafikus vezérlők Detect = 0; CGA = 1; MCGA = 2; EGA = 3; EGA64 = 4; EGAMono = 5; IBM8514 = 6; HercMono = 7; ATT400 = 8; VGA = 9; PC3270 =10; Grafikus módok CGA meghajtó grafikus módjai: CGAC0 = 0; { 320x200 } CGAC1 = 1; { 320x200 } CGAC2 = 2; { 320x200 } CGAC3 = 3; { 320x200 } CGAHi = 4; { 640x200 } MCGA meghajtó grafikus módjai: MCGAC0 = 0; { 320x200 } MCGAC1 = 1; { 320x200 } MCGAC2 = 2; { 320x200 } MCGAC3 = 3; { 320x200 } MCGAMed = 4; { 640x200 } MCGAHi = 5; { 640x480 } EGA meghajtó grafikus módjai: EGALo = 0; { 640x200 } EGAHi = 1; { 640x350 } EGA64 meghajtó grafikus módjai: EGA64Lo = 0; { 640x200 } EGA64Hi = 1; { 640x350 } EGAMonoHi = 3; { 640x350 } HercMono meghajtó grafikus módja: HercMonoHi = 0; { 720x348 } ATT400 meghajtó grafikus módjai: ATT400C0 = 0; { 320x200 } ATT400C1 = 1; { 320x200 } ATT400C2 = 2; { 320x200 } ATT400C3 = 3; { 320x200 ] ATT400Med = 4; { 640x200 } ATT400Hi = 5; { 640x400 } VGA meghajtó grafikus módjai: VGALo = 0; { 640x200 } VGAMed = 1; { 640x350 } VGAHi = 2; { 640x480 } PC3270 meghajtó grafikus módjai: PC3270Hi = 0; { 720x350 } IBM8514 meghajtó grafikus módjai: IBM8514Lo = 0; { 640x480 } IBM8514Hi = 1; { 1024x768 } Színkonstansok Black = 0; Blue = 1; Green = 2; Cyan = 3; Red = 4; Magenta = 5; Brown = 6; LightGray = 7; DarkGray = 8; LightBlue = 9; LightGreen = 10; LightCyan = 11; LightRed = 12; LightMagenta = 13; Yellow = 14; White = 15; Színek a 8514 EGABlack = 0; EGABlue = 1; EGAGreen = 2; EGACyan = 3; EGARed = 4; EGAMagenta = 5; EGABrown = 20; EGALightgray = 7; EGADarkgray = 56; EGALightblue = 57; EGALightgreen = 58; EGALightcyan = 69; EGALightred = 60; EGALightmagenta= 61; EGAYellow = 62; EGAWhite = 63; Vonal stílusok és szélességek: SolidLn = 0; DottedLn = 1; CenterLn = 2; DashedLn = 3; UserBitLn = 4; NormWidth = 1; ThickWidth = 3; Karakterkészletek és irány: DefaultFont = 0; TriplexFont = 1; SmallFont = 2; SansSerifFont = 3; GothicFont = 4; HorizDir = 0; { balról jobbra } VertDir = 1; { alulról felfelé ] UserCharSize = 0; Vágó konstansok: ClipOn = true; ClipOff = false; Bar3D konstansok: TopOn = true; TopOff = false; Töltő minták: EmptyFill = 0; { nincs minta, kitöltés háttér színű } SolidFill = 1; { egyenletes, halvány tónus } LineFill = 2; { vízszintes vonalas minta } LtSlashFill = 3; { dőlt '/' vonalas minta } SlashFill = 4; { dőlt '/' vastag vonalas minta } BkSlashFill = 5; { dőlt '\' vastag vonalas minta } LtBkSlashFill = 6; { dőlt '\' vonalas minta } HatchFill = 7; { kockás minta } XHatchFill = 8; { dőlt kockás minta } InterLeaveFill = 9; { sűrűn pontozott minta } WideDotFill = 10; { ritkán pontozott minta } CloseDotFill = 11; { közepesen pontozott minta } UserFill = 12; { a felhasználó által definiált minta, amit a SetFillPattern eljárásnál adott meg } PutImage bit operátorai: NormalPut = 0; { MOV } CopyPut = 0; { MOV } XORPut = 1; { XOR } OrPut = 2; { OR } AndPut = 3; { AND } NotPut = 4; { NOT } Vízszintes és függőleges elrendezés a SetTestJustification eljárás számára: CenterText = 1; LeftText = 0; RightText = 2; BottomText = 0; TopText = 2; Konstansok és rekordok: const MaxColor = 15; type PaletteType = record Size : Byte; Colors: array[0..MaxColors] of Shortint; end; LineSettingsType = record LineStyle : Word; Pattern : Word; Thickness : Word; end; TextSettingsType = record Font : Word; Direction : Word; CharSize : Word; Horiz : Word; Vert : Word; end; FillSettingsType = record Pattern : Word; Color : Word; end; FillPatternType = array[ 1..8 ] of Byte; PointType = record X,Y : integer; end; ViewPortType = record x1,y1,x2,y2 : integer; Clip : Boolean; end; ArcCoordType = record X,Y, Xstart,Ystart, Xend,Yend : integer; end; Változók: var GraphGetMemPtr : pointer; GraphFreeMemPtr : integer; 14.5. Grafikus programok készítése 14.5.1. Színkezelés különböző vezérlők esetén Pascalban a színek kiválasztásánál névvel vagy sorszámmal hivatkozhatunk. Közvetlenül 16 szín programozható (0-15) vezérlőtöl és a kiválasztott módtól függően. Példaként bemutatunk néhány színt. A szinekre névvel, vagy számmal is hivartkozhatunk: SetTextColor(blue); vagy SetTextColor(2); 14.5.2. Jelentősebb mód konstansok A grafikus programok készítéséhez a grafikus meghajtókhoz tartozó mód típusokra és a hozzájuk tartozó adatokra. A jelentősebb grafikus mód konstansokat az alábbi táblázat fogalja össze: Grafikus Érték Konstans Érték Oszlopxsor Paletta Lap meghajtó neve HercMono 7 HercmonoHi 0 720x348 2 szín 2 CGA 1 CGAC0 0 320x200 C0 1 CGAC1 1 320x200 C1 1 CGAC2 2 320x200 C2 1 CGAC3 3 320x200 C3 1 CGAHi 4 640x200 2 szín 1 EGA 3 EGALo 0 640x200 4 szín 1 EGAHi 1 640x350 16 szín 1 VGA 9 VGALo 0 640x200 16 szín 2 VGAMed 1 640x350 16 szín 2 VGAHi 2 640x480 16 szín 1 14.5.3. Grafikus program felépítésének vázlata Ahhoz, hogy rajzolni tudjunk az uses mellett definiálni kell a Graph unit-ot. Deklarálni kell három egész típusú változót Gdriver grafikus vezérlő, Gmode grafikus mód, Hibakód a grafikus hiba kódját tartalmazza. Ha a Gdriver:=Detect; ez azt jelenti, hogy a InitGraph eljárásra bízzuk, hogy állapítsa meg a meghajtó típusát és a Gmode változóba a típusnak megfelelő legnagyobb felbontásnak megfelelő módot ajánlja. Az InitGraph harmadik paramétere, hogy a grafikus vezérlő program (.BGI) hol található. Három eset lehetséges: 1. '' üres sztring megadása esetén abban az alkönyvtárban van a megfelelő .BGI, ahol a program van. 2. 'C:\tp\bgi\' az útvonal pontos nevét adjuk meg, vagy 3. programból rákérdezünk az útvonal pontos nevére. Mindhárom megoldást bemutatják a GRAFIKA1 ill. a GRAFIKA2 programok. Ha a grafikus megnyitás sikeres volt, megkezdődhet a rajzolás. Ahhoz, hogy a rajz a képernyőn maradjon javasolt a readln; aktiválása, amely az ENTER leütéséig kimerevíti a képernyőt. A grafikát a CloseGraph eljárással zárjuk le, mielőtt a program a futását befejezné. program grafika1; uses Graph; var Gdriver,Gmode,Hibakod: integer; begin Gdriver:=Detect; InitGraph(Gdriver,Gmode,''); Hibakod:=GraphResult; if Hibakod<>GrOk then begin writeln('Grafikus hiba: ',GraphErrorMsg(Hibakod)); Writeln('Program exit...'); Halt; end (* rajzolas *) Rectangle(100, 100, 60, 40); readln; CloseGraph; end. A GRAFIKA2.PAS program a BGIUtvonal sztringből veszi a .BGI file elérési útvonalát, ha ez nem megfelelő, akkor a program hibát jelez és rákérdez az elérési útvonalra. Helytelen útvonal megadása esetén a program befejezi a futását. program grafika2; uses Graph; var Gdriver,Gmode,Hibakod: integer; BGIUtvonal: string; begin BGIUtvonal:='C:\BGI\'; Gdriver:=Detect; InitGraph(Gdriver,Gmode,BGIUtvonal); Hibakod:=GraphResult; if Hibakod<>GrOk then begin writeln('Grafikus hiba: ',GraphErrorMsg(Hibakod)); if Hibakod = grFileNotFound then begin write('Adja meg a BGI teljes utvonalat', ' vagy Ctrl-Break program exit: '); readln(BGIUtvonal); Gdriver:= Detect; InitGraph(Gdriver, Gmode, BGIUtvonal); if (GraphResult <> GrOK) then Halt(1); end end; (* rajzolás *) Rectangle(100,100, 60, 40); readln; CloseGraph; end. Nézzünk néhány példát különböző típusú monitorok valamely grafikus módjának a megnyitására: a. Hercules monitor esetén A grafikus üzemmód megnyitása: GraphDriver:=HercMono; GraphMode:=HercMonoHi; InitGraph(GraphDriver, GraphMode,''); A Hercules monitornak nincs más üzemmódja. A 720x348 felbontás azt jelenti, hogy 0-719 sorszámúak az oszlopok száma és 0-347 sorszámúak a sorok száma. Két szín használható, amelyből egy a háttérszín. A lapok száma kettő, lehetőség van megjelenített lap mellett egy másik lapra is rajzolni és a lapokat váltani lehet, amely animációs rajzprogramnál meggyorsítja a képek mozgatását a képernyőn. b. CGA monitor esetén CGA monitor esetén 5 fajta üzemmód van. Négy üzemmódban a 320x200 durva grafikában négy színt hasznáhatunk, a 640x200 finom grafikában pedig csak két színt. Csak egy grafikus lapja van. Nézzük meg részletesebben a CGA durva grafika színkiválasztását. A négy szín közül egy a háttérszín, amely a 16 szín közül bármely lehet. Négy paletta közül választhatjuk a további 3 színt a rajzoláshoz. A mód kiválasztásával aktiváljuk a palettát. Grafikus mód színek sorszáma neve száma 1 2 3 CGAC0 0 világoszöld világospiros sárga CGAC1 1 világos türkiz világoslila fehér CGAC2 2 zöld piros barna CGAC3 3 türkiz lila világosszürke CGAHi 4 Például válasszuk ki a CGA monitor 0-ás palettáját: GraphDriver:=CGA; GraphMode:=CGAC0; InitGraph(GraphDriver, GraphMode,''); Ennél a palettánál a világoszöld, világospiros és a sárga használható. Válasszuk háttérszínnek a kéket és váltogassuk a rajzolás színét: GraphDriver:=CGA; GraphMode:=CGAC1; InitGraph(GraphDriver, GraphMode,''); SetBkColor(Blue); háttérszín kék SetColor(1); rajzolás színe : világos türkíz, SetColor(2); világoslila, SetColor(3); fehér. Válasszuk ki a CGA monitor nagyfelbontású módját: GraphDriver:=CGA; GraphMode:=CGAHi; InitGraph(GraphDriver, GraphMode,''); c. EGA monitor esetén EGA monitor esetén a hardver 64 színt tud kezelni, azonban közvetlenül 16 színt használhatunk egyidejűleg. Válasszuk ki az EGA monitor nagyfelbontású módját: GraphDriver:=EGA; GraphMode:=EGAHi; InitGraph(GraphDriver, GraphMode,''); Rajzoljuk kék színnel: SetColor(Blue); vagy SetColor(1); d. VGA monitor esetén VGA monitor 256 színből közvetlenül csak 16 szín. A VGALo és a VGAMed mód kiválasztása esetén 2 grafikus lapot programozhatunk. 14.5.4. Grafikus üzemmód hibajelzései A GraphResult függvény adja vissza a GRAPH unit belső hibajelzéseit, mely mindig az utoljára végrehajtott grafikus művelet állapotáról ad információt. A GraphResult eljárásnak az alábbi hiba kód konstansai léteznek: const grOk = 0; { Nincs hiba. } grNoInitGraph = -1; { BGI nincs installálva InitGraph hívásával } grNotDetected = -2; { Nem érzékelt grafikus hardvert. } grFileNotFound = -3; { Az egység meghajtó .BGI file hiányzik. } grInvalidDriver = -4; { Érvénytelen a meghajtó .BGI file } grNoLoadMem = -5; { Kevés a memória a meghajtó betöltéséhez. } grNoScanMem = -6; { Kevés a memória. } grNoFloodMem = -7; { Kevés a memória. } grFontNotFound = -8; { Karakterkészlet file-t nem találja. } grNoFontMem = -9; { Kevés a memória a karakter- készlet betöltéséhez. } grInvalidMode = -10; { Érvénytelen a grafikus mód a kiválasztott meghajtó számára. } grError = -11; { Grafikus hiba. } grIOError = -12; { Grafikus I/O hiba. } grInvalidFont = -13; { Érvénytelen karakterkészlet file. } grInvalidFontNum = -14; { Érvénytelen karakterkészlet szám. } grInvalidDeviceNum = -15; { Érvénytelen a grafikus eszköz száma } 14.6. Grafikus mintafeladatok 14.6.1. Szöveg kiírása grafikus módban MINTA1.PAS program minden monitoron fut, fekete/fehér rajzot készít. Ez az egyszerű rajzprogram egy maximális méretű téglalapot rajzol és a téglalap közepére 'Grafikus feladat' szöveget írja ki. Tervezzük meg a programot: A program neve legyen rajz_minta. A uses kulcsszó mellett meg kell adni a Graph grafikus könyvtár nevét, így tudunk hozzáférni a grafikus eljárásokhoz és függvényekhez. Három egész típusú változóra lesz szükségünk: GraphDriver a grafikus meghajtó GraphMode a grafikus mód és a ErrorCode a hibaüzenet számára. Ha olyan grafikus programot tervezünk, amely automatikusan meghatározza a vezérlő típusát és a legnagyobb felbontásnak megfelelő módot ajánlja fel, akkor a grafikus üzemmód megnyitásánál az InitGraph eljárást a GraphDriver paraméterben megadott Detect konstanssal kell hívni. Ennek hatására a GraphDriver a megfelelő meghajtót és a GraphMode pedig az aktuális meghajtónak megfelelő legnagyobb felbontást jelentő módot fogja tartalmazni. A GraphResult függvénnyel ellenőrizhetjük, hogy az InitGraph eljárás aktiválásával sikerült-e áttérni a grafikus üzemmódra. Ha az ErrorCode változóban visszaadott érték megegyezik a grOk konstanssal, akkor sikeres volt a grafikus üzemmód inicializálása, ellenkező esetben a GraphErrorMsg eljárást az ErrorCode változóval aktiválva szöveges formában is kiírathatjuk a hiba okát és a program futása megszakad. Hibátlan inicializálás esetén rajzoljunk egy maximális méretű téglalapot a Rectangle eljárással. A téglalap bal felső sarka a (0,0) pont és a jobb alsó sarka pedig a grafikus kártyától függően a maximális oszlop, ill. sorok száma legyen, ezeket a GetMaxX és a GetMaxY függvényekkel kérdezhetjük le. A képernyőn a szöveg helyzetét a SetTextJustify eljárással állíthatjuk be. Ha a SetTestJustify mindkét paraméterénél a CenterText konstanst adjuk meg, akkor a szöveg középre kerül. Ezután definiálnunk kell a karakterkészlet típusát, a kiirandó szöveg irányát, valamint a betűk méretét. Jelen példánkban használjuk a normál karakterkészletet, a kiírás iránya legyen vízszintes és a betűk nagysága 3-szoros. A SetTextStyle eljárást a DefaultFont, a Horizdir és 3 paraméterekkel kell aktíválnunk. Ha a szöveget adott koordinátapontnál akarjuk megjeleníteni, akkor az OutTextXY eljárást használjuk. Az OutTextXY eljárás első két paramétere az x,y koordinátapont, ahol a szöveg megjelenik, mivel a SetTextJustify eljárással a szöveget középre centírozzuk, így itt a képernyő közepét kell megadni. Képernyő közepét különböző típusú monitorok esetén dinamikusan a GetMaxX és a GetMaxY függvények hívásával tudjuk kiszámítani. Az így megkapott maximális x, ill y irányú méretet egészosztással (div) a képernyő közepére tesszük. Az OutTextXY eljárás harmadik paramétere a kiirandó szöveg, jelenleg a programban aposztrofok között sztring konstansként adjuk meg a kiirandó szöveget. Gondoskodnunk kell arról, hogy a felrajzolt kép ne tünjön el azonnal, hanem addig lássuk, amíg akarjuk. Ezt elérhetjük egy Readln paraméternélküli hívásával, ennek hatására a kép kimerevedik a képernyőn addig, míg Enter billentyűt nem nyomtunk meg. A grafikus programot a CloseGraph eljárás hívásával kell lezárni, amely visszaállítja azt a módot, amely a grafikus üzemmód előtt volt, jelen esetben az eredeti normál video módot. A rajz_minta1 rajzprogram listája a következő: (* minta1.pas *) program rajz_minta1; uses Graph; var GraphDriver, GraphMode, ErrorCode : integer; begin GraphDriver := Detect; InitGraph(GraphDriver, GraphMode,''); ErrorCode := GraphResult; if ErrorCode <> grOk then begin writeln('Grafikus hiba: ', GraphErrorMsg(ErrorCode)); writeln('Program exit… '); Halt(1); end; Rectangle(0, 0, GetMaxX, GetMaxY); SetTextJustify(CenterText, CenterText); SetTextStyle(DefaultFont, HorizDir, 3); OutTextXY(getMaxX div 2, GetMaxY div 2, 'Grafikus feladat '); Readln; CloseGraph; end. Ha a programot lefuttatjuk olyan PC-ken, amelyeknek Hercules, CGA, EGA vagy VGA monitort csatlakozik, akkor a program mindegyik gépen a legnagyobb felbontást választva két színt használva rajzolja a keretet és írja ki a szöveget a képernyő közepére. Módosítsuk a programunkat úgy, hogy a különböző típusú monitorok esetén módot választunk. (MINTA2.PAS). A MINTA3.PAS programban a háttér, a téglalap és a szöveg színesen jelenik meg, kivéve Hercules monitor esetében. (* minta2.pas *) program rajz_minta2; uses Graph; var GraphDriver, GraphMode, ErrorCode: integer; begin GraphDriver := Detect; case GraphDriver of 1: { CGA driver } GraphMode := CGAC1; 3: { EGA driver } GraphMode:= EGALo; 7: { Hercules driver } GraphMode := HercMonoHi; 8: { VGA driver } GraphMode := VGALo; end; InitGraph(GraphDriver, GraphMode,''); ErrorCode := GraphResult; if ErrorCode <> grOk then begin writeln('Grafikus hiba: ',GraphErrorMsg(ErrorCode)); writeln('Program exit… '); Halt(1); end; SetBkColor(White); SetColor(2); Rectangle(0, 0, GetMaxX, GetMaxY); SetTextJustify(CenterText, CenterText); SetTextStyle(DefaultFont, HorizDir,3); SetColor(1); OutTextXY(GetMaxX div 2, GetMaxY div 2, 'Grafika'); Readln; CloseGraph; end. A G_SZOVEG.PAS program a képernyő közepén jeleníti meg a szöveget. Az összes karakterkészlet be van építve, csak egy érvényes belőle. A futtatáskor változtathatjuk a szöveg nagyságát és a karakterkészletet is. Az F_SZOVEG.PAS a normális, a keskeny és a széles karakterek kiírását mutatja be. A meghajtó nevének kiiratása A MEGHAJTO.PAS program kiírja a meghajtó nevét a képernyőre. A .BGI file-oknak az aktuális könyvtárban kell lenniük, (* meghajto.pas *) program meghajto; uses Graph; { GetDriverName procedure } var Gd,Gm,ErrorCode: integer; procedure grstart; begin Gd:=Detect; Initgraph(Gd,Gm,''); ErrorCode := GraphResult; if ErrorCode<>GrOk then begin writeln('Grafikus hiba: ' ,GraphErrorMsg(ErrorCode)); writeln('A program befejezi a futasat. '); Halt(1); end; end; begin grstart; Outtext('Meghajto neve: '+ GetDriverName); Readln; CloseGraph; end. 14.6.2. Szöveges és grafikus mód váltása GRVALTAS.PAS program mutatja be a grafikából szöveges módba, majd újra grafikába való váltást. (* GRValtas.pas *) (* Grafika es szoveges mod valtasa *) program GValtas; uses Graph,Crt; { GetGraphMode procedure } var Gd,Gm:integer; Mode: Integer; Procedure grstart; begin Gd:=Detect; Initgraph(Gd,Gm,''); if GraphResult<>GrOk then Halt(1); end; begin grstart; Rectangle(20,20,290,100); OutTextxy(25,30,' kilepunk a grafikabol.'); Readln; RestoreCRTMode; GotoXY(10,10); Write(' Szoveges modban vagyunk…'); GotoXY(10,12); write(' hatasara visszaterunk grafikus modba.'); Readln; SetGraphMode(GetGraphMode); Rectangle(20,20,290,100); OutTextXY(25,30,'Grafikus modban vagyunk'); OutTextXY(25,30+TextHeight('H'), ' lezarjuk a grafikat'); Readln; CloseGraph; end. A RAJZ_T.PAS program a CRT_PR.PAS program továbbfejlesztett változata. A 40 oszlopos szöveges módban az olvas eljárás felhasználásával olvassuk be a téglalap két oldalának adatait és a bal felső koordinátáinak értékét, mindegyik adat ellenőrízve van, és javításra is van lehetőség. A DetectGraph eljárás automatikusan megvizsgálja a képernyő típusát és annak megfelelően állítjuk be a grafikus módot és a rajzolás két színét a RAJZ_M.PAS programban. 14.6.3. CGA.BGI és a LITT.CHR programba fordítása A FERDEHAJ.PAS program a ferdehajítást szimulálja. A szöveges módban 40 karakterre állítja be a képernyőt. Párbeszédes üzemmódban kérdezi meg a dobás távolságát, melyet el kell találni, majd a dobás szögét és sebességét. Az adatokat ellenőrzi. A grafikához a CGA meghajtót és a CGAC0 módot választja ki, ezáltal a zöld, piros és a sárga palettát használja. A grafikus mód nyitásánál meg kell adni azt annak az alkönyvtárnak nevét, ahol program megtalálja a grafikát meghajtó .BGI file-okat, vagy a programunkkal együtt mindig be kell másolni az adott alkönyvtárba és mindig a programmal együtt kell léteznie. Lehetőség van a .BGI file-oknak a programba való befordítására. A jelen program a grafikus mód váltásánál nem keresi a CGA.BGI file-t, mert a meghajtót a programba fordítottuk az alábbi módon: 1. A BINOBJ segédprogram segítségével object formátumra alakítjuk a megfelelő .BGI file-t, pl. a CGA.BGI, akkor a következő parancsot kell kiadni: binobj cga.bgi cga.obj cga Hatására a CGA.OBJ nevű file-ban előáll az object formátumú grafikus meghajtó, melyet programunkban CGA eljárásnéven deklaráltunk. 2. A program elején {$L} fordítási direktívával beszerkesztjük a CGA.OBJ nevű file-t, majd az external kulcsszóval külső eljárásnak deklaráljuk CGA néven. {$L CGA.OBJ} { az object formatumu CGA } procedure CGA; EXTERNAL; { meghajto beszerkesztese } 3. A grafikus nyitás elején a Graph unit-ban található RegisterBGIDriver függvény meghívásával bejegyezzük a rendszerbe a meghajtó memóriabeli helyét. A függvény bemenő paramétere a CGA nevű eljárás memóriabeli címe. Hiba esetén a függvény visszaadott értéke negatív. uses Crt,Dos,Graph; $L LITT.OBJ} procedure LITT; External; {Small fontokat tartalmazó file beszerkesztése } {$L CGA.OBJ } procedure CGA; External; { meghajto beszerkesztese } .... var gm, gd: integer; { grafika megnyitasa elotti ellenorzes } gd:= 1; { CGA } gm:=CGAC0; if RegisterBGIDriver(@CGA) < 0 then { CGA meghajto } begin writeln('Nem sikerult beepiteni a CGA file-t '); halt(1); end; if RegisterBGI Font(@LITT) < 0 then { Small font } begin writeln('Nem sikerult beepiteni a LITT file-t '); halt(2); end; InitGraph(gd,gm,''); ... A FERDEHAJ.PAS program grafikus képernyője 14.6.4. Grafikus kurzor mozgatása A CUR_PROG.PAS program bemutatja, hogyan lehet grafikus kurzort mozgatni a képernyőn. A program CGA, EGA és VGA képernyőt tud kezelni. Kirajzolja a képernyőre az aktuális dátumot, a napot valamint az időt is kijelzi. A program eljárásai: EGA_color EGA és VGA képernyőre a rajzolás színeit állítja be, CGA_color CGA képernyőre a rajzolás szineit állítja be, graph_ini automatikusan kiválasztja a grafikus meghajtót, frame_ini a rajzkeret adatait és a kurzor x irányú mozgatásának nagyságát állítja, frame megrajzolja a keretet a fejlécekkel, aktiválja a rajzol eljárást, adat_ki a keret jobb szélén függőlegesen írja vissza a kurzor alatti adat értékét, rajzol adatokat generál és rajzol, draw_cursor mozgatja a kurzort és leolvassa az ábrázolt adatokat a kurzor jobbra mozgatásánál szaggatott vonallal, balra mozgatásánál telt vonallal jelenik meg és az adat kiíratási színe is változik. A CURSOR.PAS unit grafikusan mozgatható kurzor rutinokat tartalmaz. A kurzor hossza, színe és stílusa (teljes vagy szaggatott vonalú) is beállítható. A unit két eljárást tartalmaz: putcursor delcursor A putcursor eljárás kihelyezi a kurzort a képernyőre, a paraméterei: p pointer, kimenő paraméter, amely rámutat arra a memória címre, ahol a kurzor képe van tárolva, h a kurzor x koordinátája, v a kurzor y koordinátája, h1 a kurzor magasságának mérete, szélessége 5-5 raszterre van állítva, vonal 1 a kurzor teljes vonal, 0 a kurzor szaggatott vonal, color a kurzor színe. A delcursor eljárás törli a kurzort a képernyőről, a paraméterei: p pointer, a kurzor memóriabeli címére mutat, h a kurzor x koordinátája, v a kurzor y koordinátája, h1 a kurzor magassága. 14.6.5. Alakzat mozgatása Az URHAJO.PAS program inkább egy repülő csészealjhoz hasonló tárgyat mozgat. A EGA vagy VGA monitorral rendelkező gépen fut. Az animációhoz szükséges lapozási technikát mutatja be. A Page eljárása váltogatja a lapokat. procedure Page; begin setvisualpage(Active); Active := 1 - Active; setactivepage(Active); cleardevice; end; PALETTA.PAS program a színskálát körcikkein mutatja be. ENTER leütésére a kör forogni kezd, ha megáll újra ENTER leütésére fejezi be a program futását. 14.6.6. Képernyő torzításának kiküszöbölése ASPECT_P.PAS program EGA és VGA monitoron fut, bemutatja a négyzet és a beleírható kör torzításának számítását. A TORZIT.PAS program ellipszisből kiindulva addig növeli a torzítási arányt, míg kör nem lesz a rajzból. 14.6.7. Alakzatok rajzolása A RAJZ1.PAS program EGA, VGA monitoron jeleníti meg az összes rajzolható alakzatot, vonalat, görbeívet, alakzat festését is demonstrálja. A RAJZ2.PAS program EGA,VGA monitoron bemutatja a betűkészleteket. A szöveg nagyságának és irányának programozásával. A RAJZ3.PAS program EGA monitoron a véletlenszám generátorral képzett színkódot, véletleszszám generátorral megadott helyre teszi ki a PutPixel eljárás. A PALETTAD.PAS program EGA monitoron bemutatja a paletta átdefiniálását. A GPLD.PAS program EGA, VGA monitoron egy szép grafikus képet hoz létre. 2500 ms ideig kimerevíti a képet, majd a grafikus módot lezárva, visszatér szöveges módba. 14.6.8. Kép kivágása és újrahelyezése A KIVAG.PAS program a grafikus képernyő egy részét a memóriába menti, majd az Enter leütése után újra megjeleníti. (* Kivag.pas *) program kivag; uses Graph; { ImageSize function } var Gd,Gm: integer; P: pointer; Size: word; Procedure grstart; begin Gd:=Detect; Initgraph(Gd,Gm,''); if GraphResult<>GrOk then Halt(1); end; begin grstart; { A teljes kepernyot kifesti } Bar(0,0,GetMaxX,GetMaxy); { Lekeri a kivagando negyzet meretet } Size:=ImageSize(10,20,30,40); GetMem(P,Size); { memoriat foglal le } { Elteszi a memoriaba } GetImage(10,20,30,40,P^); Readln; { torli a kepernyot } ClearDevice; { Kiteszi az eltarolt negyzetet } PutImage(100,100,P^,NormalPut); Readln; CloseGraph; end. A V_FEKETE.PAS program minden monitoron bemutatja a getimage, putimage használatát, a képernyőn képezhető összes művelettel. A V_SZINES.PAS program EGA, VGA monitoron színesen mutatja be a getimage és a putimage használatát. Ellenőrző kérdések: 1. Milyen módokban használhatják a Pascal programok a PC képernyőjét? 2. Melyik unit tartalmazza a grafikus eljárásokat? 3. Mire szolgál a .BGI file? 4. Mi a kiterjesztése a karakterkészletnek? 5. Milyen eljárással kell a grafikus módot megnyitni és mivel zárni? 6. Milyen módszerrel lehet a programba befordítani a grafikus meghajtót? 7. Melyek a koordinátái a grafikus képernyő bal felső sarkának? 8. Mivel lehet a grafikus képernyőt kimerevíteni, hogy a felrajzolt ábra a képernyőn maradjon? Feladatok: 1. Œrjon programot, amely grafikus módban kirajzolja az olimpiai karikákat. (OLIMPIA.PAS) 2. Œrjon programot, amely a képernyőn adott osztásban négyzethálót rajzol. (RASTER.PAS) 3. Œrjon programot, amely egy házat rajzol ki és a falakat kifesti. (HAZ.PAS) 4. Irjon évdiagram rajzolására programot. (EV_DIAG.PAS) 5. Általános oszlopdiagram rajzolására tervezzen programot. (OSZLOP.PAS) 6. Œrjon programot, amely egyszerű analóg-digitál órát rajzol a képernyőre. (ORA.PAS) 7. Rajzolja ki a színskálát, használja a PaletteType típust. (SZINES.PAS)