home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* GR-EDIT1.PAS *)
- (* Programm zur Demonstration der Vektorgrafik *)
- (* (c) 1988 Helmut Wessels & TOOLBOX *)
- (* ------------------------------------------------------ *)
- PROGRAM VektorGraphik;
- USES Dos, Crt, Graph;
- TYPE tSTRING = STRING[20];
- tText = STRING[45];
- tINFO = RECORD
- x1 : BYTE;
- anzahl : INTEGER;
- {Byte 2,3 = Anzahl der Zeichen }
- x2, anfang : BYTE;
- {Byte 5 = ASCII-Nr. d. 1.Zeichens}
- vect_anfang : INTEGER;
- {Byte 6,7 = Anf. d. Vektortabelle}
- x3, hoehe : BYTE;
- {Byte 9 = Höhe in Pixel + 1 }
- x4, unterlaengen : ShortInt;
- {Byte 11 = Unterlängen }
- x5,x6,x7,x8,x9 : BYTE;
- END;
- tOFFS = ARRAY [1..1024] OF INTEGER;
- {Adressen der Vektoren in tVECT }
- tBREITE = ARRAY [1..1024] OF BYTE;
- {Breite für die Zeichen}
- tVECT = ARRAY [0..14200] OF BYTE; {evtl. auch mehr}
- {Liste der Vektoren}
- tART = (normal,ref_zeichen,Kreis,texte,usw,quatsch);
- {in den oberen 4 Bit gespeichert}
- tsatz = ARRAY [0..16383] OF BYTE; { evtl. größer }
- tstrukt = RECORD
- satz : ^tsatz; {der ganze Satz}
- info : ^tInfo; {Struktur-Infos}
- breite : ^tBreite; {Breitentabelle}
- offs : ^tOffs; {Einsprungadressen}
- vect : ^tVect; {Vektorentabelle}
- END;
- VAR faktor : BYTE;
- rx, ry : ShortInt;
- korr_faktor : REAL;
- i,k,s,cx,cy,cx_g,cy_g,cy_t,tx,ty,txof,
- umfang, GraphDriver, GraphMode : INTEGER;
- c : CHAR;
- gr_filename : tSTRING;
- userfont, outfont : tstrukt;
- usatz : tsatz;
- f : FILE;
-
- FUNCTION liesz : INTEGER; {Hilfsroutine}
- VAR s : STRING[5]; i, k : INTEGER;
- BEGIN
- ReadLn(s);
- Val(s, i, k);
- IF k = 0 THEN liesz := i ELSE liesz := 0;
- WriteLn;
- END;
-
- FUNCTION bildwahl : WORD; {Wahl einer Bildnummer}
- VAR i : INTEGER; c : CHAR;
- BEGIN
- Write('Nummer (bzw. Taste) des Bildes, Ende: [ESC] ',
- #8#8#8);
- c := ReadKey; i := 0;
- WHILE c IN ['0'..'9'] DO BEGIN
- i := 10*i + Ord(c) - 48; Write(c);
- c := ReadKey
- END;
- IF (c <> #27) AND (i = 0) THEN i := Ord(c);
- WITH userfont, info^ DO
- IF (i < anfang) OR (i >= anfang + anzahl) THEN BEGIN
- i := 0; WriteLn;
- Write('Bild (noch) nicht vorhanden! [RETURN]');
- c := ReadKey; DelLine;
- END;
- bildwahl := i;
- END;
-
- FUNCTION decodiere_vektor(a,b:BYTE; VAR x,y:ShortInt;
- VAR linie:BOOLEAN):tART;
- {entschlüsselt die Bedeutung eines Byte-Paares}
- BEGIN
- x := a AND $7f; y := b AND $7f;
- IF Odd(y SHR 6) THEN y := $80 + y;
- linie := Odd(b SHR 7);
- IF Odd(a SHR 7) THEN decodiere_vektor := normal
- ELSE IF a AND $70 > 0 THEN
- decodiere_vektor := tART(a SHR 4)
- ELSE decodiere_vektor := quatsch;
- END;
-
- PROCEDURE zeichne(font : tstrukt; nr : WORD; ref : BOOLEAN;
- faktor: REAL; drehung : BYTE);
- {Zeichnet ein Bild, ruft sich u.U. selbst rekursiv auf}
- VAR x,y:ShortInt; w1,w2:BYTE; x1,y1,gcx,gcy,z,off:INTEGER;
- linie:BOOLEAN;
- sina,cosa,sinz,cosz,z1,z2,xf,alp,pi180:REAL;
- BEGIN
- WITH font DO BEGIN
- off:=offs^[nr]; {Anfang der Vektorfolge}
- IF ref OR (font.satz = outfont.satz) THEN BEGIN
- gcx := GetX; gcy := GetY
- END ELSE BEGIN {beim letzten Punkt weiter}
- gcx := cx; gcy := cy
- END; {Bezugspunkt=Ursprung}
- xf := faktor/korr_faktor;
- REPEAT
- CASE
- decodiere_vektor(vect^[off],vect^[off+1],x,y,linie) OF
- normal: BEGIN
- IF drehung <> 0 THEN BEGIN
- alp := drehung/90*Pi; x1 := x;
- x1:=Round(xf*(x*Cos(alp)-y*Sin(alp)));
- y1:=Round(faktor*
- (+x*Sin(alp)+y*Cos(alp)));
- END ELSE BEGIN
- x1 := Round(xf*x);
- y1 := Round(faktor*y)
- END;
- IF linie THEN LineTo(gcx + x1, gcy - y1)
- ELSE MoveTo(gcx+x1,gcy-y1)
- END; {normal}
- ref_zeichen: BEGIN
- { folgt in Teil 3 }
- END; {ref_zeichen}
- texte : BEGIN
- { folgt in Teil 3 }
- END; {texte}
- Kreis : BEGIN
- { folgt in Teil 3 }
- END {kreis}
- END; {case}
- Inc(off, 2)
- UNTIL (vect^[off] = 0);
- IF (font.satz=userfont.satz) AND NOT ref THEN Inc(cx,x1)
- END;
- END;
-
- PROCEDURE struktur(VAR font : tstrukt);
- BEGIN {Zeiger werden gesetzt}
- WITH font DO BEGIN
- info := @satz^[128];
- {Bis Byte 127: Impressum von BORLAND}
- offs := @satz^[144 - 2*(info^.anfang - 1)];
- breite:= @satz^[144 + 2*info^.anzahl -(info^.anfang-1)];
- vect := @satz^[128 + info^.vect_anfang]
- END;
- END;
-
- PROCEDURE loadfont; {Vektor-Datei für Texte wird geladen}
- VAR fontf : FILE;
- BEGIN
- Assign(fontf, 'lit1.chr'); {Wird für Text benutzt}
- Reset(fontf, 1);
- GetMem(outfont.satz, FileSize(fontf));
- BlockRead(fontf, outfont.satz^, FileSize(fontf));
- Close(fontf);
- IF RegisterBGIfont(outfont.satz) < 0 THEN BEGIN
- Write(#7#7#7, 'Fehler'); Delay(2000);
- END;
- struktur(outfont); {lit1.chr wird strukturiert}
- END;
-
- PROCEDURE laden; {Vektor-Datei für Anwenderzeichen }
- CONST kenn : STRING[87] =
- 'PK'#8#8'GRAPHIK-EDITOR für Vektor-Graphik, Version 2.0, Nov. 1988***'#13#10'(c)Helmut Wessels'#13#10#0#0;
- neu :ARRAY[1..25] OF BYTE =($2b,1,0,0,1,$13,0,0,$19,0,
- $FE,0,0,0,0,0,0,0,6,$80,0,$86,0,0,0);
- BEGIN
- Assign(f, gr_filename);
- {$I-} Reset(f, 1); {$I+}
- IF IOResult = 0 THEN BEGIN
- BlockRead(f, usatz, FileSize(f));
- umfang := FileSize(f);
- Close(f);
- END ELSE BEGIN
- Write(#7'Datei nicht vorhanden, wird neu erstellt!');
- FillChar(usatz, 128, #0);
- usatz[87] := $1a; usatz[88] := $80;
- usatz[96] := 1; usatz[98] := 1;
- Move(neu, usatz[128], 25);
- umfang := 153; Delay(1000);
- END;
- userfont.satz := @usatz;
- struktur(userfont); {Anwender-Datei wird strukturiert}
- FOR k := 1 TO Length(kenn) DO usatz[k-1] := Ord(kenn[k]);
- END;
-
- PROCEDURE meintext(k:BYTE;st:tText); {entspricht OUTTEXT}
- VAR i : INTEGER; {nur mit mehr Möglichkeiten}
- BEGIN
- FOR i := 1 TO Length(st) DO
- zeichne(outfont, Ord(st[i]), FALSE, k*ty/50,0);
- END;
-
- PROCEDURE hoehe_aendern; {Einstellung Standardhöhe}
- BEGIN
- WITH userfont DO BEGIN
- ClrScr;
- GotoXY(1,16);
- Write('Neue Werte eingeben, RETURN für alten Wert');
- GotoXY(1,12);
- Write('Bildhöhe in Raster-Einheiten: ', info^.hoehe);
- GotoXY(1,14);
- Write('Unterlängen in Raster-Einheiten: ',
- -info^.unterlaengen);
- GotoXY(37,12); k := liesz;
- IF k <> 0 THEN info^.hoehe := k;
- GotoXY(37,14); k := liesz;
- IF k <> 0 THEN info^.unterlaengen := -k
- END;
- END;
-
- PROCEDURE anfuegen; {fügt Platz für ein neues Zeichen an}
- CONST leer:ARRAY[1..6] OF BYTE = ($80,$00,$86,$00,$00,$00);
- BEGIN {offs^ ergänzen, breite^ und vect^ verschieben }
- WITH userfont, info^ DO BEGIN
- Inc(vect_anfang, 3); {davor werden 3 Byte eingefügt}
- Inc(umfang, 9); {plus 6 Byte Leerzeichen}
- Move(vect^[0], vect^[3], umfang - vect_anfang - 128);
- {um 3 Byte verschieben}
- vect := @vect^[3];
- Move(breite^[anfang], breite^[anfang+2], anzahl);
- {um 2 Byte verschieben}
- breite := @breite^[3];
- breite^[anfang+anzahl] := 6;
- offs^[anfang+anzahl] := umfang - vect_anfang - 128 - 6;
- Move(leer, vect^[offs^[anfang+anzahl]], 6);
- Inc(anzahl);
- END;
- END;
-
- PROCEDURE gr_speichern(bildname:tSTRING); {Datei speichern}
- BEGIN
- k := 80; {Eintrag für Dateiumfang suchen}
- REPEAT Inc(k)
- UNTIL (usatz[k-2] = $1a) AND (usatz[k-1] = $80)
- AND (usatz[k] = $00) OR (k>110);
- i := Pos(':', bildname); {Name des Zeichensatzes}
- FOR s := i + 1 TO i + 4 DO
- usatz[k + s - i] := Ord(UpCase(bildname[s]));
- usatz[k + 6] := (umfang - 128) SHR 8;
- usatz[k + 5] := (umfang - 128) AND $FF;
- IF Pos('.',bildname) = 0 THEN bildname := bildname+'.chr';
- Assign(f, bildname); Rewrite(f, 1);
- BlockWrite(f, usatz, umfang, k); Close(f);
- END;
-
- PROCEDURE editieren; {Erstellen/bearbeiten einer Grafik}
- BEGIN {folgt im 2. Teil}
- END;
-
- PROCEDURE testen; {Schreibt Zeichen auf leeren Schirm}
- VAR st: STRING[4];
- BEGIN
- WriteLn; WriteLn(#10,'Test-Ende mit ESC!',#10);
- REPEAT
- Write('Welchen Vergrößerungsfaktor wünschen Sie? (',
- faktor,') ');
- k := liesz;
- UNTIL k*userfont.info^.hoehe < GetMaxY;
- IF k > 0 THEN faktor := k;
- SetGraphMode(GraphMode);
- WITH userfont, info^ DO BEGIN
- cx := 0; cy := faktor*hoehe; {Anfangspunkt 1.Zeichen}
- REPEAT
- k := Ord(ReadKey);
- IF (k >= anfang) AND (k < anfang + anzahl)
- OR (k = 13) THEN BEGIN
- IF (cx > GetMaxX -
- Round(faktor/korr_faktor*breite^[k]))
- {ist noch genügend Platz bis zum rechten Rand?}
- OR (k=13) THEN BEGIN {RETURN gedrückt?}
- cx := 0; {neue Zeile}
- cy := cy + faktor*(hoehe - unterlaengen + 1);
- IF cy > GetMaxY THEN BEGIN {Schirm voll}
- ClearDevice; {löschen}
- cx := 0; cy := faktor * hoehe;
- END;
- MoveTo(cx, cy);
- END;
- IF k<>13 THEN zeichne(userfont,k,FALSE,faktor,0);
- END ELSE Write(#7);
- UNTIL k = 27; {Ende mit ESC}
- RestoreCrtMode;
- END;
- END;
-
- PROCEDURE Zeichen_ansehen; {Übersicht Grafik-Zeichen }
- VAR st : STRING[4];
- faktor, xbreite, vx : WORD;
- BEGIN
- SetGraphMode(GraphMode);
- vx := GetMaxX DIV 16; {Mindestabstand der Zeichen}
- WITH userfont, info^ DO BEGIN
- faktor := Trunc((GetMaxY-ty)/(hoehe-unterlaengen+ty)/3);
- {Faktor wird nach Graphikkarte und Zeichenhöhe angepaßt}
- cx := 0;
- cy := 2*GetMaxY DIV 7 + faktor*unterlaengen;
- {Es werden drei Zeilen pro Schirm geschrieben á 2/7 Höhe}
- MoveTo(cx, cy);
- i := anfang;
- REPEAT
- xbreite := Round(faktor/korr_faktor*breite^[i]);
- IF (cx>GetMaxX-xbreite) OR (cx>GetMaxX-vx) THEN BEGIN
- cx := 0; Inc(cy, 2*GetMaxY DIV 7 + ty)
- END;
- IF (cy>GetMaxY-ty) OR (i = anfang + anzahl) THEN BEGIN
- MoveTo(1, GetMaxY);
- meintext(5, 'Bild-Datei '+
- Copy(gr_filename,1,Pos('.',gr_filename)-1));
- MoveTo(GetMaxX DIV 2, GetMaxY);
- meintext(5, ' [RET] = weiter, [ESC] = Ende');
- c := ReadKey;
- ClearDevice;
- cx := 0;
- cy := 2*GetMaxY DIV 7 + faktor*unterlaengen;
- END;
- IF (i < anfang + anzahl) AND (c <> #27) THEN BEGIN
- Str(i, st);
- MoveTo(cx, cy + faktor * (1 - unterlaengen) + ty);
- meintext(5, 'Nr.' + st);
- MoveTo(cx, cy);
- zeichne(userfont, i, FALSE, faktor, 0);
- IF xbreite < vx THEN Inc(cx, vx + 9 - xbreite)
- ELSE Inc(cx, 10);
- END;
- Inc(i);
- UNTIL (i > anfang + anzahl) OR (c = #27);
- END;
- RestoreCrtMode;
- END;
-
- PROCEDURE initialisieren;
- {Grafikkarten werden erkannt, für verschiedene Karten wird
- ein Korrekturfaktor und eine Zeichengröße beigegeben }
- BEGIN
- GraphDriver := detect;
- InitGraph(GraphDriver, GraphMode, '');
- CASE GraphDriver OF {sorgt für Hardcopies}
- CGA: IF GraphMode = CGAHi THEN {im richtigen Höhen- }
- korr_faktor:=0.5; {Seiten-Verhältnis }
- EGA,EGAMono: CASE GraphMode OF
- EGALo : korr_faktor := 0.5;
- EGAHi,EGAMonoHi : korr_faktor := 0.936;
- END;
- HercMono, PC3270 : korr_faktor := 0.832;
- ELSE korr_faktor := 1;
- END;
- cx_g := Round(GetMaxX/24); {Grundstellung (Ursprung) für}
- cy_g := Round(GetMaxY*0.675); {Graphik-Raster}
- cy_t := Round(GetMaxY*0.758); {Höhe für Zahlenausgabe}
- tx := Round(GetMaxX/16); {Breite f. 1 Zahlenpaar}
- txof := GetMaxX-GetMaxX DIV 4 - tx DIV 2; {Menüleiste}
- ty := GetMaxY DIV 29; {Höhe der Textzeichen}
- CASE GraphDriver OF
- CGA : ty := 6; {Anpassung für}
- HercMono,PC3270 : ty := 11; {einige Graphikkarten}
- EGA,EGAMono : ty := 10; {ausprobieren!}
- VGA : ty := 12;
- END;
- SetColor(white);
- RestoreCrtMode;
- END;
-
- BEGIN { Hauptprogramm }
- ClrScr;
- WriteLn(#10'Der Vektor-Graphik-Editor ( V 2.0 )'+
- ' h.w. 1988');
- WriteLn('mit Einbindung von Referenz-Adressen, Ellipsen,'+
- ' Bögen und Texten');
- WriteLn('sowie Größen- und Lageveränderungen'#10);
- loadfont;
- Write(#10#10,
- 'Welche Vektor-Zeichen-Datei soll geladen werden: ');
- ReadLn(gr_filename);
- IF Pos('.',gr_filename)=0 THEN
- gr_filename:=gr_filename+'.chr';
- laden; initialisieren;
- WITH userfont,info^ DO BEGIN
- faktor:=Round(GetMaxY/3/(hoehe-unterlaengen));
- {Anpassung des Vergrößerungsfaktors an die Zeichenhöhe}
- cx:=0; cy:=faktor*hoehe;
- REPEAT
- GotoXY(1,5);
- WriteLn('Bilddatei ',gr_filename,' enthält ',umfang,
- ' Byte mit ',anzahl,' Bildern ab Nr.',anfang,'.');
- WriteLn('Höhe der Zeichen ',hoehe+1,
- ' Raster-Einheiten, ','Unterlängen ',-unterlaengen,
- ' Raster-Einheiten');
- WriteLn('Momentaner Vergrößerungsfaktor für Test: ',
- faktor);
- WriteLn;
- WriteLn('Sie möchten ...');
- WriteLn(' die Grafiken testen (schreiben) .. T');
- WriteLn(' eine Grafik editieren (ansehen) .. E');
- WriteLn(' die Standard-Höhe ändern ......... H');
- WriteLn(' Platz für neue Grafik anfügen .... A');
- WriteLn(' Grafiken in Übersicht sehen ...... G');
- WriteLn(' Aufhören ........................ Q');
- Write ('-------------------------------------> ',
- #8#8#8);
- c := UpCase(ReadKey);
- CASE c OF
- 'T' : testen;
- 'E' : editieren;
- 'H' : hoehe_aendern;
- 'A' : IF anfang + anzahl < 1000 THEN anfuegen;
- 'G' : Zeichen_ansehen;
- END;
- UNTIL c = 'Q';
- END;
- Write(#13'Möchten Sie den Zeichensatz speichern? (J/N)');
- IF UpCase(ReadKey) = 'J' THEN BEGIN
- WriteLn;
- Write('Neuer Name: (4 Zeichen für Borland) ');
- ReadLn(gr_filename);
- IF gr_filename<>'' THEN gr_speichern(gr_filename);
- WriteLn('Falls Sie einen neuen Namen gewählt haben '+
- 'und den Satz mit GRAPH.TPU benutzen wollen,');
- WriteLn('müssen Sie den Namen noch in GRAPH.TPU eintr'+
- 'agen (ab Byte 697C)!')
- END;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von GR-EDIT1.PAS *)