home *** CD-ROM | disk | FTP | other *** search
- (* ****************************************************** *)
- (* DREHFONT.PAS *)
- (* BGI-Erweiterung für die Ausgabe von Texten in *)
- (* beliebigen Richtungen auf dem Bildschirm *)
- (* (für Vektorfonts) *)
- (* (c) 1993 Jeanette Winzenburg & DMV *)
- (* ****************************************************** *)
- UNIT DrehFont;
-
- INTERFACE
-
- USES Graph, Objects;
-
- CONST
- xyRatio : REAL = 1.0;
- { Seitenverhältnis des Bildschirms }
-
- PROCEDURE InitDrehen;
- { Initialisiert Drehmöglichkeit für Vektorfonts,
- Aufruf nach InitGraph und vor SetTextStyle }
-
- { ** redefinierte BGI-Funktionen ** }
- FUNCTION RegisterBGIFont(FontZeiger : Pointer) : INTEGER;
-
- PROCEDURE SetTextStyle
- (FontNr, Direction, CharSize : INTEGER);
-
- PROCEDURE SetUserCharSize
- (xMul, xDiv, yMul, yDiv : INTEGER);
- PROCEDURE OutText(Text : STRING);
- PROCEDURE OutTextXY(x, y : INTEGER; Text : STRING);
-
- { ** neue Einstellfunktionen ** }
- PROCEDURE SetGrad(Winkel : INTEGER);
- PROCEDURE SetDirection(Winkel : REAL);
- PROCEDURE SetKursiv(Winkel : INTEGER);
-
- IMPLEMENTATION
-
- CONST
- FontInstalled : BOOLEAN = FALSE;
-
- TYPE
- tBruch = RECORD
- Fakt, Nenn : INTEGER;
- END;
- tBPoint = RECORD
- x, y : ShortInt;
- END;
- pPktBuf = ^tPktbuf;
- tPktBuf = ARRAY [0..1023] OF tBPoint;
-
- pVektorTab = ^tVektorTab;
- tVektorTab = ARRAY [0..256] OF WORD;
- tZeiger = ARRAY [0..10] OF Pointer;
- MemFunct = PROCEDURE(VAR p : Pointer; Size : WORD);
-
- pfontInfo = ^FontInfo;
- FontInfo = RECORD
- Id : BYTE; { Startkennung }
- Anzahl : word; { Zeichenzahl }
- xx, Erstes : CHAR; { erstes Zeichen }
- VektorOfs : WORD; { offset Vektorinfo }
- xx1, Hoehe, { Zeichenhöhe }
- xx2, Unter : ShortInt; { Zeichenunterlänge }
- xx3 : ARRAY [0..4] OF BYTE;
- END; { alle xx unbekannte Bedeutung }
-
- tFont = RECORD
- Nummer : integer;
- Base : word; { offset zum Infostart }
- Zeiger, { Zeiger auf Fontinformation }
- Breiten : pByteArray; { Breitentabelle }
- Info : pFontInfo; { Infostart }
- VektorTab : pVektorTab; { Vektortabelle }
- xFak, yFak: tBruch; { Usercharsize }
- kursiv : BOOLEAN; { kursiv-flag }
- sRad, sSin, sCos, { Winkel/trigon. Werte }
- kRad, kSin : REAL;
- END;
-
- VAR
- Font : tFont; { aktueller Font }
- RegFonts : tZeiger;
- { registrierte Fonts }
- GraphGetMem : MemFunct;
- { "alte" Speicherfkt }
-
- PROCEDURE FontGetMem(VAR P : Pointer; Size : WORD); FAR;
- BEGIN
- GraphGetMem(p, Size);
- IF NOT FontInstalled THEN Font.Zeiger := p;
- END;
-
- PROCEDURE InitDrehen;
- BEGIN
- FillChar(Font, SizeOf(font), 0);
- GraphGetMem := MemFunct(GraphGetMemPtr);
- GraphGetMemPtr := @FontGetMem;
- { Memreservierung verbiegen }
- END;
-
- FUNCTION RegisterBGIFont(FontZeiger: Pointer): INTEGER;
- VAR
- c : INTEGER;
- BEGIN
- c := Graph.RegisterBGIFont(FontZeiger);
- IF c > 0 THEN RegFonts[c] := FontZeiger;
- RegisterBGIFont := c;
- END;
-
- PROCEDURE InitFont(FontNr : INTEGER);
- { setzt font-Werte }
- VAR
- i : INTEGER;
- BEGIN
- Font.Nummer := FontNr;
- i := 0;
- REPEAT
- Inc(i);
- UNTIL Font.Zeiger^[i] = $1A;
- Font.Base := Word(Font.Zeiger^[i + 1]);
- Font.Info := @Font.Zeiger^[Font.Base];
- Font.Vektortab := @Font.Zeiger^[Font.Base + $10];
- Font.Breiten := @font.Zeiger^[font.base + $10 +
- Font.Info^.Anzahl * 2];
- SetKursiv(0);
- SetDirection(HorizDir);
- FontInstalled := TRUE;
- END;
-
- FUNCTION GetVektor(Zeichen : CHAR) : pPktbuf;
- { liefert Zeiger auf Vektor }
- VAR
- Stelle : INTEGER;
- BEGIN
- GetVektor := NIL;
- Stelle := Byte(Zeichen) - Byte(Font.Info^.Erstes);
- IF (Stelle < 0) OR
- (Stelle >= Font.Info^.Anzahl) THEN Exit;
- GetVektor := @Font.Zeiger^[Font.Base +
- Font.Info^.VektorOfs +
- Font.VektorTab^[Stelle]];
- END;
-
- PROCEDURE SetDirection(Winkel : REAL);
- BEGIN
- Font.sRad := Winkel;
- Font.sSin := Sin(Font.sRad);
- Font.sCos := Cos(Font.sRad);
- END;
-
- PROCEDURE SetGrad(Winkel : INTEGER);
- BEGIN
- SetDirection(Winkel * pi / 180);
- END;
-
- PROCEDURE SetKursiv(Winkel : INTEGER);
- BEGIN
- IF Winkel <> 0 THEN BEGIN
- Font.Kursiv := True;
- Font.kRad := Winkel * pi/ 180;
- Font.kSin := Sin(Font.kRad);
- END ELSE
- Font.kursiv := FALSE;
- END;
-
- PROCEDURE Transform(VAR Punkt : tPoint);
- VAR
- Temp : tPoint;
- BEGIN
- Punkt.x := Font.xFak.Fakt * Punkt.x
- DIV Font.xFak.Nenn;
- Punkt.y := - Font.yFak.Fakt * Punkt.y
- DIV Font.yFak.Nenn ;
- IF Font.kursiv THEN
- Inc(Punkt.x, Round(Punkt.y * Font.kSin));
- Temp.x := Round(Punkt.x * Font.sCos +
- Punkt.y * Font.sSin);
- Temp.y := Round((Punkt.y * Font.sCos -
- Punkt.x * Font.sSin) * xyRatio);
- Punkt := Temp;
- END;
-
- PROCEDURE OutVektor(Vektor: pPktBuf);
- { gibt Vektor aus }
- VAR Anfang, Temp : tPoint;
- Stelle : INTEGER;
- Punkt : tbPoint;
- BEGIN
- Anfang.x := GetX;
- Anfang.y := GetY;
- Stelle := 0;
- Punkt := Vektor^[Stelle];
- WHILE Punkt.x AND $80 <> 0 DO BEGIN
- Temp.x := (Punkt.x AND $7F);
- Temp.y := (Punkt.y AND $7F);
- IF (Temp.y AND $40) <> 0 THEN
- Temp.y := Temp.y - $80;
- Transform(Temp);
- Inc(Temp.x, Anfang.x);
- Inc(Temp.y, Anfang.y);
- IF Punkt.y AND $80 <> 0 THEN
- LineTo(Temp.x, Temp.y)
- ELSE
- MoveTo(Temp.x, Temp.y);
- Inc(Stelle);
- Punkt := Vektor^[Stelle];
- END;
- END;
-
- PROCEDURE OutChar(Zeichen : CHAR);
- { gibt Zeichen aus }
- VAR
- Vektor : pPktBuf;
- BEGIN
- Vektor := GetVektor(Zeichen);
- IF Vektor <> NIL THEN OutVektor(Vektor);
- END;
-
- PROCEDURE SetUserCharSize
- (xMul, xDiv, yMul, yDiv : INTEGER);
- BEGIN
- Graph.SetUserCharSize(xMul, xDiv, yMul, yDiv);
- Font.xFak.Fakt := xMul;
- Font.yFak.Fakt := yMul;
- Font.xFak.Nenn := xDiv;
- Font.yFak.Nenn := yDiv;
- END;
-
- TYPE
- Faktors = ARRAY [0..10] OF tBruch;
-
- CONST { Standard-Vergrößerungen }
- StdSize : Faktors = ( (Fakt: 1; Nenn: 1),
- (Fakt: 3; Nenn: 5), (Fakt: 7; Nenn: 10),
- (Fakt: 8; Nenn: 11), (Fakt: 1; Nenn: 1),
- (Fakt: 4; Nenn: 3), (Fakt: 5; Nenn: 3),
- (Fakt: 2; Nenn: 1), (Fakt: 5; Nenn: 2),
- (Fakt: 3; Nenn: 1), (Fakt: 4; Nenn: 1));
-
- PROCEDURE SetTextStyle
- (FontNr, Direction, CharSize : INTEGER);
- BEGIN
- FontInstalled := (Font.Nummer = FontNr)
- OR (FontNr = 0) OR (FontNr > 10);
- Graph.SetTextStyle(FontNr, Direction, CharSize);
- IF NOT FontInstalled THEN BEGIN
- IF RegFonts[FontNr] <> NIL THEN
- Font.Zeiger := RegFonts[FontNr];
- InitFont(FontNr);
- END;
- CASE CharSize OF
- 0..10: BEGIN
- Font.xFak := StdSize[CharSize];
- Font.yFak := StdSize[CharSize];
- END;
- ELSE BEGIN
- Font.xFak := StdSize[0];
- Font.yFak := StdSize[0];
- END;
- END;
- SetGrad(Direction);
- END;
-
- PROCEDURE OutText(Text : STRING);
- VAR
- i : INTEGER;
- setting : TextSettingsType;
- merke, delta : tPoint;
- len, hoehe : INTEGER;
- BEGIN
- GetTextSettings(Setting);
- IF (Setting.Font = Font.Nummer) AND
- (Setting.Font <> 0) THEN BEGIN
- Merke.x := GetX;
- Merke.y := GetY;
- Len := TextWidth(Text);
- Hoehe := TextHeight(Text);
- Delta.x := 0; Delta.y := 0;
- CASE Setting.Horiz OF
- CenterText : BEGIN
- Delta.x := -Round(Len/2 * Font.sCos);
- Delta.y := Round(Len/2 * Font.sSin * xyRatio);
- END;
- RightText : BEGIN
- Delta.x := -Round(Len * Font.sCos);
- Delta.y := Round(Len * Font.sSin * xyRatio);
- END;
- END;
- CASE Setting.Vert OF
- CenterText : BEGIN
- Inc(Delta.x, Round(Hoehe/2*Font.sSin));
- Inc(Delta.y, Round(Hoehe/2*Font.sCos * xyRatio));
- END;
- TopText : BEGIN
- Inc(Delta.x, Round(Hoehe*Font.sSin));
- Inc(Delta.y, Round(Hoehe*Font.sCos * xyRatio));
- END;
- END;
- MoveTo(Merke.x + Delta.x, Merke.y + Delta.y);
- FOR i := 1 TO Length(Text) DO
- OutChar(Text[i]);
- IF Setting.Horiz = LeftText THEN
- MoveRel(-Delta.x, -Delta.y)
- ELSE
- MoveTo(Merke.x, Merke.y);
- END ELSE
- Graph.OutText(Text);
- END;
-
- PROCEDURE OutTextXY(x, y: INTEGER; Text : STRING);
- BEGIN
- MoveTo(x, y);
- OutText(text);
- END;
-
- BEGIN
- FillChar(RegFonts, SizeOf(RegFonts), 0);
- END.
- (* ****************************************************** *)
- (* Ende von DREHFONT.PAS *)