/*
* DVI previewer for X.
*
* Eric Cooper, CMU, September 1985.
*
* Code derived from dvi-imagen.c.
*
* Modification history:
* 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS.
* 7/1988 Modified for X.11 --Mark Eichin, MIT
* 12/1988 Added 'R' option, toolkit, magnifying glass
* --Paul Vojta, UC Berkeley.
* 2/1989 Added tpic support --Jeffrey Lee, U of Toronto
* 4/1989 Modified for System V --Donald Richardson, Clarkson Univ.
* 3/1990 Added VMS support --Scott Allendorf, U of Iowa
* 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem
* 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
* and Lee Hetherington, MIT
*
* Compilation options:
* SYSV compile for System V
* VMS compile for VMS
* X10 compile for X10
* NOTOOL compile without toolkit (X11 only)
* BUTTONS compile with buttons on the side of the window (needs toolkit)
* MSBITFIRST store bitmaps internally with most significant bit first
* BMSHORT store bitmaps in shorts instead of bytes
* BMLONG store bitmaps in longs instead of bytes
* ALTFONT default for -altfont option
* A4 use European size paper
* TEXXET support reflection dvi codes (right-to-left typesetting)
* GREY use grey levels to shrink fonts
*/
currinf.fontp = NULL;
currinf.set_char_p = set_no_char;
#ifdef TEXXET
currinf.dir = 1;
scan_frame = NULL; /* indicates we're not scanning */
#endif
for (;;) {
ch = xone();
if (debug & DBG_DVI)
print_dvi(ch);
if (ch <= SETCHAR0 + 127)
#ifndef TEXXET
DVI_H += (*currinf.set_char_p)(ch);
#else
(*currinf.set_char_p)(ch, ch);
#endif
else if (FNTNUM0 <= ch && ch <= FNTNUM0 + 63)
change_font((unsigned long) (ch - FNTNUM0));
else {
long a, b;
switch (ch) {
case SET1:
case PUT1:
#ifndef TEXXET
a = (*currinf.set_char_p)(xone());
if (ch != PUT1) DVI_H += a;
#else
(*currinf.set_char_p)(ch, xone());
#endif
break;
case SETRULE:
/* Be careful, dvicopy outputs rules with
height = 0x80000000. We don't want any
SIGFPE here. */
a = xsfour();
b = xspell_conv(xsfour());
#ifndef TEXXET
if (a > 0 && b > 0)
#else
if (a > 0 && b > 0 && scan_frame == NULL)
#endif
set_rule(pixel_round(xspell_conv(a)),
pixel_round(b));
DVI_H += DIR * b;
break;
case PUTRULE:
a = xspell_conv(xsfour());
b = xspell_conv(xsfour());
#ifndef TEXXET
if (a > 0 && b > 0)
#else
if (a > 0 && b > 0 && scan_frame == NULL)
#endif
set_rule(pixel_round(a), pixel_round(b));
break;
case POP:
if (current_frame == minframe)
tell_oops("more POPs than PUSHes");
currinf.data = current_frame->data;
current_frame = current_frame->prev;
break;
#ifdef TEXXET
case SREFL:
if (scan_frame == NULL) {
/* we're not scanning: save some info. */
oldinfo = currinf;
oldmaxchar = maxchar;
if (!currinf.virtual)
file_pos = xtell(currinf.pos);
scan_frame = current_frame; /* now we're scanning */
refl_count = 0;
break;
}
/* we are scanning */
if (current_frame == scan_frame) ++refl_count;
break;
case EREFL:
if (scan_frame != NULL) { /* if we're scanning */
if (current_frame == scan_frame && --refl_count < 0)
{
/* we've hit the end of our scan */
scan_frame = NULL;
/* first: push */
if (current_frame->next == NULL) {
struct frame *newp = (struct frame *)
xmalloc(sizeof(struct frame),
"stack frame");
current_frame->next = newp;
newp->prev = current_frame;
newp->next = NULL;
}
current_frame = current_frame->next;
current_frame->data = currinf.data;
/* next: restore old file position, XX, etc. */
if (!currinf.virtual) {
off_t bgn_pos = xtell(dvi_buffer);
if (file_pos >= bgn_pos) {
oldinfo.pos = dvi_buffer
+ (file_pos - bgn_pos);
oldinfo.end = currinf.end;
}
else {
(void) lseek(fileno(dvi_file), file_pos,
SEEK_SET);
oldinfo.pos = oldinfo.end;
}
}
currinf = oldinfo;
maxchar = oldmaxchar;
/* and then: recover position info. */
DVI_H = current_frame->data.dvi_h;
DVI_V = current_frame->data.dvi_v;
PXL_V = current_frame->data.pxl_v;
/* and finally, reverse direction */
currinf.dir = -currinf.dir;
}
break;
}
/* we're not scanning, */
/* so just reverse direction and then pop */
currinf.dir = -currinf.dir;
currinf.data = current_frame->data;
current_frame = current_frame->prev;
break;
#endif /* TEXXET */
case RIGHT1:
case RIGHT2:
case RIGHT3:
case RIGHT4:
DVI_H += DIR * xspell_conv(xsnum(ch - RIGHT1 + 1));
break;
case W1:
case W2:
case W3:
case W4:
WW = xspell_conv(xsnum(ch - W0));
case W0:
DVI_H += DIR * WW;
break;
case X1:
case X2:
case X3:
case X4:
XX = xspell_conv(xsnum(ch - X0));
case X0:
DVI_H += DIR * XX;
break;
case DOWN1:
case DOWN2:
case DOWN3:
case DOWN4:
DVI_V += xspell_conv(xsnum(ch - DOWN1 + 1));
PXL_V = pixel_conv(DVI_V);
break;
case Y1:
case Y2:
case Y3:
case Y4:
YY = xspell_conv(xsnum(ch - Y0));
case Y0:
DVI_V += YY;
PXL_V = pixel_conv(DVI_V);
break;
case Z1:
case Z2:
case Z3:
case Z4:
ZZ = xspell_conv(xsnum(ch - Z0));
case Z0:
DVI_V += ZZ;
PXL_V = pixel_conv(DVI_V);
break;
case FNT1:
case FNT2:
case FNT3:
case FNT4:
change_font(xnum(ch - FNT1 + 1));
break;
case XXX1:
case XXX2:
case XXX3:
case XXX4:
a = xnum(ch - XXX1 + 1);
if (a > 0)
special(a);
break;
case FNTDEF1:
case FNTDEF2:
case FNTDEF3:
case FNTDEF4:
xskip((long) (12 + ch - FNTDEF1 + 1));
xskip((long) xone() + (long) xone());
break;
#ifndef TEXXET
case SREFL:
case EREFL:
#endif
case PRE:
case POST:
case POSTPOST:
tell_oops("shouldn't happen: %s encountered",
dvi_table2[ch - (FNTNUM0 + 64)]);
break;
default:
tell_oops("unknown op-code %d", ch);
} /* end switch*/
} /* end else (ch not a SETCHAR or FNTNUM) */
} /* end for */
}
#undef xspell_conv
void
draw_page()
{
/* Check for changes in dvi file. */
if (!check_dvi_file()) return;