home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1989-05-03 | 8.6 KB | 304 lines |
- (*******************************************************)
- (* CHR.MOD *)
- (* Implementationmodul des CHR-Moduls *)
- (* Treiberroutinen für BGI-Zeichensätze *)
- (* (C) 1989 R.Hensmann & TOOLBOX *)
-
- IMPLEMENTATION MODULE Chr;
-
- FROM FIO IMPORT IOcheck,Open,Close,Size,File, RdBin;
- FROM Storage IMPORT ALLOCATE, DEALLOCATE;
- FROM Lib IMPORT FatalError;
- FROM Str IMPORT Concat, Compare, Length, Caps;
- FROM Graph IMPORT Line, NumColor, Width, Depth;
-
- CONST MaxTable = 24;
-
- TYPE Tiny = SET OF [0..7];
- ChrString = ARRAY [0..3] OF CHAR;
- (* Allgemeiner Datenpuffer *)
- Buffer = POINTER TO TBuffer;
- TBuffer = ARRAY CARDINAL OF SHORTCARD;
- (* Interne Daten frei nach Arne Schäpers *)
- PStart = POINTER TO RECORD
- StartInhalt : CARDINAL;
- Name : ChrString;
- LengthInhalt,
- MinVersion,
- MaxVersion : CARDINAL;
- END;
- PHeader = POINTER TO RECORD
- (* Unbekannter Zweck *)
- UnKnown : BYTE;
- (* Anzahl der Zeichen *)
- TblSize : SHORTCARD;
- Unused1 : WORD;
- (* Erstes definiertes Zeichen *)
- MinChar : CHAR;
- (* Start der Vektortabelle *)
- VecStart : CARDINAL;
- Unused2 : BYTE;
- (* Pixelhöhe *)
- PixelH : SHORTCARD;
- Unused3 : BYTE;
- (* Unterlänge (negativ) *)
- UnderL : SHORTINT;
- Unused4 : ARRAY [0..4] OF BYTE;
- (* Start der Vektor-Adresstab. *)
- VecAddress : WORD;
- END;
- (* Addresstabelle *)
- PAddress = POINTER TO ARRAY SHORTCARD OF CARDINAL;
- (* Breitentabelle *)
- PWidth = POINTER TO ARRAY SHORTCARD OF SHORTCARD;
- (* Einträge in interne Tabelle *)
- ChrEntry = RECORD
- Name : ChrString;
- Header : PHeader;
- Address : PAddress;
- Width : PWidth;
- Vec : Buffer;
- Buf : Buffer;
- END;
- ChrTable = ARRAY [0..MaxTable] OF ChrEntry;
- TIdentTable = ARRAY[0..MaxTable] OF ChrString;
-
- VAR TextStyles : ChrTable;
- MaxEntry : CARDINAL;
- ActStyle : ChrEntry;
- Horiz : BOOLEAN;
- ScaleX, ScaleY : CARDINAL;
- IdentTable : TIdentTable;
- i : INTEGER;
-
-
- (*$V-*)
- PROCEDURE LoadDriver( Name : ARRAY OF CHAR ) : ADDRESS;
- (* Lädt File in internen Puffer *)
- VAR IOold : BOOLEAN;
- Data : File;
- SizeChr,
- Hilf : CARDINAL;
- Satz : Buffer;
- BEGIN
- IOold:=IOcheck;
- IOcheck:=FALSE;
- Data:=Open(Name);
- IF CARDINAL(Data) = MAX(CARDINAL) THEN
- IOcheck:=IOold;
- RETURN NIL;
- END;
- SizeChr := CARDINAL(Size(Data));
- ALLOCATE(Satz, SizeChr);
- Hilf := RdBin( Data, Satz^, SizeChr );
- IF (Satz^[0]<>50H) OR (Satz^[1]<>4BH)
- OR (Hilf <> SizeChr) THEN
- DEALLOCATE(Satz, SizeChr);
- IOcheck:=IOold;
- RETURN NIL;
- END;
- Close(Data);
- IOcheck:=IOold;
- RETURN Satz;
- END LoadDriver;
-
- PROCEDURE RegisterFont( BufAdr : ADDRESS );
- (* Trägt Puffer in Tabelle ein *)
- VAR Hilf,Segment : Buffer;
- Start : CARDINAL;
- HStart : PStart;
- BEGIN
- Hilf:=BufAdr;
- Start:=3;
- WHILE (Hilf^[Start] # 1AH) DO
- INC(Start);
- END;
- HStart := ADR(Hilf^[Start+1]);
- WITH ActStyle DO
- Name := HStart^.Name;
- Header := ADR( Hilf^[HStart^.StartInhalt] );
- Segment := ADDRESS(Header);
- Address := ADR( Segment^[10H] );
- Width := ADR( Segment^[10H+2*CARDINAL(Header^.TblSize)] );
- Vec := ADR( Segment^[Header^.VecStart] );
- Buf := Hilf;
- END; (* WITH *)
- IF MaxEntry <= MaxTable THEN
- TextStyles[MaxEntry] := ActStyle;
- IdentTable[MaxEntry] := ActStyle.Name;
- INC(MaxEntry);
- ELSE
- FatalError("Zu viele CHR-Zeichensätze");
- END;
- END RegisterFont;
-
- PROCEDURE InstallUserFont(Name : ARRAY OF CHAR) : INTEGER;
-
- VAR Buffer : ADDRESS;
-
- BEGIN
- Buffer := LoadDriver(Name);
- RegisterFont(Buffer);
- RETURN (MaxEntry - 1);
- END InstallUserFont;
-
- PROCEDURE TextStyle( Name : ARRAY OF CHAR;
- Horizontal : BOOLEAN;
- NewScaleX,
- NewScaleY : CARDINAL);
- (* Wählt Font aus - nur die ersten vier Buchstaben
- von Name sind signifikant *)
- VAR Lauf : CARDINAL;
- Buf : Buffer;
- Filename : ARRAY [0..11] OF CHAR;
- BEGIN
- Caps(Name);
- Lauf:=0;
- WHILE (Compare(TextStyles[Lauf].Name,Name) # 0)
- AND (Lauf<MaxEntry) DO
- INC(Lauf);
- END;
- IF Lauf = MaxEntry THEN
- Concat(Filename,Name,".CHR");
- Buf:=LoadDriver(Filename);
- IF Buf=NIL THEN
- FatalError("Datei nicht gefunden !");
- END;
- RegisterFont( Buf );
- ELSE
- ActStyle:=TextStyles[Lauf];
- END;
- Horiz:=Horizontal;
- ScaleX:=NewScaleX;
- ScaleY:=NewScaleY;
- END TextStyle;
-
- PROCEDURE SetTextStyle(Font : CARDINAL;
- Direction : CARDINAL;
- CharSize : CARDINAL );
- BEGIN
- TextStyle(IdentTable[Font],
- (Direction=HorizDir),
- CharSize,CharSize);
- END SetTextStyle;
-
- PROCEDURE OutCharXY( X,Y : CARDINAL; Ch : CHAR);
- (* Gibt ein Zeichen an der vorgegebenen Stelle aus *)
- VAR Lvec : CARDINAL;
- XVec, YVec : SHORTINT;
- WertX, WertY,
- OldX, OldY : CARDINAL;
- MinCh : CHAR;
- PixelH : SHORTINT;
- WriteIt : BOOLEAN;
-
- BEGIN
- MinCh :=ActStyle.Header^.MinChar;
- PixelH:=ActStyle.Header^.PixelH;
- IF (Ch<MinCh)
- OR (SHORTCARD(Ch)
- >= SHORTCARD(MinCh)+ActStyle.Header^.TblSize) THEN
- RETURN
- END;
- OldX:=X;
- OldY:=Y;
- WITH ActStyle DO
- Lvec:=Address^[SHORTCARD(Ch)-SHORTCARD(MinCh)];
- LOOP
- XVec:=SHORTINT(Vec^[Lvec ]);
- YVec:=SHORTINT(Vec^[Lvec+1]);
- IF 7 IN Tiny(XVec) THEN
- WriteIt:= 7 IN Tiny(YVec);
- XVec:=(XVec << 1) >> 1;
- YVec:=(YVec << 1) >> 1;
- WertX:= CARDINAL(INTEGER(X)
- +(INTEGER(XVec)
- *INTEGER(ScaleX)) DIV 16);
- WertY:= CARDINAL(INTEGER(Y)
- -(INTEGER(YVec-PixelH)
- * INTEGER(ScaleY)) DIV 16);
- IF WriteIt THEN
- Line(OldX,OldY,WertX,WertY,NumColor-1);
- END;
- OldX:=WertX;
- OldY:=WertY;
- INC(Lvec,2);
- ELSE
- IF NOT (7 IN Tiny(YVec)) THEN
- EXIT;
- END;
- END;
- END; (* LOOP *)
- END (* WITH *)
- END OutCharXY;
-
- PROCEDURE OutTextXY( X,Y : CARDINAL; Text : ARRAY OF CHAR);
- (* Gibt einen Text an der vorgegebenen Stelle aus *)
- VAR Lauf : CARDINAL;
- MinCh : SHORTCARD;
- TextH : CARDINAL;
-
- BEGIN
- TextH:=TextHeight(Text);
- MinCh := SHORTCARD(ActStyle.Header^.MinChar);
- FOR Lauf:=0 TO Length(Text) DO
- IF X >= Width THEN RETURN; END;
- IF Y >= Depth THEN RETURN; END;
- OutCharXY( X,Y,Text[Lauf]);
- IF (Text[Lauf]>=CHAR(MinCh))
- AND (SHORTCARD(Text[Lauf])
- < MinCh+ActStyle.Header^.TblSize) THEN
- IF Horiz THEN
- INC(X,(INTEGER(ScaleX)
- *INTEGER(ActStyle.Width
- ^[SHORTCARD(Text[Lauf])-MinCh]))
- DIV 16 );
- ELSE
- INC(Y, TextH);
- END;
- END;
- END;
- END OutTextXY;
-
- PROCEDURE TextHeight(Text : ARRAY OF CHAR) : CARDINAL;
- (* Gibt die Texthöhe zurück
- (abhängig von Textart und Skalierung) *)
- BEGIN
- WITH ActStyle.Header^ DO
- RETURN
- CARDINAL(((INTEGER(PixelH) - INTEGER(UnderL))
- * INTEGER(ScaleY))) DIV 16;
- END;
- END TextHeight;
-
- PROCEDURE TextWidth( Text : ARRAY OF CHAR) : CARDINAL;
- (* Gibt die Textbreite zurück *)
- VAR W,Lauf : CARDINAL;
- MinCh : SHORTCARD;
- BEGIN
- MinCh:=SHORTCARD(ActStyle.Header^.MinChar);
- Lauf:=1; W:=0;
- FOR Lauf:=0 TO Length(Text) DO
- IF (Text[Lauf]>=CHAR(MinCh))
- AND (SHORTCARD(Text[Lauf])
- < MinCh+ActStyle.Header^.TblSize) THEN
- INC(W,CARDINAL(ActStyle.Width
- ^[SHORTCARD(Text[Lauf]) - MinCh]));
- END;
- END;
- RETURN ( W * CARDINAL(ScaleX)) DIV 16;
- END TextWidth;
- (*$V+*)
-
- BEGIN
- FOR i := 0 TO MaxTable DO
- IdentTable[i] := "";
- END;
- IdentTable[0] := ""; (* Wäre der Rasterfont *)
- IdentTable[1] := "TRIP";
- IdentTable[2] := "LITT";
- IdentTable[3] := "SANS";
- IdentTable[4] := "GOTH";
- MaxEntry:=5;
- END Chr.