/* (C)opyright 1994 Wolfgang R. Mueller, Computing Centre,
Heinrich-Heine-University Duesseldorf, Germany,
wolfgang@uni-duesseldorf.de, +49-211-311-3905.
This program may be used without any warranty under
the terms of the GNU general public licence. */
/* translated from the original TurboPascal source
partly with p2c, the Pascal-to-C translator */

#undef DJCOLOUR
#ifdef DJ550C
#define DJCOLOUR
#endif
#ifdef DJ500C
#define DJCOLOUR
#endif

#define DINA4
#include <stdio.h>

#ifdef __MSDOS__
 #ifdef __TURBOC__
  #include <dos.h>
 #else
  #include <pc.h>
 #endif
#endif

#ifdef __TURBOC__
  #include <mem.h>
  #include <alloc.h>
  #define malloc farmalloc
  #define calloc farcalloc
  #define realloc farrealloc
  #define free farfree
#endif

#define uchar unsigned char
#define ushort unsigned short
#define ulong unsigned long
#define ptr void *

#define xmb       294   /* 8.5 inch X 300 dpi / 8 dot per byte*/
#ifdef __TURBOC__
#define ymax       47   /* +1=multiple of 8 */
#else
#define ymax      839   /* +1=multiple of 8 */
#endif
#define linl      299   /* =xmb+2+(xmb+128)div 128 */
#define maxink     16
#define smax      100

#ifdef __MSDOS__
static char tfmprefix[] = "c:\\tex\\fonts\\tfm\\";
static char fontprefix[] = "c:\\tex\\fonts\\canon\\";
#else
static char tfmprefix[] = "/usr/lib/texmf/fonts/tfm/";
static char fontprefix[] = "/usr/lib/texmf/fonts/pk/";
#endif

typedef struct colpix { uchar cpix, mpix, ypix, kpix; } colpix;
typedef struct greydesc { uchar maskc, maskm, masky, maskk; } greydesc;

static uchar maskmat[5][4][4] = {
  { {17,2,5,17},{17,17,8,17},{17,17,17,11},{17,17,14,17} },
  { {1,17,17,3},{5,17,17,6},{8,10,12,17},{14,16,17,17} },
  { {17,17,17,17},{17,4,17,17},{17,17,17,17},{17,17,17,12} },
  { {14,4,16,2},{7,9,5,11},{15,1,13,3},{6,12,8,10} },
  { {0x88,0x44,0x22,0x11},{0,0,0,0},{0,0,0,0},{0,0,0,0} } };

static FILE *prot=stderr;
static uchar stackcy[smax], stackma[smax], stackye[smax], stackbl[smax];
static char STR[99], FOPRE[99], FOMAG[16], FONAM[99], FOLOC[99], FOFUL[99];
static char prfnam[99] = "prn";
static char defnam[73];
static colpix *pxlmem[ymax + 1];
static greydesc greymask[8];
static uchar maskb[maxink + 1][4][4];

static uchar zoll, zoll0, vsk1, vsk2, hsk3, prfilout, clearing, prinit = 0;
static long zoelli;
static short zilli, lz, colst, xres, yres, xmax;
static short vskop, hsk1, hsk2, lzd, vchd, prbs, prbe;
static FILE *prfile;
static uchar prbuf[2048];

static void Tptr(void *p) {  if(p==NULL) {
  fprintf(prot, " - not enough memory :-( "); exit(1);
} }
static void prfeval() {
  if (!strcmp(".dvi", defnam+strlen(defnam)-4)) defnam[strlen(defnam)-4]=0;
  if (*prfnam == '\0')  sprintf(prfnam, "%s.pcl", defnam);
  prfilout = (strcmp(prfnam, "prn") != 0);
  xres = 300;  yres = 300;  xmax = xmb * 8 + 7;
  zoll0 = (yres * 12 + ymax) / (ymax + 1);
  if (prfilout)  fprintf(prot, "writing to file %s\n", prfnam);
}
static void propen() { if (prinit)  return;  prinit = 1;
  prbs=0;  prbe=0;  if(prfilout)  prfile = fopen(prfnam, "w+b");
}
static void prflush() { if(prbs>=prbe) return;
  if(prfilout) fwrite(&prbuf[prbs], prbe - prbs, 1, prfile);
  prbe=0; prbs=prbe;
}
static void put(x) uchar x; {
  if (prfilout) {
    if (prbe == 2048)  prflush();
    prbuf[prbe] = x;  prbe++;
  } else
#ifdef __MSDOS__
  outportb(0x378,x);
  while((inportb(0x379)&0x80)==0);
  outportb(0x37a,13);
  inportb(0x379);
  outportb(0x37a,12);
#else
  putc(x,stdout);
#endif
}
static void esc(s)  char *s;  {  short i, l;
  put(0x1b);  l = strlen(s);
  for (i = 0; i < l; i++)  put(s[i]);
}
static void prclos()  {
  if (!prinit)  return;
  prflush();  prinit = 0;
  if (prfilout)  fclose(prfile);
}
static void hardform()  {  esc("*rbC");  put(0xc);  esc("E");
}
static void putint(i)  short i;  {
  if (i >= 10)  putint(i / 10);
  put(i % 10 + '0');
}
static void putbits(c, pbuf)  char c;  uchar pbuf[linl+1]; {
  uchar qbuf[linl+1];  short i, j, k, l, m, n;  uchar b, ba;
  n = xmb;  while (pbuf[n] == 0 && n >= 0) n--;
  if (n < 0)  m = 0;  else {
    b = pbuf[0];  j = 1;  k = 2;  l = 2;  qbuf[k] = b;
    for (i = 1; i <= n; i++) {  ba = b;  b = pbuf[i];
      if (ba == b) {
	if (l == k) {
	  if (k == j + 1)  k--;  else {
	    l++;  qbuf[l] = b;
	    if (l - j >= 128) {  qbuf[j] = k - j - 2;  j = k;  }
	} } else {  l++;
	  if (j < k) {  qbuf[j] = k - j - 2;  j = k;  }
	  if (l - j >= 128) {
	    qbuf[j] = 129;  j = k + 2;  k = j + 1;  l = k;  qbuf[k] = b;
      }	} } else {
	if (l == k) {  k++;
	  if (k - j > 128) {  qbuf[j] = k - j - 2;  j = k;  k++;  }
	  qbuf[k] = b;  l = k;
	} else if (j == k) {  qbuf[j] = k - l + 256;
	  j += 2;  k = j + 1;  l = k;  qbuf[k] = b;
	} else {  l++;  k = l;  qbuf[k] = b;
    } } }
    if (l == k)        { qbuf[j] = l - j - 1;   m = l;
    } else if (j == k) { qbuf[j] = k - l + 256; m = j + 1;
    } else             { qbuf[j] = l - j - 1;   m = l;
  } }
  esc("*b");  putint(m);  put(c);
  for (i = 1; i <= m; i++)  put(qbuf[i]);
}
static short skipper;
static void hardcopy()  {  uchar pbuf[linl+1];
  short x, y;  uchar b,nothing;  colpix *WITH;
  propen();
  if (zilli == 0) {
    esc("E");
#ifdef DINA4
    esc("&l26A");
#endif
    esc("&a1N");  esc("*r2360S");  esc("*t300R");
#ifdef DJ550C
    esc("*r-4U");
#endif
#ifdef DJ500C
    esc("*r-3U");
#endif
    esc("*p0x0Y");  esc("*r0A");  esc("*b2M"); skipper=0;
  }
  for (y = 0; y <= ymax; y++) { nothing=1;
    for (x = 0; x <= xmb; x++) {  WITH = &pxlmem[y][x];
#ifdef DJCOLOUR
      b = WITH->kpix | (WITH->cpix & WITH->mpix & WITH->ypix);
#else
      b = WITH->kpix | (WITH->cpix | WITH->mpix | WITH->ypix);
#endif
      WITH->kpix = b;
#ifdef DJ550C
      b = ~b; WITH->cpix &= b;  WITH->mpix &= b;  WITH->ypix &= b;
#endif
#ifdef DJ500C
      WITH->kpix = WITH->cpix | b;  WITH->mpix |= b;  WITH->ypix |= b;
#endif
      if(WITH->kpix|WITH->cpix|WITH->mpix|WITH->ypix) nothing=0;
    }
    if(nothing) skipper++; else {
      if(skipper>0) { esc("*b"); putint(skipper); put('Y'); skipper=0; }
      for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].kpix;
#ifdef DJ550C
      putbits('V', pbuf);
      for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].cpix;
#endif
#ifdef DJCOLOUR
      putbits('V', pbuf);
      for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].mpix;
      putbits('V', pbuf);
      for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].ypix;
#endif
      putbits('W', pbuf);
} } prflush(); }
static void pixet(y, x, b)  ushort y, x;  uchar b;  {
  colpix *WITH;  greydesc *WITH1;
  WITH = &pxlmem[y][x];  WITH1 = &greymask[y & 7];
  if (clearing) {  WITH->cpix &= ~b;  WITH->mpix &= ~b;
    WITH->ypix &= ~b;  WITH->kpix &= ~b;  return;
  }
  WITH->cpix |= b & WITH1->maskc;  WITH->mpix |= b & WITH1->maskm;
  WITH->ypix |= b & WITH1->masky;  WITH->kpix |= b & WITH1->maskk;
}
static void setrect(xl, yl, xh, yh)  ushort xl, yl, xh, yh;  {
  ushort x, y, xll, xrr;  uchar a, b, c;
  xll = xl >> 3;  xrr = xh >> 3;
  a = (0xff >> (xl & 7)) & 255;  c = 0xff << (7 - (xh & 7));
  for (y = yl; y <= yh; y++) {  b = a;
    for (x = xll; x <= xrr; x++) {
      if (x == xrr)  b &= c;
      pixet(y, x, b);  b = 0xff;
} } }
/*static long prodovz(a, b)  ushort a, b;  {  return ((long)a * (long)b);  }
static long scaled(w, z)  long w, z;  {  long s;
  union {  long l;  struct {  ushort n, h;  } U1;  } a, b;
  a.l = w;  b.l = z;
  s = (((((ulong)prodovz(a.U1.n, b.U1.n)) >> 16) + prodovz(a.U1.n,
	  b.U1.h) + prodovz(a.U1.h, b.U1.n)) >> 4) +
      (prodovz(a.U1.h, b.U1.h) << 12);
  if (w < 0)  s -= z << 12;  return s;
} */
static long scaled(w, z)  long w, z;  {  long s; ulong t=w, u=z;
  /* should return  w * z / 2**20  */
  s = ( ( (((t & 65535L) * (u & 65535L)) >> 16)
	+   (t & 65535L) * (u >>    16)
	+   (t >>    16) * (u & 65535L)         ) >> 4)
    + ( (   (t >>    16) * (u >>    16)         ) << 12);
  if (w < 0)  s -= z << 12;  return s;
}
static char dviname[73];
static FILE *dvifile;
static long dvimag;
static uchar dvibuf[2048];
static ushort dvibufp, dvibufe;

static void baddvi(s)  char *s;  {
  fprintf(prot, "bad dvi: %s\n", s);  exit(1);
}
static void dvibytes(s, l)   char *s;  uchar l;  {  ushort ll;
  s[l] = '\0';  ll = dvibufe - dvibufp;
  if (ll >= l) {
    memmove((ptr)s, (ptr)(&dvibuf[dvibufp]), (long)l);
    dvibufp += l;  return;
  }
  if (ll > 0)  memmove((ptr)s, (ptr)(&dvibuf[dvibufp]), (long)ll);
  dvibufe = fread(dvibuf, 1, 2048, dvifile);
  if (dvibufe + ll < l)  baddvi("ends prematurely !");
  memmove((ptr)(&s[ll]), (ptr)dvibuf, (long)(l - ll));
  dvibufp = l - ll;
}
static uchar dvibyte() { uchar b;
  if (dvibufp >= dvibufe) {  dvibufp = 0;
    dvibufe = fread(dvibuf, 1, 2048, dvifile);
  }
  if (dvibufp >= dvibufe)  baddvi("ends prematurely !");
  b = dvibuf[dvibufp];  dvibufp++;  return b;
}
static void dviskip(l)  long l;  {  uchar b;
  while (l > 0) {
    l += (long)dvibufp - (long)dvibufe;
    if (l <= 0)  dvibufp = dvibufe + l;
    else {  dvibufp = dvibufe;  l--;  dvibyte();  }
} }
static long dvinum(b)  uchar b;  {  uchar i;  long n;
  n = 0;
  if (dvibufp + b > dvibufe) {
    for (i = 1; i <= b; i++)  n = (n << 8) | dvibyte();  return n;
  }
  for (i = 0; i < b; i++)  n = (n << 8) | dvibuf[dvibufp + i];
  dvibufp += b;  return n;
}
static long dviint(b)  uchar b;  {  uchar i;  long n;
  if (dvibufp + b <= dvibufe) {
    n = dvibuf[dvibufp];
    if (n > 127)  n -= 256;
    for (i = 1; i < b; i++)  n = (n << 8) | dvibuf[dvibufp + i];
    dvibufp += b;  return n;
  }
  n = dvibyte();
  if (n > 127)  n -= 256;
  for (i = 2; i <= b; i++)  n = (n << 8) | dvibyte();  return n;
}
static void dviposit(l)  long l;  {  fseek(dvifile, l, 0);
  dvibufe = fread(dvibuf, 1, 2048, dvifile);  dvibufp = 0;
}
static void dviopen() {  long l;  uchar j, em;  ushort k;
  sprintf(STR, "%s.dvi", dviname);
  if ((dvifile = fopen(STR, "rb"))==0) {  strcpy(STR, dviname);
    if ((dvifile = fopen(STR, "rb"))==0)  baddvi("not existing !");
  }
  dvibufe = fread(dvibuf, 1, 2, dvifile);
  if (dvibufe < 2) baddvi("empty !");
  em = dvibuf[1];
  if (dvibuf[0] != 247) baddvi("no valid preamble");
  /* now position to postamble */
  fseek(dvifile, 0L, 2);  l=ftell(dvifile);  if(l>2048) l=2048;
  fseek(dvifile, -l, 2);  k = fread(dvibuf, 1, 2048, dvifile);
  do {  k--;  } while (k >= 4 && dvibuf[k] != em);
  if (k < 4)  baddvi("no postamble in last 2048 bytes !");
  dvibufe = k + 1;  dvibufp = k - 4;  l = dvinum(4);
  fseek(dvifile, l, 0);  dvibufe = fread(dvibuf, 1, 2048, dvifile);
  dvibufp = 0;  dvibyte();
}

typedef union chdesc { uchar b8[16];
  struct { short wid, hei, hof, vof; long bmp, tfw; } U1;
  struct { long tfh, tfd, dum1, dum2; } U2;
} chdesc;
typedef struct fontdesc {
  long dfn;  char *fonam;  chdesc *chv;
  long danf;  uchar *chm;  short mch, fty;
} fontdesc;
static fontdesc **fontvect;
static uchar fontint;
static FILE *fofil;
static uchar *achm;
static uchar fofbyte() {  uchar b;
  if (fread(&b, 1, 1, fofil) <= 0) b = 0;  return b;
}
static long fofint(b)  uchar b;  {  uchar i;  long n;
  n = fofbyte();  if (n > 127)  n -= 256;
  for (i = 2; i <= b; i++)  n = (n << 8) | fofbyte();
  return n;
}

static long hs[smax], vs[smax], ws[smax], xs[smax], ys[smax], zs[smax];
static long cnt[10];
static uchar bitrev[256];
static char comment[256];
static double conv, vconv;
static long l, landx, landy, newmag;
static long a, b, c, f, q, h, v, hoff, voff, w, x, y, z;
static long chk, scf, dsz, fofchk, num, den, mag, spl, lpp, mxh, mxv;
static int pagnum, pag1, paganz, i, k;
static ushort s, mst, mpn;
static char dviori;
static uchar o, j, post, fini, started, below;

static void initbitrev() {  uchar b, i, j, k, m, n;
  for (m = 0; m <= 3; m++) { n=m;
#ifdef DJCOLOUR
    n=3;
#endif
    for (i = 0; i <= maxink; i++) {
      for (j = 0; j <= 3; j++) {  b = 0;
        for (k = 0; k <= 3; k++) {
  	  if (maskmat[n][j][k] <= i)  b |= maskmat[4][0][k];
  }  maskb[i][m][j] = b;  } } }
  bitrev[0] = 0;  m = 0x80;  n = 1;
  while (m) {  /* put bits into reverse order within a byte */
    for (j = 0; j < n; j++)  bitrev[j + n] = bitrev[j] | m;
    n += n;  m >>= 1;
} }

static void tfmdef() {  short ll, lh, bc, ec, nw, nh, nd, i;
  uchar b1, b2, b3;  short FORLIM;
  fontdesc *WITH = fontvect[fontint];
  sprintf(STR, "%s%s.tfm", tfmprefix, FONAM);
  fprintf(prot, "trying  %s  instead", STR);
  fofil = fopen(STR, "rb");
  if (fofil==0) {  fprintf(prot, " - absent as well :-(\n");  return;  }
  ll = fofint(2);  lh = fofint(2);  bc = fofint(2);  ec = fofint(2);
  nw = fofint(2);  nh = fofint(2);  nd = fofint(2);  fseek(fofil, 0L, 2);
  if (ll * 4 > ftell(fofil) || ll < lh + ec - bc + nw + nh + nd + 7) {
    fprintf(prot, " - not a TFMfile !\n");  fclose(fofil);  return;
  }
  WITH->mch = ec;
  Tptr( WITH->chv = (chdesc *)calloc(WITH->mch + 1, sizeof(chdesc)) );
  fseek(fofil, 24L, 0);  fofchk = fofint(4);
  if (chk != 0) if (fofchk != 0) if (chk != fofchk)
    fprintf(prot, " *+* wrong checksum *+* ");
  fseek(fofil, (lh + ec - bc + 7L) * 4, 0);
  FORLIM = nw + nh + nd;
  for (i = 0; i < FORLIM; i++)
    WITH->chv[i].U2.dum1 = scaled(fofint(4), scf);
  fseek(fofil, lh * 4L + 24, 0);
  for (i = bc; i <= ec; i++) {
    b1 = fofbyte();  b2 = fofbyte();  fofbyte();  fofbyte();
    WITH->chv[i].U1.tfw = WITH->chv[b1].U2.dum1;
    WITH->chv[i].U2.tfh = WITH->chv[nw + (b2 >> 4)].U2.dum1;
    WITH->chv[i].U2.tfd = WITH->chv[nw + nh + (b2 & 15)].U2.dum1;
  }
  fclose(fofil);  WITH->fty = 1;  fprintf(prot, " - TFMfile OK\n");
}
static void tfmchar() {  short hr, vr, br, ar;  uchar li, re, ob, un;
  chdesc *WITH = &fontvect[fontint]->chv[c];
  switch (dviori) {
  case 0:
    hr = (long)(conv * h + 0.5);
    vr = (long)(vconv * (v - WITH->U2.tfh) + 0.5);
    br = (long)(conv * (h + WITH->U1.tfw) + 0.5);
    ar = (long)(vconv * (v + WITH->U2.tfd) + 0.5);
    break;
  case 1:
    hr = (long)(conv * (landx + v - WITH->U2.tfh) + 0.5);
    vr = (long)(vconv * (landy - h - WITH->U1.tfw) + 0.5);
    br = (long)(conv * (landx + v + WITH->U2.tfd) + 0.5);
    ar = (long)(vconv * (landy - h) + 0.5);
    break;
  case 3:
    hr = (long)(conv * (landx - v - WITH->U2.tfd) + 0.5);
    vr = (long)(vconv * (landy + h) + 0.5);
    br = (long)(conv * (landx - v + WITH->U2.tfh) + 0.5);
    ar = (long)(vconv * (landy + h + WITH->U1.tfw) + 0.5);
    break;
  case 2:
    hr = (long)(conv * (landx - h - WITH->U1.tfw) + 0.5);
    vr = (long)(vconv * (landy - v - WITH->U2.tfd) + 0.5);
    br = (long)(conv * (landx - h) + 0.5);
    ar = (long)(vconv * (landy - v + WITH->U2.tfh) + 0.5);
    break;
  }
  li = 1;  re = 1;  ob = 1;  un = 1;
  if (hr < 0) {  hr = 0;  li = 0;  }
  if (br > xmax) {  br = xmax;  re = 0;  }
  vr -= zilli;  ar -= zilli;
  if (vr < 0) {  vr = 0;  ob = 0;  }
  if (ar > ymax) {  ar = ymax;  un = 0;  below = 1;  }
  if (hr > br)  return;
  if (vr > ar)  return;
  if (ob)  setrect(hr, vr, br, vr);
  if (li)  setrect(hr, vr, hr, ar);
  if (un)  setrect(hr, ar, br, ar);
  if (re)  setrect(br, vr, br, ar);
}

static ushort pkpos;
static uchar pkn1()  {  uchar Result;
  Result = achm[pkpos];  pkpos++;  return Result;
}
static short pki1()  {  short b;
  b = pkn1();  if (b > 127)  b -= 256;  return b;
}
static short pkn2()  {  short b;
  b = pkn1();  return (b * 256 + pkn1());
}
static short pki2()  {  short b;
  b = pkn1();  if (b > 127)  b -= 256;
  return (b * 256 + pkn1());
}
static long pkn3()  {  long b;  short c;
  b = pkn1();  c = pkn1();
  return ((b * 256 + c) * 256 + pkn1());
}
static long pki3()  {  long b;
  b = pki1();  return (b * 65536L + pkn2());
}
static long pki4()  {  long b;
  b = pki2();  return (b * 65536L + pkn2());
}
static void pkdef()  {  long a, l;  ushort d;  uchar b, bb;
  uchar terminate;  short i, j, c;  fontdesc *WITH;  chdesc *WITH1;
  WITH = fontvect[fontint];  sprintf(STR, "%spk", FOFUL);
  fprintf(prot,"preparing font %ld: %s", f, STR);
  if( (fofil = fopen(STR, "rb"))==0) {
    fprintf(prot," not found :-(\n");
    sprintf(STR, "%spk", FOLOC);
    fprintf(prot,"preparing font %ld: %s", f, STR);
    fofil = fopen(STR, "rb");
  }
  if (fofil==0) {  WITH->mch = -1;
    fprintf(prot, " - file not found !\n");  return;
  }
  if ((fgetc(fofil)!=0xf7)||(fgetc(fofil)!=0x59)){  WITH->mch = -1;
    fprintf(prot, " - not a PKfile !\n");  fclose(fofil);  return;
  } else {
    fseek(fofil, 0L, 2);  WITH->danf = ftell(fofil);
    if (WITH->danf > 65520L) {  WITH->mch = -1;  fclose(fofil);
      fprintf(prot, " - too big for this driver\n");  return;
    } else {
      Tptr( WITH->chv = (chdesc *)calloc(256, sizeof(chdesc)) );
      Tptr( achm = (uchar *)malloc(WITH->danf) );
      fseek(fofil, 0L, 0);  fread(achm, WITH->danf, 1, fofil);
      fclose(fofil);  WITH->mch = -1;  pkpos = 0;  terminate = 0;
      do {  b = pkn1();
	if (b >= 240) {
	  switch (b) {
	  case 240:  case 241:  case 242:  case 243: l = 0;
	    for (i = 240; i <= b; i++)  l = (l << 8) + pkn1();
	    pkpos += l;  break;
	  case 244:  pkpos += 4;  break;
	  case 245:  terminate = 1;  break;
	  case 246:  break;
	  case 247:  b = pkn1();  i = pkn1();
	    pkpos += i + 4;  fofchk = pki4();
	    if (chk != 0) if (fofchk != 0) if (chk != fofchk)
             fprintf(prot, " *+* wrong checksum *+* ");
            pkpos += 8;  break;
	  case 248:  case 249:  case 250:  case 251:
	  case 252:  case 253:  case 254:  case 255:  break;
	  }
	} else {  d = pkpos - 1;  bb = b & 7;
	  switch (bb) {
	  case 0:  case 1:  case 2:  case 3:
	    l = bb * 256 + pkn1() - 8;  c = pkn1();  break;
	  case 4:  case 5:  case 6:  l = bb - 4;
	    l = (l << 16) + pkn2() - 13;  c = pkn1();  break;
	  case 7:  l = pki4() - 28;  c = pki4();  break;
	  }
	  WITH1 = &WITH->chv[c];
	  switch (bb) {
	  case 0:  case 1:  case 2:  case 3:
	    WITH1->U1.tfw = scaled(pkn3(), scf);  pkn1();
	    WITH1->U1.wid = pkn1();  WITH1->U1.hei = pkn1();
            WITH1->U1.hof = pki1();  WITH1->U1.vof = pki1();  break;
	  case 4:  case 5:  case 6:
	    WITH1->U1.tfw = scaled(pkn3(), scf);  pkn2();
	    WITH1->U1.wid = pkn2();  WITH1->U1.hei = pkn2();
            WITH1->U1.hof = pki2();  WITH1->U1.vof = pki2();  break;
	  case 7:
	    WITH1->U1.tfw = scaled(pki4(), scf);  pki4();  pki4();
	    WITH1->U1.wid = pki4();   WITH1->U1.hei = pki4();
            WITH1->U1.hof = pki4();   WITH1->U1.vof = pki4();  break;
	  }
	  pkpos += l;
	  if ((unsigned)c <= 255) {
	    if (WITH->mch < c)  WITH->mch = c;
	    WITH->chv[c].U1.bmp = d;
      }	} } while (!terminate); free(achm);
      if (WITH->mch < 0)  fprintf(prot, " - PKfile in error !\n");
       else  fprintf(prot, " - available\n");
      WITH->chv = (chdesc *) realloc(WITH->chv, 16*(WITH->mch + 1));
      Tptr( WITH->fonam = (char *) malloc(strlen(STR)+1) );
      strcpy(WITH->fonam, STR);
} } }
static struct  {  short xs, x, wid1;  short ii, j;
  uchar dd, db;  ushort d;  uchar white;  uchar buf[xmb + 1];
  uchar bmerk;  long repc, count;  short dynf, dyng, dynh;
}  Lpkc;
static uchar pknib()  {  uchar Result;
  if (Lpkc.bmerk != 0) {
    Result = Lpkc.bmerk & 0xf;  Lpkc.bmerk = 0;  return Result;
  }
  Lpkc.bmerk = pkn1();  Result = Lpkc.bmerk >> 4;
  Lpkc.bmerk |= 0xf0;  return Result;
}
static long pknum()  {  uchar i, j, k;  long n;
  k = 1;
  do {  i = pknib();  k++;
    if (i == 0) {
      do {  j = pknib();  i++;  } while (j == 0);
      n = j;
      while (i > 0) {  i--;  n = (n << 4) + pknib();  }
      n += Lpkc.dyng;
    } else if (i <= Lpkc.dynf)  n = i;
    else if (i < 14)  n = (i << 4) + pknib() + Lpkc.dynh;
    else if (i == 14)  k = 0;
    else {  k = 1;  n = 1;  }
    if (k == 1)  Lpkc.repc = n;
  } while (k != 2);  return n;
}
static void pkline()  {
  if (Lpkc.dynf == 14) {
    Lpkc.j = Lpkc.wid1 + Lpkc.xs;
    Lpkc.db += Lpkc.xs;
    do {
      if (Lpkc.db < 8)	Lpkc.d = (Lpkc.d << 8) | pkn1();
      else  Lpkc.db -= 8;
      Lpkc.dd = (Lpkc.d >> Lpkc.db) & 255;
      if (Lpkc.j >= 8) {  Lpkc.j -= 8;	Lpkc.buf[Lpkc.x] = Lpkc.dd;
      } else {	Lpkc.db += 8 - Lpkc.j;
	Lpkc.buf[Lpkc.x] = Lpkc.dd & (0xff00L >> Lpkc.j) & 255;
	Lpkc.j = 0;
      }  Lpkc.x++;
    } while (Lpkc.j != 0);
    Lpkc.d &= 0xffffL >> (16 - Lpkc.db);  return;
  }
  Lpkc.ii = 0;  Lpkc.j = Lpkc.wid1;  Lpkc.db = 8 - Lpkc.xs;  Lpkc.d = 0;
  if (Lpkc.repc > 0) {  Lpkc.repc--;  return;  }
  while (Lpkc.j > 0) {
    if (Lpkc.count == 0) { Lpkc.count = pknum();  Lpkc.white = !Lpkc.white; }
    Lpkc.dd = Lpkc.db;
    if (Lpkc.dd > Lpkc.j)  Lpkc.dd = Lpkc.j;
    if (Lpkc.dd > Lpkc.count)  Lpkc.dd = Lpkc.count;
    if (Lpkc.white)  Lpkc.db -= Lpkc.dd;
    else {  Lpkc.d += 1 << Lpkc.db;
      Lpkc.db -= Lpkc.dd;  Lpkc.d -= 1 << Lpkc.db;
    }
    Lpkc.count -= Lpkc.dd;  Lpkc.j -= Lpkc.dd;
    if (Lpkc.db == 0 || Lpkc.j == 0) {
      Lpkc.buf[Lpkc.x] = Lpkc.d & 255;
      Lpkc.x++;  Lpkc.d = 0;  Lpkc.db = 8;
} } }
static void pkchar()  {  short hr, vr;  long bma, bmx;
  short x1, x2, x3, y1, y2, y;  uchar b, bb, mach, mac, mpm, bach;
  fontdesc *WITH;  chdesc *WITH1;
  WITH = fontvect[fontint];  WITH1 = &WITH->chv[c];
  pkpos = WITH1->U1.bmp;  b = pkn1();
  Lpkc.white = ((b & 8) == 0);  Lpkc.wid1 = WITH1->U1.wid;
  Lpkc.dynf = b >> 4;
  Lpkc.dyng = (13 - Lpkc.dynf) * 16 + Lpkc.dynf - 15;
  Lpkc.dynh = -(Lpkc.dynf + 1) * 15;  bb = b & 7;
  switch (bb) {
  case 0:  case 1:  case 2:  case 3:  pkpos += 10;  break;
  case 4:  case 5:  case 6:  pkpos += 16;  break;
  case 7:  pkpos += 36;  break;
  }
  Lpkc.bmerk = 0;  Lpkc.d = 0;  Lpkc.db = 0;  Lpkc.repc = 0;
  Lpkc.count = 0;  Lpkc.white = !Lpkc.white;
  switch (dviori) {
  case 0:
    hr = (long)(conv * h + 0.5) - WITH1->U1.hof;
    vr = (long)(vconv * v + 0.5) - WITH1->U1.vof - zilli;
    if (vr > ymax)  below = 1;  else {
      if (vr + WITH1->U1.hei >= 1) {
	x1 = hr / 8;  x2 = (hr + WITH1->U1.wid - 1) / 8;
	Lpkc.xs = hr & 7;	y2 = vr + WITH1->U1.hei - 1;
	if (y2 > ymax) {  y2 = ymax;  below = 1;  }
	if (0 <= x1) {
	  if (x2 <= xmb) {
	    for (y = vr; y <= y2; y++) {
	      Lpkc.x = x1;  pkline();
	      if (y >= 0) {
		for (Lpkc.x = x1; Lpkc.x <= x2; Lpkc.x++)
		  pixet(y, Lpkc.x, Lpkc.buf[Lpkc.x]);
    } } } } } }  break;
  case 1:
    hr = (long)(conv * (landx + v) + 0.5) - WITH1->U1.vof;
    vr = (long)(vconv * (landy - h) + 0.5) + WITH1->U1.hof - zilli;
    if (vr - WITH1->U1.wid + 1 > ymax)  below = 1;  else {
      if (vr >= 0) {  Lpkc.xs = 0;  mac = 0x80;  bma = 0;	y1 = vr;
	if (y1 > ymax) {  below = 1;  bma += ((ulong)(y1 - ymax)) >> 3;
	  mac = 0x80 >> ((y1 - ymax) & 7);  y1 = ymax;
	}
	y2 = vr - WITH1->U1.wid + 1;  if (y2 < 0)  y2 = 0;
	x2 = hr + WITH1->U1.hei - 1;  if (x2 > xmax)  x2 = xmax;
	for (x3 = hr; x3 <= x2; x3++) {
	  Lpkc.x = 0;  pkline();
	  if (x3 >= 0) {
	    mach = mac;  Lpkc.x = ((unsigned)x3) >> 3;
	    mpm = 0x80 >> (x3 & 7);  bmx = bma;  bach = Lpkc.buf[bmx];
	    for (y = y1; y >= y2; y--) {
	      if ((bach & mach) != 0)  pixet(y, Lpkc.x, mpm);
	      mach >>= 1;
	      if (mach == 0) {
		mach = 0x80;  bmx++;  bach = Lpkc.buf[bmx];
    } } } } } }  break;
  case 3:
    hr = (long)(conv * (landx - v) + 0.5) + WITH1->U1.vof;
    vr = (long)(vconv * (landy + h) + 0.5) - WITH1->U1.hof - zilli;
    if (vr > ymax)  below = 1;  else {
      if (vr + WITH1->U1.wid >= 1) {
	Lpkc.xs = 0;  mac = 0x80;  bma = 0;  y1 = vr;
	if (y1 < 0) {  bma += ((unsigned)(-y1)) >> 3;
	  mac = 0x80 >> ((-y1) & 7);  y1 = 0;
	}
	y2 = vr + WITH1->U1.wid - 1;
	if (y2 > ymax) {  y2 = ymax;  below = 1;  }
	x2 = hr - WITH1->U1.hei + 1;  if (x2 < 0)  x2 = 0;
	for (x3 = hr; x3 >= x2; x3--) {
	  Lpkc.x = 0;  pkline();
	  if (x3 <= xmax) {
	    mach = mac;  Lpkc.x = ((unsigned)x3) >> 3;
	    mpm = 0x80 >> (x3 & 7);  bmx = bma;  bach = Lpkc.buf[bmx];
	    for (y = y1; y <= y2; y++) {
	      if ((bach & mach) != 0)  pixet(y, Lpkc.x, mpm);
	      mach >>= 1;
	      if (mach == 0) {
		mach = 0x80;  bmx++;  bach = Lpkc.buf[bmx];
    } } } } } }  break;
  case 2:
    hr = (long)(conv * (landx - h) + 0.5) + WITH1->U1.hof;
    vr = (long)(vconv * (landy - v) + 0.5) + WITH1->U1.vof - zilli;
    if (vr - WITH1->U1.hei + 1 > ymax)  below = 1;  else {
      if (vr >= 0) {
	x1 = hr / 8;  x2 = (hr - WITH1->U1.wid + 1) / 8;
	Lpkc.xs = (7 - hr) & 7;  y2 = vr - WITH1->U1.hei + 1;
	if (y2 < 0)  y2 = 0;
	if (vr > ymax)  below = 1;
	if (0 <= x2) {
	  if (x1 <= xmb) {
	    for (y = vr; y >= y2; y--) {
	      Lpkc.x = xmb - x1;  pkline();
	      if (y <= ymax) {
		for (Lpkc.x = x1; Lpkc.x >= x2; Lpkc.x--)
		  pixet(y, Lpkc.x, bitrev[Lpkc.buf[xmb - Lpkc.x]]);
    } } } } } }  break;
} }

static void fontdef() {  uchar a, b, p, q;  fontdesc *WITH;
  if (f < 0)  baddvi("negative fontnumber");
  b = f & 0xff;  a = 0;
  if ((f > 255) || (fontvect[b] != NULL)) do {
    if (fontvect[a] == NULL)  b = a;
    else if (fontvect[a]->dfn == f)  baddvi("double fontnumber");
    a++;
  } while (a);
  if (fontvect[b] != NULL)  baddvi("too many fonts");
  fontint = b;
  Tptr( fontvect[b] = (fontdesc *)malloc(sizeof(fontdesc)) );
  WITH = fontvect[fontint];  WITH->dfn = f;
  chk = dvinum(4);  scf = dvinum(4);  dsz = dvinum(4);
  WITH->chm = NULL;  WITH->fty = -1;
  p = dvibyte();  q = dvibyte();  dvibytes(FONAM, q);
  if (p == 0)  strcpy(FOPRE, fontprefix);  else dvibytes(FOPRE, p);
  sprintf(FOMAG, "%ld",
	  (long)(xres * dvimag / 1000.0 * ((double)scf / dsz) + 0.5));
#ifdef __MSDOS__
  sprintf(FOFUL, "%s%s\\%s.", FOPRE, FOMAG, FONAM);
  sprintf(FOLOC, "%s.", FONAM);
#else
  sprintf(FOFUL, "%s%s.%s", FOPRE, FONAM, FOMAG);
  sprintf(FOLOC, "%s.%s", FONAM, FOMAG);
#endif
  pkdef();  if (WITH->mch < 0)  tfmdef();
}

static void fontlod() { uchar b = 0;
  fontdesc *WITH = fontvect[fontint];
  WITH->chm = (uchar *)malloc(WITH->danf);
  if (WITH->chm == NULL) { do {
      if (fontvect[b] != NULL) {
	if (fontvect[b]->chm) free(fontvect[b]->chm);
	fontvect[b]->chm = NULL;
      }  b++;
    } while (b);
    Tptr( WITH->chm = (uchar *)malloc(WITH->danf) );
  }
  fofil = fopen(WITH->fonam, "rb");
  fread(WITH->chm, WITH->danf, 1, fofil);  fclose(fofil);
}

static void fontset() {  uchar a, b, x;
  b = f & 0xff;  x = 0;
  if (fontvect[b] != NULL)  if (fontvect[b]->dfn == f)  x = 1;
  if (x == 0) {  a = 0;
    do {
      if (fontvect[a] == NULL)	a++;
      else if (fontvect[a]->dfn != f)  a++;
      else {  x = 1;  b = a;  a = 0;  }
    } while (a != 0);
  }
  if (x == 0)  baddvi("undefined fontnumber");
  fontint = b;
}
static void putrule() {  short hr, vr, br, ar;
  if (b <= 0)  return;
  switch (dviori) {
  case 0:
    hr = (long)(conv * h + 0.5);
    vr = (long)(vconv * (v - a) + 0.5);
    br = (long)(conv * b + 0.5);  if (br > 0)  br--;
    ar = (long)(vconv * a + 0.5);
    break;
  case 1:
    hr = (long)(conv * (landx + v - a) + 0.5);
    vr = (long)(vconv * (landy - h - b) + 0.5);
    br = (long)(conv * a + 0.5);
    ar = (long)(vconv * b + 0.5);  if (ar > 0)  ar--;
    break;
  case 3:
    hr = (long)(conv * (landx - v) + 0.5);
    vr = (long)(vconv * (landy + h) + 0.5);
    br = (long)(conv * a + 0.5);
    ar = (long)(vconv * b + 0.5);  if (ar > 0)  ar--;
    break;
  case 2:
    hr = (long)(conv * (landx - h - b) + 0.5);
    vr = (long)(vconv * (landy - v) + 0.5);
    br = (long)(conv * b + 0.5);  if (br > 0)  br--;
    ar = (long)(vconv * a + 0.5);
    break;
  }
  vr -= zilli;  ar += vr;  br += hr;
  if (hr < 0)  hr = 0;
  if (br > xmax)  br = xmax;
  if (vr < 0)  vr = 0;
  if (ar > ymax) {  ar = ymax;  below = 1;  }
  if (hr <= br)  if (vr <= ar)  setrect(hr, vr, br, ar);
}
static void putchar_() {  fontdesc *WITH;  chdesc *WITH1;
  WITH = fontvect[fontint];
  if (c > WITH->mch) {  q = 0;  return;  }
  WITH1 = &WITH->chv[c];  q = WITH1->U1.tfw;
  if (WITH->fty == 1) {  tfmchar();  return;  }
  if (WITH1->U1.bmp == 0)  return;
  if (WITH->chm == NULL)  fontlod();
  achm = WITH->chm;  pkchar();
}
static void clrpxlmem() {  short i;  below = 0;
  for (i = 0; i <= ymax; i++)
   memset((ptr)pxlmem[i], 0, (xmb+1)*sizeof(colpix));
}
static void pagebeg() {  uchar j;  greydesc *WITH;
  for (j = 0; j <= 9; j++)  cnt[j] = dvinum(4);
  lpp = dvinum(4);  pagnum++;
  if (pagnum >= pag1) {  started = 1;  fprintf(prot, "[%d", pagnum);  }
  s = 0;  w = 0;  x = 0;  y = 0;  z = 0;  zilli = 0;  lz = 0;  zoll = zoll0;
  for (j = 0; j <= 7; j++) {  WITH = &greymask[j];  WITH->maskc = 0;
    WITH->maskm = 0;  WITH->masky = 0;  WITH->maskk = 0xff;
  }
  zoelli = ftell(dvifile);  zoelli += (long)dvibufp - (long)dvibufe;
  h = (long)((xres - hoff) / conv + 0.5);
  v = (long)((yres - voff) / vconv + 0.5);
  clrpxlmem();
}
static void pageend() {
  if (s != 0)  fprintf(prot, "Stack not empty at EOP\n");
  if (!started)  return;
  hardcopy();  /* fprintf(prot, "/%d", (short)zoll); */
  if (zoll > 0 && below) {  zoll--;  dviposit(zoelli);
    s = 0;  w = 0;  x = 0;  y = 0;  z = 0;  zilli += ymax + 1;
    h = (long)((xres - hoff) / conv + 0.5);
    v = (long)((yres - voff) / vconv + 0.5);
    clrpxlmem();  return;
  }
  hardform();  fprintf(prot, "]");
  paganz--;  if (paganz <= 0) fini = 1;
}
static void deffont() {  ushort l, m;
  if (!post) {  fontdef();  return;  }
  dviskip(12L);  l = dvibyte();  m = dvibyte();  dviskip((long)(l + m));
}
static void special() {  long i, j, k;  char *parm;
  double x, y, cy, ma, ye, bl;  short cle, m, n;
  if (spl > 255) {  fprintf(prot, "special >>");
    for (i = spl; i > 0; i--)  fputc(dvibyte(), prot);
    fprintf(prot, "<< ignored\n");  return;
  }
  dvibytes(comment, (int)spl);
  if (!memcmp(comment, "landend", 7)) {  dviori = 0;  return;  }
  if (!memcmp(comment, "landstart", 9)) {
    if (comment[10] == '1')  dviori = 1;
    else if (comment[10] == '0')  dviori = 3;
    else dviori = 2;
    sscanf(comment+12, "%lg%lg", &x,&y);
    j = (long)(x * 65535L + 0.5);
    k = (long)(y * 65535L + 0.5);
    switch (dviori) {
    case 1:  landx = h - v;  landy = v + j + h;  break;
    case 3:  landx = h + k + v;  landy = v - h;  break;
    case 2:  landx = h + h + k;  landy = v + j + v;  break;
  } return; }
  if (memcmp(comment, "color", 5)) {
    fprintf(prot, "special >>%s<< ignored", comment);  return;
  }
  parm = comment+6;
  if (!memcmp(parm, "pop", 3)) {  parm +=4;  colst--;
    if (colst < 0) {  colst = 0;  fprintf(prot, " color stack underflow"); }
  } else {
    if (!memcmp(parm, "push cmyk", 9)) {  parm +=10;  colst++;
      if (colst > smax-1) { colst = smax-1;
        fprintf(prot, " color stack overflow");
    } }
    if (sscanf(parm,"%lg%lg%lg%lg",&cy,&ma,&ye,&bl)<4) {
      fprintf(prot," color: cmyk values <%s> incomplete ",comment); return;
    }
    n = (long)(cy * maxink);  if (n < 0) n = 0;
    if (n > maxink) n = maxink;  stackcy[colst] = n;
    n = (long)(ma * maxink);  if (n < 0) n = 0;
    if (n > maxink) n = maxink;  stackma[colst] = n;
    n = (long)(ye * maxink);  if (n < 0) n = 0;
    if (n > maxink) n = maxink;  stackye[colst] = n;
    n = (long)(bl * maxink);  if (n < 0) n = 0;
    if (n > maxink) n = maxink;  stackbl[colst] = n;
  }
  n = stackcy[colst];  cle = n;
  for (m = 0; m <= 7; m++)  greymask[m].maskc = maskb[n][0][m & 3];
  n = stackma[colst];  cle += n;
  for (m = 0; m <= 7; m++)  greymask[m].maskm = maskb[n][1][m & 3];
  n = stackye[colst];  cle += n;
  for (m = 0; m <= 7; m++)  greymask[m].masky = maskb[n][2][m & 3];
  n = stackbl[colst];  cle += n;
  for (m = 0; m <= 7; m++)  greymask[m].maskk = maskb[n][3][m & 3];
  clearing = (cle == 0);
}
static void preambl() {  uchar l;
  l = dvibyte();  num = dvinum(4);  den = dvinum(4);
  dvimag = dvinum(4);  if (newmag != 0) dvimag = newmag;
  conv = num / 254000.0 * ((double)xres / den) * (dvimag / 1000.0);
  vconv = num / 254000.0 * ((double)yres / den) * (dvimag / 1000.0);
  l = dvibyte();  dvibytes(comment, l);  fprintf(prot, "%s\n", comment);
}
static void postamb() {
  lpp = dvinum(4);  num = dvinum(4);  den = dvinum(4);
  dvimag = dvinum(4);  if (newmag != 0) dvimag = newmag;
  conv = num / 254000.0 * ((double)xres / den) * (dvimag / 1000.0);
  vconv = num / 254000.0 * ((double)yres / den) * (dvimag / 1000.0);
  mxv = dvinum(4);  mxh = dvinum(4);  mst = dvinum(2);  mpn = dvinum(2);
}
main(int argc, char **argv) { char *parm;
  post = 0;  fini = 0;  started = 0;  dviori = 0;  pagnum = 0;
  pag1 = 1;  paganz = 9999;  newmag = 0;  q = 0;  hoff = 78;  voff = 156;
  for (i = 0; i <= ymax; i++)  {
    Tptr( pxlmem[i] = (colpix *) malloc((xmb+1)*sizeof(colpix)) );
  }
  Tptr( fontvect = (fontdesc **) calloc(256, 4) );
  initbitrev();  colst = 0;
  stackcy[colst] = 0;  stackma[colst] = 0;
  stackye[colst] = 0;  stackbl[colst] = maxink;

  fprintf(prot, "This is the HP Deskjet 550 Color TeX driver, V 94.01 .\n");
  fprintf(prot, "(C)opyright 1994 Wolfgang R. Mueller, Computing Centre,\n");
  fprintf(prot, "Heinrich-Heine-University Duesseldorf, Germany\n");
  if (argc == 1) {
    fprintf(prot, "Please use with dvifilename and optional parameters\n");
    fprintf(prot, " -s<starting page>     (default: 1  i.e. first in file)\n");
    fprintf(prot, " -c<number of pages>   (default: 9999  i.e. all)\n");
    fprintf(prot, " -m<new magnification> (default: from DVIfile)\n");
    fprintf(prot, " -h<horizontal offset> (default: %ld (pixels)\n", hoff);
    fprintf(prot, " -v<vertical offset>   (default: %ld (pixels)\n", voff);
    fprintf(prot, " -f<font directory>    (default: %s)\n", fontprefix);
    fprintf(prot, " -t<TFMfile directory> (default: %s)\n", tfmprefix);
    fprintf(prot, " -o<outfile>           (default: %s)\n", prfnam);
    fprintf(prot, "   prn for <outfile> goes directly to printer port,\n");
    fprintf(prot, "   empty <outfile> part is replaced by <DVIfile>.pcl\n");
    exit(0);
  }
  strcpy(dviname, "texput");
  for (j = 1; j < argc; j++) {  parm = argv[j];
    if (parm[0] != '-') {  strcpy(dviname, parm);
    } else {  switch (parm[1]) {
      case 's':  case 'S':  sscanf(parm+2, "%d", &pag1);  break;
      case 'c':  case 'C':  sscanf(parm+2, "%d", &paganz);  break;
      case 'f':  case 'F':  strcpy(fontprefix, parm+2);  break;
      case 't':  case 'T':  strcpy(tfmprefix, parm+2);  break;
      case 'm':  case 'M':  sscanf(parm+2, "%ld", &newmag);  break;
      case 'h':  case 'H':  sscanf(parm+2, "%ld", &hoff);  break;
      case 'v':  case 'V':  sscanf(parm+2, "%ld", &voff);  break;
      case 'o':  case 'O':  strcpy(prfnam, parm+2);	break;
  } } }
  strcpy(defnam, dviname);  prfeval();  dviopen();  postamb();
  do {  o = dvibyte();  /* fprintf(prot, "(%u)", (ushort)o); */
    switch (o) {
    case 128:  case 129:  case 130:  case 131:
      c = dvinum(o - 127);  if (started) putchar_();  h += q;  break;
    case 132:  a = dviint(4);  b = dviint(4);
      if (started) putrule();  h += b;  break;
    case 133:  case 134:  case 135:  case 136:
      c = dvinum(o - 132);  if (started) putchar_();  break;
    case 137:  a = dviint(4);  b = dviint(4);
      if (started) putrule();  break;
    case 138:  break;
    case 139:  pagebeg();  break;
    case 140:  pageend();  break;
    case 141:  if (s < smax) {	s++;  hs[s - 1] = h;  vs[s - 1] = v;
	ws[s - 1] = w;	xs[s - 1] = x;	ys[s - 1] = y; zs[s - 1] = z;
      } else  baddvi("stack overflow");  break;
    case 142:  if (s > 0) {  h = hs[s - 1];  v = vs[s - 1];
	w = ws[s - 1];	x = xs[s - 1];	y = ys[s - 1];	z = zs[s - 1];	s--;
      } else  baddvi("stack underflow");  break;
    case 143:  case 144:  case 145:  case 146:
      h += dviint(o - 142);  break;
    case 147:  h += w;  break;
    case 148:  case 149:  case 150:  case 151:
      w = dviint(o - 147);  h += w;  break;
    case 152:  h += x;  break;
    case 153:  case 154:  case 155:  case 156:
      x = dviint(o - 152);  h += x;  break;
    case 157:  case 158:  case 159:  case 160:
      v += dviint(o - 156);  break;
    case 161:  v += y;  break;
    case 162:  case 163:  case 164:  case 165:
      y = dviint(o - 161);  v += y;  break;
    case 166:  v += z;  break;
    case 167:  case 168:  case 169:  case 170:
      z = dviint(o - 166);  v += z;  break;
    case 235:  case 236:  case 237:  case 238:
      f = dvinum(o - 234);  if (started) fontset();  break;
    case 239:  case 240:  case 241:  case 242:
      spl = dvinum(o - 238);  special();  break;
    case 243:  case 244:  case 245:  case 246:
      f = dvinum(o - 242);  deffont();  break;
    case 247:  preambl();  break;
    case 248:  fini = 1;  break;
    case 249:  dviposit(0L);  post = 1;  break;
    case 250:  case 251:  case 252:
    case 253:  case 254:  case 255:  break;
    default:
      if (o <= 127) {
	c = o;	if (started) putchar_();  h += q;
      } else if (o >= 171 && o <= 234) {
	f = o - 171;  if (started)  fontset();
  } break; } } while (!fini);
  fprintf(prot,"\n"); prclos(); fclose(dvifile); exit(0);
}
