|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 14800 (0x39d0)
Types: TextFile
Names: »aed512vdu.mod«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
└─⟦this⟧ »./DVIware/crt-viewers/others/dvitovdu/src/aed512vdu.mod«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z«
└─⟦ca79c7339⟧
└─⟦this⟧ »DVIware/crt-viewers/others/dvitovdu/src/aed512vdu.mod«
IMPLEMENTATION MODULE aed512vdu;
(* Author: Andrew Trevorrow
Implementation: Modula-2 under VAX/UNIX 4.2 BSD
Date Started: June, 1986
Description:
Implements the InitAED512 procedure that initializes the generic VDU
routines and parameters used in DVItoVDU.
The AED512 screen is 483 or 512 pixels high (depending on monitor) and
512 pixels wide. The variable screenht will be set to 512 for the AED512
and 483 for the AED483 (see InitVDUInterface).
The bottom left pixel is the point (x=0,y=0); x coordinates
increase to the right and y coordinates increase up the screen.
DVItoVDU uses a coordinate scheme in which horizontal (=h) coordinates
also increase to the right but vertical (=v) coordinates increase DOWN the
screen, i.e. the top left pixel on the screen is the point (h=0,v=0).
This means that the AED512 routines will have to do a
simple translation of the vertical coordinates passed by DVItoVDU.
DVItoVDU assumes text lines on the screen start at 1 and increase downwards.
*)
FROM vduinterface IMPORT
DVIstatusl, windowstatusl, messagel, commandl, bottoml,
windowh, windowv, windowwd, windowht,
TeXtoASCII,
StartText, MoveToTextLine, ClearTextLine, ClearScreen,
StartGraphics, LoadFont, ShowChar, ShowRectangle,
ResetVDU;
FROM screenio IMPORT
Write, WriteString, WriteBuffer;
CONST
ALPHA = 1C; (* SOH = enter Alpha mode *)
INTER = 33C; (* ESC = enter Interpreter mode *)
FF = 14C; (* form feed to erase screen *)
SAP = '^'; (* select Alpha parameters for char size *)
MOV = 'Q'; (* move CAP to absolute x,y position;
CAP = Current Access Position *)
DVA = 'A'; (* draw vector from CAP to absolute x,y position *)
DFR = 'o'; (* draw filled rectangle with one corner at CAP and
opposite corner at absolute x,y position *)
SEC = 'C'; (* set current writing colour *)
SBC = '['; (* set background colour *)
green = 2C; (* my writing colour; better than default red *)
black = 0C; (* my background colour; also the default *)
lineht = 9; (* height in pixels of my default text line *)
charwidth1 = 6; (* 5*8 font for dialogue region; 85 chars per line *)
charwidth2 = 8; (* normal 7*12 font; 64 chars per line *)
charwidth3 = 12; (* double 5*8 font; 42 chars per line *)
charwidth4 = 16; (* double 7*12 font; 32 chars per line *)
TYPE
xycoords = [0..511];
VAR
maxy : CARDINAL; (* screenht - 1 *)
loadedwidth, (* remember charwidth set by last LoadFont *)
charwidth : CARDINAL; (* used to select Alpha font *)
(******************************************************************************)
PROCEDURE InitAED512;
(* The dialogue region will be the top 4 text lines in Alpha mode.
The window region will be the remaining screen area.
*)
BEGIN
DVIstatusl := 1; (* DVItoVDU assumes top text line = 1 *)
windowstatusl := 2;
messagel := 3;
commandl := 4;
maxy := CARDINAL(screenht) - 1;
bottoml := screenht DIV lineht; (* number of text lines on AED512 screen *)
windowv := 4 * lineht + 5; (* height in pixels of dialogue region *)
windowh := 0;
windowht := screenht - windowv;
windowwd := 512;
ClearTextLine := AED512ClearTextLine;
MoveToTextLine := AED512MoveToTextLine;
ClearScreen := AED512ClearScreen;
StartText := AED512StartText;
StartGraphics := AED512StartGraphics;
LoadFont := AED512LoadFont;
ShowChar := AED512ShowChar;
ShowRectangle := AED512ShowRectangle;
ResetVDU := AED512ResetVDU;
Write(INTER);
Write(SBC); (* make sure black is the background colour *)
Write(black);
Write(SEC); (* change writing colour to green; easier to read than red *)
Write(green);
Write('('); (* programmable option *)
Write(6C);
Write(1C); (* override any overlapping TEK4010 commands,
regardless of option switch 4! *)
charwidth := charwidth1; (* font for dialogue region *)
loadedwidth := charwidth; (* for first StartGraphics call *)
SelectAlphaFont;
END InitAED512;
(******************************************************************************)
PROCEDURE AED512StartText;
BEGIN
Write(ALPHA);
END AED512StartText;
(******************************************************************************)
PROCEDURE AED512MoveToTextLine (line : CARDINAL);
(* Move to start of given text line; at the end of this routine we must
be ready to display default Alpha characters.
*)
BEGIN
Write(INTER);
Write(MOV);
SendXY(0,maxy-(line*lineht));
charwidth := charwidth1; (* use default Alpha font *)
SelectAlphaFont;
END AED512MoveToTextLine;
(******************************************************************************)
PROCEDURE SendXY (x, y : xycoords);
(* Assuming non-mnemonic 8-bit encoding (the default),
send the 3 bytes representing the given x,y address.
*)
BEGIN
Write(CHR((x DIV 256) * 16 + (y DIV 256))); (* x11,x10,x9,x8,y11,y10,y9,y8 *)
Write(CHR(x MOD 256)); (* x7 ,x6 , ... ,x0 *)
Write(CHR(y MOD 256)); (* y7 ,y6 , ... ,y0 *)
END SendXY;
(******************************************************************************)
PROCEDURE SelectAlphaFont;
(* Select a new Alpha font depending on the current value of charwidth
and prepare to display Alpha text.
charwidth is charwidth1 initially; changed in MoveToTextLine and LoadFont.
*)
BEGIN
Write(INTER);
Write(SAP); (* select Alpha parameters *)
CASE charwidth OF
charwidth1
: Write('1'); (* normal sized *)
Write('5'); (* 5*8 font *)
Write(CHR(charwidth1)); (* default hspace *)
Write(CHR(lineht)); (* default vspace *)
|
charwidth2
: Write('1'); (* normal sized *)
Write('7'); (* 7*12 font *)
Write(CHR(charwidth2));
Write(15C); (* vspace = 13 *)
|
charwidth3
: Write('2'); (* double sized *)
Write('5'); (* 5*8 font *)
Write(CHR(charwidth3));
Write(22C); (* vspace = 18 *)
|
charwidth4
: Write('2'); (* double sized *)
Write('7'); (* 7*12 font *)
Write(CHR(charwidth4));
Write(32C); (* vspace = 26 *)
ELSE
WriteString('Bug in AED512VDU! Illegal charwidth!');
END;
Write('L'); (* Alpha cursor position identical with CAP *)
Write(ALPHA);
END SelectAlphaFont;
(******************************************************************************)
PROCEDURE AED512ClearTextLine (line : CARDINAL);
(* Erase given text line; note that DVItoVDU does not assume anything about
the location of the cursor after this routine is called.
*)
BEGIN
Write(INTER);
Write(SEC);
Write(black); (* set writing colour to background temporarily *)
Write(MOV);
SendXY(0, (* set CAP to bottom left corner of text line *)
maxy-(line*lineht)-2); (* ensure g,j,p... descenders are erased *)
Write(DFR); (* draw filled rectangle to top right corner *)
SendXY(511,maxy-(line*lineht)+(lineht-3));
Write(SEC);
Write(green); (* back to green *)
Write(ALPHA); (* safer to leave in Alpha mode *)
END AED512ClearTextLine;
(******************************************************************************)
PROCEDURE AED512ClearScreen;
BEGIN
Write(INTER);
Write(FF); (* erase screen and return cursor to home position;
also exits Interpreter *)
(* preferable to ERS = '~' which has some problems with setting x,y origin *)
END AED512ClearScreen;
(******************************************************************************)
PROCEDURE AED512StartGraphics;
BEGIN
IF charwidth <> loadedwidth THEN (* graphics mode was interrupted *)
charwidth := loadedwidth;
SelectAlphaFont; (* restore font selected in last LoadFont *)
END;
Write(INTER);
END AED512StartGraphics;
(******************************************************************************)
PROCEDURE AED512LoadFont (fontname : ARRAY OF CHAR;
fontsize : CARDINAL;
mag, hscale, vscale : REAL);
(* AED512 uses the given information to select an appropriate character size
(based on horizontal scaling only!) for future calls of ShowChar.
DVItoVDU only calls this routine in graphics mode.
*)
VAR newwidth : CARDINAL;
BEGIN
(* convert fontsize into scaled screen pixels using mag and hscale *)
fontsize := TRUNC( FLOAT(fontsize) * mag * hscale + 0.5 );
(* Chooose one of the 4 Alpha mode character sizes based on fontsize:
charwidth max chars/line fontsize range
1 85 0..20
2 64 21..40
3 42 41..60
4 32 61...
The fontsize ranges were chosen by trial and error.
*)
IF fontsize < 21 THEN
newwidth := charwidth1;
ELSIF fontsize < 41 THEN
newwidth := charwidth2;
ELSIF fontsize < 61 THEN
newwidth := charwidth3;
ELSE
newwidth := charwidth4;
END;
loadedwidth := newwidth; (* remember for ShowChar *)
IF charwidth <> newwidth THEN (* change needed *)
charwidth := newwidth;
SelectAlphaFont;
END;
Write(INTER); (* must exit in graphics mode *)
END AED512LoadFont;
(******************************************************************************)
PROCEDURE AED512ShowChar (screenh, screenv : CARDINAL;
ch : CHAR);
(* We show the given character (mapping TeX text character to ASCII) using
the given reference point and the charwidth selected by the last LoadFont.
DVItoVDU only uses this routine in a Terse display.
Note that Alpha characters g,j,p,q,y have descenders that fall below their
reference point; when baselines appear near the bottom of the screen the
descenders will wrap to the top.
*)
VAR newch : CHAR; (* = TeXtoASCII[ch] *)
BEGIN
(* shift character left if it will overlap right edge of screen *)
IF screenh + charwidth > 511 THEN
screenh := 511 - charwidth;
END;
(* DVItoVDU only calls ShowChar in graphics mode *)
Write(MOV);
SendXY(screenh,maxy-screenv); (* move cursor to reference point *)
(* We use TeXtoASCII to map ch into a comparable ASCII character, apart
from most of the ? characters which we attempt to simulate.
*)
Write(ALPHA);
newch := TeXtoASCII[ch];
IF newch <> '?' THEN
(* newch is similar to TeX ch *)
Write(newch);
ELSE
(* attempt to display something other than ? *)
CASE ch OF
13C..17C : (* ff, fi, fl, ffi, ffl *)
Write('f');
(* only simulate rest of ligature if room at right edge *)
IF screenh + 2 * charwidth - (charwidth DIV 2) <= 511 THEN
Write(INTER);
Write(MOV);
SendXY(screenh + charwidth - (charwidth DIV 2),maxy-screenv);
Write(ALPHA);
CASE ch OF
13C : Write('f') |
14C : Write('i') |
15C : Write('l') |
16C,
17C : Write('f');
IF screenh + 3 * charwidth - 2 * (charwidth DIV 2) <= 511 THEN
Write(INTER);
Write(MOV);
SendXY(screenh + 2 * charwidth - 2 * (charwidth DIV 2),
maxy-screenv);
Write(ALPHA);
IF ch = 16C THEN
Write('i');
ELSE
Write('l');
END;
END;
END;
END;
|
31C : Write('B'); (* German sharp S *)
|
32C, 33C, 35C, 36C : (* diphthongs: ae, oe, AE, OE *)
CASE ch OF
32C : Write('a') |
33C : Write('o') |
35C : Write('A') |
36C : Write('O')
END;
IF screenh + 2 * charwidth - (charwidth DIV 2) <= 511 THEN
Write(INTER);
Write(MOV);
SendXY(screenh + charwidth - (charwidth DIV 2),maxy-screenv);
Write(ALPHA);
CASE ch OF
32C, 33C : Write('e') |
35C, 36C : Write('E')
END;
END;
|
40C : Write("'"); (* Polish suppressed l and L *)
ELSE
Write('?');
END;
END;
Write(INTER); (* must exit in graphics mode *)
END AED512ShowChar;
(******************************************************************************)
PROCEDURE AED512ShowRectangle (screenh, screenv, (* top left pixel *)
width, height : CARDINAL; (* of rectangle *)
ch : CHAR); (* black pixel *)
(* Display the given rectangle without using the given black pixel character.
We assume that the top left position is correct and that the given
dimensions do not go beyond the screen edges.
We assume DVItoVDU is in graphics mode.
*)
VAR pos : CARDINAL;
BEGIN
IF height = 1 THEN (* show row vector *)
pos := maxy-screenv;
Write(MOV);
SendXY(screenh,pos); (* move cursor to start of row *)
Write(DVA);
SendXY(screenh+width-1,pos); (* draw vector to end of row *)
ELSIF width = 1 THEN (* show column vector *)
Write(MOV);
SendXY(screenh,maxy-screenv); (* move cursor to start of column *)
Write(DVA);
SendXY(screenh,maxy-(screenv+height-1)); (* draw vector to end of column *)
ELSE (* assume height and width > 1 *) (* draw filled rectangle *)
Write(MOV);
SendXY(screenh,maxy-screenv); (* CAP to top left corner *)
Write(DFR);
SendXY(screenh+width-1,
maxy-(screenv+height-1)); (* fill to bottom right corner *)
END;
END AED512ShowRectangle;
(******************************************************************************)
PROCEDURE AED512ResetVDU;
(* We DON'T reset AED512 to power-up state; we leave AED using green as the
writing colour and set font back to power-up values.
Such decisions may not please other AED sites, but I was talked into them
by our AED users (all 2 of them!).
*)
BEGIN
Write(INTER);
Write(SAP); (* select Alpha parameters *)
Write('1'); (* normal sized *)
Write('7'); (* 7*12 font *)
Write(10C); (* hspace = 8 *)
Write(14C); (* vspace = 12 *)
Write('L'); (* Alpha cursor position identical with CAP *)
Write(ALPHA); (* exit in Alpha mode *)
END AED512ResetVDU;
(******************************************************************************)
BEGIN
screenht := 512; (* changed in InitVDUInterface to 483 for the AED483 *)
END aed512vdu.