|
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 t
Length: 11327 (0x2c3f) Types: TextFile Names: »tek4010vdu.mod«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./DVIware/crt-viewers/others/dvitovdu/src/tek4010vdu.mod« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/crt-viewers/others/dvitovdu/src/tek4010vdu.mod«
IMPLEMENTATION MODULE tek4010vdu; (* Author: Andrew Trevorrow Implementation: Modula-2 under VAX/UNIX 4.2 BSD Date Started: June, 1986 Description: Implements the routines used in VDU-specific modules that emulate a Tektronix 4010 terminal (VIS500/550, VT640). The screen is assumed to be 780 pixels high by 1024 pixels wide. (The actual resolution of an emulating screen may be different, but such terminals provide automatic scaling.) 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 Tektronix 4010 routines will have to do a simple translation of the vertical coordinates passed by DVItoVDU. *) FROM vduinterface IMPORT TeXtoASCII; FROM screenio IMPORT Write; CONST ESC = 33C; FF = 14C; FS = 34C; GS = 35C; US = 37C; VAR oldhiy, (* for remembering old address in SendXY *) oldhix, oldloy : CARDINAL; charwidth, (* set by LoadFont and used in ShowChar *) loadedsize, (* remember alpha size set by last LoadFont; VT640, VIS500/550 VDUs don't actually need to worry about this since they use non-TEK4010 fonts to draw in dialogue region. VIS240 however uses alpha mode font. *) charsize : CARDINAL; (* used to select alpha character size *) (******************************************************************************) PROCEDURE SendXY (x, y : CARDINAL); (* Translates the given screen address into 4 bytes. havesentxy is used to minimize the number of bytes sent: after the first 4 bytes have been sent, subsequent bytes that don't change need not be sent (except for the low x byte which is always sent). If the high x byte changes then the low y byte must also be sent. *) VAR hiy, loy, hix, lox : CARDINAL; sendhix : BOOLEAN; BEGIN (* we assume y is in [0..maxy] and x is in [0..1023] *) hiy := ORD(' ') + (y DIV 32); hix := ORD(' ') + (x DIV 32); loy := ORD('`') + (y MOD 32); lox := ORD('@') + (x MOD 32); IF havesentxy THEN IF hiy <> oldhiy THEN Write(CHR(hiy)); oldhiy := hiy; END; sendhix := hix <> oldhix; IF (loy <> oldloy) OR sendhix THEN Write(CHR(loy)); oldloy := loy; END; IF sendhix THEN Write(CHR(hix)); oldhix := hix; END; Write(CHR(lox)); ELSE (* send first 4 bytes *) Write(CHR(hiy)); oldhiy := hiy; Write(CHR(loy)); oldloy := loy; Write(CHR(hix)); oldhix := hix; Write(CHR(lox)); havesentxy := TRUE; END; (* SYSDEP: We assume XON/XOFF flow control is enabled to avoid data loss. *) END SendXY; (******************************************************************************) PROCEDURE TEK4010StartText; (* DVItoVDU will only call MoveToTextLine, ClearTextLine, ClearScreen and ResetVDU while in text mode. *) BEGIN Write(US); END TEK4010StartText; (******************************************************************************) PROCEDURE TEK4010MoveToTextLine (line : CARDINAL); (* Move cursor to start of given line using lineht. At the end of this routine we must be in alpha mode and ready to display characters in the default charsize. *) BEGIN Write(GS); (* switch to graphics mode *) SendXY(0,maxy+1 - (line*lineht)); Write(ESC); (* reset alpha character size *) Write('0'); charsize := 0; charwidth := 13; Write(US); (* back to alpha mode *) END TEK4010MoveToTextLine; (******************************************************************************) PROCEDURE TEK4010ClearScreen; BEGIN Write(GS); (* make sure we're in graphics mode *) Write(ESC); Write(FF); (* erase graphics and put in alpha mode *) havesentxy := FALSE; (* ESC FF will home cursor *) charsize := 0; (* ESC FF resets character size *) charwidth := 13; END TEK4010ClearScreen; (******************************************************************************) PROCEDURE TEK4010StartGraphics; (* DVItoVDU will only call LoadFont, ShowChar and ShowRectangle while in graphics mode. *) BEGIN IF charsize <> loadedsize THEN (* graphics mode was interrupted *) charsize := loadedsize; dragdown := (charsize + 1) * 5; (* used by VIS500/550 ShowChar *) Write(GS); Write(ESC); Write(CHR(ORD('0')+charsize)); (* recall last LoadFont character size *) END; Write(GS); havesentxy := FALSE; (* safer to send all location bytes anew *) END TEK4010StartGraphics; (******************************************************************************) PROCEDURE TEK4010LoadFont (fontname : ARRAY OF CHAR; fontsize : CARDINAL; mag, hscale, vscale : REAL); (* Use the given fontsize to select an appropriate character size (based on horizontal scaling only!) for future ShowChar calls. *) VAR newsize : 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: charsize max chars/line relative size fontsize range 0 80 x1 0..40 1 40 x2 41..80 2 26 x3 81..120 3 20 x4 121... The fontsize ranges were chosen by trial and error. *) IF fontsize < 41 THEN newsize := 0; charwidth := 13; (* 1024/80 = 12.8 *) ELSIF fontsize < 81 THEN newsize := 1; charwidth := 26; (* 1024/40 = 25.6 *) ELSIF fontsize < 121 THEN newsize := 2; charwidth := 40; (* 1024/26 = 39.4 *) ELSE newsize := 3; charwidth := 52; (* 1024/20 = 51.2 *) END; loadedsize := newsize; (* remember in case graphics mode is interrupted *) IF charsize <> newsize THEN (* change character size *) charsize := newsize; Write(ESC); Write(CHR(ORD('0')+charsize)); END; (* Alpha character reference pts on some emulating VDUs (VIS500/550) are below baselines to allow for descenders. Such VDUs can use dragdown to drag baselines down to TeX reference pts when calling ShowChar. *) dragdown := (charsize + 1) * 5; (* used by VIS500/550 ShowChar *) Write(GS); (* must exit in graphics mode *) END TEK4010LoadFont; (******************************************************************************) PROCEDURE TEK4010ShowChar (screenh, screenv : CARDINAL; ch : CHAR); (* Show the given Terse character (mapped to ASCII) at the given ref pt. We use the charwidth set by last LoadFont call. *) VAR newch : CHAR; (* = TeXtoASCII[ch] *) BEGIN (* shift character left if it will overlap right edge of screen *) IF screenh + charwidth > 1023 THEN screenh := 1023 - charwidth; END; (* we assume StartGraphics, LoadFont or last ShowChar has just sent GS *) SendXY(screenh,maxy-screenv); (* move cursor to ref pt *) (* We use TeXtoASCII to map ch into a comparable ASCII character, apart from most of the ? characters which we attempt to simulate. *) Write(US); (* enter alpha mode *) 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) <= 1023 THEN Write(GS); SendXY(screenh + charwidth - (charwidth DIV 2),maxy-screenv); Write(US); CASE ch OF 13C : Write('f') | 14C : Write('i') | 15C : Write('l') | 16C, 17C : Write('f'); IF screenh + 3 * charwidth - 2 * (charwidth DIV 2) <= 1023 THEN Write(GS); SendXY(screenh + 2 * charwidth - 2 * (charwidth DIV 2), maxy-screenv); Write(US); 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) <= 1023 THEN Write(GS); SendXY(screenh + charwidth - (charwidth DIV 2),maxy-screenv); Write(US); CASE ch OF 32C, 33C : Write('e') | 35C, 36C : Write('E') END; END; | 34C, 37C : (* Scandinavian slashed o and O *) CASE ch OF 34C : Write('o') | 37C : Write('O') END; Write(GS); SendXY(screenh,maxy-screenv); (* overwrite *) Write(US); Write('/'); | 40C : Write("'"); (* Polish suppressed l and L *) ELSE Write('?'); END; END; Write(GS); (* must exit in graphics mode *) END TEK4010ShowChar; (******************************************************************************) PROCEDURE TEK4010ShowRectangle (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). DVItoVDU ensures that the top left position is visible and that the given dimensions do not go beyond the window edges. *) VAR i, endpt : CARDINAL; BEGIN (* DVItoVDU ensures width and height > 0 *) IF height < width THEN (* show row vectors *) endpt := screenh+width-1; FOR i := 0 TO height-1 DO Write(GS); SendXY(screenh,maxy-(screenv+i)); (* move cursor to start of row *) SendXY(endpt,maxy-(screenv+i)); (* draw vector to end of row *) END; ELSE (* show column vectors *) endpt := maxy - (screenv+height-1); FOR i := 0 TO width-1 DO Write(GS); SendXY(screenh+i,maxy-screenv); (* move cursor to start of column *) SendXY(screenh+i,endpt); (* draw vector to end of column *) END; END; END TEK4010ShowRectangle; (******************************************************************************) BEGIN havesentxy := FALSE; (* for first SendXY call *) charsize := 0; (* the default character size *) loadedsize := charsize; (* for first StartGraphics call *) charwidth := 13; (* 1024 / 80 = 12.8 *) maxy := 779; (* some VDUs may want to change this *) lineht := 26; (* 30 text lines; 26 * 30 = 780 *) END tek4010vdu.