|
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: 14984 (0x3a88) Types: TextFile Names: »aed512vdu.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦883b7f77d⟧ »dvi2vdu.tar.Z« └─⟦f158c222e⟧ └─⟦this⟧ »dvi2vdu/dvi2vdu-1.1J/src/aed512vdu.c«
/* Original 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. This version converted to C and ported to BSD and System V UNIX by some chaps at Kernel Technology up to September 1989. Contact mjh@uk.co.kernel (Mark J. Hewitt) with bug fixes etc. Involved were: Mark J. Hewitt Dave Dixon Marc Hadley */ #include "def.h" static char *sccsid[] = "@(#)aed512vdu.c 1.1"; void InitAED512 (); Void AED512StartText (); Void AED512MoveToTextLine (); Void SendXY (); Void SelectAlphaFont (); Void AED512ClearTextLine (); Void AED512ClearScreen (); Void AED512StartGraphics (); Void AED512LoadFont (); Void AED512ShowChar (); Void AED512ShowRectangle (); Void AED512ResetVDU (); #define ALPHA '\1' /* SOH = enter Alpha mode */ #define INTER ESC /* ESC = enter Interpreter mode */ #define ERASE FF /* form feed to erase screen */ #define SAP '^' /* select Alpha parameters for char size */ #define MOV 'Q' /* move CAP to absolute x,y position; CAP = Current Access Position */ #define DVA 'A' /* draw vector from CAP to absolute x,y pos */ #define DFR 'o' /* draw filled rectangle with one corner at CAP nd opposite corner at absolute x,y position */ #define SEC 'C' /* set current writing colour */ #define SBC '[' /* set background colour */ #define GREEN '\2' /* my writing colour; better than default red */ #define BLACK '\0' /* my background colour; also the default */ #define LINEHT 9 /* height in pixels of my default text line */ #define CHARWIDTH1 6 /* 5*8 fnt for dialogue region; 85 chs per lne */ #define CHARWIDTH2 8 /* normal 7*12 font; 64 chars per line */ #define CHARWIDTH3 12 /* double 5*8 font; 42 chars per line */ #define CHARWIDTH4 16 /* double 7*12 font; 32 chars per line */ int screenht = 512; /* AED screen can be 512 or 483 pixels high */ typedef short xycoords; unsigned int maxy, /* screenht - 1 */ loadedwidth, /* remember charwidth set by last LoadFont */ charwidth; /* used to select Alpha font */ /******************************************************************************/ /* The dialogue region will be the top 4 text lines in Alpha mode. The window region will be the remaining screen area. */ void InitAED512 () { DVIstatusl = 1; /* DVItoVDU assumes top text line = 1 */ windowstatusl = 2; messagel = 3; commandl = 4; maxy = ((unsigned) screenht) - 1; bottoml = screenht / 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 (((char) 06)); Write (((char) 01)); /* override any overlapping TEK4010 commands, regardless of option switch 4! */ charwidth = CHARWIDTH1; /* font for dialogue region */ loadedwidth = charwidth; /* for first StartGraphics call */ SelectAlphaFont (); } /******************************************************************************/ Void AED512StartText () { Write (ALPHA); } /******************************************************************************/ Void AED512MoveToTextLine (line) unsigned int line; { /* Move to start of given text line; at the end of this routine we must be ready to display default Alpha characters. */ Write (INTER); Write (MOV); SendXY (0, (short) (maxy - (line * LINEHT))); charwidth = CHARWIDTH1; /* use default Alpha font */ SelectAlphaFont (); } /******************************************************************************/ Void SendXY (x, y) xycoords x, y; { /* Assuming non-mnemonic 8-bit encoding (the default), send the 3 bytes representing the given x,y address. */ Write ((char) ((x / 256) * 16 + (y / 256)));/* x11,x10,x9,x8,y11,y10,y9,y8 */ Write ((char) (x % 256)); /* x7 ,x6 , ... ,x0 */ Write ((char) (y % 256)); /* y7 ,y6 , ... ,y0 */ } /******************************************************************************/ Void 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. */ Write (INTER); Write (SAP); /* select Alpha parameters */ switch (charwidth) { case CHARWIDTH1: { Write ('1'); /* normal sized */ Write ('5'); /* 5*8 font */ Write ((char) (CHARWIDTH1));/* default hspace */ Write ((char) (LINEHT));/* default vspace */ break; } case CHARWIDTH2: { Write ('1'); /* normal sized */ Write ('7'); /* 7*12 font */ Write ((char) (CHARWIDTH2)); Write ((char) 015); /* vspace = 13 */ break; } case CHARWIDTH3: { Write ('2'); /* double sized */ Write ('5'); /* 5*8 font */ Write ((char) (CHARWIDTH3)); Write ((char) 022); /* vspace = 18 */ break; } case CHARWIDTH4: { Write ('2'); /* double sized */ Write ('7'); /* 7*12 font */ Write ((char) (CHARWIDTH4)); Write ((char) 032); /* vspace = 26 */ break; } default: WriteString ("Bug in AED512VDU! Illegal charwidth!"); } Write ('L'); /* Alpha cursor position identical with CAP */ Write (ALPHA); } /******************************************************************************/ Void AED512ClearTextLine (line) unsigned int line; { /* Erase given text line; note that DVItoVDU does not assume anything about the location of the cursor after this routine is called. */ Write (INTER); Write (SEC); Write (BLACK); /* set writing colour to background temporarily */ Write (MOV); SendXY (0, (short) (maxy - (line * LINEHT) - 2)); /* ensure g,j,p... descenders are erased */ Write (DFR); /* draw filled rectangle to top right corner */ SendXY (511, (short) (maxy - (line * LINEHT) + (LINEHT - 3))); Write (SEC); Write (GREEN); /* back to green */ Write (ALPHA); /* safer to leave in Alpha mode */ } /******************************************************************************/ Void AED512ClearScreen () { Write (INTER); Write (ERASE); /* erase screen and return cursor to home position; also exits Interpreter */ /* preferable to ERS = '~' which has some problems with setting x,y origin */ } /******************************************************************************/ Void AED512StartGraphics () { if (charwidth != loadedwidth) { /* graphics mode was interrupted */ charwidth = loadedwidth; SelectAlphaFont (); /* restore font selected in last LoadFont */ } Write (INTER); } /******************************************************************************/ /* 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. */ /*ARGSUSED*/ Void AED512LoadFont (fontname, fontsize, localmag, hscale, vscale) char fontname[]; unsigned int fontsize; float localmag, hscale, vscale; { unsigned int newwidth; /* convert fontsize into scaled screen pixels using localmag and hscale */ fontsize = (int) (((float) fontsize) * localmag * 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) newwidth = CHARWIDTH1; else if (fontsize < 41) newwidth = CHARWIDTH2; else if (fontsize < 61) newwidth = CHARWIDTH3; else newwidth = CHARWIDTH4; loadedwidth = newwidth; /* remember for ShowChar */ if (charwidth != newwidth) /* change needed */ { charwidth = newwidth; SelectAlphaFont (); } Write (INTER); /* must exit in graphics mode */ } /******************************************************************************/ /* 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. */ Void AED512ShowChar (screenh, screenv, ch) unsigned int screenh, screenv; char ch; { char newch; /* = TeXtoASCII[ch] */ /* shift character left if it will overlap right edge of screen */ if ((screenh + charwidth) > 511) screenh = 511 - charwidth; /* DVItoVDU only calls ShowChar in graphics mode */ Write (MOV); SendXY ((short) (screenh), (short) (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 != '?') /* newch is similar to TeX ch */ { Write (newch); } else /* attempt to display something other than ? */ { switch (ch) { case '\13': case '\14': case '\15': case '\16': case '\17': /* ff, fi, fl, ffi, ffl */ { Write ('f'); /* only simulate rest of ligature if room at right edge */ if (screenh + 2 * charwidth - (charwidth / 2) <= 511) { Write (INTER); Write (MOV); SendXY ((short) (screenh + charwidth - (charwidth / 2)), (short) (maxy - screenv)); Write (ALPHA); switch (ch) { case 13: Write ('f'); break; case 14: Write ('i'); break; case 5: Write ('l'); break; case 16: case 17: { Write ('f'); if (screenh + 3 * charwidth - 2 * (charwidth / 2) <= 511) { Write (INTER); Write (MOV); SendXY ((short) (screenh + 2 * charwidth - 2 * (charwidth / 2)), (short) (maxy - screenv)); Write (ALPHA); if (ch == 016) Write ('i'); else Write ('l'); } } } } break; } case 31: Write ('B'); break; /* German sharp S */ case 32: case 33: case 35: case 36: /* diphthongs: ae, oe, AE, OE */ { switch (ch) { case 32: Write ('a'); break; case 33: Write ('o'); break; case 35: Write ('A'); break; case 36: Write ('O'); break; } if (screenh + 2 * charwidth - (charwidth / 2) <= 511) { Write (INTER); Write (MOV); SendXY ((short) (screenh + charwidth - (charwidth / 2)), (short) (maxy - screenv)); Write (ALPHA); switch (ch) { case 32: case 33: { Write ('e'); break; } case 35: case 36: { Write ('E'); } } } break; } case 40: { Write ('\''); break; /* Polish suppressed l and L */ } default: Write ('?'); } } Write (INTER); /* must exit in graphics mode */ } /******************************************************************************/ /* 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. */ /*ARGSUSED*/ Void AED512ShowRectangle (screenh, screenv, width, height, ch)/* black pixel */ unsigned int screenh, screenv, width, height; char ch; { unsigned int pos; if (height == 1) { /* show row vector */ pos = maxy - screenv; Write (MOV); SendXY ((short) (screenh), (short) (pos));/* move cursor to start of row */ Write (DVA); SendXY ((short) (screenh + width - 1), (short) (pos)); /* draw vector to end of row */ } else if (width == 1) { /* show column vector */ Write (MOV); SendXY ((short) (screenh), (short) (maxy - screenv)); /* move cursor to start of column */ Write (DVA); SendXY ((short) (screenh), (short) (maxy - (screenv + height - 1))); /* draw vector to end of column */ } else /* assume height and width > 1 *//* draw filled rectangle */ { Write (MOV); SendXY ((short) (screenh), (short) (maxy - screenv)); /* CAP to top left corner */ Write (DFR); SendXY ((short) (screenh + width - 1), (short) (maxy - (screenv + height - 1))); /* fill to bottom right corner */ } } /******************************************************************************/ Void 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!). */ Write (INTER); Write (SAP); /* select Alpha parameters */ Write ('1'); /* normal sized */ Write ('7'); /* 7*12 font */ Write ((char) 010); /* hspace = 8 */ Write ((char) 14); /* vspace = 12 */ Write ('L'); /* Alpha cursor position identical with CAP */ Write (ALPHA); /* exit in Alpha mode */ } /******************************************************************************/ /* screenht changed in InitVDUInterface() to 483 for the AED483 */