


 SYSTMOV A PROGRAMTORSK SERVIS MON


















        TURBO PASCAL 5.0 / 5.5
        
                   a
        
        PURE PASCAL pro Atari ST

               druh dl



             RNDr. Tom RUBA
             RNDr. Jana  VINOV
             RNDr. Eva   NOVKOV
             RNDr. Tom EHK























           PRAHA, duben 1990

      Posledn zmna: 30.11.1994
         Poet dek: 11 390





Pedmluva

     Souasn rozvoj vpoetn techniky a vzrstajc poptvka po
kolench Turbo Pascalu podanch organizac MON si vynutily
vydn skript jako studijnho materilu k tmto kolenm.

     Skripta jsou lenna do dvou dl.

     Prvn dl odpovd Zkladnmu kursu Turbo Pascalu a pomrn
iroce jej dopluje.

     Druh dl pokrv (a svm rozsahem znan pesahuje) kurs
Turbo Pascalu pro pokroil.

     Pedtm, ne pijdete na kurs pro pokroil, procvite si
ltku zkladnho kursu natolik, aby Vs jej pouvn nezdro-
valo pi procviovn nov ltky.

                                       Mnoho spch pi prci.

OBSAH                                                      Strana:


VOD . . . . . . . . . . . . . . . . . . . . . . . . . . . .   6

6. Abstraktn datov struktury . . . . . . . . . . . . . . .   9
   6.1. Dynamick alokace  . . . . . . . . . . . . . . . . .   9
      6.1.1. HEAP  . . . . . . . . . . . . . . . . . . . . .   9
      6.1.2. Procedura NEW . . . . . . . . . . . . . . . . .  10
      6.1.3. Uvolovn dynamicky alokovan pamti . . . . .  11
      6.1.4. Organizace HEAPu  . . . . . . . . . . . . . . .  12
   6.2. Mocn nstroj "pointer"  . . . . . . . . . . . . . .  15
      6.2.1. Netypovan promnn . . . . . . . . . . . . . .  16
      6.2.2. Petypovn . . . . . . . . . . . . . . . . . .  18
      6.2.3. Adresa  . . . . . . . . . . . . . . . . . . . .  19
      6.2.4. Dynamick pole  . . . . . . . . . . . . . . . .  20
   6.3. Abstraktn datov struktury  . . . . . . . . . . . .  23
      6.3.1. Od promnn k modulu  . . . . . . . . . . . . .  23
      6.3.2. Seznamy . . . . . . . . . . . . . . . . . . . .  24
      6.3.3. Stromy  . . . . . . . . . . . . . . . . . . . .  30
      6.3.4. Mnoiny . . . . . . . . . . . . . . . . . . . .  33
   6.4. Objekty  . . . . . . . . . . . . . . . . . . . . . .  36
      6.4.1. Metody objekt  . . . . . . . . . . . . . . . .  36
      6.4.2. Hierarchizace objekt   . . . . . . . . . . . .  37
      6.4.3. Virtualizace metod  . . . . . . . . . . . . . .  39
      6.4.4. VMT a implementace  . . . . . . . . . . . . . .  46
   6.5. Unity  . . . . . . . . . . . . . . . . . . . . . . .  49
      6.5.1. Zpis program a unit . . . . . . . . . . . . .  49
      6.5.2. Kompilace . . . . . . . . . . . . . . . . . . .  53
      6.5.3. Unity jako moduly . . . . . . . . . . . . . . .  56
      6.5.4. Overlay . . . . . . . . . . . . . . . . . . . .  57
      6.5.5. Standardn unity  . . . . . . . . . . . . . . .  64
      6.5.6. Pouit unit - shrnut  . . . . . . . . . . . .  67
   6.6. Pseudonhodn sla  . . . . . . . . . . . . . . . .  68

7. Spoluprce s DOSem (TOSem)
   7.2. Parametry programu . . . . . . . . . . . . . . . . .  75
   7.3. Promnn DOSu  . . . . . . . . . . . . . . . . . . .  76
   7.4. Spoutn proces  . . . . . . . . . . . . . . . . .  77
   7.5. Indikace chyby . . . . . . . . . . . . . . . . . . .  79
      7.5.1. Indikace chyb v unitch . . . . . . . . . . . .  79
      7.5.2. Nvratov kdy  . . . . . . . . . . . . . . . .  81
      7.5.3. Exit procedura  . . . . . . . . . . . . . . . .  82
   7.9. Automatick optimalizace . . . . . . . . . . . . . . 100
   7.10. Soubory a DOS . . . . . . . . . . . . . . . . . . . 101
      7.10.1. Diskov sluby . . . . . . . . . . . . . . . . 101
      7.10.2. File Record  . . . . . . . . . . . . . . . . . 102
   7.11. Unita DOS . . . . . . . . . . . . . . . . . . . . . 107

8. Prce se standardnmi technickmi zazenmi  . . . . . . 111
   8.1. Obrazovka  . . . . . . . . . . . . . . . . . . . . . 112
      8.1.1. Textov md obrazovky   . . . . . . . . . . . . 114
      8.1.2. Nastaven barev . . . . . . . . . . . . . . . . 116
      8.1.3. Zpis na obrazovku  . . . . . . . . . . . . . . 120
      8.1.4. Okna  . . . . . . . . . . . . . . . . . . . . . 122
      8.1.5. Pm pstup k videopamti . . . . . . . . . . 124
   8.2. Klvesnice   . . . . . . . . . . . . . . . . . . . . 131
      8.2.1. Klvesnice jako vstupn soubor  . . . . . . . . 131
      8.2.2. Pm vstup znak   . . . . . . . . . . . . . . 132
      8.2.3. Zjitn stavu dcch klves  . . . . . . . . 136
   8.3. Reproduktor  . . . . . . . . . . . . . . . . . . . . 139
   8.4. Tiskrna   . . . . . . . . . . . . . . . . . . . . . 140
      8.4.1. Unita Printer   . . . . . . . . . . . . . . . . 141
      8.4.2. Detekce stavu tiskrny  . . . . . . . . . . . . 141
      8.4.3. dc znaky  . . . . . . . . . . . . . . . . . 142
   8.5. Hodiny   . . . . . . . . . . . . . . . . . . . . . . 143
      8.5.1. Datum a as   . . . . . . . . . . . . . . . . . 144
      8.5.2. asova   . . . . . . . . . . . . . . . . . . . 145
      8.5.3. Alarm   . . . . . . . . . . . . . . . . . . . . 146
   8.6. Unita Crt  . . . . . . . . . . . . . . . . . . . . . 149
   9.1.Prosted grafiky   . . . . . . . . . . . . . . . . . 152
      9.1.1. Nastaven reimu  . . . . . . . . . . . . . . . 152
      9.1.2. Nastaven mdu videa  . . . . . . . . . . . . . 160
      9.1.3. Chybov hlen . . . . . . . . . . . . . . . . 163
      9.1.4. Okna  . . . . . . . . . . . . . . . . . . . . . 166
      9.1.5. Strnky . . . . . . . . . . . . . . . . . . . . 168
   9.2. Parametry grafiky  . . . . . . . . . . . . . . . . . 170
      9.2.1. Barvy . . . . . . . . . . . . . . . . . . . . . 170
      9.2.2. ry  . . . . . . . . . . . . . . . . . . . . . 178
      9.2.3. Vpln  . . . . . . . . . . . . . . . . . . . . 180
      9.2.4. Texty . . . . . . . . . . . . . . . . . . . . . 181
      9.2.5. Souhrn stavovch promnnch a inicializace  . . 188
   9.3. Vkonn pkazy  . . . . . . . . . . . . . . . . . . 188
      9.3.1. seky  . . . . . . . . . . . . . . . . . . . . 189
      9.3.2. Obrazce . . . . . . . . . . . . . . . . . . . . 192
      9.3.3. Kivky  . . . . . . . . . . . . . . . . . . . . 196
      9.3.4. Text  . . . . . . . . . . . . . . . . . . . . . 200
      9.3.5. Standardn vstupn procedury . . . . . . . . . 201
   9.4. Image  . . . . . . . . . . . . . . . . . . . . . . . 202
   9.5. Dal funkce . . . . . . . . . . . . . . . . . . . . 208
   9.6. Unita Graph  . . . . . . . . . . . . . . . . . . . . 214

A. ASCII tabulka . . . . . . . . . . . . . . . . . . . . . . 221

B. Chybov hlen . . . . . . . . . . . . . . . . . . . . . 225
   1. Chyby pi pekladu nebo pi prci s integrovanm sys-
      tmem  . . . . . . . . . . . . . . . . . . . . . . . . 225
   2. Bhov chyby . . . . . . . . . . . . . . . . . . . . . 228
   3. Chyby pi Overlay  . . . . . . . . . . . . . . . . . . 230
   4. Chyby v grafice  . . . . . . . . . . . . . . . . . . . 231

C. Turbo Pascal 5.5 versus procedurln jazyky . . . . . . . 232
   1. Varianty a verze Pascalu . . . . . . . . . . . . . . . 232
   2. Jin programovac jazyky . . . . . . . . . . . . . . . 234
      i)   Deklarace . . . . . . . . . . . . . . . . . . . . 234
      ii)  Vrazy  . . . . . . . . . . . . . . . . . . . . . 235
      iii) Pkazy . . . . . . . . . . . . . . . . . . . . . 237
      iv)  Procedury a funkce  . . . . . . . . . . . . . . . 237
      v)   Soubory . . . . . . . . . . . . . . . . . . . . . 238
      vi)  Nov a bezpen . . . . . . . . . . . . . . . . . 239

Seznam pouit literatury  . . . . . . . . . . . . . . . . . 244

Seznam peddefinovanch procedur a funkc  . . . . . . . . . 246

Rejstk . . . . . . . . . . . . . . . . . . . . . . . . . . 251

VOD

     Turbo Pascal je v souasn dob u ns nejpouvanjm pro-
fesionlnm programovacm jazykem na osobnch potach. V
potaov vysplm svt je ji do jist mry vytlaen do
pozad jazykem C a hlavn uivatelsky orientovanm softwarem
(Oracle atp.). Pesto se domnvme, e se u ns bude jet
nkolik let pouvat (zatm m dl vc), a to s ohledem na:
-  Velkou rozenost mezi naimi programtory, a tedy i na
   dostatek informac o nm a dostatek pascalskho softwaru.
-  Uivatelskou pitalivost zabudovanho integrovanho sys-
   tmu.
-  Vuku Pascalu na naich stednch i vysokch kolch.

     Na naem trhu je sice ada uebnic programovn vetn ueb-
nic Pascalu, hor je to vak s nabdkou knih o Turbo Pascalu a
jsou-li njak, vtinou se omezuj na, eknme, "Zkladn kurs
Turbo Pascalu" a vztahuj se k verzi 3.0, v nejlepm ppad k
verzi 4.0.

     Pedloenou prac jsme se pokusili tuto mezeru vyplnit.

     Kniha je urena programtorm, a ji zanajcm nebo pokro-
ilm.
     Pedpokld, e ten ovld zkladn programovac techniky
a e um programovat v njakm jazyce, a ji je to Basic,
Pascal, Cobol, Fortran, nebo jin vy programovac jazyk. 
     Druhm, mn nutnm pedpokladem, je znalost operanho sys-
tmu MS DOS.


     Prce je urena nejirmu okruhu programtor, od zana-
jcch, a po velmi pokroil.

     Prce obsahuje mnoho daj, kter nejsou uvedeny ani v pro-
gramov pruce Turbo Pascalu, spolu s adou doporuen k
jejich pouit. Prce obsahuje minimum jednoduchch pklad,
nebo tch je spousta na distribunch disketch Turbo Pascalu
a jejich opisovn by zbyten zvtilo rozsah i cenu prce.
Pesto tu pklady jsou. Tkaj se vtinou nestandardnch pro-
gramovacch technik a sna se ukzat (leckdy za cenu obt-
nosti) jejich slu.

     Na konci kad kapitoly je uvedeno nkolik pklad a cvie-
n, kter Vm pomohou zopakovat si probranou ltku a zamyslet
se nad jejm obsahem.
Strun popime, co je obsahem jednotlivch kapitol:

II.dl
-  6.kapitola je vnovna Abstraktnm datovm strukturm. Popi-
   suje se v n prce s dynamickmi promnnmi, netypovanmi
   promnnmi, prce se seznamy, stromy atd. V dal sti je
   vnovna nemal pozornost novmu prvku Turbo Pascalu 5.5 -
   objektm a pot unitm. Zbytek tto kapitoly diskutuje pro-
   blematiku generovn nhodnch sel v Turbo Pascalu. Kapi-
   tola je urena pokroilejm programtorm, kte chtj
   vytvet rozshlej aplikace.
-  7.kapitola vyaduje jist znalosti o prci osobnho po-
   tae, nebo se zabv problematikou uloen dat, spoluprce
   s Dosem, spoutn proces, optimalizace pekladu atp.
-  8.kapitola pojednv o prci s periferiemi. Obsahuje zklad-
   n soubor pkaz pro jejich ovldn, pomoc nho me i
   mrn pokroil TurboPascalista vytvet pomrn pitaliv
   uivatelsk interface (barven obrazovky, windows, atd.).
   Vedle toho tato kapitola navazuje na kapitolu sedmou a popi-
   suje pouit nkterch slueb operanho systmu, kter
   vytvej ir prostor pro design Vaeho softwaru. Je to
   ale opt trochu obtnj.
-  9.kapitola popisuje prci s grafikou, a to od t nejjedno-
   du rovn a po rove Dosu.

Dodatky
-    Dodatek A obsahuje ASCII tabulku s rozenmi kdy.
-  Dodatek B obsahuje komentovan seznam chybovch hlen.
-  Dodatek C obsahuje odlinosti jednotlivch verz Turbo Pas-
   calu a strun nvody, jak implementovat nkter prvky jinch
   programovacch jazyk. Tento dodatek je vhodn zejmna pro
   ty, kte mnoho let pracovali v jinm jazyce a maj pocit, e
   ten Turbo Pascal vlastn nic neum. D se tak pojmout jako
   sbrka jednoduchch pklad.

    Jak ji vyplynulo z pehledu kapitol, prce se vnuje Turbo
Pascalu verzm 5.0 a 5.5, nebo je povaujeme za perspektivn.
Verze 5.5, vak dosud nen jet tak rozena, a proto vechny
pase vnujc se prvkm, kter jsou ve verzi 5.5 oproti verzi
5.0 navc, jsou vyznaeny svislou arou podl textu. Majitelm
verze 5.0 je doporuuji peskoit, aby nezvidli. PURE Pascal je 
kompatibiln s TP 5.5.

     Kniha je dost obshl, a tak jsme si prci rozdlili na MFF
UK takto: Kapitoly 1,4 a 8 sepsala Eva Novkov, kapitoly 2 a 9
Jana Vinov, kapitoly 3,6 a 7 spolu s dodatky Tom Ruba, na
5. kapitole pracoval Tom ehk z VCHT.6. Abstraktn datov struktury

     Pi prci s daty mnohdy narme na problem s jejich pevnm
rozsahu, nebo napklad vechna pole mus bt pedem deklaro-
vna i se svou velikost. Pomoc popsanch strukturovanch typ
se nelze rozsahem promnnch pizpsobit velikosti dat nebo
jinm okolnostem zjitnm a pi bhu programu. 
     Tento problm e dynamicky alokovan promnn (krtce
dynamick promnn), kter meme "vytvoit" a v okamiku, kdy
je skuten potebujeme.
     Vytven takovchto promnnch popeme v nsledujcm
odstavci. Ve druhm odstavci popeme nkter speciln obraty,
jako je prce s netypovanmi promnnmi, petypovn a adreso-
vn, pomoc nich lze prci s dynamickmi i statickmi promn-
nmi zefektivnit (za cenu bezpenosti programu).

     Tet odstavec je vnovn nkterm typickm obratm pi prci
s dynamickmi promnnmi jako jsou seznamy, stromy a mnoiny.
Tyto pojmy jsou zkladnmi stavebnmi kameny "Datov abstrakce",
kter je nezbytnm nstrojem modernho programtora. Turbo
Pascal 5.5 mylenku datov abstrakce dle rozvj formou objek-
tovho programovn, popsanho ve tvrtm odstavci. Nejvy
zatm dosaen stupe datov abstrakce je modulrn programo-
vn. O jeho mylenkch a zpsobech vyuit budeme hovoit v
odstavci ptm, kde popeme prci s pascalskmi "moduly" -
UNITami.

     Na zvr tto kapitoly zabrousme do svta nhod a popeme
prci s pseudonhodnmi sly v Turbo Pascalu.

6.1. Dynamick alokace

     Jak jsme ji ekli v vodu, dynamick promnn lze vytvoit
a tehdy, kdy je skuten potebujeme. Meme jich vytvet
prv tolik, kolik jich potebujeme. Nepotebn promnn lze i
zruit, tj. uvolovat msto, kter zabraj v pamti, abychom je
mohli pout pro dal promnn.

6.1.1. HEAP

     Realizace dynamickch alokac je velmi jednoduch. V kadm
programu je vyhrazena jist st pamti pro prci s dynamickmi
promnnmi. Pomoc specilnch funkc se zde alokuj (vyzna
se obsazen pamti) nov promnn a po pouit se zase uvoln.
Pro prci s nimi se pouvaj ukazatele a pointery, kter na n
odkazuj.
     sti pamti, ve kter jsou alokovny dynamick promnn, se
k HEAP (hromada, halda,...). Oproti jinm stem pamti nen
HEAP omezen na 64KB, nebo kad promnn, se kterou se v HEAPu
pracuje, je vdy adresovna plnou adresou (obvykle pomoc Extra
Segment ES). Z tohoto vak plyne jin omezen: "dn promnn
neme bt vt ne 64KB".

     Jak velk m bt HEAP? To je oek pmo pro Popelku. Zvis
na zvolenm algoritmu. Pokud nepouvme voln podproces (viz
7.4.), je rada jednoduch: "Co nejvt". V opanm ppad jej
musme udlat tak velk, aby nm stail a aby zbyl dostatek
pamti i pro volan podprocesy.
     Jak velk me bt? Nejmn 0 byt a nejve tolik, kolik
zbv voln pamti. Stejn jako pro zadvn velikosti zso-
bnku, existuj i pro zadn velikosti HEAPu parametry, kter
lze nastavit v integrovanm systmu, nebo na potku programu
pomoc direktivy kompiltoru {$M}. 
     Tato direktiva m ti parametry: 
-  Velikost zsobnku (o n jsme hovoili ji ve 3. kapitole).
-  Minimln velikost HEAPu. Toto je daj, kter popisuje ne-
   zbytn nutnou velikost pamti pro HEAP. Pokud se pokusme
   spustit program, pro jeho kd, data, zsobnk a takto speci-
   fikovan HEAP nebude dostatek pamti, dojde k chyb "Program
   too big to fit in memory".
-  Maximln velikost HEAPu. Tento daj specifikuje, jak nej-
   vt st pamti bude zabrna pro HEAP, bude-li j dostatek.
   Zbytek pamti zstane voln pro podprocesy. Je-li maximln
   velikost HEAPu vt ne velikost skuten voln pami, bude
   pro poteby HEAPu pouita cel voln pam.
Standardn nastaven tto direktivy je: {$M 16384,0,655360}.

     Kolik pamti me zbvat pro HEAP? To zle na dlce pro-
gramu a velikosti vnitn pamti. Pedpokldejme napklad tuto
konfiguraci: standardn nastaven pepnae M, 512KB vnitn
pamti a kratik program. Pot pro HEAP programu sputnho z
integrovanho systmu zbv asi 132KB a pi pmm sputn z
DOSu to je asi 432KB. Pi sputn z operanho systmu od-
startovanho z Turbo Pascalu pomoc "OS shell" zbv pro HEAP
programu 194KB (vimnme si, e to je vce ne pi sputn pod
integrovanm systmem, nebo program turbo.exe ped sputnm
novho COMMAND.COM uvoln asi 64KB pamti). Pi pamti 640KB
jsou tyto ho1noty o 128KB vy, tj. 260KB, 560KB a 322KB. 

6.1.2. Procedura NEW

     Pro vytven novch dynamickch promnnch slou procedura
NEW. V zkladn podob (pro objekty je sloitj) m tento
tvar:

Ŀ
    procedure NEW ( var P : pointer );                      


     Jej parametr je vstupnm parametrem. Provedenm tto pro-
cedury je alokovno msto pro promnnou, na ni odkazuje uveden
ukazatel (velikost alokovanho msta je urena z velikosti
pslun promnn) a skuten parametr po proveden alokaci
bude obsahovat adresu tohoto vyhrazenho msta, tj. adresu
dynamicky alokovan promnn.
     Protoe promnn typu pointer je odkazem na promnnou ne-
znmho typu, chpe se pro tento el jako ukazazatel na pro-
mnnou velikosti 0B. Pokud pouijeme NEW(P), kde P bude typu
pointer, nebude alokovn dn prostor a P bude odkazovat na
prvn neobsazen byte HEAPu.
     Napklad:

          var p:^real;
          begin new(p) end. { Alokuje 6 byt, na n odkazuje P. }

     Takto vytvoen promnn zabraj v datovm nebo zsobnkovm
segmentu pouze 4 byty potebn pro pslun ukazatel. Dynamick
alokace se proto vyuv tak pro sporu pamti (viz 3.4.)
Dal zpsoby pouit popeme dle.

     Pro flexibilitu jazyka lze ve verzi 5.5 pout new t jako
funkci:

Ŀ
    function NEW ( <id. typu> ) : pointer;                  


     Parametrem je identifiktor typu, jeho exempl m bt vy-
tven a vsledkem je ukazatel na vytvoen exempl. Nsle-
dujc sekvence jsou ekvivalentn:

     type MujTyp = ... ;           type MujTyp = ... ;
     var  P : ^MujTyp;                  var  P : ^MujTyp;
     begin ... New(P) ... end.  begin ... P:=New(MujTyp) ... end.

6.1.3. Uvolovn dynamicky alokovan pamti

     Pro uvolnn dve alokovan pamti lze pout dvou stan-
dardnch technik. Buto uvolovn jednotlivch promnnch, nebo
celho bloku promnnch.

     PROCEDURA DISPOSE

     Pro uvolnn promnn alokovan pomoc procedury New, na ni
odkazuje ukazatel P, slou procedura:

Ŀ
    procedure DISPOSE ( var P : pointer );                  


     Po proveden tto operace je uvolnno msto po pslun
promnn pro dal pouit, avak hodnota ukazatele nen zmn-
na! Je-li skuten parametr typu pointer, k uvolnn nedojde.
     Je-li parametrem ukazatel s hodnotou nil nebo ukazuje-li
mimo HEAP, dojde k bhov chyb "204 Invalid pointer operation".
     Je-li parametrem "nesprvn ukazatel", tj. ukazatel odkazu-
jc nkam do "HEAPu" je oblast, kter je jm urena, povaovna
za volnou a me bt pozdji piazena njak promnn a tedy i
mnna. Tedy pozor na "nestandardn operace" pi pouit Dis-
pose.

     Tento zpsob uvolovn pamti je pouvn zejmna tehdy,
kombinujeme-li vce typ dynamickch promnnch, jejich poty
jsou znan, a prce s nimi se proln.

     PROCEDURA MARK-RELEASE

     Pro uvolnn celho bloku promnnch slou dvojice procedur:

Ŀ
    procedure MARK ( var P : pointer );                     


     Tato procedura nealokuje dn msto v pamti a zape pouze
do skutenho parametru adresu poslednho volnho bytu (jako
procedura new proveden na pointer, avak jej kd je oproti new
o 18 byt krat a je mnohem srozumitelnj).
     Slou k oznaen msta v HEAPu pro pozdj smazn.

Ŀ
    procedure RELEASE ( var P : pointer );                  


     Tato procedura uvoln vechny promnn alokovan po oznaen
msta v HEAPu ukazatelem P. Tento ukazatel mohl vzniknout i
pomoc NEW, ale nedlejte to, program je potom patn iteln.
     Uvdomme si, e hodnoty ukazatel na tyto uvolnn promnn
nejsou zmnny, tj. ukazuj nkam, kde ji me bt nco jinho.

     Je-li parametrem nil nebo "nesprvn ukazatel", dojde k
uvolnn pamti od msta oznaenho ukazatelem (pi nil to
znamen od 0 - tj. potek pamti obsahujc vektory perue-
n...). Tedy stejn chyba jako u Dispose. Pozor na "odvn
operace s pointery".

     Pouit procedury RELEASE m velmi dleit omezen: "Proce-
duru RELEASE lze volat pouze tehdy, nebylo-li dosud pouito
procedury DISPOSE". Nen-li tato zsada dodrena, dojde k chyb,
kter nen hlena, ale m stejn nsledky jako DISPOSE na
"nesprvn ukazatel". Pesn vznik chyby plyne z mechanismu
uvolovn popsanho dle.

     Zpsob uvolovn pamti pomoc MARK-RELEASE se pouv v
lohch (zejmna na jejich potku ped prvnm DISPOSE), v nich
je na uritou dobu (nap. v procedue) poteba velk mnostv
dynamickch promnnch a po ukonen tto sti programu nejsou
ji dn z nich pouity.

6.1.4. Organizace HEAPu

     Tato st povdn je opt trochu sloitj a zatenk ji
me peskoit.

     Struktura HEAPu

     Cel HEAP je logicky rozdlen na ti oblasti: obsazenou,
volnou a seznam volnch oblast. Tyto oblasti jsou ureny temi
peddefinovanmi promnnmi:

     var FreePtr, HeapPtr, HeapOrg : pointer;

     Jejich vznam je nejlpe patrn z obrzku:

                Ŀ
                 Seznam volnch oblast 
      FreePtr Ĵ
                   Voln HEAP           
      HeapPtr Ĵ
                   Obsazen HEAP        
      HeapOrg 

     Nyn popime obsah jednotlivch oblast:
-  Obsazen oblast obsahuje ji alokovan promnn, ale i voln
   msta uvolnn pomoc DISPOSE. Posledn byte ped HeapPtr je
   vdy alokovn, je-li tato oblast neprzdn.
-  Voln oblast je neobsazena a je pipravena pro dal alokaci.
-  Seznam volnch oblast obsahuje seznam vech uvolnnch
   mst, kter jsou v obsazen oblasti. Tato oblast je popsna
   promnnou FreePtr, kter je de facto typu:
          FreePtr : ^array [1..16384] of 
                              record
                                   Low, { Ukazatel na zatek voln oblasti }
                                   High { Ukazatel na konec voln oblasti }
                                          : pointer
                              end;
     Segment FreePtr je po zahjen programu roven adrese
   poslednho plnho segmentu HEAPu. Adresa PTR(SEG(FreePtr^),
   $FFFF) je adresou poslednho bytu alokovanho pro program
   (resp. prvnho volnho). Oba ukazatele jsou normovny.
     Je-li seznam przdn, je offset roven $0000. Je-li ne-
   przdn, odkazuje offset na potek seznamu volnch mst (pi
   jedn uvolnn oblasti to je $FFF8, pi dvou $FFF0, pi tech
   $FFE8, atd.).
     Je-li seznam naplnn, tj. offset ji opt obsahuje $0000
   (seznam m 16384 volnch mst), je pi dalm uvolnn na-
   plovn opt odshora a daje o zbylch fragmentech jsou
   ztraceny. Tato situace nen nijak indikovna, ale je tak
   nepravdpodobn, e se o ni tm nikdy nemusme starat.

     Te se vrame k procedurm new, dispose a release a popime
jejich innost z hlediska prce s oblastmi HEAPu:

     Procedura New

     Procedura se pokou nalzt blok vhodn velikosti. Pokud
bychom chtli pedem vdt, zda existuje, nebo kolik jet zbv
v HEAPu volnho msta, meme pout tyto funkce:

Ŀ
    function MemAvail : longint;                            


     Vrac celkovou velikost volnch st HEAPu.

Ŀ
    function MaxAvail : longint;                            


     Vrac velikost nejvt voln souvisl oblasti v HEAPu.

     Procedura NEW nejprve prohledv seznam volnch oblast. Na-
lezne-li zde dostaten velkou oblast, vezme prvn takovou a
alokuje ji. Je-li oblast vt, ne poadovan, uprav pslu-
nm zpsobem seznam volnch oblast; je-li stejn velk, vynech
tuto oblast ze seznamu a vechny zznamy o "pozdji uvolnnch"
oblastech spolu s FreePtr posune o 8 byt k vym adresm.
     Z toho plyne, e astm stdnm NEW a DISPOSE na promnn
trochu jinch velikost vznik v HEAPu velk FRAGMENTACE, tj.
mal nevyuit kousky pamti.

     Nenalezne-li volnou oblast v seznamu, podv se na velikost
hlavn voln oblasti. Je-li dostaten, alokuje pslun msto
zvenm HeapPtr o patin poet byt.

     Pokud v celm HEAPu neexistuje dostaten velk souvisl
voln kus pamti, dojde k chyb 203 "Heap overflow error".
     Pi vzniku tto chyby se lze pokusit o zchranu pomoc funk-
ce, kterou si sami napeme a v n HEAP potebnm zpsobem
uvolnme. Pro psan tto funkce, plat nsledujc zsady:
-  Adresa vstupnho bodu tto funkce mus bt uloena do ped-
   definovan promnn

            var HeapError : pointer;

     jej implicitn hodnota je nil.
-  Funkce mus bt volna jako FAR.
-  Funkce mus mt jeden vstupn parametr volan hodnotou typu
   word, do nho je pi voln uloena velikost promnn,
   kterou chceme alokovat.
-  Funkce mus bt typu integer, piem vsledek bude inter-
   pretovn takto:
          0 = oprava se nezdaila, dojde k chyb 203.
          1 = oprava se nezdaila, ale k bhov chyb dojt nemus, 
          me vrtit nil (nap. viz 6.4).
          2 = msto bylo uvolnno, zkus znovu alokovat!
Tato funkce by mohla vypadat takto:

          {$F+}
          function HE ( Size : word ) : integer;
          {$F-}
               begin
               writeln('Je poteba alokovat poloku velikosti ',Size);
               release(HeapOrg); { Vyprzdn cel HEAP }
               if MaxAvail<Size then
                    begin
                    writeln(', ale s takhle malou pamt to nejde.');
                    HE:=0;
                    end
               else
                    begin
                    writeln(', tak jsem vyklidil cel HEAP');
                    HE:=2;
                    end;
               end;
          begin
          HeapError:=@HE;
          ...

     Je-li HEAP zaplnn, meme chtt v HeapError procedue n-
kter zznamy uvolnit pomoc DISPOSE. To se nm vak nemus
podait, nebo nelze posunovat ani FreePtr (HEAP je pln), aby-
chom do seznamu volnch oblast mohli zaadit 8 byt pro ozna-
en uvolnn oblasti.
     Abychom tomuto mohli pedejt, je peddefinovna promnn:

               var FreeMin : word ;

kter uruje, kolik byt m zstat volnch mezi HeapPtr a
FreePtr. Implicitn hodnota je 0. Tato hodnota je uvaovna
vdy pi alokaci dal pamti (a pi voln funkc MemAvail,
MaxAvail) a pokud by po alokaci zbvalo mn, je vyvolna funkce
uren ukazatelem HeapError (resp. dojde k chyb 203).

     HeapError procedury lze napklad vyut k vytvoen vlast-
nho istie pamti (Garbage Collector), kter nen standardn
v Turbo Pascalu zabudovn.

     Procedura DISPOSE

     Je-li uvolnna oblast tsn pod HeapPtr, je uvolnn prove-
deno snenm tohoto pointeru o pslun poet byt a k prvn-
mu obsazenmu pamovmu mstu (ppadn voln sti pamti
zahrnut nyn do voln oblasti jsou vyazeny ze seznamu volnch
oblast).
     Je-li uvolnna oblast uvnit obsazen oblasti v sousedstv
jin voln oblasti, jsou tyto oblasti spojeny a tvo jednu
volnou oblast v tabulce volnch oblast pslun "soutov"
velikosti.
     Je-li uvolnna oblast uvnit obsazen oblasti a nesoused-li
pitom s jinou volnou oblast, je tato oblast pidna do seznamu
volnch oblast.

     Procedura RELEASE

     Tato procedura nastav HeapPtr na hodnotu svho parametru.
Hodnoty v seznamu volnch oblast nemn, proto tedy nelze
kombinovat RELEASE a DISPOSE.

     Promnn

     Promnn FreePtr, HeapPtr, HeapOrg jsou normln promnn,
kter lze st, pedvat jako parametry (to se me hodit pro
assemblersk podprogramy) atp.

     Lze tak mnit jejich hodnoty. Nenapad m vak jedin ro-
zumn dvod k tomu, abych to dlal, nebo vsledek bude jist
zajmav...

6.2. Mocn nstroj "pointer"

     S vyuitm dynamickch promnnch lze provdt mnoh kouzla s
pamt znm v assembleru. K tmto trikm je poteba pistupovat
s co nejvt opatrnost, nebo vtina chyb pi takovchto
obratech vede k zabloudn programu a k dsledkm, o nich jsme
ji hovoili na konci tet kapitoly.
     Popeme zde prci s netypovanmi promnnmi, zpsob jejich
petypovn a zskvn jejich pmch adres.
     Pouit tchto mechanism budeme nakonec demonstrovat na
efektivnm zpsobu implementace dynamickch pol.

6.2.1. Netypovan promnn

     Netypovan promnn jsou promnn reprezentovan pointerem,
kter odkazuje na sek pamti, o jeho struktue a dlce nen
implicitn nic znmo. Prci s takovmito promnnmi mus pln
obhospodait programtor. S ohledem na segmentovou strukturu
pamti mohou bt i tyto promnn velk nejve 64KB.

     Pouit

     Netypovan promnn jsou nejastji pouvny v tchto p-
padech:
-  Netypovan parametry jsou vlastn inicializovan netypovan
   promnn. Pouvaj se pi prci se zznamy rzn struktury
   (tdc algoritmy, vyhledvn, vypisovn zznam, algo-
   ritmy pro prci s grafy atp., pokud chceme zabezpeit dosta-
   tenou obecnost procedur) a pi prci s poli promnn dlky
   (viz dynamick pole v odstavci 6.2.4.), kde je lze vyut v
   mnoha obecnch algoritmech.
     Netypovan parametry lze najt i u nkolika standardnch
   procedur nap. BlockRead, SetTextBuf, GetImage atd.
-  Dynamick netypovan promnn realizujc dynamick pole (viz
   6.2.4), vyrovnvac pamti, ukldn st obrazovky atd.

     Pi tomto ten se Vm jist vybav otzka, zda-li skuten
jde o nco tak pevratnho, nebo zda-li se bez takovchto pro-
mnnch obejdeme. Teoreticky se obejdeme, nebo ve lze nahradit
nap. seznamem byt (viz 6.3), avak prakticky je prce s tmito
promnnmi jak co do pracnosti, tak co do vsledn rychlosti
mnohem efektivnj. Musme si vak stle opakovat, e je teba
dbt zven opatrnosti, nebo ppadn chyby maj nedozrn
nsledky.

     Vytvoen

     Pokud chceme alokovat novou netypovanou promnnou, nevysta-
me s procedurou NEW. Potebujeme proceduru dal, kter alokuje
pam takov dlky, kolik si explicitn ekneme (do 64KB) a
odke na tento sek pamti v HEAPu pointerem, kter je jejm
skutenm parametrem.
     Takovou procedurou je:

Ŀ
    procedure GetMem ( var p : pointer; Size : word );      


     Prce tto procedury je zcela analogick innosti procedury
NEW (vetn ppadnho voln funkce HeapError). Parametrem vak
me bt libovoln pointer a velikost alokovan oblasti je
urena parametrem Size.

     Pro uvolnn alokovan pamti slou procedura:

Ŀ
    procedure FreeMem ( var p : pointer; Size : word );     


kter je protjkem procedury DISPOSE.
     Pracuje zcela analogicky jako procedura DISPOSE s tm, e
uvoln tu oblast v HEAPu, na ni odkazuje pointer a je m
uvedenou dlku. Je velmi dleit, aby dlka uvolovan oblasti
byla STEJN jako dlka oblasti pi vytven. Pokud bude krat,
zstane zbytek alokovn. Pokud bude del, me bt uvolnna i
st sousedn oblasti a dsledky si ji jist umte pedstavit.

     Pedan netypovan parametr sm o sob je zcela k niemu,
nebo s nm neumme nijak manipulovat. Potebujeme obvykle jeho
dlku. Je tedy nutnm zvykem, e pi pedvn netypovanch
parametr je jako dal parametr pedvna i jeho dlka. 
     Co kdy chceme takovouto proceduru pout pro njakou roz-
shlou promnnou se sloitou strukturou? Musme se posadit, pln
se soustedit a potat byte po bytu, abychom mohli pesn urit
velikost pedvan promnn? Nikoli. Tvrci jazyka ns tto
innosti uetili a zavedli funkci:

Ŀ
    function SizeOf ( <promnn nebo typ> ) : word;         


     Tato funkce vyd velikost promnn, resp. promnn danho
typu, kter je jejm parametrem, v bytech. Pouvejte tuto funk-
ci, kdykoli pjde o velikost njak promnn. Pokud byste nkdy
strukturu tto promnn opravili, museli byste tyto daje pepo-
tvat, a to vbec nemyslm na katastrofy, kter by vznikaly
pi chybnm vpotu.

     Piazovn

     S netypovanmi promnnmi lze pracovat bnmi prostedky
pouze tehdy, kdy je petypujete (viz 6.2.2). To vtinou lze,
pokud chcete pracovat s jejich stmi (viz 6.2.4.). Hor je to
ji s piazovacm pkazem. Proto namsto nj byla implemen-
tovna velmi efektivn procedura (jde o jednu strojovou in-
strukci):

Ŀ
    procedure Move ( var Source, Dest; Count : word );      


     Tato procedura penese od prvnho bytu promnn Source celkem
Count byt na pamov msto uren prvnm bytem promnn Dest.
Penen i clov oblast se mohou libovoln pekrvat, ani by
to ohrozilo vsledek penosu.
     Vimnme si, e zde nejsou parametry typu pointer, ale pmo
promnn. Tato efektivn nestandardn procedura je velmi vhodn
i pro posuny poloek v polch.
     Napklad:

          type RefByte = ^ byte;
          var  a : array [ byte ] of char;
                 x,y : record ... end;
                 p,q : pointer;
          begin ...
               Move(x, y, SizeOf(x))   { Piazen zznam };
               Move(a[3], a[9], 246)   {Posun textu v etzci znak 
                                   od 3. psmene o 6 vpravo };
               GetMem( p, 2000 );  ...  ;
               GetMem( q, 2000 );  ...  ;
               Move( RefByte(p)^, RefByte(q)^, 2000 )
                                                     {Piazen netypovanch pro-
                                   mnnch pomoc petypovn
                                   (viz 6.2.2) };
          end.

     Konstanty netypovanch promnnch samozejm neexistuj.
asto je vak poteba inicializovat njakou (obvykle netypova-
nou) promnnou jednm znakem v celm jejm rozsahu. K tomuto
elu slou procedura:

Ŀ
    procedure FillChar ( var x; Count : word; CH : char );  


     Tato procedura napln Count byt pamti znakem CH, ponaje
prvnm bytem promnn x.

     Ze zejmch dvod je u obou tchto procedur poteba vnovat
velkou pozornost potu penench byt. Chyby jsou jinak kata-
strofln a velmi obtn se hledaj.

6.2.2. Petypovn

     Petypovn je takov prava vrazu, pi n nen zmnna
bitov reprezentace vrazu, ale jej interpretace. Syntaxi
petypovn pipomeme nkolika pklady:
     byte('A')   longint(34242)   pointer($000F) ...

     Jak jsme ekli dve, vraz lze petypovat pouze takovm
typem, kter m stejnou dlku jako typ petypovvanho vrazu
nebo tehdy, je-li nov typ i petypovvan vraz ordinlnho
typu.

     Tento fakt lze obejt pomoc ukazatel, jak ukeme v dalm
odstavci.
     Petypovan vraz m tedy stejnou hodnotu, ale nov typ. U
ordinlnch vraz nestejn dlky jsou zleva doplnny nuly,
resp. pebyten byty zleva odznuty. Napklad: byte(256)=1;
word(2)=2; longint('A')=chr('A'); boolean(x)=(x mod 256 > 0).

     Uveme nkolik typickch pklad pouit tohoto nestan-
dardnho postupu:

-  Pstup k poloce uveden ordinality. Pouit je podobn jako
   u funkce Chr u typu char.

-  Zvten rozsahu mezivsledku, pekrauje-li rozsah slova
   (viz 3.1.2.). Napklad: 

          var x:word; begin x:=40000; writeln(40000+longint(x)) end;

-  Pijet netypovanho parametru. Pokud jsme pmo schopni
   urit typ pijatho parametru, je lep pracovat s nm jako s
   typovanm. Znme-li strukturu a dlku, pouvme petypovn
   k zskn poloek pijatho parametru (viz dle).

-  Redefinice promnn. Tento pojem je velmi blzk programto-
   rm v Cobolu nebo assembleru. Jde o "jin pohled" na stru-
   kturu promnn. Tohoto obratu nedoporuuji uvat pro re-
   definovn zznam (k tomu slou variantn zznamy) a pol.
   Existuje ale jedna aplikace, u n je pouit redefinice
   velmi vhodn. Jde o identifikovn bit v rmci bytu. S tmto
   problmem se setkme, kdykoli zaneme pracovat s promnnmi
   operanho systmu. Jako pklad uveme prci s atributy
   znaku z klvesnice (viz kapitola 8):

      type Bity = ( RightShift, LeftShift, Ctrl, Alt,
                              ScrollLock, NumLock, CapsLock, InsertLock );
                 Status = set of Bity;
          var stav : byte;
          begin   ... 
                    stav :=...;{Piazen stav klvesnice (viz. kap. 8)}
                    if [Ctrl,Alt] <= Status(stav) then ...; 
          end.

-  Pstup k netypovanm promnnm formou masky pamti. Tohoto
   obratu se nejastji uv u dynamickch pol, ale tak u
   netypovanch parametr, chceme-li s nimi pracovat byte po
   bytu. 
     Zkladn mylenkou je vytvoen napklad takovhoto typu:
               type Maska = array [ byte ] of byte;
                    RefMaska = ^Maska;
   Pomoc tohoto typu lze pot pistoupit k osmmu bytu promnn
   X takto:      RefMaska(@X)^[7].

6.2.3. Adresa

     O adrese jsme ji tak hovoili a vme, e unrn opertor 
"@" aplikovan na promnnou vydv jej adresu a pi pouit na
podprogram vydv vstupn bod tohoto podprogramu. Vsledkem
tohoto opertoru je normovan adresa typu pointer.
     Co se stane po proveden tohoto opertoru na promnnou typu
podprogram? Odpov je jednoznan, jde o vstupn bod pslu-
nho podprogramu. Chceme-li zskat adresu tto podprogramov
promnn, musme opertor @ aplikovat dvakrt. Nap.:

          var P : function : real;
              @P  - vstupn bod funkce
                @@P - adresa promnn P

     Pokud by se nkomu nelbilo pouit neobvyklho opertoru
"@", me msto nj pouvat funkci:

Ŀ
    function Addr ( <promnn> ) : pointer;                 


     Tato funkce m pln stejn vznam jako opertor "@".

     Povimnme si opt zkladnch obrat pi prci s adresami:

-  Pedvn procedurlnch parametr podprogramm psanch v
   assembleru je mon pouze pomoc pedn adresy vstupnho
   bodu (viz kapitola 7).
-  Pedvn procedurlnch parametr podprogramm ve verzi 4.0 
   je takt mon pouze pomoc vstupnho bodu. Voln takov
   procedury je pot realizovno pomoc INLINE procedury (viz
   kapitola 7).
-  Petypovn nestejnch dlek. Pokud je poteba provst pe-
   typovn dvou typovanch promnnch rzn dlky, lze to
   realizovat pomoc jejich ukazatel asi takto:
          type A=...; B=...; RefA=^A;
          var  aa:a;  bb:b;
          begin bb:=...;
                    aa:= RefA ( @ bb ) ^ ; { Dynamick petypovn }
          end.
-  Petypovn poloek uvnit strukturovan promnn. Jde o
   nejnestandardnj operaci, kter jet me mt vznam (viz
   piazen etzce do znakovho etzce v odstavci 3.1.2.).
   Nap.
               type A = array [1..6] of byte;
                      RA= ^A; 
               var  x : array [0..72] of
                                   record Info, Value : word end;
                      xa:A;   
               begin ...
                    xa:=RA(@x[11].Info)^;
                         ...
               end;

6.2.4. Dynamick pole

     Mnohokrte probranou nevhodou Pascalu je nezabudovn
mechanismu dynamickch pol. Jde o to, abychom mohli vytvoit
pole, a ho budeme potebovat a teprve v tomto okamiku urit
jeho rozmry. Obvykle se jedn o lokln pole, jejich velikost
by mla bt urena na zklad vstupnch parametr podprogramu.
     Tato problematika byla sten eena v nvrhu Normy jazyka
verze 1., kam oproti verzi 0. byla dodna tzv. KONFORMN POLE.
     Ani toto rozen problm nee, a tak nebylo do jazyka
Turbo Pascal vbec zahrnuto. Prostedky netypovanch promnnch
jsou natolik siln, e nm spolehliv posta k vybudovn
dynamickch pol.

     Dynamick pole opt nejsou nevyhnuteln, ale s jejich pou-
itm se zefektivn programovn i rychlost vpotu. I zde je
ale teba zachovvat zvenou opatrnost, nebo kad chybika
se mnohonsobn vymst (vdy se budeme pohybovat mezi netypo-
vanmi promnnmi).
     Dynamick pole se hod pro tvorbu obecnch algoritm pro
prci s maticemi (tedy i s grafy). Vhodn jsou i pro tvorbu
seznam s vyhledvnm podle indexu atd.

     Nyn procvime probranou ltku na nkolika pkladech v-
cch se k dynamickm polm.

   Mylenka implementace Dynamickho pole je podobn jako pi
   pouit masky:

          const Max = 16380 {65520/4};
          type Zaznam = record
                                   Key,Info:word;
                                end;
                 Meze = 1..Max;
                 Pole = array [ Meze ] of Zaznam;
                 Dynamic = ^Pole;
                 DynArr = record
                                     D : Dynamic;
                                     M : Meze
                                end;

          procedure Sort ( var X : DynArr );
               { Bublinkov tdn }
               var i,j : Meze;
                     Z : Zaznam;
             begin
               with X do 
                    begin
                    for i:=1 to M-1 do
                         for j:=i+1 to M do
                              if D^[j].Key>D^[j-1].Key then 
                                    begin 
                                    Z:=D^[j]; 
                                    D^[j]:=D^[j-1];
                                    D^[j-1]:=Z 
                                    end;
                    end; 
               end { Sort };

          procedure Make ( var X : DynArr; N : word );
               { Vytvo poadovan dynamick pole velikosti N }
               begin
               with X do 
                    begin
                    M:=N;
                    GetMem(D,SizeOf(Zaznam)*N);
                    FillChar(D^,SizeOf(Zaznam)*N,#0); { Vynuluje pole }
                    end;
               end { Make };
          ...  

     Na uvedenm pkladu jsme demonstrovali zpsob prce s dyna-
mickmi poli, jejich velikost nepesahuje 64KB. Pokud potebu-
jeme pole vt, je poteba pistoupit k realizaci pomoc tzv.
"pointeru na pole pointer":

          const Max = 16380 {65520/4};
          type Zaznam = record
                                   Key  : word;
                                   Info : string[80]
                                end;
                 RefZaznam = ^ Zaznam;  
                 Meze = 1..Max;
                 Pole = array [ Meze ] of RefZaznam;
                 Dynamic = ^Pole;
                 DynArr = record
                                     D : Dynamic;
                                     M : Meze 
                                end;

     Je jasn, e se tm zkomplikuje pstup k polokm, ale stle
je to lep ne vytvet njak seznamy.

     Pokud bychom chtli napsat obecnou tdc proceduru pro
libovoln zznamy obsaen v dynamickm poli, vypadalo by to asi
takto:

          const Max = 16380 {65520/4};
          type Meze = 1..Max;
                 Pole  = array [Meze] of pointer;
                 Dynamic = ^Pole;
                 DynArr = record 
                                     D : Dynamic; 
                                     M : Meze 
                                end;

          procedure Sort ( var X : DynArr; KeyPos : byte );
               { Bublinkov tdn }
               type Maska = array [1..255] of char; {  Existuje   }
                                                                  {  uspodn }
                      _Pole  = array [Meze] of ^Maska;
                      _Dynamic = ^_Pole;
                 _DynArr = record 
                                             D : _Dynamic; 
                                             M : Meze  
                                        end;
               var i,j : Meze;
                     Z : pointer;
             begin
               with _DynArr(X) do 
                    begin
                    for i:=1 to M-1 do
                         for j:=i+1 to M do
                              if D^[j]^[KeyPos] > D^[j-1]^[KeyPos] then
                                    begin
                                    Z:=D^[j]; 
                                    D^[j]:=D^[j-1];
                                    D^[j-1]:=Z 
                                    end;
                    end;
               end { Sort };

     Podmnka u IF pkazu v tomto pkladu je skuten dost
sloit. Pokud Vm nen moc jasn, tak si z toho nic nedlejte,
s trochou praxe budete asem tvoit jet hor vci.

     Dynamick pole nemohou bt vt ne 16380 poloek. Toto
omezen vak nen pli podstatn. Uvdomme si, e v poli
budeme uchovvat njak data. Ji pi nepatrn velikosti uchov-
vanch zznam 10B, zabr onch 16380 zznam celkem 16380 * (
10 + 4 ) = 229KB, co je obvykle vce ne operan pam pi
bhu programu pod integrovanm systmem me pro HEAP poskyt-
nout.

     Jet jedna poznmka, pokud dynamick pole naplujete jedno-
rzov a mte dostatek pamti, je mon alokovat plnou velikost
pole a po naplnn zbytek pole uvolnit pkazem FREEMEM. Tento
postup je velmi efektivn, zejmna pi "natn soubor do
pamti", ale pi uvolovn je poteba dbt zven opatrnosti,
nebo chybn vpoet dlky voln sti pole by mohl vst ke
katastrof. Uvolovac pkaz by vypadal asi takto:

     var X : DynArr; ... { DynArr je popsn ve }
     FreeMem ( @ X.D [LastRecord+1], (Max - LastRecord) * 4 );

6.3. Abstraktn datov struktury

     Pi tvorb mnohch program eench tmy programtor, jen
st vystame s klasickmi programovacmi metodami (jakou ji
nyn je strukturovan programovn probran ve 3. kapitole).
Souasn trend smuje k objektovmu a modulrnmu programovn.
Zkladnm stavebnm kamenem obou tchto pstup, kter budou
popisovny v 6.4. a 6.5., je datov abstrakce.
     Tento pojem je pro modernho programtora velmi dleit.
Akoli vlastn definice, jak je dle uvedena, je velmi jedno-
duch, bv aplikace tohoto pojmu leckdy algoritmicky dosti
nron, pesto vak podceovan.
     Kdo si s vybalancovanmi stromy tyk a hauje i ze span,
me pokraovat a od 6.4., nebo v tomto odstavci se o Pascalu
nic novho nedov. Pro ns ostatn je tento odstavec jakousi
sbrkou pklad s dosti nronou tmatikou z oblasti infor-
matiky, na n si dostaten procvime dosud probranou ltku.

6.3.1. Od promnn k modulu

     Ji od potaov prehistorie existuj celoseln promnn.
Praxe si vak vydala zaveden promnnch etzcovch, logic-
kch atd. Byl tak zaveden DATOV TYP jako mnoina hodnot pro-
mnn, jak jsme jej diskutovali v pedchozch kapitolch.

     Dal vvoj ukzal, e je uiten data spojovat do vtch
celk. Hovome o DATOV STRUKTUE. Jde zejmna o zznamy a pole
(viz 2.).

     O pr dn pozdji si lid vimli, e k nkterm datovm
strukturm jaksi "pat" nkter procedury a funkce. Jde o ty
procedury, kter realizuj prci s pslunmi datovmi stru-
kturami (ukldn, mazn, inicializace, propoty, atd.). To u
ale pedn teoretici vydvali sv knihy, v nich se objevuje
pojem ABSTRAKTN DATOV STRUKTURA (ADS).

     ADS je matematick model objektivn reality se seznamem
operac definovanch nad tmto modelem. Je realizovn datovou
strukturou a seznamem odpovdajcch procedur. Jsou-li data i
procedudy ADS syntakticky spojeny do jednoho celku (objekt,
modul), hovome o ABSTRAKTNM DATOVM TYPU.

     Vrame se jet do historie a pipomeme, jak byla dve
obchzena absence ukazatel. Velmi jednodue, namsto HEAPu se
deklarovalo pole (pro kadou promnnou jedno) a "adresou" prvku
zde byl index tohoto prvku. Ukazatel byl suplovn celoselnou
promnnou, tzv. KURZOREM.

     Abychom se mohli vyjadovat o rychlostech jednotlivch algo-
ritm, zavedeme jet tento pojem: "Algoritmus pracujc s N
daty pracuje rychlost O(f(N)), pokud existuje konstanta C,
takov, e pro kad dostaten velk N trv bh celho programu
mn ne dobu C*f(N)". Konstanta C zhruba odpovd dob zpraco-
vn tla cykl. Namsto "pracuje rychlost O(f(n))" se nkdy
pouv: "je sloitosti O(f(n))" nebo "pracuje v ase O(f(n))".
     Budeme-li v souvislosti s tmto pojmem pouvat logaritmu
(log), pjde o logaritmus pi zkladu 2.

     Umluvme se jet pro tuto kapitolu, e vechny zznamy sdru-
ovan pomoc njak ADS, budou pro jednoduchost obsahovat
jedin informan daj: " Info : byte ".

     Nyn jsme vybaveni dostatenou zsobou termn, abychom se ve
svt informatiky neztratili.

6.3.2. Seznamy

     Seznam je takov ADS, kter obsahuje jist poet zznam
linern uspodanch.

     Nad seznamy mohou bt definovny zejmna tyto operace:
-  ADD(Info) = Pid specifikovan zznam na konec/zatek
   seznamu.
-  INSERT(Info,Position) = Zaad specifikovan zznam na uvede-
   nou pozici v seznamu.
-  DELETE(Position) = Smae specifikovan zznam na uveden
   pozice.
-  LOCATE(Info) = Vyhled zznam pro aktualizaci, pokud exi-
   stuje, tj. jeho pozici nebo ukazatel na nj.
-  NEXT(Position), PREVIOUS(Position) = Vyhled nsledujc,
   resp. pedchoz zznam v danm uspodn.
-    MAKENULL = Vytvo przdn seznam.
-    FIRST = Vyhled prvn zznam v danm uspodn.
-    PRINTLIST = Vytiskne vechny zznamy v pslunm uspodn.
-    CONCAT = Spoj dva seznamy v jeden.
-  SPLIT = Rozdl seznam na dva (podle poad ukldn).

     Posledn dv operace nepat do standardnho seznamu procedur
pracujcch se seznamy a vyskytuj se pouze v nkterch aplika-
cch.

     Budeme-li realizovat njakou ADS, musme si vdy uvdomit,
kter procedury budeme pouvat asto, kter ojedinle a kter
vbec ne. Podle toho si potom vybereme nkter z monch zpsob
implementace. 
     Nejpouvanj zpsoby reprezentace seznam jsou tyto:

     Pole

          const
               MaxLength = 100 {Vhodn konstanta};
          var  List : record
                                   Info : array [1..MaxLength] of byte;
                                   Last : word;
                               end;

ADD   - Je-li poet prvk seznamu <= MaxLength, pracuje v ase
      O(1). Dal prvky ji nelze pipojit. Vimnme si, e tuto
      situaci nezachrn ani dynamick pole.
INSERT - pracuje v ase O(n) (vlo prvek a ostatn odsune).
DELETE - pracuje v ase O(n) (vymae prvek a ostatn pisune).
      Vimnme si, e ob tyto procedury lze velmi dobe imple-
      mentovat (v podstat v O(1)) pomoc Move napklad takto:
               procedure Delete ( Position : word );
               begin
                    with List do 
                         begin
                         if (Position<1) or (Position>Last) then ERROR;
                         Move( @Last[Position+1], @Last[Position],
                                   (Last-Position) * SizeOf(byte) );
                         Dec(Last);
                         end
               end;
LOCATE - pracuje v ase O(n) (prohledv postupn jednotliv
          prvky seznamu).
NEXT, PREVIOUS, MAKENULL, FIRST - pracuj v ase O(1).
PRINTLIST - projde cel pole, take sloitost je O(n).
CONCAT, SPLIT - lze nejlpe realizovat koprovnm, co mimo
      sloitosti O(n) zabr i dvojnsobek pamti. Pouit tto
      implementace pro tyto procedury je nevhodn.

     Spojov seznamy

          type
               RefZaznam = ^ Zaznam;
               Zaznam = record
                                   Info : byte;
                                   Next : RefZaznam;
                              end;
          var List : RefZaznam;

     Graficky lze tuto strukturu znzornit takto:

       Ŀ  Ŀ  Ŀ  Ŀ
        1   o> 2   o> 3   o> 4   o>
             

ADD - Pidn na zatek pracuje v ase O(1):
               procedure Add(Info:byte);
               var RZ:RefZaznam;
               begin
                    new(RZ);
                    RZ^.Info:=Info;
                    RZ^.Next:=List;
                    List:=RZ;
               end;
INSERT - Mus nalzt pslunou pozici, take je sloitosti
      O(n).
DELETE - Prohled v nejhorm ppad cel seznam a nalezen
          zznam vypust, opt sloitost O(n):
               procedure Delete(var RZ:RefZaznam);
               var pos, last : RefZaznam;
               begin
                    if List=nil then ERROR;
                    if List=RZ then List:=List^.Next
                    else
                         begin
                         pos:=List^.Next;
                         last:=List; { o jeden zznam pozadu }
                         while pos<>nil do
                              if pos=RZ then
                                   begin
                                   last^.Next:=pos^.Next; { vlastn DELETE }
                                   Dispose(pos);
                                   pos:=nil; { konec cyklu }
                                   end;
                              else
                                   begin
                                   last:=pos; { posun po seznamu }
                                   pos:=pos^.next
                                   end;
                         end;
               end; { Delete }
LOCATE - pracuje podobn jako DELETE, (dn prvek vak nevy-
          pout), take pracuje v ase O(n).
NEXT - pracuje v ase O(1). Provede "RZ:=RZ^.Next".
PREVIOUS - podobn jako delete mus najt pedchdce (v nejhor-
      m ppad) prochzenm celho seznamu s ukazatelem o
      jednu pozici pozadu. Sloitost je O(n), tj. vt neli u
      NEXT.
MAKENULL - uvoln vechny zznamy a potom piad List:=nil.
      Dky prochzen celho seznamu je sloitost O(n). Respe-
      ktive vytvo przdn seznam - O(1).
FIRST - pracuje v ase O(1), nebo FIRST:=List.
PRINTLIST - v ase O(n) projde cel seznam.
CONCAT - Projde prvn seznam a pipoj za nj druh. (O(n))
SPLIT - V urenm mst vytvo nov ukazatel a pedchdce
      odke na nil, k emu potebuje projt prvn st se-
      znamu, take rychlost bude O(n).

     Dvousmrn spojov seznam

          type
               RefZaznam = ^ Zaznam;
               Zaznam = record
                                   Info : byte;
                                   Last, Next : RefZaznam;
                              end;
          var List : RefZaznam;

     Graficky lze tuto strukturu znzornit takto:

       Ŀ  Ŀ  Ŀ  Ŀ
        1 oo> 2 oo> 3 oo> 4 oo>
       <<<   
                         

     Implementace procedur je vtinou analogick jednosmrnmu
spojovmu seznamu. Procedury PREVIOUS a SPLIT nemus prochzet
seznam, aby byl nalezen pedchdce danho prvku, m se zrychl
na O(1). Procedury INSERT a DELETE se podstatn zjednodu,
nebo nen teba "pamatovat si pedchdce".
     Pro ilustraci popeme proceduru pro vkldn:
               procedure INSERT(NewInfo:byte);
               var pos, pam : RefZaznam;
               begin
               if List=nil then
                    begin  { Seznam je przdn }
                    new(List);
                    with List do
                         begin
                         Info:=NewInfo;
                         Next:=nil;
                         Last:=nil
                         end
                    end
               else
                    begin
                    pos:=List;
                    while (pos^.Next<>nil) and (pos^.Info<NewInfo) do
                         pos:=pos^.Next;
                    if pos^.Info<NewInfo then pam:=nil
                    else
                         begin
                         pam:=pos; { Nov nslednk }
                         pos:=pos^.Last; { Nov pedchdce }
                         end;
                    if pos=nil then
                         begin { Nov zznam je men ne ostatn }
                         new(List);
                         with List do
                              begin
                              Info:=NewInfo;
                              Next:=pam;
                              Last:=nil
                              end
                         end
                    else
                         begin { Nov zznam bude alespo druh }
                         New(pom^.Next);
                         with pos^.Next do
                              begin
                              Info:=NewInfo;
                              Next:=pam;
                              Last:=pos;
                              end;
                         end;
                    end;
               end; { Insert }

     Kurzorov seznam

     Jde o pole, piem jednotliv jeho prvky jsou provzny
pomoc kurzor (sla index nslednka, resp. pedchdce).

          var
               List : array [1..MaxLength] of
                              record
                                   Info : byte;
                                   Next, {Last} : word; 
                              end;

                    Info            Next
         ͻ
       1. 112 {Prvn}     n  oĿ
         Ķ    
       2.   4 {Tet}    12 ...<Ŀ 
         Ķ   
               :            :       
       n.   9 {Druh}     2  o <
         ͼ  
                               

     Pro implementaci seznam nen vhodn, nebo shrnuje vechny
dosud uvdn nevhody. Uvdn je pouze pro plnost. Uren
sloitosti pslunch procedur Vm ponechme jako cvien.

     Kruhov seznamy

     Jde o spojov seznamy (obvykle dvousmrn), u nich prvn a
posledn prvek jsou propojeny pomoc Next a Last. Potek a
tak konec je pot uren ukazatelem "List".
     Tmto propojenm se mrn zkomplikuje procedura NEXT a tak
PREVIOUS:
               procedure Next(var RZ:RefZaznam):RefZaznam;
               begin
                    if RZ^.Next=List then Next:=nil
                    else Next:=RZ^.Next
               end;
     Odmnou je velk zjednoduen procedur INSERT a DELETE.
Zkuste si jednu z nich napsat. Poznamenejme, e asov sloi-
tosti jsou stejn jako u pslunch necyklickch seznam.

     Hlava

     Nkdy se do spojovch seznam (zejmna do kruhovch) vkld
jeden zznam s extrmn hodnotou Info (nap. 0). Tento zznam se
do seznamu nepot, ale jeho vskyt e problmy s przdnm
seznamem v procedurch INSERT, DELETE, LOCATE, PRINTLIST.
     Sloitost vpotu zstv stejn.

     Vhody a nevhody jednotlivch implementac

     Hlavn nevhodou imlementace seznam pomoc pol je omezen
na jist poet poloek. Tento odhad sice meme odloit a do
okamiku bhu programu s vyuitm dynamickch pol, ale leckdy
ani ten nen mon. Jedn se zejmna o lohy, kde je kombinovna
prce s vce ASD.
     Vtina operac s polem je oproti tomu mnohem jednodu ne
se seznamy. Pi bhu jsou obvykle tyto operace tak nepatrn
rychlej.
     Pi prci se seznamy je erpno vdy tolik pamti, kolik je
poteba. U pol (nememe-li pout uvolnn zbytku pole) je
leckdy vt st pamti nevyuita. Z tohoto tvrzen vak exis-
tuje vjimka. Jde o ppad, kdy pole je naplnno a zbytek je
uvolnn. V tomto ppad seznam zabr vce pamti, nebo obsa-
huje ukazatele na nslednka (pop. i pedchdce).
     Kad zlepen seznamu, na dvousmrn, kruhov nebo s hlavou
vede sice ke snazmu programovn a leckdy k rychlejmu vpo-
tu, ale zrove zabr vce msta. Nebojte se pouit kruhovch
seznam s hlavou pro nkolikaprvkov seznamy. Ztrta pamti nen
nikterak vrazn a uette si programovn (zejmna pi lad-
n).

Pouit spojovch seznam demonstrujme na nsledujcch ADS:

-    Zsobnk
     Jednou z astch aplikac seznam je zsobnk. Jde o ADS, na
n jsou provdny operace: MAKENULL (vytvo przdn zsobnk),
POP = DELETE(FIRST), PUSH = ADD.
     Princip innosti zsobnku byl popsn ve 3.kapitole na syst-
movm zsobnku. Ideln implementac zsobnku je jednosmrn
spojov seznam nebo pole. Vechny uveden operace pracuj v ase
O(1).

-    Fronta
     Dal astou aplikac seznam je fronta. Jde o ADS, kdy
zznamy ze struktury odchzej v poad, ve kterm pily. Tato
ADS je charakterizovna operacemi:
      MAKENULL,   FIRST,   DELETE(FIRST),   ADD (na konec).
Nejvhodnj implementac tto struktury je kruhov spojov
dvousmrn seznam s hlavou. Vechny uveden operace pracuj v
ase O(1).

-    Mapovn
     Mn diskutovanou, ale o to astji pouvanou strukturou je
mapovn. Jde o vytvoen jaksi pevodn tabulky, kdy jedn
hodnot uritho typu piazuji hodnotu jinou, pop. i jinho
typu. Poadovan operace zde jsou: MAKENULL, ASSIGN=ADD, COMPUTE
=LOCATE. Tato struktura me bt implementovna polem nebo
jednosmrnm spojovm seznamem.


6.3.3. Stromy

     Strom je ADS obsahujc prvky nazvan UZLY, z nich jeden je
KOEN. Uzly jsou spojeny necyklickmi relacemi, kter na nich,
ponaje od koene, tvo hierarchickou strukturu. Uzly ble ke
koenu se nazvaj rodie a jejich nslednci dti.
     Pro pouvat stromy, kdy u umme pracovat se seznamem a
strom je pouze komplikovanji reprezentovan seznam?
Dvodem je rychlost. Akoli procedury pro prci se stromy jsou
nkolikrt sloitj ne tomu bylo u seznam, jsou pi vhodn
realizaci pslunch procedur pro velk N (tj. pro velk poty
prvk) v prmru rychlej.

     Uvaujme strom, jeho kad uzel m dva nslednky, a na
posledn rove, kde nejsou dn a je zleva doprava uspodn.
Napklad:

                      8Ŀ
          4Ŀ                   12Ŀ   
  2Ŀ           6Ŀ         10Ŀ   14Ŀ
  1        3          5        7        9         11   13   15

Rychlost vpotu jednotlivch procedur nad tmto stromem bude
pi vhodn realizaci takovto:
ADD - O(log(n));  INSERT - O(log(n));  DELETE - O(log(n));
LOCATE - O(log(n)); NEXT - O(log(n));  MAKENULL - O(1);
FIRST - O(1);     PRINTLIST - O(n*log(n)).
CONCAT a SPLIT jsou realizovateln pouze pro podstromy.

     Stromy lze dlit podle tchto hledisek:
-  Poet nslednk:
     -    maximln 2 = BINRN STROM,
     -    maximln N = N-nrn strom.
-  Vyvenost stromu:
     -vechny uzly mimo uzl posledn rovn maj maximln
      mon poet nslednk= VYBALANCOVAN STROMY,
     -vechny uzly mimo uzl posledn rovn maj jist mini-
      mln poet (>2) nslednk = Vyvaovan stromy (nap. 2-3
      STROMY),
          velikosti levho a pravho podstromu kadho uzlu binr-
          nho stromu se li nejve o jednu = AVL STROMY.
-  Zpsob uspodn binrnch strom:
     -zleva doprava (preorder)
     -zprava doleva (postorder)
     -shora (inorder)
               Pklady:
                     2            2            1 
                    1     3        3     1        2   3
   N-rn stromy jsou uspodny vdy preorder.

     Pokud se na strom dvme jako na ADS, musme si poloit i
otzku, kter procedury by mla datov struktura implementujc
strom zpracovvat. Charakteristick procedury jsou tyto:
-  PARENT(Node) = Rodi pslunho uzlu.
-  LEFTMOST_CHILD(Node) = Nejlevj (prvn) syn.
-  RIGHT_SIBLING(Node) = Nejbli prav soused (sourozenec).
-  CREATE(Node,Info,Info,... ,Info) = Vytvo nov uzel Node a
   pslun syny s hodnotami Info...
-  ROOT = Vrt koen stromu.
-  MAKENULL = Vytvo przdn strom.

     Tyto procedury, tj. ADS stromu lze realizovat mnoha zpsoby.
Uvedeme zde opt jen ty nejpouvanj:

     Implementace obecnho stromu seznamem

          const MaxNodes = 100; { Vhodn konstanta }
          type
               Nodes= 1..MaxNodes;
               Tree = array [Nodes] of 
                              record
                                   Info : byte;
                                   Sibling : Nodes;
                                   Child : Nodes;
                              end;

     V tto struktue vdy jeden kurzor odkazuje na nejlevnjho
syna a jeden na nejbliho pravho souseda.
     Tento seznam me bt samozejm realizovn libovolnou meto-
dou uvedenou u seznam. 
     Pro nzornost prce s indexy uvedeme rekurzivn proceduru
vypisujc vechny prvky v uspodn preorder.

          procedure Print ( var T : Tree; Node : Nodes );
          var Child : Nodes;
          begin
               writeln(T[Node].Info);
               if T[Node].Child <> 0 then
                    begin
                         Child:=T[Node].Child;
                         repeat
                              Print(T,Child);
                              Child:=T[Child].Sibling;
                         until Child=0;
                    end;
          end; { Print }

     Binrn vyhledvac strom

          const MaxNodes = 100; { Vhodn konstanta }
          type
               Nodes= 1..MaxNodes;
               Tree = array [Nodes] of 
                              record
                                   Info : byte;
                                   Left : Nodes;
                                   Right : Nodes;
                              end;

     V tto implementaci jsou pouity odkazy na levho a pravho
syna binrnho stromu. Pepsn tto struktury pomoc pointer
by Vm jist ji neinilo dn pote, take tuto velmi astou
formu implementace ponechme na Vs.
     Vhoda tto implementace se projev zejmna pi FIND, LOCATE,
INSERT a DELETE operacch, jak se o nich hovoilo na potku
toho odstavce, nebo jejich rychlost je O(log(n)). 
     Nejjednodu je operace vyhledvn:
          function Locate(var T:Tree; Node:Nodes; Info:byte):Nodes;
          begin
               if T[Node].Info = Info then Locate := Node
               else
                    if T[Node].Info < Info then
                         if T[Node].Left = 0 then Locate := 0
                         else Locate := Locate(T,T[Node].Left,Info)
                    else
                         if T[Node].Right = 0 then Locate := 0
                         else Locate := Locate(T,T[Node].Right,Info)
          end; { Locate }

     Operace INSERT a DELETE jsou pro implementaci polem nevhodn.
Jejich popis provedeme na ji dve pipomenut realizaci pomoc
pointer:
          procedure INSERT(var Node:Nodes; _Info:byte);
          begin
               if T = nil then
                    begin
                    new(Node);
                    with Node do
                         begin
                              Info:=_Info;
                              Left:=nil;
                              Right:=nil;
                         end;
                    end
               else
                    if _Info<Node.Info then INSERT(Node.Left,_Info)
                    else INSERT(Node.Right,_Info)
          end; { INSERT }

     Dal druhy strom

     Srom se pouv cel ada, mezi ty nejznmj pat:
-  Proit stromy - libovoln stromy, kter u kadho uzlu maj
   odkaz na nslednka - urychuje to sekvenn prohledvn.
-  Nkdy bv u jednotlivch uzl odkaz i na rodie, je-li
   poteba provdt operaci PARENT.
-  Vybalancovan stromy, AVL stromy, 2-3 stromy jsou velmi
   efektivn implementace strom, jejich definice byla uvedena
   ve. Implementace tchto dleitch ADT pesahuje rmec
   prce a lze se o n dost nap. v [AHO].
-  B-stromy - jde o stromy, kter maj v uzlu tolik informanch
   poloek, kolik maj potomk+1. Jde o jaksi zobecnn binr-
   nch vyhledvacch strom, kter se vyuv nejastji u
   indexovch soubor (viz [AHO],[TACCESS]).

6.3.4. Mnoiny

     Mnoina je takov ADS, kter obsahuje mnoinu daj jistho
typu. Tato ADS je charakterizovna nsledujcmi operacemi:
-  UNION(A,B) = Sjednocen mnoin A a B.
-  INTERSECTION(A,B) = Prnik mnoin A a B.
-  DIFFERENCE(A,B) = Rozdl mnoin A a B.
-  MERGE(A,B) = Sjednocen mnoin s przdnm prnikem.
-  MEMBER(x,A) = Vydv true, pokud je x prvkem mnoiny A.
-  MAKENULL(A) = Vytvo przdnou mnoinu A.
-  INSERT(x,A) = Prvek x pid do mnoiny A.
-  DELETE(x,A) = Odebere prvek x z mnoiny A.
-    ASSIGN(A,B) = Provede "A := B".
-  MIN(A), MAX(A) = Nejmen a nejvt hodnota z mnoiny A.
-  EQUAL(A,B) = Vyd true, pokud je A = B.
-  FIND(x) = Vyhled mnoinu z njak skupiny disjunktnch
   mnoin, kter obsahuje prvek x.

     Tento seznam je pomrn rozshl a tko bychom hledali
implementaci, v n by se vechny tyto operace provdly dosta-
ten efektivn. Z tohoto dvodu se pouvaj ty implementace,
kter optimalizuj nejastji pouvan operace.
     Nejastj aplikac je SLOVNK, tj, ADS obsahujc operace
INSERT, DELETE, MEMBER, MAKENULL.

     Bitov mapa

     Pro mnoiny z universa obsahujcho maximln 256 prvk je
nejvhodnj pouit standardnho typu set. Implementaci vtch
mnoin je mon realizovat polem nap.:

          const SetSize= 1000 div 4; {mnoina 1000 prvk (4x256B)}
          type Mnozina : array [0 .. SetSize] of set of byte;

     Uveme pklady implementace nkterch procedur:
          procedure UNION ( var {IN:} A,B, {OUT:} C : Mnozina );
          var i:byte;
          begin
               for i:=1 to SetSize do C[i]:=A[i]+B[i];
          end {UNION};

          function MEMBER ( x : word; var A : Mnozina ) : boolean;
          begin
               MEMBER := x in A[x div 256];
          end { MEMBER };

     Spojov seznam

     Lze pout libovolnou implementaci spojovho seznamu, kterou
jsme probrali v 6.3.2. Pslun procedury ji jist snadno
naprogramujete sami. Pi implementaci slovnku je vhodn pou-
vat uspodan seznam.

     Hashing

     Tato metoda je zaloena na nhodnosti vstupnch dat. Je
nutn, abychom umli vytvoit takovou funkci (Hash function),
kter na zklad hodnot ukldanch poloek vytv hodnoty s
diskrtnm rovnomrnm rozdlenm. O mn budou tyto hodnoty
rovnomrn, o to pomalej bude pstup k jednotlivm polokm.
Obor hodnot Hash-funkce je obvykle interval 0..HashSize, co
odpovd rozsahu pamti, kter pro Hashing obtujeme.

     Mylenka pstupu k polokm pomoc Hash-funkce Hash(x) je
velmi jednoduch. Definujeme pole velikosti HashSize a funkce
Hash(x) uruje umstn poloky x v pslunm poli. Je-li toto
kdovn navreno optimln, je pstup ke kad poloce v
podstat pm (tj. O(1))!!!

     Problmy nastanou, jakmile funkce H piad dvma polokm
tut hodnotu. Tuto KOLIZI lze eit dvma zpsoby:

A. Oteven Hashing - Pole obsahuje ukazatele na seznamy poloek
   (seznamy lze implementovat jednou z dve uvedench technik).

          const HashSize = 100;
          type OpenHashing = array [0..HashSize] of RefList;

B. Uzaven Hashing - Pole obsahuje pmo ukldan poloky.
   Velikost pole mus bt vt, ne je oekvan poet poloek.
   Ppadn kolize je eena REHASHING-funkc, tj. funkc, je
   se rekurzivn sna nalzt vhodn umstn poloky.

          const HashSize = 100;
          type CloseHashing = array [0..HashSize] of byte;

     Mylenka je to jednoduch a pitom velmi pkn. Problmem
zstv pouze tvorba Hash a Rehash funkc. Tyto funkce jsou
popsny v mnoh literatue a jsou pmo zvisl na rozdlen
hodnot ukldanch prvk.

     Nejjednodu metoda (a obvykle dostaten) je tato:

          function Hash ( Info : byte ) : byte;
          begin
               Hash := Info mod HashSize;
          end { Hash };

          function MEMBER_Rehash ( var H : CloseHashing;
                                                   Info : byte ) : boolean;
          { Vyhledv prvek Info ve struktue H }
          var Index : byte;
          begin
               if H[Hash(Info)]=Info then MEMBER_Rehash:=true
                  {Info je na hashovanm mst, nen teba hledat
                     dle}
               else
                    begin
                    Index:=Hash(Info);

                    {$B-  Rehash}
                    while (Index <= HashSize) and (H[Index] <> 0) and
                              (H[Index] <> Info) do Inc(Index);
                    {Prochz postupn do konce pole dokud nenajde Info}
                    {$B+  End Of Rehash }

                    MEMBER_Rehash := H[Index] = Info;
                    end;
          end { MEMBER_Rehash };

     Jak plyne ze zpsobu implementace, pouv se tto metody
zejmna pro implementaci Slovnku.

     Stromy

     Velmi efektivn a astou implementac Slovnku jsou sten
uspodan binrn vyhledvac stromy. S jejich popisem jsme se
setkali v odstavci 6.3.3. 
     Stejn tak jsme se zmnili o vybalancovanch stromech, o 2-3
stromech a jinch pokroilch strukturch, kter jsou velmi
efektivn, ale dost sloit.


     Povdnm o ADS jsme ani zdaleka nevyerpali tuto problema-
tiku. Doufm, e Vm uveden pklady poslouily jako pklady
jednoduchch procedur v Turbo Pascalu, nebo byly tak tak
mnny.

6.4. Objekty

     Jednm z vsledk snahy lpe postihnout abstraktn datov
struktury (ADS) je zaveden pojmu OBJEKT, jak jsme to uinili v
2.4.4. K pojmu objekt se ve pojem Objektov orientovan pro-
gramovn (OOP), co je speciln metodika pro tvorbu program s
vyuitm typu objekt. OOP neet mnoho psan (obas jej sp
pidlv), ale umouje vytvoen ADS mnohdy jako jedinho
objektu spolu s pslunmi metodami. Ve spoluprci s unitami
(viz 6.5) tvo OOP nejpogresivnj programtorskou techniku
pouvanou zejmna pi tvorb rozshlch systm s koatou
datovou strukturou, kdy se principy ddn a virtualizace zro
v pln me. O zsadch OOP budeme hovoit v prbhu tohoto
odstavce tak, jak na n budeme naret.

6.4.1. Metody objekt

     Kad objekt me obsahovat ve sv deklaraci i hlaviky metod
(procedury, funkce, konstruktory, destruktory), kter se k nmu
v. Pipomeme, e:
-  Formln parametry kad metody se mus liit od ostatnch
   poloek objektu (vetn poloek prefixu).
-  Kad metoda mus bt v te deklaran sti za deklarac
   objektu sama deklarovna.
-  Identifiktor metody pi vlastn deklaraci (za deklarac
   objektu, jemu pslu) je kvalifikovn, tj. sloen z iden-
   tifiktoru typu, teky a identifiktoru metody.
-  Metody jsou vdy volny jako FAR, bez ohledu na stav pep-
   nae {$F}.
-  Popis metody v objektu je chpn pro vlastn deklaraci (uve-
   denou za deklarac objektu) jako forward, tedy:
          -Nesm bt kdekoli uveden jako forward.
          -Formln parametry se mus pln shodovat s hlavikou
         popsanou v deklaraci objektu nebo mus chybt.
-  Jak jsme se ji zmnili v 3.4.7, kad metod je pi voln
   jako posledn parametr pedvna odkazem instance odpovda-
   jcho objektu jako parametr SELF, kter je v metod uiva-
   teli pstupn. Tedy nap.:
          procedure Objekt.Init ( X : integer );
     je ve skutenosti peloen jako:
          procedure Objekt.Init ( var Self : Objekt; X : integer );
   Pedvn tohoto parametru je pekldno jako:
          les  DI,adresa_objektu
          push ES
          push DS
-  Tlo kad metody je implicitn prefixovno pkazem "with
   Self do", take uvnit metody jsou implicitn pstupn
   vechny poloky objektu (proto nesm kolidovat s formlnmi
   parametry).

Uvedeme pklad, jak lze pouit objekt obejt bez prostedk
pro OOP:

type                                         type
     Z = object                                 Z = record
       X : byte;                                  X : byte;
       function F : byte;                    F:function(var Self:Z):byte;
     end;                                       end;
function Z.F : byte;                    function Z_F (var Self:Z) : byte;
     begin                                           begin with Self do begin
          Z.F:=X;                                  Z_F:=X;
     end;                                       end end;
var                                          var
     A,B : Z;                                   A,B : Z;
begin                                             begin
     A.X:=1;                                  A.X:=1; A.F:=@Z_F;
     B.X:=2;                                  B.X:=2; B.F:=@Z_F;
     writeln(A.X+B.F);                     writeln(A.X+Z_F(B));
end.                                         end.

     Z pkladu plyne, e object nen smanticky nikterak silnj
nstroj, nebo jej meme tm "1:1" pepsat do verze 5.0. To
plat i pro hierarchizaci (vnoen zznamy) a virtualizaci (me-
tody jsou explicitn inicializovny a v konstruktoru), avak
jeho hlavn sla je v syntaxi. Umouje toti pst programy
obsahujc objekty "iteln", a tak nabz pouit OOP i tm
nejistm pascalistm.

     Prvn princip OOP: "K polokm objektu pistupujte zsadn
pomoc metod." Objekt se od zznamu li tm, e zznam popisuje
njakou objektivn realitu jejmi atributy, avak objekt pomoc
metod popisuje jej vztah k okol a o jej "vnitn" atributy se
nezajm, akoli je samozejm vyuv pi tvorb tchto vztah
(metod). Objekty Vm umouj pohlet na realitu v jej dyna-
mice (metody realizuj jej promny, innost, reakce na vnj
podnty atd.). Nedegradujte je na "zznam s piazenmi podpro-
gramy".

6.4.2. Hierarchizace objekt 

     Jak jsme ji uvedli ve 2.4.4, lze kadmu objektu pipojit
jeden prefix, m se tento objekt stv podobjektem svho
prefixu. Tmto mechanismem vznik stromov struktura, take se
na prefix meme dvat jako na pedchdce (rodie) a na pod-
objekt jako na nslednka (potomka).

     Jak tak vme, podobjekt dd od svho prefixu vechny sloky
(datov poloky i metody). Mechanismus ddn s sebou pin
tyto aspekty:
-  Datov poloky popsan v podobjektech mus mt identifiktory
   rzn od identifiktor jednotlivch sloek prefixu.
-  Identifiktory metod popsan v podobjektu:
          -Mus bt rzn od vech datovch poloek prefixu.
          -Mohou "zakrvat" (viz 3.4.4) libovolnou metodu v pre-
         fixu.
          -Mohou bt virtuln (viz 6.4.3).
-  Metody mohou obsahovat i voln "zakrytch metod" prefixu
   pomoc kvalifikace tto metody typem pslunho pedchdce
   (viz 3.1.1). Napklad:
          type 
               A = object function F : boolean end;
               B = object (A) function F : byte end;
          function A.F : boolean;
               begin A.F:=true end;
          function B.F : byte;
               begin if A.F {Self.A.F} then B.F:=1 end; ...

     Pipomeme si jet zvltnosti piazovacho pkazu: Vedle
bnho piazen mezi promnnmi tho typu objekt je mono
piadit hodnotu typu objekt promnn, jej typ je prefixem
typu piazovan hodnoty. Nap.:

          type                                AA           BB
               A = object    XA,YA:byte;    Ŀ  Ŀ
               B = object(A) XB,YB:byte;       XA    <-   XA    
               C = object(B) XC,YC:byte;       YA    <-   YA    
          var                                 Ĵ
               AA : A;                        \     /       XB    
               CC : C;                         \   /        YB    
          begin ...                             \ /      Ĵ
               AA:=CC; {nelze CC:=AA}           / \         XC    
          end.                                 /   \        YC    
                                              /     \    

     Tmto piazenm jsou piazeny pouze poloky prefixu. Ostat-
n poloky se nepenej. Toto piazen se proto pouv pouze
ojedinle na "konci prce", kdy jsou do prefixu uloeny souhrnn
daje z ostatnch poloek podobjekt, kter ji nebudou dle
pouvny.
     Mnohem astji se k objektm pistupuje pomoc ukazatel.
Obdobn lze zcela bez problm piadit ukazateli na typ prefixu
ukazatel na promnnou jeho podobjektu. Opan operace, tj.
piazen ukazateli na typ podobjekt ukazatel na promnnou jeho
prefixu, je mon s pouitm petypovn (viz 3.1.1 a 6.2), co
pln odpovd poadavku na zabezpeenost, nebo tmto petypo-
vnm "slibujete", e piazovan ukazatel de facto odkazuje na
cel podobjekt. Podrobn se k tto problematice jet vrtme
(viz 6.4.3).

     Druh princip OOP: "Podobjekty objekt vytvejte vdy jako
vsledek procesu konkretizace." Podobjekt by ml ble konkre-
tizovat objektivn realitu popisovanou v prefixu. Prefix se tak
stv obecnm pojmem pro mnoinu vech svch podobjekt, kter
jej v jeho rznorodosti konkretizuj.

6.4.3. Virtualizace metod

     Jak plyne z druhho principu OOP, prefix obvykle odpovd
obecnmu pojmu a podobjekty jeho konkretizacm. Prefix  proto
obvykle obsahuje "spolen poloky" pro vechny konkretizace a
ml by obsahovat i jejich spolen metody. Uvaujme takovto
pklad: Navrhujeme realizaci datovho modelu rozshl diskrtn
energetick st. Jde o konenou s popsanou orientovanm
multigrafem, kde kad orientovan hran multigrafu odpovd
njak tok energie. Takovouto hranu meme popsat napklad:

     record Zacatek, Konec : VrcholGrafu;
                HustotaTokuEnergie : Extended;
     end;

Jednotliv hrany ovem reprezentuj rzn druhy penosu energie
(teplovody, elektrick veden, svtlovody...). Tmto potom budou
odpovdat pslun podobjekty. Jednou z vznamnch spolench
vlastnost vech tchto penos energie jsou napklad mrn
ztrty (pedpokldejme je linern na hustot energetickho
toku). Tento daj je ovem funkc konkrtnch parametr konkrt-
nch veden a lze jej tedy popsat jako funkci pouze u jednotli-
vch podobjekt (kde jsou i pslun data) a nikoli pmo u
prefixu, jak by to vyadovala logika vci.
     Tento rozpor je een pomoc VIRTULNCH metod. Takovto
metoda je popsna u spolenho prefixu jako virtuln (uvedena
klauzule virtual u popisu metody objektu). U vech podobjekt, u
nich je pot definovna, mus mt shodn poet, poad a typ
parametr a mus bt tak popsna jako virtuln. Vechny takto
popsan metody mus bt samy dle deklarovny (i kdy teba jen
s przdnm tlem).
     N pklad by mohl zanat njak takto:

     type
     Energie = object
                         Zacatek, Konec : VrcholGrafu;
                         HustotaTokuEnergie : Extended;       {W/s}
                         function Vykon (Cas : Real) : Comp;  {W}
                         function Ztraty : Extended; virtual; {Mrn}
                         ...
                     end;
          function Energie.Vykon (Cas : Real) : Comp;
               begin Vykon := HustotaTokuEnergie * Cas end;
          function Energie.Ztraty : Extended; begin end;
          ...
     type
     Elektricka = object (Energie)
                              Napeti             : Double;  {V}
                              ProudovaHustota : Double;  {A/s}
                              Odpor              : Double;  {}
                              Prurez, Delka   : Double;  {m}
                              function Ztraty : Extended; virtual;
                              ...
                          end;
          function Elektricka.Ztraty : Extended;
          {Idealizovan mrn Joulovy ztrty se zanedbanm svodem}
               begin
               Ztraty:=Odpor*Sqr(ProudovaHustota)*Delka/(Prurez*Pi);
               end;
          ...
     ...

     Zpsob pouit virtulnch metod je velmi jednoduch a, jak
dle ukeme, je tak pomrn efektivn. M vak jednu vadu na
krse, a to nutnost pouit konstruktor a destruktor, kter
jsou v pedchozm pklad naznaeny tekami.

     Konstruktor 

     Virtuln metody jsou realizovny pomoc jistch tabulek
virtulnch metod (VMT), kter jednotlivm podobjektm piazuj
pslun metody. Tuto tabulku je pro kadou instanci poteba
inicializovat, co je automaticky provedeno pi voln konstru-
ktoru (viz 2.4.4, 3.4.2), kter me mt v nejjednodu form
tento tvar:

  constructor Energie.Init; begin end;

     Konstruktor mus bt vdy voln ped prvnm pouitm virtu-
ln metody (sm proto neme bt virtuln). Bv obvykle voln
ji v inicializan sti programu. Tato skutenost vede k
mylence pouvat jej pro inicializaci objekt. Parametry kons-
truktoru lze tedy povaovat za inicializan daje a innost
konstruktoru obvykle vypad tak, e inicializuje jednotliv
vlastn poloky objektu a poloky prefixu (to je obvykle reali-
zovno volnm konstruktoru prefixu).
     N pklad bychom mohli doplnit napklad takto:

          constructor Energie.Init ( Od,Po : VrcholGrafu;
                                                     HTE : extended );
          begin
               Zacatek:=Od;
               Konec:=Po;
               Hustota_Toku_Energie:=HTE;
          end;

          constructor Elektricka.Init ( Od,Po : VrcholGrafu;
                                                        U,I,R,D,L : double );
          const
               Eps0 = 8.855E-12;
          begin
               Energie.Init(Od, Po, Eps0/4*Sqr(U/L) {Piblin} );
               Napeti:=U;
               ProudovaHustota:=I;
               Odpor:=R;
               Prurez:=D;
               Delka:=L;
          end;

     Dynamick alokace

     Situace se mrn zkomplikuje, pjde-li o dynamicky alokovan
objekt. V tomto ppad objekt musme nejprve alokovat pkazem
NEW a pot inicializovat volnm konstruktoru. Abychom mohli ob
souvisejc akce zapsat najednou, poskytuje verze 5.5 toto
rozen procedury NEW:

Ŀ
  procedure New ( var P : pointer; <voln konstruktoru> ); 


     Poznamenejme, e pi tomto zpisu nesm bt jmno konstru-
ktoru kvalifikovno identifiktorem objektu, nebo v okamiku
voln tento objekt jet neexistuje. Druh parametr m tvar
voln konstruktoru, avak vlastn voln je provedeno a po
vytvoen pslunho objektu. Nejde tedy o pedn parametru,
ale pouze o syntaktick spojen dvou smanticky souvisejcch
pkaz. Zpis      New(P,Init)         je pouze zkratkou za:
                              New(P); P^.Init.

     Stejn je rozen i funkn tvar podprogramu New:

Ŀ
    function New (<Id. typu>;<voln konstruktoru>):pointer;  


     Nech:
          type RefEn = ^Energie;
                 RefEl = ^Elektricka;
          var  Ren : RefEn;
                 Rel : RefEl;
     potom zpis:
          Rel := New ( RefEl, Init(0,1,7,9,0.3,2,1) );
     je zkratkou za:
          Rel := New ( RefEl );
          Rel^.Init(0,1,7,9,0.3,2,1);

     Dynamick metody 

     Jak plyne z pedchozch pklad, meme s objektem pracovat
pomoc ukazatel. Pstup k polokm je stejn jako u zznam
(Ren^.Konec, Rel^.Odpor, Rel^.Zacatek). Obdobn tomu je u p-
stupu k metodm (Ren^.Vykon, Rel^.Init). Na uvedenm pklad si
pipomeme mechanismus zakrvn metod:
               Ren^.Init;  {3 parametry}
               Rel^.Init;  {7 parametr}

     Vrame se k piazovacmu pkazu diskutovanmu v 6.4.2.
Piazen mezi objekty stejnho typu je zejm a nevyaduje
dn dal koment. Zvanj je ppad piazen mezi prefi-
xem a podtypem:

-  "Ren:=Rel" V tomto ppad jsme na objekt Rel^ odkzali
   ukazatelem Ren. Jde vlastn o proces abstrakce (opak konkre-
   tizace), kdy vme, e uveden podobjekt je typu elektrina,
   ale ns nyn budou zajmat pouze ty jeho rysy, kter m tento
   objekt jako model obecnho penosu energie. Pkladem me
   bt reprezentace multigrafu na energetick st seznamem
   hran (seznam reprezentovan polem):

          const Max = ...;
          type  Rozsah = 1..Max;
          var 
               Sit : array [Rozsah] of RefEn;
               j   : Rozsah;
               ...
          begin
               for j:=1 to Max do
                    begin
                    ... { Naten daj o j-t hran }

                    if ... { Jde o penos elektiny } then
                         Sit[j] := New (RefEl; Init(...) )
                    else ... { Dal typy penos };

                    end;
               ...
          end;

-  "Virtuln voln" Nyn se dostvme k hlavn vhod virtul-
   nch metod. Je-li volna virtuln metoda, je pro uren
   skuten metody, je m bt volna, rozhodujc, jakho typu
   je "ve skutenosti" objekt, jeho metodu volme. Je-li tedy
   Ren:=Rel, je Ren^ typu Energie, avak ve skutenosti Ren
   odkazuje na msto v pamti, kde je uloen objekt typu Ele-
   ktrina, a to je pro interpretaci virtulnho voln rozho-
   dujc.
     Pi voln virtuln metody je tedy volna ta metoda,
   kter je popsna v deklaraci podobjektu, na nj pouit
   ukazatel odkazuje. Pokud takov metoda nen, je volna ta
   metoda, kter byla deklarovna v prefixu naposledy. Nap-
   klad:

          type
               A = object     constructor CO;
                                   procedure P; virtual  end;
               B = object     constructor CO; end;
               C = object     constructor CO;
                                   procedure P; virtual  end;
               D = object     constructor CO; end;
               E = object     constructor CO;
                                   procedure P; virtual  end;
          ... { Deklarace jednotlivch konstruktor a procedur }
          var
               Ra = ^A;
               Rd = ^D;
          begin
               Ra := New (Rd,CO);
               Ra^.P;     { Jde o voln procedury CO.P }
          end.

     Vrame se k na energetick sti. Budeme-li chtt vypo-
   tat celkov mrn ztrty, meme to udlat takto:

          function CelkoveZtraty : extended;
          var Sum : extended; 
                j   : Rozsah;
          begin
               Sum := 0;
               for j:=1 to Max do
                    Sum:=Sum+Sit[j]^.Ztraty;
                    { Pro rzn podobjekty jsou volny rzn funkce. }
               CelkoveZtraty:=Sum;
          end;      

-  "Rel:=RefEl(Ren)" Tmto pkazem kme: "Mil potai,
   prove klidn poadovan piazen, ukazatel Ren ukazuje na
   poloku Elektrina, za toto tvrzen se ti zaruuji, nebo to
   plyne z okolnost, kterm neme pmo rozumt, ale je to
   tak!". Z tto, i kdy trochu nadsazen, interpretace zmnn-
   ho pkazu plyne jeho nebezpenost, pesto se vak obas
   pouv, pro nkter "doplkov" vpoty, kdy ns zajmaj
   daje pouze v nkterch podobjektech.
     V na sti to me bt napklad vpoet celkov proudov
   hustoty ve vech elektrickch tocch:

          function CelkovaProudovaHustota : extended;
          var Sum : extended; 
                j   : Rozsah;
          begin
               Sum:=0;
               for j:=1 to Max do
                    if TypeOf(Sit[j])=TypeOf(Elektrina) {viz dle}
                    then Sum:=Sum+RefEl(Sit[j]^).ProudovaHustota;
               CelkovaProudovaHustota:=Sum;
          end;

     Destruktor 

     Pokud chceme dynamicky alokovan objekt uvolnit, poslou nm
k tomu znm procedura DISPOSE. Problmy vak nastanou v mnoho-
krte diskutovanm ppad:
           Ren:=Rel; Dispose(Ren);
nebo touto sekvenc se uvoln pouze prefix a poloky Napt a
Dlka zstanou v pamti. Proto se tohoto jednoduchho zpsobu
voln procedury DISPOSE nepouv. Namsto nj se vyuv jeho
rozen formt:

Ŀ
  procedure Dispose (var P:pointer; <voln destruktoru>);  


kde druhm parametrem je voln destruktoru bez kvalifikace
objektem (podobn jako u NEW), kter implicitn na zklad
tabulek o virtulnch metodch ur pesnou velikost uvolova-
nho objektu. Jeho nejjednodu tvar je napklad:

          destructor Energie.Done; begin end;

     Protoe je pouvn pi uvolovn objekt a jeho tlo je
provedeno vdy tsn ped uvolnnm pamti, pouv se asto k
uvolovn pamti souvisejc s danm objektem (vnitn seznamy
atp.). Je-li pouit pro tento (klidov) el, je obvykle vhod-
n, aby byl popsn jako virtuln a pro kad podobjekt byl
sestrojen specializovan destruktor uvolujc vechny speciln
alokace pamti a volajc pot destruktor svho prefixu.

     Tet princip OOP

     Shrme metodick pokyny plynouc z tohoto odstavce do posled-
nho metodickho principu:
   "Prefix mus obsahovat vechny poloky a metody, kter jsou
   spolen vem jeho podobjektm, piem tyto metody by mly
   bt popsny jako virtuln, pokud je jejich zpracovn z-
   visl na typu podobjektu."
     Cel povdn o OOP uzaveme pkladem. eknme, e jste aka-
demick keramik, kter dostal za kol vytvoit mozaiku z rznch
kachliek. eknme, e mte k dispozici tvercov kachliky o
stran 20, 40, 80, 160 a 320 cm. Kad takov kachliek me bt
hladk nebo pedstavovat rzn vzory (pro jednoduchost kruh nebo
tverec). Vam kolem je kachliky "umlecky sloit". Vsledn
mozaika m bt 3.2 x 6.4 m velk. Jej skldn tedy jist
nebude moc pohodln. Rozhodnete se proto prci penechat po-
tai s tm, e vyuijete genertoru pseudonhodnch sel RANDOM
(viz 6.6), kter nhodn vygeneruje rozmry, barvy a tvary
kachliek a Vy si pot pouze vyberete tu sprvn "umleckou
kompozici". Pro malovn obrzk pouijeme grafickch procedur
v reimu 320x640 bod, kter budeme dostaten komentovat a
jejich pesn popis bude uveden v kapitole 9.
     lohu budete samozejm eit pomoc objekt. Zkladn ob-
jekt = kachliek, podobjekty = koleko, tvereek, ...

Program Mozaika;
uses Crt,Graph;
type
    Kachlik = object
                 x, y : word;
                 ForCol, BkCol : byte;
                 Size : word;
                 constructor Init (_x, _y, _Size : word);
                 procedure Generuj;
                 procedure Maluj; virtual;
                 destructor Done; virtual;
              end;
           RefKach = ^Kachlik;
              constructor Kachlik.Init;
                 begin
                    x:=_x;
                    y:=_y;
                    Size:=_Size;
                    Generuj; {Nemusi byt forward}
                 end;
              procedure Kachlik.Generuj;
                 begin
                    BKCol :=Random(15);
                    ForCol:=Random(15);
                 end;
              procedure Kachlik.Maluj;
                 var i,j:word;
                 begin
                    SetFillStyle(1,BKCol);
                    Bar3D(x,y,X+Size,y+Size,0,False);
                                        {Vybarvi ctverecek barvou BKCol}
                 end;
              destructor Kachlik.Done;
                 begin end;

type
       Kruh = object (Kachlik)
                 procedure Maluj; virtual;
              end;
           RefKruh = ^Kruh;
              procedure Kruh.Maluj;
                 begin
                    Kachlik.Maluj;    {vybarvi pozadi}
                    SetColor(ForCol); {nastavi barvu kresleni}
                    Circle( x+Size div 2,
                                              y+Size div 2, Size div 2)
                                      {namaluje kruznici}
                 end;

type
    Ctverec = object (Kachlik)
                 procedure Maluj; virtual;
              end;
           RefCtverec = ^Ctverec;
              procedure Ctverec.Maluj;
                 begin
                    Kachlik.Maluj;    {vybarvi pozadi}
                    SetColor(ForCol); {nastavi barvu kresleni}
                    Rectangle( x + Size div 4, y + Size div 4,
                               x + Size - Size div 4,
                               y + Size - Size div 4 )
                                      {namaluje obdelnik}
                 end;

type
     Rozdel = object (Kachlik)
                 lh, ld, ph, pd : RefKach; {sklada se z mensich}
                 procedure Maluj; virtual;
                 constructor Init (_x, _y, _Size : word);
                 destructor Done; virtual;
              end;
           RefRozdel = ^Rozdel;
              procedure Rozdel.Maluj;
                 begin
                    lh^.Maluj;
                    ld^.Maluj;
                    ph^.Maluj;
                    pd^.Maluj;
                 end;
              constructor Rozdel.Init (_x, _y, _Size : word);
                 function Make (x, y : word) : RefKach;
                    var R : 0..3;
                    begin
                       R:=random(4);
                       gotoXY(5,25);
                       case R of
                       0:if _Size>20 then
                          Make:=new(RefRozdel, Init(x,y,_Size))
                            else
                          Make:=new(RefKach,   Init(x,y,_Size));
                       1:Make:=new(RefKach,   Init(x,y,_Size));
                       2:Make:=new(RefKruh,   Init(x,y,_Size));
                       3:Make:=new(RefCtverec,Init(x,y,_Size));
                       end;
                    end;
                 begin
                    _Size := _Size div 2;
                    lh := Make (_x,       _y);
                    ld := Make (_x,       _y+_Size);
                    ph := Make (_x+_Size, _y);
                    pd := Make (_x+_Size, _y+_Size);
                 end;

              destructor Rozdel.Done;
                 begin
                    dispose (lh, Done);
                    dispose (ld, Done);
                    dispose (ph, Done);
                    dispose (pd, Done);
                 end;
var
   GD,GM : integer; {parametry grafickeho rezimu}
   c     : char;    {pomocna promenna pro rizeni cyklu}
   A,B   : RefKach; {promenne realizujici jednotlive mozaiky}

begin
   GD:=3; GM:=1;           { adaptr EGA, md 640 x 350 bod }
   InitGraph (GD, GM, ''); { Inicializace grafickho mdu }
   repeat
      A := new ( RefRozdel, Init(  0, 0, 320) );
      B := new ( RefRozdel, Init(319, 0, 320) );
      A^.Maluj;
      B^.Maluj;
      c:=ReadKey;
      dispose(A,Done);
      dispose(B,Done);
   until c in ['A','a','Y','y'];
end .

6.4.4. VMT a implementace (na PC IBM)

     Jak jsme se ji zmnili v pedchozm odstavci a ve 2.4.4.,
virtuln metody jsou realizovny pomoc VMT (Virtual Method
Table). Pro kad typ objekt obsahujc virtuln metody (i
zddn) existuje prv jedna VMT. Tyto tabulky jsou vytvoeny
ji v dob pekladu a jsou uloeny v poad deklarac na potku
datovho segmentu ped typovanmi konstantami (spolu s nimi jsou
tak pmo uloeny v .EXE souboru - viz 6.5).
     Jak ji vme z 2.4.4., kad instance pouvajc virtuln
metody obsahuje prv jednu 2-bytovou poloku obsahujc offset
adresy pslun VMT (tzv. VMT-field). Nyn popeme tvar VMT.

     VMT

     Prvn slovo obsahuje velikost instance v bytech. Druh slovo
obsahuje tak tuto velikost, avak se zpornm znamnkem. Dle
nsleduje pole (4-bytovch) pointer odkazujcch na vstupn
body jednotlivch virtulnch metod pslunch danmu podobje-
ktu. VMT si tedy meme pedstavit jako:

     type VMT = record
                              Size    : integer;
                              NegSize : integer;
                              Entry   : array[1..<poet virtulnch metod>]
                                                  of pointer;
                      end;

     Poloka Size je vyuvna destruktorem a uruje velikost
uvolovan oblasti. Vedle toho ji vyuv i funkce SizeOf, kter
tedy vdy vrac "skutenou velikost" instance.
     Poloka NegSize spolu se Size je pouvna pro oven ini-
cializace instance. Je-li instance inicializovna, odkazuje VMT-
field na pslunou VMT, pro ni plat Size+NegSize=0. Pokud
poloka instance VMT-field urujc offset VMT odkazuje na jin
msto v pamti, tj. nebyla dosud konstruktorem inicializovna,
je tento vsledek velmi nepravdpodobn. Na tomto principu je
tak provdn test (spolu s ovenm Size>0). Je-li nastaven
pepna {$R+}, je pi kadm voln virtuln metody provdn
tento test a ppadn generovna bhov chyba 210. Je-li {$R-},
tento test se neprovd a ppadn chyba kon "zabloudnm"
programu.

     Posledn poloky VMT jsou adresy vstupnch bod jednotlivch
virtulnch metod. Tyto adresy jsou vyuvny pi voln virtu-
lnch metod, kdy namsto standardnho CALL <podprogram>, je
provedeno:
               MOV   DI, ES:[DI+VMT-field]       ;DI:=Self.VMT-field
               CALL  DWORD PTR [DI+<podprogram>] ;adresa vzhledem k
                                                               ;VMT
Je vidt, e toto voln je velmi rychl a efektivn.

     Offset VMT jednoznan identifikuje "skuten" typ objektu.
Tto skutenosti je vyuvno i v nov funkci:

Ŀ
  function TypeOf ( var P : <objekt> ) : pointer;           


     Parametrem tto funkce me bt instance typu objekt obsa-
hujc virtuln metody nebo pmo identifiktor typu takovto
instance. Vsledkem tto funkce je adresa pslun VMT (tj. 4
byty "DSEG : VMT-field"). Je-li parametrem jin typ nebo pro-
mnn (a to i objekt bez virtulnch metod), dojde k chyb pi
pekladu. Funkce je pouiteln k uren typu podobjektu, jak
jsme to mohli vidt u pkladu pro vpoet celkov proudov
hustoty (viz 6.4.3).

     Konstruktor a destruktor

     Pro voln konstruktoru a destruktoru plat stejn pravidla
jako pro voln ostatnch metod s tm, e za Self parametrem je
pedvn jet jeden 2-bytov parametr (tzv. VMT-parametr).

     Pi voln konstruktoru je ve VMT parametru uloena pozice
VMT-field v rmci instance (Self), resp. 0, pokud Self neob-
sahuje virtuln metody a inicializaci Self nen teba prov-
dt.
     Pi voln destruktoru indikuje 0 ve VMT-parametru  "normln
voln", tj. chov se jako obyejn procedura. Jinak jde o
voln v rmci pkazu Dispose, kter po proveden tla destru-
ktoru uvoln instanci Self velikosti Self.VMT-field^.Size.

     Vrame se k innosti konstruktoru volanho v rozenm
pkazu NEW: Na potku je nejprve vytvoena pslun instance,
pot je inicializovna poloka Self.VMT-field a nakonec je pro-
vedeno vlastn tlo konstruktoru jako u bn procedury.
     Do Self parametru je pi nvratu uloena hodnota nil a adresa
vytvoen instance je vrcena v DX:AX. Nen-li alokace pamti
mon, dojde k chyb 203. Je-li vak instalovna vlastn   
HeapError funkce a vrt "1", nen tlo konstruktoru vbec
provedeno a v DX:AX je vrceno nil.
     Pokud bychom chtli tuto situaci simulovat, tj. vsledek nil
a neproveden tla konstruktoru, napklad v okamiku, kdy v
konstruktoru nespn alokujeme dal dynamick promnn,
meme pout:

Ŀ
    procedure Fail;                                         


Tato procedura se me vyskytovat jedin v konstruktoru. Je-li
pouita, uvoln vechny dosud (v konstruktoru) dynamicky aloko-
van promnn, do DX:AX ulo nil a provede EXIT.

     spnost proveden konstruktoru meme ovit tak, e otes-
tujeme vsledek NEW na rovnost s nil. Problmy nastanou pi
voln konstruktoru pmo, v tomto ppad nelze FAIL-ukonen
nijak poznat. Pro tento el lze konstruktor volat jako funkci
typu boolean, kter vrac True, byla-li provedena spn a
False, byla-li ukonena volnm procedury FAIL. Napklad :

          constructor Elektricka.Init ( Od,Po : VrcholGrafu;
                                                        U,I,R,D,L : double );
          const     Eps0 = 8.855E-12;
          begin
               if Energie.Init(Od, Po, Eps0/4*Sqr(U/L))
                     then     writeln(' Alokuji dal objekt. ')
                     else Fail;
            Napeti:=U;
                ProudovaHustota:=I;
                Odpor:=R;     Prurez:=D;     Delka:=L;
      end;

6.5. Unity

     Velmi dleitm prvkem Turbo Pascalu jsou UNITY. Jde o sti
programu, kter lze separtn kompilovat a pipojovat je k jinm
stem programu podle poteby. Jednotliv unity mohou obsahovat
konstanty, typy, promnn a podprogramy, kter lze v hlavnm
programu vyuvat.

     Unity jsou nejastji vyuvny jako knihovny podprogram
(Menu systm, Statistick balky, Databzov balk, atd.), mezi
n pat i standardn knihovny (unity: SYSTEM, CRT, PRINTER,
DOS, GRAPH, OVERLAY).
     Druh forma pouit, kter se vyskytuje zejmna u velkch
systm, je pouit unit jako modul ve smyslu ADS.
     Vhodou unit je monost jejich pekrvn (Overlay), jak o
nich budeme hovoit v poslednm odstavci, a tak jsou unity nkdy
pouvny tak k dekompozici rozshlch program.

6.5.1. Zpis program a unit

     Nejprve si pipomeme a doplme syntaxi programu z 1.kapito-
ly:

     Program

     Syntaktick diagram programu m tento tvar:

     <program> ::=  
                                                     Ŀ  Ŀ
         program <id. programu>  ( <id. souboru> ,... )  ; 
                                                       
              Ŀ
         <uses>   <blok> .
              

piem
                                              Ŀ
   <blok> ::=  <deklarace>  begin  <pkaz> ;...  end
                                              

     Pojmy "deklarace" a "pkaz" byly vysvtleny dve. Klauzule
uses bude vysvtlena pozdji. Nyn zde popime ostatn sti:

     Jak ji vme, identifiktor programu a seznam soubor je
koment a do jazyka je zahrnut s ohledem na kompatibilitu se
standardn verz Pascalu. V praxi se seznam soubor neuvd.
Zachovv se pouze identifiktor programu, a to z tchto dvod:
-  Program m formln "zatek" a je pro lep orientaci po-
   jmenovn.
-  Identifiktor programu lze vyut pro kvalifikaci objekt
   jazyka (viz 6.4.2.).
-  Je uiten, aby identifiktor programu byl shodn s nzvem
   souboru, v nm je uloen. Tato konvence Vm usnadn orien-
   taci zejmna pi astm pechzen a koprovn mezi pro-
   gramy.

     Unita

     Unity jsou programov moduly, kter se zapisuj do samo-
statnch soubor, lze je pipojovat k jinm programm nebo
unitm, ale samostatn je nelze spustit. Maj tuto strukturu:

     <unit> ::=

                unit  <id. unity> ;
                              Ŀ
             interface   <uses> 
                              
                                               Ŀ
                - <deklarace konstant>           
                - <deklarace typ>          ;... 
                - <deklarace promnnch>         
                - <hlavika podprogramu>         
                                               
                                   Ŀ
             implementation   <uses> 
                                   
                           Ŀ
                 <deklarace> 
                           
                                    Ŀ Ŀ
                 begin   <pkaz> ;...   
                                     
             end .

     Strun popime jednotliv sti unity:
-  Identifiktor unity je pouvn stejn jako identifiktor
   programu. Navc je nutn pro identifikaci unity v klauzuli
   uses v jinch unitch nebo v hlavnm programu (viz dle).
   Tento idetifiktor MUS bt shodn se jmnem souboru, kter
   unitu obsahuje.
-  st interface obsahuje deklaraci konstant, typ, promnnch
   a podprogram, kter mohou bt pouity v cel unit a ve
   vech unitch (pop. hlavnm programu), v nich je popisovan
   unita uvedena v klauzuli uses. Vimnme si, e u podprogram
   se uvd pouze hlaviky (tlo je popsno a v sti implem-
   entation).
-  st implementation obsahuje lokln deklarace pouvan v
   implementaci podprogram a v inicializan sti unity.
   Objekty zde deklarovan nejsou pstupn mimo unitu (ani v
   sti interface). Identifiktory zde popsanch objekt se
   mus liit od identifiktor pouitch v sti interface.
     Vedle tchto loklnch objekt zde mus bt deklarovny
   vechny podprogramy popsan v sti interface. V hlavikch
   tchto procedur mohou i nemus bt uvedeny parametry (pop.
   vsledek funkce). Pokud vak uvedeny jsou, mus bt zcela
   shodn s popisem v sti interface. Tyto podprogramy nesm
   pouvat directivu FORWARD, nebo byly pedem popsny v sti
   interface.
-  Inicializan st unity, tj. st za begin, me chybt,
   jinak je chpna jako nepojmenovan procedura bez parametr a
   je vyvolvna vdy pi inicializaci unity (viz klauzule
   uses).

     Klauzule USES

     Syntaxe tto klauzule je velmi jednoduch:

     <uses> ::=  <id. unity> ,...  ;

     Tento seznam uruje, kter unity budou pouity pi tvorb
programu. V seznamu unit nesm bt dn unita uvedena dvakrt.
Obsahuje-li nkter unita klauzuli uses v sti interface i
implementation, nesm se ani v tchto seznamech dn unita
opakovat.

     Do seznamu unit v klauzuli uses je (ped prvn unitu) vdy
implicitn zaazena standardn unita SYSTEM, kterou proto nelze
uvdt explicitn.

     Je-li unita uvedena v seznamu uses, mohou se vechny konstan-
ty, promnn i podprogramy specifikovan v sti interface
pouvat, jako by byly deklarovny v mst klauzule uses, a to v
poad zleva doprava. Je-li nkter identifiktor pouit ve vce
unitch zapsanch v seznamu uses, plat vznam definovan na-
posledy, tj. v neposled uveden unit. Lokln deklarace se
zpracovvaj a po vech deklaracch v seznamu uses, tj. za-
krvaj vechny stejnojmenn objekty z unit.

     Na rozdl od zakrytch identifiktor pi voln vnoench
procedur jsou zakryt identifiktory z jinch unit pstupn
pomoc kvalifikace jmnem unity, podobn jako u poloek zznam.
Napklad:
          Crt.Delay     Printer.Lst       System.Write   atd.
Objekty hlavnho programu lze kvalifikovat identifiktorem
programu. Kvalifikace podprogram se s vhodou pouv pi
pedefinovn knihovnch podprogram.

     Unity vyskytujc se v klauzuli uses mohou tak obsahovat
klauzuli uses, a tak vznik stromov struktura vnoench unit.
Objekty specifikovan v interface sti unity vnoen v unitu
specifikovanou v seznamu uses hlavnho programu nebo jin unity
nejsou pmo pstupn. Tyto objekty lze zpstupnit jedin
kvalifikac.

     Po odstartovn programu jsou nejprve provedeny inicializan
sti jednotlivch unit v poad "preorder", tj. zleva doprava,
piem nejprve je zpracovna unita nejhloubji vnoen do prvn
unity seznamu uses. Pro tento el se unity zapsan v klauzuli
uses v sti implementation ad za unity zapsan v klauzuli
uses v sti interface te unity.
     Je-li v tomto strom unit nkter unita uvedena nkolikrt,
provd se jej inicializace pouze jednou.

     Proveden inicializace odpovd voln procedury bez paramet-
r, tj. je provedeno:
          PUSH 0         ; uloen BP - jedn se o samostatn modul
          CALL inicializace  ; adresa vstupnho bodu (voln FAR)

     Inicializan st je peloena jako procedura bez parametr
a je uloena, spolu s ostatnmi podprogramy sti implementa-
tion, do jednoho segmentu, jeho velikost nesm pekroit 64KB a
pi voln z jinch modul nebo z hlavnho programu je vdy
pouito voln FAR.
     Do tohoto kdovho segmentu jsou tak uloeny vechny netypo-
van konstanty, bez ohledu na to, byly-li pouity nebo ne.

     Vechny pouit typovan konstanty a promnn jsou uloeny do
datovho segmentu (a ji z sti interface nebo implementa-
tion), kter je spolen pro vechny unity i hlavn program a
jeho celkov velikost nesm peshnout 64KB.

     Jsou-li nkter unity uvedeny ve vce klauzulch uses (u
rznch unit), jsou vechny jej promnn i konstanty v datovm
segmentu uvedeny pouze jednou!

     Unity nesm bt specifikovny v sti interface ve svch
klauzulch uses kem (jaksi rekurze).
     Pokud by bylo poteba, aby se unity navzjem pouvaly, mus
bt specifikovny v klauzulch uses a v sti implementation.
Bylo-li by poteba vyuvat vzjemn jejich typ ji v sti
interface, je nutn tyto typy uloit do tet unity, a tu potom
volat z obou. Demonstrujme tuto mylenku na nsledujcm p-
kladu:

program P;
uses a,b,Blok;
const
   xb:sb=[];
   xc:sc=[];
begin
    pa(xb);
    pb(xc);
end.

unit A;
interface
   uses BLOK;
   procedure PA (var x:sb);
implementation
   uses b;
   procedure PA;
      var
         xc:sc;
      begin
         if 0 in x then
            begin
            xc:=sc(x);
            pb(xc);
            x:=sb(xc)-[0]
            end
         else x:=x+[0];
   end; { PA }
begin
   writeln('A ');
end.

unit B;
interface
   uses BLOK;
   procedure PB (var x:sc);
implementation
   uses a;
   procedure PB;
      var
         xb:sb;
      begin
         if '0' in x then
            begin
            xb:=sb(x);
            pa(xb);
            x:=sc(xb)-['0']
            end
          else x:=x+['0'];
      end; { PB }
begin
   write('B - ');
end.

unit Blok;
interface
   uses c;
   type
      sb = set of byte;
      sc = set of char;
implementation
begin
   write(' Blok - ');
end.

Vsledkem bude tisk:    " Blok - B - A ".

6.5.2. Kompilace

     Pro peklad jsou podstatn tyto typy uivatelskch soubor:
-  .PAS = Soubory obsahujc zdrojov text
          1. hlavnho programu
          2. nkter unity 
          3. nkter sti programu jako INCLUDE (viz 4.3.3)
-  .OBJ = Object modul , kter lze pilinkovat k programu   
     (viz 7.8.2)
-  .TPU = Pedkompilovan tvar unity, obsahujc piblin:
          -kd programu
          -    seznam popis typ z sti interface
          -seznam popis promnnch a typovanch konstant z sti
         interface
          -velikost pamti pro alokovn loklnch promnnch
          -seznam unit popsanch v klauzulch uses spolu s sly
         verz pslunch .TPU soubor (viz dle)
          -seznam pouitch INCLUDE a .OBJ soubor
-  .TPL = Knihovna .TPU soubor. Pi astm pekldn je zby-
   ten stle vyhledvat odladn .TPU soubory na disku, ale
   sta vyhledat .TPL soubor a pracovat pouze s nm. Peklad se
   tak podstatn zrychl.  Knihovnu lze spravovat pomoc pro-
   gramu TPUMOVER tmito zkladnmi instrukcemi (viz 4.8.2):
          TPUMOVER knihovna /+ unita   - vlo unitu do knihovny
          TPUMOVER knihovna /- unita   - vymae unitu z knihovny
          TPUMOVER knihovna /* unita   - vype obsah knihovny
-  .EXE = Obsahuje spustiteln tvar programu, tj. EXE-hlaviku,
   relokan tabulku, code segmenty vech nepekrvanch unit a
   vechny typovan konstanty.
-  .OVR = Obsahuje code segmenty vech overlayovanch unit (viz 
   6.5.)

     Pro peklad lze pout pkazy COMPILE, MAKE, BUILD. Jejich
rozdl byl popsn ve 4. kapitole. Zajmav je postup zejmna pi
Compile a Make, kdy je pekldno pouze to, co je poteba. Pro
tento el je u soubor .OBJ, .TPU a .PAS sledovno datum a as
posledn aktualizace. Navc u soubor .TPU i slo verze, kter
je ureno jako souet vech byt sti interface.

     Pro ty, kdo prahnou po vdn, uvdme zjednoduen nstin
algoritmu kompilace z hlediska prce se soubory. Znalost tohoto
algoritmu vak pro prci nen nezbytn a tak, chcete-li, klidn
jej peskote.

     Algoritmus kompilace

     Pro zpis algoritmu je pouito dcch pkaz jazyka Pascal
doplnnch o mnoinu etzc a FOR-cyklus pes prvky mnoiny,
co zpis znan zjednodu. Uveden zjednoduen nznak se
nikterak nesna bt korektn a je pouze jakmsi piblenm
skutenho algoritmu. Clem tohoto pseudoprogramu je demonstro-
vn piblinho postupu pi pekladu, z kterho plyne vtina
tvrzen pedchozho odstavce a kter zlatm eskm hlavikm
umon samostatn vymlet dal fakta a fgle...
     Pro jednoduchost nebudeme uvaovat INCLUDE, .OBJ, .TPL soubo-
ry. Jejich zaazen do algoritmu jist ten zvldne sm.

program Kompilace;
type UnitName, FileName : string;
var
     Zpracovn : set of UnitName { Takto to v Pascalu nejde ! };
                         { Mnoina dosud zpracovanch unit }
     Units     : UnitName;
     VersionError : boolean;  { Indikace chybn verze }

Zpracuj ( U : UnitName; Version : longint );

     function Exist ( F : FileName ) : boolean;
     -Vydv true, pokud uveden soubor v pslunm adresi
      existuje;
     function Date ( F : FileName ) : longint;
     -Vypote posledn datum aktualizace v sekundch, pouitm
      systmovho data a asu aktualizace souboru;
     function VersionCount ( U : UnitName ) : longint;
     -Vypote slo verze souboru U+'.TPU', jako souet vech
      byt sti interface;
     procedure Delete ( F : FileName );
     -Smae uveden soubor z disku (diskety);
     procedure Make ( U : UnitName ):
     -Pelo unitu a jej kd spolu s ostatnmi TPU-daji ulo
      do souboru U+'.TPU';

     begin
     VersionError:=false;
     if not U in Zpracovn then
          begin
          if Exist(U+'.TPU') and Exist(U+'.PAS') then
               if Date(U+'.TPU')<Date(U+'.PAS') then Delete(U+'.TPU');
          if Exist(U+'.TPU') then
               begin
                    begin
                    Zpracuj(Units,<Verze uloen u Units v U+'.TPU'>);
                    if VersionError then
                         begin
                         Delete(U+'.TPU');
                         Zpracuj(U,0);
                         exit;
                         end;
                    end;
               end;
          end
     else
          begin
          if not Exist(U+'.PAS') then Error;
          for Units in<seznam uses v sti interface unity U
                     brno zleva> do Zpracuj(Units,0);
          -Vlo peklad sti interface do pamti pro pt Make;
          Zpracovn := Zpracovn + [ U ];
          for Units in<seznam uses v sti implementation unity U
                     brno zleva> do Zpracuj(Units,0);
          if U <> 'MAIN' then Make(U);
          end;
     if (VersionCount(U+'.TPU')<>Version) and (Version<>0) then
          VersionError := true;
     end; { Zpracuj }

begin
     Zpracuj('SYSTEM',0);
     Zpracuj('MAIN',0);
     -Vytvo hlaviku EXE-souboru;
     for Units in Zpracovn <brno od naposled uloenho> do
          begin 
          -Rozvrhne msto v datovm segmentu pro pouit promnn
         a typov konstanty z sti interface, spolu s mstem
         pro lokln promnn z sti interface;
          -Ulo do .EXE-souboru (resp. do .OVR-souboru) kd
         podprogram a inicializan sti
          end;
     -Do .EXE-souboru ulo typovan konstanty.
end.

     Na zvr poznamenejme, e soubory .TPU jsou vytveny vdy,
tj. i tehdy, pokud je kompilace provdna s Destination=Memory.
To samozejm neplat, jsou-li ji umstny v knihovn .TPL.

6.5.3. Unity jako moduly

     Ji v vodu tto kapitoly a pot v povdn o objektech jsme
se zmiovali o MODULECH jako vhodn implementaci ADS. Co to
vlastn je? Modul je samostatn programov celek, kter obsahuje
seznam podprogram, kter se mohou volat z jinch st celho
programu a pomoc nich se d k modulu pistupovat. Vlastn
datov struktura modulu a konkrtn realizace podprogram je
programtorovi vdy utajena.

     Moduly obvykle realizuj nkterou ADS nebo modeluj njak
objekt. Velkm pnosem je oddlen sti interface a implemen-
tation od sebe. Pin to tyto vhody:
-  Prce me bt snadno rozdlena do pracovnho kolektivu
   specifikac st interface potebnch modul.
-  Moduly syntakticky sdruuj celou problematiku do jednoho
   msta programu a orientace v nm je proto snaz.
-  Moduly lze samostatn kompilovat a ladit, co zvyuje sprv-
   nost vslednho programu.
-  Existence interface st konkretizuje minimln poadavky na
   dokumentaci, nebo komentovn vech prvk v interface umo-
   uje ostatnm programtorm (vlastn po njakm ase i Vm)
   jejich snadn a pmoar pouit.
-  Modulrn pstup umouje postupnou precizaci realizace.
   Ukame to na pklad zsobnku (tj. operace PUSH a POP). V
   prvn etap obvykle realizujeme zsobnk co nejjednodueji
   (pomoc pole - viz 6.3). Po ase se teba uke, e vlastn
   potebujeme vce etit mstem a zsobnk pedlme pomoc
   spojovho seznamu. K tto prav nen poteba zasahovat do
   hlavnho programu i jinch unit (kter mohl dlat nkdo
   jin), akoli zsobnk pouvaj. Zmnme pouze implementaci
   pslunho modulu.

     Novj jazyky, jako ADA nebo MODULA, umouj skrt ped
uivatelem vedle implementace podprogram tak strukturu zveej-
nnch typ. Dvod je jasn, zmnme-li implementaci, obvykle
mnme i strukturu tchto typ. Pokud je struktura tchto typ
zveejnna, je nutn upravit pi jej zmn vechny odkazy na
sloky tto struktury a leckdy i podstatn zasahovat do nemodu-
lrn navrenho algoritmu hlavnho programu.

     V praxi se vyskytuj ti typy modul:
-  Modul realizujc ADS.
-  Modul realizujc "interface" mezi paralelnmi procesy a
   automaticky zaruujc jednoznan pstup k datm z paralel-
   n zpracovvanch program (tzv. MONITOR).
-  Modul realizujc interface mezi programem a paraleln pracu-
   jc PERIFERI.

     V Turbo Pascalu m smysl pouze ppad 1. a 3. Oba jsou obvyk-
le realizovny  pomoc unit, nebo ty nejvce odpovdaj my-
lence modulu. Tet ppad se od prvnho li pouze v tom, e v
implementan sti jsou pouvny pkazy pro obsluhu peru-
en, pro prci s vnj pamt, atd., jak o tom budeme hovoit
v 7. a 8. kapitole.

     Pouit unity jako modulu m dv nevhody:
-  Nelze skrt strukturu typ. Je tedy pouze na kzni program-
   tora, aby k slokm typu pistupoval pouze pomoc podprogram
   a nikoli pmo.
-  Nelze vytvoit modul (ani je-li mal) jako soust hlavnho
   programu. Pi vtm potu unit se orientace v nich kompliku-
   je. Doporuuji pro vt programy zakldat vlastn adrese a
   pot Load-Menu bude de facto nabzet seznam dosud vytvoench
   unit spolu s hlavnm programem.

6.5.4. Overlay
       (vznam opt pouze na PC, kter chudci neumj spravovat vt 
       pam ne 640 KB !)

     Pokud je cel program tak velk, e se nevejde do pamti, je
mon kd programu rozdlit na jednotliv sti (OVERLAY), je
jsou do operan pamti ZAVDNY pouze tehdy, jsou-li poteba.
Tmito stmi programu mohou bt pouze unity.

     Tvar unit

     Unity, kter maj bt pekrvny (overlayovny), mus splo-
vat tyto podmnky:
-  Mus zanat direktivou pro peklada {$O+}, co informuje
   peklada, e unita bude overlayovna. Peklada pi voln
   podprogramu se skutenm parametrem volanm hodnotou, jm je
   konstanta typu string, ped kadm volnm ulo tento para-
   metr do zsobnku (v dlce konstanty). Zsobnk je opt
   vyprzdnn pi dalm voln podobnho podprogramu nebo po
   ukonen pslun unity.
-  Vechny procedury a funkce mus bt volny FAR, a to i v
   hlavnm programu.
-  Overlayovan unity nesm obsahovat ovladae peruen (in-
   terrupt handlers).

     Vechny overlayovan unity by tedy mly zanat: {$O+,F+}.

     Overlayovan unity jsou po pekladu (mus bt vdy provdn
na disk) uloeny do souboru s rozenm .OVR a hlavn program
zstv v souboru .EXE.

     Poznamenejme, e ze standardnch unit me bt overlayovna
pouze unita DOS. Ostatn unity, tj. SYSTEM, OVERLAY, CRT, GRAPH,
PRINTER a unity "pro Turbo Pascal 3.0" overlayovny bt nemohou.

     Tvar programu

     Hlavn program mus specifikovat, kter z unit popsanch v
klauzuli uses bude skuten overlayovna. K tto specifikaci se
opt pouv direktiva pro peklada "O", tentokrte s uvedenm
jmna pslun unity. Nap.:

     program Editor;
     {$F+}
     uses Overlay, Crt, Ovr, Edit1, Edit2;
     {$O Edit1}
     {$O Edit2}

     Ped prvnm pouitm nkter overlayovan unity mus bt
inicializovn a nastaven zavad overlayovanch unit. To plat
i pro inicializan sekci unity (jde vlastn o voln proce-
dury). Je proto vhodn koncipovat tuto inicializaci a nastaven
do jedn NEOVERLAYOVAN unity (nap. Ovr v pedchozm pkladu).
Tato unita mus bt v seznamu unit zaazena ped prvn over-
layovanou unitou. Konkrtn pklad takovto unity uvedeme
pozdji.

     Inicializace overlay

     Inicializace dcho systmu overlay je realizovna pomoc

Ŀ
  procedure OvrInit ( FileName : string );                  


     Parametrem tto procedury mus bt soubor obsahujc pelo-
en overlay unity (.OVR). Pi vyvoln OvrInit je tento soubor
vyhledn (nen-li urena cesta - uvauje se: aktuln adres,
adres obsahujc EXE-soubor, adrese podle PATH). Tento
soubor je pot oteven. Pi opakovanm voln je star soubor
pekryt novm (star nen explicitn uzavrn).
     Pi zpracovn tto procedury me dojt k chyb OvrError
nebo OvrNotFound (viz dle OvrResult).
     Pokud nebyla inicializace spn nebo nebyla vbec prove-
dena, dojde pi prvnm pstupu k overlay unit k bhov chyb
208 - Overlay manager not installed.

     Na potku programu je, v zvislosti na seznamu overlayova-
nch objekt, v operan pamti na kor HEAPu alokovn prostor
(BUFFER), pro nejdel overlayovanou unitu. Velikost tohoto
prostoru je nsobkem estncti (zaokrouhlena na cel segmenty) a
je uloena v promnn OvrHeapSize (viz dle). Toto msto je vy-
uvno pi prci s overlay unitami pro jejich zavdn do
pamti a je popsno tmito peddefinovanmi promnnmi:

          var OvrHeapOrg  : word;  { Poten segment bufferu  }
                OvrHeapEnd  : word;     { Koncov segment bufferu    }
                OvrHeapSize : word;     { Minimln velikost bufferu }

     Pokud bychom chtli zrychlit ast zavdn unit, je zpoma-
luje zejmna pstup k overlay souboru, meme tento soubor
zkoprovat do Expanded memory specification (EMS, viz 7.7.4) ,
pokud je v potai instalovna. Toto zkoprovn lze provst
pomoc:

Ŀ
    procedure OvrInitEMS;                                   


     Tato procedura je volna po OvrInit. Dal overlay pot
probhaj pouze mezi vnitn pamt a EMS. Vlastn Overlay
soubor je uzaven. U tto procedury me dojt k chybm: Ovr-
Error, OvrIOError, OvrNoEMSDriver,OvrNoEMSMemory. Dojde-li k
nkter z tchto chyb, je chyba hlena v OvrResult (viz dle),
ale vpoet pokrauje s tm, e overlayovn stle probh na
disk.

     Algoritmus zavade Ovr. u Turbo Pascalu 5.0

     Pro prci s overlay je vyuvn buffer inicializovan po
zahjen programu. Jakmile je vydn poadavek dcmu systmu
overlay na prci s uritou overlay unitou (voln podprogramu,
inicializace unity), je tato zavedena z pslunho OVR-souboru
(pop. z EMS) do bufferu, pokud nebyla zavedena ji dva a
nebyla pepsna jinou unitou.
     Je-li zde dostatek prostoru, je umstna do voln oblasti.
     Nen-li zde dostatek msta, jsou postupn pekrvny, dokud
je poteba, neaktivn unity (tj. ty, jejich podprogram nen
prv aktivn - nem dynamick exempl v zsobnku). Pokud ani
to nesta, jsou podle poteby postupn mazny (pekrvny) i
unity aktivn.

     m vt buffer nastavme, tm vce unit se do nj vejde a
tm mn asto se budou zavdt nov unity z disku (nebo EMS).
Na druh stran m vt bude buffer, tm men bude HEAP.
Nastavenou velikost bufferu v bytech lze zjistit pomoc:

Ŀ
    function OvrGetBuf : longint;                           


     Nov lze velikost bufferu nastavit procedurou:

Ŀ
    procedure OvrSetBuf ( Size : longint );                 


jej parametr uruje novou velikost bufferu Tato velikost me
bt z intervalu: od velikosti nejvtho overlaye (tj. hodnota
OvrGetBuf po OvrInit = OvrHeapSize) a po OvrGetBuf + MemAvail.
Tuto proceduru lze pout, pouze pokud je HEAP przdn (tj.
nebyly dosud pouity podprogramy New, GetMem, InitGraph,... ) a
pokud v bufferu nejsou zavedeny dn overlay unity. V tto
procedue me dojt k chyb OvrError a OvrNoMemory (viz dle) -
 v tom ppad vpoet pokrauje bez zmny bufferu.

     Pokud bychom uprosted programu chtli zmnit velikost buf-
feru, musme vyprzdnit HEAP a vymazat vechny zaveden overlaye
pomoc procedury:

Ŀ
    procedure OvrClearBuf;                                  


     Je-li tato procedura volna z overlay unity, je tato unita
opt ihned zavedena.

     Hlen chyb

     Po kadm vyvoln nkterho z Ovr-podprogram je nastavena
hodnota peddefinovan promnn:

               var OvrResult : integer;

Tato promnn me jako vsledek obsahovat nsledujc ped-
definovan hodnoty:

               const
                    OvrOk = 0;               { Bez chyby                    }
                    OvrError    = -1;   { Chyba v zen overlay       }
                    OvrNotFound = -2;   { Nenalezen soubor .OVR        }
                    OvrNoMemory = -3;   { Nedostatek pamti pro buffer }
                    OvrIOError  = -4;   { I/O chyba u .OVR souboru     }
                    OvrNoEMSDriver = -5;     { Nen instalovno EMS    }
                    OvrNoEMSMemory = -6;     { Nedostatek pamti v EMS }

     Nejastjm dvodem pro chybu OvrError je neexistence dn
overlayovan unity (viz {$O jmno}).

     Algoritmus zavade Ovr. u Turbo Pascalu 5.5

     Verze 5.5 pinesla do problematiky overlay nov zefektivnn.

-  Overlaye jsou ukldny v cyklick front a pro smazn jsou
   pouity vdy ty unity, kter jsou ve front nejdle (bez
   ohledu na to, jsou-li aktivn). Tmto zpsobem je zamezeno
   fragmentaci pamti, nebo fronta je vdy "setsna" k nkte-
   rmu okraji bufferu.
-  Aby bylo zabrnno astmu zavdn frekventovanch unit z
   disku (pop. EMS), je buffer rozdlen na dv oblasti: "pra-
   covn" a "pechodnou". Toto dlen, jak dle popeme, uruje
   programtor na zklad experiment.
-  Hotov .OVR soubor vytvoen s Debug/Standalone Debugging
   nastavenm na Off lze pipojit k .EXE souboru pkazem DOSu:
               COPY /B PROG.EXE + PROG.OVR
   Inicializaci lze provst vyvolnm procedury:
   OvrInit('PROG.EXE')   nebo OvrInit(ParamStr(0))  {viz 7.2.}

     Nyn si vimnme podrobnji druhho bodu:

     Jakmile je zavdna nov unita do bufferu a fronta v pracovn
oblasti je pln, jsou ty unity, je jsou ve front nejdle a
jejich smazn umon zaveden nov unity, pesunuty do oblasti
pechodn. Jsou-li pot optn zavdny dve, ne byly z pe-
chodn oblasti smazny, tj. pouvaj-li se dostaten asto,
jsou zavedeny na potek fronty v pracovn oblasti pmo z tto
pechodn oblasti bez pstupu na disk (EMS) a zde jsou smazny.
Pokud celou "testovac dobu", kdy byly v pechodn oblasti,
nebyly pouity, tj. pouvaj-li se pomrn ojedinle, jsou pi
naplnn pechodn oblasti smazny a pi ptm zavdn budou
zavdny z disku (resp. EMS).
     Programtor mus velikost tto pechodn oblasti (probation
area) specifikovat procedurou:

Ŀ
    procedure OvrSetRetry ( Size : longint );               


     Velikost specifikovan oblasti v bytech mus bt v rozsahu od
0 do OvrGetBuf. Implicitn hodnota je 0. Doporuen hodnoty jsou
asi od 1/3 do 1/2 velikosti celho bufferu.

     Aktuln velikost tto oblasti lze zjistit pomoc:

Ŀ
    function OvrGetRetry : longint;                         


     Pokud byste chtli velikosti bufferu a pechodn oblasti
optimalizovat, mohou Vm k tomu napomoci peddefinovan tae,
jejich hodnoty upravuje dc systm overlay:

          var
          OvrTrapCount : word; { Poet zavdn (i z pechod.obl.) }
          OvrLoadCount : word; { Poet zavdn z disku nebo EMS.  }

     Dal promnnou, uitenou pro st, je promnn:

          var OvrFileMode : byte;

jej hodnota, nastaven ped OvrInit, specifikuje pstupovou
metodu k .OVR souboru (viz sluba Dosu $3D, parametr AL). Impli-
citn je 0, tj. ReadOnly. M-li bt .Ovr soubor sdlen nap. v
sti, je vhodn hodnota 128, tj. Shared - ReadOnly.

     Posledn promnn, spolu se svm typem, umouje uivateli
pout pro .OVR soubor i disketu:

          type OvrReadFunc = function ( OvrSeg : word ) : integer;
          var  OvrReadBuf : OvrReadFunc;

     Tato funkce je volna vdy, kdy je teba zavst novou unitu,
jej identififace je OvrSeg, a ji z disku nebo z EMS. Je-li
zaveden spn, vrac 0, jinak jinou hodnotu a dsledkem toho
je chyba 209 ... .
     Implicitn tato funkce provede pslun zaveden unity a pi
nespchu vyd kd z intervalu $80..$FF.
     Uivatel me tuto funkci zmnit po vyvoln OvrInit, aby v
n nap. oetil vyjmut diskety s OVR-souborem (viz pklad
dle). Je-li zavolna procedura OvrInitEMS, je pouita tato
funkce ke koprovn do EMS. Potom je pouvna opt implicitn
funkce pro zavdn z EMS a uivatel ji me takt pedefi-
novat.

     Pklad: Ovr

     Na zvr povdn o unitch uveme pklad unity, kter by
mla bt v hlavnm programu v seznamu uses zapsna jako prvn
(nebo druh, hned za overlay). Tato unita podporuje prci s
overlay unitami a dopluje (jako pklad) prostedky pro zen
overlay:

{*********************************************************}
{                                                         }
{                UNIT nahrazujic OVERLAY                 }
{                                                         }
{   Zapisuje se jako prvn do seznamu unit namsto unity  }
{   OVERLAY. Provede automaticky nastartovn OvrInit  a  }
{   zavede Error Handling funkci pro Overlay  z  diskety. }
{   Pedpokld .OVR soubor se jmnem jako m .EXE soubor.}
{   Nabz uivatelsky orientovan podprogramy pro prci  }
{   s bufferem a pechodnou oblast.                      }
{                                                         }
{*********************************************************}

unit OVR1;

interface

   procedure SetBufferByHeap ( HeapSize : longint );
   { Nastav velikost bufferu tak, aby zbylo pouze HeapSize
     byt pro Heap, je-li to mon. spnost procedury  je
     indikovna v promnn OvrResult. }

   procedure SetRetry ( Percent : byte );
   { Nastav velikost pechodn oblasti tak, aby inila pr-
     v Percent % z velikosti bufferu. Je-li promnn Percent
     vet ne 100%, dosad se implicitn hodnota 50%. }

   function Effectivity : byte;
   { Vsledkem je poet procent zaveden z disku z celkovho
     potu zavadench unit. }

     const Mode : byte = 0;  { ReadOnly mode pro .EXE soubor }

implementation

   uses Overlay, Dos, Crt;

   var
      SaveOvrRead : OvrReadFunc;
      UsingEMS    : boolean;

   procedure Error ( s : string; hlt : boolean );
   { Vype na doln dek obrazovky hleni "S" a je-li hlt
     rovno true, zastav vpoet, jinak pokrauje dl. }
   begin
      GotoXY(1,25);
      writeln('*** Overlay ERROR : '+s+' ***');
      if hlt then HALT;
   end; { Error }

   {$F+}
   function MyOvrRead ( OvrSeg : word ) : integer;
   { ErrorHandling funkce ( viz dokumentace k Overlay ). }
   var
      E : integer;
   begin
      repeat
         E := SaveOvrRead ( OvrSeg );
         if E <> 0 then
            if UsingEMS then Error ( 'EMS failure', true )
            else Error ( 'Insert source diskette', false )
      until E = 0;
      MyOvrRead := 0;
   end; { MyOvrRead }
   {$F-}

   procedure SetBufferByHeap;
   begin
      if HeapSize > MemAvail then OvrResult:=OvrNoMemory
      else OvrSetBuf ( OvrGetBuf + MemAvail - HeapSize );
   end; { SetBufferByHeap }

   procedure SetRetry;
   begin
      if Percent > 100 then Percent := 50;
      OvrSetRetry ( Round ( OvrGetBuf * Percent / 100 ) );
   end; { SetRetry }

   function Effectivity : byte;
   begin
      Effectivity := Round (OvrLoadCount/OvrTrapCount*100);
   end; { Effectivity }

begin

   OvrFileMode := Mode;   { Nastaven mdu .OVR souboru. }

     { Oteven .OVR souboru. }
   repeat
      OvrInit ( Copy ( Paramstr (0), 1,
                Length ( Paramstr(0) ) - 4 ) + '.OVR' );
      case OvrResult of
           OvrError    : Error ( 'Manager Error', true );
           OvrNotFound : Error ( 'Insert source diskette',
                                 false );
           OvrNoMemory : Error ( 'No Memory', true );
           OvrIOError  : Error ( 'I/O', false );
           end;
   until OvrResult <> -2;

        { Zaveden MyOvrRead funkce }
   SaveOvrRead := OvrReadBuf;
   OvrReadBuf  := MyOvrRead;
     { Vyuit ppadnho EMS }
   UsingEMS := false; { Funkce slu pro zavdn do EMS }
   OvrInitEMS;
   if OvrResult = OvrOK then UsingEMS := true   { EMS OK }
end.

6.5.5. Standardn unity

     Ji nkolikrt jsme se zmiovali o tom, e TurboPascal obsa-
huje peddefinovan unity. Vtina z nich je uloena v knihovn
TURBO.TPL, pouze grafick unita GRAPH.TPU je pro svj rozsah
ponechna samostatn.

     Zopakujme pehled standardnch unit:
Crt    - Podporuje prci s periferiemi, podrobn je tato unita
         popsna v osm kapitole.
Dos    - Podporuje prci se soubory, pouvn slueb Dosu a
         Biosu. Popis tto unity je na konci sedm kapitoly.
Graph  - Obsahuje prostedky pro grafick vstupy na monitor.
         Podrobn popis tto unity je uveden v devt kapitole.
Graph3 - Realizuje grafiku verze 3.0, kter se ji prakticky
         nepouv, a proto se touto unitou nebudeme zabvat.
Turbo3 - Zajiuje kompatibilitu s verz 3.0 - opt vynechme.
Overlay - Obsahuje prostedky pro prci s overlay tak, jak to
               bylo popsno v pedchozm odstavci.
Printer - Umouje pm vstup na tiskrnu, jak jsme o nm
               hovoili v pt kapitole.
System - Jde vlastn o "Run-time modul", obsahujc zkladn
         prostedky pro prci s daty a pro zen vpotu, jak
         je postupn popisujeme v souvislosti s kontextem.

     Popisem unity z hlediska uivatele je popis jejho interface.
Na tomto mst popeme ti posledn jmenovan unity, tj. uve-
deme jejich interface:

     Overlay

unit Overlay;  { viz pedchoz odstavec }
interface
   uses Dos;

     const { Kd chyby }
          OvrOk = 0;
          OvrError = -1;
          OvrNotFound = -2;
          OvrNoMemory = -3;
          OvrIOError = -4;
          OvrNoEMSDriver = -5;
          OvrNoEMSMemory = -6;

     var
          OvrResult    : integer;               { Indikace chyby }
          OvrTrapCount : word;     { Celkov poet zavdn ovr. }
          OvrLoadCount : word;   { Poet externch zavdn ovr. } 
          OvrFileMode  : byte;         { I/O mod overlay soubor }

     type                     
          OvrReadFunc = function ( OvrSeg : word ) : integer;
     var
          OvrReadBuf : OvrReadFunc; { Implicitn obsluha chyb }

     procedure OvrInit(Filename:string);
     procedure OvrInitEMS;

     procedure OvrSetBuf(Size:longint);
     function  OvrGetBuf:longint;
     procedure OvrClearBuf;

     procedure OvrSetRetry(Size:longint);
     function  OvrGetRetry:longint;




     Printer

unit Printer;
interface
     uses Crt;
     var Lst : Text;     { viz 5. kapitola }
implementation
begin
     assign(Lst,'LPT1');
     rewrite(Lst);
end.




     System

unit System;
interface

   var { viz 5. kapitola }
      Input : Text;          { Standardn vstupn soubor }
      Output : Text;          { Standardn vstupn soubor }

   const { viz 3.4.7., 6.1.3., 7.1. }
      PrefixSeg : word = 0;       { Program segment prefix }
      HeapOrg : pointer = nil;             { Zatek HEAPu }
      HeapPtr : pointer = nil;              { HEAP pointer }
      StackLimit : word = 0; { Nejmen velikost zsobnku }
      FreePtr : pointer = nil;     { Ukazatel na Free list }
      FreeMin : word = 0;   { Minimln velikost Free list }


   const { viz 5., 6.1., 6.6., 7.5. }
      InOutRes : integer = 0;                  { Kd chyby }
      HeapError : pointer = nil;       { Heap error funkce }
      ExitProc : pointer = nil;           { Exit procedura }
      ExitCode : integer = 0;              { Nvratov kd }
      ErrorAddr : pointer = nil;     { Adresa bhov chyby }
      RandSeed : longint;    { Hnzdo nhodnho genertoru }
      FileMode : byte = 2;                   { Md souboru }
      Test8087 : byte = 0;                { Existence 8087 }


   const { viz pedchoz odstavec }
      OvrHeapSize: word = 0;       { Velikost ovr. bufferu }
      OvrHeapOrg: word = 0;         { Zatek ovr. bufferu }
      OvrHeapEnd: word = 0;           { Konec ovr. bufferu }
               { Promnn, jejich vznam pesahuje uiva- 
                 telsk pstup k Turbo Pascalu  ( nejsou  
                 dokumentovny ani v Reference Guide T.P.) }
      OvrCodeList: word = 0;         
      OvrDebugPtr: pointer = nil;    
      OvrHeapPtr: word = 0;          
      OvrLoadList: word = 0;         
      OvrDosHandle: word = 0;        
      OvrEMSHandle: word = 0;        

   var { viz 7.6 }
      SaveInt00,SaveInt02,SaveInt1B,SaveInt23,
      SaveInt24,SaveInt34,SaveInt35,SaveInt36,
      SaveInt37,SaveInt38,SaveInt39,SaveInt3A,
      SaveInt3B,SaveInt3C,SaveInt3D,SaveInt3E,
      SaveInt3F,SaveInt75: pointer;

     procedure & function -Tato unita obsahuje okolo 90 procedur
                           a funkc. Jejich popis by byl zdlou-
                           hav a zbyten, nebo jsou vdy
                           vysvtleny jinde. Zde uvedeme pouze
                           jejich abecedn seznam:

   Abs           Exit          MkDir         Round
   Addr          Exp           Move          RunError
   Append        FilePos       New           Seek
   ArcTan        FileSize      Odd           SeekEof
   Assign        FillChar      Ofs           SeekEoln
   BlockRead     Flush         Ord           Seg
   BlockWrite    Frac          ParamCount    SetTextBuf
   ChDir         FreeMem       ParamStr      Sin
   Chr           GetDir        Pi            SizeOf
   Close         GetMem        Pos           SPtr
   Concat        Halt          Pred          Sqr
   Copy          Hi            Ptr           Sqrt
   Cos           Inc           Random        SSeg
   CSeg          Insert        Randomize     Str
   Dec           Int           Read (typed)  Succ
   Delete        IOResult      Read (text)   Swap
   Dispose       Length        Readln        Trunc
   DSeg          Ln            Release       Truncate
   Eof (typed)   Lo            Rename        UpCase
   Eof (text)    Mark          Reset         Val
   Eoln          MaxAvail      Rewrite       Write (typed)
   Erase         MemAvail      RmDir         Write (text)
                                             Writeln


     Velikosti unit

     Mnohdy se programtoi sna nepouvat standardn unity, aby
"zbyten neobsazovali pam nm, co nezbytn nepotebuj".
Tato mylenka je obvykle zavdjc. Jak jsme si ji ekli, do
pamti se ukldaj pouze pouit promnn a podprogramy. Je
pravdou, e inicializace jednotlivch unit nco stoj, i kdy je
v programu dle nepouijeme. Podvejme se kolik (daje jsou
uvedeny v bytech):

      Ŀ
         Jmno    Minimum   Kd      Data    Symboly 
      Ĵ
         System            21332      664     4636   
         Crt       1600     1555       20     1651   
         Dos          0     1585        5     4143   
         Graph     4000    16373     1070     9001   
         Overlay      0     1586       10      696   
         Printer    336       37      256      276   
      

     Hodnoty v tabulce postupn uvd, kolik byt zabere pouh
uveden unity do seznamu use (inicializace), jak je celkov
velikost jejich Code segmentu, kolik zabraj pi plnm vyuit
z Data segmentu a kolik symbol obsahuj.
     Jak je vidt, inicializaci provd (mimo Printer) pouze unity
Crt a Graph. Je to pochopiteln, nebo pracuj s periferiemi a
mus nejprve otestovat jejich stav (nap. druh videoadaptru).
Tyto testy nm pot usnaduj cestu pi budovn vysoce kvalit-
nho uivatelskho prosted a jejich velikost za to stoj.

6.5.6. Pouit unit - shrnut

     Unity se tedy pouvaj k tmto elm:
-  Jako programov balky obsahujc destky podprogram, kter
   jsou orientovny jednm smrem: DataBase Tool Box, Menu
   System, Statistic Tool Box atd. Tyto unity jsou obvykle
   vyrbny firemn (u ns z nouze i jednotlivci) a je mon je
   zakoupit jako rozen jazyka. Pouvte-li takovch unit
   vce, je vhodn je pipojit do Turbo.TPL (d se pedpokldat,
   e jsou dobe), m znan zrychlte peklad. Mimochodem,
   tyto firemn programy ve zdrojovm tvaru jsou velmi dobrou
   cviebnic Turbo Pascalu...
-  Jako implementace ADS, o em jsme ji hovoili.
-  Jako interface s perifernm zazenm (nap. CRT-unit). Tyto 
   unity jsou takt vyrbny firemn (Mouse Driver, atp.). Na
   rozdl od programovch balk, kde jde obvykle o implementaci
   njakch vce i mn znmch algoritm, psan takovchto
   unit vyaduje velmi dobrou znalost perifernch zarzen a
   jejich ovlada (driver), no a samozejm ltky probran v
   7. a 8. kapitole.
-  Jako overlay, tj. logick komponenta rozshlho programu,
   kter by bez pekrvn nebylo mono pod Dosem provozovat.
     Dekompozice rozshlch program by se pirozen mla
   snait vyuvat pirozench rozhran plynoucch z modularity
   a strukturovn programu.
-  Jako komponentu programu, jeho velikost kdu by bez dekom-
   pozice pesahovala 64KB.
-  Jako model njakho objektu. Tento pojem je velmi blzk ADS.
   Prakticky jde o implementaci souhrnu podprogram modeluj-
   cch interakci objektu s okolm. Takovchto struktur se
   pouv pi objektov orientovanm programovn a jsou velmi
   vhodn pro rozdlen prce mezi pracovn kolektiv.
6.6. Pseudonhodn sla

     Nhodn posloupnost sel je takov posloupnost, kter vznik-
ne realizac nezvislch nhodnch veliin (nap. hzen kost-
kou). V mnohch lohch simulace a modelovn (a v potaovch
hrch) se nkter procesy d statistickmi rozdlenmi. Aby-
chom tyto nhodn jevy mohli modelovat, potebujeme postupn
sla z pslunho rozdlen.

     Jak je z matematick statistiky znmo, vechna pouvan
rozdlen lze vytvoit na zklad rozdlen rovnomrnho. Sta
nm, budeme-li mt posloupnost sel s rovnomrnm rozdlenm.

     Chceme ale vbec nhodn sla? Ne! Jak bychom ladili? Vdy
bychom nikdy nemohli vpoet opakovat. My tedy potebujeme
sla, kter maj statistick vlastnosti nhodnch sel, ale
pi opakovanm bhu jsou stejn. Tato sla obvykle vytvme
aritmetickmi operacemi (kongruenn genertory). Takovm slm
kme PSEUDONHODN. S ohledem na konenost uloen sel v
potai mus bt tato posloupnost periodick. Hovome potom o
dlce nebo period pseudonhodn posloupnosti sel. Funkce,
kter postupn vydv sla z takovto posloupnosti, se nazv
Genertor pseudonhodnch sel.

     Genertor pseudonhodnch sel

     V TurboPascalu je genertorem pseudonhodnch sel funkce
RANDOM, kter se me vyskytovat ve dvou tvarech:

Ŀ
    function Random : real;                                 


     Tato funkce generuje pseudonhodn reln sla z intervalu
<0,1).

Ŀ
    function Random ( var X : word ) : word;                


     Tato funkce generuje pseudonhodn cel sla z intervalu
0..X-1.

     Tento genertor m pro vtinu aplikac velmi dobr para-
metry. Napklad pi testovn posloupnosti dlky 50000 vychz:
-  Generovan posloupnost m rovnomrn rozdlen (ovovno
   testem dobr shody na hladin 95%).
-  Posloupnost je dostaten nhodn ve smyslu lokln nhod-
   nosti (vechny intervaly jsou "stejn" obsazeny).
-  Vbrov momenty jsou uvedeny v nsledujc tabulce:

          Ŀ
                            Skuten  Vbrov 
               MOMENTY       hodnoty   hodnoty 
          Ĵ
           Stedn hodnota   0.5000    0.4997  
           Rozptyl           0.0833    0.0828  
           ikmost           0.0000   -0.0004  
           piatost         1.8000    1.8007  
          

     Hnzdo 

     Genertor pouv peddeklarovanou promnnou (tzv. Hnzdo):

          var RandSeed : longint;

     Postupnm volnm funkce generuje cel sla podle vzorce:
          RandSeed := 1 + ( RandSeed * 1347758130 ) mod 4294967296.
Potom na zklad vygenerovan hodnoty vytvo pslun cel
nebo reln slo z poadovanho rozsahu.

     Vytvoen hodnota RandSeed je vdy zvisl na hodnot ped-
choz. Z toho plyne, e nastaven RandSeed na njakou hodnotu
uruje vechny dal generovan hodnoty. (Jde o sla PSEUDO-
nhodn).

     Inicializace hnzda

     Na potku bhu programu je automaticky inicializovna hod-
nota RandSeed (jde vlastn o typovanou konstantu) na nulu.

     Ve vslednch programech (zejmna u her) mnohdy potebujeme
hnzdo "znhodnit". K tomuto elu slou procedura:

Ŀ
    procedure Randomize;                                    


     Tato procedura nastav hodnotu RandSeed v zvislosti na
systmovm ase (CLOCK).

     Nezvisl posloupnosti

     Mnohdy potebujeme v jedn loze vce nezvislch genertor.
Nyn popeme nkolik zkladnch metod, jak se s tmto problmem
vypodat:
-  Napsat si vlastn genertory. Tento postup zajist 100%
   nezvislost. Bohuel tento kol nen tak jednoduch, zejmna
   pi vtm potu genertor, nebo kvalita genertoru zvis
   na vhodn zvolench konstantch a jejich nalezen je obvykle
   velmi nesnadn. Je teba si uvdomit, e genertor, jeho
   momenty se shoduj s teoretickmi momenty, nemus vbec
   vyhovovat poadavku rovnomrnosti.
-  Pouvat stle funkci Random. Tato metoda je velmi jedno-
   duch. Jej nevhodou je jist zvislost vytvoench posloup-
   nost. Tato zvislost je pro vtinu aplikac, s ohledem na
   kvalitu genertoru a vnitn zvislost v kad posloupnosti
   plynouc z filozofie pseudonhodnch sel, snesiteln mal.
-  Zvislost vslednch posloupnost v pedchozm ppad lze
   odstranit pravidelnm stdnm jednotlivch genertor.
   Rada je to jednoduch, ale leckdy zcela nerealizovateln.
-  Dalm eenm je stdn hnzd.
     Jak ji vme, kad pseudonhodn posloupnost sel je
   periodick. Horn odhad pro dlku posloupnosti generovan
   funkc RANDOM je 4294967296, ale skuten dlka bude asi
   men, nebo v posloupnosti nemus bt zahrnuta vechna sla
   typu longint. Odhaduji ji dov na miliardu. (Pesn oven
   dlky by stlo asi tden nepetritho provozu potae).
     Prakticky vyuvme pouze kousek a periodinost nm
   vbec nevad. Tento fakt ns zrove pivd na mylenku,
   vyut jednotliv seky posloupnosti jako nezvisl poslou-
   pnosti (zvislost je zcela zanedbateln).
     Jedinm problmem je uren dostaten od sebe vzdlench
   hnzd, aby se nestala jedna posloupnost soust druh, m
   by se stala zcela zvislou. Tyto konstanty lze urit pouze
   experimentln v zvislosti na pedpokldan dlce vyuvan
   posloupnosti. Pro jednoduch ppady obvykle sta hnzda 1,
   2, 3, 4,..., jejich vzdlenost je vt ne 100000 a slo-
   vn je velmi vhodn.
          Pro generovn potom pouvme takovouto funkci:
               function RND ( var Hnizdo : longint ) : real;
               begin
                    RandSeed:=Hnizdo;
                    RND:=Random;
                    Hnizdo:=RandSeed;
               end;
-  Posledn navrhovan een generuje takt pln nezvisl
   rozdlen pi dostaten kvalitnm genertoru a, a je o nco
   pracnj a nronj, je pomrn dobe realizovateln.
   Metoda smench genertor se sna potlait jakoukoli
   zvislost v generovan posloupnosti.
   Postup:
     -generujeme posloupnost Y0,Y1,... z R(0,1)
     -prvnch N len posloupnosti Y0,Y1,... ulome "na adresy
      0,...,N-1" (posloupnost meme ukldat teba do pole)
     -generujeme dal posloupnost R0,R1,... z R(1,...,N)
     -novou posloupnost zskme tak, e vezmeme R0-t len
      posloupnosti Y, na jeho msto do pamti ulome YN, dal
      nhodn slo zskme jako R1-n len Y, hodnotu opt
      nahradme N+1-nm lenem posloupnosti Y, popsanm zpsobem
      generujeme novou posloupnost X0,X1,...
   Vsledek metody zvis na kvalit pouitch genertor,
   meme ji tedy s spchem V TP pouvat. Hod se pro simulaci
   nezvislch nhodnch sel. Nevhodou je, e musme vyge-
   nerovat dv nhodn sla Y,R, abychom zskali X.

    Otzky a cvien

  1.  Jak formty pkazu NEW znte a k emu slou?
  2.  Popite organizaci HEAPu a procedury a funkce, kter s nm
      pracuj. K emu slou promnn HeapError?
  3.  Jak lze v Turbo Pascalu realizovat dynamick pole?
  4.  Co je Abstraktn datov struktura? Uvete pklady jejho
      pouit a jej implementace.
  5.  Jak typy implementac spojovho seznamu znte? Napite
      proceduru INSERT pro kruhov seznam s hlavou.
  6.  Popite principy HASH - struktur. Jak je rozdl mezi Open
      Hash a Close Hash.
  7.  Vyjmenujte principy objektov orientovanho programovn a
      vysvtlete je.
  8.  Co je to virtualizace metod? K emu se pouv a jak
      pin programtorovi vhody?
  9.  Co je VMT a co o ni vte?
 10.  Jak se li konstruktor a destruktor od ostatnch podpro-
      gram?
 11.  Jakou syntaxi maj unity?
 12.  Popite algoritmus kompilace rozshlho programu.
 15.  Jak vyuit maj unity v Turbo Pascalu?
 16.  Jak lze generovat nezvisl pseudonhodn posloupnosti
      sel?7. Spoluprce s DOSem





7. Spoluprce se systmem

7.2. Parametry programu

     Spoutte-li program z pkazov dky, zadvte jeho jmno a 
seznam parametr. Parametry me zskat program na Atari napklad 
tak penesenm ikony libovolnho souboru na ikonu spoutnho 
programu, kter dostane jako parametr prv jmno tohoto pesunutho 
souboru (Drag & Drop protocol).
Podobn, spoutte-li program z integrovanho systmu,
mete zadat jeho parametry ve volb Option/Parameteres. Tyto
parametry budou mt smysl pouze tehdy, budete-li je v programu
st. K tomu slou nsledujc dv funkce:

Ŀ
    function ParamCount : word;                             


     Tato funkce vrac poet parametr programu (nen-li dn,
vrac nulu), piem jako oddlova jednotlivch parametr me
bt pouita pouze mezera. Hodnotu I-tho parametru vrac

Ŀ
    function ParamStr ( I : word ) : string;                


     Vsledkem tto funkce je:
-  pro I=0 : Cel nzev spoutnho programu (drive i cesta),
   nap.: C:\TP\MUJPROG.PRG.
-  pro 0<I<=ParamCount : Vsledkem je I-t parametr.
-  pro I>ParamCount : Vsledkem je przdn etzec ('').


7.3. Promnn DOSu
     
     Operan systm nabz uivateli nkolik promnnch, kter
popisuj jeho konfiguraci. Pro Ataristy plat ta zsada: Ovte si 
funkci danho pkazu na ST v on-line helpu, nebo nkter vci 
mohou bt v podstat identick s PC, ale jin mohou pln chybt.

     VER

     Verzi systmu meme zskat pomoc funkce

Ŀ
    function DosVersion : word;                             


V dolnm bytu vsledn promnn je uloeno hlavn slo verze
(nap. 3) a v hornm slo doplkov (nap. 30), take pi
operanm systmu DOS 3.30 pkaz write( Lo(DosVersion), '.',
Hi(DosVersion) ) vytiskne vraz   "3.30".

     VERIFY

     Pkaz DOSu VERIFY lze ovldat pomoc

Ŀ
    procedure GetVerify ( var On : boolean );               


kter nastav true, je-li VERIFY ON a pomoc

Ŀ
    procedure SetVerify ( var On : boolean );               


kter podle hodnoty parametru nastav promnnou DOSu.

     BREAK

     Stav pepnae BREAK lze otestovat pomoc

Ŀ
    procedure GetBreak ( var On : boolean );                


kter vrac true, je-li BREAK ON.

     SET

     Uivatel me definovat sv vlastn promnn DOSu v oblasti
Environment pomoc pkazu SET. Pstup k takto definovanm
promnnm, kter jsou uloeny v etzci (jeho dlka je speci-
fikovna pi inicializaci systmu), je analogick jako u para-
metr programu.
     Poet promnnch nastavench pomoc SET vydv

Ŀ
    function EnvCount : integer;                            


     I-tou promnnou obdrme v textovm tvaru pomoc

Ŀ
    function EnvStr ( I : integer ) : string;               


Jestlie I<1 nebo I>EnvCount, funkce EnvStr vrac przdn et-
zec ('').
     Pokud byste se na promnnou chtli odvolvat pmo, zskte
jej hodnotu pomoc

Ŀ
    function GetEnv ( DosVariable : string ) : string;      


Jestlie pslun DosVariable neexistuje, vrac przdn et-
zec. Pi zadvn jmna promnn nezle na velikosti psmen.
     Poznamenejme, e pomoc tto funkce lze zskat nap. i hodnotu
PATH (pokud je definovna) volanou pomoc GetEnv('PATH').


7.4. Spoutn proces (pro PC IBM)

Ŀ
  procedure Exec ( Proces, ParamLine : string );            


Prvnm parametrem je jmno programu, a to I S JEHO ROZENM,
poppad celou cestou, resp. drivem. Pi vyhledvn tohoto
souboru je (nen-li explicitn uveden adres) prohledvn pouze
aktuln adres (PATH je ignorovn!). Druhm parametrem je
seznam parametr pejman pomoc ParamStr.

     Uvdomme si, e sputnmu procesu je pln pedno zen
(neb paraleln), ale v pamti je uloen vedle svho RODIE.
Po skonen procesu se vpoet vrt za voln procedury Exec   
do rodiovskho procesu. Na tomto mst meme ovit, byl-li
proces skuten sputn (DosError=0) nebo ne (DosError=2, 8,
10, 11) - viz 7.5.

     Nvratov kd procesu lze zskat pomoc funkce DosExitCode
(viz 7.5.).

     Poznamenejme jet, e pi voln procesu i jeho nvratu je
automaticky provdna procedura SwapVectors (viz 7.6.).


7.5. Indikace chyby

     Velmi dleitm prvkem bezpenho programovn je vasn
indikace chyb. Pehled chybovch hlen je uveden v dodatku C.
Chyby lze rozdlit podle toho, jestli ukonuj vpoet nebo ne.
     Prvnm typem chyb jsou natolik podstatn bhov chyby, e
vpoet ihned peruuj.
     Druhm typem jsou chyby v podprogramech jednotlivch unit,
kter neperuuj vpoet, ale jeho dal prbh me bt chy-
bn. 
     Pesnou hranici mezi obma typy chyb nelze pesn urit,
nebo mnoh chyby neperuujc vpoet jsou pouze "obhospoda-
en" podstatn chyby (viz {$I-}).
     Tyto chyby vznikaj nejastji pi voln slueb DOSu, a
proto kdy mnohch chyb odpovdaj kdm pslunch chyb DOSu.

7.5.1. Indikace chyb v unitch

     Zde probereme zpsob, jakm jsou indikovny chyby neperuu-
jc bh programu pi provdn podprogram ze standardnch
unit.

     Chyby v podprogramech unity OVERLAY jsou indikovny v pro-
mnn OvrResult (viz 6.5.5., C.3.).

     Chyby v podprogramech unity GRAPH jsou dostupn pomoc funkce
GraphResult (viz 9.1.3., C.4.).

     Chyby v podprogramech unity DOS jsou indikovny v promnn
               var DosError : integer;  (viz C.2.).

     Unity CRT a PRINTER negeneruj dn chybov kdy.

     Specilnm ppadem je unita SYSTEM. Pi nastaven {$I+}
dnou indikaci chyb neprovd a rovnou ukon vpoet. Pi
nastaven {$I-} dojde k bhov chyb (viz C.2.) pouze tehdy,
nejde-li o chybu pi vstupn/vstupn operaci (nap. Division by
zero, Range check error, atd.). Jde-li o chybu pi vstupn/v-
stupn operaci, vpoet peruen nen a slo chyby je uloeno
do promnn

               var InOutRes : integer;

Kd tto chyby lze tak zskat pomoc voln funkce

Ŀ
  function IOResult : integer;                              


kter vrac hodnotu InOutRes a zrove ji nuluje.

     Pro vechny unity plat, e spnmu proveden sledovanho
podprogramu odpovd kd 0. Kd chyby je v pslun promnn
uloen:
-  Dokud nen programtorem explicitn pepsn.
-  U Overlay a DOS:  Dokud nen proveden dal podprogram te
                     unity nastavujc takt chybov kd.
     U Graph a System:Dokud nen volna funkce, kter jej nuluje
                     (GraphResult, IOResult).

     U unity SYSTEM mus bt pznak chyby jednm z uvedench
zpsob vynulovn ped volnm dalho podprogramu pro vstup
nebo vstup. Pokud se tak nestane, je vsledek nedefinovn
(pesnji: pi {$I+} je ohlena chyba nebo podprogram neprovede
nic nebo pracuje normln). U unity Graph zle na typu chyby
(viz kapitola 9).

     Pouit tchto indikac chyb demonstrujme na pkladu ten
sel ze vstupu pomoc procedury Readln:

program IO;
uses Crt;
var i,IOR : integer;
begin
   {$I-}
     repeat
     write('Zadejte cislo: ');
     readln(i);
     IOR:=IOResult;
     if IOR<>0 then writeln('Zadana hodnota neni cislo');
     until IOR=0;
end.

     Poznamenejme, e promnnou IOR nelze nahradit (pi vymazn
piazovacho pkazu) ani pomoc IOResult (cyklus by ihned
skonil) a ani pomoc InOutRes (cyklus by nikdy neskonil, nebo
dal voln read, write a writeln by se neprovedla).

7.5.2. Nvratov kdy

     Kad program (i proces) pi svm ukonen vrac jako v-
sledek nvratov kd. Tento kd lze po nvratu do operanho
systmu v dvkovm zpracovn testovat pomoc ERRORLEVEL (pe-
snji jeho doln byte).

     Program me bt ukonen pti zpsoby:

a) Program pejde pes koncov END. Nvratov kd je 0.

b) Bhov chyba. Nvratovm kdem je kd bhov chyby.
     Pokud bychom chtli ukonit program konkrtn bhovou
   chybou, a ji chybou stanovenho vznamu nebo chybou, jej
   vznam definujeme sami, meme pout proceduru:

Ŀ
  procedure RunError ( ErrorCode : word );                  


   Tato procedura vygeneruje chybu s danm kdem, vyd pslun
   chybov hlen a vpoet ukon. Procedura me bt zapsna
   i bez parametr, co je tot jako RunError(0). Napklad:

               const Input_Value_Out_Of_Range = 99;
               var   x : word;
               begin
                    Readln(x);    { Zde me bt pouze 1..10 }
                    if x>10 then RunError( Input_Value_Out_Of_Range );
               end.
   
Je-li vstupn hodnota 11, je vpoet zastaven a vydno hlen:
"Runtime error 99 at 0000:006D".

c) Pedasn ukonen vpotu procedurou

Ŀ
  procedure Halt ( ExitCode : word );                       


   Tato procedura ukon vpoet a nastav nvratov kd na
   hodnotu ExitCode. Procedura me bt zapsna i bez parametr,
   co je tot jako Halt(0).

d) Podobn vznam m i procedura 

Ŀ
  procedure Keep ( ExitCode : word );                       


   jej pesn popis uvedeme v 7.6. Nvratov kd je roven
   ExitCode + 768.

e) Je-li nastavena promnn

               var CheckBreak : boolean;

   na true (implicitn hodnota), je stisknut klvesy Ctrl-Break
   pi provdn vstupn-vstupn operace chpno jako uiva-
   telsk ukonen bhu programu. V tomto ppad je nvratov
   kd roven 255.

     Nvratov kd procesu (viz 7.4.) lze ve volajcm programu
obdret pomoc 

Ŀ
  function DosExitCode : word;                              


kter zrove tento nvratov kd vynuluje (srovnej s IOResult).

7.5.3. Exit procedura

     Ped ukonenm bhu programu je volna uivatelsk EXIT
procedura, jej adresa mus bt uloena v promnn:

               var ExitProc : pointer;

     Je-li v tto promnn nil, co je implicitn hodnota, dn
voln se neprovede. Uivatelsk procedura nesm mt dn
parametry a mus bt volna jako FAR.

     Nkter knihovn unity pouvaj voln EXIT procedury. Je
tedy dobrm zvykem pi inicializaci EXIT procedury nejprve
uloit pvodn hodnotu ExitProc a v zvru voln EXIT procedury
tuto hodnotu opt obnovit.
     Ped kadm volnm EXIT procedury je do promnn ExitProc
piazena hodnota nil. Je-li po ukonen v ExitProc nov hod-
nota, tj. adresa dal EXIT procedury (nap. z unity), vyvol se
tato procedura. To se opakuje tak dlouho, dokud v ExitProc
nezstane pvodn hodnota nil. Algoritmus voln vnoench EXIT
procedur meme popsat takto:
             while ExitProc<>nil do CALL(ExitProc).

   Pi voln prvn EXIT procedury jsou nastaveny tyto promnn:

               var ExitCode : integer;

obsahujc nvratov kd a

               var ErrorAddr : pointer;

v n je uloena adresa bhov chyby v kdu programu (resp.
RunError). Pi normlnm ukonen programu (resp. Halt, Keep,
Ctrl-Break) je v ErrorAddr uloen nil. V EXIT procedurch lze
ob tyto promnn aktualizovat.

     Systmov EXIT procedura (volan jako posledn, kdy je v
ExitProc hodnota nil) uloen v unit SYSTEM uzave soubory
INPUT a OUTPUT, provede SwapVectors a pokud ErrorAddr nen nil,
vyd Runtime error hlen.

     EXIT procedura vydvajc vlastn chybov hlen a uzavra-
jc pracovn soubor F me mt tento tvar:

program Exit_Procedura;
uses Crt;
var
    ExitSave:pointer;      {Adresa pedchoz EXITproc}
    F:text;
{$F+}
procedure MyExit;
const ExitError:boolean=false;
begin
   ExitProc:=ExitSave;     {Specifikuji druhou proceduru}
   if ErrorAddr<>nil then  {Pokud dolo k chyb}
     writeln('Behova chyba cislo: ',ExitCode:3,' na ',
         'adrese: ',Seg(ErrorAddr^),':',Ofs(ErrorAddr^));
   ErrorAddr:=nil;         {Zabrnm systmovmu hlen chyby}
   if not ExitError then   {Nebyl-li dosud F uzavrn}
      begin
      ExitError:=true;
      ExitProc:=@MyExit;   {Pi chyb pi Close vol MyExit}
      Close(F);
      ExitProc:=ExitSave;  {Potom vol ExitSave}
      end;
end;
{$F-}
begin
   ExitSave:=ExitProc;     {Ukldm dal ExitProc}
   ExitProc:=@MyExit;      {Inicializuji vlastn ExitProc}
     ...
end.


7.9. Automatick optimalizace

     Turbo Pascal, jako kad modern peklada, provd adu
optimalizac. Vtinu z nich jsme ji podrobn probrali v ped-
chozch kapitolch. Pesto je na tomto mst shrme, nebo
jejich znalost Vm pome odladit nkter zapeklitj chyby
(skok do neexistujcho kdu apod.).
-  Vechny konstantn vrazy jsou vyhodnocovny ji v dob
   pekladu.
-  Stejn etzcov konstanty jsou uloeny pouze jednou.
-  Pi nastaven {$B+} jsou logick konjunkce a alternativy
   vyhodnocovny, pokud nen o jejich vsledku rozhodnuto.
-  Vrazy jsou a na "{$B+} pi and a or" vyhodnocovny zprava,
   co umouje generovat efektivnj kd.
-  Range-Checking pi vyhodnocovn konstantnch vraz je
   provdno ji v dob pekladu.
-  Nsoben konstantnm vrazem, jen je mocninou dvou, je
   realizovno pomoc instrukce SHL.
-  Vechny promnn vt ne 1 byte jsou zarovnvny na cel
   slova (sud adresy), pokud je {$A+}.
-  Nepouit kdy (if false then ... ; while false do ...)
   nejsou generovny.
-  Nepouit promnn a podprogramy nejsou zahrnuty do vsled-
   nho modulu (dleit zejmna pi pouit unit).

     Vedle tchto automatickch optimalizac lze vsledn (odla-
dn) program optimalizovat nastavenm pepna:
     {$D-,L-,R-,S-,V-}.





8. Prce se standardnmi technickmi zazenmi

     V tto kapitole jsou popsny prostedky, kter Turbo Pascal
poskytuje pro prci s obvyklmi perifernmi zazenmi (obrazov-
kou, klvesnic a tiskrnou) a pro prci s hodinami.

     Pstup k technickm zazenm potae zajiuj sluby
operanho systmu. Jsou to jednak sluby jdra operanho
systmu (GEMDOS=DOS), jednak sluby modulu BIOS, kter zajiuje
ovldn periferi.
     Jdro operanho systmu DOS (Disk Operating System) posky-
tuje prostedky pro ovldn technickch zazen na logick
rovni. Umouje s jednotlivmi technickmi zazenmi pracovat
nezvisle na jejich konkrtnm typu. Poadavky na prci s tech-
nickmi zazenmi pedan DOSu se obvykle zpracovvaj pomoc
slueb BIOSu.
     Modul BIOS (Basic Input/Output System) je st programovho
vybaven operanho systmu, kter zajiuje ovldn technic-
kch zazen potae na nejni rovni. Je tedy zvisl na
konkrtnch technickch zazench pipojench k potai.
Sluby BIOSu se vyvolvaj pomoc peruen. 


Standardn vstupn a vstupn zazen

     Standardnm vstupnm zazenm je implicitn klvesnice,
standardnm vstupnm zazenm obrazovka. Oznaen obou tchto
zazen v systmu je CON.
     V Turbo Pascalu lze se standardnm vstupnm zazenm i se
standardnm vstupnm zazenm pracovat jak na rovni DOSu, tak
na rovni BIOSu. Pi prci na rovni BIOSu lze obvykle doshnout
rychlejho vstupu resp. vstupu, ne pi prci na rovni DOSu,
nebo sluby DOSu vyuvaj slueb BIOSu. Pm voln slueb
BIOSu je vhodn zejmna, potebujeme-li urychlit vstup na
obrazovku.

     Prci se standardnm vstupem a vstupem na rovni BIOSu
umouje v Turbo Pascalu procedura AssignCrt deklarovan v unit
Crt:

Ŀ
 procedure AssignCrt (var f: text);                        


     Procedura piad souboru f standardn vstupn resp. vstupn
zazen, piem vstup z resp. vstup na zazen je provdn
prostednictvm pmho voln slueb BIOSu.

Pklad:
     uses Crt;
     var f,g: text;
     ...
     begin
     AssignCrt(f); Rewrite(f);
       {souboru f je piazeno standardn vstupn zazen 
      (obrazovka), pi vstupu jsou pmo volny sluby BIOSu}
     ...
     AssignCrt(g); Reset(g);
       {souboru g je piazeno standardn vstupn zazen 
      (klvesnice), pi vstupu jsou pmo volny sluby BIOSu}
     ...
     Close(f); Close(g);
     end.

     Pouijeme-li pro piazen standardnho vstupnho resp. stan-
dardnho vstupnho zazen njakmu souboru proceduru Assign,
provd se vstup z tohoto resp. vstup na toto zazen pro-
stednictvm slueb DOSu.

     Turbo Pascal implicitn piazuje standardnmu vstupnmu
zazen textov soubor Input a standardnmu vstupnmu zazen
textov soubor Output. Inicializan kd unity Crt obsahuje
pkazy:

     AssignCrt(Input); Reset(Input);
     AssignCrt(Output); Rewrite(Output);

Jestlie tedy program nebo unita uv unitu Crt, jsou pi
ten ze souboru Input a pi zpisu do souboru Output volny
pmo sluby BIOSu. Chceme-li vstupn/vstupn operace s tmito
soubory provdt prostednictvm DOSu, je teba pout pkazy:

     Assign(Input,'CON');  
       { nebo ekvivalentn  Assign(Input,''); }
     Reset(Input);
a
     Assign(Output,'CON');  
       { nebo ekvivalentn  Assign(Output,''); }
     Rewrite(Output);

Pokud program nebo unita unitu Crt neuv, jsou pi prci se
soubory Input a Output volny sluby DOSu.


8.1. Obrazovka 

     Pro prci s obrazovkou jsou v Turbo Pascalu ureny konstanty,
promnn, procedury a funkce deklarovan v unitch Crt a Graph,
kter krom vlastnho zpisu na obrazovku umouj nastavovat
rzn textov a grafick mdy obrazovky a urovat barvu vstupu
a jeho umstn.

     Zobrazovac monosti obrazovky zvis na instalovanm video-
adaptru (nkdy se pouv tak termnu karta). Nejbnj
typy videoadaptr jsou adaptry CGA, EGA a VGA, kter umouj
barevn zobrazovn, a monochromatick adaptr HGC. Z funknho
hlediska se jednotliv videoadaptry li rozliovac schopno-
st,(tj. potem bod zobrazitelnch na obrazovce), monostmi
zobrazovn v barvch a velikost videopamti.

     Adaptr CGA (Color Graphics Adapter) m rozliovac schopnost
640x200 bod a umouje zobrazovn v 16 barvch. Pipojuje se
vtinou k levnjm potam.
     Adaptr EGA (Enhanced Graphics Adapter) m maximln roz-
liovac schopnost 640x350 bod a umouje zobrazovn v palet
16 barev, kterou lze vybrat ze 64 monch barev. Adaptr EGA je
shora kompatibiln s adaptrem CGA, to znamen, e souasn
zachovv zobrazovac monosti tohoto videoadaptru. Adaptr EGA
pedstavuje urit standard ve td pota stedn ceny.
     Adaptr VGA (Video Graphics Array) m maximln rozliovac
schopnost 640x480 bod pro zobrazovn v 16 barvch, kter lze
vybrat ze 64 monch barev, a 320x200 bod pro zobrazovn v 256
barvch, kter lze vybrat z 262144 monch barev. Adaptr VGA je
shora kompatibiln s adaptrem EGA. Pipojuje se vtinou k
potam tdy AT a k nkterm modelm ady PS/2.
     Monochromatick adaptr HGA (Hercules Graphics Card) je uren
zejmna pro prci v textovm reimu, nebo umouje doshnout
vysok kvality zobrazovanho textu - jeho rozliovac schopnost
je 720x350 bod. Adaptr pracuje pouze ve dvou zkladnch bar-
vch, vtinou ernoble nebo ernozelen.

     Instalovanmu videoadaptru vtinou odpovd typ monitoru.
Monitor me bt monochromatick (ernobl resp. dvoubarevn)
nebo barevn.

     Data uren pro zobrazen se zapisuj do videopa-
mti. Videopamti je na PC IBM v pamovm prostoru potae vyhrazeno
128 KB na adresch A0000 a BFFFF. Obsah aktuln sti videopa-
mti uren reimem zobrazen, je neustle prostednictvm
adie obrazovky (adie CRT) zobrazovn na monitoru.
     Na Atari je, jak znmo, videopam umstna v hlavn pamti a 
pistupuje se do n podle toho velice jednoduchm a snadno 
pochopitelnm zpsobem.

     Vechny uveden typy videoadaptr na PC umouj pracovat s obra-
zovkou ve dvou zkladnch reimech, v reimu textovm a reimu
grafickm, zatmco Atari ST pracuje stle v prafickm reimu. POZOR!
     V textovm reimu lze zobrazovat pouze znaky, a to vechny
znaky ASCII tabulky krom nkterch znak dcch. Pi prci v
textovm mdu je obrazovka rozdlena do uritho potu sloupc a
dek (standardn je to 80 sloupc a 25 dek), kter vytvej
pravidelnou obdlnkovou s. Do tto st jsou zobrazovny
jednotliv znaky. Poet bod obrazovky vymezen pro zobrazen
jednoho znaku je uren rozmrem jednoho pole st, tj. potem
sloupc a dek a rozliovac schopnost instalovanho video-
adaptru. Elementrn obdlnky obrazovky, do nich jsou zobra-
zovny jednotliv znaky, se nazvaj znakov pole. Je-li nap.
obrazovka rozdlna do 80 sloupc a 25 dek, pouv adaptr
CGA pro zobrazen jednoho znaku znakov pole o rozmru 8x8 bod,
adaptr EGA znakov pole o rozmru 8x14 bod, adaptr VGA znako-
v pole o rozmru 8x19 bod a monochromatick adaptr HGA znako-
v pole o rozmru 9x8 bod.
     V grafickm reimu lze zobrazovat pmo jednotliv body,
take je mon vytvet libovoln obrazy. 

     Reim prce s obrazovkou zvis na nastavenm videomdu.
Videomd uruje zpsob ukldn dat do videopamti, tedy i
zpsob zobrazen dat na monitoru. Pro dan typ videoadaptru
existuje obvykle nkolik videomd. Videomdy lze rozdlit do
dvou zkladnch skupin, na videomdy podporujc prci v texto-
vm reimu (textov mdy) a na videomdy podporujc prci v
grafickm reimu (grafick mdy). Textov mdy uruj poet
dk a sloupc na obrazovce, grafick mdy poet zobrazitelnch
bod a barev. Jednotliv videomdy je mono programov pepnat.

     Tato kapitola je vnovna prci s obrazovkou v textovm
reimu, prce v grafickm reimu je popsna v kapitole 9.


8.1.1. Textov md obrazovky PC

     Pi prci s obrazovkou lze pouvat nsledujc textov mdy:

BW40    -   ernobl md pro barevn adaptr (CGA, EGA, VGA),
            obrazovka je rozdlena do 40 sloupc a 25 dk,
BW40Hi  -   ernobl md pro adaptr EGA resp. VGA, obrazovka
            je rozdlena do 40 sloupc a 43 resp. 50 dk,
BW80    -   ernobl md pro barevn adaptr (CGA, EGA, VGA),
            obrazovka je rozdlena do 80 sloupc a 25 dk,
BW80Hi  -   ernobl md pro adaptr EGA resp. VGA, obrazovka
            je rozdlena do 80 sloupc a 43 resp. 50 dk,
Mono    -   ernobl md pro monochromatick adaptr, obrazovka
            je rozdlena do 80 sloupc a 25 dk,
CO40    -   barevn md pro barevn adaptr (CGA, EGA, VGA),
            obrazovka je rozdlena do 40 sloupc a 25 dk,
CO40Hi  -   barevn md pro adaptr EGA resp. VGA, obrazovka je
            rozdlena do 40 sloupc a 43 resp. 50 dk,
CO80    -   barevn md pro barevn adaptr (CGA, EGA, VGA),
            obrazovka je rozdlena do 80 sloupc a 25 dk,
CO80Hi  -   barevn md pro adaptr EGA resp. VGA, obrazovka je
            rozdlena do 80 sloupc a 43 resp. 50 dk.

     Pro oznaen tchto textovch md v Turbo Pascalu jsou v
unit Crt deklarovny nsledujc konstanty:

const BW40 = 0;
      BW80 = 2;
      Mono = 7;
      CO40 = 1;
      CO80 = 3;
      Font8x8 = 256;
      C40 = CO40;
      C80 = CO80;

BW40, CO40, BW80 a CO80 reprezentuj tyi barevn textov mdy
podporovan barevnm grafickm adaptrem CGA (tedy i EGA a VGA).
Konstanta Mono reprezentuje jednoduch ernobl textov md
podporovan monochromatickm adaptrem. Konstanta Font8x8 slou
k oznaen 43 resp. 50-ti dkovch md podporovanch adaptry
EGA resp. VGA. Konstanty C40 a C80 zajiuj kompatibilitu Turbo
Pascalu verze 3.0 s verz 5.5 resp. 5.0.
     Vzjemn vztah textovch md a uvedench konstant je nsle-
dujc: 
 Ŀ
  textov md   oznaen mdu pomoc konstant unity Crt 
 Ĵ
   BW40          BW40                                   
   BW40Hi        BW40+Font8x8                           
   BW80          BW80                                   
   BW80Hi        BW80+Font8x8                           
   Mono          Mono                                   
   CO40          CO40  resp. C40                        
   CO40Hi        CO40+Font8x8  resp. C40+Font8x8        
   CO80          CO80  resp. C80                        
   CO80Hi        CO80+Font8x8  resp. C80+Font8x8        
 


     K nastaven textovho mdu z turbopascalskho programu slou
procedura TextMode deklarovan v unit Crt:

Ŀ
 procedure TextMode (Mode: word);                          


Parametr Mode uruje textov md, kter bude po vyvoln proce-
dury nastaven. Parametrem procedury me bt libovoln oznaen
textovho mdu pomoc jedn z ve definovanch konstant (viz
tabulka) nebo libovoln vraz typu word. Pokud vraz pedan
procedue TextMode jako parametr nereprezentuje dn textov
md, nastav procedura textov md CO80.
     Poznamenejme, e md CO80 je implicitn textov md.

     Pi kadm voln procedury TextMode je stvajc textov md
uloen do promnn LastMode. Promnn LastMode je deklarovna v
unit Crt:

     var LastMode: word;

Pi zahjen bhu programu uvajcho unitu Crt je promnn
LastMode inicializovna na zklad aktulnho videomdu.

Pklady:
     Voln  TextMode(LastMode)  zpsob nastaven pedchozho
aktivnho textovho mdu; lze je pout nap. tehdy, chceme-li
obnovit textov md po prci s grafikou.
     Voln  TextMode(Lo(LastMode))  nastav textov md uren
spodnm bytem promnn LastMode; pokud promnn LastMode repre-
zentuje nkter ze 43 resp. 50-ti dkovch textovch md, je
nastaven odpovdajc 25-ti dkov md.
     Voln  TextMode(Lo(LastMode)+Font8x8)  zpsob nastaven 43
resp. 50-ti dkovho mdu odpovdajcho 25-ti dkovmu mdu
urenmu spodnm bytem promnn LastMode.

Dal pklad:
{nastaven textovho mdu na md, kter byl aktivn pi sputn
programu}
     uses Crt;
     var OrigMode: word;
     begin
     OrigMode:= LastMode;
     ...  {rzn zmny videomd} ...
     TextMode(OrigMode);
     end.

Poznmka: Pi voln procedury TextMode je aktuln okno roz-
eno na celou obrazovku, promnn TextAttr je piazena hod-
nota, kterou mla pi sputn programu, promnn DirectVideo je
piazena hodnota True a, pokud je vybrn barevn md, je hod-
nota True piazena i promnn CheckSnow.


8.1.2. Nastaven barev

     V textovm reimu jsou pi zpisu do videopamti kadmu
znaku piazeny dva byty. Prvn byte obsahuje ASCII kd zobrazo-
vanho znaku, ve druhm bytu jsou zakdovny textov atributy
zobrazovanho znaku. Textov atributy jsou: barva znaku, barva
pozad znaku a pznak blikn znaku. Kad znak zapisovan v
textovm reimu do videopamti me mt jin textov atributy.
Byty reprezentujc zobrazovan znaky se do videopamti ukldaj
v poad urenm pozic znaku na obrazovce, a to po dcch
levm hornm rohem ponaje. Pro kad znak je nejprve uloen
byte obsahujc ASCII kd tohoto znaku a pot byte s jeho texto-
vmi atributy.

     V Turbo Pascalu me bt pi prci v barevnch textovch
mdech  vybrna  barva  kadho znaku ze 16 barev, barva pozad
z 8 barev. Kad znak me navc blikat. 
     Barvy jsou reprezentovny celmi sly z intervalu 0 a 15.
Pro sna identifikaci barev lze msto sel pouvat nsle-
dujc konstanty deklarovan v unit Crt:

const  Black        =  0;       {ern}
       Blue         =  1;       {modr}
       Green        =  2;       {zelen}
       Cyan         =  3;       {tyrkysov}
       Red          =  4;       {erven}
       Magenta      =  5;       {fialov}
       Brown        =  6;       {hnd}
       LightGray    =  7;       {svtle ed}
       DarkGray     =  8;       {tmav ed}
       LightBlue    =  9;       {svtle modr}
       LightGreen   = 10;       {svtle zelen}
       LightCyan    = 11;       {svtle tyrkysov}
       LightRed     = 12;       {svtle erven}
       LightMagenta = 13;       {svtle fialov}
       Yellow       = 14;       {lut}
       White        = 15;       {bl}

     Zobrazen barev je zaloeno na kombinaci t zkladnch
barevnch signl (modr, zelen, erven) a signlu intenzity.
Textov mdy  pracujc se 16 barvami mohou mt tedy informaci o
barv zakdovanou ve 4 bitech nsledujcm zpsobem (I=inten-
zita, =erven, Z=zelen, M=modr):

   I    Z  M        
   0  0  0  0        ern
   0  0  0  1        modr
   0  0  1  0        zelen
   0  0  1  1        modrozelen (tyrkysov)
   0  1  0  0        erven
   0  1  0  1        fialov
   0  1  1  0        hnd
   0  1  1  1        svtle ed
   1  0  0  0        tmav ed
   1  0  0  1        svtle modr
   1  0  1  0        svtle zelen
   1  0  1  1        svtle modrozelen
   1  1  0  0        svtle erven
   1  1  0  1        svtle fialov
   1  1  1  0        lut
   1  1  1  1        bl

Kdovn bytu obsahujcho textov atributy zobrazovanho znaku
je uvedeno v nsledujc tabulce:

   Ŀ
    bit                vznam                  
   Ĵ
     0          modr komponenta poped       
     1          zelen komponenta poped      
     2          erven komponenta poped     
     3          intenzita poped              
     4          modr komponenta pozad        
     5          zelen komponenta pozad       
     6          erven komponenta pozad      
     7          indikace blikn               
   

Doln tyi bity uruj barvu psma (16 monch barev), nsle-
dujc ti bity barvu pozad (8 monch barev), sedm bit indi-
kuje blikn znaku - je-li sedm bit nastaven na hodnotu 1,
zobrazen znak blik.

Poznmka: Blikn znak s nastavenm sedmm atributovm bitem a
blikn kurzoru je realizovno adiem CRT a vnitnm asovaem
videoadaptru.

     Byte obsahujc textov atributy, kter jsou piazeny vem
znakm zapisovanm pomoc procedur Write a Writeln do videopam-
ti (tzv. aktuln textov atributy), zpstupuje v Turbo Pas-
calu promnn TextAttr deklarovan v unit Crt:

     var TextAttr: byte;

Obsah promnn TextAttr je tedy nsledujc:

         7     6     5     4     3     2     1     0
      Ŀ
        B    b    b    b    f    f    f    f  
      

       bit      3-bitov kd        4-bitov kd
      indiku-    barvy pozad        barvy psma
       jc
      blikn

     Textov atributy se obvykle nastavuj pomoc procedur TextCo-
lor a TextBackground (viz dle). Lze je vak nastavit i pmm
uloenm odpovdajc hodnoty do promnn TextAttr.

Pklad: Piazen 

     TextAttr:= Yellow + Blue * 16 + 128

nastav lut blikajc psmo na modrm pozad.

Hodnota barvy pozad mus bt vynsobena 16, aby byla v bytu
umstna na sprvnou pozici. Piten konstanty 128 nastav
sedm bit promnn TextAttr na hodnotu 1, zpsob tedy blikn
zobrazovanch znak.

     K nastaven blikajcho psma lze pout konstantu Blink 
deklarovanou v unit Crt:

     const  Blink = 128;

Ekvivalentn zpis pedchozho piazen tedy je:

     TextAttr:= Yellow + Blue * 16 + Blink .

     Pro volbu barvy zobrazovanch znak slou v Turbo Pascalu
procedura  TextColor  deklarovan v unit Crt:

Ŀ
 procedure TextColor (Color: byte);                        


     Procedura nastav na zklad hodnoty parametru Color bity 0
a 3 promnn TextAttr. Barva vech znak zapsanch na obrazov-
ku po vyvoln tto procedury je tedy urena hodnotou parametru
Color. Je-li hodnota parametru Color vt ne 15, je do bit 0
a 3 promnn TextAttr uloena hodnota  Color mod 16  a sedm
bit promnn TextAttr je nastaven na 1, to znamen, e zobrazo-
van znaky blikaj.

Pklad:
     uses Crt;
     begin
     ... 
     TextColor(Green);        {zelen psmo}
     ...
     TextColor(14+Blink);     {blikajc lut psmo}
     ...
     end.

     Barvu pozad znak zapisovanch na obrazovku lze zvolit po-
moc procedury  TextBackground  deklarovan takt v unit Crt:

Ŀ
 procedure TextBackground (Color: byte);                   


     Procedura nastav na zklad hodnoty parametru Color bity 4
a 6 promnn TextAttr, kter uruj barvu pozad znak zapiso-
vanch do videopamti. Po vyvoln tto procedury m tedy pozad
vech znak zapisovanch na obrazovku barvu specifikovanou
parametrem Color.  Je-li hodnota parametru Color vt ne 7, je
do bit 4 a 6 promnn TextAttr uloena hodnota  Color mod 8.
Barvu pozad lze tud nastavit pouze na barvu odpovdajc
nkter z prvnch osmi konstant pro barvy (Black, Blue, Green,
Cyan, Red, Magenta, Brown, LightGray).

     Dal procedury, kter umouj zmnit hodnoty aktulnch
textovch atribut, jsou procedury NormVideo, HighVideo a Low-
Video opt deklarovan v unit Crt:

Ŀ
 procedure NormVideo;                                      


     Procedura zmn hodnotu promnn TextAttr tak, aby odpovdala
nastaven textovch atribut, je bylo aktuln pi sputn
programu. Barvy psma a pozad a pznak blikn psma jsou tedy
po vyvoln procedury nastaveny tak, jak byly nastaveny v oka-
miku sputn programu (jak je nastavil pedchoz sputn
program).

Ŀ
 procedure HighVideo;                                      


     Po vyvoln tto procedury se zv intenzita zobrazovanch
znak. To znamen, e tet bit promnn TextAttr je nastaven na
1. Jinmi slovy: Je-li hodnota textovho atributu udvajcho
barvu zobrazovanch znak (bity 0 a 3 promnn TextAttr) z
intervalu 0 a 7, je po vyvoln procedury tato hodnota zvena
o 8. 

Ŀ
 procedure LowVideo;                                       


     Po vyvoln tto procedury se sn intenzita zobrazovanch
znak. To znamen, e tet bit promnn TextAttr je nastaven na
0. Je-li tedy hodnota textovho atributu udvajcho barvu
zobrazovanch znak (bity 0 a 3 promnn TextAttr) z intervalu
8 a 15, je po vyvoln procedury tato hodnota snena o 8. 


8.1.3. Zpis na obrazovku 

     K zpisu na obrazovku dochz pi zpisu dat pomoc procedur
Write a Writeln do kadho souboru, ktermu je piazena obra-
zovka, a pi zadvn dat z klvesnice pomoc procedur Read a
Readln. 

     Procedury Write, Writeln, Read a Readln byly podrobn popsny
v kapitole 5.

     Umstn znak zapisovanch na obrazovku lze dit pomoc
procedury GotoXY deklarovan v unit Crt:

Ŀ
 procedure GotoXY (X,Y: byte);                             


     Procedura pemst na obrazovce kurzor na pozici urenou
souadnicemi X a Y, kde X udv slo sloupce a Y slo dky.
Lev horn roh obrazovky m souadnice [1,1], souadnice pravho
dolnho rohu zvis na nastavenm textovm mdu; nap. pro 80-
ti sloupcov a 25-ti dkov mdy je souadnice pravho dolnho
rohu obrazovky [80,25].
     Pokud nejsou souadnice zadny korektn (tj. nkter z para-
metr procedury je nekladn nebo pli velk), nem voln
procedury dn inek.

     Aktuln pozici kurzoru lze kdykoli zjistit pomoc funkc
WhereX a WhereY deklarovanch rovn v unit Crt:

Ŀ
 function WhereX: byte;                                    


     Funkce vrac X-ovou souadnici aktuln pozice kurzoru na
obrazovce.

Ŀ
 function WhereY: byte;                                    


     Funkce vrac Y-ovou souadnici aktuln pozice kurzoru na
obrazovce.


     Pi generovn vstupu na obrazovku lze dle vyut nsle-
dujc procedury deklarovan v unit Crt:

Ŀ
 procedure ClrScr;                                         


     Procedura smae obsah obrazovky, pesnji eeno, vypln
obsah obrazovky mezerami v barv uren bity 4 a 6 promnn
TextAttr, tj. v aktuln barv pozad, a umst kurzor do levho
hornho rohu obrazovky. 

Ŀ
 procedure ClrEol;                                         


     Procedura smae znaky od pozice kurzoru do konce dky.
Pesnji eeno, znaky od pozice kurzoru do konce dky jsou
pepsny mezerami, ani by se zmnila poloha kurzoru; barva
pepsan sti dky je urena bity 4 a 6 promnn TextAttr,
tj. aktuln barvou pozad.

Ŀ
 procedure DelLine;                                        


     Procedura smae na obrazovce dku obsahujc kurzor. dky
umstn pod n jsou posunuty o jednu dku nahoru a pod dosud
posledn dku obrazovky je vloena przdn dka. Barva vloen
dky je urena aktuln barvou pozad. Kurzor je pesunut do
prvnho sloupce dky, kter byla umstna pmo pod smazanou
dkou.
     Procedura vyuv rolovac rutiny BIOSu.

Ŀ
 procedure InsLine;                                        


     Procedura vlo ped dku, na n je umstn kurzor, przd-
nou dku. dka obsahujc kurzor a vechny dky pod n jsou
na obrazovce posunuty o jednu dku dol, posledn dka tedy z
obrazovky zmiz. Barva vloen dky je urena aktuln barvou
pozad. Kurzor je umstn na zatek vloen dky.
     Procedura pouv rolovac rutiny BIOSu.


     Dal procedurou unity Crt, kterou lze pout pi komunikaci
programu s uivatelem, napklad i bhem zpisu na obrazovku, je
procedura Delay, jej voln zpsob ekn programu:

Ŀ
 procedure Delay (ms: word);                               


Parametr ms uruje poet milisekund, po kter je provdn
programu pozastaveno. Doba ekn programu je mena pomoc
systmovho asovae, kter generuje asov signly kadch 55
ms (viz 8.5). Skuten doba ekn je tedy pouze aproximac doby
specifikovan parametrem ms.


dc znaky pro vstup na obrazovku

     Pi zpisu do souboru piazenmu obrazovce (standardnmu
vstupnmu zazen) maj speciln vznam nsledujc dc
znaky:

#7    (Bell) vyvol zvukov signl,
#8    (Backspace) posune kurzor o jeden znak vlevo; je-li kurzor
      na levm okraji obrazovky, nem #8 dn inek,
#10   (Line feed) posune kurzor o jednu dku dol; je-li kurzor
      na posledn dce, obsah obrazovky se vyroluje a objev se
      nov dka,
#13   (Carriage return) pesune kurzor na zatek dky.

Vechny ostatn dc znaky se pi zpisu objev na obrazovce.


8.1.4. Okna 

     Turbo Pascal poskytuje prostedky pro prci s textovmi okny.
Pojmem okno oznaujeme libovoln obdlnkov vsek obrazovky, do
nho je soustedn veker vstup smrovan na obrazovku. Obra-
zovka vn okna je nedostupn. 
     V kadm okamiku je mon v programu pracovat pouze s jed-
nm, tzv. aktulnm oknem. Aktuln textov okno lze na obrazov-
ce definovat pomoc procedury Window deklarovan v unit Crt:

Ŀ
 procedure Window (X1,Y1,X2,Y2: byte);                     


Parametry X1,Y1 uruj obrazovkov souadnice levho hornho
rohu, parametry X2,Y2 obrazovkov souadnice pravho dolnho
rohu definovanho okna. X1, X2 jsou sla sloupc, Y1, Y2 sla
dek. Poznamenejme, e lev horn roh obrazovky m souadnice
[1,1], souadnice pravho dolnho rohu obrazovky zvis na
nastavenm textovm mdu.
     Po vyvoln procedury Window se stane aktulnm okno, kter
je procedurou definovno a kurzor je umstn do levho hornho
rohu definovanho okna. Nen-li zadn parametr procedury
Window korektn (tj. nkter z parametr je nekladn nebo pesa-
huje rozmry obrazovky), nem voln procedury dn inek.
     Minimln velikost textovho okna me bt jeden sloupec krt
jeden dek. Implicitn je aktuln textov okno rozeno na
celou obrazovku. Rozen aktulnho textovho okna na celou
obrazovku je provedeno tak po kadm vyvoln procedury Text-
Mode.

Pklad: Zelen okno na ern obrazovce.
     uses Crt;
     begin
     TextBackground(Black);
     ClrScr;
     Window(20,5,60,20);
     TextBackground(Green);
     ClrScr;  
     end.

     Pi prci s okny jsou vechny souadnice obrazovky krom
souadnic pouvanch pi definovn novho okna v procedue
Window relativn vzhledem k aktulnmu oknu. To znamen, e 
-  procedury Write, Writeln, Read, Readln, ClrScr, ClrEol, Del-
   Line, InsLine, GotoXY pracuj pouze s st obrazovky vymeze-
   nou aktulnm oknem, piem lev horn roh aktulnho okna
   m souadnice [1,1], 
-  funkce WhereX, WhereY vrac hodnoty relativn vzhledem k ak-
   tulnmu oknu.

     Obrazovkov souadnice aktulnho okna jsou uloeny v promn-
nch WindMin a WindMax deklarovanch v unit Crt:

     var WindMin, WindMax: word;

Promnn WindMin a WindMax jsou aktualizovny pi kadm voln
procedury Window. WindMin obsahuje hodnotu odpovdajc absolut-
n souadnici levho hornho rohu aktulnho textovho okna na
obrazovce, WindMax hodnotu odpovdajc absolutn souadnici
pravho dolnho rohu aktulnho textovho okna na obrazovce.
     Souadnice jsou v promnnch WindMin a WindMax zakdovny
takto: sloupcov (X-ov) souadnice jsou uloeny v dolnm bytu
tchto promnnch, dkov (Y-ov) souadnice v jejich hornm
bytu. Lev horn roh aktulnho okna m tedy souadnice 
          (Lo(WindMin), Hi(WindMin)), 
prav doln roh aktulnho okna souadnice 
          (Lo(WindMax), Hi(WindMax)). 
ka aktulnho okna je 
          Lo(WindMax) - Lo(WindMin) + 1  sloupc,
vka aktulnho okna
          Hi(WindMax) - Hi(WindMin) + 1  dek.

     Pozor, lev horn roh obrazovky m pi prci s promnnmi
WindMin a WindMax souadnice [0,0], zatmco pi prci s procedu-
ami Window a GotoXY jsou souadnice levho hornho rohu obra-
zovky [1,1].

Poznmka: Aktuln textov okno je mon nastavit i piazenm
odpovdajcch hodnot promnnm WindMin a WindMax. Ped zpisem
do takto nastavenho okna je vak teba umstit kurzor do levho
hornho rohu okna (tj. na pozici [1,1]), jinak se me stt, e
je umstn zobrazovanch znak zcela neodpovdajc naim
pedstavm i hranicm okna.


8.2. Klvesnice 

     Klvesnice je vedle obrazovky zkladnm technickm prosted-
kem pro komunikaci s potaem. Implicitn je klvesnice stan-
dardnm vstupnm zazenm. Stejn jako s obrazovkou lze i s
klvesnic pracovat v Turbo Pascalu jak na rovni DOSu tak na
rovni BIOSu.

     Prci s klvesnic na rovni DOSu umouj procedury Read a
Readln vztaen ke standardnmu vstupnmu souboru, tj. 
-  procedury Read a Readln volan bez parametru oznaujcho
   vstupn textov soubor  (pokud nepracujeme s unitou Crt),
-  procedury Read a Readln volan s parametrem oznaujcm
   textov soubor, jemu byl pomoc procedury Assign piazen
   standardn vstup, nap.
             Assign(f,'CON')  resp.  Assign(f,'').

     Chceme-li pracovat s klvesnic na rovni BIOSu, je teba
pout unitu Crt a klvesnici zvolenmu textovmu souboru pia-
dit pomoc procedury AssignCrt, kter zajist, e pi natn
dat z klvesnice jsou volny sluby vstupnho/vstupnho systmu
BIOS. K natn dat z klvesnice opt slou procedury Read a
Readln.
Poznmka: Jak ji bylo uvedeno na zatku tto kapitoly, pou-
v-li program (nebo unita) unitu Crt, jsou pi provdn proce-
dur Read a Readln (Write a Writeln), volanch bez parametru
udvajcho nzev textovho souboru, pouvny sluby BISu.

     daje natan z klvesnice pomoc procedur Read a Readln
(jak na rovni DOSu tak na rovni BIOSu) jsou automaticky zobra-
zovny na obrazovce, a to od aktuln pozice kurzoru ponaje.
Ob tyto procedury tedy generuj vstup na obrazovku a mn
aktuln pozici kurzoru. Jak vak uvidme v odstavci 8.2.2,
nabz Turbo Pascal v unit Crt tak prostedky, kter umouj
natat data z klvesnice pmo, bez jejich zobrazen na obra-
zovce.


8.2.1. Klvesnice jako vstupn soubor 

     Jak ji vme, jsou pro natn hodnot z klvesnice jako z
textovho souboru ureny procedury Read a Readln. Jejich popis
byl uveden v kapitole 5 a o zobrazen jejich vstupnch hodnot na
obrazovku jsme se zmnili v odstavcch 8.1.3. a 8.1.4. 

dkov vstup
     Natn dat ze souboru Input nebo z textovho souboru, kter
byl piazen standardnmu vstupnmu zazen (klvesnici), se
provd po dkch. Natan dka je ukldna do vnitnho
bufferu pslunho textovho souboru (velikost bufferu je 127
znak). Po stisknut klvesy Enter je natn vstupn dky
ukoneno a vnitn buffer vstupnho souboru je pouit jako zdroj
vstupu pro procedury Read a Readln.

     Pracujeme-li s klvesnic na rovni DOSu, lze pi zadvn
vstupn dky vyuvat slueb, kter DOS nabz pro editaci
vstupu (tyto sluby jsou "napojeny" nap. na klvesy F1, F3,
Ecs, F6, Ctrl-C apod. - viz [IBM]).

     Pi prci s klvesnic na rovni BIOSu lze pi zadvn
obsahu vstupn dky pout nsledujc editan pkazy:

Backspace -    smae posledn znak zadan z klvesnice,
Esc            -smae celou vstupn dku,
Ctrl-S         -m stejnou funkci jako Backspace,
Ctrl-A         -m stejnou funkci jako Esc,
Ctrl-D         -vyvol znak, kter byl v danm poad natn na
               pedchoz vstupn dce,
Ctrl-F         -vyvol pedchoz vstupn dku,
Enter               -ukon vstupn dky a ulo do bufferu oznaen
               konce rdku (CR LF),
Ctrl-M         -m stejnou funkci jako Enter,
Ctrl-Z         -je-li hodnota promnn CheckEof (viz dle) True,
               ukon vstupn dku a ulo do bufferu znak
               chr(26) oznaujc konec souboru, jinak je stisk-
               nut Ctrl-Z ignorovno.

     V unit Crt je deklarovna boolovsk promnn CheckEof, na
zklad jej hodnoty je resp. nen pi naten znaku Ctrl-Z
(chr(26)) uloeno do bufferu oznaen konce souboru:

     var  CheckEof: boolean;

     Je-li hodnota promnn True, je pi stisknut Ctrl-Z pi
natn daj ze souboru piazenho klvesnici procedurou
AssignCrt uloen do bufferu znak chr(26) oznaujc konec soubo-
ru, to znamen, e funkce Eof vrt hodnotu True.
     Je-li hodnota promnn False, je stisknut Ctrl-Z ignorovno.
     Implicitn hodnota promnn je False.


8.2.2. Pm vstup znak 

     Pmm vstupem znak z klvesnice rozumme natn znak
zadvanch z klvesnice bez jejich zobrazen na obrazovce.

     Pro pm vstup znak z klvesnice jsou ureny funkce ReadKey
a KeyPressed deklarovan v unit Crt. Dve, ne si tyto funkce
popeme, eknme si nco mlo o tom, jak probh komunikace
klvesnice s potaem.

Funkce ReadKey a KeyPressed

Ŀ
 function ReadKey: char;                                   


     Funkce vrt znakovou reprezentaci prvnho zznamu resp.
prvnho bytu uloenho ve vyrovnvac pamti klvesnice. Je-li v
okamiku vyvoln funkce ReadKey buffer klvesnice przdn,
funkce ek, dokud nen stisknutm njak klvesy resp. kom-
binace klves do bufferu nco uloeno.
     Pokud prvn zznam uloen v bufferu klvesnice reprezentuje
nkter ze znak ASCII tabulky krom znaku NUL (chr(0)), vrt
funkce tento znak.
     Jestlie prvn zznam bufferu reprezentuje rozen kd 
(extended scan code) nebo znak NUL, vrt funkce znak #0 (tj.
znakovou reprezentaci hlavnho bytu) a pi dalm voln znako-
vou reprezentaci pslunho kdu (tj. pomocnho bytu), v ppa-
d znaku NUL je to #3. 

Pklad:
  { Vytiskne znak nebo rozen kd reprezentujc
    stisknutou klvesu resp. kombinaci klves.}
uses Crt;
var c: char;
begin
c:= ReadKey;
if c <> #0 then
  write(c,' ',ord(c));   
               { znak ASCII tabulky }
else
  begin
  c:= ReadKey;
  write('EX ',ord(c):3);  
               { rozen kd }
  end;
end.


Ŀ
 function KeyPressed: boolean;                             


     Funkce vrac hodnotu True, pokud je buffer klvesnice ne-
przdn. Je-li buffer klvesnice przdn, vrac hodnotu False.

Pklad:
uses Crt;
...
procedure Cekej_na_stisknuti_klavesy;
  {-------------------------------------------------------}
  {  Procedura ek, dokud nen stisknuta njak klvesa  }
  {   (vyjma samostatnho stisknut dcch klves).     }
  {-------------------------------------------------------}
  var c: char;
  begin
  while KeyPressed do c:= ReadKey;
              { vyprzdnn bufferu klvesnice }
  writeln('Stisknete libovolnou klavesu...');
  repeat until KeyPressed;
              { ekn na stisknut klvesy }
  end;

Poznmka:
     ekn na stisknut klvesy Enter lze snadno realizovat
pomoc procedury Readln:

     ...
     write('Stisknete klavesu ENTER ...');
     readln;
     ...


8.3. Reproduktor 

     Pro prci s vestavnm reproduktorem jsou v Turbo Pascalu
deklarovny v unit Crt procedury Sound a NoSound.

Ŀ
 procedure Sound (Hz: word);                               


     Procedura zapne vestavn genertor tn. Parametr Hz udv
frekvenci generovanho tnu v hertzch. Tn je generovn tak
dlouho, dokud nen vyvolna procedura NoSound (vypnut tnu)
nebo pokud nen vyvolna procedura Sound s jinm parametrem
(zmna frekvence tnu).

Ŀ
 procedure NoSound;                                        


     Procedura vypne vestavn reproduktor.

Pklad:
     uses Crt;
     begin
     Sound(440);
     Delay(200);
     NoSound;
     end.

     Frekvence nkterch tn v hertzch jsou uvedeny v nsleduj-
c tabulce (frekvence jsou temperovan a zaokrouhlen):

  Ŀ
   OKTVA    mal        1'        2'   
                    (zkladn)          
  Ĵ
    c         131       262       523   
    cis       139       277       554   
    d         147       294       587   
    dis       156       311       622   
    e         165       330       659   
    f         175       349       698   
    fis       185       370       740   
    g         196       392       784   
    gis       208       415       831   
    a         220       440       880   
    b         233       466       932   
    h         247       494       988   
    c         262       523      1046   
  


8.4. Tiskrna 

     Pro pipojen tiskrny k potai jsou ureny paraleln
porty, jejich oznaen v systmu je LPT1, LPT2, LPT3... Za-
zen pipojen na LPT1 se nazv standardn tiskrna a jeho
ekvivalentn oznaen je PRN.
     Chceme-li v programu njak textov soubor smrovat na tis-
krnu, je teba tomuto souboru piadit pslun zazen a
otevt ho pro vstup.

Pklad:
     ...
     var  tiskrna: text;
     ...
     begin
     ...
     assign(tiskrna,'LPT1');
     rewrite(tiskrna);
     ...
     close(tiskrna);
     ...
     end.

     Zpis na tiskrnu probh prostednictvm sluby 17H/00
BIOSu. kter je volna pi zpisu kadho znaku. Sluba pole
zapisovan znak na tiskrnu a ek na potvrzen pijet tohoto
znaku. Znaky poslan na tiskrnu jsou ukldny do bufferu tis-
krny. Tisk znak z bufferu se provd po dkch. Posloupnost
znak uloen do bufferu tiskrny je tedy vytisknuta a v oka-
miku, kdy je do bufferu uloeno oznaen konce dky, tj.
dvojice znak CR LF (chr(13), chr(10)). Pokud posledn dek
souboru smrovanho na tiskrnu nekon dvojic znak CR LF,
nen tento dek vytisknut. 

     Nen-li tiskrna k potai pipojena, dojde pi zpisu do
souboru piazenho pslunmu perifernmu zazen k bhov
chyb "152: Drive not ready".


8.4.1. Unita Printer 

     Pro usnadnn prce s tiskrnou slou standardn unita
Printer:

unit Printer;
interface
var Lst: text;
implementation 
begin 
Assign(Lst,'PRN');
Rewrite(Lst),
end.

Textovmu souboru Lst je pi inicializaci unity Printer pia-
zena standardn tiskrna, tj. zazen LPT1 resp. PRN.
     Pouvn unity Printer odstrauje nutnost deklarace, pia-
zovn a otevrn textovho souboru smrovanho na standardn
tiskrnu.

Pklad: Nsledujc dva programy jsou ekvivalentn:

     program TISK1;
     uses Printer;
     begin
     writeln(Lst, 'Vstup na standardn tiskrnu');
     end.

     program TISK2;
     var f:text;
     begin
     assign(f,'PRN');  {nebo  assign(f,'LPT1');}
     rewrite(f);
     writeln(f, 'Vstup na standardn tiskrnu');
     end.

Poznmka: Vimnte si, e soubor Lst nen uzavrn. Pokud tedy
nen posledn tisknut dka zakonena znaky CR LF (nap. pomoc
Writeln), nen vytisknuta!


8.4.3. dc znaky 

     Pro pravu vstupu smrovanho na tiskrnu lze pout nkter
dc znaky (ASCII 0 a 31) a tzv. Esc-sekvence, co jsou
posloupnosti znak zanajc dcm znakem #27 (Esc). dc
znaky a Esc-sekvence se zadvaj do textu poslanho na tiskr-
nu, nejsou vak vytisknuty, ale zpsob proveden urit akce,
nap. oddkovn, odstrnkovn, nastaven velikosti psma,
podtrhvn atd.

     Vznam dcch znak a Esc-sekvenc nemus bt pi prci s
rznmi typy tiskren stejn. Pesn informace naleznete v
manulu pslun tiskrny.
     Pro ilustraci uvdme pehled funkc nejastji uvanch
dcch znak a Esc-sekvenc. Podrobnj vet naleznete nap.
v [TECHHELP].

dc znaky: 

#7       vygeneruje zvukov signl (beep),
#10      zpsob oddkovn, tj. posun na dal dku (line
         feed),
#12      zpsob odstrnkovn, tj. dotisknut dky z bufferu a
         posun na zatek dal strnky (eject),
#13      zpsob nvrat vozku, tj. posun na zatek dky (car-
         riage return)
#14      zapne tisk proloenho psma (psmo dvojnsobn veli-
         kosti); tisk proloenho psma je vypnut na konci dky
         nebo dcm znakem #20,
#15      zapne tisk komprimovanho psma; tisk komprimovanho
         psma lze vypnout dcm znakem #18,
#18      vypn tisk komprimovanho psma,
#20      vypn tisk proloenho psma,


Esc-sekvence:

<Esc> G , tj. #27 G
            zapne dvojit tisk (tiskne se dvakrt pes sebe -
            zv se kvalita tisku),
<Esc> H     vypne dvojit tisk,
<Esc> E     zapne tisk tlustho psma,
<Esc> F     vypne tisk tlustho psma,
<Esc> - 1   zapne podtrhvn,
<Esc> - 0   vypne podtrhvn,
<Esc> W 1   zapne tisk proloenho psma,
<Esc> W 0   vypne tisk proloenho psma,
<Esc> S 1   zapne tisk dolnch index,
<Esc> S 0   zapne tisk hornch index,
<Esc> T     vypne tisk index,
<Esc> @     nastav implicitn reim tiskrny (standardn tisk).

Pklad:
uses Printer;
...
procedure Eject;
     {------------------------------------------}
     { vyvoln procedury zpsob odstrnkovn }
     { na standardn tiskrn                   }
     {------------------------------------------}
     begin
     write(Lst,#12);
     end;
...

Poznmka: Vyvarujte se tisku dcch znak, pokud bezpen
nevte, jak vznam pi prci s tiskrnou maj, jinak se mete
dokat rznch pekvapen (nap. #9 a #11 mohou zpsobit neeka-
n posun papru, nebo slou k horizontln a vertikln tabe-
laci, #24 smae v bufferu znaky z neukonen dky, tj. znaky,
kter jsou v bufferu uloeny za poslednm oznaenm konce dky
CR LF).


8.5. Hodiny 

8.5.1. Datum a as 

     Ke sledovn a nastavovn systmovho asu vetn data jsou
v Turbo Pascalu ureny procedury  GetTime, GetDate, SetTime a
SetDate deklarovan v unit Dos.

Ŀ
 procedure GetTime (var Hour,Minute,Second,Sec100: word)   


     Procedura vrac aktuln systmov as. Vznam parametr je
nsledujc:
          Hour   -  hodiny,
          Minute -  minuty,
          Second -  sekundy,
          Sec100 -  setiny sekundy.

Ŀ
 procedure GetDate (var Year,Month,Day,DayOfWeak: word)    


     Procedura vrac aktuln systmov datum. Vznam parametr je
nsledujc:
          Year      -  rok,
          Month     -  msc,
          Day       -  den,
          DayOfWeak -  slo dne v tdnu (0=nedl, 1=pondl,      
             2=ter, 3=streda, ..., 6=sobota).

Ŀ
 procedure SetTime (Hour,Minute,Second,Sec100: word)       


     Procedura nastav na zklad hodnoty parametr aktuln
systmov as. Vznam parametr je stejn jako u procedury
GetTime.

Ŀ
 procedure SetDate (Year,Month,Day: word)                  


     Procedura nastav na zklad hodnoty parametr aktuln
systmov datum. Vznam parametr je stejn jako u procedury
GetDate. Parametr Year mus bt alespo 1980.


Pklad:
uses Dos;
const  DNY: array [0..6] of string[7] = 
            ('nedele', 'pondeli', 'utery', 'streda',
             'ctvrtek', 'patek', 'sobota');
var  rok, mesic, den, den_v_tydnu: word;
     h, m, s, ss: word;

function format (w: word): string;
  var s: string;
  begin
  str(w:0,s);
  if length(s) = 1 then s:= '0'+s;
  format:= s;
  end;
begin
GetDate(rok,mesic,den,den_v_tydnu);
GetTime(h,m,s,ss);
Writeln('Dnes je ',DNY[den_v_tydnu],
         ' ',den:0,'.',mesic:0,'.',rok:0);
Writeln('Je prave ',format(h),':',format(m),':',
         format(s),'.',format(ss));
end.


8.6. Unita Crt 

     Na zvr tto kapitoly uveme pro pehled seznam konstant,
promnnch, procedur a funkc deklarovanch v seku "interface"
unity Crt:

unit Crt;
interface
const
 { textov mdy }
  BW40          = 0;   {40x25 ernobl pro barevn adaptr}
  CO40          = 1;   {40x25 barevn pro barevn adaptr}
  BW80          = 2;   {80x25 ernobl pro barevn adaptr}
  CO80          = 3;   {80x25 barevn pro barevn adaptr}
  Mono          = 7;   {80x25 pro monochromatick adaptr }
  Font8x8       = 256; {43 resp. 50-ti dkov mdy}
  C40           = CO40; 
  C80           = CO80;

{ konstanty pro barvy textu a pozad }
  Black         = 0;
  Blue          = 1;
  Green         = 2;
  Cyan          = 3;
  Red           = 4;
  Magenta       = 5;
  Brown         = 6;
  LightGray     = 7;

{ konstanty pro barvy textu }
  DarkGray      = 8;
  LightBlue     = 9;
  LightGreen    = 10;
  LightCyan     = 11;
  LightRed      = 12;
  LightMagenta  = 13;
  Yellow        = 14;
  White         = 15;

{ konstanta pro blikn textu }
  Blink         = 128;

var

  CheckBreak: Boolean;    {zapn Ctrl-Break}
  CheckEOF: Boolean;      {zapn Ctrl-Z}
  DirectVideo: Boolean;   {zapn pm pstup k videopamti}
  CheckSnow: Boolean;     {zapn kontrolu snen obrazovky}
  LastMode: Word;         {aktuln textov md}
  TextAttr: Byte;         {aktuln textov atributy}
  WindMin: Word;          {souadnice levho hornho rohu
                            aktulnho okna}
  WindMax: Word;          {souadnice pravho dolnho rohu
                            aktulnho okna}

procedure AssignCrt (var F: Text)
function KeyPressed: Boolean;
function ReadKey: Char;
procedure TextMode(Mode: Integer);
procedure Window(X1,Y1,X2,Y2: Byte);
procedure GotoXY(X,Y: Byte);
function WhereX: Byte;
function WhereY: Byte;
procedure ClrScr;
procedure ClrEol;
procedure InsLine;
procedure DelLine;
procedure TextColor(Color: Byte);
procedure TextBackground(Color: Byte);
procedure LowVideo;
procedure HighVideo;
procedure NormVideo;
procedure Delay(MS: Word);
procedure Sound(Hz: Word);
procedure NoSound;



     Otzky a cvien

  1.  Co vte o videoadaptrech a videomdech? Jakm zpsobem
      lze v Turbo Pascalu nastavit textov md obrazovky?
  3.  Co jsou to textov atributy a jak je lze v Turbo Pascalu
      nastavit?
  4.  Kter procedury lze pout pi zpisu na obrazovku a k
      emu?
  5.  Jak prostedky poskytuje Turbo Pascal pro prci s okny?
  8.  Popite funkce ReadKey a KeyPressed.
 10.  Jak prostedky nabz Turbo Pascal pro psan "psniek"?
 11.  Co vte o unit Printer?
 12.  Jakm zpsobem lze urit stav tiskrny?
 13.  Jak procedury poskytuje Turbo Pascal pro prci se syst-
      movm asem a datem? Ve kter unit jsou deklarovny?





 9. Grafika

     V mnoha programech potebujeme na obrazovce zobrazit vsledky
ve form graf, schmat a obrzk. K tomu slou speciln unita
podporujc prci v grafickm reimu videoadaptru. Grafick
reim poskytuje mnohem lep rozliovac monosti zobrazen ne
textov, protoe v grafickm reimu je obrazovka rozdlena na
vce dk a sloupc a navc umouje vytvet obrazy bod po
bodu.

     Prci s grafikou umouje unita Graph. V tto unit je defi-
novna ada standardnch podprogram usnadujcch prci s
grafikou. Grafika je toton v Turbo Pascalu 5.0 i v 5.5, oproti
verzi 4.0 je zde nkolik novch monost.

     Grafiku meme pouvat, mme-li unitu GRAPH.TPU, dle ovla-
da (driver) pro pslunou grafickou kartu (videoadaptr)
eventuln fonty pro rzn typy psma. Ovlada je soubor s
rozenm .BGI, fonty jsou uloeny v souborech s rozenm
.CHR.
     Ovlada i unita jsou pro prci v grafice nezbytn!
     Interface unity Graph obsahuje vechny pouvan peddefi-
novan konstanty a typy, seznmme se s nimi postupn v ptch
odstavcch.

     Tato kapitola je rozlenna do 5 odstavc. V prvnm se sezn-
mme s prostedm pro prci grafiky - s videoadaptry, nasta-
venm reimu prce, atd. Ve druhm odstavci probereme parametry
grafiky jako jsou barvy, typy psma, ar atd. Dal odstavec je
vnovn vkonnm pkazm grafiky. Ve tvrtm odstavci budeme
studovat prci s stmi obrazovky (tzv. image), v dalm odsta-
vci poznme dal doplkov funkce grafiky a nakonec uvedeme
interface unity Graph..

9.1.Prosted grafiky 

     Grafick monosti PC IBM potae jsou vzny na videoada-
ptr a monitor potae. Monitor by ml odpovdat videoadaptru
- na monochromatickm monitoru nevyuijete barvy, apod.
     V naich podmnkch jsou nejastji pouvanmi adaptry CGA
(Color Graphics Adapter), EGA (Enhanced Graphics Adapter), HGC
(Hercules Graphics Card, tak oznaovan Hercules monochrome) a
VGA (Video Graphics Array). Dal mon adaptry uvedeme pozdji
v tabulce.
     Nkdy mluvme o videoadaptru jako o grafick kart, co je
termn odvozen z technick realizace adaptru.
     Dle se budeme zabvat pouze grafickm reimem videoadaptru.

9.1.1. Nastaven reimu

     Zpsob uloen dat ve videopamti 
zvis na videomdu. Videomd je specifikace grafickho reimu
ve smyslu rozliovac schopnosti (poet sloupc krt poet
dek), potu barev, vbru palety a potu strnek. Videomdy
jednotlivch adaptr shrneme v tabulce.

     Jet bychom se mli zastavit u vztahu programov podpory
grafiky a technickho vybaven. Softwarov je prce s grafikou
zajitna ovladaem a unitou Graph. Meme ale pracovat pouze s
videoadaptrem, kterm je vybaven n pota. Tedy ovlada pro
kartu EGA je k niemu, kdy na potai je adaptr CGA. Naopak
na nkterch dokonalejch adaptrech lze emulovat innost
jinho adaptru. Videomd vybrme nejen podle typu adaptru,
ale tak podle druhu monitoru.

     U jsme si ekli, e grafick ovladae jsou ve zvltnm
souboru s rozenm .BGI, v nsledujc tabulce je uveden
seznam videoadaptr a pslunch ovlada.

      ͻ
          VIDEOADAPTR          OVLADA     
      ͹
           Atari vechny typy   VDI.BGI     
                                            
           IBM CGA, MCGA        CGA.BGI     
           IBM EGA, VGA         EGAVGA.BGI  
           Hercules monochrome  HERC.BGI    
           AT&T 6300            ATT.BGI     
           IBM 3270 PC          PC3270.BGI  
           IBM - 8514           IBM8514.BGI 
      ͼ

     Ovlada pro konkrtn adaptr nastavme standardn procedurou
InitGraph (viz dle) a pomoc nkter z konstant z uvedenho
seznamu DRIVERS:

     const                                                  { DRIVERS }
          Detect        =    0;
          CGA           =    1;
          MCGA          =    2;
          EGA           =    3;
      EGA64         =    4;
      EGAMono       =    5;
          IBM8514       =    6;
          HercMono      =    7;
          ATT400        =    8;
          VGA           =    9;
          PC3270        =   10;
          CurrentDriver = -128;    { nepouv se pro nastaven! }

     Vztah mezi ovladai a konstantami v seznamu DRIVERS je uren
jmnem konstanty (s vjimkou konstant Detect a CurrentDriver),
tedy napklad ovlada EGAVGA.BGI pro adaptr EGA meme na-
stavit v pkazu InitGraph konstantou EGA, EGA64, EGAMono podle
poteby (tj. podle skuten instalovan karty) apod. Nkter
adaptry mohou navc emulovat innost jinch adaptr, samo-
zejm "jednoduch" nebo srovnatelnch, nap. EGA pln emuluje
kartu CGA, VGA emuluje EGA. Ke kompatibilit videoadaptr se
jet vrtme, a se seznmme s jejich vlastnostmi (barevn
monosti, rozlien, strnky, ...).

     Monosti nastaven jednotlivch adaptr uvdme v tabulce
GRAPHMODE, kde jsou:
-  Konstanty videomdu pevzat z sti interface unity Graph.
-  Rozliovac schopnost grafiky ve tvaru poet sloupc * poet
   dk.
-  Pro nkter adaptry segment adresy zatku vyuvan video-
   pamti.
-  Poet strnek pro dan md.
-  Poet barev, chyb-li, pak se jedn o monochromatick md
   (zkratka MONO).
-  slo palety barev (viz 9.2.1) a zkratky barev (mimo ern
   barvy, kter vdy pat do palety). Pro palety jsme pouili
   tto mluvy:
          0 = LightGreen, LightRed, Yellow    {LG,LR,Y}
          1 = LightCyan, LightMagenta, White  {LC,LM,W}
          2 = Green, Red, Brown               {G,R,B  }
          3 = Cyan, Magenta, LightGray        {C,M,LGr}

     Tabulka GRAPHMODE:

Ŀ
  Videomd  RozlienAdresaStrnekBarvy   Paleta   
Ĵ
CGAC0     =0 320*200  B800    1     4   0 = LG,LR,Y
CGAC1     =1 320*200  B800    1     4   1 = LC,LM,W
CGAC2     =2 320*200  B800    1     4   2 = G,R,B  
CGAC3     =3 320*200  B800    1     4   3 = C,M.LGr
CGAHi     =4 640*200  B800    1    MONO            
Ĵ 
MCGAC0    =0 320*200          1     4   0 = LG,LR,Y
MCGAC1    =1 320*200          1     4   1 = LC,LM,W
MCGAC2    =2 320*200          1     4   2 = G,R,B  
MCGAC3    =3 320*200          1     4   3 = C,M,LGr
MCGAMed   =4 640*200          1    MONO            
MCGAHi    =5 640*480          1    MONO            
Ĵ
EGALo     =0 640*200  A000    4    16              
EGAHi     =1 640*350  A000    2    16              
Ĵ
EGA64Lo   =0 640*200  A000    1    16              
EGA64Hi   =1 640*350  A000    1     4              
EGAMonoHi =3 640*350          1  pro 128 KB na kart 
                              2  pro 256 KB na kart 
Ĵ
HercMonoHi=0 720*348          2    MONO            
Ĵ
ATT400C0  =0 320*200          1     4   0 = LG,LR,Y
ATT400C1  =1 320*200          1     4   1 = LC,LM,W
ATT400C2  =2 320*200          1     4   2 = G,R,B  
ATT400C3  =3 320*200          1     4   3 = C,M,LGr
ATT400Med =4 640*200          1    MONO            
ATT400Hi  =5 640*400          1    MONO            
Ĵ
VGALo     =0 640*200  A000    4    16              
VGAMed    =1 640*350  A000    2    16              
VGAHi     =2 640*480  A000    1    16              
Ĵ
PC3270Hi  =0 720*350          1    MONO            
Ĵ
IBM8514LO =0 640*480          1   256              
IBM8514HI =11024*768          1   256              


     Videomdy pro kartu EGA nabzej videomd EGALo s rozlienm
640*200 bod, 16 barvami a se tymi strnkami. Vy rozlien
doshneme v mdu EGAHi 640*350 bod, 16 barev, ale poet strnek
se zmen na dv.
     Pro kartu EGA64 jsou k dispozici videomd EGA64Lo s rozli-
enm 640*200 bod, jednou strnkou a 16 barvami, EGA64Hi s
lepm rozlienm 640*350 bod, jednou strnkou a tymi barva-
mi. EGAMonoHi pracuje v monochromatickm reimu s rozlienm
640*350 bod a jednou nebo dvma strnkami podle instalovan
karty.
     Volba videomdu pro kartu EGA zvis mimo jin tak typu
instalovan grafick karty (karty se li pedevm velikost
videopamti).
     Pro adaptr Hercules existuje jedin md s rozlienm 720*348
a dvma strnkami v monochromatickm reimu.
     Adaptr AT&T 6300 umouje prci ve tyech mdech odlinch
pouze vbrem palety, s jedinou strnkou a rozlienm 320*200
bod. Dal dva mdy se vztahuj k monochromatickmu reimu,
poskytuj lep rozliovac schopnost (640 krt 200, resp. 400
bod) a jednu strnku.
     Karta VGA pat k vysoce kvalitnm adaptrm. Videomd VGALo
s nejmen rozliovac schopnost (640*200) m 16 barev a tyi
strnky. Md VGAMed m rozlien 640*350 bod, dv strnky a 16
barev. VGAHi m jedinou strnku, stle 16 barev a rozliovac
schopnost 640*480.
     U adaptru IBM 3270 PC je jedin monochromatick md s rozli-
enm 720*350 bod a jednou strnkou.
     Z uvedench adaptr je jasn nejlep adaptr IBM - 8514,
kter me pracovat ve dvou mdech. Prvn md IBM8514Lo m
rozlien 640*480 bod, jednu strnku a dokonce 256 barev. Druh
md IBM8514Hi se li pouze rozliovac schopnost 1024*768
bod.

     Kompatibilita videoadaptr znamen, e nkter adaptr me
emulovat innost jinho videoadaptru v plnm rozsahu, tj. ve
vech videomdech. Technicky dokonalej videoadaptry maj roz-
en sluby BIOSu pro prci s videoadaptrem. Jde tedy o to,
obsahuje-li toto rozen vechny sluby obsluhujc dan
videoadaptr (nap. VGA oproti A a EGA oproti CGA).
     Pehled kompatibility uvedench adaptr nememe udlat,
protoe monost emulace zvis na pesnm typu adaptru, piem
adaptry uveden v tabulce jsou jakmisi "typickmi pedstavite-
li". Napklad grafick karta EGA se vyskytuje v ad variant
licch se zejmna velikost pamti.

     Konstanty v seznamu DRIVERS a prv popsan konstanty video-
md se pouvaj pro oznaen ovlada a videomd v nsle-
dujcch grafickch pkazech.

     Nyn se po seznmen s konstantami, vyhrazenmi pro ovladae
a videomdy jednotlivch adaptr, naume grafiku iniciali-
zovat.

Ŀ
    procedure InitGraph(var Driver,Mode:integer;Path:string); 


     Procedura zavede do pamti ovlada uren parametrem Driver,
inicializuje grafiku do mdu urenho parametrem Mode a inicia-
lizuje vechny stavov promnn grafiky (viz 9.2.5). V etz-
covm parametru Path meme specifikovat cestu k ovladai.
     Voln procedury InitGraph mus bt ped vemi grafickmi
pkazy. Podrobnji:
-  Ovlada EGAVGA.BGI alokuje v HEAPu 9213 KB, CGA.BGI 10593 KB,
   atd., proto pozor na nastaven direktivy {$M...}. Mal rozsah
   HEAPu zpsob chybu (viz 9.1.3).
-  Prvn dva parametry jsou volny odkazem, a proto skuten
   parametry mus bt promnn typu integer. Nelze tedy pout
          InitGraph(EGA,EGAHi,'');
-  Parametrem Driver me bt libovoln konstanta ze seznamu
   DRIVERS vyjma CurrentDriver, tj. konstanty 1 a 10.
-  Zvolme-li konstantu Detect, je ovlada zvolen podle skuten
   instalovan grafick karty, jako videomd je volen nejvy
   mon md podle danho ovladae (nap. pro CGA to je CGAHi).
-  Videomd meme zadat do parametru Mode v rozmez hodnot
   konstant z prvnho sloupce "Videomd" ve uveden tabulky
   GRAPHMODE, samozejm vybrme videomd pslun zvolenmu
   ovladai, nap. pro CGA lze volit md v rozsahu 0 a 4.
   Videomdm je vnovn nsledujc odstavec.
-  Parametrem Path se uruje cesta k ovladai, je mon zadat i
   literl typu string. Pi zadvn cesty se dme pravidly MS
   DOSu. Przdn etzec oznauje aktuln adres.
-  Chybov hlen a piny chyb popeme v odstavci 9.1.3.
   Me dojt k chybm -2, -3, -4, -5, -10 a -15.
-  Pro adaptr IBM-8514 nelze pout konstantu Detect, ale mus
   se zadat konstanta IBM8514. Jak uvidme v nsledujcm ods-
   tavci, nelze pout ani proceduru DetectGraph.
Pklad:

          var GraphDriver,GraphMode : integer;
          begin ... GraphDriver:=EGA;
                          GraphMode:=1;      {nebo GraphMode:=EGAHi}
                          InitGraph(GraphDriver,GraphMode,'');...

   {  Pro adaptr EGA jsme inicializovali grafiku ve videomdu
      640*350 bod na obrazovce, s 16-ti barvami a dvma strn-
      kami, ovlada EGAVGA.BGI byl vyhledn v aktulnm adre-
      si. }
   {  Meme tak pout konstantu Detect. Pokraujme v popsanm
      pkladu. }
          ......... CloseGraph;     {te je grafika uzavena}
                          GraphDriver:=Detect;
                          InitGraph(GraphDriver,GraphMode,'c:\TPAS');
                          ... end;
   {  Ovlada byl tentokrt vyhledn v adresi TPAS. }

Ŀ
    procedure CloseGraph;                                     


     Tato procedura ukon grafick reim, pejde do textovho
reimu v mdu LastMode, smae obrazovku a uvoln pam. V texto-
vho reimu je nastavena barva psma bl a ern pozad, na-
staven barev (palety - viz dle) je nezvisl na nastaven v
grafickm reimu.
     Voln CloseGraph by mlo bt uvedeno za poslednm grafickm
pkazem. Chyb-li, zpsob to pote pi vstupech programu do
textovho reimu - pkazy se provedou v grafickm reimu, a
tedy s nedefinovanm vsledkem (nap. po nvratu do MS DOSu se
neobjev kurzor, nelze mnit reimy, ...).
     Pkaz CloseGraph uveden bez pedchozho voln InitGraph
(to znamen, e grafika nen inicializovan) jako prvn pkaz
grafiky nezpsob dnou chybu.

     MLUVY

     V dalm textu se budeme odvolvat na tzv. aktuln pozici,
zkratkou AP. Je to obdoba aktuln pozice kurzoru, jak ji znme
z textovho reimu, ale li se od n tm, e nen vidt. AP se
mn podle provdnch grafickch operac.
     V grafickm reimu se pouv nsledujc souadnicov sys-
tm (obrzek je pro kartu EGA v mdu 640*350 bod):

                      X
          >

       [0,0]                     [639,0]
         Ŀ
                                  
                                  
                                  
    Y                             
                                  
                                  
                                  
        
      v [0,349]                   [639,349]

     Lev horn roh m tedy vdy souadnice [0,0], souadnice
odpovdajc sloupci je na prvnm mst, druh souadnice uruje
dek. 
     Zpravidla se budeme dret oznaen X pro sloupcov souadnice
a Y pro dkov.
     Po proveden InitGraph je AP=[0,0].

     Turbo Pascal ve skutenosti pracuje v tzv. zobecnnm sou-
adnicovm systmu. Tento systm m rozmry [-MAXINT .. MAXINT,
-MAXINT .. MAXINT]. AP me bt v mezch tchto souadnic a tak
vechny podprogramy grafiky pracuj v tchto mezch. Systm si
meme schematicky zobrazit: 
                                                 
                             -MAXINT            
                                                
                                                
                                                
               -MAXINT       [0,0]       MAXINT 
               * 
                                               
                             Zobrazovno       
                                               
                            *      
                                         [639,349]  
                              MAXINT            
                                                 

     Ze zejmch dvod je vak z tohoto zobecnnho souadni-
covho systmu zobrazovna pouze st odpovdajc souadnmu
systmu nastavenho mdu (resp. podle SetViewPort). Zaveden
tohoto pojmu e vechny problmy se "zpisem mimo obrazovku",
a protoe se o nich nebudeme ji dle zmiovat, uveme pklad:

               ...
               MoveTo(0,0);      {umst AP do bodu [0,0]}
               LineTo(500,500);  {seka z [0,0] do [500,500]}
               LineTo(500,-150); {seka z [500,500] do [500,-150]}
               LineTo(0,349);    {seka z [500,-150] do [0,349]}
               {seky se zobrazuj se smrnicemi, kter odpovdaj
            znzornnmu zobecnnmu souadnicovmu systmu.}
               {  Schematicky viz na obrzku. }
               ...
                                  
           *Ŀ       
             \         /            
               \     /              
                 \ /                
                 / \                
               /     \              
             /         \            
           *       


Ŀ
  procedure GraphDefaults;                                  


     Umst AP do levho hornho rohu obrazovky a provede stan-
dardn nastaven vech parametr grafiky vetn barev tak, jak
je popeme v odstavci 9.2.5 a jak jsou nastaveny vdy po voln
InitGraph. Procedura nemae obrazovku.
     Videomd se nemn, protoe ten je nutn explicitn uvst bu
v pkazu InitGraph nebo v pkazu SetGraphMode.

Ŀ
  procedure ClearDevice;                                    


     Smae obrazovku v podkladov barv (v barv, kter byla
naposledy nastavena, viz 9.2.1) a AP umst do bodu [0,0].
Nastaven parametr nemn.

Ŀ
  function GetDriverName : string;                          


     Funkce vrac etzec obsahujc jmno aktivnho ovladae (tj.
ovladae zavedenho v pamti).
Pklad:
          var GD,GM : integer;
                s : string;
          begin ... GD:=EGA;
                GM:=EGAHi;
                InitGraph(GD,GM,'');
                          s:=GetDriverName;...CloseGraph;...
                          write('DRIVER = '+s); 
          { vype text: DRIVER = EGAVGA}
                ... 
          end;

9.1.2. Nastaven mdu videa 

     V pedchozm odstavci jsme se seznmili s ppustnmi mdy
videa pro jednotliv adaptry. Md videa je mon nastavit pro-
cedurou InitGraph. 
     Nkdy ale potebujeme zmnit md videa bhem prce s grafi-
kou, eventuln se na chvli vrtit do textovho reimu a pak
opt pokraovat v prci s grafikou (nap. zjistit maximln
mon md, detekovat pouit hardware, apod). K tomu slou dle
uveden procedury a funkce.

Ŀ
  procedure RestoreCrtMode;                                 


     Nastav podle promnn LastMode textov reim, kter byl
aktivn ped vyvolnm grafiky procedurou InitGraph. Ovlada
zstv zaveden v pamti.
     V textovm reimu nememe pouvat podprogramy definovan
pro grafick reim (nap. nastaven barvy psma musme provdt
pomoc procedury TextColor), pi voln grafickho podprogramu
je innost programu ukonena a na obrazovku se vype hlen:
BGI Error: Not in graphics mode. 
     Zdraznme, e nastaven barev v grafickm reimu nem vliv
na nastaven barev v textovm reimu.
     Pi obnoven textovho reimu se smae obrazovka a nastav se
barva psma na blou barvu, barva podkladu na ernou. V tomto
reimu mete pracovat do dalho vyvoln grafiky (InitGraph -
nepouvejte, protoe si zbyten zavedete do pamti znovu
ovlada; pouijte SetGraphMode).

Ŀ
  procedure SetGraphMode ( Mode : integer );                


     Parametrem procedury je slo mdu videa podle tabulky GRAPH-
MODE. Procedura nastav tento grafick md. Me dojt k chyb
-10, pokud se pokuste nastavit neexistujc md (nap. parametr
bude zporn). Procedura smae obrazovku, AP umst do bodu
[0,0] a nastav vechny parametry tak, jak jsou nastaveny po
InitGraph (viz 9.2.5).
     Pouit SetGraphMode po RestoreCrtMode m oproti pouit
CloseGraph a InitGraph jet tu vhodu, e nen znovu vyhledn a
zaveden ovlada, take jej proveden je mnohem rychlej.

Ŀ
  procedure DetectGraph ( var GD:integer; var GM:integer ); 


     Tato procedura vrac konstanty odpovdajc pouitmu hard-
waru. V GD je slo pslunho ovladae podle seznamu DRIVERS,
v GM md videa podle tabulky GRAPHMODE. Je-li vce monch md,
vrac procedura nejvy mon. Pokud chyb grafick karta,
dojde k chyb -2.
     Procedura DetectGraph skuten detekuje hardware, nen proto
dleit pedchoz nastaven grafiky. Je jednou z mla procedur
unity Graph, kter nevyaduje pedchoz pouit InitGraph.
Pklad poit:

     var GD,GM : integer;
     ... 
          DetectGraph(GD,GM);
          if GraphDriver < EGA then {chybov hlen}
          else InitGraph(GD,GM,'')
     ...

     Poznamenejme, e nsledujc sekvence jsou ekvivalentn:

     ...                                 ...
          GD:=detect;   { =0 }                DetectGraph(GD,GM);
          InitGraph(GD,M,'');                 InitGraph(GD,GM,'');
     ...                                 ...

Ŀ
  function GetGraphMode : integer;                          


     Funkce vrac aktuln grafick md, tedy md naposledy nasta-
ven procedurou InitGraph nebo SetGraphMode podle GRAPHMODE.

Ŀ
  procedure GetModeRange ( GD:integer; var LM,HM:integer ); 


     Vstupnm parametrem je odpovdajc slo ovladae podle
seznamu DRIVERS, vstupnmi parametry jsou LM, co je nejni
pouiteln md videa pro dan driver, a HM, co je nejvy
mon md podle GRAPHMODE.
     Pi zadn patnho parametru GD nedojde k chyb, ale do
promnnch LM, HM je uloena hodnota -1.

Ŀ
  function GetMaxMode : word;                               


     Vsledkem funkce je maximln mon md dle tabulky GRAPHMODE
pro prv aktivn ovlada. Je to tedy nejvy mon hodnota,
kter me bt argumentem procedury SetGraphMode.

Ŀ
  function GetModeName ( ModeNumber:word ) : string;        


     Pro zadan md (aktulnho ovladae) funkce vrac etzec
obsahujc nzev mdu ve tvaru poet sloupc krt poet dek,
nzev ovladae a eventuln oznaen pouit palety.
     Napklad budeme mt reim CGA v mdu CGAC2:

     var GD,GM : integer;
     begin
          GD:=CGA;
          GM:=CGAC2;
          InitGraph(GD,GM,'');
          OutText(GetModeName(GM));  {procedura OutText vype
                                   etzec v grafickm reimu,
                                   zobraz se:
                                                            '320 x 200 CGA C2'}

     Pi patn zadanm mdu nen vsledek definovn a vsledkem
je etzec obsahujc nedefinovanou st pamti.

Ŀ
  function GetMaxX : integer;                               


     Funkce vrac maximln poet sloupc v grafickm reimu
aktulnho ovladae a mdu. Pozor na to, e rozmry se v grafice
potaj od 0, tedy pro reim EGA 640 x 350 vrt tato funkce
hodnotu 639.

Ŀ
  function GetMaxY : integer;                               


     Analogicky jako pedchzejc funkce vrac tato funkce maxi-
mln poet dk v aktivnm reimu, ve zmnnm pklad to
bude hodnota 349.

     Tyto dv funkce se pouvaj pi formtovn vstupu nez-
visle na zvolenm mdu (nap. umstn obrzku ve stedu obra-
zovky).

Ŀ
  procedure GetAspectRatio ( var Xasp,Yasp : word );        


     Touto procedurou je mon zjistit pomr Xasp/Yasp horizon-
tlnch a vertiklnch vzdlenost mezi body na obrazovce. Tento
pomr nen zvisl na fyzickm nastaven ky horizontlnho a
vertiklnho dkovn monitoru, kter bv u lepch monitor
run nastaviteln. Pouv se ke korekci pi zobrazen pra-
videlnch obrazc (pro EGA kartu je to piblin "10:8").
     Korekce je provdna automaticky u pkaz pro kresbu kru-
nice nebo oblouku (Circle, Arc). Kdybychom chtli nakreslit
krunici bez pouit standardn procedury circle, museli bychom
pi uren y-ov souadnice bodu krunice provst vynsoben
pomrem Xasp/Yasp.

Ŀ
  procedure SetAspectRatio ( Xasp,Yasp : word );            


     Tato procedura pracuje podobn jako pedchoz s tm rozdlem,
e tentokrt zadvme pomr parametry Xasp a Yasp. M vliv
pouze na standardn procedury Circle a Arc.
     Nastaven pomru Xasp/Yasp zstv nezmnno pi proveden
pkazu GraphDefaults, ale je zmnno pkazy RestoreCrtMode,
SetGraphMode na implicitn hodnoty.
     Pouv se ve spojen s procedurou GetAspectRatio, pomoc n
se ur aktuln pomr Xasp/Yasp, tento pomr pak meme zmnit
procedurou SetAspectRatio. Nap.:

     ... GetAspectRatio(Xasp,Yasp);  {samozejm jsme v grafice!}
           Circle(100,120,20);          {krunice se stedem v bod
                                   [100,120] a polomrem 20}
           Yasp:=Yasp*3;
           SetAspectRatio(Xasp,Yasp);
           Circle(300,120,20);          {krunice je "roztaena" do
                                   ky}
           Yasp:=round(Yasp/6);
           SetAspectRatio(Xasp,Yasp);
           Circle(500,120,20);          {tentokrt je krunice prota-
                                   ena do vky}
           ...

9.1.3. Chybov hlen

     Pi prci v grafickm reimu napklad snadno dojde k si-
tuaci, kdy chcete zapisovat mimo obrazovku. Nic se nestane -
st obrzku chyb, ale k chyb nedojde. K chybm, kter jsou
hleny a vedou k peruen vpotu, me dojt inicializaci
mdu, pi specifikaci reimnebo v ppad nesmyslnch parametr
(zporn sla, apod.), kdy je bu vsledek nedefinovan nebo
me dojt k bhov chyb.
     V unit Graph jsou deklarovan tyto chybov konstanty:

     const grOk               =  0; {No error}
               grNoInitGraph      = -1; {(BGI)graphics not installed
                                                       (use InitGraph)}
               grNotDetected      = -2; {Graphics hardware not
                                                       detected}
               grFileNotFound     = -3; {Device driver file not found}
               grInvalidDriver    = -4; {Invalid device driver file}
               grNoLoadMem        = -5; {Not enough memory to load
                                                       driver}
               grNoScanMem        = -6; {Out of memory in scan fill}
               grNoFloodMem       = -7; {Out of memory in flood fill}
               grFontNotFound     = -8; {Font file not found}
               grNoFontMem        = -9; {Not enough memory to load
                                                       font}
               grInvalidMode      =-10; {Invalid grafics mode for
                                                       selected driver}
               grError            =-11; {Graphics error}
               grIOError          =-12; {Graphics I/O error}
               grInvalidFont      =-13; {Invalid font file}
               grInvalidFontNum   =-14; {Invalid font number}
               grInvalidDeviceNum =-15; {Invalid device number}

     Anglick komente ke grafickm chybm jsou vmluvn, pesto
si jednotliv chyby jet strun popeme:
     -0  = grafick operace probhly bez chyby.
     --1 = z njakho dvodu nebyl proveden pkaz InitGraph.
      Ovte, e jej skuten provdte, a pak za nj dejte
      kontroln vpis funkce GraphResult (viz dle).
     --2 = nen instalovn grafick hardware, tedy nen k dispo-
      zici grafick karta.
     --3 = nebyl nalezen ovlada, tj. soubor s rozenm BGI.
      Ovte jeho existenci v adresi specifikovanm pkazem
      InitGraph.
     --4 = ovlada (soubor typu BGI) je pokozen. Nahrajte jej
      znovu z distribunch disket.
     --5 = nen dostatek pamti v HEAPu pro zaveden ovladae.
      Zkontrolujte direktivu {$M...}, eventuln zrute rezi-
      dentn programy v pamti.
     --6 = nen dostatek msta v pamti pro vyplovn zadan
      oblasti (nap. FillPoly). Postupujte jako v ppad chyby
      slo -7.
     --7 = nen dostatek pamti pro vyplnn oblasti procedurou
      FloodFill. Zkontrolujte parametry procedur, kter pro-
      vdj vyplovn oblast (v dalm textu je u kad
      procedury uvedeno, zda me zpsobit chybu, ppadn slo
      chyby). Dal monost je pouit procedury SetGraphBuf-
      Size, kter umouje zvtit vyrovnvac pam pro operace
      vyplovn oblast.
     --8 = nenalezen soubor urujc typ psma (soubor typu
      CHR). Ovte, zda existuje v adresi specifikovanm v
      pkazu InitGraph.
     --9 = nen dostatek msta k zaveden souboru typu CHR do
      pamti. Postupujte jako v ppad chyby -5.
     --10 = hodnota videomdu nen pro zvolen ovlada p-
      pustn. Pouijte pro volbu mdu napklad nkterou z
      popsanch monost - zadn ovladae konstantou Detect
      (md se nastav automaticky), procedura DetectGraph v
      parametrech vrac konstanty odpovdajc instalovanmu
      hardwaru, zjistte maximln ppustnou hodnotu videomdu
      funkc GetMaxMode.
     --11 = nekorektn hodnoty parametr nkterch standardnch
      grafickch procedur, zkontrolujte zejmna parametry pro-
      cedur, kter nastavuj stavov promnn.
     --12 = chyba pi ten BGI souboru nebo CHR souboru. Zkuste
      ten zopakovat, eventuln soubory znovu nahrajte z
      distribunch disket.
     --13 = soubor typu CHR je pokozen, nahrajte jej znovu z
      distribunch disket.
     --14 = patn slo urujc soubor typu CHR, konstanty pro
      zadn souboru typu CHR najdete v odstavci 9.2.4.
     --15 = cesta uveden v pkazu InitGraph obsahuje nedo-
      volen zazen.

     Chyby -1, -2, -3, -4, -5, -10 vedou pi dalm voln nkter
grafick procedury k ukonen programu, zobraz se jedno ze dvou
nsledujcch hlen:
          BGI Error: Graphics not initialized (use InitGraph)
          BGI Error: Not in graphics mode

     Informaci o chyb pi prci v grafickm reimu podvaj
funkce:

Ŀ
  function GraphResult : integer;                           


     Funkce vrac kd chyby pro posledn provdnou grafickou
operaci. Kdy chyb jsme prv uvedli. Pokud k chyb nedojde,
vrac hodnotu 0.
     Pznak chyby je nastaven po proveden tchto grafickch
pkaz:

          Bar                      ImageSize           SetFillPattern
          Bar3D                         InitGraph           SetFillStyle
          ClearViewPort       InstallUserDriver   SetGraphBufSize
          CloseGraph               InstallUserFont          SetGraphMode
          DetectGraph              PieSlice            SetLineStyle
          DrawPoly                 RegisterBGIdriver   SetPalette
          FillPoly                 RegisterBGIfont          SetTextJustify
          FloodFill           SetAllPalette       SetTextStyle
          GetGraphMode

     Tyto grafick pkazy mohou vst k chyb. Pokud k n dojde,
nastav pznak chyby. Tento pznak meme pest a vynulovat
funkc GraphResult. Pokud chyba nevede k ukonen vpotu,
meme pokraovat v prci (nap. vytisknout hlen, e dolo k
chyb, a pak pokraovat v provdn programu).

Ŀ
  function GraphErrorMsg (ErrorCode : integer) : string;    


     Tato funkce dopluje pedchoz funkci. Vsledkem je etzec
charakterizujc chybu slo ErrorCode, tyto etzce jsou uve-
deny jako komente u konstant popisujcch jednotliv chyby.
     asto se uv tmto zpsobem (pedpokldejme inicializovanou
grafiku):
     var Error    : integer;
           ErrorMsg : string;
     begin
     ... Error:=GraphResult; ...
           ErrorMsg:=GraphErrorMsg(Error);
     ... if Error <> 0 then
                begin
                RestoreCrtMode;
                writeln(ErrorMsg);
                end
           else ... { pokraujeme v grafice }
     end;

9.1.4. Okna

     Podobn jako v textovm, tak i v grafickm reimu meme
pracovat s "okny" - tedy definovat si na obrazovce obdlnkovou
oblast, do n budeme smovat vechny grafick vstupy. Um-
stn okna urme levm hornm bodem a pravm dolnm bodem
obdlnkov oblasti.
     Samozejm me dojt k situaci, kdy vsledek nkter gra-
fick operace pekrauje vymezenou oblast. V tomto ppad
meme sami urit, zda se tyto pesahy budou zobrazovat nebo zda
zstaneme omezeni pouze na dan okno.
     V kadm okamiku meme mt (na aktivn strnce - viz dal
odstavec) definovan jedin okno, v nm pracujeme. Nelze tedy
definovat vce oken najednou a pak mezi nimi jenom "pepnat".
     Po definovn okna pracuj vechny pkazy s relativnmi
souadnicemi vzhledem k danmu oknu. Lev horn bod okna se
stv bodem [0,0] v novch souadnicch.
     Absolutnmi souadnicemi mme na mysli souadnicov systm na
cel obrazovce, jak byl popsn v odstavci 1.1.1.
     Okno je popsno v unit Graph typem:

     const
          ClipOn  = true;
          ClipOff = false;
     type
          ViewPort = record
                                x1,y1,x2,y2 : integer;
                                Clip        : boolean;
                           end;

     Poloky x1,y1 obsahuj souadnice levho hornho rohu defi-
novanho okna, x2,y2 jsou souadnice pravho dolnho rohu, jak
je vidt z obrzku:

         Ŀ
                                   
            [x1,y1]                
            *Ŀ         
                                 
                                 
                                 
                                 
            *[x2,y2]  
         

     Poloka Clip uruje, budou-li pesahy zobrazeny nebo ne.
Hodnota ClipOn (tedy true) uruje, e pesahy se nezobraz.
Hodnota ClipOff (false) umouje zobrazit pesahy.

     Definici a zmny oken zajiuj procedury:

Ŀ
  procedure SetViewPort (x1,y1,x2,y2:integer;Clip:boolean); 


     Procedura definuje okno uren body [x1,y1], [x2,y2] v abso-
lutnch souadnicch a parametrem Clip. 
     Samozejm mus platit, e x1<x2 a zrove y1<y2. Poruen
tto zsady nezpsob chybu (GraphResult vrac nulu), ale je
nastaveno okno [0,0], [GetMaxX,GetMaxY], take napklad pkazy
uveden v relativnch souadnicch se provedou v absolutnch
souadnicch.
     AP se umst do bodu [0,0], co je tedy lev horn bod defi-
novanho okna.
     Parametr Clip obvykle zadvme pomoc peddefinovanch kon-
stant.

Ŀ
  procedure GetViewSettings ( var ViewPort:ViewPortType );  


     V parametru typu ViewPortType jsou v celoselnch polokch
vrceny (absolutn) souadnice aktivnho okna a v poloce Clip
je uloen stav pepnae (ClipOn/ClipOff). 
     Nen-li definovan dn okno, jsou v promnn ViewPort
uloeny rozmry standardnho okna (tedy cel obrazovky), co
jsou nap. v ppad karty EGA a mdu 640*350 bod hodnoty:
x1=0, y1=0, x2=639, y2=349, Clip=true.

Ŀ
  procedure ClearViewPort;                                  


     Vymae oblast odpovdajc naposled definovanmu oknu. Pokud
nebylo dn okno definovan (pkazem SetViewPort), smae se
cel obrazovka. Nastaven oken se nemn, jak se mete pe-
svdit pomoc pedchoz procedury.
     Okno je smazno v aktuln barv podkladu (o barvch si
povme vce v odstavci 9.2.1). Ale pozor - nememe zmnit barvu
podkladu a vymazat obsah okna v nov barv. Vdy pi zmn barvy
pozad se pebarv cel obrazovka! Zobrazen objekty na pe-
barven obrazovce zstanou a vymae se pouze obsah okna.

     Popsan procedury si zaslou pklad - definujeme okno s
levm hornm bodem [10,20] a pravm dolnm [120,130], nepovolme
pesahy, parametry okna ulome do promnn typu ViewPort,
zobrazme seku spojujc body [10,20] a [120,130], pak obno-
vme textov reim a vypeme na obrazovku parametry okna:

     var v : ViewPortType;
     ... { pedpokldme inicializovanou grafiku }
   SetViewPort(10,20,120,130,ClipOn); 
   Line(0,0,110,110);         {pkaz pro zobrazen seky spoju-
                              jc body s relativnmi souadni-
                              cemi [0,0] a [110,110] }
   GetViewSettings(v); 
   RestoreCrtMode; 
   with v do 
      writeln('x1 = ',x1,' y1 = ',y1,' x2 = ',x2,' y2 = ',y2,
                         'CLIP = ',Clip); 
     ...

9.1.5. Strnky

     V odstavci 1.1.1 jsme se zmnili o existenci strnek (lo-
gickch) ve videopamti a definovali jsme aktivn a zobrazovanou
strnku. Poet strnek zavis na zvolenm videomdu.

     Prci se strnkami umouj dv procedury. Prvn z nich uin
strnku aktivn, to znamen, e vechny grafick pkazy se
provdj na dan strnce. Druh procedura zadanou strnku
zobraz. Mohlo by se zdt, e to jsou stejn operace, ale v tom
je prv pitalivost strnek - zatmco je jedna strnka "vidi-
teln", na dal (nebo dalch) strnce se mezitm vytv nov
obraz.
     Vhodnm stdnm obou procedur a dalch pkaz doshneme
pomrn efektnch vsledk, jako jsou jednoduch animace, ply-
nul stdn text a ilustrac, apod.

     Umstn AP a nastaven oken je vdy pouze jedno. To znamen,
e pi kadm pemstn AP, resp. definici okna, se AP, resp.
definice okna, zmn na vech strnkch. Proto nen mon mt
nap. dv strnky s odlin nastavenmi okny a okna mnit jenom
"strnkovnm".

     Slben procedury:

Ŀ
    procedure SetActivePage ( Page : word );                  


     Procedura smuje vechny grafick operace na strnku slo
Page. Strnky se sluj od 0. Poet strnek zvis na zvolenm
videomdu a ovladai.
     Pokud zadte slo neexistujc strnky, nebudou se grafick
pkazy provdt, ale chybu to nezpsob.

Ŀ
    procedure SetVisualPage ( Page : word );                  


     Procedura zobraz strnku slo Page. Strnky se sluj
stejn jako v pedchoz procedue. Zadme-li slo neexistujc
strnky, zobraz se strnka slo 0. Grafick chyba nen hle-
na.

     Pi inicializaci grafiky je vdy aktivn a zobrazovna str-
nka slo 0.
     asto se pracuje s jednou strnkou, kter je aktivn a z-
rove se i zobrazuje. Mme-li ale monost pracovat na vce
strnkch, pouv se nezobrazen strnka k vytven obraz,
jejich realizace je pli zdlouhav, apod.
     Popsan procedury si zaslou pklad. Vzhledem k tomu, e
jsme jet neprobrali vkonn pkazy grafiky, budeme pouvat
vlastn, ble nepopsan procedury:

     procedure MyText(s : string);
     begin ... { procedura zobraz etzec s } ... end;

     procedure Schema;
     begin ... { procedura zobraz schma }    ... end;

     begin ...
     GraphDriver:=EGA;        {volme adaptr EGA}
     GraphMode:=1;            {md 640*350 bod, 2 strnky}
     InitGraph(GraphDriver,GraphMode,'');
     SetVisualPage(0);        {zobrazen strnka 0, zrove aktivn}
                                        {zobraz se nsledujc text}
     MyText('Vytvarim schema');    
     SetActivePage(1);        {zatmco je zobrazen text, aktivn se
                           stv strnka 1}
     Schema;                       {na aktivn strnce se zobraz schma,
                           bhem vytven je stle zobrazovna
                           strnka 0}
     SetVisualPage(1);        {po dokonen je schma zobrazeno}
     ...
     end;

     Uveden pklad demonstroval pouit strnek pro potlaen
dlouhho vytven obrzk. Nsledujc pklad je animac
otejc se kruhov vsee (zkuste tento pklad i bez strn-
kovn a porovnejte vsledky ...).

     var 
          i,j   : integer; 
     const 
          step  : byte=15; 

     procedure Vysec ( alfa:integer; Color:byte ); 
     {Procedura zobraz kruhovou vse (60 stup) barvou Color
      a potenm hlem alfa. }
     begin 
     SetFillStyle(SolidFill,Color); 
     PieSlice(100,100,alfa mod 360,60+alfa mod 360,50); 
     end; 
 
     begin 
     DetectGraph(GD,GM); 
     InitGraph(GD,GM,''); 
     i:=step; 
          for j:=1 to 15 do 
          begin 
          SetActivePage(0); 
          i:=i-step; 
          Vysec(i,Black); 
             i:=i+step; 
          Vysec(i,White); 
          SetVisualPage(0); 
             SetActivePage(1); 
          Vysec(i,Black); 
          i:=i+step; 
          Vysec(i,White); 
          SetVisualPage(1); 
          end; 
          ...
     end.


9.2. Parametry grafiky

     Grafika v Turbo Pascalu 5.5 m adu parametr, kter si
programtor me sm nastavit. Jsou to barvy, typy ar, vpln
oblast a parametry pro psmo.
     Implicitn nastaven parametr po inicializaci grafiky pop-
eme v samostatnm odstavci (9.2.4).

9.2.1. Barvy

     VOD

     Jet ne se pustme do popisu konstant, typ, funkc a
procedur definovanch v unit Graph pro prci s barvami, musme
si vysvtlit, jak jsou barvy tvoen a co to je paleta.

     Zobrazen barev je realizovno kombinac t barevnch sign-
l (erven, zelen, modr) a jejich intenzity. Vsledn efekt
pot zvis na typu monitoru, zda se barvy zobraz barevn nebo
jako odstny edi i pouze v ernoblm kontrastu.

     Nejprve budeme definovat zkladn pojmy, kter nm usnadn
vklad prce s barvami. Jsou to tyto pojmy: vnitn barva,
paleta, velikost palety, rozsah palety, barva vzhledem k palet,
barva psma, barva pozad, okraj a barva okraje.
     Vnitn barva je slo charakterizujc barvu, obvykle odpo-
vd fyzick reprezentaci barvy. Vnitn barva je jednoznan
piazen kad barv.
Pklad: u adaptru EGA uvedeme nkter vnitn barvy:
               tmav zelen   =  2
               stedn zelen = 16
               svtl zelen  = 18
     Rozsah barev je maximln poet vnitnch barev danho video-
adaptru (u EGA 0 a 63).
     Z technickch dvod nen mon zobrazit vechny vnitn
barvy najednou na monitoru. Proto je vdy teba specifikovat
podmnoinu vnitnch barev (paletu), kter se pouv pro zobra-
zen na monitoru.
     Paleta je uspodan podmnoina vnitnch barev. Vnitn
barvy v palet jsou v danm uspodn oslovny pirozenmi
sly od nuly (u EGA 0 a 15).
     Velikost palety je slo udvajc poet najednou zobrazi-
telnch vnitnch barev. Velikost palety zvis na videoadaptru
a videomdu.
Pklad: u karty EGA je velikost palety 16.
     Barva vzhledem k palet je poadov slo vnitn barvy v
rmci palety.
     MLUVA: pod pojmem barva budeme rozumt barvu vzhledem k
palet.
     Okraj je st obrazovky mimo nejvt zobraziteln okno. Do
okraje nen mono zapisovat v textovm ani grafickm reimu.
     Barva okraje je vnitn barva okraje. Barvu okraje lze zmnit
pomoc peruen BIOSu (viz 8.1.4). Implicitn je barva okraje
ern.

     Krom ve definovanch pojm budeme pracovat tak s pojmy, 
kter ji nesouvis s technickou realizac zobrazen barev. Jsou
to tyto pojmy:
     Barva psma je barva nastaven procedurou SetColor (viz
dle). Tato barva se pouv pi zobrazen ar, obrys obrazc a
psma.
     Barva vpln je barva nastaven procedurami SetFillStyle,
SetFillPattern. Pouv se pi "vybarven" vpln obrazc a spe-
cifikovanch oblast.
     Barva pozad je prvn barva palety (poadov slo 0).
     Pozad (tak podklad) je pojem velmi pesn v ppad texto-
vho reimu, kdy zobrazujeme pouze omezenou mnoinu pevn danch
znak. V grafickm reimu vytvme obraz bod po bodu, a proto
budeme pozad intuitivn chpat jako body, kter jsme explicitn
nezobrazili a kterch bv na obrazovce "vc".

     Dsledky uvedench definic:
-  Pi zmn palety se vdy ihned zmn interpretace barev
   obsahu obrazovky. Nelze tedy kombinovat dv palety na jedn
   obrazovce. Vyplv to z definice palety.
-  Procedura ClearViewPort mae obrazovku v aktuln barv
   pozad, nyn ji vme, co to znamen.
-  O pozad mluvme vtinou v ppadech, kdy je naprosto jasn,
   co to znamen - napklad zobrazme seku na jinak "przdn"
   obrazovce.

     PEDDEFINOVAN KONSTANTY A TYPY

     Barvy vzhledem k palet jsou definovny v unit Graph pomoc
konstant:

     const                                             {COLORS}
          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;

     Pro zachovn kompatibility mezi adaptrem IBM - 8514 a
ostatnmi adaptry existuj jet dal konstanty:

     const                                             {EGA-COLORS}
          EGABlack        =  0;
          EGABlue         =  1;
          EGAGreen        =  2;
          EGACyan         =  3;
          EGARed          =  4;
          EGAMagenta      =  5;
          EGABrown        = 20;
          EGALightGray    =  7;
          EGADarkGray     = 56;
          EGALightBlue    = 57;
          EGALightGreen   = 58;
          EGALightCyan    = 59;
          EGALightRed     = 60;
          EGALightMagenta = 61;
          EGAYellow       = 62;
          EGAWhite        = 63;

     Konstanty v seznamu EGA-COLORS pedstavuj implicitn vnitn
barvy barev palety uvedench v seznamu COLORS. Schematicky si
meme vztah vnitnch barev a barev vzhledem k palet znzornit
na obrzku:

              Ŀ
Vnitn barva  0 1 2 3 4 520 75657585960616263
              
                0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
                          Barva vzhledem k palet

     Obvykl rozsah barev je pro kartu EGA 64 barev, vnitn barvy
se sluj od 0 do 63, velikost palety bv 16 barev. Tyto
hodnoty zvis na zvolenm videomdu danho adaptru, jak jsme
se s nimi seznmili v tabulce GRAPHMODE.

     Paleta je popsna v sti interface unity Graph pomoc kons-
tanty MaxColors a typu PaletteType:

     const
          MaxColors = 15;
     type
          PaletteType = record
               Size   : byte;
               Colors : array [0..MaxColors] of shortint;
          end;

     V poloce Size je velikost palety, v poli Colors jsou uloeny
vnitn barvy palety, index pole Colors odpovd barv vzhledem
k palet.

     Pro doplnn informac si nyn probereme monosti jedno-
tlivch videoadaptr podrobn.

     BARVY V ADAPTRECH

     MONO reim (adaptry Hercules, PC3270a pslun mdy v CGA,
MCGA a ATT)

     V tomto reimu se pracuje pouze v bl barv na ern barv
pozad a nem smysl pout dnou z procedur a funkc tkajcch
se barev. Jejich pouit je bu ignorovno nebo dojde k chyb.
     Vhodou tohoto reimu je snadn uloen obrazu v pamti,
nebo body jsou uloeny po dcch a dky po bitech (0=ern,
1=bl), piem pstup k tmto datm je obdobn pstupu v
textovm reimu. 
     Napklad v CGA zanaj sud dky (ponaje nultm dkem)
na adrese B800H, lich dky na adrese BA00H a meme napsat
kupkladu takovouto podmnku:

     if MEM[ $BA00 : (5 div 2)*(640 div 8)+(18 div 8) ]
                    and 32 > 0 then { bod [18,5] je bl} ...

     CGA, MCGA, ATT v barevnm mdu

     Tyto adaptry pracuj se tybarevnou paletou, kter vak
nen nastaviteln a je urena pi volb mdu prce (vbr ze
ty pevn danch palet). V tomto reimu nem smysl pouvat
procedury a funkce pro prci s paletou, ale pouze podprogramy
pro nastaven barvy (barvy vzhledem k palet 0..3).
     V tomto reimu je cel obsah obrazovky jet uloen v pamti.
Opt po dcch, piem jednomu bodu odpovdaj dva bity, v
nich je zakdovan pslun barva vzhledem k palet (0..3).

     EGA

     Ega m nastavitelnou 16-ti prvkovou paletu. Existuje 16
registr pro jednotliv barvy palety a jeden registr pro okraj.
Okraj je implicitn ern.
     Rozsah palety je 64.

     Zpsob kdovn vnitn barvy:
          bit 7 - rezervovan
                6 - rezervovan
                5 - SecondaryRed
                4 - SecondaryGreen
                3 - SecondaryBlue
                2 - Red
                1 - Green
                0 - Blue

piem barvy s pvlastkem Secondary maj intenzitu 1/3, osta-
tn barvy intenzitu 2/3, take barvu s maximln intenzitou
zskme kombinac zmnnch barev. Napklad zelen je 02H
(obsazen bit 1), "stedn" intenzivn zelen je 10H (bit 4) a
nejsilnj intenzitu zelen barvy doshneme hodnotou 12H (bity
1 a 4).
     V tomo reimu lze pln vyuvat vechny dle uveden pocedury
a fukce tkajc se barev mimo procedury SetRGBPalette. Obsah
obrazovky stejn, jako u VGA a IBM - 8514, je z valn sti
uloen mimo adresovateln sti pamti a pstup k nmu je mon
pouze pes pslun porty a to dost sloitm zpsobem, kter se
pro svou pracnost ve vych jazycch nepouv.
     Pro dokreslen pedstavy o paletch CGA uveme kdy barev
jednotlivch palet v CGA podle implicitn palety v EGA (vnitn
barvy):
               C0 - 0,10,12,14
               C1 - 0,11,13,15
               C2 - 0, 2, 4, 6
               C3 - 0, 3, 5, 7

     VGA

     M 16-ti prvkovou paletu z 256K vnitnch barev. Protoe je
pln kompatibiln s EGA, lze pro nj pout libovolnou proceduru
jako u EGA. Chceme-li vyut jeho 256K vnitnch barev, meme
pout proceduru SetRGBPalette jako u IBM - 8514.

     IBM - 8514

     Tento adaptr m 256-ti barevnou paletu z 256K vnitnch
barev. Uv ti zkladn 6-ti bitov barvy (erven, zelen,
modr) pro definici ostatnch barev. Vnitn barva je tak slo-
ena z tchto t barev. piem kad me nabvat jedn z 64
intenzit (porovnejme to s EGA kartou, kter rozliuje jenom 4
intenzity: 0, 1/3, 2/3, 1). Z tohoto dvodu existuje speciln
procedura SetRGBPalette pro manipulace s paletou, ostatn stan-
dardn procedury nelze ut (tj. SetAllPalette, SetPalette,
GetPalette).


     V nsledujc sti popeme jednotliv pkazy pro prci s
barvami, u kadho pkazu strun na pkladu nazname pou-
it, na zvr tohoto odstavce shrneme vyloen pojmy ve vtm
pkladu.

     PKAZY PRO PRCI S BARVAMI

Ŀ
  procedure GetDefaultPalette ( var Pal : PaletteType );    


     V parametru Pal je vrcena paleta tak, jak byla iniciali-
zovna pkazem InitGraph. Pokud tedy bhem prce v grafickm
reimu mnme paletu, tmto pkazem zjistme pvodn nastaven
barev.
Pklad:

     var P : PaletteType;
     ... {pedpokldme inicializovanou grafiku} ...
     GetDefaultPalette(P);    {do promnn P se uloila paleta
                              nastaven po inicializaci grafiky}
     RestoreCrtMode;               {nvrat do textovho reimu}
     writeln('Barva podkladu = ',P.Colors[0]);
     writeln('Treti barva palety = ',P.Colors[2]);
     ... {podobn si meme vypsat cel obsah palety}

Ŀ
  procedure GetPalette ( var Palette : PaletteType );       


     Tato procedura vrac v promnn Palette aktuln paletu. To
znamen paletu naposledy nastavenou. Pokud nedolo ke zmn
palety, vrt stejn hodnoty jako pedchoz procedura.
Pklad:

     var P : PaletteType;
     ... {pedpokldme inicializovanou grafiku} ...
     GetPalette(P);
     ... {nyn je v P uloena aktuln paleta}

Ŀ
  procedure SetAllPalette ( var Palette );                  


     Procedura zmn celou paletu. Parametrem je netypovan (!)
promnn Palette. Zmna se provede tak, e prvn byte promnn
Palette se bere jako velikost palety, dal byty jako vnitn
barvy palety. Me dojt k chyb -11.
     Pipomeme, e kad zmna palety zpsob pebarven obsahu
obrazovky.
     Doporuujeme mnit paletu pomoc promnn typu PaletteType.
Pklad:

     var P : PaletteType;
     ... {pedpokldme inicializovanou grafiku} ...
     GetDefaultPalette(P);    {do P se nastav implicitn barvy}
     SetAllPalette(P);             {paleta se nastav na implicitn
                              hodnoty}
     ...

Ŀ
  procedure SetPalette ( ColorNum:word; Color:shortint );   


     Procedura zmn v palet barvu vzhledem k palet ColorNum na
vnitn barvu Color. ColorNum mus bt od 0 do MaxColors (=15).
Me dojt k chyb -11.
     Opt plat, e zmna v palet se ihned projev na obrazovce.
Pklad:

     ... SetPalette(blue,8);...  { na msto modr barvy je
                                   nastavena tmav modr barva}

Ŀ
  procedure SetRGBPalette ( ColorNum,R,G,B : word );        


     Tato procedura je urena pro adaptr IBM - 8514 nebo adaptr
VGA. Parametr ColorNum uruje barvu vzhledem k palet, me bt
v rozsahu 0 a 255 pro IBM - 8514, eventuln 0 a 15 pro VGA
kartu. Parametry R, G, B uruj zkladn barvy palety. Tyto
parametry jsou typu word, proto se z nich bere doln byte a z
nj je pouito 6 bit (viz [BORLAND 88]).

Ŀ
  function GetPaletteSize : word;                           


     Funkce vrac velikost aktuln palety.

Ŀ
  function GetMaxColor : word;                              


     Vsledkem je nejvy slo barvy vzhledem k palet. Nap.
pro kartu EGA vrac funkce GetPaletteSize slo 16, zatmco
funkce GetMaxColor vrac 15.

Ŀ
  procedure SetColor ( Color : word );                      


     Nastavuje barvu psma. Parametr Color se vybr z barev
vzhledem k aktuln palet. Hodnota skutenho parametru by mla
bt v rozmez 0 a velikost palety, nap. pro kartu CGA ve
videomdu ty barev (CGA1) by se mlo vybrat z hodnot 0 a 3.
     Zvolme-li barvu mimo uveden rozmez, nezpsob to chybu,
ale nastav se urit barva vzhledem k palet. 
     Volba tto barvy zvis na ovladai a videomdu, nap. u
karty EGA se mohou zadvat barvy s vymi hodnotami ne 15,
nastav se barva Color mod 16, zatmco u karty CGA v mdu uva-
jcm paletu 0 se nastavuje pro Color vt ne 3 stle nejvy
barva vzhledem k palet 0, tj. lut.

Ŀ
  procedure SetBkColor ( Color : word );                    


     Procedura nastav podle parametru Color barvu pozad, to
znamen prvn barva vzhledem k palet se nahrad barvou (vzhle-
dem k palet) Color, tedy hodnota skutenho parametru by mla
bt v rozmez 0 a 15.
     Je-li Color=0, nastav se vdy ern barva bez ohledu na
vnitn barvu prvn barvy vzhledem k palet (tj. Colors[0]).

     V souvislosti s obma zmnnmi procedurami bychom se mli
zastavit u ppadu, kdy barva psma a barva podkladu jsou to-
ton. To znamen, e jejich vnitn barvy se shoduj, tebae
barva psma a barva podkladu jsou rzn barvy vzhledem k palet.
Pi dal zmn palety se jejich vnitn barvy mohou opt liit.
Pklad:
     Na obrazovce se nap. zobraz seka stejnou barvou jako
barva podkladu (v tto chvli nen vidt), pak se zmn barva
pozad a seka je na novm podkladu viditeln.
     Tento efekt si meme piblin vysvtlit tm, e barva
kadho bodu je uloena jako barva vzhledem k palet. Pedpokl-
dejme, e jsme nastavili barvu pozad pkazem SetBkColor(5), v
palet je na prvnm i ptm mst uloen slo stejn vnitn
barvy, ale obrazovka je uloena takto:

    
    4000000000
    0400000000
    0040000000
    0004000000  >
    0000400000
    0000040000
        
        
        v

Nyn jsou barvy 0 a 4 vzhldem k palet stejn, ale pi zmn
barvy pozad se zmn jen prvn barva vzhledem k palet, nov se
obarv tedy jen ty body, kter jsou na obrzku uloeny jako "0".

Ŀ
  function GetColor : word;                                 


     Vsledkem funkce je barva vzhledem k palet nastaven proce-
durou SetColor nebo nastaven implicitn po zaveden grafiky. 

Ŀ
  function GetBkColor : word;                               


     Funkce pracuje obdobn jako pedchoz, vsledkem je barva
podkladu.

     Na zvr vkladu o barvch a paletch si uvedeme pklad:

     uses Graph,Crt;
     var 
          P : PaletteType;
          GD,GM : integer;
     procedure TiskPalety(var P : PaletteType); 
     var i : byte; 
     begin 
     with P do 
          begin 
               ClrScr;
          writeln; 
          writeln('      VELIKOST PALETY = ',size); 
          writeln('      BARVY PALETY : '); 
          for i:=0 to 15 do writeln('          ',colors[i]); 
          end; 
          delay(2000);
     end;
  
     begin
          GD:=EGA;                      {inicializace grafiky pro EGA}
          GM:=1;
          InitGraph(GD,GM,'');

          GetDefaultPalette(P); 
        RestoreCrtMode; 
     TiskPalety(P);           {vytisknou se barvy nastaven pi
                                              inicializaci}
        SetGraphMode(GM);
          SetBkColor(11);          {zmn P.Colors[0] na 11}
          SetPalette(1,5);         {  "   P.Cplors[1] na 5}
          SetPalette(2,5);         {  "   P.Colors[2] na 5}
          SetColor(5);             {neprovede dnou zmnu v palet}
      GetPalette(P);          {paleta se zmnnou barvou pozad
                                              se ulo do P}
        RestoreCrtMode; 
     TiskPalety(P);           {tisk zmnn palety}
     SetGraphMode(GM); 
          ... end;

9.2.2. ry

     Dalm parametrem, kter si meme zvolit, je tlouka a typ
ar. Nastaven tohoto parametru se projevuje ve vech pkazech
uvajcch ry (nap. Line, Rectangle, Arc, DrawPoly, apod.),
ale nikoli v pkazech pracujcch s texty, protoe typ psma je
uren jinmi parametry.

     ry jsou popsny nsledujcmi konstantami a typem:

     const                                                  {LINE-STYLE}
          SolidLn    = 0;     {pln ra}
          DottedLn   = 1;     {ra sloen z "bod" - krtkch rek}
          CenterLn   = 2;     {erchovan ra}
          DashedLn   = 3;     {peruovan ra}
          UserBitLn  = 4;     {uivatelem definovan typ ry}
                                                            {THICKNESS}
          NormWidth  = 1;     {normln tlouka ry (1 bod)}
          ThickWidth = 3;     {silnj tlouka ry (3 body)}

     type
          LineSettingsType = record
               LineStyle : word;
               Pattern   : word;
               Thickness : word;
           end;

     Typ LineSettingsType popisuje zpsob zobrazovn ar. V
poloce LineStyle je uloen typ ry, mohou to bt konstanty 0
a 4 ze seznamu LINE-STYLE. Pokud je v LineStyle uloena kons-
tanta 4, vytv se typ ry podle poloky Pattern. V poloce
Thickness je tlouka ry, tedy 1 nebo 3 podle seznamu THICK-
NESS.

     ra se vytv podle "charakteristickho slova", co je
vlastn 16-ti bitov maska, v n se ozna jednotliv bity k
zobrazen. Kad ra se skld z 16-ti bodovch sek.
     Pro usnadnn prce jsou nejpouvanj typy ar pedde-
finovny konstantami 0 a 3. Vlastn typ ry me uivatel
zadat v poloce Pattern, kter je typu word. Maska se aplikuje
od hornch bit.
     Napklad hodnota 225 vytvo peruovanou ru, hodnota
65535 plnou ru. Bitov reprezentace poloky Pattern = 225:

     Ŀ
                      X X X X X X X X
     
 Bit:  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0

Pattern = 65535 (odpovd peddefinovan konstant SolidLn):

     Ŀ
      X X X X X X X X X X X X X X X X
     
 Bit:  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0

     Poznamenejme, e je vdy lep vytvet masku tak, aby byl
bit 15 obsazen (viz peddefinovan konstanty), nebo tak je
namalovna i pomrn krtk st. 

     Bitov reprezentace peddefinovanch konstant uvdme v 
tabulce:

         Ŀ
DottedLn  X X     X X     X X     X X    
         Ĵ
CenterLn  X X X X X X X X     X X X X    
         Ĵ
DashedLn  X X X X X X     X X X X X X    
         

     Procedury pro prci s rami jsou:

Ŀ
  procedure SetLineStyle(LineStyle,Pattern,Thickness:word); 


     Procedura nastav zpsob vytven ar typu LineStyle, tlou-
ky Thickness a je-li LineStyle=4, uprav se ra podle masky
zadan v parametru Pattern.
     Me dojt k chyb -11.
     Parametr Thickness by ml bt 1 nebo 3, jin hodnoty zpsob
kresbu normln tloukou ry.

Ŀ
  procedure GetLineSettings (var LnInfo:LineSettingsType);  


     V promnn typu LineSettingsType jsou vrceny parametry prce
s rami tak, jak byly naposled nastaveny SetLineStyle nebo
inicializovny systmem. Tedy v poloce LineStyle je typ ry, v
Thickness je tlouka a v Pattern je uloena maska pro vytvoen
ry.

9.2.3. Vpln

     Pi tvorb grafickch objekt asto potebujete urit obla-
sti vyplnit - rafovnm, rznmi barvami, znaky a podobn.
Typickm pkladem je tzv. kolov graf, kde jednotliv sti
kruhu mus bt vrazn odlieny.
     Vyplovat oblasti se naume v odstavci vnovanm obrazcm
(9.3.2), nyn se seznmme s druhy vpln, monost definice
vlastn vpln a s procedurami pro prci s vplnmi.
     Pi vbru vpln zle na videomdu a grafick kart (nebo
emulaci karty) - nkter vpln vypadaj efektn v reimu CGA
karty, ale v reimu s vtm rozlienm (nap. EGA) zaniknou.

     Vpl je urena matic 8*8 bod, v tto matici je zakdovn
urit obrazec (realizac se budeme zabvat za chvli). Vkonn
pkaz provdjc vyplnn oblasti pak pokryje zadanou oblast
polky s urenm obrazcem nebo st obrazce (v okrajch po-
krvan oblasti)

     Nejprve se seznmme s peddefinovanmi konstantami a typy
pro vpln:

     const
          EmptyFill      =  0;     {vpl oblasti v barv pozad}
          SolidFill      =  1; {vpl oblasti v barv psma}
          LineFill       =  2; {vpl vodorovnmi arami }
          LtSlashFill    =  3; {vpl /// }
          SlashFill      =  4; {vpl /// silnmi arami}
          BkSlashFill    =  5; {vpl \\\ silnmi arami}
          LtBkSlashFill  =  6; {vpl \\\ s hustmi arami}
          HatchFill      =  7; {vpl mkou}
          XHatchFill     =  8; {vpl ikmou mkou}
          InterleaveFill =  9; {vpl hustou ikmou mkou}
          WideDotFill    = 10; {dk tekovn}
          CloseDotFill   = 11; {hust tekovn}
          UserFill       = 12; {vpl podle vlastn definice}

     type
          FillSettingsType = record
               Pattern : word;
               Color   : word;
           end;

          FillPatternType = array [1..8] of byte;

     Typ FillSettingsType uruje typ vpln pomoc ve popsanch
konstant a barvu vzhledem k palet, v n se vpl zobraz.
     V ppad, e je Pattern = 12, pouije se k uren vpln typ
FillPatternType, kde je uloen tvar vpln jako bitov mapa 8*8
bit. Kad bit v tto masce odpovd bodu a uruje, zda je bod
zobrazen nebo ne. Vpl skldajc se napklad z kk (+++)
definujeme takto:

     const Krizek : FillPatternType=(24,24,24,255,255,24,24,24);

     Konstantu Krizek meme pout jako parametr v procedue
SetFillPattern.

     Nastaven vpln a informace o vplnch poskytuj procedury:

Ŀ
  procedure SetFillStyle ( Pattern:word; Color:word );      


     Procedura nastav podle aktuln palety barvu vpln a na-
stav typ vpln parametrem Pattern. Je-li Pattern = 12 (nebo
vt), vytvo vpl podle nastaven procedurou SetFillPattern.
     Me dojt k chyb -11, samozejm se typ a barva vpln
nezmn.

Ŀ
  procedure SetFillPattern (P:FillPatternType; Color:word); 


     Touto procedurou nastavme vlastn typ vpln. Parametr Color
uruje barvu vpln. Parametr P uruje pomoc bitov mapy, jak
bude vpl vypadat. 
     Stejn jako v procedue SetFillStyle je zde parametr defi-
nujc barvu vpln. Je to uiten v situaci, kdy pouvme
vce vlastnch vpln a zobrazujeme je rznmi barvami.
     Me dojt k chyb -11, pak se ale aktuln typ vpln ne-
zmn.
Pklad: vyuijeme ve definovan konstanty Krizek a zobrazime
obdlnk vyplnn "kky", pouijeme standardn proceduru Bar,
s n se seznmme v odstavci 9.3.2.

     const Krizek : FillPatternType=(24,24,24,255,255,24,24,24);
     ... SetFillStyle(12,1);
           SetFillPattern(Krizek,1); {Pepe barvu danou pro-
                                   cedurou SetFillStyle. }
           Bar(30,30,130,130);
     ... { Obdlnk byl vyplnn "kky" v barv 1. }

9.2.4. Texty

     Vstupy v grafickm reimu potebujeme samozejm tak ko-
mentovat a popisovat. V grafice reprezentovan v Turbo Pascalu
unitou Graph jsou v zsad ti monosti pro zpis textu:
-  Prvn monost je psmo vytven pomoc bitov mapy 8*8
   bod. Toto psmo je obsaeno v unit Graph, pouv se impli-
   citn, pokud nen zvolen jin styl psma.
-  Jako samostatn soubory typu CHR existuj tak zvan rov
   typy psma, kdy jednotliv zobrazovan znaky jsou vytveny
   pomoc ar. Styl psma se specifikuje zvltnm pkazem,
   nen-li pslun soubor nalezen, pouije se "bitov" psmo.
   Existuj tyi soubory obsahujc rov typy psma, jsou to:
          TRIP.CHR -psmo sloen z trojitch ar
          LITT.CHR -psmo vhodn pro zpis text v menm formtu,
                  tvo jej jednoduch ry
          SANS.CHR -psmo tvoen dvojitmi arami
          GOTH.CHR -vysoce ozdobn typ psma
   O struktue tchto soubor se zmnme jet v odstavci 9.5.
-  Posledn monost je vyut procedur textovho reimu write a
   writeln. M-li promnn DirectVideo z unity Crt hodnotu
   false nebo je vstup realizovn pomoc slueb Dosu (viz 8.1),
   zobrazuj se vsledky uvedench procedur v grafickm reimu,
   piem se pouv aktuln nastaven paleta v grafice.

     Psmo vytven bitovou mapou je vhodn k zpism v menm
mtku, protoe pi vtm zvten jsou znaky nepli hezky
sloen z obdlnk.
     rov typy psma oproti tomu vyniknou pi zobrazen text ve
vtm mtku.
     Texty zapsan pomoc procedur writeln, write jsou vytvoeny
tak bod po bodu, ale ve tvaru a velikosti znak z textovho
reimu v mdu 80 znak na 25 dek.

     Dle se budeme v tomto odstavci zabvat prvnmi dvma monos-
tmi, tj. rovmi typy psma a psmem vytvenm bitovou mapou.
Procedurami write a writeln se budeme zabvat v odstavci 9.3.5.

     Pro prci s texty jsou v unit Graph peddefinovan nsle-
dujc konstanty urujc styl psma TEXTSTYLE, smr psma (ver-
tikln nebo horizontln) TEXTDIRECTION a velikost psma TEXT-
SIZE:

     const                           {TEXTSTYLE}
          DefaultFont   = 0;
          TriplexFont   = 1;
          SmallFont     = 2;
          SansSerifFont = 3;
          GothicFont    = 4;

          HorizDir      = 0;           {TEXTDIRECTION}
          VertDir       = 1;

          UserCharSize  = 0;           {TEXTSIZE}

     Dal konstanty obsaen v seznamu TEXTJUSTIFICATION uruj
horizontln zarovnn, tj. umstn textu vzhledem k AP, od n
se m text napsat (prvn ti konstanty), a vertikln umstn, 
tj. umstn vzhledem k "dce", na kterou se text pe (nsle-
dujc ti konstanty, konstanta CenterText je pro plnost uve-
dena v obou stech):

     const                           {TEXTJUSTIFICATION}
          LeftText   = 0;
          CenterText = 1;
          RightText  = 2;

          BottomText = 0;
       {CenterText = 1;}
          TopText    = 2;

     Vyjmenovan konstanty se uvaj k definici typu psma, pro
tento el je zaveden peddefinovan typ:

     type
          TextSettingsType = record
               Font      : word;             {styl psma}
               Direction : word;         {smr psma}
               CharSize  : word;         {velikost psma}
               Horiz     : word;         {horizontln zarovnn}
               Vert      : word;         {vertikln zarovnn}
          end;

     Jednotliv poloky typu TextSettingsType se zadvaj pomoc
ve uvedench seznam: poloka Font podle TEXTSTYLE, Direction
dle TEXTDIRECTION, CharSize dle TEXTSIZE nebo slem, poloky
Horiz a Vert dle konstant v seznamu TEXTJUSTIFICATION.
     Zdraznme, e veker textov vstupy jsou provedeny barvou
psma.

     Po obeznmen s konstantami a peddefinovanm typem se sezn-
mme s pkazy pro nastaven stylu psma:

Ŀ
  procedure SetTextStyle ( Font,Direction,CharSize : word );


     Tato procedura nastavuje typ psma. Prvnm parametrem je
Font urujc styl psma, pouvaj se konstanty popsan v
seznamu TEXTSTYLE. Psmo odpovdajc konstant Default je
vytven na zklad bitov mapy, nen soust dnho souboru.
Konstanty TriplexFont, SmallFont, SansSerifFont, GothicFont
odpovdaj psmu tvoenmu pomoc ar, psmo je uloen v sou-
borech s rozenm CHR, jsou to soubory TRIP.CHR, LITT.CHR,
SANS.CHR, GOTH.CHR.
     Je-li skutenm parametrem hodnota odpovdajc nktermu
rovmu typu psma, zavede se do pamti (HEAPu) pslun
soubor. Jednotliv fonty (soubory odpovdajc nktermu stylu
psma) zabraj v pamti (piblin velikost v bytech):
               TriplexFont   ... 7800 
               SmallFont     ... 2700 
               SansSerifFont ... 6000 
               GothicFont    ... 9100 
     Pi zmn fontu je pedchoz font z HEAPu uvolnn pomoc
FreeMem. Procedura SetTextStyle se proto ned kombinovat s
pkazem Release.
     Z uvedench velikost plyne, e pi pouit nejvtho fontu
GOTHIC.CHR a ovladae EGAVGA.BGI je teba pro grafiku potat
18300 byt msta v HEAPu.
     Zadme-li neexistujc slo fontu (viz 9.5) jako skuten
parametr, zvol se styl psma odpovdajc konstant DefaultFont
(bitov mapa).

     Druh parametr uruje, zda je text zobrazen horizontln
zleva doprava nebo vertikln (tm rozumme otoen textu v
horizontln poloze o 90 stup) ve smru zdola nahoru. Opt
zadvme prostednictvm peddefinovanch konstant v seznamu
TEXTDIRECTION.
     Peshne-li hodnota skutenho parametru 1, bere se verti-
kln smr psma. Poznamenejme, e v ppad psma tvoenho
bitovou mapou me dojt jet k otoen vertiklnho smru o 90
stup a texty jsou zobrazeny v tomto umstn.

     Tet parametr uruje velikost psmen. Velikost psmen je
zvisl na stylu psma. 
     Nejprve tedy mjme psmo vytven na zklad bitov mapy 8*8
bod. Bitov mapa 8*8 bod odpovd velikosti psma 1, vt
velikosti odpovdaj pslun zvten bitov map, nap.
velikost 2 koresponduje s mapou 16*16 bod. Maximln zvten
pvodnho psma nen omezen (ale pozor na pesahy, na monitoru
se nezobraz), prakticky je nejvt zvten 10 a 15-ti n-
sobn.
     Pro rov styly psma je maximln mon velikost 10, m-li
skuten parametr vt hodnotu ne 10, bere se jako velikost
psma hodnota 10. V ppad psma urenho konstantou SmallFont
je prvn "iteln" velikost 4, texty zapsan v men velikosti
jsou pli mal. U ostatnch styl psma lze velikost volit v
mezch 1 a 10.
     Me dojt k chybm -8, -9, -11, -12, -13, -14. O jejich
pinch jsme se zmiovali v odstavci 9.1.3.

Ŀ
  procedure SetTextJustify ( Horiz, Vert : word );          


     Parametry tto procedury uruj zpsob zobrazen text (pro-
cedurami pro vstup v grafickm reimu OutText, OutTextXY).
     Parametr Horiz uruje horizontln zarovnn, to znamen
umstn zobrazovanho textu vzhledem k AP. Vznam konstant ze
seznamu TEXTJUSTIFICATION si znzornme v obrzku:

                  
Horiz = LeftText                       X X X X X X X X X X  
                  
Horiz = CenterText           X X X X X X X X X X            
                  
Horiz = RightText  X X X X X X X X X X                      
                  
                                                           
                                      AP                    

     Podobn si znzornme vznam parametru Vert vzhledem k aktu-
ln pozici napklad pro umstn textu vlevo od AP:

                                  Ŀ
Vert = BottomText                          T E X T         
                             AP   *

                                  Ŀ
Vert = CenterText            AP   *         T E X T         
                                  

                             AP   *Ŀ
Vert = TopText                             T E X T         
                                  

     Nsledujc procedury usnaduj formtovn text:

Ŀ
  procedure GetTextSettings ( var Info:TextSettingsType );  


     V parametru Info typu TextSettingsType jsou po zavoln
procedury uloeny aktuln parametry psma: styl, smr, velikost
a umstn psma.

Ŀ
  function TextHeight ( TextString : string ) : word;       


     Vsledkem funkce je vka etzce udan v bodech. Vka
vstupnho etzce se uruje podle aktulnho stylu psma a
zvolen velikosti psma (viz rozmr A na obrzku dle). Pi
uren vky etzce tedy nezle na velkch a malch psme-
nech, plat:
                         TextHeight('A')=TextHeight('a')

Ŀ
  function TextWidth ( TextString : string ) : word;        


     Funkce vrac ku etzce zobrazenho aktulnm stylem
psma. Vsledek je uveden v bodech. ka etzce zvis na
dlce etzce, stylu psma, velikosti a jeho obsahu.
     Funkce vrac ku etzce vetn posledn meziznakov mezery
na konci etzce. Pro psmo tvoen bitovou mapou je ka
meziznakov mezery konstantn a vechna psmena maj stejnou
ku. U ostatnch styl psma je ka psmen promnn. Nap-
klad plat:
          TextWidth('Janicka')=TextWidth('Jani')+TextWidth('cka')
          TextWidth('Janicka')<>TextWidth('Milacek')
     
     Tato funkce se uv stejn jako ve zmnn funkce pi
formtovn text na obrazovce v grafickm reimu. Z uvedench
vlastnost vyplv, e texty nelze snadno editovat pepsnm
sti textu, vhodnj je pepsat cel text znovu.

Ŀ
  procedure SetUserCharSize ( MultX,DivX,MultY,DivY:word ); 


     Tato procedura umouje definovat pro rov typy psma
vlastn ku a vku.
     V definici stylu psma zvolme nkter z rovch typ psma
(viz seznam TEXTSTYLE), smr psma (viz TEXTDIRECTION) a veli-
kost zadme konstantou UserCharSize. Velikost meme zadat i
jinou hodnotou, ale vsledek bude pi pouit procedury SetUser-
CharSize stejn, proto je vhodn zadat pi volb stylu psma
konstantu UserCharSize, kter napovd, e budeme psmo mnit
spaciln procedurou SetUserCharSize.
     Parametry MultX a DivX uruj pomr MultX/DivX, v jakm se
zmn ka text zobrazench aktivnm stylem psma.
     Obdobn parametry MultY, DivY zadvaj pomr (MultY/DivY) pro
zmnu vky v textu.
     Zkladn velikost pro zvolen styl psma se bere 4. Jsou-li
tedy parametry tto procedury rovny jedn, zobraz se texty
aktulnm stylem psma a ve velikosti 4.
     Pomoc procedury SetUserCharSize lze formtovat texty do
pesn urench oblast, jak si to ukeme na pkladu.
Pklad: 
     Napeme proceduru WriteBox, kter do zadan obdlnkov
oblasti vepe uren text danm stylem psma, text pak ormuje
rmekem. Rmeek si znzornme hlavn pro kontrolu umstn
textu.
     Parametrem procedury jsou: styl psma Font, souadnice levho
hornho bodu obdlnkov oblasti [x1,y1], souadnice pravho
dolnho bodu [x2,y2] a etzec s, kter chceme zobrazit.
     V procedue nejprve nastavme styl psma, umstn textu,
definujeme pomry upravujc ku a vku textu vzhledem k
rmeku, pot etzec vytiskneme procedurou OutTextXY a nakres-
lme rmeek pkazem Rectangle (oba pkazy probereme v odsta-
vci 9.3).

...
procedure WriteBox (font:word;x1,y1,x2,y2:integer;s:string); 
begin 
   SetTextStyle(font,HorizDir,UserCharSize); 
   SetTextJustify(LeftText,BottomText); 
   SetUserCharSize(x2-x1,TextWidth(s),y2-y1,TextHeight(s)); 
   OutTextXY(x1,y2,s); 
   Rectangle(x1,y1,x2,y2);
end;
... 
begin ... WriteBox(TriplexFont,10,10,630,110,'Hoj'); ... end.

     Na obrazovce se zobrazil rmeek se zadanm textem. Umstn
textu z hlediska ky je sprvn, na vku je text umstn
celkem sprvn - vad nm jenom to, e psmeno j pesahuje pod
rmeek a naopak v horn sti rmeku je nad psmenem H jet
voln msto odpovdajc pesahu pod rmeek.
     Nyn bychom si mli podrobn vysvtlit, jak rozmrov pra-
vidla pro jednotliv styly psma plat (na rzn styly psma se
budeme odvolvat pomoc peddefinovanch konstant ze seznamu
TEXTSTYLE). K vkladu pouijeme zjednoduen obrzek:

   
                                                        
                            ɻ       
                                    ȼ              
A                  ͻ     ͻ             
   B         ͹                              
      C                                     D   
                                                
     
                                              E     
                Ĵ           ͼ      
                      F                                  

     Horn a doln ryska uruj "dek", do nho se text zobra-
zuje. Vznam zakreslench veliin:
     A = vka psma tak, jak ji vrac funkce TextHeight
     B = vka velkho psmene
     C = vka malho psmene
     D = vka psma vzhledem k "pesahujcm" psmenm, plat A=D
     E = pesah pod doln rysku, plat B=D-E, A=B+E
     F = ka psmene

     Pro psmo tvoen bitovou mapou plat pevn dan rozmrov
vztahy. Zkladn velikost bitov mapy je 8*8 bod, pi zvten
psma se zvt odpovdajcm zpsobem bitov mapa. Plat tyto
rozmrov vztahy:
     A = D = 8
     B = 7
     C = 5
     E = 1
     F = 6
     Toto psmo m na rozdl od rovch typ stejnou ku vech
psmen.

     U rovch typ psma rozliujeme styl SmallFont a zbvajc
styly (TriplexFont, SansSerifFont, GothicFont), kter jsou z
hlediska velikosti a pomrovch vztah shodn. Pomry jsme
piblin odhadli hodnotami:
                                                    
     ͻ
                       A : B    A : C    A : E 
     ͹
       SmallFont        1.3      1.9      4.3  
     Ķ
       Ostatn styly    1.3      1.9      4.5  
     ͼ

     ka psma je u rovch typ psma rzn podle zobrazo-
vanch znak. Proto je vhodn pouvat funkce TextWidth.
     Vku znak jsme shrnuli do nsledujc tabulky, kde je pro
plnost uvedeno i psmo DefaultFont (bitov mapa). Vka je
samozejm uvedena v bodech:                                 
                                                             
     ͻ 
      Zvten     1  2  3  4  5  6  7  8  9 10  
     ͹ 
      DefaultFont  8  16 24 32 40 48 56 64 72 80 
     Ķ 
      SmallFont    4  5  6  8  10 13 16 20 24 32 
     Ķ 
      Ostatn      16 18 21 28 37 46 56 70 84112 
     ͼ 

     Na zvr si jet upesnme umstn textu konstantami ze
seznamu TEXTJUSTIFICATION. Horizontln zarovnn je jasn, text
se umsuje podle aktuln pozice nebo urenho bodu (pkazy
OutText, OutTextXY). Vertikln umstn (odpovdajc kons-
tantm TopText, BottomText) se provd podle veliiny A, to
znamen, e text se umst podle horn, resp. doln rysky v
naem obrzku. Umstn dle konstanty CenterText odpovd stedu
mezi obma ryskami.
     Tm se tak vysvtluje, pro jsme v pkladu (kde jsme pou-
vali funkci TextHeight) neumstili text pesn do rmeku.

9.2.5. Souhrn stavovch promnnch a inicializace

     Stavov promnn grafiky uruj grafick prosted z hlediska
nastaven barev, typu vpln, nastaven typu psma, apod. Sta-
vov promnn se inicializuj pkazy InitGraph a GraphDefaults.
     Nyn si popeme implicitn nastaven stavovch promnnch v
poad, jak jsme se s nimi seznmili:
     -Ovlada a videomd jsou nastaveny pkazem InitGraph,
      pouijeme-li ovlada uren konstantou Detect, nastav se
      videomd na nejvy mon pro detekovanou grafickou
      kartu.
     -Okno je nastaveno na maximln velikost, tj. je ureno
      body [0,0], [GetMaxX,GetMaxY] a konstantou ClipOn (GetMaxX
      oznauje nejvy mon slo sloupce pro dan videomd,
      obdobn GetMaxY).
     -Aktuln pozice je [0,0].
     -Aktivn strnka, kter se zrove zobrazuje, je strnka
      slo 0.
     -Paleta se zvol podle videomdu. Nkter palety (napklad
      pro adaptr CGA) jsou uvedeny v tabulce GRAPHMODE, impli-
      citn nastaven palety pro EGA kartu jsme uvedli v od-
      stavci 9.2.1.
     -Barva psma je nastavena na nejvy barvu vzhledem k
      palet.
     -Barva podkladu je prvn barva vzhledem k palet.
     -Styl ar je SolidLn, tlouka je NormWidth, maska Pattern
      definovan uivatelem je 0.
     -Typ vpln je nastaven na vpl SolidFill, barva vpln je
      nejvy barva vzhledem k palet, uivatelsk typ vpln
      Pattern je (255, 255, 255, 255, 255, 255, 255, 255).
     -Styl psma je DefaultFont (bitov mapa), smr HorizDir,
      velikost 1. Horizontln umstn textu je nastaveno na
      LeftText, vertikln na BottomText.

9.3. Vkonn pkazy

     V tomto odstavci se seznmme s vkonnmi pkazy grafiky.
Pkazy zobraz podle zadanch parametr grafick objekty aktu-
ln barvou, stylem ar, apod. U kad skupiny grafickch p-
kaz uvedeme stavov promnn, ktermi se pkazy d (barva,
vpl, psmo, ...).
     Vstupy vkonnch pkaz se provdj v rmci aktulnho
okna, pesahy se mohou zobrazovat.
     Pokud nkter souadnice grafickho objektu jsou mimo rozsah
standardnho okna, nedojde ke grafick chyb, pouze se st
obrazu na obrazovce (resp. ve standardnm oknu) nezobraz.
Nedojde ani k zpisu "pesahujc" sti na dal strnku. V
ppad pkazu, kter mn aktuln pozici, me mt AP sou-
adnice mimo standardn okno na obrazovce.

     Vkonn pkazy budeme v kadm odstavci ilustrovat na pk-
ladu. Vdy budeme pedpokldat, e je inicializovan grafika 
pro kartu EGA a videomdu EGAHi.

     MLUVA: V dalm textu se asto budeme odkazovat na sou-
adnice aktuln pozice AP. Abychom to nemuseli komplikovan
opisovat, budeme tyto souadnice oznaovat [APx,APy].
     Maximln rozmry standardnho okna budeme oznaovat MaxX a
MaxY. Napklad pro EGA kartu v mdu EGAHi je MaxX=639,
MaxY=349.

9.3.1. seky

     V tomto odstavci jsou krom vkonnch pkaz pro zobrazen
seek tak pkazy pro umstn aktuln pozice.
     seky se zobrazuj aktuln barvou psma (nastavena pro-
cedurou SetColor) a zvolenm stylem ry (nastaven procedurou
SetLineStyle) v zadanm reimu zpisu. Krom peddefinovanch
styl ar meme definovat tak vlastn typ ry.

     Vkonn pkazy:

Ŀ
  function GetX : integer;                                  


     Vsledkem je sloupcov absolutn souadnice AP.

Ŀ
  function GetY : integer;                                  


     Vrac dkovou absolutn souadnici AP.

Ŀ
  procedure MoveTo ( X,Y : integer );                       


     Umst aktuln pozici do bodu [x,y], piem souadnice
[x,y] jsou absolutn a AP se umst bez ohledu na nastaven
okno. V textovm reimu existuje obdobn procedura GoToXY. AP
mn nsledujc pkazy:
          ClearDevice              MoveRel
          ClearViewPort            MoveTo
          GraphDefaults            OutText
          InitGraph                SetGraphMode
          LineRel                  SetViewPort
          LineTo

Ŀ
  procedure MoveRel ( Dx,Dy : integer );                    


     Procedura penese AP do bodu [APx+Dx,APy+Dy]. Procedura je
vhodn v ppadech, kdy provdme grafick operace v relativnch
souadnicch, a proto nechceme AP pemsovat do pevn danho
bodu.

Ŀ
  procedure SetWriteMode ( WriteMode : integer );           


     Procedura uruje reim zpisu do videopamti. Reim me bt
bu koprovn do pamti, kdy se data ulo bez ohledu na ped-
choz obsah, nebo uloen, kdy se provede mezi daty uloenmi v
pamti a daty ukldanmi operace XOR (non ekvivalence), podrobn
je tento reim zpisu (XORPut) popsn v odstavci 9.4. Z vlast-
nost operace XOR plyne, e dvoj proveden tto operace za
sebou obnov pvodn obsah obrazovky.
     Parametr WriteMode uruje, kter z obou reim bude vybrn.
Existuj peddefinovan konstanty:

          const
               CopyPut = 0;
               XORPut  = 1;

CopyPut (koprovn) a XORPut (XOR), doporuujeme je pouvat.
     Po inicializaci systmu je nastaven reim koprovn.
     Tento pkaz m vliv pouze na procedury:
               Line                Rectangle
               LineRel             DrawPoly
               LineTo              Bar3D
               PieSlice            Sector

     Pouit si ukeme v nsledujcm pkladu:

          uses Graph; 
          var GD,GM,i : integer; 

          begin 
             GD:=EGA; 
             GM:=EGAHi; 
             InitGraph(GD,GM,''); 
             SetWriteMode(XORPut); 
             Rectangle(150,130,450,210); 
             Readln; 
             for i:=11 to 20 do 
                begin 
                rectangle(200-(i-1)*5,150-(i-1)*2,
                                    400+(i-1)*5,190+(i-1)*2); 
                rectangle(200-i*5,150-i*2,400+i*5,190+i*2); 
                end;
             Readln; 
             CloseGraph; 
          end.

Ŀ
  procedure Line ( x1,y1,x2,y2 : integer );                 


     Nakresl seku z bodu [x1,y1] do bodu [x2,y2] definovanou
barvou a stylem. Nezmn AP. Chceme-li zrove s nakreslenm
seky mnit AP, musme pout dle uveden procedury LineRel,
LineTo nebo Line a pak AP pemstit pkazem MoveTo.

Ŀ
  procedure LineRel ( Dx,Dy : integer );                    


     Nakresl seku spojujc AP s bodem [APx+Dx,APy+Dy]. Posune
AP do koncovho bodu seky, tj. bodu [APx+Dx,APy+Dy].

Ŀ
  procedure LineTo ( x,y : integer );                       


     Nakresl seku spojujc AP s bodem [x,y] a pemst AP do
bodu [x,y].

     Pklad: V zadanm datovm poli D budeme mt seln hodnoty
pipraven k zobrazen (napklad kladn sla mezi 0 a 250).
Hodnoty nakreslme do grafu a spojme je sekami.

          type 
               DATA = array [1..10] of integer; 
          var 
               D : DATA;
          procedure KresliGraf ( var D:DATA; Styl, Barva:byte );
          var i:word; 
          begin 
             SetLineStyle(Styl,0,NormWidth); 
             SetColor(Barva); 
               SetWriteMode(CopyPut);
             Line(20,20,20,340);      {souadnicov osy}
             Line(10,330,630,330); 
             MoveTo(100,330-D[1]);    {umst kurzor do 1.bodu dat}
             for i:=2 to 10 do 
          LineRel(60,D[i-1]-D[i]); 
          end; 

Toto je nejjednodu tvar pkazu, meme ale pout i dal
pkazy pro kreslen seek, napklad (nahrazuje pkaz LineRel
v uvedenm cyklu):
            LineTo(20+i*60,330-D[i]);
nebo (v procedue se nemus umstit AP pkazem MoveTo, uvedeme
cel cyklus):
               for i:=1 to 9 do
                Line(20+i*60,330-D[i],20+(i+1)*60,330-D[i+1]);
Pro zajmavost si uveme jet pklad rovho histogramu, v
pedchozm cyklu bychom zadali pkaz:
                    Line(20+i*60,330,20+i*60,330-D[i+1]);
Nsleduje pklad voln a inicializace hodnot:

          begin
               ...
         D[1]:=100;D[2]:=120;D[3]:=90;D[4]:=200;D[5]:=30; 
         D[6]:=150;D[7]:=100;D[8]:=100;D[9]:=100;D[10]:=130;
               KresliGraf(D,SolidLn,White);
               ...
          end;

9.3.2. Obrazce

     V tto sti se seznmme s pkazy pro kreslen pravohlch
obrazc, mnohohelnk a vyplovnm oblast.
     Vkonn pkazy se provdj aktuln barvou psma, stylem
ar, stylem a barvou vpln, barvou pozad. U kadho pkazu
uvedeme stavov promnn, ktermi se d. Prbn budeme
pkazy ilustrovat na pkladech.

     Vkonn pkazy:

Ŀ
  procedure Rectangle ( x1,y1,x2,y2 : integer );            


     Zobraz obdlnk (obrys) barvou psma, jeho lev horn roh
m souadnice [x1,y1], prav doln roh [x2,y2]. Pro parametry
plat: 0 <= x1 < x2 <= MaxX,
       0 <= y1 < y2 <= MaxY.

Pklad: Nakreslme tverec s levm hornm bodem v [150,50],
pravm dolnm v bod [250,150]. Vimnte si, e se nezobraz
tverec, ale obdlnk, co je dsledek nestejnho pomru hori-
zontlnch a vertiklnch vzdlenost.

          ... SetLineStyle(SolidLn,0,NormWidth);
                SetColor(White);
                Rectangle(150,50,250,150); ...

Ŀ
  procedure Bar ( x1,y1,x2,y2 : integer );                  


     Nakresl se obdlnkov oblast vyplnn aktuln vpln v
barv vpln. Nezobraz se hranice oblasti - obrys obdlnku.
Me dojt k chyb -6. Pro parametry plat:
       0 <= x1 < x2 <= MaxX,
       0 <= y1 < y2 <= MaxY.

Pklad: Mjme data v poli D typu DATA (viz pklad na kreslen
seek), nakreslme histogram pomoc pkazu Bar.

          procedure Histogram(var D:DATA;styl,barva:byte); 
          var I:word; 
          begin 
             SetFillStyle(Styl,Barva); 
             SetColor(Barva); 
          Line(20,20,20,340);       {souadnicov osy}
          Line(10,330,630,330); 
          for i:=1 to 10 do 
               Bar(20+i*50,330-D[i],20+(i+1)*50,330); 
          end; 

Ŀ
  procedure Bar3D (x1,y1,x2,y2:integer;D:word;Top:boolean); 


     Procedura zobraz trojrozmrn kvdr z pravho hornho po-
hledu. 
     Pedn stna je zadan souadnicemi levho hornho bodu
[x1,y1] a pravho dolnho bodu [x2,y2]. Pro souadnice plat
stejn omezen jako v proceue Rectangle. Pedn stna se vypln
aktuln vpln v dan barv. Me dojt k chyb -6.
     Hloubku kvdru uruje parametr D, co je hodnota uveden v
bodech. Skuten hloubka (nap. H) se pepot na hodnotu v
bodech piblin podle vztahu D=round(H/4).
     Posledn parametr specifikuje tvar zobrazen, zadv se
peddefinovanmi konstantami TopOn, TopOff:

          const
               TopOn  = true;
               TopOff = false;

     Je-li skuten parametr true (tedy TopOn), zobraz se kvdr
vetn horn stny (s obrysem). Je-li false, nen horn stna
zobrazena.
     Orientan je situace znzornna na obrzku:

         TopOn                       TopOff

         D   **                           *        
           /    /                                    
 [x1,y1] **            [x1,y1] **          
                *                         *        
               /                         /         
         **                     **   D       
               [x2,y2]                     [x2,y2]

Pklad: Histogram z pedchozho pkladu nakreslme "trojroz-
mrn", tj. pouijeme pkaz Bar3D.

          procedure Histogram3D(var D:DATA;Styl,Barva:byte); 
          var i:word; 
          begin 
          SetFillStyle(Styl,Barva); 
          SetColor(Barva);
               SetWriteMode(CopyPut);
          Line(20,20,20,340); 
          Line(10,330,630,330); 
          for i:=1 to 10 do       {Hloubku zvolme 20 bod}
               BAR3D(20+i*50,330-D[i],20+(i+1)*50,330,20,TopOn); 
          end; 
          ... Histogram(D,SolidFill,White); ...


     Pro prci s body a souadnicemi bod existuje peddefinovan
typ:

          type PointType = record
                                  x,y : integer;
                       end;

Ŀ
  procedure DrawPoly ( NumPoints:word; var PolyPoints );    


     Procedura zobraz mnohohelnk v dan barv psma se speci-
fikovanm potem vrchol.
     Parametr NumPoints uruje poet vrchol o jednu zvten.
asto se pouv funkce SizeOf tak, jak je to uvedeno v p-
kladu.
     Netypovan parametr PolyPoints obsahuje souadnice vech
vrchol mnohohelnku v uspodanm poad, v nm tvo mnoho-
helnk,  souadnice se skld ze dvou slov: x-ov a y-ov
sloky. Vzhledem k tomu, e poet vrchol se zadv o jednu
vt ne je skuten poet, souadnice prvnho a poslednho
vrcholu se mus shodovat. Pokud se neshoduj, nevede to k chyb,
ale rozhodn nezobrazme dan n-helnk. Provede se toti
spojen bod o souadnicch zadanch prvn a posledn polokou
parametru NumPoints.
     Na zvr poznamenejme, e n-helnk nemus bt konvexn (viz
pklad), ale me se dokonce skldat z vce oblast spojench
jedinm bodem, jak je to vidt na nsledujcm obrzku, kde jsou
vrcholy oslovny a oznaeny hvzdikou:

                         3    4                
                        **                    
                  6                              
                  **                    
                            5                    
                  **                          
                  1     2

Pklad: Nakreslme si pravideln 8-mi helnk podle nsle-
dujcho obrzku. sla vrchol uruj poad, v jakm zadme
souadnice vrchol v pkazu. V pkladu jsme pouili pro zadn
souadnic typovanou konstantu P, vrchol slo 1 m souadnice
[40,250], vrchol 2 m [40,100], atd. a oznaili jsme je hvz-
dikou.

                4               5                  
               **     
                                
         2**3               6**7           
                                                 
                                                 
                                                 
          **8           
          1 = 9                                    

      type  Polygon = array [1..9] of PointType;  
          const P : Polygon = ((x: 40;y:250),(x: 40;y:100),
                           (x:140;y:100),(x:140;y: 50),
                                         (x:500;y: 50),(x:500;y:100),
                                         (x:600;y:100),(x:600;y:250),
                                         (x: 40;y:250)); 
          begin
      ... DrawPoly(SizeOf(P) div SizeOf(PointType),P); ...
          end;

Ekvivalentn zpis pkazu:
                DrawPoly(9,P);
Pouit procedury SetWriteMode ilustrujme tak na tomto p-
kladu, dvakrt za sebou provedeme zpis v reimu XOR a tm
obnovme pvodn obsah obrazovky.

                ...
                SetBkColor(Green);
                SetColor(White);
                ClearViewPort;
              SetWriteMode(XORPut); 
              DrawPoly(SizeOf(p) div SizeOf(PointType),P);
                Delay(2000);
              DrawPoly(SizeOf(p) div SizeOf(PointType),P);
                Delay(2000);
                ...

Ŀ
  procedure FillPoly ( NumPoints:word; var PolyPoints );    


     Tato procedura zce souvis s pedchoz. Nakresl n-helnk a
vypln jej aktulnm stylem a barvou vpln. Obrysovou ru
provede barvou psma, piem styl tto ry je uren pkazem
SetLineStyle.
     Parametry zadvaj n-helnk stejn jako v pedchoz pro-
cedue. Opt se me stt, e prvn a posledn bod (resp. jejich
souadnice) v parametru NumPoints se neshoduj. Potom se vsle-
dek neuren, protoe zvis na hodnotch souadnic v parametru
NumPoints (tj. souadnicch poslednho bodu).
     Me dojt k chyb -6. Poznamenejme, e n-helnk se me
skldat z vce oblast spojench jedinm bodem. FillPoly vypln
vechny oblasti tvoc n-helnk.
     Nastaven reimu zpisu do pamti procedurou SetWriteMode na
XOR me zpsobit neoekvan efekt - provede se XOR mezi body
tvocmi hranici n-helnku a body vpln. 
     Napklad v nsledujcm pkladu, kde pouvme ve defi-
novanou konstantu P, bude mt hranin ra pekvapiv blo-
fialovou barvu (uvdomte si , e vyplujeme "rkovanou vp-
ln"). Zkuste si:

                ...
                SetWriteMode(XORPut);
                SetFillStyle(SlashFill,Green);
                SetLineStyle(SolidLn,0,NormWidth);
                SetColor(White);
                SetBkColor(Black);
                FillPoly(SizeOf(P) div SizeOf(PointType),P); 
                ...

Ŀ
    procedure FloodFill ( x,y:integer; Border:word );         


     Procedura vypln aktulnm stylem a barvou vpln zadanou
oblast. Oblast je zadna parametry x,y, co jsou relativn
souadnice bodu lecho uvnit oblasti, kter m bt vyplnna.
Hranice, kam a bude vyplnn probhat, je oznaena parametrem
Border. Border uruje barvu vzhledem k palet.
     Vyplovn probh tak, e od bodu [x,y] se vypluje oblast,
dokud se nenaraz na hranici barvy Border. Bod [x,y] me leet
uvnit uzaven oblasti, pak se vypln vnitek oblasti; le-li
[x,y] vn oblasti, vypln se okol dan oblasti. M-li bod [x,y]
barvu stejnou jako Border, nic se neprovede.
     Me dojt k chyb -7.

     Poznamenejme, e proveden DrawPoly a FloodFill nemus bt
ani pi sprvn zvolench parametrech ekvivalentn s provedenm
pslun FillPoly, nebo ta nebere zetel na ppadn hranice
uvnit mnohohelnka a tak vypln vechny sti vznikl k-
enm ar.

Pklad: Obrazovku rozdlme diagonlou a oblast nad diagonlou
vyplnme vpln typu BkSlashFill.

                ...
                ClearViewPort;
                SetFillStyle(BkSlashFill,Green);
                SetColor(White);
                Line(0,0,GetMaxX,GetMaxY);
                FloodFill(10,0,White);
                ...

9.3.3. Kivky

     Dosud probran vkonn pkazy rozme o pkazy pro zn-
zornn krunic, kruhovch oblouk, vse kruhu, elips a vse
elips.
     Upozornme na fakt, e u pkaz vztahujcch se ke krunici
a kruhu, se automaticky provd korekce horizontlnch a verti-
klnch vzdlenost.
     Kivky se kresl danm stylem ry a barvou psma. U nkte-
rch pkaz se tak pouv aktuln styl a barva vpln.
Souadnice bod jsou relativn vzhledem k oknu podobn jako
ostatn vkonn pkazy.
     Pklady budeme opt prbn vkldat k pkazm.
     K dispozici mme peddefinovan typ:

          type
               ArcCoordsType = record
                    x,y           : integer;
                    Xstart,Ystart : integer;
                    Xend,Yend     : integer;
               end;

     Vkonn pkazy:

Ŀ
  procedure Arc (x,y:integer;StAngle,EndAngle,Radius:word); 


     Procedura nakresl kruhov oblouk se stedem v bod [x,y],
polomrem Radius, potenm hlem StAngle a koncovm hlem
EndAngle.
     hly se zadvaj ve stupnch od 0 do 360. Pedstavme-li si
soustavu souadnic, pak hel se zobrazuje proti smru hodinovch
ruiek, nulov hel le na ose x, hel 90 stup na ose y,
atd. a k ose x, kde hel 0=360. Pekro-li nkter hodnota
skutenho parametru velikost 360, bere se tato hodnota modulo
360. Ppustn hodnoty skutench parametr jsou napklad
StAngle=90, EndAngle=70. Zobraz se oblouk odpovdajc hlu od
90 stup a k 0 a od 0 do 70 stup. Cel kruh lze namalovat
jko oblouk od 0 do 360 stup.
Pklad: Zobrazme oblouk pro prav hel ve stedu obrazovky a s
polomrem 50.

                ...
                SetLineStyle(SolidLn,0,NormWidth);
                SetColor(Green);
                Arc(GetMaxX div 2,GetMaxY div 2,0,90,50);
                ...

Ŀ
  procedure PieSlice (x,y:integer;StAngle,EndAngle,R:word); 


     Procedura pracuje obdobn jako pedchoz, ale zobrazuje
kruhovou vse msto oblouku. Vse vypln aktulnm stylem a
barvou vpln.
     Parametry x,y uruj souadnice stedu, R je polomr, StAngle
a EndAngle uruj poten a koncov hel.
     Pi zpisu v reimu CopyPut je vse lemovna obrysovou
arou, pi zpisu pomoc XORPut obrysov ra chyb (obrysov
hel je vak zobrazovn).
     Me dojt ke grafick chyb -6.
     Budeme.li chtt namalovat kruh, lze to realizovat v mdu
XORPut namalovnm vsee v hlu 0 a 360.

Pklad: Mjme pole obsahujc ti hodnoty (pro jednoduchost
pedpokldejme, e hodnoty jsou u upraveny podle procentulnho
vyjden mezi 0 a 100), tyto hodnoty si zobrazme jako kol-
ov graf rozdlnmi styly vpln se stedem uprosted obrazovky
a polomrem 70.

           var 
                D   : array [1..3] of word;
                i,x : byte;
           ...
           D[1]:=30;D[2]:=10;D[3]:=60;
           for i:=1 to 3 do
                begin
                SetFillStyle(i+5,i);
                PieSlice(GetMaxX div 2,GetMaxY div 2,
                               x,x+round(D[i]*3.6),70);
                x:=x+round(D[i]*3.6);
                end;
           ...

     Poznamenejme, e pi reimu zpisu odpovdajcmu CopyPut,
budou jednotliv vsee oddleny arami pslunho stylu.
Budeme-li v reimu XORPut, vsee oddleny nebudou, protoe se
kad vse vlastn zape 2 krt, m se smae (a tedy obry-
sov ra nebude namalovna).

Ŀ
  procedure Circle ( x,y:integer; Radius:word );            


     Tento pkaz zobraz krunici se stedem v bod [x,y] a
polomrem Radius. Zobrazen se provede barvou psma a aktulnm
stylem ry. Je tedy ekvivalentn pkazu Arc(x,y,0,360,Radius).
Pklad: Pedchoz pklad meme jet vylepit tm, e po
nakreslen vse doplnme za cyklus pkaz pro nakreslen
krunice, protoe vsee nemaj obrysov oblouk  (v reimu
XORPut). Tvar pkazu:

           Circle(GetMaxX div 2,GetMaxY div 2,70);

     Nsleduj ti pkazy pro prci s elipsami. Zdraznme, e na
rozdl od krunic se u elips neprovd vyrovnn pomru hori-
zontlnch a vertiklnch vzdlenost.

Ŀ
  procedure Ellipse ( x,y:integer; StA,EndA,XR,YR:word );   


     Procedura nakresl elipsu, resp. st elipsy se stedem v
bod [x,y], dlkou poloos XR, YR. Tato standardn procedura
zobrazuje elipsu s poloosami rovnobnmi s osou X a Y.
     Parametry x,y uruj souadnice stedu, XR velikost poloosy
rovnobn s osou X, analogicky YR. Parametry StA, EndA uruj
hel, pro kter se zobraz eliptick oblouk. hly se opt zad-
vaj ve stupnch, hodnoty by se mly pohybovat v rozsahu 0 a
360 stup. Oblouk se vytv ve smru proti hodinovm ruikm,
nulov hodnota odpovd ose X, prav hel ose Y, atd.
     Uv se aktuln barva psma a styl ar. Neprovd se kore-
kce vertiklnch a horizontlnch vzdlenost. Korekci lze 
provst v rmci zadn velikosti poloos (viz pklad).

Pklad: Nakreslme nkolik elips do sebe tak, aby se postupn
zmnil pomr hlavn a vedlej poloosy (zkuste si):

          var 
             stredX,stredY,i : integer; 
          begin 
               ...
             stredX:=GetMaxX div 2; 
             stredY:=GetMaxY div 2; 
               for i:=1 to 10 do 
                    Ellipse(stredX,stredY,0,360,250-10*i,50+10*i); 
               ...
          end;

Ŀ
  procedure FillEllipse ( x,y:integer; XR,YR:word );        


     Pkaz zobraz elipsu a vypln ji aktulnm stylem vpln
barvou vpln.
     Parametry x, y uruj souadnice stedu elipsy, XR a YR
odpovdaj poloosm rovnobnmi s osami X a Y.

Ŀ
  procedure Sector ( x,y:integer; StA,EndA,XR,YR:word );    


     Pkaz zobraz eliptick sektor (vse elipsy) uren po-
tenm a koncovm hlem, stedem elipsy a poloosami. Sektor
vypln aktulnm stylem a barvou vpln. Je to obdoba pkazu
PieSlice pro elipsy.
     Parametry x,y obsahuj souadnice stedu elipsy. StA,resp.
EndA jsou poten, resp. koncov hel eliptickho sektoru,
zadvaj se ve stupnch, plat pro n konvence vyloen u p-
kaz Ellipse a Arc. Parametry XR, YR jsou vyhrazeny pro poloosy,
XR je rovnobn s osou X, YR s osou Y.
     Procedura zobrazuje vsee stejnm zpsobem jako PieSlice
vzhledem k reimu, kter se nastavuje pomoc SetWriteMode.
     Pi vyplovn me dojt k chyb -6.

Ŀ
  procedure GetArcCoords ( var ArcCoords : ArcCoordsType ); 


     Procedura vrac v parametru ArcCoords informace o poslednm
pouit nkterho z pkaz v tomto odstavci. Parametr ArcCoords
je peddefinovanho typu ArcCoordsType (viz potek odstavce).
     V polokch x,y jsou vrceny souadnice stedu kivky, po-
loky Xstart, Ystart, resp. Xend, Yend obsahuj poten, resp.
koncov bod kivky.
     Byla-li naposled volna procedura Circle nebo FillEllipse, je
poten i koncov bod stejn a odpovdaj hlu 0. Nebyla-li
ped volnm tto procedury pouita dn z pedchozch pro-
cedur, k chyb nedojde, ale hodnota ArcCoords je nedefinovna
(obvykle nuly).
     Tato procedura se obvykle pouv pro napojovn ar na
oblouky.

Pklad pouit pedchozch procedur: Ti uveden procedury
shrneme v jednoduchm pkladu, kde vyplnme elipsu zadanou
vpln, pak zmnme vpl poloviny elipsy.

          var
               ArcCoords : ArcCoordsType;
          begin
               ...
               StredX:=GetMaxX div 2;
               StredY:=GetMaxY div 2;
               Ellipse(StredX,StredY,0,360,150,150);
               SetFillStyle(CloseDotFill,LightBlue);
               FillEllipse(stredX,stredY,150,150);  {vyplnn elipsy}
               SetFillStyle(HatchFill,white); 
               Sector(stredX,stredY,0,180,150,150); {vpl poloviny}
             GetArcCoords(ArcCoords); 
               { Nyn m promnn ArcCoords hodnotu:
          (319,174,469,174,169,174), co po ad odpovd souad-
         nicm stedu, souadnicm potenho a koncovho
         bodu.}
               ...
          end;

9.3.4. Text

     V odstavci 9.2.4 jsme se podrobn seznmili s nastavenm
stylu a umstn psma. Pkaz SetTextStyle uruje styl, ums-
tn a velikost psma. Pkaz SetTextJustify specifikuje hori-
zontln a vertikln zarovnn (podrobn viz 9.2.4). Pokud
nebyly tyto pkazy pouity, uvauje se implicitn nastaven
parametr tak, jak bylo popsno (9.2.5).
     Pipomeme, e texty se zobrazuj v dan barv psma.

     Vkonn pkazy:

Ŀ
  procedure OutText ( TextString : string );                


     Umst etzec na aktuln pozici. etzec zobraz aktulnm
stylem psma (rov styl nebo pomoc bitov mapy) v dan veli-
kosti, umst na obrazovku (horizontln nebo vertikln) a
provede zarovnn podle nastaven SetTextJustify vzhledem k
aktuln pozici.
     Umst AP na konec etzce (pslunou souadnici zvt o
TextWeight(TextString)).

Ŀ
  procedure OutTextXY ( x,y:integer; TextString:string );   


     Pracuje stejn jako pedchoz procedura, umstn etzce se
vak neprovd vzhledem k aktuln pozici, ale k bodu danmu
souadnicemi x,y.
     Nem vliv na AP, vpis textu tedy AP nemn.

Pklad pouit obou procedur: Vypeme text dvojm zpsobem,
uvdomte si rozdl mezi OutText a OutTextXY z hlediska zmny
aktuln pozice.

          begin
               ...
             SetTextStyle(TriplexFont,HorizDir,5); 
               SetColor(White);
               OutTextXY(stredX,stredY,'Ahoj, '); 
               OutText('jak se vede?'); 
               ...
Porovnejte s:
               ...
               ClearDevice;
               OutText('Ahoj, ');
               OutText('jak se vede?');
               ...
          end;

9.3.5. Standardn vstupn procedury

     I v grafickm reimu meme vyuvat standardn vstupn
procedury write, writeln k zobrazen text. Dle meme uvat
dalch podprogram unity Crt pro prci s obrazovkou. Zle
ovem, jakm zpsobem standardn procedury volme a zda pou-
vme unitu Crt.
     Tento zpsob zobrazen text je vhodn pro prci s "formu-
li" v grafickm reimu, popis schmat a podobn.

     Jak u vme z osm kapitoly, existuj dva zpsoby voln -
pomoc DOSu nebo BIOSu.

     Pomoc DOSu volme standardn procedury write, writeln tak,
e pouijeme Assign pro piazen vstupnho zazen (monitor).
Potom jsou voln uskuteovna pes DOS, hodnota promnn
DirectVideo (povme-li unitu Crt) nem dn vliv na procedury
write, writeln. 
     Zkladn vlastnosti text zobrazench pomoc DOSu:
     -Barva psma je barva 8 podle palety (tj. LightGray).
     -Barva podkladu je toton s barvou podkladu v grafickm
      reimu (tato barva je nastavena procedurou SetBkColor).
      Podklad chpeme stejn jako v textovm reimu - kad znak
      se zobrazuje v obdlnkov oblasti podle typu adaptru (v
      EGA 8x14), piem tuto oblast ped zpisem explicitn
      vypln.
     -Umstn kurzoru je dan pedchozmi vstupy pomoc write,
      writeln. Kurzor se v grafickm reimu nezobrazuje, ale
      jeho pozice se uchovv.
     -Text je zobrazen ve standardnm mdu 80x25, ostatn mdy
      jsou prakticky nepouiteln.
     -Pi vpisu textu delho ne jedna dka se pokrauje na
      nsledujc dce. Dojde-li se a na konec strnky, str-
      nka roluje a voln konce dky jsou vyplovny barvou
      pozad.
     -Vstup zmnnch procedur se vdy provd na nultou strn-
      ku. Pracujete-li na jin strnce ne nult, me dojt k
      nepjemnmu efektu, protoe text se zapisuje na nultou
      strnku a na aktivn strnku se provd pouze oddkovn,
      eventuln rolovn obrazovky.
     -Okna v grafickm reimu (nastaven procedurou SetViewPort)
      nemaj vliv na vstupy procedur write a writeln.

     Voln standardnch vstupnch procedur meme uskutenit
tak prostednictvm BIOSu. Toto voln uplatnme tehdy, kdy
pouvme unitu Crt, vstupn soubor je piazen pomoc pro-
cedury AssignCrt (nebo piazen neprovedeme, pak se automaticky
pracuje se standardnm vstupnm zazenm) a promnn (urujc
zpsob pstupu do pamti) DirectVideo m hodnotu false. Impli-
citn je nastaveno DirectVideo=true. V tomto ppad se vstupy
procedur write, writeln v grafickm reimu "smyslupln nepro-
jevuj", tj. bu se nezobraz vbec nebo se zobraz nedefinovan
vsledek. Opt shrneme zkladn vlastnosti do nkolika bod:
     -Barva psma se uruje podle promnn TextAttr, kterou lze
      nastavit pomoc procedury TextColor.
     -Barva pozad je stejn jako barva pozad v grafickm
      reimu nastaven procedurou SetBkColor (ppadn voln
      TextBackGround je ignorovno).
     -Pouit konstanty Blink (nap. pkazem pro nastaven
      barvy psma TextColor(Blink+Magenta)), kter v textovm
      reimu zpsob blikn textu, m tentokrt odlin vznam.
      Pokud nen blink nastaveno, je zapisovn cel znak (nap.
      8x14 bod u EGA). Je-li nastaven blink, je proveden tent
      zpis, ale v reimu XOR. Protoe barva pozad m slo 0,
      pvodn obsah obrazovky se tak "kolem znak nezmn".
      Vlastn znaky jsou pot transformovny do barvy podle
      pvodnho obsahu obrazovky, jak to znme ze SetWriteMode.
     -Texty se opt zobrazuj v mdu 80x25. Ostatn mdy jsou
      nepouiteln, tj. voln procedury TextMode v grafickm
      reimu m nedefinovan inek.
     -Umstn kurzoru je ureno nejen pedchozmi vpisy pomoc
      write, writeln, ale tak pomoc GoToXY, apod. Kurzor se
      nezobrazuje, ale jeho pozice se uchovv.
     -Barva psma se nastavuje z aktuln palety.
     -Po naplnn dky textem se pokrauje na dal dce, pi
      vyplnn obrazovky obrazovka roluje. 
     -Velmi nepjemnou chybou v tomto reimu prce je, e
      znaky, kter se na dce dopluj (pi rolovn), se
      dopln v barv psma. V barv psma se tak vkldaj a
      maou dky (InsLine, DelLine). Mazn strnky (ClrScr),
      resp. dky (ClrEol), se provd v barv psma.
     -Nastaven oken v grafice nem vliv na vstupy procedur
      write, writeln. Naopak lze vyuvat okna znm z textovho
      reimu (Window).
     -Vstupy se vdy zobrazuj na nultou strnku. Pozor na
      situaci, kdy je aktivn jin strnka ne nult - me
      dojt k tomu, e oddkovn a rolovn se zobrazuje v
      barv psma na aktivn strnce, zatmco text je zobrazen
      na nult strnce.

9.4. Image

     Vkonn pkazy, s nimi jsme se dosud seznmili, nm po-
skytuj celou adu standardnch, nejastji uvanch grafickch
vstup. Vedle tchto standardnch operac potebujeme jet dva
typy pkaz. Jednak pkazy pro prci s jedinm bodem (pixel),
co nm umouje vytvet obrazy bod po bodu (nap. nestandardn
kivky), jednak pkazy pro operace se souvislou obdlnkovou
st obrazovky, pro tento el nazvme st obrazovky, s n
pracujeme, image.
     Existuj dva vkonn pkazy pro image - uloen image do
pamti a zobrazen image na obrazovku (resp. na prv aktivn
strnku). Prci s image ukeme v pkladu na konci tohoto
odstavce.
     Image spolu s vhodnm pouvnm strnek umouje "animovat"
obrzky.

     Podobn jako u pkaz uvajcch seek existovala monost
seku zkoprovat do videopamti nebo provst kombinaci se
stvajcm obsahem pamti (XOR), existuj dal peddefinovan
konstanty, kter slou k rznm zpsobm ukldn image do
pamti. Jsou to konstanty (pro plnost uvdme i konstanty
CopyPut a XORPut znm z 9.3.1):

          const                            {IMAGECONST}
               CopyPut = 0;
               XORPut  = 1;
               OrPut   = 2;
               AndPut  = 3;
               NotPut  = 4;

     Jak napovdaj nzvy konstant v seznamu IMAGECONST, kad
konstanta odpovd nkter logick operaci. Uit konstant si
vysvtlme u vkonnch pkaz.

     Vkonn pkazy:

Ŀ
  procedure PutPixel ( x,y:integer; Pixel:word );           


     Pkaz zobraz bod se souadnicemi x,y barvou (vzhledem k
palet), kter je urena parametrem Pixel.
     Uv se pi kreslen obrzk bod po bodu.

Ŀ
  function GetPixel ( x,y:integer ) : word;                 


     Vsledkem funkce je barva (vzhledem k palet) bodu o sou-
adnicch x,y.

Pklad: Bod po bodu zakreslme sloitj kivku (jde o kar-
dioidu, jej parametrick vzorec je nap. v [AM]). Nejprve
musme mt proceduru, jejm vsledkem je bod kivky s para-
metrem t. Tyto body zobrazovan volnm na procedury v cyklu
vykresl kivku.

          var 
               x,y   : word; 
               pomer : real; 

          procedure Kardioida (s1,s2,zvets,barva:word; 
                           pomer,r:real);
{ [s1,s2] = sted kivky
   zvets  = zvten obrzku
   barva  = barva, kterou se kivka vykresl
   pomer  = korekn pomr horiz. a vert. vzdlenost
   r      = jedin parametr kivky}
               var 
                    i,x,y : integer; 
 
               procedure KardPixel (t:word; var x,y:integer); 
               {vpoet souadnic x,y bodu kivky podle parametru t}
                    var 
                         px,py,pom : real; 
                    begin 
                         pom:=t*pi/180; 
                         px:=r*(2*cos(pom)-cos(2*pom)); 
                         py:=r*(2*sin(pom)-sin(2*pom)); 
                         x:=round(zvets*px); 
                         y:=round(zvets*pomer*py); 
                    end;  {of KardPixel} 
 
               begin 
                    {kivka se zobrazuje po jednotlivch bodech}
                    {vykresluje se "zrove" ve dvou smrech}
                    for i:=0 to 360 do 
                         begin 
                       KardPixel(i,x,y); 
                       PutPixel(s1+x,s2+y,barva); 
                       PutPixel(s1-x,s2-y,barva); 
                       end; 
               end;  {of Kardioida} 

begin ... {inicializovan grafika}
     GetAspectRatio(x,y);
     pomer:=x/y;
     Kardioida(300,100,50,15,pomer,0.5); 
     ...
end;

Ŀ
  function ImageSize ( x1,y1,x2,y2:integer );               


     Vsledkem je velikost pamti (v bytech) potebn k uloen
souvisl obdlnkov oblasti zadan levm hornm bodem [x1,y1] a
pravm dolnm [x2,y2]. Tato funkce se pouv pi voln pro-
cedury GetImage.
     Peshne-li velikost image hodnotu 64KB, vrt se nula a
dojde k chyb -11.
     Se zpsobem uloen image a vzorcem pro vpoet velikosti u
videoadaptr CGA, EGA se seznmme v pkladu na konci ods-
tavce.

Ŀ
  procedure GetImage ( x1,y1,x2,y2:integer; var BitMap );   


     Ulo do pamti souvislou obdlnkovou oblast obrazovky
zadanou body [x1,y1] a [x2,y2], tj. levm hornm a pravm dolnm
bodem obdlnkovho image. Data se ulo do netypovanho para-
metru BitMap, tedy na msto v pamti, kde zan BitMap.
     Obvykle se jako parametr BitMap uv dynamick promnn.
     Velikost parametru BitMap je nejlep urit funkc ImageSize
nebo pro nkter adaptry podle dle uvedenho vzorce (viz
pklad uloen image v rznch adaptrech). Tato velikost se
pouv pro alokovn msta v pamti, kter potebuje skuten
parametr pi voln procedury. 
     Zpsob prce s image je dobe vidt v nsledujcm pkladu,
kde pomoc image doshneme jednoduch animace. Za tmto p-
kladem je ukzka uloen image v nejastji uvanch adapt-
rech.

Ŀ
  procedure PutImage (x,y:integer; var BitMap;BitBlt:word); 


     Na obrazovku je zobrazen image uloen v netypovanm para-
metru BitMap (uloen hodnoty se chpou ve formtu uloen
pkazem GetImage). Image se zobraz tak, aby jeho lev horn
bod leel v bod [x,y].
     Zpsob zobrazen uruje parametr BitBlt. Zpsob zobrazen se
obvykle zadv konstantou ze seznamu IMAGECONST, piem jed-
notliv konstanty uruj, zda se data na obrazovku zkopruj
nebo kter logick operace se s daty provede. Ppustn logick
operace jsou xor, or, and, not.
     Vimnme si jednotlivch md:
-  CopyPut = Image je penesen na dan msto na obrazovce.
   Pouv se pro zobrazovn tvercovch obrazc (nap. ikony
   pro prci s my, kter jsou pedem vytvoeny, a ji mimo
   program a uloeny v souboru nebo v programu na druh strn-
   ce), pro "save" a "restore" st grafick obrazovky, kop-
   rovn obrzk atp.
-  NotPut = Zobrazuje tvercov obrzek v inverznch barvch,
   piem inverzn pry jsou tyto:
               jasn barva - tmav barva
               ern       - bl
               modr       - hnd
               zelen      - fialov
               erven     - tyrkysov
   Pouv se obvykle u jednobarevnch ikon k jejich zvraznn
   (jsou-li nap. vybrny my jako aktivn poloka ikonovho
   menu).
-  XORPut = Zobrazuje tvercov obrzek v transformovanch
   barvch. Transformace barev je permutac zobrazen barvy
   podle barvy podkladu. Barvy spolu souvis podle nsledujc
   tabulky (kdy barev odpovdaj anglickm ekvivalentm, kter
   se pouily pi deklaraci konstant):

   ͻ
      X O R   000  001  010  011  100  101  110  111  
       Put     N    B    G    Gr   R    C    M    W   
   ͹
     000  N   N    B    G    C    R    M    Br   W   
     001  B   B    N    C    G    M    R    W    Br  
     010  G   G    C    N    B    Br   W    R    M   
     011  C   C    G    B    N    W    Br   M    R   
     100  R   R    M    Br   W    N    B    G    C   
     101  M   M    R    W    Br   B    N    C    G   
     110  Br  Br   W    R    M    G    C    N    B   
     111  W   W    Br   M    R    C    G    B    N   
   ͼ

   Vimnme si, e zpis dvakrt stejnou barvou na tot msto
   vrt pvodn barvu (jednoznan) a e pro kadou barvu
   pozad a kadou zamlenou barvu existuje takov barva psma,
   jej zpis na uvedenou barvu pozad je transformovn na
   poadovanou barvu. 
     Tchto vlastnost jsme u vyuvali pi animaci rovch
   obrazc (nap. expanze rmeku) a pi zpisu pomoc BIOSu v
   reimu blink, kdy je tak mono koment zapsat i do vce-
   barevn oblasti monitoru. Ve spojen s image se obvykle
   vyuv pro animaci dvoubarevnch obraz.
-  AndPut a OrPut = Oproti pedchozm variantm nezachovvaj
   rozumn ani pozad ani vlastn image a lze je pout nap.
   pro tvorbu efektnch bizardnch obrazc (jejich kdovn lze
   zskat provedenm pslunch operac na bitov mapy kon-
   vertovan dvojice barev).

Pklad: Zkusme animaci pomoc GetImage a PutImage. Pklad si
vyzkouejte v rznch obmnch. Zejmna si musme uvdomit, e
pesuny pomoc image nejsou pli rychl.

var 
   stredX,stredY,i : integer; 
   p               : pointer; 
 
begin 
     ...
   stredX:=GetMaxX div 2; 
   stredY:=GetMaxY div 2; 
   SetWriteMode(XorPut); 
   SetColor(black); 
   SetFillStyle(SolidFill,magenta); 
   PieSlice(stredX,stredY,0,360,20); 
          { Penen obraz.}
   GetMem(p,ImageSize(stredX-25,stredY-25,stredX+25,stredY+25));
          { Alokovn potebnho msta v pamti.}
   GetImage(stredX-25,stredY-25,stredX+25,stredY+25,p^); 
          { Uloen image do pamti.}
   SetFillStyle(SolidFill,black); 
   PieSlice(stredX,stredY,0,360,20); 
          { Smazn penenho obrazu.}
   stredY:=320; 
   stredX:=0; 
   for i:=1 to 600 div 3 do 
      PutImage(stredX+3*i,stredY-round(300*sin(3*i/600*3.14)),
                         p^,CopyPut); 
end;

     Zpsob uloen image pro nejastji uvan adaptry

     Image neboli obdlnkov souvisl oblast na obrazovce uren
levm hornm bodem a pravm dolnm bodem se ukld do pamti
adaptr CGA (barevn i monochromatick reim), EGA podle nsle-
dujcch pravidel (doporuujeme sledovat pravidla zrove na
piloenm obrzku):
-  Body se ukldaj po "dcch" v rmci zadan oblasti.
-  V rmci jednoho bytu se body ukldaj "pozptku".
-  Uloen image zan tymi byty, v nich je velikost image
   uloen takto: ve dvou bytech poet sloupc mn jedna, v
   nsledujcch dvou bytech poet dek mn jedna.
-  Uloen image je ukoneno dvma byty, kter jsou rezervovny.
-  U adaptru CGA v monochromatickm reimu se image skuten
   ukld jako bitov mapa podle tchto pravidel.
-  U adaptru CGA v barevnm reimu je kad bod uloen pomoc
   dvou bit (viz obrzek).
-  U adaptru EGA se jeden bod ukld pomoc ty bit, kter
   odpovdaj intenzit a barv - erven, modr, zelen.
-  Uloen u ostatnch adaptr je analogick.

     Na obrzku mme image s deseti sloupci a tymi dky, barvy
jsme na obrzku znzornili seln.

         
                       X=10                      
               Ŀ           
                1 1 1 1 2 3 3 3 3 3            
           Y=4  1 1 1 2 2 2 3 3 3 3            
                1 1 2 2 2 2 2 3 3 3            
                1 2 2 2 2 2 2 2 3 3            
                          
                                                 

     Nyn si graficky znzornme uloen image v pamti, piem *
oznauje nevyuit bit:

        Ŀ
            $09         0                          X-1
        Ĵ
            $03         0                          Y-1
        Ŀ
        01 01 01 0111 11 11 10** ** 11 11         1.dek
        Ĵ
        10 01 01 0111 11 10 10** ** 11 11         2.dek
        Ĵ
        10 10 01 0111 10 10 10** ** 11 11         3.dek
        Ĵ
        10 10 10 0110 10 10 10** ** 11 11         4.dek
        
          rezerv.    rezerv.                       
        


     Vzorce pro vpoet velikosti pamti uloen image rozmr
X*Y:

      ͻ
        CGA (mono)        4+((1*X+7) div 8)*Y+2  
      Ķ
        CGA (color)       4+((2*X+7) div 8)*Y+2  
      Ķ
        EGA               4+((4*X+7) div 8)*Y+2  
      ͼ


9.5. Dal funkce 

     U jsme se seznmili s vtinou podprogram unity Graph a
dokeme si poradit s adou aplikac, kde vyuijeme grafiku.
Nyn se jet zmnme o nkterch specilnch podprogramech
(SetGraphBufSize, RegisterBGIdriver, RegisterBGIfont, Install-
UserDriver, InstallUserFont), prci s dynamicky alokovanou
pamt a na zvr si orientan uvedeme zkladn lenn soubor
s rozenm .CHR.

     Prce s vyrovnvac pamt

     Nejprve se vrtme k procedurm FloodFill, FillPoly a dalm,
kde se pracovalo s vyplovnm oblast. Informace o vyplovan
oblasti je uloena ve vnitn vyrovnvac pamti. Velikost
bufferu meme zmnit nsledujc procedurou.

Ŀ
  procedure SetGraphBufSize ( BufSize : word );             


     Tato procedura zvtuje velikost vyrovnvac pamti pro
vyplovn oblast. Implicitn velikost jsou 4 KB, tuto velikost
tedy nememe zmenit. Implicitn velikost 4KB odpovd (dle
[BORLAND 88]) oblasti dan 650-ti hranami. Je-li vstupnm para-
metrem men hodnota ne 4KB (=4096B), ignoruje se.
     Voln tto procedury mus bt vdy ped InitGraph, jinak se
ignoruje.
     Ve vtin bnch aplikac vystame s implicitn velikost
bufferu. Vyskytnou-li se pi pouvn procedur FloodFill nebo
FillPoly neoekvan vsledky (pracujete s velkou strukturou a
neprovede se vyplnn, apod.), zkuste zvtit velikost vyrov-
nvac pamti.
Pklad: Budeme pracovat s mnohohelnkem, kter m 700 hran.
Abychom mohli pout proceduru FillPoly, musme zvtit buffer.

          program GrafickyBuffer;
          uses 
               Graph; 
          var 
               Polygon : array [1..700] of PointType; 
               GD,GM,i : Integer; 
          begin 
               { Zvten velikosti bufferu na dvojnsobek. }
               SetGraphBufSize(8*1024);
               { Inicializace vrchol polygonu. }
               for i:=1 to 350 do 
                    begin 
                    Polygon[2*i].x:=i; 
                    Polygon[2*i].y:=100; 
                    polygon[2*i-1].x:=300; 
                    Polygon[2*i-1].y:=200; 
                    end; 
               GD:=Detect; 
               InitGraph(GD, GM, ''); 
               if GraphResult <> grOk then Halt; 
               { Vyplnn polygonu implicitnm stylem vpln. }
               FillPoly(SizeOf(Polygon) div 
              SizeOf(PointType),Polygon); 
               ReadLn; 
               CloseGraph; 
          end.

     Zaveden ovladae nebo fontu do pamti

     Dal dv procedury umouj zrychlit prci s ovladai a se
soubory, v nich jsou uloeny rov styly psma.

Ŀ
  function RegisterBGIfont ( font:pointer ) : integer;      


     Funkce slou k uloen rovho stylu psma do pamti
(HEAPu).
     Jejm parametrem je ukazatel na msto v pamti, kam byl
uloen pslun font (tj. soubor s rozenm .CHR), jak plyne
z pkladu.
     Funkce ulo tento ukazatel do sv intern tabulky, kter je
pouvna procedurou SetTextStyle. Pi nastaven stylu psma
(procedurou SetTextStyle) na uloen font nen tento font za-
vdn z disku, ale z pamti. Vsledkem funkce je intern slo
pslunho fontu podle intern tabulky font (1 a 4 sla
standardnch font pidlovan funkc InstallUserFont, viz
dle).
     Dolo-li k chyb, je vsledkem zporn slo.

     Poznamenejme jet, e soubor obsahujc rov styl psma
me bt peveden programem BINOBJ na .OBJ soubor a pot pi-
pojen ("pilinkovn") k vslednmu .EXE souboru. Psmo tvoen
bitovou mapou je soust unity Graph a je tedy vdy soust
peloenho programu.

Popsan vlastnosti si objasnme na pkladu: Vyzkoume si
zaveden gotickho stylu psma do pamti a porovnme rychlost
vpisu textu s jinm rovm stylem psma.

          program FONTY; 
          uses Graph; 
          var 
               GD,GM : integer; 
               Font  : file; 
               RefF  : pointer; 
          begin 
               { Do pamti zavedeme gotick styl psma. }
               Assign(font,'GOTHIC.CHR'); 
               Reset(Font,1); 
               GetMem(RefF,FileSize(Font)); 
               {Alokovali jsme dostatek msta pro font gotickho
            stylu psma. }
               BlockRead(Font,RefF^,FileSize(Font)); 
               {Zavedli jsme do pamti na msto dan ukazatelem RefF
            font GOTHIC.CHR. }
               if RegisterBGIFont(RefF)<0 then 
                    begin 
                    write('CHYBA'); 
                    halt; 
                    end; 
               GD:=CGA; 
               GM:=CGAC0; 
               InitGraph(GD,GM,''); 
               SetTextStyle(TriplexFont,0,4); 
               MoveTo(10,10); 
               OutText('Ahoj'); 
               readln; 
               SetTextStyle(GothicFont,0,4); 
               { Nezavdl se ze souboru! }
               OutText('TOME'); 
               readln; 
               SetTextStyle(TriplexFont,0,4); 
               { Trv dle ne pedchoz, zavd se ze souboru. }
               OutText('Ahoj'); 
               readln; 
               CloseGraph; 
          end.

Ŀ
  function RegisterBGIdriver ( driver:pointer ) : integer;  


     Tato funkce pracuje analogicky jako ve uveden funkce,
tentokrt ovem zrychluje prci s ovladai. Umouje zavst do
pamti (HEAPu) ovlada, co opt zrychluje prci pi zavdn
grafiky (InitGraph).
     Vsledkem je intern slo ovladae, je-li slo zporn,
dolo k chyb. Me dojt k chyb -4, je-li tvar ovladae (sou-
boru s rozenm .BGI) nekorektn.
     Stejn jako v pedchozm meme pevst soubory typu .BGI
(ovladae) na .OBJ tvar a pipojit ("pilinkovat") je k pe-
loenmu programu ve tvaru .EXE souboru.

Pklad: V nsledujcm pkladu si do pamti zavedeme ovlada
EGAVGA.BGI a porovnme si rychlost prce pi zavdn CGA.BGI
ovladae z disku a ovladae EGAVGA.BGI z pamti.

          program DRIVERY; 
          uses Graph; 
          var 
             GD,GM   : integer; 
             driver  : file; 
             RefF    : pointer; 
          begin 
             { Zaveden do pamti. }
               Assign(driver,'EGAVGA.BGI'); 
             Reset(driver,1); 
             GetMem(RefF,FileSize(driver)); 
             BlockRead(driver,RefF^,FileSize(driver)); 
             if RegisterBGIDriver(RefF)<0 then 
                begin 
                    write('CHYBA'); 
             halt; 
                  end; 
               GD:=CGA; 
             GM:=CGAC0; 
             InitGraph(GD,GM,''); 
               { Pouijeme ovlada na disku. }
             OutText('Ahoj TOME'); 
             readln; 
             CloseGraph; 
             GD:=EGA; 
             GM:=EGAHi; 
             InitGraph(GD,GM,''); 
               { Pouijeme ovlada v pamti. }
             OutText('Uz jsem tu zase!'); 
             readln; 
             CloseGraph; 
          end.

     Instalace novho ovladae nebo fontu

Ŀ
  function InstallUserDriver (N:string;DPtr:pointer):word;  


     Slou k instalaci novch ovlada do intern tabulky ovla-
da. Pouit tto funkce je velmi nestandardn (je nap. teba
vytvoit vlastn ovlada, ...) a tak zjemce odkeme na jej
popis v [BORLAND 88].

Ŀ
  function InstallUserFont (FontFileName:string ):integer;  


     Tato funkce se pouv k instalaci novch font, tj. soubor
rovch styl psma. Parametrem je jmno fontu, kter mus bt
uloeno v hlavice pslunho fontu, pim font mus bt
uloen v adresi uvedenm v pkazu InitGraph a mus bt uloen
ve stejnojmennm souboru s rozenm .CHR. Funkce Install-
UserFont pouze ulo jmno a slo do vnitn tabulky, vlastn
zaveden (kontrola existence a formtu) je provedeno a v p-
kazu SetTextStyle.
     Vsledkem funkce je slo novho rovho stylu psma, toto
slo se pouv v procedue SetTextStyle k volb stylu psma.
Je-li intern tabulka styl psma pln, vsledkem funkce je 0.

Pklad: Prv popsan funkce slou k instalaci novho stylu
psma. Abychom si ji mohli vyzkouet, zmnme troku soubor
GOTH.CHR. Pejmenujeme jej na TEST.CHR a v hlavice souboru
zapeme nzev souboru - msto GOTH zapeme od bytu 92 etzec
TEST. Uvdme pouze kostru programu bez oeten ppadnch
chyb.

          program InstalaceFontu; 
          uses Graph; 
          var 
             GD,GM    : integer; 
             TestFont : integer; 
          begin 
               { Instalujeme "nov" font.}
             TestFont:=InstallUserFont('TEST'); 
             GD:=detect; 
             InitGraph(GD,GM,''); 
             SetTextStyle(TestFont,0,6); 
             OutText('AHOJ !!!'); 
               { Vpis se provedl stylem GOTH.}
             readln; 
          end.

     Prce s pamt

     Soust unity Graph jsou tak dv promnn typu pointer:

          var
               GraphGetMemPtr  : pointer;
               GraphFreeMemPtr : pointer;

tyto promnn implicitn odkazuj na standardn procedury Graph-
GetMem a GraphFreeMem, kter alokuj a uvoluj pam v HEAPu.
Do tto pamti jsou zavdny ovladae, soubory styl psma a je
zde alokovn buffer grafiky (viz SetGraphBufSize). 
     Procedury odpovdajc tmto promnnm jsou volny nktermi
procedurami unity Graph (CloseGraph, InitGraph, RegisterBGI-
driver, RegisterBGIfont, SetTextStyle). Tyto procedury mus mt
tento tvar:

     procedure GraphGetMem  ( var P:pointer; Size:word );
     procedure GraphFreeMem ( var P:pointer; Size:word );

a dle:
-  Ob mus bt volny FAR.
-  GraphGetMem mus alokovat v HEAPu msto velikosti Size a jeho
   adresu vrtit v parametru P.
-  GraphFreeMem uvoln pam v HEAPu od adresy P velikosti Size,
   pokud P nen rovno nil.

     Promnn GraphGetMemPtr a GraphFreeMemPtr se mohou vyut pro
instalaci vlastnch procedur pro alokaci (resp. uvolnn) pa-
mti v HEAPu.
     Uivatelsk procedura GraphGetMem me bt vyuvna pro
vlastn obsluhu chyby pi nedostatku pamti v HEAPu. Pokud chybu
neoetme (P=nil, jak je tomu u standardn procedury), volajc
procedura adresu P otestuje a v ppad chyby nastav Graph-
Result na pslun kd, pi dalm voln grafickch pkaz
dojde chyb (viz 9.1.3).
     Neznme dn rozumn pouit vlastn instalovan procedury
GraphFreeMem a domnvme se, e pointer GraphFreeMemPtr je
uveden pouze z dvod symetrie.
Pklad: Vimnte si direktiv urujcch velikost pamti, zkuste
program pro jin nastaven direktivy {$M ...}.

          {$M 16000,0,5000} 
          program UserHeapManagement; 
          uses Graph; 
          var 
             GD,GM : integer; 
          {$F+} 
          procedure MyGetMem ( var P:pointer; Size:word ); 
          begin 
             if MaxAvail<Size then 
                {viz HeapError a odstavec 6.1.4} 
                write('Neni dostatek pameti pro zavedeni grafiky!')
             else 
                GetMem(P,Size); 
          end; 
           
          procedure MyFreeMem ( var P:pointer; Size:word ); 
          begin 
             if P <> nil then 
                begin 
                FreeMem(P,Size); 
                P:=nil; 
                end; 
          end; 
          {$F-} 
 
          begin 
             GraphGetMemPtr:=@MyGetMem; 
             GraphFreeMemPtr:=@MyFreeMem; 
             GD:=detect; 
          InitGraph(GD,GM,''); 
          OutText('A H O J !!!'); 
             Readln; 
             CloseGraph; 
          end. 

     Nznak struktury soubor styl psma (font)

     Soubory typu .CHR obsahuj rov styly psma (nkdy jsou
tak nazvny vektorov styly psma). Tyto styly jsou vytvoeny
z vektor, kter udvaj umstn a tvar ar tvocch zobra-
zovan znak. Obvykle se nezobrazuj vechny znaky ASCII tabulky,
ale pouze znaky s ordinalitou 33 a 127.
     Na tomto mst si pouze nazname tvar .CHR souboru, co je
soubor obsahujc dan styl psma. Nejprve je v souboru hlavika
obsahujc nzev souboru (resp. nzev stylu psma), asov daje
o distribuovanm souboru, jmno firmy. V zvru hlaviky souboru
(od 92.bytu) je nzev fontu pouvan procedurou SetTextStyle
(resp. InstallUserFont). Tto vlastnosti jsme vyuili ve ve
uvedenm pkladu. Nsleduj globln daje o fontu, dle jsou
uvedeny odkazy, kde jsou v souboru informace o jednotlivch
zobrazovanch znacch ASCCII tabulky, pot nsleduj vektory
urujc tvar znaku.

9.6. Unita Graph

     Konstanty, typy, promnn a standardn grafick podprogramy
uvdme souhrnn ve tvaru interface unity Graph. O vech uve-
dench pojmech jsme u mluvili v pedchozch odstavcch, proto
jsou popsny pouze ilustrujcmi komenti.

unit Graph; 
 
interface 
 
const 
  { Kdy chyb, kter vrac funkce GraphResult: } 
  grOk               =   0; 
  grNoInitGraph      =  -1; 
  grNotDetected      =  -2; 
  grFileNotFound     =  -3; 
  grInvalidDriver    =  -4; 
  grNoLoadMem        =  -5; 
  grNoScanMem        =  -6; 
  grNoFloodMem       =  -7; 
  grFontNotFound     =  -8; 
  grNoFontMem        =  -9; 
  grInvalidMode      = -10; 
  grError            = -11; 
  grIOerror          = -12; 
  grInvalidFont      = -13; 
  grInvalidFontNum   = -14; 
 
  { Konstanty popisujc ovladae: } 
  CurrentDriver = -128; { pouv se v GetModeRange } 
  Detect        = 0;    {     "      pro detekci hardwaru} 
  CGA           = 1; 
  MCGA          = 2; 
  EGA           = 3; 
  EGA64         = 4; 
  EGAMono       = 5; 
  IBM8514       = 6; 
  HercMono      = 7; 
  ATT400        = 8; 
  VGA           = 9; 
  PC3270        = 10; 
 
  { Konstanty popisujc videomdy: } 
  CGAC0      = 0;
  CGAC1      = 1;
  CGAC2      = 2;
  CGAC3      = 3;
  CGAHi      = 4;
  MCGAC0     = 0;
  MCGAC1     = 1;
  MCGAC2     = 2;
  MCGAC3     = 3;
  MCGAMed    = 4;
  MCGAHi     = 5;
  EGALo      = 0;
  EGAHi      = 1;
  EGA64Lo    = 0;
  EGA64Hi    = 1;
  EGAMonoHi  = 3;
  HercMonoHi = 0;
  ATT400C0   = 0;
  ATT400C1   = 1;
  ATT400C2   = 2;
  ATT400C3   = 3;
  ATT400Med  = 4;
  ATT400Hi   = 5;
  VGALo      = 0;
  VGAMed     = 1;
  VGAHi      = 2;
  PC3270Hi   = 0;
  IBM8514LO  = 0;
  IBM8514HI  = 1;
 
  { Barvy pro SetPalette a SetAllPalette: } 
  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; 
 
  { Barvy pro adaptr IBM - 8514: } 
  EGABlack             = 0;
  EGABlue              = 1; 
  EGAGreen             = 2; 
  EGACyan              = 3; 
  EGARed               = 4; 
  EGAMagenta           = 5; 
  EGABrown             = 20; 
  EGALightgray         = 7; 
  EGADarkgray          = 56;
  EGALightblue         = 57; 
  EGALightgreen        = 58; 
  EGALightcyan         = 59; 
  EGALightred          = 60; 
  EGALightmagenta      = 61; 
  EGAYellow            = 62; 
  EGAWhite             = 63; 
 
  { Styly ar pro Get/SetLineStyle: } 
  SolidLn    = 0; 
  DottedLn   = 1; 
  CenterLn   = 2; 
  DashedLn   = 3; 
  UserBitLn  = 4;       { Uivatelem definovan ra } 
 
  NormWidth  = 1; 
  ThickWidth = 3; 
 
  { Styly psma pro Set/GetTextStyle: } 
  DefaultFont   = 0;    { 8x8 bitov mapa } 
  TriplexFont   = 1;    { rov styly } 
  SmallFont     = 2; 
  SansSerifFont = 3; 
  GothicFont    = 4; 
 
  HorizDir   = 0;       { horizontln umstn textu } 
  VertDir    = 1;       { vertikln umstn } 
 
  UserCharSize = 0;
 
  ClipOn  = true; 
  ClipOff = false; 
 
  TopOn  = true; 
  TopOff = false; 
 
  { Styly vpln pro Get/SetFillStyle: } 
  EmptyFill       = 0;  { vpl v barv pozad } 
  SolidFill       = 1;  { vpl barvou psma } 
  LineFill        = 2;  { --- } 
  LtSlashFill     = 3;  { /// } 
  SlashFill       = 4;  { /// silnmi arami } 
  BkSlashFill     = 5;  { \\\ silnmi arami } 
  LtBkSlashFill   = 6;  { \\\ fill } 
  HatchFill       = 7;  { vpl mkou } 
  XHatchFill      = 8;  { vpl ikmou mkou } 
  InterleaveFill  = 9;  { vpl ikmou hustou mkou } 
  WideDotFill     = 10; { dk tekovn } 
  CloseDotFill    = 11; { hust tekovn } 
  UserFill        = 12; { uivatelem definovan vpl } 
 
  { Kdy operac pro PutImage, resp. SetWriteMode: } 
  NormalPut     = 0;    { MOV }  {pro SetWriteMode }
  CopyPut       = 0;    { MOV } 
  XORPut        = 1;    { XOR } 
  OrPut         = 2;    { OR  } 
  AndPut        = 3;    { AND } 
  NotPut        = 4;    { NOT } 
 
  { Horizontln a vertikln umstn pro SetTextJustify: } 
  LeftText   = 0; 
  CenterText = 1; 
  RightText  = 2; 
 
  BottomText = 0; 
{ CenterText = 1; ji definovan ve } 
  TopText    = 2; 
 
 
const 
  MaxColors = 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; 
 
  ArcCoordsType = record 
      X, Y           : integer; 
      Xstart, Ystart : integer; 
      Xend, Yend     : integer; 
    end; 
 
 
var 
   GraphGetMemPtr  : Pointer;
   GraphFreeMemPtr : Pointer;

   function GraphErrorMsg(ErrorCode : integer) : String; 
   function GraphResult : integer; 

     procedure DetectGraph(var GraphDriver, GraphMode : integer); 
     function GetDriverName : string; 
   procedure InitGraph(var GraphDriver : integer; 
                       var GraphMode   : integer; 
                       PathToDriver    : String); 
 
     function RegisterBGIfont(Font : pointer) : integer; 
     function RegisterBGIdriver(Driver : pointer) : integer; 
     function InstallUserDriver(DriverFileName : string; 
                       AutoDetectPtr : pointer) : integer; 
     function InstallUserFont(FontFileName : string) : integer; 
     procedure SetGraphBufSize(BufSize : word); 
     function GetMaxMode : integer; 
     procedure GetModeRange(GraphDriver : integer; 
                       var LoMode,HiMode : integer); 
     function GetModeName(GraphMode : integer) : string; 
     procedure SetGraphMode(Mode : integer); 
     function GetGraphMode : integer; 
     procedure GraphDefaults; 
     procedure RestoreCrtMode; 
     procedure CloseGraph; 
 
     function  GetX : integer; 
     function  GetY : integer; 
     function  GetMaxX : integer; 
     function  GetMaxY : integer; 
 
     procedure ClearDevice; 
     procedure SetViewPort(x1, y1, x2, y2 : integer; 
                       Clip : boolean); 
     procedure GetViewSettings(var ViewPort : ViewPortType); 
     procedure ClearViewPort; 
     procedure SetVisualPage(Page : word); 
     procedure SetActivePage(Page : word); 
 
     procedure PutPixel(X, Y : integer; Pixel : word); 
     function  GetPixel(X, Y : integer) : word; 
 
     procedure SetWriteMode(WriteMode : integer); 
     procedure LineTo(X, Y : integer); 
     procedure LineRel(Dx, Dy : integer); 
     procedure MoveTo(X, Y : integer); 
     procedure MoveRel(Dx, Dy : integer); 
     procedure Line(x1, y1, x2, y2 : integer); 
     procedure GetLineSettings(var LineInfo : LineSettingsType); 
     procedure SetLineStyle(LineStyle : word; 
                       Pattern   : word; 
                       Thickness : word); 
 
     procedure Rectangle(x1, y1, x2, y2 : integer); 
     procedure Bar(x1, y1, x2, y2 : integer); 
     procedure Bar3D(x1, y1, x2, y2 : integer; Depth : word; 
                       Top : boolean); 
     procedure DrawPoly(NumPoints : word; var PolyPoints); 
     procedure FillPoly(NumPoints : word; var PolyPoints); 
     procedure GetFillSettings(var FillInfo : FillSettingsType); 
     procedure GetFillPattern(var FillPattern : FillPatternType); 
     procedure SetFillStyle(Pattern : word; Color : word); 
     procedure SetFillPattern(Pattern : FillPatternType; 
                        Color : word); 
     procedure FloodFill(X, Y : integer; Border : word); 
 
     procedure Arc(X, Y : integer; StAngle, EndAngle, 
                        Radius : word); 
     procedure GetArcCoords(var ArcCoords : ArcCoordsType); 
     procedure Circle(X, Y : integer; Radius : word); 
     procedure Ellipse(X, Y : integer; 
                        StAngle, EndAngle : word; 
                        XRadius, YRadius  : word); 
     procedure FillEllipse(X, Y : integer; 
                        XRadius, YRadius  : word); 
     procedure GetAspectRatio(var Xasp, Yasp : word); 
     procedure SetAspectRatio(Xasp, Yasp : word); 
     procedure PieSlice(X, Y : integer; 
                        StAngle, EndAngle, Radius : word); 
     procedure Sector(X, Y : Integer; 
                        StAngle, EndAngle, 
                        XRadius, YRadius : word); 
 
     procedure SetBkColor(ColorNum : word); 
     procedure SetColor(Color : word); 
     function GetBkColor : word; 
     function GetColor : word; 
     procedure SetAllPalette(var Palette); 
     procedure SetPalette(ColorNum : word; Color : shortint); 
     procedure GetPalette(var Palette : PaletteType); 
     function GetPaletteSize : integer; 
     procedure GetDefaultPalette(var Palette : PaletteType); 
     function GetMaxColor : word; 
     procedure SetRGBPalette(ColorNum, RedValue,
                        GreenValue, BlueValue : integer); 
 
     function  ImageSize(x1, y1, x2, y2 : integer) : word; 
     procedure GetImage(x1, y1, x2, y2 : integer; var BitMap); 
     procedure PutImage(X, Y : integer; var BitMap; 
                        BitBlt : word); 
 
     procedure GetTextSettings(var TextInfo : TextSettingsType); 
     procedure OutText(TextString : string); 
     procedure OutTextXY(X, Y : integer; TextString : string); 
     procedure SetTextJustify(Horiz, Vert : word); 
     procedure SetTextStyle(Font, Direction : word; 
                        CharSize : word); 
     procedure SetUserCharSize(MultX, DivX, MultY, DivY : word); 
     function  TextHeight(TextString : string) : word; 
     function  TextWidth(TextString : string) : word; 

     Otzky a cvien

  1.  Co potebujete pro prci v grafickm reimu?
  3.  Inicializujte grafiku na Vaem potai, vyzkouejte si
      rzn zpsoby inicializace (Detect, DetectGraph).
  6.  Existuje v grafice ekvivalent textovho window? Jak se
      li od textovho, jak se definuje?
  7.  Co to je vnitn barva?
  8.  Co vte o barvch (nap. pojem palety, barvy vzhledem k
      palet, ...)?
  9.  Napite proceduru demonstrujc barevn monosti Vaeho
      videoadaptru v mdu s nejlepmi barevnmi monostmi -
      zobrazujte na obrazovce vechny barvy palety a postupn
      paletu obmujte. Zmny palety komentujte.
 10.  Jak se definuje uivatelsk styl vpln?
 11.  K emu slou SetUserCharSize? Demonstrujte pouit tto
      procedury - napklad mete popsat histogram (viz pklad
      pouit Bar3D), jist vyuijete znalost o rovch sty-
      lech psma a text zformtujete pesn do danch obdln-
      kovch oblast.
 12.  Jak je rozdl mezi procedurou Rectangle a Bar? Lze pout
      jet dal standardn procedury k zobrazen obdlnku?
      Jak?
 13.  Dokete namalovat elipsu, jej poloosy nejsou rovnobn
      se souadnicovm systmem?
 14.  Zkuste vytvoit vodn (reklamn) obrazovku k Vaim pro-
      gramm, na n budete animovat njak obrazec (tvercovou
      oblast, elipsa, ...). Zkuste jednotliv akce plynule
      spojit - napite si proceduru pro vlastn mazn obrazovky
      jednm smrem (zleva doprava), pohyb image po parametricky
      zadan drze, pohyb textu, ...
 15.  Jak existuj monosti zobrazen text v grafickm reimu,
      jak se navzjem li, ve kterch situacch je pouijete?
 16.  K emu slou RegisterBGIfont, k emu InstallUserFont?
      Vyzkouejte je!
      

A. ASCII tabulka

     Pi prci s funkc READKEY a pi vpisu znak na monitor nebo
na tiskrnu se obvykle neobejdeme bez ASCII tabulky o n jsme
ji hovoili.

     V jednotlivch sloupcch jsou postupn uvedeny: slo deka-
dicky a hexadecimln, znak, jak je zobrazovn na monitoru a
jak je ten z klvesnice, znak, jak je ten z klvesnice funkc
READKEY, pokud ped tm vydala nulu a konen vznam uvedenho
kdu pro tiskrnu.

                                                            st 1.
ͻ
  slo Chr  Extended  PRN  slo Chr  Extended  PRN
Ķ
   0 00  *             NUL  32 20       Alt D       
   1 01  *                  33 21  !    Alt F       
   2 02  *     NUL          34 22  "    Alt G       
   3 03  *                  35 23  #    Alt H       
   4 04  *                  36 24  $    Alt J       
   5 05  *                  37 25  %    Alt K       
   6 06  *                  38 26  &    Alt L       
   7 07  **            BEL  39 27  '                
   8 08  **                40 28  (                
   9 09  *                  41 29  )                
  10 0A  **            LF   42 2A  *                
  11 0B  *             TAB  43 2B  +                
  12 0C  *             FF   44 2C  ,    Alt Z       
  13 0D  **            CR   45 2D  -    Alt X       
  14 0E  *             Spr  46 2E  .    Alt C       
  15 0F  *  Shift TAB  Sko  47 2F  /    Alt V       
  16 10  *    Alt Q         48 30  0    Alt B       
  17 11  *    Alt W         49 31  1    Alt N       
  18 12  *    Alt E    Eko  50 32  2    Alt M       
  19 13  *    Alt R         51 33  3                
  20 14  *    Alt T    Epr  52 34  4                
  21 15  *    Alt Y        53 35  5                
  22 16  *    Alt U         54 36  6                
  23 17  *    Alt I         55 37  7                
  24 18  *    Alt O    CAN  56 38  8                
  25 19  *    Alt P         57 39  9                
  26 1A  **            EOF  58 3A  :                
  27 1B  *             ESC  59 3B  ;      F1        
  28 1C  *                  60 3C  <      F2        
  29 1D  *                  61 3D  =      F3        
  30 1E  *    Alt A         62 3E  >      F4        
  31 1F  *    Alt S         63 3F  ?      F5        
ͼ

     Hodnoty uveden ve sloupci Chr jsou zobraziteln na monitoru
s vjimkou tch, kter jsou oznaeny dvma hvzdikami, tyto
znaky se projev jako: 7 = BEL (ppnut), 8 = BACKSPASCE (je
smazn pedchoz znak na monitoru a kurzor se nastav na tuto
pozici), 10 = LF (posun o dku vped), 13 = CR (nastaven
kurzoru na prvn sloupec aktuln dky).

                                                            st 2.
ͻ
  slo Chr  Extended  PRN  slo Chr  Extended  PRN
Ķ
  64 40  @      F6          96 60  `    Ctrl F3     
  65 41  A      F7          97 61  a    Ctrl F4     
  66 42  B      F8          98 62  b    Ctrl F5     
  67 43  C      F9          99 63  c    Ctrl F6     
  68 44  D      F10        100 64  d    Ctrl F7     
  69 45  E                 101 65  e    Ctrl F8     
  70 46  F                 102 66  f    Ctrl F9     
  71 47  G     Home        103 67  g    Ctrl F10    
  72 48  H      Up         104 68  h    Alt F1      
  73 49  I     PgUp        105 69  i    Alt F2      
  74 4A  J                 106 6A  j    Alt F3      
  75 4B  K     Left        107 6B  k    Alt F4      
  76 4C  L    Center       108 6C  l    Alt F5      
  77 4D  M     Right       109 6D  m    ALt F6      
  78 4E  N                 110 6E  n    Alt F7      
  79 4F  O     End         111 6F  o    Alt F8      
  80 50  P     Down        112 70  p    Alt F9      
  81 51  Q     PgDn        113 71  q    Alt F10     
  82 52  R    Insert       114 72  r  Ctrl Print    
  83 53  S    Delete       115 73  s  Ctrl Left     
  84 54  T   Shift F1      116 74  t  Ctrl Right    
  85 55  U   Shift F2      117 75  u  Ctrl End      
  86 56  V   Shift F3      118 76  v  Ctrl PgDn     
  87 57  W   Shift F4      119 77  w  Ctrl Home     
  88 58  X   Shift F5      120 78  x    Alt 1       
  89 59  Y   Shift F6      121 79  y    Alt 2       
  90 5A  Z   Shift F7      122 7A  z    Alt 3       
  91 5B  [   Shift F8      123 7B  {    Alt 4       
  92 5C  \   Shift F9      124 7C  |    Alt 5       
  93 5D  ]   Shift F10     125 7D  }    Alt 6       
  94 5E  ^    Ctrl F1      126 7E  ~    Alt 7       
  95 5F  _    Ctrl F2      127 7F      Alt 8       
ͼ

     Zvltn roli zde hraje kd 26 = EOF (konec souboru), kter
lze pmo zobrazit, pokud vstup provdte pmo pomoc write,
jakmile jde o vstup do textovho souboru (viz AssignCrt), je
chpn jako konec souboru a zobrazeno ji nen nic.

     Pi vstupu pomoc READKEY jsou samozejm pouiteln pouze ty
znaky, kter lze z klvesnice zmknout. Pamatujme si, e pro
tento el je: BACKSPACE = 8, TAB = 9, Ctrl ENTER = 10, ENTER =
13 + 10, ESC = 27; podobn, jako je to u tisk.

     Pro tiskrnu plat, e jednotliv znaky jsou zobraziteln
podle Chr, nen-li uvedeno jinak v sloupeku PRN. Vznam tchto
hodnot je zapsn v pslun pruce pro Vai tiskrnu. Zde
jen orientan:
- BEL, BACKSPACE, CR, LF, TAB m stejn vznam jako na monito-
ru.
- FF = pechod na novou strnku;    CAN = smazn napsan dky.
- Sxx = zatek, Exx = konec:
        pr = proloenho tisku, ko = komprimovanho tisku.
                                                            st 3.
ͻ
  slo Chr  Extended  PRN  slo Chr  Extended  PRN
Ķ
 128 80      Alt 9        160 A0                  
 129 81      Alt 0        161 A1                  
 130 82      Alt -        162 A2                  
 131 83      Alt =        163 A3                  
 132 84    Ctrl PgUp      164 A4                  
 133 85       F11         165 A5                  
 134 86       F12         166 A6                  
 135 87    Shift F11      167 A7                  
 136 88    Shift F12      168 A8                  
 137 89     Ctrl F11      169 A9                  
 138 8A     Ctrl F12      170 AA                  
 139 8B      Alt F11      171 AB                  
 140 8C      Alt F12      172 AC                  
 141 8D                   173 AD                  
 142 8E                   174 AE                  
 143 8F                   175 AF                  
 144 90                   176 B0                  
 145 91                   177 B1                  
 146 92                   178 B2                  
 147 93                   179 B3                  
 148 94                   180 B4                  
 149 95                   181 B5                  
 150 96                   182 B6                  
 151 97                   183 B7                  
 152 98                   184 B8                  
 153 99                   185 B9                  
 154 9A                   186 BA                  
 155 9B                   187 BB                  
 156 9C                   188 BC                  
 157 9D                   189 BD                  
 158 9E                   190 BE                  
 159 9F                   191 BF                  
ͼ

     Znaky od 128 do 173 jsou ve standardu vnovny mezinrodn
abeced. V echch se obvykle nepouv a msto n se zavd
jin sady, jako je tomu i v naem ppad, kdy jsme do tabulky
zapsali "etinu podle bratr Kamenickch", kter je pro spolu-
prci s Turbo Pascalem vyhovujc. Mnoho programtor pouv
na osobnch potach jin verze etin, zejmna LATIN II.
Tato sada pekrv kdy 64 a 127. Ob verze vyaduj pro poui-
t speciln ovladae (drivers) pro klvesnici, monitor a tisk-
rnu, kter je poteba jet ped prac s Turbo Pascalem do
systmu zavst.

     Editor integrovanho systmu je osmibitov, tj. je schopen
reprezentovat i znaky z nrodn abecedy a znaky semigrafick.
Tyto znaky lze pst i pomoc ALT klvesy tak, e stisknete
klvesu ALT a na prav (numerick) sti klvesnice vypete
kd znaku, kter chcete zobrazit (nap. do konstanty typu et-
zec), nyn klvesu ALT uvolnte.
                                                           st 4.
ͻ
  slo Chr  Extended  PRN  slo Chr  Extended  PRN
Ķ
 192 C0                   224 E0                  
 193 C1                   225 E1                  
 194 C2                   226 E2                  
 195 C3                   227 E3                  
 196 C4                   228 E4                  
 197 C5                   229 E5                  
 198 C6                   230 E6                  
 199 C7                   231 E7                  
 200 C8                   232 E8                  
 201 C9                   233 E9                  
 202 CA                   234 EA                  
 203 CB                   235 EB                  
 204 CC                   236 EC                  
 205 CD                   237 ED                  
 206 CE                   238 EE                  
 207 CF                   239 EF                  
 208 D0                   240 F0                  
 209 D1                   241 F1                  
 210 D2                   242 F2                  
 211 D3                   243 F3                  
 212 D4                   244 F4                  
 213 D5                   245 F5                  
 214 D6                   246 F6                  
 215 D7                   247 F7                  
 216 D8                   248 F8                  
 217 D9                   249 F9                  
 218 DA                   250 FA                  
 219 DB                   251 FB                  
 220 DC                   252 FC                  
 221 DD                   253 FD                  
 222 DE                   254 FE                  
 223 DF                   255 FF  *                
ͼ

     Znaky oznaen hvzdikou nen mon vytisknout, protoe to
jsou dc znaky pro tiskrnu. B. Chybov hlen

     Pi prci s Turbo Pascalem se nevyhneme chybm. Abychom je
mohli odstraovat, musme znt jejich pinu. V tomto dodatku
uvdme seznam chybovch hlen pi pekladu a pi bhu (ve-
tn chyb pi prci s unitami Dos, Overlay a Graph). Vtina z
nich nen komentovna, nebo jejich pina je zejm ji z
vznamu anglickho hlen. Ty chyby, kter mohou mt vce
pin nebo jsou sloitj, obsahuj strunou npovdu k jejmu
odstrann.



1. Chyby pi pekladu nebo pi prci s integrovanm systmem

     Tyto chyby se vyskytuj pouze v integrovanm systmu jako
hlen ve stavovm dku editorovho okna.


  1 Out of memory
    - Nastavte Compile = Disk a Link = Disk.
    - Odstrate rezidentn programy (obvykle Reset).
    - Kd pesahuje 64KB, pouijte TPC.exe.
  2 Identifier expected
  3 Unknown identifier
  4 Duplicate identifier
  5 Syntax error
  6 Error in real constant
  7 Error in integer constant
  8 String constant exceeds line
  9 Too many nested files               (max 4)
 10 Unexpected end of file
 11 Line too long                            (max 126) 
 12 Type identifier expected
 13 Too many open files                 (max 15)
    - Do Config.sys ulote FILES=20.
 14 Invalid file name
 15 File not found
 16 Disk full
 17 Invalid compiler directive
 18 Too many files
    - Pli mnoho INCLUDE soubor.
 19 Undefined type in pointer definition
 20 Variable identifier expected
 21 Error in type
 22 Structure too large                 (max 64K)
 23 Set base type out of range     (0..255)
 24 File components may not be files or objects
 25 Invalid string length          (1..255)
 26 Type mismatch
 27 Invalid subrange base type
 28 Lower bound greater than upper bound
 29 Ordinal type expected
 30 Integer constant expected
 31 Constant expected
 32 Integer or real constant expected
 33 Type identifier expected
 34 Invalid function result type
 35 Label identifier expected
 36 BEGIN expected
 37 END expected
 38 Integer expression expected
 39 Ordinal expression expected
 40 Boolean expression expected
 41 Operand types do not match operator
 42 Error in expression
 43 Illegal assignment
 44 Field identifier expected
 45 Object file too large               (max 64KB)
 46 Undefined external
      - Provte popis PUBLIC u podprogramu v OBJ-souboru.
      - Provte korektn specifikaci vech .OBJ v {$L ...}.
 47 Invalid object file record
      - .OBJ soubor nem pedepsan tvar.
 48 Code segment too large              (max 64KB)
 49 Data segment too large              (max 64KB)
 50 DO expected
 51 Invalid PUBLIC definition
      -PUBLIC identifiktor nem odpovdajc external v Pascalu.
      - Dvakrt definovan tent PUBLIC.
      - PUBLIC definovan mimo CODE segment.
 52 Invalid EXTERN definition
      - Promnn nen definovna nebo je absolute nebo inline.
 53 Too many EXTRN definitions     (max 256)
 54 OF expected
 55 INTERFACE expected
 56 Invalid relocatable reference
      - Program uloen mimo CODE segment.
      - Pouit nedovolenho odkazu na relokabiln symboly.
      - Odkaz na symbol mimo CODE nebo DATA segment.
      - Podprogram volan s offsetem, nap. CALL Proc + 16.
 57 THEN expected
 58 TO or DOWNTO expected
 59 Undefined forward
      -Podprogram popsan v interface nen popsn v implementa-
      tion.
      -Podprogram popsan jako forward nem pslunou deklaraci.
 60 Too many procedures                 (max 512)
      - Pesute podprogramy do unit.
 61 Invalid typecast
      - Petypovn typem odlin velikosti.
      - Na tomto mst neme bt petypovn.
 62 Division by zero
 63 Invalid file type
 64 Cannot Read or Write variables of this type
 65 Pointer variable expected
 66 String variable expected
 67 String expression expected
 68 Circular unit reference
      - Data spolen obma unitm pesute do unity tet.
 69 Unit name mismatch
      - Jmno souboru i unity mus bt stejn.
 70 Unit version mismatch
      - Nenalezen .PAS soubor k unit, jej .TPU je "star".
 71 Duplicate unit name
 72 Unit file format error
      - .TPU soubor nem pedepsan tvar.
 73 Implementation expected
 74 Constant and case types do not match
 75 Record variable expected
 76 Constant out fo range
 77 File variable expected
 78 Pointer expression expected
 79 Integer or real expression expected
 80 Label not within current block
 81 Label already defined
 82 Undefined label in preceding statement part
 83 Invalid @ argumen
 84 UNIT expected
 85 ";" expected
 86 ":" expected
 87 "," expected
 88 "(" expected
 89 ")" expected
 90 "=" expected
 91 ":=" expected
 92 "[" or "(." expected
 93 "]" or ".)" expected
 94 "." expected
 95 ".." expected
 96 Too many variables                  (max 64KB pro Local i Global)
 97 Invalid FOR control variable
 98 Integer variable expected
 99 Files are not allowed here
100 String length mismatch
101 Invalid ordering of fields
102 String constant expected
103 Integer or real variable expected
104 Ordinal variable expected
105 INLINE error
      - "<" pouit s relokabilnm symbolem.
106 Character expression expected
107 Too many relocation items      (max 64KB)
    - Rozdlit program na vce proces spoutnch pomoc EXEC.
112 Case constant out of range     (-32768..32767, pouze u 5.0)
113 Error in statement
114 Cannot call an interrupt procedure
116 Must be in 8087 mode to compile this
      - Nastavte {$N+}.
117 Target address not found
118 Include files are not allowed here
120 NIL expected
121 Invalid qualifier
      -Indexovn, tekov notace nebo dereference promnn ne-
      vhodnho typu.
122 Invalid variable reference
123 Too many symbols                         (max 64KB)
    - Pekldejte s {$D-}.
    - Rozdlte deklaraci do vce unit.
124 Statement part too large       (max 24KB)
    - Rozdlte pkazovou st bloku na podprogramy.
126 Files must be var parameters
127 Too many conditional symbols
128 Misplaced conditional directive
129 ENDIF directive missing
130 Error in initial conditional defines
131 Header does not match previous definition
      -Hlavika v interface (resp. forward) a v deklaraci mus
      bt zcela stejn nebo nesm obsahovat dn parametry. 
132 Critical disk error
      - Kupte si nov disk.
      - Vlote poadovanou disketu.
133 Cannot evaluate this expression
134 Expression incorrectly terminated
135 Invalid format specifier
136 Invalid indirect reference
      -V absolute nebo inline je pouit identifiktor z jinho
      modulu.
137 Structured variables are not allowed here
138 Cannot evaluate without System unit
      - TURBO.TPL nenalezen, nebo neobsahuje SYSTEM.TPU.
139 Cannot access this symbol
    - Symbol nen alokovn, nebo nen pouit v kdu programu.
140 Invalid floating-point operation
141 Cannot compile overlays to memory
142 Procedure or function variable expected
143 Invalid procedure or function reference
    - Nejastji chybjc {$F+}.
144 Cannot overlay this unit
    - Chybjc {$O+}.
147 Object type expected
148 Local object types are not allowed
149 VIRTUAL expected
150 Method identifier expected
151 Virtual constructors are not allowed
152 Constructor identifier expected
153 Destructor identifier expected
154 Fail only allowed within constructors



2. Bhov chyby

     Bhov chyby jsou chyby vznikl pi bhu programu. Tento
seznam chyb je mnohem dleitj neli chyby pi pekladu,
nebo pi bhu programu mimo integrovan systm je uvedeno pi
chyb pouze jej slo a ne chybov hlen. Tento seznam je
pouvn i pi detekci chyb pomoc IOResult (mimo Fatal errors),
DosExitCode,  RunError (u neuvedench chyb integrovan systm
hls "Runtime error"). Teoreticky se tento chybnk pouv i u
procedur Halt a Keep.

     st tohoto seznamu lze vyut i pro detekci chyb pi prci s
unitou DOS pomoc promnn DosError (pouze chyby 2, 3, 5, 6, 8,
10, 11, 18).
    DOS Errors

     Tyto chyby jsou vydvny pmo Dosem. Chyby uveden v zvor-
kch nemohou vzniknout pi bhu programu (s vjimkou chyb u
DosError) a jsou zde uvedeny pouze pro plnost (mohou vzniknout
u inline nebo external procedur).

( 0 No error )
    - RunError neohls v integrovanm systmu chybu (mimo nj
      ano), ale vpoet peru.
  1 Invalid DOS function code
      - Nedovolen parametry pi voln MSDOS (resp. Intr($21)).
  2 File not found
  3 Path not found
  4 Too many open file
    - Vce ne 15 otevench soubor.
    - Nenastaveno FILES=20 v CONFIG.SYS.
  5 File access denied
    - Soubor je adres nebo Read Only.
    - Soubor nen oteven na ten/zpis.
    - Adres je pln (u Rewrite).
    - Soubor existuje (u Rename, MkDir).
    - Jmno obsahuje i driver (u MkDir).
    - Neexistujc, neprzdn nebo koenov adres (RmDir).
  6 Invalid file handle
( 7 Memory control block destroyed )
  8 Not enough memory
( 9 Invalid memory block address )
(10 Invalid environment )
(11 Invalid format )
 12 Invalid file access code
(13 Invalid data )
 15 Invalid drive number
 16 Cannot remove current directory
 17 Cannot rename across drives
(18 No more matching files )
      -Takov (resp. dal) soubor neexistuje (viz FindFirst,
      FindNext).

     I/O Errors

     Tyto chyby jsou generovny Pascalem pi chybch u vstupu a
vstupu. Lze je, stejn jako ostatn I/O chyby generovan Dosem,
potlait pomoc {$I-}.

100 Disk read error
    - READ() za koncem souboru.
101 Disk write error
    - Pln disk.
102 File not assigned
103 File not open
104 File not open for input
105 File not open for otput
106 Invalid numeric format
    Critical Errors

     Tyto chyby jsou generovny Dosem pi diskovch operacch (INT
24H a INT 25H).

150 Disk is write-protected
151 Unknown unit
152 Drive not ready
153 Unknown command
154 CRC error in data
155 Bad drive request structure length
156 Disk seek error
157 Unknown media type
158 Sector not found
159 Printer out of paper
160 Device write fault
161 Device read fault
162 Hardware failure

     Fatal Error

     Tyto chyby jsou generovny Pascalem a vdy kon bh progra-
mu.

200 Division by zero
201 Range check error
202 Stack overflow error
203 Heap overflow error
204 Invalid pointer operation
205 Floating point overflow
206 Floating point underflow
207 Invalid floating point operation
208 Overlay manager not instaled
209 Overlay file read error

     Ctrl Break

255 User break
      -Tento nvratov kd odpovd peruen programu uivatelem
      klvesou CtrlBreak (je-li CheckBreak=true).


3. Chyby pi Overlay

     Chyby pi Overlay jsou podrobn popsny v 6.5.4. Jsou indi-
kovny v promnn OvrResult. Jejich hodnoty mohou bt tyto:

          OvrOk = 0;                    { Bez chyby }
          OvrError    = -1;        { Chyba v zen overlay }
          OvrNotFound = -2;        { Nenalezen soubor .OVR }
          OvrNoMemory = -3;        { Nedostatek pamti pro buffer }
          OvrIOError  = -4;        { I/O chyba u .OVR souboru }
          OvrNoEMSDriver = -5;     { Nen instalovno EMS }
          OvrNoEMSMemory = -6;     { Nedostatek pamti v EMS }

4. Chyby v grafice

     Chyby v grafice jsou podrobn popsny v 9.1.3. Jsou pstupn
pomoc funkce GraphResult a jejich text pomoc GraphErrorMsg.
Jde o tyto chyby:


  0 = grOK               No error
 -1 = grNoInitGraph      (BGI) graphics not installed
          -Nenalezen .BGI soubor.
 -2 = grNotDetected      Graphics hardware not detected
          -Adaptr vaeho monitoru nepodporuje grafiku.
 -3 = grFileNotFound     Device driver file not found ()
          -Nenalezen .BGI soubor.
 -4 = grInvalidDriver    Invalid device driver file ()
          -.BGI soubor nem pedepsan tvar.
 -5 = grNoLoadMem        Not enough memory to load driver
          -Nedostatek pamti na HEAP pro zaveden grafickho ovla-
         dae ( potebuje asi 10KB ).
 -6 = grNoScanMem        Out of memory in scan fill
 -7 = grNoFloadMem       Out of memory in flood fill
 -8 = grNotFound         Font file not found ()
          -Nenalezen .CHR soubor.
 -9 = grNoFontMem        Not enough memory to load font
          -Nedostatek pamti na HEAP pro zaveden fontu (pro
         Gothic 8.5KB - nejvt peddefinovan font).
-10 = grInvalidMode      Invalid gr. mode for selected driver
          -Pouijte DetectGraph.
-11 = grError            Graphics error
-12 = grIOError          Graphics I/O error
-13 = grInvalidFont      Invalid font file ()
          -.CHR soubor nem pedepsan tvar.
-14 = grInvalidFontNum   Invalid font number
-15 = grInvalidDeviceNum Graphics error (-15)

C. Turbo Pascal 5.5 versus procedurln jazyky

     V tto kapitole se pokusme postihnout zsadn rozdly mezi
verzemi Pascalu. Pot si uvdomme, jak rozdly m Turbo Pascal
oproti standardn verzi Pascalu [WIRTH] a pokusme se popsat
podstatn rozdly oproti jinm bnm procedurlnm jazykm
minulosti i souasnosti ( Fortran,  Cobol,  Algol,  PL/1, 
Simula 67, C, Modula, Ada ).
     Vechny vyjmenovvan odchylky budeme popisovat pouze jedno-
smrn, tj. co jin jazyky um a Turbo Pascal nikoli, a budeme
vdy hledat een, jak tento prvek v Turbo Pascalu snadno
realizovat.

     Tyto odchylky jsou vesms malichernm syntaktickm pozltkem
a jsou uvedeny sp jako cvien algoritmickch technik. Kdyby
se mne vak nkdo zeptal, co mi na Turbo Pascalu skuten vad,
ekl bych asi toto: "Je to pedevm nemonost vytvet object-
moduly, tj. soubory typu .OBJ, kter by vznikly pekladem zdro-
jovho programu a kter by bylo mono pomoc LINK pipojit jako
extern modul k jinm, zejmna databzovm, aplikacm.
Druhou stinnou strnkou je fakt,
e systm neumouje provdt kontrolu inicializace promnnch a
zejmna pointer, ba dokonce klidn pracuje se zznamy adresova-
nmi pomoc nil. Chyby takto vznikl se velmi tko odhaluj a
okrdaj programtora, o nho systm jinak peuje jako ve
vatice, o znan mnostv asu."

1. Varianty a verze Pascalu

     Prvn nvrh normy jazyka Pascal byl publikovn ve [WIRTH] a
stal se standardem jazyka. Na osobnch potach se Pascalu
ujala firma Borland International, kter postupn vytv jedno-
tliv verze Turbo Pascalu. U ns se nyn pevn pouvaj
verze 4.0, 5.0 a 5.5. V souasnosti se na trhu objevil i produkt
konkurenn firmy Microsoft pod nzvem Quick Pascal, kter
vychz z Turbo Pascalu verze 5.0.
     Vimnme si jednotlivch verz ble:

     Standardn Pascal

     Vtina peklada standardnho Pascalu kontroluje iniciali-
zaci hodnot. Nm tedy nezbv, ne se snait nezapomenout dnou
promnnou inicializovat a pi prci s ukazateli a pointery si
stle pedstavovat tu hromadu asu, kterou bychom mohli strvit
ladnm ppadnch chyb.

     Uveme prvky, kter v Turbo Pacalu nejsou oproti standardu
realizovny, pro ppad pepisu program ze standardu do Turbo
Pascalu:
-  Turbo Pascal umouje pstup k souborm pouze pomoc proce-
   dur READ a WRITE. Nejsou zde implementovny ani procedury
   GET, PUT a PAGE a ani mechanismus vyrovnvacch pamt:
   "<id.typu soubor>^". Tento fakt plyne z odlin filozofie 
   DOSu pi prci se soubory oproti dvjm operanm sys-
   tmm.
-  Standardn Pascal umouje, aby parametrem podprogramu byl
   opt podprogram. Verze 4.0 to neumouje vbec. Dal verze
   to ji umouj v plnm rozsahu, avak s odlinou syntax,
   kter koncepci jazyka lpe vyhovuje. Ve verzi 4.0 je jedinou
   cestou tvorba INLINE-procedur, kter umon pedvn para-
   metr a voln podprogram pomoc adresy jejich vstupnho
   bodu, podle konvenc popsanch ve 3. a 7. kapitole.
-  Turbo Pascal nerozeznv pakovan a nepakovan promnn
   (nebo vechny se pakuj automaticky), a tak slvko PACKED je
   zde chpno jako koment a procedury PACK a UNPACK nejsou
   implementovny vbec.

     Shrme ve strunm pehledu ostatn drobn prvky Turbo
Pascalu odlin oproti standardu:
-  Identifiktory se rozliuj podle prvnch 63 znak.
-    Symbol @ nelze pout ve smyslu opertoru ^.
-  Nelze kombinovat { a *), stejn jako (* a }.
-  Nelze pout globln deklarace nvt pro skok v podpro-
   gramu.
-  Read na konci dku textovho souboru vrt hodnotu #13.

     Turbo Pascal 4.0 x 5.0

     Verze 5.0 je pln kompatibiln s verz 4.0, pouze s tm, e
pro prci v 5.0 je teba znovu peloit vechny unity, nebo
.TPU soubory maj jin tvar. Verze 5.0 roziuje verzi 4.0
pedevm o:
-  Kvalitn integrovan systm, umoujc trasovn, prbn
   sledovn hodnot promnnch (watching), pouit breakpoint a
   vyhodnocovn libovolnch vraz nad promnnmi programu.
-  Promnn typu podprogram, kter mohou bt zrove i procedu-
   rlnm parametrem.
-  Monost Overlay, jak jsme o nich hovoili v 6.4.
-  Nkolik knihovnch procedur, kter umouj zejmna: pstup
   k systmovm promnnm, obnoven vektoru peruen, a dopl-
   nn unity Graph o podprogramy umoujc: vytven elipti-
   ckch vse, definovn uivatelskch rozmr psma, insta-
   lace vlastnch styl psma a ovlada, atd.

     Turbo Pascal 5.0 x 5.5

     Verze 5.5 je s 5.0 pln kompatibiln, vetn tvaru .TPU
soubor. Je doplnna o pechodnou oblast pro prci s Overlay,
co zvyuje efektivitu algoritmu pro zavdn overlay. Nejpod-
statnj je samozejm monost objektov orientovanho progra-
movn, kter tato verze pln podporuje (viz 6.4.).

     Quick Pascal

     Quick Pascal je (pr) kompatibiln s verz 5.0, a na dv
vci: 
-  Quick Pascal neobsahuje prostedky pro Overlay.
-  Vechny unity je nutno znovu peloit.

     Quick Pascal takt podporuje objektov orientovan progra-
movn, ale syntaxe se oproti Turbo Pascalu 5.5 trochu li.
     Standardn knihovna podprogram je ir ne u Turbo Pas-
calu. Systm ovldn je analogick vem produktm firmy Micro-
soft, piem obsahuje srovnateln ladc prostedky jako Turbo
Pascal 5.5.

2. Jin programovac jazyky

     V tomto odstavci nechci rozebrat rozdly jednotlivch ja-
zyk, ale sp si povimnout, jakmi technikami lze ten i onen
obrat realizovat.

i)   Deklarace

     S politovnm na tomto mst musm opt konstatovat, e
vtina jazyk kontroluje inicializaci promnnch...

     Nov typy

-  complex je typ reprezentujc komplexn sla. Vyskytuje se v
   mlo bnch aplikacch a realizovat se d jako zznam:
                    record Re, Im : real end;
   Vedle tto deklarace je samozejm poteba napsat i procedury
   realizujc bn operace, co jist zvldnete. Nap.:
                    procedure SUM (op1, op2 : complex; var v : complex);
-  offset je blzk ukazatel (tj. ukazatel neobsahujc seg-
   ment), jen zabr pouze dva byty. Jeho pouit je zejm
   efektivn, avak s ohledem na segmentaci pamti zenou pe-
   kladaem v Turbo Pascalu tm nemon. (viz PL/1)
-  text jako etzcov promnn (Simula 67), odpovdajc pro-
   mnn string, obsahujc navc "aktuln pozici v textu".
   Prce s touto promnnou je pomrn odlin od prce s etz-
   ci, nebo pro uloen text se pouv HEAP. Akoli by ji
   bylo mono opt realizovat pomoc zznam zcela pesn, je
   pi existenci string zbyten, a proto jej implementaci
   ponechm zarytm Simulistm jako cvien.
-  float je specifikace relnch sel. Podstatnou odlinost je
   monost specifikovat pesnost a poet platnch sel jejich
   reprezentace. Tuto specifikaci lze nahradit vbrem vhodnho
   typu (single, real, double, extended). Odlien po bitech
   nen, s ohledem na bytovou orientaci PC, podstatn.
-  union je typ adekvtn typu record se stejnm stupnm zabez-
   peenosti. Jeho mylenku - sjednocovn jednoduchch struktur
   ve sloitj - lze realizovat pomoc zznam jednoduch
   zznam.

     Do jazyka nen zahrnut vtov typ s uivatelsky definovanou
implementac: nap.
          type status=(Ready=>24, Busy=>144, Delay=>118);
Vhoda tohoto typu je zejm pi programovn obsluhy periferi,
nebo zven zabezpeenosti lze v Pascalu nahradit pouze zve-
nou pozornost.

     Podobnm prvkem jsou cobolsk podmnkov jmna [JANKOVEC].
Ani tato technika v Pascalu nen. Tm, kdo nechtj milovan
value opustit, doporuuji napsat logick funkce, kter tyto
podmnky vyhodnocuj; nebo omezen podmnkov rozsah realizovat
vtovm typem.

     Deklaran klauzule

-  own je algolsk [RAICHL] klauzule vyjadujc, e  pslun
   promnn bude do ptho voln procedury zachovvat svoji
   hodnotu. Tto klauzuli pln odpovd pouit typovanch
   konstant.
-  value jako klauzuli inicializujc hodnotu promnn lze
   nahradit typovanou konstantou.
-  filler je cobolsk jmno pro oznaovn nepodstatnch poloek
   zznam (Nevyuito, rezervovno,...). Doporuuji i v Pascalu
   pro tento el pouvat podobnch promnnch (kter mus bt
   bohuel i zde navzjem rzn), nap. FILLER1, FILLER2,...
-  implicit je fortransk klauzule definujc implicitn tdu
   nkterch promnnch. Pouit implicitn deklarace je vnm
   poruenm zabezpeenosti jazyka, a proto nebyla do Pascalu
   zahrnuta. Na druh stran je pro itelnost program dobr,
   aby programtoi dodrovali obvykl konvence (i,j,k,... =
   integer, atd.). 
-  redefine slou k redefinici sti zznam. Tuto klauzuli lze
   snadno nahradit v Turbo Pascalu variantnmi zznamy (statick
   redefinice) a petypovnm (dynamick redefinice).
-  rename lze v Pascalu provst pouze na rovni typ a konstant.
   Na rovni promnnch vede ke ztrt zabezpeenosti, a proto
   nen nikterak umonna (leda pomoc dynamickch promnnch).

ii)  Vrazy

     Opertory

     Programovac jazyky obsahuj tak vce opertor, jedn se
zejmna o tyto:

-  M ** N = umocovn, lze spn nahradit vrazem
                    exp(ln(M)+N).
-  P + N; P - N, jako operace v adresnm prostoru (jazyk C)
   jsou pomrn nebezpen, a tak je nelze eit.
-  a += 3 a podobn vrazy (L-value), kdy je adresa operandu,
   je je zrove na lev i prav stran vrazu, vyhodnocovna
   pouze jednou (zpis odpovd proveden a:=a+3) nejsou Turbo
   Pascalem podporovny a uivatel, kte chtj sv programy
   takto optimalizovat, mus pout inline nebo external podpro-
   gramy.
-  x < 7 or > 15 a podobn vrazy, jak je znme z Cobolu, sice
   tak optimalizuj kd, ale velmi sniuj zabezpeenost pro-
   gramu, a proto nebyly do jazyka zahrnuty.

     Konstanty

-  all zahrnuje vechny prvky libovoln mnoiny [ADA]. Tako-
   vouto konstantu si me uivatel vytvoit napklad ns-
   ledujc funkc:
          function All ( Size : byte ) : pointer;
          var P : pointer;
          begin
               Getmem(P,Size);
               FillChar(P^,Size,#255);
               All:=P;
          end;
-  seln konstanty zapisovan v oktalov nebo binrn soustav
   takt nejsou soust jazyka; pokud bychom na jejich kdo-
   vn v programu trvali, sta napsat takovouto funkci:
          function Num ( S : string; Soustava : byte ) : longint;
          { Pevd etzec zapsan v zadan soustav na slo
            typu longint, nap.: stav:=Num('10110001',2) }
          var i:byte;
                n:longint;
          begin
               n:=0;
               for i:=1 to length(s) do
                    n:=n*Soustava + ord(s[i])-ord('0');
               Num:=n;
          end;

     Funkce

-  Space(N); Repl(Znak,N); lze velmi snadno dopsat (stlm
   uivatelm Turbo Pascalu to doporuuji, nebo jsou asto
   poteba), napklad takto:
          function Repl ( C : char; N : byte ) : string;
          var s:string;
          begin
               s[0]:=N;
               FillChar(s[1],N,C);
          end;
-  Numeric(S); Alphabetic(S); jsou logick funkce testujc,
   zdali prvn znak etzce je slice nebo psmeno. Lze je
   realizovat takto:
          function Numeric ( s : string ) : boolean;
          var N:real; Code: integer;
          begin
          Val(s,N,Code);
          Numeric := Code=0;
          end;
-  IIF(B,V1,V2); je jedna z forem podmnnho vrazu. Tato
   konstrukce nen do jazyka zaazena opt z hlediska "istoty
   struktury jazyka". Jej realizace pro formtovn vstup
   (tj. etzc), me mt napklad takovto tvar:
          function IIF ( B : boolean; S1, S2 :string ) : string;
          begin if B then IIF:=S1 else IIF:=S2 end;
-  Vrazy nad strukturovanmi promnnmi a jejich podmnoinami
   nejsou do jazyka zahrnuty s ohledem na jejich asovou n-
   ronost pi provdn a samozejm i ztrtu zabezpeenosti.
   Tato skutenost nut programtora pemlet o tom, zdali
   zamlenou operaci skuten potebuje pout a pokud ano,
   nut jej, aby jej provdn ml pln pod kontrolou tm, e
   ji rozepe po polokch. Pkladem me bt pkaz z PL/1
   A[*,*] = B[1,*] jen se d snadno a bezpen vyjdit jako
   for i:= 1 to N do A[i,i] := B[1,i].

iii) Pkazy

     dc pkazy

     Jazyk Pascal pat mezi strukturovan jazyky se znanou
zabezpeenost. Z tohoto by se v nm neml asto pouvat pkaz
goto. Je tedy zejm, e by nebylo rozumn do jazyka zavst
monost skok s promnnm nvtm. Z toho plyne, pro nebyly do
jazyka zahrnuty pepnae (switch), promnn nvt (label),
skok na promnn nvst (goto alter) atp.

     Podobn problm, i kdy ne tak vyhrocen, nastv pi pouit
pkazu FOR se zadanm krokem a ppadnou logickou podmnkou
tak, jak jej znme z Algolu [RAICHL]; nap.:
          for i:=1 step 1.1 to 18 until sqr(i)<sqrt(j) do ... ;
     Ji na prvn pohled je jasn, e ci kolikrt se bude tlo
cyklu vlastn provdt, nen tak jednoduch, a e takovto
specifikace cyklu in program mn iteln.
     Pokud byste nco takovho potebovali, pouijte FOR-cyklus a
pomocnou promnnou, kterou vdy vynsobte potebnm krokem a pro
vslednou podmnku pouijte vskok z cyklu pomoc GOTO.

     Piazovn hodnot

     O piazovn hodnot jsme vlastn ji hovoili v souvislosti
s vrazy. Doplme toto povdn jet dvma poznmkami:
-  Pascal neobsahuje cobolsk MOVE CORRESPONDING. Dvodem je
   opt bezpenost a plat to, co jsme kali o vrazech nad
   strukturovanmi typy.
-  Turbo Pascal neumouje vcensobn piazen. Ztrc tak
   monost generovn efektivnjho kdu, ale zvyuje tm
   bezpenost programovn. Co teba s takovmito konstrukty:
          A[p]:=p:=B[A[p]]:=p+1.

iv)  Procedury a funkce

     Petovn identifiktor

     Petovn identifiktor podprogram (stejn pojmenovan
podprogramy lic se typem nebo potem parametr) me zsadn
zmenit rozsah knihoven podprogram a tm zjednoduit jejich
pouvn, na druh stran zmenuje bezpenost jejich pouvn.
     V Turbo Pascalu jsou definovny tyto petovan podpogramy:
Write, Writeln, Read, Readln, New, Dispose a tak vtina pod-
program pro prci se soubory; jejich innost jsme se ji
mnohokrte zabvali.
     Uivatel si sm petovan podprogram napsat neme, avak
me pout dv podobn techniky:
-  Pekrvn podprogram v rmci unit a jejich voln pomoc
   kvalifikace jmnem unity (viz 6.5.).
-  Virtualizace podprogram, jak je popsna v odstavci o objek-
   tech (viz 6.4.).

     Voln parametr

     V tomto odstavci probereme jednotliv typy pedvn para-
metr v jinch jazycch:

-  In = Jde o pedvn hodnotou.
-  Out = Jde o pedvn vsledku. Tento druh pedvn para-
     metr lze pln nahradit volnm odkazem.
-  VarInOut = Jde o bn pedvn parametr odkazem.
-  InOut = Jde o pedvn hodnotou pi vstupu i vstupu, jak to
      znme nap. z Fortranu. Toto voln lze opt nahradit
      volnm odkazem, piem je poteba vdt o odlinostech
      obou zpsob. Srovnejme tyto dva programy:
                    n = 1                   var n : integer;
                    call X(n)               procedure X(var i:integer);
                    ...                               begin
                    stop                          n:=n+1;
                    end                           i:=n+i;
                    subroutine X (/i/)         end;
                    integer i               begin
                    n = n + 1                  n=1;
                    i = n + i                  X(n);
                    return                     ...
                    end                     end.
      Po nvratu z podprogramu X bude v promnn N ve fortran-
      skm programu hodnota 3 a v turbopascalskm programu
      hodnota 4. Nen vak poteba zdrazovat, e takto se
      programovat nem.
-  Name = Jde o pedvn parametr jmnem, kter pro svou
      znanou nebezpenost nen zahrnuto v dnm novjm
      programovacm jazyce (naposled Simula 67) a tedy ani v
      Pascalu.

     V nkterch jazycch je zvykem pedvat vsledek funkce
pkazem Return, pokud se tohoto zvyku nechcete vzdt, pouvej-
te pkazu Exit spolu s pedchozm piazenm vsledku funkci.

   Peddefinovan podprogramy

     Turbo Pascal nem pli velk knihovny podprogram. Tyto
knihovny umouj pouze komunikaci s operanm systmem a peri-
feriemi. Firma Borland vak dodv mnoho unit s knihovnmi
podprogramy. Vyjmenujme ty nejznmj: Sort, Database, Mathe-
matic, Statistic, Graphic, Menu, Edit, atd.

     Pro cobolisty bych doporuoval jako dobr cvien napsat v
Turbo Pascalu ekvivalenty pkaz Examine nebo Transform, kter
zde mnohdy postrdaj... Mal nvod:
          procedure TransfFirst (var s : string; From, ToC : char);
          begin if Pos(s[i],From) then s[Pos(s[i],From)]:=ToC end;

v)   Soubory

     Pstup k souborm

     Turbo Pascal podporuje vechny bn typy pstupu k soubo-
rm. Pro prci s indexovmi a index-sekvennmi soubory je
vhodn pouvat toolbox Database. Primitivn soubory (oproti
jinm jazykm) umouj velmi efektivn pracovat s libovolnm
typem struktury soubor (nap. pstup k souborm typu .dbf
pouvanm v Dbase III + atp.).

     Zkusme realizovat napklad fortranskou operaci Backspace(F):
               seek(filepos(F)-1)
Podobn meme realizovat i ten souboru pozptku, jak je tomu
v PL/1, pi pouit klauzule Backward.

     Formty vstup

     Jednm z prvnch zpsob formtovn vstup je pouit
fortranskho pkazu FORMAT. Tento pkaz sice umouje mnoho
zpsob formtovn, ale stejn se obvykle pouv pouze jejich
podmnoina, jeho pouit nen moc pohodln (jinde WRITE a jinde
FORMAT) a zpis nen pli iteln. Vhodu separovn formtu
vstupu od vlastnho vstupnho pkazu a monost pouvat
stejn formt vstupu na rznch mstech programu, lze velmi
snadno realizovat i v Pascalu vytvoenm pslun formtovac
procedury:

      write (x,y) 100        procedure Write100(x,y:real);
      ...                     begin writeln(x:10:5, y:10:5) end;
100 format(2F10.5)            ... Write100(x,y) ...

     Dal prvky pi formtovn vstup se objevily zejmna v
Cobolu a pro vytven vstupnch sestav jsou velmi uiten.
Diskutujme nejpouvanj z nich: BLANK WHEN ZERO. Pi vstupu
msto nuly tiskne mezery. Toto lze opt velmi snadno vyeit
pomoc vstupn procedury. Hor je situace, kdy potebujeme
zapisovat i vedouc nuly. V tomto ppad je vhodn pout
nejprve proceduru str a pot cyklem opravit vechny mezery na
nuly.

     Pi pebrn cobolskch soubor leckdy vznikaj problmy s
transformac dat zejmna v BCD kdu (COMP-3). Takovto data je
nutno pest jako etzec znak a pot dekdovat pomoc kom-
binace opertor div a mod:
          function Unpack (s:string):longint;
          var l:string;
                i:byte;
          begin
             l:=0;
               for i:=1 to Length(s) do
                    l:=l*100 + 10 * ( s[i] div 16 - ord('0')) +
                                              ( s[i] mod 16 - ord('0'));
               Unpack:=l;
          end;

vi)  Nov a bezpen

     Assert

     V modernch jazycch [ADA] se objevil pkaz ASSERT. Tento
pkaz m tvar:
          assert <logick vraz>
a pouv se k oven sprvnosti bhu programu. Je-li hodnota
vrazu False, dojde k indikaci chyby. Program proloen v kon-
trolnch bodech cykl a na pechodech mezi logickmi bloky
takovmito testy, kter "verifikuj parciln korektost progra-
mu", bude jist velmi rychle odladn a bude pracovat "pomrn
sprvn" [MANNA].
     V Pascalu lze tento pkaz nahradit procedurou, jak je uvede-
na v nsledujcm pkladu. Takovouto proceduru doporuuji hojn
pouvat pi ladn i pi vlastn prci programu (pokud to
program podstatn nezpomaluje), zejmna v mlo pehlednch
programech (nap. numerick vpoty).

     Jako pklad uvedeme vpoet Eulerova sla e=2.71828...
podle vzorce:
                       1    1    1    1          1
               e = 1 +  +  +  +  + ... + 
                       1!   2!   3!   4!         n!

na zadan poet platnch mst (konstanta Long):


Program Euler;
uses crt;

type
    Numeric = word;

const
    Long = 7000;

type
    LongNum = array [1..Long] of byte;

var E,Delta : LongNum;
    i   : Numeric;

procedure Assert (V:boolean; S: string);
     {Procedura pro ovovni sprvnosti algoritmu}
   const Assert_Error = 20;
   begin
      if not V then
         begin
         TextAttr := Black shl 4 + White;
         writeln;
         writeln('*** Assert Error: ',S,' ***');
         RunError(Assert_Error);
         end;
   end; {Assert}

procedure Out (var Z:LongNum);
     {Tisk sla Z}
   var i:Numeric;
   begin
      write(z[1],'.');
      for i:=2 to Long do write(z[i]);
      writeln;
   end; {Out}

procedure Jedna (var Z:LongNum);
     {Inicializuje Z: "Z:=1.00000"}
   var i:Numeric;
   begin
      Z[1]:=1;
      for i:= 2 to Long do Z[i]:=0;
   end; {Jedna}

procedure Add (var Z,X:LongNum);
     {Sete Z a X a vsledek ulo do Z}
   var i,Carry,CP:Numeric;
   begin
      Carry:=0;
      for i:=Long downto 1 do
         begin
         CP:=(X[i]+Z[i]+Carry) div 10;
         Z[i]:=(X[i]+Z[i]+Carry) mod 10;
         Carry:=CP;
         end;
      Assert(Carry=0,'ADD OVERFLOW');
   end; {Add}

function Divide (var Z:LongNum; A:Numeric):boolean;
     {Vydl Z/A -> Z, a pokud je Z=0 vyd true, jinak false}
   var i,Carry,CP,P:Numeric;
   begin
      Carry:=0;
      P:=0;
      for i:=1 to Long do
         begin
         CP:=((Z[i]+Carry) mod A) * 10;
         Z[i]:=(Z[i]+Carry) div A;
         Carry:=CP;
         Assert(Carry*10 >= Carry,'DIV UNDERFLOW');
         if (P=0) and (Z[i]>0) then P:=i;
         end;
      Divide:=P=0;
   end; {Divide}

begin
   Jedna(E);
   Jedna(Delta);
   i:=1;
   repeat
      ADD(E,Delta);
      Inc(i);
          {V Delta je uveden 1/I!, potan jako (1/(i-1)!)/i}
   until Divide(Delta,i);
   Out(E);
end.

     Zkuste si program prostudovat, ne budete st dl a rozho-
dnout, zda je dobe nebo ne. Poznamenejme, e pokud jej spu-
stte pi konstant Long=10, vype se 2.718281823, tak jak
bychom oekvali...

     Tak tedy program dobe nen. Pro? Protoe pi vpotu hod-
noty promnn Carry v procedue Divide dojde k peteen a pokud
by nebyl proveden Assert-test, vpoet by pokraoval klidn dl,
ale vsledek by byl od 1561. msta zaten zaokrouhlovac chybou
a tedy patn. Je jasn, e pokud byste tento test neprovedli,
tko na tuto chybu nkdy pijdete. Poznamenejme, e tento
program spn pracuje napklad pro hodnotu Long=1000 (vpoet
trv nkolik minut).

     Uveden pklad je velmi demonstrativn, ale proceduru Assert
lze pouvat i v mn zvanch ppadech jako jakousi formu
"kontrolovanho komente".

     Lokln bloky

     Modern jazyky umouj pracovat s loklnmi bloky, nap:
          var i,n:byte;
          begin
               ...
               Inc(i);
               var i:integer;
                     s:string;
               begin
                    read(s);
                    val(s,n,i);
               end;
               n:=n*i;
               ...
          end.

     Jejich vznam spov zejmna v monosti pouvat lokln
promnn a tak zvit bezpenost programu s ohledem na monost
pouit stejnho identifiktoru pro "pracovn=lokln" promnnou
a promnnou globln.
     V Pascalu nen mon lokln bloky vytvet. Lze je vak
velmi dobe nahradit volnm procedur, kter jsou volny teba
jenom jednou. Je pravda, e se tm program trochu prodlou a u
delch program se zkomplikuje jeho ten, ale bezpenost
programu za to stoj.

     Paraleln programovn a vjimen situace

     Dal prvek modernch jazyk je paralelismus. Obecn paraleln 
programovn nen podporovno operanm systmem MS DOS ani TOS, a 
proto se pod Turbo Pascalem prakticky provozovat ned. Na Atari pro 
tyto ely vele doporuuji pouit modernho MINTu (MultiTOS).
     S paralelnm programovnm a programovnm perifernch za-
zen velmi zce souvis obsluha vjimench situac, jak je
znme z PL/1 (ON) nebo z ADA (exception). Protoe jsme vylouili
paraleln programy, zbvaj zhruba tyto ppady (nzvy pevzaty
z PL/1):

     Area        -Nedostatek msta v pamti lze eit vytvoenm
                  vlastn procedury HeapError (viz 6.1.4.)
     Conversion - Turbo Pascal m silnou typovou kontrolu, a tak
                  vechny kontroly konverze probhnou ji pi
                  pekladu a pi bhu k takovto chyb nedojde.
     EndFile     -Prce se soubory nen eena pomoc vjime-
                  nch situac, nebo Pascal upednostuje
                  sekvennost zpracovn kdu. Pokud by dolo k
                  tto situaci chybou pi vstupu, je mon ji
                  opt sekvenn obslouit (viz IOResult a
                  {$I+}).
     Error            -Situace vznikajc pi vech neuvedench
                  chybch. Lze ji pmo obslouit pouitm Exit
                  procedury (viz 7.5.3.).
     Overflow   - Lze potlait pomoc {$R-}. Pokud bychom chtli
                  realizovat vlastn obsluhu, musme napsat
                  vlastn obsluhu INT 04H, podobn, jako to dl
                  integrovan systm TURBO.EXE.
     Underflow  - Podteen bohuel v Turbo Pascalu detekovat
                  nelze.
     ZeroDivide - Dlen nulou lze opt obslouit vytvoenm
                  vlastn obsluhy peruen INT 00H.

     Tento pehled je pouze vtem zkladnch situac a jist sami
snadno vyete otzky, co s uivatelskmi situacemi, perue-
nmi z klvesnice, z periferie atp., kter se vesms e na
rovni BIOSu.

     Generick moduly

     Posledn bod, o kterm bych se chtl jet zmnit, jsou gene-
rick moduly, jak je znme z Ady nebo Moduly. Jsou to vlastn
obyejn moduly (viz 6.5.), ale jejich parametry a typy, s nimi
pracuj, jsou zadvny a pi bhu programu. Moduly jsou tzv.
vygenerovny. Jako pklad meme uvst obecn zsobnk, jeho
hloubku a typ poloek urme a pi jeho pouit.
     Vhodou tchto generickch modul je jejich obecnost. Vytvo-
me-li knihovnu takovchto modul realizujc i pomrn sloit
abstraktn datov struktury, meme ji potom vyut v mnoha
rozlinch aplikacch, piem moduly vdy "nakonfigurujeme"
tak, jak pro danou lohu potebujeme.
     Jak vme, moduly se v Turbo Pascalu realizuj pomoc unit.
Tm vak nen mon pedat parametry. e se to tedy tak, e
vlastn inicializan st unit je tm przdn a vlastn
inicializace modulu je provdna volnm inicializan proce-
dury (jaksi konstruktor), kter ji me obsahovat potebn
parametry.
     Jedinm zvanm problmem je pedn "typu" hostitelskch
dat. Tento problm nen mon pi zachovn typov kontroly
nijak eit. Jedinou cestou je pout pro prci s abstraktn
datovou strukturou netypovan parametry procedur a v iniciali-
zan procedue uvst pouze jejich velikost (nikoli strukturu).
     Tento postup se asto vyuv (unity pro tdn (SORT),
prci s indexovmi soubory (TACCESS), atd.), ale je koda, e
nen mon zajistit typovou kontrolu dat hostitelskho typu.
Seznam pouit literatury


[AHO]     AHO,A.V.-HOPCROFT,J.E.-ULLMAN,J.D.: Data Structures and
         Algorithms, Addision-Wesley, 2.vyd., 1985, 427 s.

[ADA]    Jazyk programirovanija ADA, Finansy i statistika,
         Moskva, 1.vyd., 1981, 190 s.

[ANDL]  ANDL,J.: Matematick statistika, SNTL a ALFA, Praha,
         2.vyd., 1985, 352 s.

[AM]     Aplikovan matematika, SNTL, Praha, 1.vyd., 2386 s.

[BORLAND 87A] BORLAND INTERNATIONAL: Turbo Pascal 4.0, USA,
               1.vyd., 1987, 654 s.

[BORLAND 87B] BORLAND INTERNATIONAL: Turbo Pascal, User's Guide
               Version 5.0, USA, 1.vyd., 1987, 1988, 331 s.

[BORLAND 88] BORLAND INTERNATIONAL: Turbo Pascal 5.0, Reference
          Guide, USA,    1.vyd., 1988, 493 s.

[BORLAND 89] BORLAND INTERNATIONAL: Turbo Pascal 5.5, USA,
               1.vyd., 1989, 118 s.

[ADA]   ADA,O.: Turbo C pro pokroil, SPS VIDEOPRESS MON,
         Praha, 1.vyd.

[HRYCEJ] HRYCEJ,D.-MATYSKA,K.: Operan systm MS DOS, SPS
         VIDEOPRESS MON, Praha, 1.vyd., 212 s.

[HURT]   HURT,J.: Simulan metody, SPN, Praha, 1.vyd., 163 s.

[IBM]    IBM: Disk Operating System Version 3.30

[JANKOVEC] JANKOVEC,K.-KAPAR,J.-ZMEK,P.: Programovac jazyk
               COBOL, SPN, Praha, 1.vyd., 1982, 201 s.

[JINOCH] JINOCH,J.-MULLER,K.-VOGEL,J.: Programovn v jazyku
         Pascal, SNTL, Praha, 3.vyd., 1988, 328 s.

[JROVSK] JROVSK,V.: Osobn potae, pednka na MFF UK,
          1988,1989,1990

[JROVSK-konzultace] JROVSK,V.: konzultace

[KALB]  KALB,P.-STAR,P.: FORTRAN 4 - popis jazyka, Oborov
         informan stedisko pro OVT, Praha, 1.vyd., 1981, 
               136 s.

[KERNIGHAN] KERNIGHAN,B.W.-RITCHIE,D.M.: Programovac jazyk C,
               ALFA a SNTL, Praha, 2.vyd., 1989, 256 s.

[KRYL]   KRYL,R.: Programovn, pednka na MFF UK, 1981

[MADNICK] MADNICK,S.E.-DONOVAN,J.J.: Operan systmy, SNTL,
          Praha, 2.vyd., 1983, 592 s.

[MANNA]  MANNA,Z.: Matematick teorie program, SNTL, Praha,
         1.vyd., 1981, 468 s.

[MALK]  MALK,M.: Simula 67

[MEJZLK] MEJZLK,L.: Textov procesor Word Perfect 4.2, SPS
               VIDEOPRESS MON, Praha, 1.vyd., 1988, 64 s.

[MINIHOFER] MINIHOFER,O.-KRATOCHVLOV,J.: Anglicko-esk slov-
          nk vpoetn techniky, SNTL, Praha, 1.vyd., 1986, 496
         s.

[NORTON] NORTON,P.-STINSON,C.-KINGSBURY,B.: Assebly Languange
         database, Peter Norton Computing, Inc, (C) 1987

[PETERKA] PETERKA,J.: TPS, programov dokumentace, 1988, 100 s.

[RAICHL] RAICHL,J.: Programovn v Algolu, ACADEMIA, Praha,
         3.vyd., 1977, 236 s.

[TECHHELP] ROLLINS,D.: Tech HELP, Flamboux Software 1985,306 s.

[WICHMANN] WICHMANN,B.A.:Towards a Formal Specification of
          Floating Point, The Computer Journal, Vol. 32, 1989, 
         No. 5, 432 - 436 s.

[WIRTH]  WIRTH,N.: Systematick programovanie, ALFA a SNTL,
         Bratislava, 1.vyd., 1981, 208 s.

[YOUNG]  YOUNG,S.J.: Programovac jazyky pro RT-aplikace, SNTL,
         Praha, 1.vyd., 1989, 340 s.
Seznam peddefinovanch procedur a funkc

procedure NEW ( var P : pointer );                        
   (10)
function NEW ( <id. typu> ) : pointer;                    
   (11)
procedure DISPOSE ( var P : pointer );                    
   (11)
procedure MARK ( var P : pointer );                       
   (11)
procedure RELEASE ( var P : pointer );                    
   (12)
function MemAvail : longint;                              
   (13)
function MaxAvail : longint;                              
   (13)
procedure GetMem ( var p : pointer; Size : word );        
   (16)
procedure FreeMem ( var p : pointer; Size : word );       
   (16)
function SizeOf ( <promnn nebo typ> ) : word;           
   (17)
procedure Move ( var Source, Dest; Count : word );        
   (17)
procedure FillChar ( var x; Count : word; CH : char );    
   (18)
function Addr ( <promnn> ) : pointer;                   
   (20)
procedure New ( var P : pointer; <voln konstruktoru> ); 
   (41)
function New (<Id. typu>;<voln konstruktoru>):pointer;  
   (41)
procedure Dispose (var P:pointer; <voln destruktoru>);  
   (43)
function TypeOf ( var P : <objekt> ) : pointer;           
   (47)
procedure Fail;                                           
   (48)
procedure OvrInit ( FileName : string );                  
   (58)
procedure OvrInitEMS;                                     
   (58)
function OvrGetBuf : longint;                             
   (59)
procedure OvrSetBuf ( Size : longint );                   
   (59)
procedure OvrClearBuf;                                    
   (59)
procedure OvrSetRetry ( Size : longint );                 
   (60)
function OvrGetRetry : longint;                           
   (61)
function Random : real;                                   
   (68)
function Random ( var X : word ) : word;                  
   (68)
procedure Randomize;                                      
   (69)
function CSeg : word;                                     
   (73)
function DSeg : word;                                     
   (73)
function SSeg : word;                                     
   (73)
function SPtr : word;                                     
   (74)
function ParamCount : word;                               
   (76)
function ParamStr ( I : word ) : string;                  
   (76)
function DosVersion : word;                               
   (76)
procedure GetVerify ( var On : boolean );                 
   (76)
procedure SetVerify ( var On : boolean );                 
   (76)
procedure GetBreak ( var On : boolean );                  
   (77)
function EnvCount : integer;                              
   (77)
function EnvStr ( I : integer ) : string;                 
   (77)
function GetEnv ( DosVariable : string ) : string;        
   (77)
procedure Exec ( Proces, ParamLine : string );            
   (79)
function IOResult : integer;                              
   (80)
procedure RunError ( ErrorCode : word );                  
   (81)
procedure Halt ( ExitCode : word );                       
   (81)
procedure Keep ( ExitCode : word );                       
   (81)
function DosExitCode : word;                              
   (82)
procedure INTR ( IntNum : byte; var R : Registers );      
   (86)
procedure MSDOS ( var R : Registers );                    
   (87)
procedure SetIntVec ( IntNum:byte; EntryPoint:pointer );  
   (88)
procedure GetIntVec (IntNum:byte; var EntryPoint:pointer);
   (89)
procedure SwapVectors;                                    
   (89)
procedure InitGraph(var Driver,Mode:integer;Path:string); 
   (156)
procedure CloseGraph;                                     
   (157)
procedure GraphDefaults;                                  
   (159)
procedure ClearDevice;                                    
   (159)
function GetDriverName : string;                          
   (159)
procedure RestoreCrtMode;                                 
   (160)
procedure SetGraphMode ( Mode : integer );                
   (160)
procedure DetectGraph ( var GD:integer; var GM:integer ); 
   (161)
function GetGraphMode : integer;                          
   (161)
procedure GetModeRange ( GD:integer; var LM,HM:integer ); 
   (161)
function GetMaxMode : word;                               
   (161)
function GetModeName ( ModeNumber:word ) : string;        
   (162)
function GetMaxX : integer;                               
   (162)
function GetMaxY : integer;                               
   (162)
procedure GetAspectRatio ( var Xasp,Yasp : word );        
   (162)
procedure SetAspectRatio ( Xasp,Yasp : word );            
   (163)
function GraphResult : integer;                           
   (165)
function GraphErrorMsg (ErrorCode : integer) : string;    
   (165)
procedure SetViewPort (x1,y1,x2,y2:integer;Clip:boolean); 
   (166)
procedure GetViewSettings ( var ViewPort:ViewPortType );  
   (167)
procedure ClearViewPort;                                  
   (167)
procedure SetActivePage ( Page : word );                  
   (168)
procedure SetVisualPage ( Page : word );                  
   (168)
procedure GetDefaultPalette ( var Pal : PaletteType );    
   (174)
procedure GetPalette ( var Palette : PaletteType );       
   (175)
procedure SetAllPalette ( var Palette );                  
   (175)
procedure SetPalette ( ColorNum:word; Color:shortint );   
   (175)
procedure SetRGBPalette ( ColorNum,R,G,B : word );        
   (175)
function GetPaletteSize : word;                           
   (176)
function GetMaxColor : word;                              
   (176)
procedure SetColor ( Color : word );                      
   (176)
procedure SetBkColor ( Color : word );                    
   (176)
function GetColor : word;                                 
   (177)
function GetBkColor : word;                               
   (177)
procedure SetLineStyle(LineStyle,Pattern,Thickness:word); 
   (179)
procedure GetLineSettings (var LnInfo:LineSettingsType);  
   (179)
procedure SetFillStyle ( Pattern:word; Color:word );      
   (181)
procedure SetFillPattern (P:FillPatternType; Color:word); 
   (181)
procedure SetTextStyle ( Font,Direction,CharSize : word );
   (183)
procedure SetTextJustify ( Horiz, Vert : word );          
   (184)
procedure GetTextSettings ( var Info:TextSettingsType );  
   (185)
function TextHeight ( TextString : string ) : word;       
   (185)
function TextWidth ( TextString : string ) : word;        
   (185)
procedure SetUserCharSize ( MultX,DivX,MultY,DivY:word ); 
   (185)
function GetX : integer;                                  
   (189)
function GetY : integer;                                  
   (189)
procedure MoveTo ( X,Y : integer );                       
   (189)
procedure MoveRel ( Dx,Dy : integer );                    
   (189)
procedure SetWriteMode ( WriteMode : integer );           
   (190)
procedure Line ( x1,y1,x2,y2 : integer );                 
   (190)
procedure LineRel ( Dx,Dy : integer );                    
   (191)
procedure LineTo ( x,y : integer );                       
   (191)
procedure Rectangle ( x1,y1,x2,y2 : integer );            
   (192)
procedure Bar ( x1,y1,x2,y2 : integer );                  
   (192)
procedure Bar3D (x1,y1,x2,y2:integer;D:word;Top:boolean); 
   (193)
procedure DrawPoly ( NumPoints:word; var PolyPoints );    
   (194)
procedure FillPoly ( NumPoints:word; var PolyPoints );    
   (195)
procedure FloodFill ( x,y:integer; Border:word );         
   (195)
procedure Arc (x,y:integer;StAngle,EndAngle,Radius:word); 
   (196)
procedure PieSlice (x,y:integer;StAngle,EndAngle,R:word); 
   (197)
procedure Circle ( x,y:integer; Radius:word );            
   (198)
procedure Ellipse ( x,y:integer; StA,EndA,XR,YR:word );   
   (198)
procedure FillEllipse ( x,y:integer; XR,YR:word );        
   (198)
procedure Sector ( x,y:integer; StA,EndA,XR,YR:word );    
   (199)
procedure GetArcCoords ( var ArcCoords : ArcCoordsType ); 
   (199)
procedure OutText ( TextString : string );                
   (200)
procedure OutTextXY ( x,y:integer; TextString:string );   
   (200)
procedure PutPixel ( x,y:integer; Pixel:word );           
   (203)
function GetPixel ( x,y:integer ) : word;                 
   (203)
function ImageSize ( x1,y1,x2,y2:integer );               
   (204)
procedure GetImage ( x1,y1,x2,y2:integer; var BitMap );   
   (205)
procedure PutImage (x,y:integer; var BitMap;BitBlt:word); 
   (205)
procedure SetGraphBufSize ( BufSize : word );             
   (208)
function RegisterBGIfont ( font:pointer ) : integer;      
   (209)
function RegisterBGIdriver ( driver:pointer ) : integer;  
   (210)
function InstallUserDriver (N:string;DPtr:pointer):word;  
   (211)
function InstallUserFont (FontFileName:string ):integer;  
   (212)
Rejstk

.OBJ   53, 232
.OVR   54
.PAS   53
.TPL   53
.TPU   53
<blok>   49
<deklarace promnn>  94
<inline poloka>  96
<INLINE>   96
<P-blok>   98
<program>   49
<unit>   50
<uses>   49, 51
@@P   19
Absolute    94
Abstraktn datov struktury 
      9
ABSTRAKTN DATOV STRUKTURA 
      23
ADA   236
ADD  24
Addr  20
Adresa    19
ADS  23, 36, 49
dc klvesy  133
Aktivn strnka  153
Aktuln pozice  158
Aktuln strnka  126
Alarm  146
All   236
ALT   223
APPEND   77
Arc  196
Area    242
ASCII   221
Assert   239
ASSIGN  33, 112
AssignCrt  111, 222
AssignMem   105
AT&T 6300  156
B-stromy  32
BACKSPACE   222, 239
Backward   239
Bar  192
Bar3D  193
Barva okraje  171
Barva psma  171
Barva pozad  171
Barva vpln  171
Barva vzhledem k palet  170
Barvy  170
BCD   239
Bhov chyby  228
Binrn vyhledvac strom 
      31
                              BINRN STROM  30
                              BIOS   93, 111
                              BIOS a DOS data  93
                              Bitov mapa  33
                              Black  116
                              BLANK WHEN ZERO  239
                              Blink  118
                              Blue  116
                              Borland   232
                              BREAK    77
                              Brown  116
                              BufEnd  103
                              BUFFER  58
                              BufPos  103
                              BW40  114
                              BW40Hi  114
                              BW80  114
                              BW80Hi  114
                              C40  114
                              C80  114
                              rov typy psma  181
                              ry  178
                              asova  143
                              CGA  112, 155
                              CheckBreak   82
                              CheckEof  132
                              CheckSnow  124
                              Chybov hlen  163
                              Chyby    79, 225
                              Chyby v grafice  231
                              Circle  198
                              ClearDevice  159
                              ClearViewPort  167
                              CloseFunc   103
                              CloseGraph  157
                              ClrEol  121
                              ClrScr  121
                              CMOS   94, 144
                              CO40  114
                              CO40Hi  114
                              CO80  114
                              CO80Hi  114
                              Cobol   235
                              Code   73
                              COMMAND   78
                              COMP-3   239
                              Complex   234
                              CON  111
                              CONCAT   24
                              Constructor   40
                              Conversion   242
                              CR   221
                              CREATE  31
                              Crt   64
                              CSeg  73
                              CtrlBreak   230
                              Cyan  116
DarkGray  116
DATOV TYP  23
Datov abstrakce  9
DATOV STRUKTURA  23
Ddn   37
Delay  122
DELETE  24, 33
DelLine  121
Destructor   43
Destruktor     43
DetectGraph  161
DIFFERENCE  33
DirectVideo  124
DISPOSE  11, 43
Dos   64, 72, 80, 111, 225
DOS Errors  229
DosError   80, 228
DosExitCode   79, 82, 228
DosVersion  76
DrawPoly  194
DSeg  73
Dvousmrn spojov seznam 
      26
Dynamick pole  20
Dynamick alokace  9
Dynamick metody  41
EGA  112, 155
EGA64   156
Ellipse  198
EndFile    243
ENTER   222
EnvCount  77
EnvStr  77
EOF   222
EQUAL  33
Error    243
ErrorAddr   82
ESC   221
Esc-sekvence  142
Exception   242
Exec  79
EXIT   82
ExitCode   82
ExitProc   82
Extended Memory  95
External   98, 229
Fail  48
FileRec   102
FillChar  18
FillEllipse  198
Filler   235
FillPoly  195
FIND  33
FIRST   24
Flags   84
Float   234
FloodFill  195
FlushFunc   103
                              Font8x8  114
                              Fonty  183
                              FORMAT   239
                              Formtovn text  185
                              FRAGMENTACE   13
                              FreeMem  16
                              FreeMin   14
                              FreePtr   12, 13
                              Fronta   29
                              Garbage Collector  15
                              Genertor pseudonhodnch
                                        sel  68
                              GET   232
                              GetArcCoors  199
                              GetAspectRatio  162
                              GetBkColor  177
                              GetBreak  77
                              GetColor  177
                              GetDate  144
                              GetDefaultPalette  174
                              GetDriverName  159
                              GetEnv  77
                              GetGraphMode  161
                              GetImage  205
                              GetIntVec  89
                              GetLineSettings  179
                              GetMaxColor  176
                              GetMaxMode  161
                              GetMaxX  162
                              GetMaxY  162
                              GetMem  16
                              GetModeName  162
                              GetModeRange  161
                              GetPalette  175
                              GetPaletteSize  176
                              GetPixel  203
                              GetTextSettings  185
                              GetTime  144
                              GetVerify  76
                              GetViewSettings  167
                              GetX  189
                              GetY  189
                              GotoXY  120
                              Graph   64, 80, 225
                              Graph3   64
                              GraphDefaults  159
                              GraphErrorMsg  165, 231
                              GraphResult   80, 165, 231
                              Green  116
                              Halt  81, 91, 228
                              Hashing    33
                              HEAP    9, 75
                              HeapError   14, 242
                              HeapOrg   12, 74
                              HeapPtr   12
                              Hercules   156
                              HGC  112
                              Hierarchizace   37
HighVideo  119
Hlavn byte  133
Hnzdo     69
Hodiny  143
Horizontln zarovnn  182
I/O Errors  229
IBM - 8514  156
IBM 3270 PC  156
IIF   236
Image  202
ImageSize  204
Implementation    50
Implicit   235
In   238
INCLUDE   53
Info  24
InitGraph  156
Inline    96, 229
InOut   238
InOutFunc   103
InOutRes   80
Input  112
INSERT  24, 33
InsLine  121
InstallUserDriver  211
InstallUserFont  212
INT 10H  126
INT 16H/02H  136
INT 16H/05H  136
INT 16H/12H  137
INT 17H/02H  141
INT 1AH/06H  146
INT 1AH/07H  147
INT 1CH  145
INT 4AH  147
Interface    50
Interrupt   87
INTERSECTION  33
INTR  86
IOResult  80, 228, 243
IRQ   84
Kivky  196
Keep  81, 228
KeyPressed  132
Klvesnice  131
Knihovny   49
KOEN   30
Kolize  34
Kompatibilita videoadaptr 
      156
Kompilace    53
KONFORMN POLE  20
Konstruktor     40
Kruhov seznamy  28
KURZOR  24
Kurzorov seznam  28
LastMode  115
LEFTMOST_CHILD  30
                              LF   221
                              LightBlue  116
                              LightCyan  116
                              LightGray  116
                              LightGreen  116
                              LightMagenta  116
                              LightRed  116
                              Line  190
                              LineRel  191
                              LineTo  191
                              LOCATE  24
                              LOCK   102
                              Lokln bloky  242
                              LowVideo  119
                              LPT1  140
                              Lst  141
                              Magenta  116
                              MAKENULL   24, 31, 33
                              Mapovn   29
                              MARK  11
                              MAX  33
                              MaxAvail  13
                              MCGA   155
                              MEM    95
                              MemAvail  13
                              MEMBER  33
                              MEML   95
                              MEMW   95
                              MERGE  33
                              Metoda smench genertor 
                                        70
                              Metody   36
                              MIN  33
                              Mnoiny    33
                              Model   67
                              Mdy videa  160
                              Monitor  113
                              Mono  114
                              Move  17
                              MOVE CORRESPONDING  237
                              MoveRel  189
                              MoveTo  189
                              MSDOS  87
                              Name   238
                              Netypovan promnn  16
                              NEW  10, 11, 41
                              NEXT  24
                              Nezvisl posloupnosti  69
                              NormVideo  119
                              NoSound  139
                              O(f(N))  24
                              OBJEKT  36
                              Objektov orientovan progr-
                                        amovn  36
                              Obrazce  192
                              Obrazovka  112
                              Offset   234
                              Okno  122, 166
Okraj  171
OOP   36
OpenFunc   103
Optimalizace    100
Oteven Hashing  34
Out   238
Output  112
OutText  200
OutTextXY  200
Overflow     243
Overlay    57, 64, 79, 225,
      230
Ovlada  153
OvrClearBuf  59
OvrError   60
OvrFileMode   61
OvrGetBuf  59
OvrGetRetry  61
OvrHeapEnd   58, 74
OvrHeapOrg   58, 74
OvrHeapSize   58
OvrInit  58
OvrInitEMS  58
OvrLoadCount   61
OvrReadBuf   61
OvrReadFunc   61
OvrResult   59, 79, 230
OvrSetBuf  59
OvrSetRetry  60
OvrTrapCount   61
Own   235
PACK   233
PACKED   233
Petovn   237
Petypovn    18
PAGE   232
Paleta   170
ParamCount  76
Parametry grafiky  170
ParamStr  76
PARENT  30
PATH   77
PieSlice  197
Psmo vytven pomoc
      bitov mapy  181
Pomocn byte  133
PORT    95
PORTW   95
Pozad  171
Prefix  37
PrefixSeg   72
PREVIOUS  24
Printer   64, 65
PRINTLIST   24
PrintScreen   92
PRN  140
PROCES   78
Program    49
                              Programov balky  67
                              Pseudonhodn sla  68
                              PSP    72, 75
                              PUT   232
                              PutImage  205
                              PutPixel  203
                              Quick Pascal  232
                              Random  68
                              Randomize  69
                              ReadKey  132, 221, 222
                              Reln as  144
                              Rectangle  192
                              Red  116
                              Redefine   235
                              Redefinice   19
                              RegisterBGIdriver  210
                              RegisterBGIfont  209
                              Registers   83
                              Registry    83
                              REHASHING  34
                              RELEASE  12
                              Rename   235
                              Reproduktor  139
                              Reset   86
                              RestoreCrtMode  160
                              Rezidentn programy  90
                              RIGHT_SIBLING  30
                              ROOT   31
                              Rozsah barev  170
                              RunError  81, 228
                              SaveIntxx   89
                              Sector  199
                              SELF  36
                              SET    77
                              SetActivePage  168
                              SetAllPalette  175
                              SetAspectRatio  163
                              SetBkColor  176
                              SetColor  176
                              SetDate  144
                              SetFillPattern  181
                              SetFillStyle  181
                              SetGraphBufSize  208
                              SetGraphMode  160
                              SetIntVec  88
                              SetLineStyle  179
                              SetPalette  175
                              SetRGBPalette  175
                              SetTextJustify  184
                              SetTextStyle  183
                              SetTime  144
                              SetUserCharSize  185
                              SetVerify  76
                              SetViewPort  166
                              SetVisualPage  168
                              SetWriteMode  190
                              Seznam volnch oblast  12
                              Seznamy    24
SizeOf  17, 47
SLOVNK  33
Sluby   83
Sort   21, 22
Souadnicov systm  158
Sound  139
SPLIT   24
Spojov seznamy  25
SPtr  74
SSeg  73
Stavov promnn grafiky 
      188
STI   88, 97
Strnka  126
Strnky  168
Stromy    30, 35
SwapVectors   79, 89
Symbol   233
Sys-Reg   92
System   64, 75
Systmov as  144
Text   234
TextAttr  117
TextBackground  119
TextBuf   103
TextColor  118
TextHeight  185
TextMode  115
Textov atributy  116
Textov mdy  113
TextRec   103
TextWidth  185
Texty  200
Tiskrna  140
TPUMOVER   54
Turbo3   64
TypeOf  47
Underflow    243
UNION  33, 234
Unit   62, 97
UNPACK   233
Useky  189
USES    51
Uzaven Hashing  34
Value   235
Vektor peruen  84
Velikost palety  170
VER    76
VERIFY    76
Vertikln umstn  182
Verze 4.0  232
VGA  112, 156
Videoadaptr  112
Videomd  113, 152
Videopam  113, 152
Vpln  180
Virtual   39
Virtualizace   39
                              VMT  40, 46, 73, 75
                              Vnitn barva  170
                              WhereX  120
                              WhereY  120
                              White  116
                              WindMax  123
                              WindMin  123
                              Window  122
                              Write  201
                              Writeln   201
                              Yellow  116
                              Zsobnk   29
                              ZeroDivide   243
                              Znakov pole  113
                              Zobrazovan strnka  153
 
Poznmky
















     Autoi:        RNDr. Tom RUBA
                      RNDr. Jana VINOV
                            RNDr. Eva NOVKOV
                              RNDr. Tom EHK


     Nzev:         TURBO PASCAL 5.0 / 5.5, druh dl


     Vydavatel:     Systmov a programtorsk servis MON Praha


     Napsno:       Textovm procesorem WORDPERFECT 4.2,
                      na potai ACER 910






        Tato publikace neprola redakn ani jazykovou
                pravou v redakci nakladatele.



