Obstacle Avoidance and Navigation in the Real World by a Seeing Robot Rover, Hans Moravec, 1980
<-- Previous  Next -->

## Appendix 10: Spinoffs

### Guide to Data Disc Graphics Routines

to use: REQUIRE “DDHDR.SAI[GRA,HPM]” SOURCE_FILE;

uses: DDFAI.REL[GRA], DDSAI.REL[GRA]

 DDINIT initialize the DD buffer SCREEN(REAL XLO, YLO, XHI, YHI) declare the full screen dimensions SCREEM(REAL XLO, YLO, XHI, YHI) returns the full screen dimensions DRKEN cause subsequent outputs to be dark LITEN cause them to be light INVEN cause them to invert the state of things DOT(X, Y, THICK(0)) display a point at X, Y LINE(X1, Y1, X2, Y2, THICK(0)) display a line RECTAN(X1, Y1, X2, Y2) fill in rectangle ELLIPS(X1, Y1, X2, Y2) fill ellipse bounded by X1, Y1, X2, Y2 POLYGO(N, X[1:N], Y[1:N]) fill in a polygon (concave and star ok) TXTPOS(X, Y, XS, YS, DXS(0), DYS(0)) Position text start at X, Y with general linear transf. First char's corners will be (X, Y), (X+DXS, Y+YS), (X+XS+DXS, Y+YS+DYS), (X+XS, Y+DYS). To make normal horizontal text of characters $W$ wide and $H$ high, do $$TXTPOS(X, Y, W, H, 0, 0)$$ or just $TXTPOS(X, Y, W, H)$. To make sideways text lying on its left side, do $$TXTPOS(X, Y, 0, 0, -H, W)$$ To make text on its right side (reading downwards), do $$TXTPOS(X, Y, 0, 0, H, -W)$$ To make text rotated from the horizontal by an arbitrary angle $T$, do $$TXTPOS(X, Y, W\cos{T}, H\cos{T}, -H\sin{T}, W\sin{T})$$ To make horizontal, italicized, text, do $$TXTPOS(X, Y, W, H, W/2, 0)$$ I leave the other possibilities to you. Consider $XS$ and $YS$ the main diagonal of a $2 \times 2$ matrix that takes a straight, horizontal, prototype character into the skewed, rotated one actually drawn. $DXS$ and $DYS$ are the off-diagonal elements of that matrix. Text can thus be rotated, italicized and reflected. TEXT(STRING) vector text, positioned by previous TXTPOS TEXTD(STRING) dot char text. Look better for tiny, inven CHAN = GDDCHN(CHAN) get a DD channel ($-1$ for any, failure) RDDCHN(CHAN) release a channel ERASE(CHAN) clear a DD channel ($-1$ means yours) DPYUP(CHAN, BUFFER(-1)) Deposit the buffer on DD channel CHAN PJUP send buffer to MOS display on PDP11 SHOW(CHAN, LIN(-1)) video switch LIN ($-1$ for yours) to CHAN SHOWA(CHAN, LIN(-1)) add CHAN to LIN SHOWS(CHAN, LIN(-1)) subtract CHAN from LIN PPPOS(YLO, YHI) position page printer between YLO, YHI XGPUP(SIZE) send the DD buffer to the XGP, SIZE$= -5$ to $+5$ XGPQUE(SIZE) like XGPUP, but creates a new job to do XGPing DDFONT(X1, Y1, X2, Y2, FONTFIL, CHAR(“A”), BASE(0), LKERN(0), RKERN(0)) insert DD buffer bounded by X1, Y1, X2, Y2 into font file. DDPAK(I, LBUF, J1, J2) pack scanline I bet. J1, J2 into LBUF 36 bit/word CHAN = SYNMAP(ORDER) which channels are the video synthesizer's. ORDER = $0$ is most significant $+$ or $-$ $1$ next, etc. SUCCESS = MAPSET(F) set video inten table. F(X) is real $[0, 1] \rightarrow [0, 1]$ SUCCESS = MAPMON(P) set v.i.t. to a monotonic function $X^P$ SUCCESS = MAPGRY(P) set v.i.t. to a gray coded monotonic function $X^P$ LINSCN(N, MAP, DT, LINENO) scan channels in MAP at rate DT MAPSCN(N, MAP, DT, LINENO) LINSCN, but VDS bit maps in MAP SCNOFF turn off the scanning (in SW mode) SCNFRZ SCNOFF, but doesn't restore screen SCNINC(INC) change the stepsize in the scan DDSTOR(DDARRAY) store the buffer in an array DDLOAD(DDARRAY) load the buffer from an array DDOR(DDARRAY) or an array into the buffer DDAND(DDARRAY) and the buffer with an array DDEXCH(DDARRAY) exchange an array with the buffer GETDDF(FILENAME) load the buffer from a file PUTDDF(FILENAME) save the buffer in a file GETMIT(FILENAME) load the buffer from a file PUTMIT(FILENAME) save the buffer in a file FNTSEL(FONT$\#$, “FONTNAME”) define a font $\#$ FNTPOS(XP, YP, XS(1), YS(1), DXS(0), DYS(0)) position & transform fonted text FNTEXT(X, Y, F, TXT) deposit fonted text FNTLIN(X1, Y1, X2, Y2, THICK(0)) draw line in FNTPOS co-ordinates FNTDOT(X1, Y1, THICK(0)) dot in FNTPOS co-ordinates FNTREC(X1, Y1, X2, Y2) rectangle FNTELL(X1, Y1, X2, Y2) ellipse FNTPOL(N, X1[1:N], Y1[1:N]) polygon DDSIZ a constant, the number of words in a DD array

Arguments followed by a value in parens default to the bracketed value.

The absolute physical screen dimension are 512 pixels in $X$ by 481 in $Y$. TEXTD characters are 6 logical pixels in $X$ by 10 in $Y$, spaces included.

Regarding TXTPOS parameters, note that, in terms of character height $H$, character width $W$, clockwise rotation angle $ccwrot$ and clockwise slant angle $ccwslant$ $$\begin{bmatrix} X \\ Y \end{bmatrix} \quad = \quad \begin{bmatrix} {W\cos(ccwrot)} & {H(\cos(ccwrot)\tan(cwslant)-\sin(ccwrot))} \\ {W\sin(ccwrot)} & {H(\sin(ccwrot)\tan(cwslant)+\cos(ccwrot))} \end{bmatrix} \;\begin{bmatrix} x \\ y \end{bmatrix}$$ $$\begin{bmatrix} X \\ Y \end{bmatrix} \quad = \quad \begin{bmatrix}{XS}&{DXS}\\{DYS}&{YS}\end{bmatrix} \;\begin{bmatrix} x \\ y \end{bmatrix}$$ thus $$\begin{matrix} XS & = & W\,\cos(ccwrot)\\ DXS & = & H\,(\cos(ccwrot)\,\tan(cwslant)-\sin(ccwrot))\\ DYS & = & W\,\sin(ccwrot)\\ YS & = & H\,(\sin(ccwrot)\,\tan(cwslant)+\cos(ccwrot))\end{matrix}$$

It might be useful to introduce a parameterization that accepts corner, width, height, rotation and slant angles (degrees): $$TP(X, Y, W, H, CCWROT, CWSLANT)$$

### Guide to GOD Graphics Routines

to use: REQUIRE “GRAHDR.SAI[GOD,HPM]” SOURCE_FILE;

uses: GRASAI.REL[GOD]

The graphics routines on [GOD,HPM] are superficially similar to the ones on [GRA,HPM], but provide an extended device-independent graphics service. To make a drawing one or more devices (graphics servers) must be activated to receive graphics commands. Currently there are servers for Data discs, the XGP and the video synthesizer. In addition the graphics commands can be written into files (called GOD files), which can be displayed later with system programs called DDJOB, XGPJOB and SYNJOB. GOD files can be called as subroutines in graphics programs. GOD files can also be fed to a program called TSTJOB which makes a SAIL program that, if run, recreates the GOD file given to the TSTJOB. Editing the SAIL program provides a way of modifying existing GOD files.

Diagrams in the form of GOD files can be included in documents by the graphics escape features of XGPSYG.

The following calls are provided in addition to the ones in the GRA package.

 JOBID = DDJOB create a server that draws on Data Disc displays. JOBID = XGPJOB create a graphics server that will output on the XGP. JOBID = SYNJOB(HIG(480),WID(512),BIT(9)) make a server that produces gray scale renditions of a drawing. JOBID = FILJOB(“FILENAME”) make a graphics server that writes graphics commands into a GOD file. JOBID = TSTJOB create a server that prints graphics commands as a SAIL program. JOBID = QUASH(JOBID) temporarily deafen a server.It still exists but will not act on subsequent display commands. JOBID = INCITE(JOBID) reactivate a server. Undoes the effect of a QUASH. JOBID = KILJOB(INTEGER JOBID) kill a server. Closes the file opened by a FILJOB, simply expunges all other server types. JOBID = DETJOB(JOBID,GRAFILE) detach a server, but give it a graphics file to process first. Server is lost to main program. GRAFIL(GRAFILE) tell currently active servers to begin processing a graphics file. Afterwards they will be ready to listen to main program again. FNTSEL(FONT$\#$,FONTNAME) select a font, and give it a number $(0-127)$. FNTPOS(XP,YP,XS(1),YS(1),DXS(0),DYS(0)) position a font pixel grid at XP, YP in SCREEN co-ordinates, with transformation set by other four parameters. 1, 1, 0, 0 results in undistorted characters. FNTEXT(X,Y,FONT$\#$,TEXT) deposit TEXT in the indicated font with lower left corner offset (X,Y) font pixels (as distorted by FNTPOS parameters) from the last FNTPOS position. FNTLIN(X1,Y1,X2,Y2,THICK(0)) draw a line between pixel co-ordinates indicated, in grid defined by last FNTPOS. FNTDOT(X1,Y1,THICK(0)) a dot in FNTPOS co-ordinates. FNTREC(X1,Y1,X2,Y2) a FNTPOS rectangle. FNTELL(X1,Y1,X2,Y2) a FNTPOS ellipse. FNTPOL(N,X[1:N],Y[1:N]) a FNTPOS polygon. PICFIL(X1,Y1,X2,Y2,PICFILE) insert a picture in the rectangle bounded in X by X1 and X2 and by Y1 and Y2 in Y. On gray scale servers this picture will come out shaded. On binary devices a halftone is produced. PICFILE should be in hand/eye format. PICFIT(X1,Y1,X2,Y2,FILE) insert a transposed picture in the indicated rectangle. BUFSIZ = DDSIZ(INTEGER JOBID($-1$)) return the display buffer size of the indicated server.

### The TYPHDR typesetting extension

The TYPHDR routines extend the GRAHDR package to permit reasonably convenient two dimensional typesetting of text in mixed fonts, for inclusion in GOD diagrams. The central concept is of a box of a certain size containing a two dimensional assembly of text and graphics. Such a box has an origin, which may be plopped down at a given place in diagram. Some of the commands create new boxes out of text, some by gluing together other ones, and some change the size or the origin of a box.

The following procedures are provided:

 FNTSELECT(FONT$\#$,FONTNAME) use this instead of FNTSEL in the GRAHDR. BOX = JTXT(FONT$\#$,TEXT) return a box containing TEXT in the indicated font. BOX = JCAT(A,B) thru JCAT6(A,B,C,D,E,F) horizontally combine a number of boxes. Origin ends up on left edge of resulting box. Useful for stringing together different fonts. BOX = JTAC(A,B) thru JTAC7(A,B,C,D,E,F,G) horizontally combine boxes, but leave origin on the right end. BOX = JBEL(A,B) thru JBEL7(A,B,C,D,E,F,G) vertically stack text boxes. Useful for assembling multiple lines of text. BOX = JSUB(A,B) make new box that is box A subscripted by box B. BOX = JEXP(A,B) make box with A superscripted by B. BOX = JXBP(A,B,C) make box with A sub B super C. BOX = PADD(DX1,DY1,DX2,DY2,A) padd box A on all four sides (margins). BOX = SHIF(DX1,DY1,A) shift origin of box A. BOX = JUL(A) make new box with contents of A underlined. BOX = JSQR(A) make a square root sign around A. BOX = JDIV(A,B) center A above B and put a division bar between. BOX = XCENTER(A) center the origin of box A in X. BOX = YCENTER(A) center A in Y. BOX = CENTER(A) move origin of A to its center in X and Y. BOX = RIGHTIFY(A) move origin to right of A. BOX = LEFTIFY(A) move origin to left of A. BOX = TOPIFY(A) move origin to top of A. BOX = BOTTOMIFY(A) move origin to bottom of A. DEPOSIT(X,Y,A) deposit box A into the diagram such that its origin is X (FNTPOS distorted) pixels to the right and Y pixels above the text position specified by the last FNTPOS.

### Guide to vision routines on [VIS,HPM]

PIXHDR.SAI utility routines for getting, saving, moving, etc. pictures

requires: PIXFAI.REL, PIXSAI.REL

 PCLN, PCWD, PCBY, PCBYA, LNWD, LNBY, LNBYA, WDBY, WDBI, BYBI, BPTAB, LINTAB where to find things in picture arrays VALUE = PIXEL(PICTURE, ROW, COLUMN) value of a particular pixel VALUE = INTREL(PIC, ROW, COL) interpolating PIXEL. ROW, COL, VALUE real. PUTEL(PICTURE, ROW, COLUMN, VALUE) change a pixel ADDEL(PICTURE, ROW, COLUMN, VALUE) increment a pixel ADDIEL(PIC, ROW, COL, VAL) interpolating ADDEL. R, C, V real. SIZE = PFLDIM(FILENAME) size of array needed for pic file SIZE = GETPFD(FILENAME, DIM[0:10]) read in parameters of picture SIZE = GETPFL(FILENAME, PICTURE) read in a pic file PUTPFL(PICTURE, FILENAME, MODE(1)) write PICTURE into a file. if MODE = 2, file is data compressed, otherwise normal CHAN = OPNPFL(FILENAME, DIM[0:10]) read in parameters of picture, opened for input at 1st scanline CHAN = CREPFL(DIM[0:10], FILENAME, MODE(1)) write header for PIC file, opened for output at 1st scanline. compressed if MODE = 2 PFLIN(CHAN, AR[1], NWDS) read next NWDS words from pic into AR PFLOUT(CHAN, AR[1], NWDS) write next NWDS words to pic from AR PFLCLS(CHAN) close picture open on channel SIZE = PIXDIM(HEIGHT, WIDTH, BITS) size of array for $H \times W \times B$ picture SIZE = MAKPIX(HEIGHT, WIDTH, BITS, PICTURE) make skeleton $H \times W \times B$ picture SIZE = MAKDIM(H, W, B, P[0:10]) make 11 word skeleton, for out of core pix WIPE(PICTURE, VALUE(0)) make every data word (not byte!) = VALUE PIXTRN(SRC, TR, DEST) transforms src into dst by array tr. tr is a 3 by 3 real array. For all pixels $(y, x)$ in dest set $(ty, tx, foo) = (y, x, 1) \times transform$. If $(ty, tx)$ is in src then $dest(y, x) = src(ty, tx)$ COPPIC(PICTURE1, PICTURE2) copy pic1 into pic2 TILE(PIC1, YL1, XL1, TY, TX, PIC2, YL2, XL2) take piece of size $TY \times TX$ at $[YL1, XL1]$ in PIC1, deposit at $[YL2, XL2]$ in PIC2 SQTILE(PIC1, YL1, XL1, TY, TX, YSQ, XSQ, PIC2, YL2, XL2) a $TY \times YSQ$ by $TX \times XSQ$ tile from PIC1 with upleft at $[YL1, XL1]$ is squished into a $TY$ by $TX$ tile in PIC2 $[YL2, XL2]$ upleft. The $YSQ$ by $XSQ$ areas in PIC1 are summed and scaled as needed SATILE(PIC1, YL1, XL1, TY, TX, YSQ, XSQ, PIC2, YL2, XL2) like SQTILE, but 0 samples in PIC1 leave PIC2 unchanged HAFPIC(PICTURE1, PICTURE2, MAXBIT) reduce pic to half resolution SHRINK(PICT1, PICT2) squeeze or expand PICT1 into PICT2 pixels are sampled, not interpolated or averaged. PICADD(PICTURE, PICSUM) add a picture to a picture PICSUB(PICA, PICDIFF) subtract. PICA$-$PICDIFF → PICDIFF PICMUL(PICTURE, PICPRD) multiply pictures. no bounds check. PICSH(PIC1, PIC2, DIV) every pixel in PIC1/DIV→PIC2 GRAY(PIC) Convert to gray code. UNGRAY(PIC) Convert back. RETRY = CAMPIX(CAMERA, YEDGE, XEDGE, PICTURE, SUMS(1), BCLIP(7), TCLIP(0), MAXTRY(20)) read from a camera NRETRY = CLPADJ(CAM, BLCIP, TCLIP) find optimum clip levels for CAM NRETRY = TVSNAP(CAM, YEDGE, XEDGE, PIC, BCLIP, TCLIP, NTRY) primitive camera routine, used by CAMPIX NRETRY = TVRAW(CAM, YEDGE, XEDGE, PIC, BCLIP, TCLIP, NTRY) primitive camera routine, used by CAMPIX TVBTMX(PIC4, PICN, XFRM, INHIBEQ) primitive camera routine, used by CAMPIX TVBTMY(PIC4, PICN, XFRM, INHIBLE) primitive camera routine, used by CAMPIX TVBTMZ(PIC4, PICN, XFRM, INHIBGE) primitive camera routine, used by CAMPIX SUM = INTOP(PIC, WINSIZE, ANSARRY, YEDGE(0), XEDGE(0)) interest operator INTLOM(HIG, WID, ANSARRY) intop local max operator SIZE = INTERESTDIM(PICTURE, WINDOWSIZE) pic size needed for interest op INTEREST(PICTURE, WINDOW, RESULTPICTURE) make interest op picture BESTVAL = MATCH(PICTURE1, SY1, SX1, SY2, SX2, PICTURE2, DY1, DX1, DY2, DX2) correlator, find Source window in pic1 in Dest in pic2 BSTCOEF = NORCOR(PICTURE1, SY1, SX1, SY2, SX2, PICTURE2, DY1, DX1, DY2, DX2) normalized correlator, find Source window in pic1 in Dest in pic2 CLEAN(PICTURE) remove single pixel noise, blurs a little PASSHI(PICTURE1, WINDOWSIZE, PICTURE2) high pass filter LOWPAS(PICTURE) in place low pass filter. 4 pixels → 1 pixel. SUM = CMPPAR(PICTURE1, PICTURE2) compare two pics: $\sum(x-y)^2$ SUM = CMPPAD(PICTURE1, PICTURE2) quick and dirty compare PERBIT(PICTURE, TRANSFORM) transform each pixel of pic HISTOG(PICTURE, HISTOGRAM) count # of occurences of each gray val ENHANCE(PICTURE) make histogram flat SYNCHRONIZE(PICTURE1) do a vertical roll fixup ROWSUM(PICTURE1, ROWSUMS) sum up the pixels in each row ROWSUD(PICTURE1, ROWSUMS) dirty rowsums, one pixel/word used COLSUM(PICTURE1, COLSUMS) sum up the pixels in each col LONG REAL = SUMSQR(PIC) double prec. sum of squares of pixels MASS = CENTRO(PIC, YL, XL, YH, XH, THR) centroid and moment of a dark area UNPACK(SOURCEARRAY, PICTURE) copy a dense byte arry into a pic GETPAR(ARRY, PICTURE) copy full word array of pixels to pic PUTPAR(PICTURE, ARRY) copy pic to full word array of pixels EDGEINIT(PICTURE, SIZE) initialize edge operator EDGE(X, Y, EDGERESULT) apply edge operator

NOTE: all picture and other arrays are zero origin in all dimensions

### Vision routines for Displays

VIXHDR.SAI for displaying gray scale and halftone pictures on data disc. an extension for the display routines in DDSUB.SAI[GRA,HPM]

requires: PIXHDR.SAI[VIS], DDHDR.SAI[GRA], VIXFAI.REL[VIS], VIXSAI.REL[VIS]

 VIDEO(X1, Y1, X2, Y2, PICTURE, BIT) display PICTURE between X1, Y1, X2, Y2 in SCREEN co-ordinates. If BIT = $-1$ then a fast, low quality halftone, if $-2$ then a high quality halftone, if $-3$ then a buggy halftone. If positive then BIT represents a bit mask, which is anded with each pixel. If the result is nonzero, a bit is turned on in the corresponding part of the display. VIDONE(PICTURE, BT, I(0), J(0)) similar to VID but faster and simpler. Maps picture elements one to one to data disc points. Upper left corner of picture is placed I physical DD scanlines from the top of the picture, and indented J DD elements from the left. Complements the masked bit instead of setting it to one. VIDFOR(PICTURE, BUF1, BUF2, BUF4, BUF8, I(0), J(0)) Like VIDONE, but for 4 bit pictures and four DD buffers. Sets up all buffers at once, clearing displayed area and inverting bits for compatibility with the inverted gray code produced by TVRAW. VIDFRT(PICTURE, BUF1, BUF2, BUF4, BUF8, I(0), J(0)) Transposed VIDFOR; picture twice as wide on its side. VIDFRX(PICTURE, BUF1, BUF2, BUF4, BUF8, I(0), J(0)) Like VIDFOR, but makes picture twice as wide and tall. One picture pixel → 4 DD pixels. VID1(PICTURE, BUF1, I(0), J(0)) Like VIDFOR, for 1 bit pictures, but assumes normal gray code and produces a complemented display. VID3(PICTURE, BUF1, BUF2, BUF4, I(0), J(0)) Like VID1, for 3 bit pictures. VID4(PICTURE, BUF1, BUF2, BUF4, BUF8, I(0), J(0)) Like VID1, for 4 bit pictures. VID5(PICTURE, BUF1, BUF2, BUF4, BUF8, BUF16, I(0), J(0)) Like VID1, for 5 bit pictures. SUCCESS = VIDXGP(PIC, I0, J0, PLEN) Send a picture to the XGP. Dumb thing to do except for one bit pictures. Wait if XGP busy. SUCCESS = VIDXG(PIC, I0, J0, PLEN) VIDXGP, but return with failure if XGP busy SUCCESS = VIDXGQ(PIC, I0, J0, PLEN) VIDXGP, but set up detached job to do XGPing if XGP busy

### Routines for putting Fonted Text into Pictures

FNTHDR.SAI for inserting XGP font characters into pictures.

requires: FNTFAI.REL[VIS], FNTSAI.REL[VIS]

 FNTSEL(FNTNUM, FILSPEC, FNTHEAD) define font number FNTNUM to be font FILSPEC. FNTHEAD is the first word of an array $204_8$ words long which must be reserved for this font. CHRDEP(FNTNUM, CHR, PIC, YLO, XLO, YCOMP, XCOMP) add character CHR to the picture PIC in font $\#$ FNTNUM starting at position YLO, XLO compressed by YCOMP in Y and XCOMP in X. CHRPED(FNTNUM, CHR, PIC, YLO, XLO, YCOMP, XCOMP) add CHR to PIC, sideways, writing bottom to top. X and Y positions and compressions refer to text, not picture, reference system. CHR3X2(FNTNUM, CHR, PIC, YLO, XLO) like CHRDEP, but compresses X by 3 and Y by 2, and goes faster CHR6X4(FNTNUM, CHR, PIC, YLO, XLO) like CHRDEP, but compresses X by 6 and Y by 4, and goes faster CHR3Y4(FNTNUM, CHR, PIC, YLO, XLO) like CHRPED, but compresses X by 3 and Y by 4, and goes faster FCACHE(BUFFER, BUFSIZ) set up a buffer for caching letter descriptions. Doing this greatly speeds up CHRDEP. 5 or 10 K is a good buffer size.

Defines FNTHIG, position in FNTHEAD where height is stored, and FNTBAS, where baseline is stored.

### Internal Picture Array Format

 WORD CONTENTS 0 PCLN number of scanlines in the picture 1 PCWD words in the pixel portion of the picture 2 PCBY valid bytes in the picture 3 PCBYA bytes in the picture, including null bytes at end of each scanline 4 LNWD words per scanline 5 LNBY valid bytes per scanline 6 LNBYA bytes per scanline, including the nulls 7 WDBY bytes per word 8 WDBI bits in the valid portion of each word 9 BYBI bits per byte 10 BMAX $2^{BYBI}-1$, the maximum value of a byte 11 BPTAB address of SECOND entry in byte pointer table, 13+PCLN+address of array 12 to 11+PCLN LINTAB table containg the actual address of the first word of each scanline, in top to bottom order 12+PCLN to 12+PCLN+LNBYA table containing byte pointers to samples within lines, to be added to line address. The first entry, when ILDB'ed causes loading of the first byte in the line. 13+PCLN+LNBYA to 12+PCLN+LNBYA+PCWD the picture

### Picture File Format

Simplified hand-eye file format, as written by PIXSAI routines, for a picture HIG samples high by WID samples wide by BIT bits/sample:

The first $200_8$ word disk block of the file contains the following seven words of data (the rest of the block is unused).

 WORD CONTENTS 0 -1 This identifies the file as a standard Stanford Hand Eye picture file 1 BIT Number of bits/sample 2 $\lceil WID/\lfloor 36/BIT\rfloor \rceil$ $\#$ of words/scanline. $\lfloor \rfloor$ is FLOOR, $\lceil \rceil$ is CEILING 3 1 first scanline number 4 HIG last scanline number 5 1 first column number 6 WID last column number

The data begins on word $200_8$ of the file, $\lceil WID/\lfloor 36/BIT\rfloor \rceil$ words per scanline, left to right, top to bottom, for HIG scanlines. Each scanline begins on a word boundary.

The data compressed variant has the same header information except word $0$ is $-2$ instead of $-1$. For each successive block of 36 words in a standard file a compressed file has from 1 to 37 words. Each bit of the first word in such a group represents one of the 36 words in the standard file block, sequenced left to right. The bit is zero if the corresponding word is the same as the previous word in the file, or one if it differs. Each word that differs is given in the group that follows the mask word.

### XGPSYN and XGPSYG

XGPSYN displays files on the video synthesizer, imitating the XGP. It can fill the screen with 1/2, 1 or 2 pages at time. XGPSYN can also list documents on the XGP, with no complexity limit, and make hand/eye compatible picture files which can be sent to printers like the VARIAN, or displayed on screens. XGPSYG has the added capability of inserting drawings and pictures into the assembled pages.

To run the programs, tell them which file you want to look at, either in the command line (R XGPSYN;FILENAME) or in answer to the FILE: question, and any spooler style switches, such as /FONT = BASL30 (.XGP files already contain most necessary switches). The page number questions can be answered with the page you want to view, any additional spooler switches, or one of the following commands:

#### XGPSYN COMMANDS

 H Half density. Next display will be one half page per screen. F Full density. A whole page per screen. D Double density. Two sequential pages per screen. C Display pages on your own DD channel instead of on the video synthesizer. S Use the video synthesizer instead of your own channel. V view. Redraw the last display (in case it was clobbered). W negate subsequent displays. Black on white becomes white on black, and vice versa. K kill. Erase the video synthesizer. Q quit. Exit from the program and load the line editor with an XSPOOL command. L(a:b) list pages a to b on the XGP. More tolerant than XSPOOL, but slower. Alternate forms for this command are L to list the whole document and L(a) to list a single page. B Bitwise resolution. Next display will be a full size bit raster suitable for XGPing or sending to a picture file for printing on other devices. T Transposed bitwise resolution. Like B mode, but page is generated 90° rotated. E Enormous resolution. Next display will be at bit raster resolution, but only upper left 480 by 512 pixel portion will be generated. O output the last display as a data compressed picture file. P output the last display as a standard hand/eye picture file. X XGP output the last B,T or E display.

The video synthesizer is a video rate D/A driven by data disc channels 30 through 37. H density requires 3 of these channels, F needs 4 and D wants 5. These are rarely available during heavy system load. It takes about 6 CPU seconds to compose a single page.

XGPSYN and XGPSYG understand the following switches, some of which are not standard with the spooler or the COPY program. The switch names may be abbreviated to the capitalized portion.

 /FONT = “fontname” Select font number 0 for the document /FONT$\#$n = “fontname” Select font number n for the document /THickness = t Select line thickness for Leland's music files /ESCape = ... change the escape sequence. Any characters except slash are ok. /REpeat = n When listing, make n copies of each page. /TMar = n Set the top margin of a listing n raster lines from top of page. /PMar = n Set the text portion of the page to be n lines tall /BMar = n Make the bottom margin n raster lines big. In listings the sum of TMAR+PMAR+BMAR is the physical length of the page. /LMar = n Set the left margin n pixels from left edge of paper. /RMar = n Set the right margin n pixels from the left edge of the paper. When writing picture files of page images, RMAR is the physical width of the resulting image. /List List the document on the XGP. Possible forms are /L to list the whole document, /L(n) to list page n and /L(a:b) to list all the pages between a and b. The simplest way to list a document with XGPSYN is by incanting R XGPSYN;file/L /XLine = n Insert n extra scanlines between lines of text. This number is initially 3. /INterchar = n Insert n extra columns between characters of text. This number is usually zero. /XShift = n Shift the contents of a page n pixels to the right on the image. Useful if you want to tweak the margins in a listing, and also for making images too large to fit in XGPSYN's core image all at once. Set RMAR small, the output the same page repeatedly with different XSHIFTS. Resulting windows can be combined later into a single file representing a large page. /YShift = n Shift the page contents n pixels up. For tweaking vertical margins, and also for making very long pages. Set TMAR+PMAR+BMAR small, then window through the file by changing YSHIFT. If resulting windows are to be assembled later the EDGE switch is also recommended. /EDge Normally characters that extend past the top margin of a page are not displayed. /EDGE selects a slower mode in which such fractional characters do appear. This is necessary if large pages are to be assembled from small windows. /XGp This file is in .XGP format, whether or not the file extension says so. /NOXgp This file is not in .XGP form (is not preceded by a switch page) /NOQueue When listing on the XGP, XGPSYN will create a detached job which waits if the XGP is not available when a page is to be generated. NOQUEUE supresses this feature. Instead, XGPSYN itself waits for the XGP. /NODpy Supresses video synthesizer display. Useful if XGPSYN is being used solely to generate files containing page images. /L invokes this mode automatically. /AUTocr Insert carriage returns when lines run beyond right margin. /NOAutocr Suppress insertion of extra carriage returns. /Halfdensity Select half page/screen mode. /Fulldensity Select full page/screen mode. /Doubledensity Select two page/screen mode. /Enormousresolution In this mode a screenful of display is generated without any compression of the original page raster. Very little of a standard page is visible, but every pixel can be resolved in that portion. /Bitwisedensity Create a one bit/pixel image of the whole page. This can be sent to the XGP (/L uses this density) or written into a hand-eye picture file. Such files can be listed on other printing devices. /Transposedbitwisedensity Like /B, but the image comes out on its side, rotated 90°. /Varian Useful only with XGPSYG. Causes halftones to be generated in a high density mode which works well with the Varian printer, but causes washing out on the XGP.

### GOD Files and XGPSYG

The following program writes the GOD file that produced Figure 10-1 in Chapter 10.

BEGIN "PRETTY"
REQUIRE "TYPHDR.SAI[GOD,HPM]" SOURCE_FILE;

INTEGER FJ,I,J,K,L,M,N; REAL P,Q;
REAL ARRAY X,Y[1:10];

FJ←FILJOB("DSK:PRETTY.GOD[DIA,HPM]");
comment open the GOD file;
DDINIT; SCREEN(-1.2,-1.2,1.2,1.2);

PICFIL(-1,-1,1,1,"U:SF2.PIC[DIA,HPM]"); LITEN;
comment insert a picture;
LINE(-1,-1,-1,1); LINE(1,1,-1,1);
LINE(1,1,1,-1);   LINE(-1,-1,1,-1);
comment outline it;
FNTSELECT(2,"METMBM"); FNTSELECT(3,"METSBM");
FNTSELECT(103,"BASL30");
comment select some fonts;
FNTPOS(-1,1.03,1,1,0,0);
FNTEXT(0,0,2,"See the pretty aeroplane");
comment use font 2;
DRKEN;
BEGIN REAL ARRAY X,Y[1:20]; INTEGER I;
FOR I←1 STEP 1 UNTIL 20 DO
BEGIN X[I]←.89+0.304*COS((I-1)*2*3.14159/20);
Y[I]←.5+0.12*SIN((I-1)*2*3.14159/20); END;
X[12]←.62; Y[12]←-.23;
POLYGO(20,X[1],Y[1]);
LITEN;
FOR I←1 STEP 1 UNTIL 20 DO
LINE(X[I],Y[I],X[(I MOD 20)+1],Y[(I MOD 20)+1],3);
END;
comment make a balloon;
FNTPOS(.89,.5);
DEPOSIT(0,0,CENTER(JTXT(3,"Yow !!!  I am an L1011 !!")));
comment put font 3 text into it;
DPYUP(-1); KILJOB(FJ);             comment close the GOD file;
END;


The GOD file contains graphics commands like line, dot, text, picture etc. When PRETTY.SAI says LINE(...) a line command gets written into PRETTY.GOD. When it says PICFIL(..., “SF1.PIC”) a binary rendition of the command gets written into the file. It is the job of whatever program reads PRETTY.GOD to deposit the picture when it encounters the PICFIL command in it, just like it's its responsibility to draw a line when it sees a LINE command.

You can insert a .GOD file into as document with XGPSYG by including a line of the form

⊂⊗⊃ G[0,.5](5,4):PRETTY.GOD[GOD,HPM] ⊂⊗⊃

in your text. This means

 ⊂⊗⊃ Here is an escape G it's a GOD file escape [0,.5] diagram center is 0 in right and .5 above page center (5,4) diagram is to be 5 inches wide by 4 inches high PRETTY.GOD get your graphics commands from this file ⊂⊗⊃ Here is the end of the escape

The position field in square brackets and the size field in parens are optional. If left out, the picture will be centered around where your escape text would have appeared if you had XSPOOLED'd or XGPSYN'ed your document. An alternative form for the position field is [%-2.3,%+3.7], which means the center of the diagram is to be put 2.3 inches to the left and 3.7 inches above where your escape sequence would have been deposited. Thus you can position diagrams on the page either absolutely, or relative to the position of the escape sequence. It is ok to make the X position, say, relative and the Y position absolute.

<-- Previous  Next -->