home *** CD-ROM | disk | FTP | other *** search
- /*
- * dopage.c of dviamiga software package.
- *
- * Main page drawing procedure. Interprets the page commands. A simple
- * (if lengthy) case statement interpreter.
- */
- #include "structures.h"
- /*
- * The external routines we use:
- */
- extern void error() ;
- extern void TPSbop(), TPSeop(), TPSselfont() ;
- extern void drawrule() ;
- extern void strflush(), texflush() ;
- extern shalfword dvibyte() ;
- extern halfword twobytes() ;
- extern integer threebytes() ;
- extern integer signedquad() ;
- extern shalfword signedbyte() ;
- extern shalfword signedpair() ;
- extern integer signedtrio() ;
- extern void dospecial() ;
- extern void loadfont() ;
- extern void setstatus(), qstatus() ;
- extern void fontdef() ;
- extern void fpageinit(), fdrawchar(), fdrawrule(), abortpage() ;
- extern void dviseek() ;
- extern void gottapage() ;
- extern int checkformessage() ;
- extern long scalewidth() ;
- extern void bopcolor() ;
- /*
- * Now the external variables.
- */
- extern fontdesctype *curfnt ;
- extern fontdesctype *baseFonts[] ;
- extern fontmaptype *ffont ;
- extern quarterword *virpos, *virlim ;
- extern frametype frames[] ;
- extern integer curpos ;
- extern halfword fnt ;
- extern shalfword hh, vv ;
- extern TeXfontdesctype *TeXfonts[] ;
- extern real conv ;
- extern integer iconv ;
- extern real vconv ;
- extern integer viconv ;
- extern Boolean pageinterrupted ;
- extern Boolean pagedrawn ;
- extern integer messagebit ;
- extern FILE *dvifile ;
- extern integer rthispage ;
- extern char lastfile[] ;
- extern real screendpi ;
- #ifdef DEBUG
- extern int debugon ;
- #endif
- void
- abortdvi() {
- error("! bad command in dvi file") ;
- }
- /*
- * Now we have the dopage procedure.
- */
- static struct dvistack {
- shalfword hh, vv ;
- integer h, v, w, x, y, z ;
- } dvistack[STACKSIZE] ;
- void dopage() {
- register shalfword cmd ;
- register integer p ;
- register chardesctype *cd ;
- register FILE *df ;
- register struct dvistack *sp ;
- integer h, v, w, x, y, z ;
- register integer thinspace ;
- register frametype *frp = frames ;
- integer *wds = 0 ;
- TeXfontdesctype *tfnt ;
- register fontmaptype *cfnt ;
- int curpsfont = -1 ;
- int charmove ;
- integer vertsmallspace = (integer)(0.025*100/vconv) ; /* 0.025 inches */
-
- qstatus("Drawing") ;
- #ifdef DEBUG
- if (debugon > 7) {
- printf("\nAt the top of dopage\n") ;
- fflush(stdout) ;
- }
- #endif
- TPSbop() ;
- df = dvifile ;
- if (df == NULL || pagedrawn)
- return ;
- gottapage() ;
- sp = dvistack ;
- pageinterrupted = 0 ;
- thinspace = 111000 ;
- hh = vv = h = v = w = x = y = z = fnt = 0 ;
- curfnt = NULL ;
- tfnt = 0 ;
- virpos = 0 ;
- dviseek(rthispage) ;
- bopcolor(1) ;
- while (1) {
- beginloop:
- cmd = dvibyte() ;
- if (cmd < 129 || cmd == 133) {
- if (cmd >= 128) {
- charmove = (cmd < 129) ;
- cmd = dvibyte() ;
- } else
- charmove = 1 ;
- cd = curfnt->chardesc+cmd ;
- #ifdef DEBUG
- if (debugon > 8) {
- if (cmd < 127 && cmd >= 32)
- printf("`%c'", cmd) ;
- else
- printf("`\\%02x'", (unsigned int)cmd) ;
- fflush(stdout) ;
- }
- #endif
- if (curfnt->virtual) {
- if (charmove) {
- sp->hh = hh + cd->pixelwidth ;
- sp->h = h + wds[cmd] ;
- } else {
- sp->h = h ;
- sp->hh = hh ;
- }
- sp->vv = vv ;
- sp-> v = v ;
- sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
- if (++sp >= &dvistack[STACKSIZE]) error("! Out of stack space") ;
- w = x = y = z = 0 ; /* will be in relative units at new stack level */
- frp->curp = virpos ;
- frp->curl = virlim ;
- frp->ff = ffont ;
- frp->curf = curfnt ;
- frp->tfnt = tfnt ;
- if (++frp == &frames[MAXFRAME] )
- error("! virtual recursion stack overflow") ;
- cd = curfnt->chardesc + cmd ;
- virpos = cd->packptr + 2 ;
- virlim = virpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
- ffont = curfnt->localfonts ;
- if (ffont) {
- tfnt = ffont->tdesc ;
- if (tfnt->loaded==NULL) {
- texflush() ;
- loadfont(tfnt) ;
- }
- curfnt = tfnt->loaded ;
- thinspace = tfnt->thinspace ;
- wds = tfnt->scaledwidth ;
- if (curfnt->virtual == 0 &&
- curfnt->id != curpsfont) {
- strflush() ;
- TPSselfont(curfnt->id) ;
- curpsfont = curfnt->id ;
- }
- } else {
- curfnt = NULL ;
- thinspace = vertsmallspace ;
- }
- goto beginloop ;
- } else {
- fdrawchar(cmd, cd->pixelwidth) ;
- if (charmove) {
- h += wds[cmd] ;
- hh += cd->pixelwidth ;
- }
- goto setmotion ;
- }
- } else if (cmd < 171) {
- #ifdef DEBUG
- if (debugon > 8) {
- printf("%02x", (unsigned)cmd) ;
- fflush(stdout) ;
- }
- #endif
- switch (cmd) {
- /* illegal options */
- case 129: case 130: case 131: case 134: case 135: case 136: case 139:
- abortdvi() ;
- case 140:
- if (virpos == NULL) goto donewloop ;
- --frp ;
- curfnt = frp->curf ;
- tfnt = frp->tfnt ;
- thinspace = (curfnt) ? tfnt->thinspace : vertsmallspace ;
- wds = tfnt->scaledwidth ;
- ffont = frp->ff ;
- virlim = frp->curl ;
- virpos = frp->curp ;
- if (hh < (sp-1)->hh+2 && hh > (sp-1)->hh-2)
- (sp-1)->hh = hh; /* retain `intelligence' of pixel width, if close */
- else
- if (debugon > 5) printf("*") ;
- /* pop */
- case 142:
- if (--sp < dvistack) abortpage() ;
- hh = sp->hh ; vv = sp->vv ;
- h = sp->h ; v = sp->v ;
- w = sp->w ; x = sp->x ;
- y = sp->y ; z = sp->z ;
- break ;
- /* rules */
- case 132: case 137:
- { integer ry, rx ;
- shalfword rxx, ryy ;
- ry = signedquad() ; rx = signedquad() ;
- if (virpos) {
- rx = scalewidth(rx, (frp-1)->tfnt->scaledsize) ;
- ry = scalewidth(ry, (frp-1)->tfnt->scaledsize) ;
- }
- if (rx > 0 && ry > 0) {
- rxx = (rx + iconv - 1) / iconv ;
- ryy = (ry + viconv - 1) / viconv ;
- fdrawrule(rxx, ryy) ;
- } else
- rxx = (rx + iconv - 1) / iconv ;
- if (cmd == 132) {
- h += rx ; hh += rxx ;
- goto setmotion ;
- }
- }
- break ;
- /* nop, eop */
- case 138:
- break ;
- /* push */
- case 141:
- if (sp >= dvistack+(STACKSIZE-1)) error("! Out of stack space") ;
- sp->hh = hh ; sp->vv = vv ;
- sp->h = h ; sp->v = v ;
- sp->w = w ; sp->x = x ;
- sp->y = y ; sp->z = z ;
- sp++ ; break ;
- /* right */
- case 143:
- p = signedbyte() ; goto horizontalmotion ;
- case 144:
- p = signedpair() ; goto horizontalmotion ;
- case 145:
- p = signedtrio() ; goto horizontalmotion ;
- case 146:
- p = signedquad() ; goto horizontalmotion ;
- /* w moves */
- case 147:
- p = w ; goto horizontalmotion ;
- case 148:
- p = w = signedbyte() ; goto horizontalmotion ;
- case 149:
- p = w = signedpair() ; goto horizontalmotion ;
- case 150:
- p = w = signedtrio() ; goto horizontalmotion ;
- case 151:
- p = w = signedquad() ; goto horizontalmotion ;
- /* x moves */
- case 152:
- p = x ; goto horizontalmotion ;
- case 153:
- p = x = signedbyte() ; goto horizontalmotion ;
- case 154:
- p = x = signedpair() ; goto horizontalmotion ;
- case 155:
- p = x = signedtrio() ; goto horizontalmotion ;
- case 156:
- p = x = signedquad() ; goto horizontalmotion ;
- /* down moves */
- case 157:
- p = signedbyte() ; goto verticalmotion ;
- case 158:
- p = signedpair() ; goto verticalmotion ;
- case 159:
- p = signedtrio() ; goto verticalmotion ;
- case 160:
- p = signedquad() ; goto verticalmotion ;
- /* y moves */
- case 161:
- p = y ; goto verticalmotion ;
- case 162:
- p = y = signedbyte() ; goto verticalmotion ;
- case 163:
- p = y = signedpair() ; goto verticalmotion ;
- case 164:
- p = y = signedtrio() ; goto verticalmotion ;
- case 165:
- p = y = signedquad() ; goto verticalmotion ;
- /* z moves */
- case 166:
- p = z ; goto verticalmotion ;
- case 167:
- p = z = signedbyte() ; goto verticalmotion ;
- case 168:
- p = z = signedpair() ; goto verticalmotion ;
- case 169:
- p = z = signedtrio() ; goto verticalmotion ;
- case 170:
- p = z = signedquad() ; goto verticalmotion ;
- }
- goto endofloop ;
- } else if (cmd < 236) { /* font selection command */
- if (cmd < 235) fnt = cmd - 171 ;
- else fnt = dvibyte() ;
- if (virpos) {
- for (cfnt=ffont; cfnt; cfnt = cfnt->next)
- if (cfnt->fontnum == fnt) break ;
- tfnt = cfnt->tdesc ;
- } else
- tfnt = TeXfonts[fnt] ;
- if (tfnt->loaded==NULL) {
- texflush() ;
- loadfont(tfnt) ;
- }
- curfnt = tfnt->loaded ;
- #ifdef DEBUG
- if (debugon > 7) {
- printf("<%d:%s>", fnt, curfnt->name+1) ;
- fflush(stdout) ;
- }
- #endif
- if (curfnt->virtual == 0 &&
- curfnt->id != curpsfont) {
- strflush() ;
- TPSselfont(curfnt->id) ;
- curpsfont = curfnt->id ;
- }
- thinspace = tfnt->thinspace ;
- wds = tfnt->scaledwidth ;
- } else {
- switch (cmd) {
- /* illegal options */
- case 236: case 237: case 238: case 244: case 245: case 246: case 247:
- case 248: case 249: case 250: case 251: case 252: case 253: case 254:
- case 255:
- abortdvi() ;
- /* font definition */
- case 243:
- fontdef() ;
- break ;
- /* specials */ /* this should eventually call a do special routine. */
- case 239: p = dvibyte() ; dospecial(p) ; break ;
- case 240: p = twobytes() ; dospecial(p) ; break ;
- case 241: p = threebytes() ; dospecial(p) ; break ;
- case 242: p = signedquad() ; dospecial(p) ; break ;
- }
- }
- goto endofloop ;
- /*
- * The calculations here are crucial to the appearance of the document.
- * If the motion is less than a thinspace, we round the motion; otherwise,
- * we update the position and round the new position. Then we check to
- * insure that the rounded position didn't accumulate an error that was
- * greater than MAXDRIFT.
- */
- verticalmotion:
- /* vertical motion cases */
- if (checkformessage())
- return ;
- if (virpos)
- p = scalewidth(p, (frp-1)->tfnt->scaledsize) ;
- v += p ;
- if (p >= vertsmallspace) vv = v / viconv ;
- else if (p <= -vertsmallspace) vv = v / viconv ;
- else
- { vv += p / viconv ;
- cmd = v / viconv - vv ;
- if (cmd > MAXDRIFT) vv += cmd - MAXDRIFT ;
- else if (cmd < -MAXDRIFT) vv += cmd + MAXDRIFT ;
- }
- goto endofloop ;
- /*
- * The horizontal kerning is done exactly analogously to the vertical
- * motion, only characters are handled automatically; there kern is
- * not dependent directly on their width in the dvi units. Thus, we
- * do the hh and h motion in the drawchar part, and only check the
- * rounding here.
- */
- horizontalmotion:
- /* horizontal motion cases */
- if (virpos)
- p = scalewidth(p, (frp-1)->tfnt->scaledsize) ;
- h += p ;
- if (p >= thinspace || p <= - (thinspace << 2)) {
- hh = h / iconv ;
- goto endofloop ;
- } else hh += p / iconv ;
- setmotion:
- cmd = h / iconv - hh ;
- if (cmd > MAXDRIFT)
- hh += cmd - MAXDRIFT ;
- else if (cmd < -MAXDRIFT)
- hh += cmd + MAXDRIFT ;
- endofloop: ;
- }
- donewloop:
- pagedrawn = 1 ;
- texflush() ;
- TPSeop() ;
- qstatus("") ;
- #ifdef DEBUG
- if (debugon > 7) {
- printf("\nAt the end of dopage\n") ;
- fflush(stdout) ;
- }
- #endif
- }
-