home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
turbo4
/
graph.doc
< prev
next >
Wrap
Text File
|
1987-12-08
|
46KB
|
1,158 lines
======================================================================
HINWEIS HINWEIS HINWEIS HINWEIS HINWEIS HINWEIS HINWEIS
======================================================================
Der erste Teil dieser Datei enthält die Interface-Dokumentation des
Units GRAPH. Der zweite Teil enthält Korrekturen und Erweiterungen des
Referenzhandbuchs.
{*********************************************************}
{ }
{ Turbo Pascal Version 4.0 }
{ Interface-Dokumentation zu GRAPH }
{ }
{ Copyright (c) 1987 by Borland International, Inc. }
{ }
{*********************************************************}
{$D-,R-,S- keine Zusatzinformationen zur Fehlersuche,
keine Bereichsprüfung, keine Prüfung des Stacks }
unit Graph;
interface
const
{ Mögliche Ergebnisse von GraphResult: }
grOk = 0; { fehlerfreie Ausführung }
grNoInitGraph = -1; { Grafikpaket nicht initialisiert }
grNotDetected = -2; { kein grafikfähiger Adapter vorhanden
bzw. gewünschter Modus nicht setzbar }
grFileNotFound = -3; { Grafik-Treiber (*.BGI) nicht gefunden }
grInvalidDriver = -4; { Grafik-Treiberdatei defekt/ungültig }
grNoLoadMem = -5; { nicht genug Platz im Speicher für Treiber }
grNoScanMem = -6; { nicht genug Speicherplatz für FillPoly }
grNoFloodMem = -7; { nicht genug Speicherplatz für FloodFill }
grFontNotFound = -8; { Zeichensatz-Datei (*.CHR) nicht gefunden }
grNoFontMem = -9; { nicht genug Speicherplatz für Zeichensatz }
grInvalidMode = -10; { Grafikmodus vom Treiber nicht unterstützt }
grError = -11; { *** ungültiger Parameter beim *** }
{ *** Aufruf einer Grafik-Routine *** }
grIOerror = -12; { I/O-Fehler beim Laden einer .BGI- oder
.CHR-Datei }
grInvalidFont = -13; { Grafik-Zeichensatzdatei zerstört/ungültig }
grInvalidFontNum = -14; { Zeichensatz-Nummer unbekannt }
grInvalidDeviceNum = -15; { Gerätenummer unbekannt / ungültig }
{ Grafik-Treiberprogramme }
Detect = 0; { automatische Erkennung }
CGA = 1;
MCGA = 2; { PS/2, Modell 30 }
EGA = 3;
EGA64 = 4;
EGAMono = 5;
RESERVED = 6;
HercMono = 7;
ATT400 = 8;
VGA = 9;
PC3270 = 10;
{ Mögliche Grafikmodi der einzelnen Treiber }
CGAC0 = 0; { 320x200 Palette 0: Hellgrün, Hellrot, Gelb; 1 Seite }
CGAC1 = 1; { 320x200 Palette 1: Helltürkis, Hell-Magenta, Weiß }
CGAC2 = 2; { 320x200 Palette 2: Grün, Rot, Braun }
CGAC3 = 3; { 320x200 Palette 3: Türkis, Magenta, Hellgrau }
CGAHi = 4; { 640x200 S/W; 1 Seite }
MCGAC0 = 0; { 320x200 Palette 0: Hellgrün, Hellrot, Gelb; 1 Seite }
MCGAC1 = 1; { 320x200 Palette 1: Helltürkis, Hell-Magenta, Weiß }
MCGAC2 = 2; { 320x200 Palette 2: Grün, Rot, Braun }
MCGAC3 = 3; { 320x200 Palette 3: Türkis, Magenta, Hellgrau }
MCGAMed = 4; { 640x200 S/W; 1 Seite }
MCGAHi = 5; { 640x480 S/W; 1 Seite }
EGALo = 0; { 640x200 16 Farben, 4 Seiten }
EGAHi = 1; { 640x350 16 Farben, 2 Seiten }
EGA64Lo = 0; { 640x200 16 Farben, 1 Seite }
EGA64Hi = 1; { 640x350 4 Farben, 1 Seite }
EGAMonoHi = 3; { 640x350 S/W; 1 Seite mit 64K, 4 Seiten mit 256 K }
HercMonoHi = 0; { 720x348 S/W, 2 Seiten }
ATT400C0 = 0; { 320x200 Palette 0: Hellgrün, Hellrot, Gelb; 1 Seite }
ATT400C1 = 1; { 320x200 Palette 1: Helltürkis, Hell-Magenta, Weiß }
ATT400C2 = 2; { 320x200 Palette 2: Grün, Rot, Braun }
ATT400C3 = 3; { 320x200 Palette 3: Türkis, Magenta, Hellgrau }
ATT400Med = 4; { 640x200 S/W; 1 Seite }
ATT400Hi = 5; { 640x480 S/W; 1 Seite }
VGALo = 0; { 640x200 16 Farben, 4 Seiten }
VGAMed = 1; { 640x350 16 Farben, 2 Seiten }
VGAHi = 2; { 640x480 16 Farben, 1 Seite }
PC3270Hi = 0; { 720x350 1 Seite }
{ Zeichenfarben }
Black = 0; { Schwarz }
Blue = 1; { Blau }
Green = 2; { Grün }
Cyan = 3; { Türkis }
Red = 4; { Rot }
Magenta = 5; { Magentarot }
Brown = 6; { Braun }
LightGray = 7; { Hellgrau }
DarkGray = 8; { Dunkelgrau }
LightBlue = 9; { Hellblau }
LightGreen = 10; { Hellgrün }
LightCyan = 11; { helles Türkis }
LightRed = 12; { Hellrot }
LightMagenta = 13; { helles Magentarot }
Yellow = 14; { Gelb }
White = 15; { Weiß }
{ Linienarten -und breiten für Get/SetLineStyle }
SolidLn = 0; { durchgezogen }
DottedLn = 1; { gepunktet }
CenterLn = 2; { Strich Punkt Strich }
DashedLn = 3; { gestrichelt }
UserBitLn = 4; { benutzerdefiniert (mit "Pattern" bei SetLineStyle) }
NormWidth = 1; { normale Breite (1 Pixel) }
ThickWidth = 3; { drei Pixel }
{ Set/GetTextStyle }
DefaultFont = 0; { 8x8 Bit pixelweise definiert }
TriplexFont = 1; { Vektor-Zeichensätze }
SmallFont = 2;
SansSerifFont = 3;
GothicFont = 4;
HorizDir = 0; { von links nach rechts }
VertDir = 1; { von unten nach oben }
UserCharSize = 0; { benutzerdefinierte Zeichengröße }
{ Für das Abschneiden von Linien ("clipping") }
ClipOn = True;
ClipOff = False;
{ Für Bar3D }
TopOn = True; { "Deckel" wird gezeichnet }
TopOff = False; { wird nicht gezeichnet }
{ Füll-Muster für Get/SetFillStyle: }
EmptyFill = 0; { Füllen mit der Hintergrundfarbe }
SolidFill = 1; { Füllen mit der Zeichenfarbe }
LineFill = 2; { --- }
LtSlashFill = 3; { /// }
SlashFill = 4; { /// mit dicken Linien }
BkSlashFill = 5; { \\\ mit dicken Linien }
LtBkSlashFill = 6; { \\\ }
HatchFill = 7; { leicht schraffiert }
XHatchFill = 8; { stark schraffiert, überkreuzend }
InterleaveFill = 9; { abwechselnde Linien }
WideDotFill = 10; { weit auseinanderstehende Punkte }
CloseDotFill = 11; { dicht beieinanderstehende Punkte }
UserFill = 12; { benutzerdefiniert }
{ BitBlt ("Bit Block Transfer") - Möglichkeiten für PutImage }
NormalPut = 0; { MOV }
XORPut = 1; { XOR }
OrPut = 2; { OR }
AndPut = 3; { AND }
NotPut = 4; { NOT }
{ Horizontale / vertikale Justierung mit SetTextJustify }
LeftText = 0; { linksbündig }
CenterText = 1; { zentriert }
RightText = 2; { rechtsbündig }
BottomText = 0; { unten abschließend }
{ CenterText = 1; bereits definiert }
TopText = 2; { oben abschließend }
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 { vordefiniertes Füll-Muster }
Pattern : Word;
Color : Word;
end;
FillPatternType = array[1..8] of Byte; { benutzerdefiniertes Füll-Muster }
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; { zeigt auf GraphGetMem und kann auf eine
eigene Routine gesetzt werden }
GraphFreeMemPtr : Pointer; { zeigt auf GraphFreeMem }
{ ------------------- Routinen ---------------------- }
{ *** Fehlerbehandlung *** }
function GraphErrorMsg(ErrorCode : Integer) : String;
function GraphResult : Integer;
{ *** Prüfung der Hardware, Initialisierung und Setzen der Grafikmodi *** }
procedure DetectGraph(var GraphDriver, GraphMode : Integer);
procedure InitGraph(var GraphDriver : Integer;
var GraphMode : Integer;
PathToDriver : String);
function RegisterBGIFont(font : Pointer) : Integer;
function RegisterBGIDriver(driver : Pointer) : Integer;
procedure SetGraphBufSize(BufSize : Word);
procedure GetModeRange(GraphDriver : Integer; var LoMode, HiMode : Integer);
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;
{ *** Bildschirm, Zeichenfenster und Speicherseiten *** }
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);
{ *** Einzelne Pixel und pixelweise definierte Bildausschnitte *** }
procedure PutPixel(X, Y : Integer; Pixel : Word);
function GetPixel(X, Y : Integer) : Word;
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);
{ *** Linien *** }
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, Pattern, Thickness : Word);
{ *** Polygone, Flächenfüllung und grafische Objekte *** }
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);
{ *** Kreise, Kreisauschnitte und andere Kurven *** }
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 GetAspectRatio(var Xasp, Yasp : Word);
procedure PieSlice(X, Y : Integer; StAngle, EndAngle, Radius : Word);
{ *** Farben und Farb-Paletten *** }
procedure SetBkColor(Color : 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 GetMaxColor : Word;
{ *** Textausgabe *** }
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;
implementation
======================================================================
KORREKTUREN UND ERWEITERUNGEN
======================================================================
Die Veränderungen im Unit GRAPH, die sich nach der Drucklegung des
Handbuchs ergeben haben, lassen sich in drei Kategorien einteilen:
1. Änderung der Parametertypen. Aus Gründen der Einheitlichkeit sind
*alle* formalen Parameter nach dem folgenden Schema typisiert:
o Alle Koordinaten haben den Typ Integer - auch dann, wenn sie im
Handbuch teilweise als Word ausgewiesen sind.
o Alle Fehlercodes des Grafikpakets haben negative Werte und werden
als Integer zurückgeliefert (wie auch im Handbuch beschrieben).
o Variablen für Grafiktreiber-Nummern und Grafikmodi (in den
Beispielprogrammen durchgehend als GraphDriver, GraphMode dekla-
riert) haben den Typ Integer, weil sie auch für das Zurückliefern
von Fehlercodes benutzt werden.
o Andere numerische Parameter sind vorzeichenlose (Word oder Byte).
Hinweis: Sowohl das Interface-Listing im ersten Teil dieser Datei
als auch die eingebaute Syntax-Hilfestellung des Editors (Ctrl-F1)
sind auf dem neuesten Stand, d.h. geben die tatsächlich verwendeten
Parametertypen wieder.
2. Neue Prozeduren und Funktionen:
o GetFillPattern - liefert das mit dem letzten Aufruf von
SetFillPattern gesetzte Füll-Muster zurück.
o GetMaxColor - liefert die höchste für den momentanen Treiber und
Modus verfügbare Zeichenfarbe zurück.
o GetModeRange - ermittelt, welche Grafikmodi für den momentan
verwendeten Treiber zulässig sind.
o GraphDefaults - setzt alle Parameter des Grafikpakets auf ihre
Standardwerte zurück (die Prozedur ClearDevice erfüllt diese
Funktion nicht mehr).
o RegisterBGIDriver - erlaubt die Verwendung von Grafik-Treibern,
die direkt mit {$L} in ein Programm aufgenommen wurden.
o RegisterBGIFont - erlaubt die Verwendung von Grafik-Zeichensätzen,
die direkt mit {$L} in ein Programm aufgenommen wurden.
o SetGraphBufSize - verändert die Größe des Puffers, der für
Flächenfüllungen verwendet wird.
o SetUserCharSize - ermöglicht die Skalierung von Zeichensätzen
in X- und Y-Richtung.
3. Korrekturen und Erweiterungen bereits beschriebener Routinen und
allgemeiner Konzept des Grafikpakets.
==========================================
Änderungen und Erweiterungen zu Kapitel 23
==========================================
Grafik-Cursor
-------------
Die Position des Grafik-Cursors wird durch Aufrufe der folgenden
Routinen verändert:
InitGraph SetGraphMode setzen den GC auf (0,0) (relativ zum
ClearDevice GraphDefaults momentan definierten Zeichenfenster,
ClearViewPort SetViewPort soweit vorhanden)
MoveTo MoveRel LineTo setzen den GC auf den angegebenen
LineRel OutText Punkt bzw. auf den Punkt, auf dem das
letzte Pixel gezeichnet wurde
Grafik-Treiber und Grafik-Zeichensätze
--------------------------------------
Grafik-Treiber können nicht nur über InitGraph zur Laufzeit des
Programms von der Diskette geladen werden - sie lassen sich auch
bei der Compilierung als .OBJ-Datei einbinden, mit der neuen
Funktion RegisterBGIDriver "registrieren" und direkt starten.
Entsprechendes gilt für Grafik-Zeichensätze, die entweder über
SetTextStyle zur Laufzeit des Programms geladen oder als .OBJ-Datei
eingebunden, mit der neuen Funktion RegisterBGIFont "registriert"
und zur Laufzeit des Programms nur noch aufgerufen werden.
Grafiktreiber für den TOSHIBA 3100
----------------------------------
Der Toshiba 3100 unterstützt einen Grafikmodus mit 640*400 Pixeln,
der zum entsprechenden Modus des AT&T kompatibel ist - lediglich
die Aktivierung dieses Modus über den Interrupt $10 funktioniert
etwas anders. Um diesen Grafikmodus auf einem Toshiba 3100 zu
verwenden, sind zwei Schritte notwendig:
1) Ein 1-Byte-Patch des Grafiktreibers ATT.BGI. Mit den folgenden
Befehlen wird das $655.Byte dieses Treibers von $40 auf den
Wert $74 umgeändert und danach wieder gespeichert:
Auf der Kommandoebene von DOS geben Sie den Befehl
DEBUG ATT.BGI
Dadurch wird das Programm DEBUG aufgerufen und lädt ATT.BGI
in den Speicher.
Hinweis: ATT.BGI muß sich im momentan gesetzten Directory
befinden.
Innerhalb von DEBUG geben Sie die folgenden Befehle:
E655 <RETURN> - ("Enter" 655)
74 <RETURN> - (neuer Wert)
W <RETURN> - (Zurückschreiben der Datei)
Q <RETURN> - (Beenden von DEBUG)
ACHTUNG: Dieser modifizierte Treiber kann nicht mehr auf
einem AT&T-Computer verwendet werden!
2) Innerhalb von Grafikprogrammen müssen Sie den Treiber explizit
setzen, also beispielsweise
program ToshibaDemo;
var
GraphDriver, GraphMode: Integer;
...
begin
GraphDriver := ATT400; GraphMode := ATT400C0;
InitGraph(GraphDriver, GraphMode, '');
...
Automatische Erkennung des Grafik-Adapters
------------------------------------------
Es hat sich gezeigt, daß das von IBM vorgeschlagene Schema zur
automatischen Erkennung von Grafik-Adaptern nicht immer korrekt
arbeitet: Auf dem PCJr identifiziert sich der Grafik-Adapter in
einigen Fällen als Nummer 6 (= RESERVED). Wenn Sie mit einem PCJr
arbeiten, sollten Sie deshalb die folgenden Anweisungen zur
Initialisierung des Grafikpakets verwenden:
uses Graph;
var
GraphDriver, GraphMode : Integer;
begin
...
GraphDriver := CGA; { PCjr emuliert CGA-Karte }
GraphMode := CGAC1; { Hier geben Sie den gewünschten Modus an }
InitGraph(GraphDriver, GraphMode, '');
...
end.
Ähnliche Probleme treten auf dem Modell 8514 bei Verwendung des
speicherresidenten Grafik-Treibers von IBM auf, der sich ebenfalls
als Nummer 6 (RESERVED) identifiziert. Hier sollten Sie die auto-
matische Erkennung grundsätzlich mit den folgenden Anweisungen
außer Kraft setzen:
uses Graph;
var
GraphDriver, GraphMode : Integer;
begin
...
GraphDriver := VGA; { IBM 8514 emuliert VGA-Karte }
GraphMode := VGAHi; { Hier geben Sie den
gewünschten Modus an }
InitGraph(GraphDriver, GraphMode, '');
...
end.
Solange Sie den speicherresidenten Treiber von IBM nicht verwenden,
funktioniert die automatische Erkennung zuverlässig, d.h. InitGraph
benutzt den VGA-Treiber.
Dynamische Belegung des Speichers
---------------------------------
Graph belegt Teile des Heap für drei Puffer, nämlich:
o Einen Allzweck-Puffer, dessen Größe mit SetGraphBufSize fest-
gelegt werden kann (Standard: 4 KByte). Dieser Puffer wird beim
Aufruf von InitGraph immer belegt.
o Den aktiven Grafik-Treiber, solange er als .BGI-Datei über
InitGraph geladen wird.
o Den aktiven Vektor-Zeichensatz, solange er als .CHR-Datei über
SetTextStyle geladen wird.
Der Initialisierungsteil des Units Graph installiert eine Routine
zur Behandlung von Fehlern bei der dynamischen Speicher-
verwaltung, d.h. verändert den Zeiger HeapError. Diese Routine
arbeitet genauso wie die in Kapitel 25 beschriebene "benutzer-
definierte" Routine: Wenn ein Programm das Unit Graph aufnimmt,
liefern Aufrufe von New und GetMem den Zeigerwert nil zurück,
falls nicht genügend Speicherplatz auf dem Heap vorhanden ist.
(Wenn Graph nicht mit uses aufgenommen und keine eigene Routine
über HeapError installiert wurde, bricht das Programm mit einem
Laufzeitfehler ab, falls New oder GetMem eine Belegung nicht
ausführen können).
Interface-Listing von GRAPH
---------------------------
Hier haben sich seit der Drucklegung des Handbuchs einige Ände-
rungen ergeben. Bitte verwenden Sie die Interface-Dokumentation
aus dem ersten Teil dieser Datei.
VGA-Grafikmodi
--------------
Das Unit Graph unterstützt drei Grafikmodi für VGA-Karten:
VGALo, VGAMed und VGAHi. VGA-Karten können darüber hinaus
dem MCGA-Modus mit 640*480 Pixel, 2 Farben und 2 Speicherseiten
emulieren. Das folgende Beispiel demonstriert, wie sich dieser
Modus setzen läßt:
uses Graph;
var
GraphDriver, GraphMode, Err : Integer;
begin
GraphDriver := MCGA; { explizit: MCGA-Treiber }
GraphMode := MCGAHi; { explizit: Modus MCGAHi }
InitGraph(GraphDriver, GraphMode, '');
if GraphResult < 0 then Halt(1);
OutText('MCGA-Modus (640x480) auf VGA');
Readln;
CloseGraph;
end.
Änderungen und Erweiterungen zum Referenzteil (Kapitel 26)
==========================================================
Bar, Bar3D
----------
Fehler während des Ausfüllens der Fläche können nicht auftreten,
GraphResult bleibt von Bar und Bar3D unbeeinflußt.
Ein Tip: Bar zeichnet keinen Umriß des Balkens - um einen Umriß
in der momentanen Linienart und -farbe zu erhalten, können Sie
Bar3D mit Depth = 0 verwenden.
ClearDevice
-----------
ClearDevice löscht den gesamten Bildschirm und setzt den
Grafik-Cursor auf den Punkt (0,0) innerhalb des momentan
gesetzten Zeichenfensters. Entgegen der Angabe im Handbuch
werden die Parameter des Grafikpakets nicht zurückgesetzt -
dazu dient die neue Prozedur GraphDefaults.
CloseGraph
----------
CloseGraph entfernt Grafik-Treiber und Zeichensätze nur dann aus
dem Hauptspeicher, wenn sie als separate Dateien (.BGI und .CHR)
geladen wurden. Mit RegisterBGIDriver und RegisterBGIFont
"registrierte" Treiber und Zeichensätze, die Teil der .EXE-Datei
sind, befinden sich im entsprechenden Code-Segment (d.h. nicht
auf dem Heap) und werden folglich auch nicht entfernt.
DrawPoly
--------
GraphResult wird durch das Zeichnen von Polygonen mit DrawPoly
nicht beeinflußt.
FillPoly
--------
Im Gegensatz zu DrawPoly muß der erste und letzte Punkt nicht
doppelt angegeben werden, die sechste Angabe für die Konstante
Pentagon im Beispielprogramm ist also unnötig. FillPoly zeichnet
zuerst den Umriß des Polygons - wenn Sie zuvor die Hintergrund-
farbe als Zeichenfarbe setzen, bleibt dieser Umriß unsichtbar.
FloodFill
---------
Da die Parametertypen der Grafikfunktionen vereinheitlicht
wurden, haben die Parameter X und Y den Typ Integer. Die korrekte
Deklaration von Floodfill ist:
procedure FloodFill(X, Y : Integer; Border : Word);
Bitte beachten Sie, daß FloodFill die Flächenfüllung nach der
aufeinanderfolgenden Ausgabe zweier komplett leerer Linien
beendet. Bei kleinen Flächen und einem Füll-Muster, das nur
wenige gesetzte Bits enthält, wird die Fläche nicht immer
komplett gefüllt. Ein Beispiel:
program StopFill;
uses Graph;
var
GraphDriver, GraphMode : Integer;
begin
GraphDriver := Detect;
InitGraph(GraphDriver, GraphMode, '');
if GraphResult <> grOk then Halt(1);
SetFillStyle(LtSlashFill, GetMaxColor);
Rectangle(0, 0, 8, 20);
FloodFill(1, 1, GetMaxColor); { wird nicht ganz ausgefüllt }
Readln;
CloseGraph;
end.
Bei der Verwendung eines dichteren Musters (z.B. SlashFill) tritt
diese Unregelmäßigkeit nicht auf.
Der Querverweis für FloodFill sollte SetFillStyle und
SetFillPattern auflisten (anstelle der nicht existierenden
Prozedur SetFloodPattern).
GetArcCoords
------------
Der Typ ArcCoordsType ist inkorrekt wiedergegeben. Die korrekte
Deklaration ist:
type
ArcCoordsType = record
X, Y,
Xstart, Ystart, { nicht: Xs, Ys }
Xend, Yend : Integer; { nicht: Word }
end;
GetFillPattern [ Neue Prozedur ]
--------------
procedure GetFillPattern(var FillPattern : FillPatternType);
Liefert das Bitmuster zurück, das mit dem letzten vorhergehenden
Aufruf von SetFillPattern gesetzt wurde. Der Typ FillPatternType
ist im Unit GRAPH folgendermaßen definiert:
type
FillPatternType = array[1..8] of Byte;
Falls SetFillPattern seit dem Start des Grafikpakets noch nicht
aufgerufen wurde, liefert GetFillPattern ein mit dem Wert $FF
gefülltes Array zurück.
GetGraphMode
------------
Die angegebene Liste der möglichen Ergebnisse wurde erweitert
(siehe Interface-Dokumentation im ersten Teil dieser Datei).
GetImage
--------
Da die Parametertypen der Grafikfunktionen vereinheitlicht
wurden, haben die Parameter x1, y1, x2 und y2 den Typ Integer.
Die korrekte Deklaration ist:
procedure GetImage(x1, y1, x2, y2 : Integer; var BitMap);
GetMaxColor [ Neue Funktion ]
-----------
function GetMaxColor : Word;
Liefert die Nummer der "höchsten" Zeichenfarbe zurück, der
geladene Treiber im momentan gesetzten Grafikmodus unterstützt.
Bei Verwendung einer EGA-Karte mit 256 KByte Speicher liefert
GetMaxColor beispiels- weise immer das Ergebnis 15 - SetColor
kann hier also mit beliebigen Werten im Bereich von 0..15
aufgerufen werden.
Für eine CGA-Karte im Modus "hohe Auflösung" oder eine Hercules-
Karte ist das Ergebnis von GetMaxColor der Wert 1 (in beiden
Fällen können mit SetColor nur die "Farben" 0 und 1 gesetzt
werden).
GetMaxX, GetMaxY
----------------
Da die Parametertypen der Grafikfunktionen vereinheitlicht
wurden, haben GetMaxX und GetMaxY den Ergebnistyp Integer. Die
korrekten Deklarationen sind:
function GetMaxX : Integer;
function GetMaxY : Integer;
GetModeRange [ Neue Prozedur ]
------------
procedure GetModeRange(GraphDriver: Integer;
var LoMode, HiMode: Integer);
Ermittelt den niedrigsten (LoMode) und den höchsten (HiMode)
Grafikmodus, der für den als GraphDriver angegebenen Grafik-
Treiber verwendbar ist. Ein Beispiel:
uses Graph;
var
Lowest, Highest : Integer;
begin
GetModeRange(EGA64, Lowest, Highest);
Write('Niedrigster Grafikmodus: ', Lowest); { 0 }
Write('Höchster Modus: ', Highest); { 1 }
end.
Mögliche Werte für GraphDriver gehen von 1..5 und von 7..10.
Werte außerhalb dieser Bereiche setzen die als LoMode und HiMode
übergebenen Variablen auf -1.
GetViewSettings
---------------
Da die Parametertypen der Grafikfunktionen vereinheitlicht
wurden, haben die Felder x1, y1, x2 und y2 des Record-Typs
ViewPortType den Typ Integer. Die korrekte Definition von
ViewPortType ist:
ViewPortType = record
x1, y1, x2, y2 : Integer;
Clip : Boolean;
end;
GraphDefaults [ Neue Prozedur ]
-------------
procedure GraphDefaults;
Setzt den Grafik-Cursor auf die (Bildschirm-)Koordinaten (0,0)
und die folgenden Parameter des Grafikpakets auf ihre Standard-
werte zurück:
o Zeichenfenster (gesamter Bildschirm)
o Farb-Palette
o Zeichenfarbe (höchste Farbnummer), Hintergrundfarbe (0)
o Linienart (durchgezogen) und -breite (normal, d.h. 1 Pixel)
o Füll-Muster (Solid), Farbe (höchste Farbnummer), benutzer-
definiertes Füll-Muster ($FF $FF ... )
o Zeichensatz (8*8), Textrichtung (horizontal), Justierung
(Linksbündig), UserCharSize (0)
GraphResult
-----------
GraphResult bleibt von Bar, Bar3D und DrawPoly unbeeinflußt. Der
Aufruf einer der folgenden Routinen mit unzulässigen Parametern
läßt die entsprechenden Werte des Grafikpakets unverändert und
erzeugt den Fehlerstatus -11:
SetAllPalette SetFillPattern SetFillStyle SetLineStyle
SetPalette SetTextJustify SetTextStyle SetViewPort
GraphResult wird durch die folgenden Routinen gesetzt:
DetectGraph, FillPoly, FloodFill, ImageSize, InitGraph,
PieSlice, RegisterBGIDriver, RegisterBGIFont, SetAllPalette,
SetFillPattern, SetFillStyle, SetGraphBufSize, SetGraphMode,
SetLineStyle, SetPalette, SetTextJustify, SetTextStyle,
SetViewPort
Die möglichen Ergebnisse von GraphResult wurden um Werte im
Bereich von -11..-15 erweitert. Eine vollständige Liste finden
Sie in der Interface-Dokumentation im ersten Teil dieser Datei.
ImageSize
---------
Da die Parametertypen der Grafikfunktionen vereinheitlicht
wurden, haben x1, y1, x2 und y2 den Typ Integer. Die korrekte
Definition von ImageSize ist:
function ImageSize(x1, y1, x2, y2 : Integer) : Word;
InitGraph
---------
Zu den angegebenen Fehlercodes kommen die Möglichkeiten -10
(Grafikmodus wird vom geladenen Treiber nicht unterstützt) und
-15 (ungültige Gerätenummer) hinzu.
OutText, OutTextXY
------------------
Die Position des Grafik-Cursors wird von OutText nur dann
verändert, wenn die Ausgabe in horizontaler Richtung (d.h. nach
dem Aufruf SetTextStyle (..., HorizDir, ...)) erfolgt und mit
linksbündiger oder rechtsbündiger Justierung (SetTextJustify)
gearbeitet wird. Ausgaben in vertikaler Richtung und/oder
mittenzentrierter Justierung ändern die Position des
Grafik-Cursors nicht! Ein Beispiel:
program CPupdate;
uses Graph;
var
GraphDriver, GraphMode : Integer;
begin
GraphDriver := Detect;
InitGraph(GraphDriver, GraphMode, '');
if GraphResult < 0 then Halt(1);
MoveTo(0, 0);
SetTextStyle(DefaultFont, HorizDir, 1); { Zeichengröße 1 }
SetTextJustify(LeftText, TopText);
OutText('ABC'); { verändert den GC }
OutText('DEF'); { verändert den GC }
MoveTo(100, 50);
SetTextStyle(DefaultFont, HorizDir, 1); { Zeichengröße 1}
SetTextJustify(RightText, TopText);
OutText('ABC'); { verändert den GC }
OutText('DEF'); { verändert den GC }
MoveTo(100, 100);
SetTextStyle(DefaultFont, VertDir, 1); { Zeichengröße 1 }
SetTextJustify(LeftText, TopText);
OutText('ABC'); { verändert den GC NICHT }
OutText('DEF'); { überschreibt 'ABC ' }
Readln;
CloseGraph;
end.
Aufrufe von OutTextXY lassen die Position des GC immer
unverändert - egal, in welcher Richtung und mit welcher
Justierung sie erfolgen.
Mit dem Standard-Zeichensatz (8x8) geschriebene Ausgaben werden
bei Überschreitung der Fenster- bzw. Bildschirmgrenzen nicht
abgeschnitten - stattdessen unterdrücken OutText und OutTextXY
die Ausgabe vollständig, wenn der Text nicht auf den Bildschirm
passen würde. Die folgenden Beispiele führen deshalb überhaupt
keine Ausgaben aus:
SetViewPort(0, 0, GetMaxX, GetMaxY, ClipOn);
SetTextJustify(LeftText, TopText);
OutTextXY(-5, 0); { -5,0 ist außerhalb des Schirms }
OutTextXY(GetMaxX - 1, 0, 'ABC'); { ein Teil von 'A' sowie 'BC'
wäre außerhalb des Schirms }
Ausgaben mit den Vektor-Zeichensätzen werden dagegen am Rand des
Bildschirms bzw. Zeichenfensters abgeschnitten, eine Unter-
drückung findet hier nicht statt.
PutImage
--------
Ein mit PutImage kopierter Bildausschnitt wird nicht abge-
schnitten, wenn er die Grenzen des Zeichenfensters oder des
Bildschirms in horizontaler Richtung überschreitet oder der
Startpunkt außerhalb des Bildschirms liegt - PutImage führt in
diesen Fällen überhaupt keine Operationen aus. Die mittleren drei
Aufrufe von PutImage im folgenden Beispiel haben deshalb keine
sichtbare Wirkung:
program NoClip;
uses graph;
var
GraphDriver, GraphMode : Integer;
p : Pointer;
begin
GraphDriver := Detect;
InitGraph(GraphDriver, GraphMode, '');
if GraphResult < 0 then Halt(1);
SetViewPort(0, 0, GetMaxX, GetMaxY, Clipon);
GetMem(p, ImageSize(0, 0, 99, 49)); { 100 * 50 Pixel }
PieSlice(50, 25, 0, 360, 45);
GetImage(0, 0, 99, 49, p^);
ClearDevice;
PutImage(GetMaxX - 99, 0, p^, NormalPut); { paßt gerade noch ... }
PutImage(GetMaxX - 98, 0, { X + Höhe > GetMaxX }
p^, NormalPut);
PutImage(-1, 0, { -1,0 ist nicht auf dem Schirm }
p^, NormalPut);
PutImage(0, -1, { 0,-1 ebenfalls nicht }
p^, NormalPut);
PutImage(0, GetMaxY - 30, { gibt 31 "Zeilen" des Bildes aus }
p^, NormalPut);
Readln;
CloseGraph;
end.
Im fünften Aufruf dieses Beispiels liegt der Startpunkt inner-
halb des Bildschirms, eine Überschreitung der Fenstergrenzen in
horizontaler Richtung findet nicht statt. Dieser Fall ist der
einzige, in dem PutImage ein "abgeschnittenes" Bild zeichnet.
RegisterBGIDriver, RegisterBGIFont [ Neue Funktionen ]
----------------------------------
function RegisterBGIDriver(driver : Pointer) : Integer;
function RegisterBGIFont(font : Pointer) : Integer;
Normalerweise belegt GRAPH für einen Treiber (beim Aufruf von
InitGraph) und für einen der Vektor-Zeichensätze (beim Aufruf von
SetTextStyle) Speicherplatz auf dem Heap. Beim Wechsel des
Zeichensatzes wird der entsprechende Platz freigegeben, ein neuer
Block belegt und die entsprechende .CHR-Datei von der Diskette
geladen. Über RegisterBGIDriver und RegisterBGIFont lassen sich
Grafik-Treiber und Zeichensätze "registrieren" - sie bleiben dann
im Speicher und müssen bei einem erneuten Wechsel nicht erst
wieder von der Diskette geladen werden. Dieses Verfahren kostet
mehr Platz im Hauptspeicher, bietet aber zwei Vorteile:
- Ein Wechsel zwischen Zeichensätzen und/oder Treibern geschieht
ohne Diskettenzugriffe.
- Nach einer Konvertierung über BINOBJ lassen sich Treiber und
Zeichensätze direkt in das Programm aufnehmen.
GRAPH speichert Zeichensätze und Treiber, die zur Laufzeit des
Programms von der Diskette geladen werden, auch nach einer
"Registrierung" auf dem Heap; mit BINOBJ konvertierte .BGI- und
.CHR-Dateien, die über {$L} in ein Programm aufgenommen wurden,
befinden sich dagegen im Code-Segment des jeweiligen Moduls.
Bei fehlerfreier Ausführung ist das Funktionsergebnis von
RegisterBGIDriver und RegisterBGIFont die interne Nummer des
Treibers bzw. Zeichensatzes, negative Werte zeigen einen Fehler
an:
Code Bezeichner Erläuterung
---- ---------- -----------
-4 grInvalidDriver Die Kopfinformationen der .BGI-Datei sind
nicht auswertbar bzw. ungültig (d.h. die
Datei ist aus irgendeinem Grund nicht in
Ordnung).
-11 grError Kein weiterer Platz in der Zeichensatz-
tabelle zur "Registrierung". (Die
Tabelle speichert maximal 10 Zeichen-
sätze - dieser Fehler sollte also nicht
vorkommen).
-13 grInvalidFont Die Kopfinformationen der .CHR-Datei sind
nicht auswertbar bzw. ungültig.
-14 grInvalidFontNum Die Zeichensatz-Nummer in der Kopfinformation
ist nicht bekannt.
Das folgende Beispielprogramm lädt den Zeichensatz "Triplex" von
der Diskette auf den Heap, "registriert" ihn mit RegisterBGIFont
und schaltet dann zwischen "Triplex" und einem anderen Vektor-
Zeichensatz hin und her, wobei der zweite Zeichensatz jeweils
wieder von der Diskette geladen wird:
program LoadFont;
uses Graph;
var
GraphDriver, GraphMode : Integer;
FontF : file;
FontP : Pointer;
begin
{ Öffnung der Zeichensatz-Datei, Laden auf den Heap und
Registrierung über RegisterBGIFont }
Assign(FontF, 'TRIP.CHR'); Reset(FontF, 1);
GetMem(FontP, FileSize(FontF));
BlockRead(FontF, FontP^, FileSize(FontF));
if RegisterBGIFont(FontP) < 0 then
begin
Writeln('Fehler bei der Registrierung: ',
GraphErrorMsg(GraphResult));
Halt(1);
end;
{ Start des Grafikpakets }
GraphDriver := Detect;
InitGraph(GraphDriver, GraphMode, '');
if GraphResult < 0 then Halt(1);
Readln;
{ Auswahl des "registrierten" Zeichensatzes: }
SetTextStyle(TriplexFont, HorizDir, 4);
OutText('Zeichensatz Triplex (direkt geladen)');
MoveTo(0, TextHeight('a'));
Readln;
{ Auswahl eines Zeichensatzes, der von der Diskette geladen wird }
SetTextStyle(SansSerifFont, HorizDir, 4);
OutText('Das Diskettenlaufwerk sollte in Betrieb sein... ');
MoveTo(0, GetY + TextHeight('a'));
Readln;
{ Erneute Auswahl von Triplex }
SetTextStyle(TriplexFont, HorizDir, 4);
OutText('Zeichensatz Triplex - ohne Diskettenzugriffe');
Readln;
CloseGraph;
end.
Hinweis: Der 8*8-Zeichensatz ist immer verfügbar, die Umschaltung
zwischen "DefaultFont" und einem einmal geladenen Vektor-
Zeichensatz erfolgt also ohne Diskettenzugriffe.
Das folgende Beispielprogramm lädt den CGA-Treiber auf den Heap,
"registriert" ihn mit RegisterBGIDriver und ruft dann InitGraph
auf:
program LoadDriv;
uses Graph;
var
GraphDriver, GraphMode : Integer;
DriverF : file;
DriverP : Pointer;
begin
{ Öffnen der Treiberdatei, Einlesen auf den Heap und
Registrierung via RegisterBGIDriver }
Assign(DriverF, 'CGA.BGI'); Reset(DriverF, 1);
GetMem(DriverP, FileSize(DriverF));
BlockRead(DriverF, DriverP^, FileSIze(DriverF));
if RegisterBGIDriver(DriverP) < 0 then
begin
Writeln('Fehler bei der Registrierung: ',
GraphErrorMsg(GraphResult));
Halt(1);
end;
{ Start des Grafikpakets }
GraphDriver := CGA;
GraphMode := CGAHi;
InitGraph(GraphDriver, GraphMode, ''); { keine Disk-Zugriffe! }
if GraphResult < 0 then Halt(1);
OutText('Grafik-Treiber ist geladen.');
Readln;
CloseGraph;
end.
Grafik-Treiber und Zeichensätze können auch direkt in die .EXE-
Datei aufgenommen werden - ein derartiges Programm benötigt keine
weiteren Dateien und kommt völlig ohne Diskettenzugriffe aus. Die
notwendigen Schritte sind in der Datei BINOBJ.DOC ausführlich
beschrieben:
1. Konvertierung der entsprechenden .BGI- und .CHR-Dateien in
.OBJ-Dateien über BINOBJ.EXE.
2. Aufnahme dieser .OBJ-Dateien in das Programm mit dem
Compiler-Befehl {$L}.
3. Entsprechende Aufrufe von RegisterBGIFont und RegisterBGIDriver
*vor* dem Start des Grafikpakets mit InitGraph.
ACHTUNG: RegisterBGIDriver muß *vor* dem Start des Grafik-Pakets
aufgerufen werden - Aufrufe zu einem späteren Zeitpunkt liefern
den Fehlercode -11 (grError).
SetBkColor
----------
Der Aufruf SetBkColor(N) setzt den N. Eintrag der Farb-Palette
als Hintergrundfarbe. Die einzige Ausnahme zu dieser Regel ist
SetBkColor(0) - dieser Aufruf setzt unabhängig vom Wert des
Paletten-Eintrags 0 immer Schwarz als Hintergrundfarbe.
SetFillStyle
------------
Die Standardvorgabe für das Füll-Muster ist "Solid", die
Standardvorgabe für die Farbe ist die höchste verfügbare
Farbnummer (d.h. das Ergebnis von GetMaxColor).
SetGraphBufSize [ Neue Prozedur ]
---------------
procedure SetGraphBufSize(BufSize : Word);
Das Unit GRAPH belegt standardmäßig einen Puffer mit 4 KByte als
Arbeitsbereich für Flächenfüllungen (FillPoly und FloodFill),
was für Polygone mit maximal 650 Eckpunkten ausreichend ist. Die
Größe dieses Puffers kann über SetGraphBufSize auf einen anderen
Wert festgelegt werden.
ACHTUNG: Der Puffer wird durch InitGraph belegt - SetGraphBufSize
muß deshalb vor dem Start des Grafikpakets aufgerufen werden
(spätere Aufrufe werden einfach ignoriert).
SetLineStyle
------------
Das als Pattern übergebene Bitmuster wird nur dann als Linienart
gesetzt, wenn LineStyle als UserBitLn angegeben ist, also
beispielsweise
SetLineStyle(UserBitLn, $AAAA, NormWidth);
In allen anderen Fällen wird eines der vorgegebenen Bitmuster
benutzt und der Wert von "Pattern" ignoriert.
Wie die Werte der Konstanten NormWidth und ThickWidth impli-
zieren, haben normale Linien ein Pixel Dicke, "dicke" Linien
werden mit drei Pixeln gezeichnet:
1010101010101010 { Pattern = $AAAA (UserBitLn), NormWidth }
1010101010101010 { Pattern = $AAAA (UserBitLn), ThickWidth }
1010101010101010
1010101010101010
SetTextStyle
------------
Zu den angegebenen Fehlermöglichkeiten kommen drei weitere Codes
hinzu:
Code Konstante Erläuterung
---- --------- -----------
-12 grIOError I/O-Fehler beim Laden der .CHR-Datei
-13 grInvalidFont Kopfinformation der .CHR-Datei nicht
auswertbar
-14 grInvalidFontNum Zeichensatz-Nummer in der Kopf-
information ist unbekannt
Die Konstante NormSize ist nicht mehr definiert. Die Standardgröße
für den Zeichensatz 8*8 ist 1.
SetUserCharSize [ Neue Prozedur ]
---------------
procedure SetUserCharSize(MultX, DivX, MultY, DivY : Byte);
Diese Prozedur erlaubt die Festlegung voneinander getrennter
Vergrößerungsfaktoren in X- und Y-Richtung für Textausgaben. Der
Vergrößerungsfaktor in X-Richtung (d.h. die Breite) ergibt sich
aus MultX / DivX, der Vergrößerungsfaktor in Y-Richtung (d.h. die
Höhe) aus MultY / DivY). Nach einem Aufruf von SetUserCharSize
mit
SetUserCharSize(4,1,3,2);
und dem Setzen dieser beiden Faktoren über einen Aufruf von
SetTextStyle mit
SetTextStyle(..., ..., UserCharSize);
arbeiten folgende Textausgaben über OutText und OutTextXY mit der
Höhe 4 und der Breite 1.5. Ein Beispiel:
program CharSize;
uses Graph;
var
GraphDriver, GraphMode, Err : Integer;
begin
GraphDriver := Detect;
InitGraph(GraphDriver, GraphMode, '');
Err := GraphResult;
if Err < 0 then
begin
Writeln('Grafik-Fehler: ', GraphErrorMsg(Err));
Halt(1);
end;
SetTextStyle(TriplexFont, Horizdir, 4);
OutText('Normal');
SetUserCharSize(1, 3, 1, 2);
SetTextStyle(TriplexFont, Horizdir, UserCharSize);
OutText('Klein');
SetUserCharSize(3, 1, 1, 1);
SetTextStyle(TriplexFont, Horizdir, UserCharSize);
OutText('Breit');
Readln;
CloseGraph;
end.
SetViewPort
-----------
Da die Parametertypen der Grafikfunktionen vereinheitlicht
wurden, haben x1, y1, x2 und y2 den Typ Integer. Die korrekte
Definition von SetViewPort ist:
procedure SetViewPort(x1, y1, x2, y2 : Integer; Clip : Boolean);