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 ht_register_page();
extern integer pagenum;
extern int ht_highlight;
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() ;
extern void draw_all_ht_pt();
/*
* 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[DVI_STACKSIZE] ; /* Changed from STACKSIZE to avoid HP conflict */
void dopage(int sheetview) {
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 */
ht_register_page();
if(ht_highlight) ht_highlight--;
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[DVI_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+(DVI_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,%d:%s>", fnt, curfnt->id, 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:
/*Now we draw the hpts*/
draw_all_ht_pt(sheetview);
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.