This is dopage.c in view mode; [Download] [Up]
/* * 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 int curpsfont = -1 ; 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 charmove ; integer vertsmallspace = (integer)(0.025*100/vconv) ; /* 0.025 inches */ qstatus("Drawing") ; curpsfont = -1 ; #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 { if (curfnt->virtual == 0 && curfnt->id != curpsfont) { strflush() ; TPSselfont(curfnt->id) ; curpsfont = curfnt->id ; } 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 }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.