summaryrefslogtreecommitdiff
path: root/dviware/kyocera/dvi.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/kyocera/dvi.c
Initial commit
Diffstat (limited to 'dviware/kyocera/dvi.c')
-rw-r--r--dviware/kyocera/dvi.c702
1 files changed, 702 insertions, 0 deletions
diff --git a/dviware/kyocera/dvi.c b/dviware/kyocera/dvi.c
new file mode 100644
index 0000000000..e2b292a41b
--- /dev/null
+++ b/dviware/kyocera/dvi.c
@@ -0,0 +1,702 @@
+/* dvi.c The dvi reader for dvi printers.
+ * Copyright 1985 Massachusetts Institute of Technology.
+ * Author: cjl@oz
+ * Slightly changed by Kees Straatman (mcvax!guvaxin!kees) for Kyocera driver
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include "fonts.h"
+#include "dev.h"
+#include "util.h"
+#include "dvi.h"
+
+extern char *rindex();
+extern char *mktemp();
+extern long ftell();
+
+#define DVI_STACK_SIZE 512 /* Maximum dvi stack size supported. */
+#define NFONTDIR_MAX 16
+#define MAXDRIFT 2
+#ifndef PXLDIR
+#define PXLDIR "/usr/lib/tex/pxlfonts"
+#endif
+
+/* Runtime parameters specified by user
+ */
+FILE *out = stdout;
+FILE *in;
+char *dirvec[NFONTDIR_MAX];
+char *acctfile = (char *)0;
+int npages = 0;
+int dirveclen;
+unsigned long devopts,fontopts;
+
+/* Runtime parameters specified by the dvi file & the user
+ */
+char pre_comment[257];
+long numerator,denominator,half_denominator,dvinum,dviden,dvimag;
+long globalmag;
+
+
+/* Runtime data structures
+ */
+char stdoutbuf[BUFSIZ];
+long h_pix,v_pix,h,v,w,x,y,z,device_dpi,fntspc;
+unsigned long fntvec[512],chrvec[512][4];
+int stackptr,fntveclen;
+long hstack[DVI_STACK_SIZE];
+long h_pixstack[DVI_STACK_SIZE];
+long vstack[DVI_STACK_SIZE];
+long v_pixstack[DVI_STACK_SIZE];
+long wstack[DVI_STACK_SIZE];
+long xstack[DVI_STACK_SIZE];
+long ystack[DVI_STACK_SIZE];
+long zstack[DVI_STACK_SIZE];
+
+/* Stack manipulation: push and pop
+ */
+
+push()
+{
+ if (stackptr >= DVI_STACK_SIZE) croak("dvi stack overflow");
+ hstack[stackptr] = h;
+ h_pixstack[stackptr] = h_pix;
+ vstack[stackptr] = v;
+ v_pixstack[stackptr] = v_pix;
+ wstack[stackptr] = w;
+ xstack[stackptr] = x;
+ ystack[stackptr] = y;
+ zstack[stackptr] = z;
+ stackptr++;
+}
+
+pop()
+{
+ if (stackptr <= 0) croak("dvi stack underflow");
+ stackptr--;
+ h = hstack[stackptr];
+ h_pix = h_pixstack[stackptr];
+ v = vstack[stackptr];
+ v_pix = v_pixstack[stackptr];
+ w = wstack[stackptr];
+ x = xstack[stackptr];
+ y = ystack[stackptr];
+ z = zstack[stackptr];
+}
+
+position()
+{
+ register int dh = h_pix - (h * numerator + half_denominator) / denominator;
+ register int dv = v_pix - (v * numerator + half_denominator) / denominator;
+
+ if (dh > MAXDRIFT) h_pix -= MAXDRIFT;
+ else if (dh < -MAXDRIFT) h_pix += MAXDRIFT;
+ if (dv > MAXDRIFT) v_pix -= MAXDRIFT;
+ else if (dv < -MAXDRIFT) v_pix += MAXDRIFT;
+ dev_position(h_pix,v_pix);
+}
+
+/* Drawing: set and setrule
+ */
+set(ch,movep)
+ unsigned long ch;
+ int movep;
+{
+ long texwidth,devwidth;
+
+ f_use_char(ch,&texwidth,&devwidth);
+ position();
+ f_setc(ch,devwidth);
+ if (movep) {
+ h += texwidth;
+ h_pix += devwidth;
+ }
+}
+
+setrule(movep)
+ int movep;
+{
+ long a = sget4(in);
+ long b = sget4(in);
+ long a_pix,b_pix;
+
+ if (a > fntspc || a < -fntspc)
+ a_pix = ((v + a) * numerator + half_denominator) / denominator - v_pix;
+ else if (a < 0)
+ a_pix = - ((-a * numerator + half_denominator) / denominator);
+ else
+ a_pix = (a * numerator + half_denominator) / denominator;
+ if (b > fntspc || b < -fntspc)
+ b_pix = ((h + b) * numerator + half_denominator) / denominator - h_pix;
+ else if (b < 0)
+ b_pix = - ((-b * numerator + half_denominator) / denominator);
+ else
+ b_pix = (b * numerator + half_denominator) / denominator;
+ if (a_pix > 0 && b_pix > 0) {
+ position();
+ dev_draw_box(a_pix,b_pix);
+ }
+ if (movep) {
+ h += b;
+ h_pix += b_pix;
+ }
+}
+
+/* Movement: right and down
+ */
+
+right(dx)
+ long dx;
+{
+ h += dx;
+ if (dx > fntspc || dx < -fntspc * 4)
+ h_pix = (h * numerator + half_denominator) / denominator;
+ else if (dx < 0)
+ h_pix -= (-dx * numerator + half_denominator) / denominator;
+ else
+ h_pix += (dx * numerator + half_denominator) / denominator;
+}
+
+down(dy)
+ long dy;
+{
+ v += dy;
+ if (dy > fntspc * 5)
+ v_pix = (v * numerator + half_denominator) / denominator;
+ else if (dy < 0)
+ v_pix -= (-dy * numerator + half_denominator) / denominator;
+ else
+ v_pix += (dy * numerator + half_denominator) / denominator;
+}
+
+
+/* Special: xxx
+ */
+xxx(k)
+ long k;
+{
+ position();
+ dev_special(k,in);
+}
+
+
+/* Fonts: fntdef
+ */
+fntdef(fontnum)
+ unsigned long fontnum;
+{
+ unsigned long tfmchecksum = get4(in);
+ long s = sget4(in);
+ long d = sget4(in);
+ int a = get1(in);
+ int l = get1(in);
+ int i;
+ char area[257];
+ char name[257];
+ long mag;
+
+ for (i = 0; i < a; i++) area[i] = getc(in); area[a] = 0;
+ for (i = 0; i < l; i++) name[i] = getc(in); name[l] = 0;
+ mag = (long) (((double) s) * ((double) globalmag) / ((double) d));
+ debug("fntdef: num= %d area=\"%s\" name=\"%s\" mag=%d s=%d d=%d\n",
+ fontnum,area,name,mag,s,d);
+ f_define_font(fontnum,0,area,name,mag,s,tfmchecksum);
+}
+
+/* Fonts: fntdef
+ */
+nullfntdef(fontnum)
+ unsigned long fontnum;
+{
+ register int a,l,i;
+
+ (void) getc(in); (void) getc(in); (void) getc(in); (void) getc(in);
+ (void) getc(in); (void) getc(in); (void) getc(in); (void) getc(in);
+ (void) getc(in); (void) getc(in); (void) getc(in); (void) getc(in);
+ a = getc(in);
+ l = getc(in);
+ for (i = 0; i < a; i++) (void) getc(in);
+ for (i = 0; i < l; i++) (void) getc(in);
+}
+
+/* Record this font number on fntvec
+ * We'll later pass fntvec to the fonts module
+ */
+int fntmark(fnt)
+ unsigned long fnt;
+{
+ register int i;
+
+ for (i = 0; i < fntveclen; i++) if (fntvec[i] == fnt) return(i);
+ if (fntveclen >= sizeof(fntvec)) croak("too many fonts");
+ chrvec[fntveclen][0] = 0;
+ chrvec[fntveclen][1] = 0;
+ chrvec[fntveclen][2] = 0;
+ chrvec[fntveclen][3] = 0;
+ fntvec[fntveclen] = fnt;
+ return(fntveclen++);
+}
+
+chrmark(ch,i)
+ unsigned long ch;
+ int i;
+{
+ chrvec[i][ch/32] |= (1 << (ch % 32));
+}
+
+/* End of page processing: eop
+ */
+eop()
+{
+ dev_eop();
+}
+
+noprint_page(c,p)
+ long c[10];
+ long p;
+{
+ int f;
+ register int ch;
+
+ (void) c; (void) p;
+ fntveclen = 0;
+ for (;;) {
+ if (ferror(in)) croak("noprint_page dvi input");
+ switch (ch = getc(in)) {
+ case SETRULE:
+ case PUTRULE:
+ (void) getc(in);
+ (void) getc(in);
+ (void) getc(in);
+ (void) getc(in);
+
+ case RIGHT4:
+ case W4:
+ case DOWN4:
+ case X4:
+ case Y4:
+ case Z4:
+ (void) getc(in);
+
+ case RIGHT3:
+ case W3:
+ case X3:
+ case DOWN3:
+ case Y3:
+ case Z3:
+ (void) getc(in);
+
+ case RIGHT2:
+ case W2:
+ case X2:
+ case DOWN2:
+ case Y2:
+ case Z2:
+ (void) getc(in);
+
+ case RIGHT1:
+ case W1:
+ case X1:
+ case DOWN1:
+ case Y1:
+ case Z1:
+ (void) getc(in);
+
+ case NOP:
+ case PUSH:
+ case POP:
+ case W0:
+ case X0:
+ case Y0:
+ case Z0:
+ break;
+
+ case EOP:
+ return;
+
+
+ case SET1:
+ case PUT1: chrmark(get1(in),f); break;
+ case SET2:
+ case PUT2: chrmark(get2(in),f); break;
+ case SET3:
+ case PUT3: chrmark(get3(in),f); break;
+ case SET4:
+ case PUT4: chrmark(get4(in),f); break;
+ case FNT1: f = fntmark(get1(in)); break;
+ case FNT2: f = fntmark(get2(in)); break;
+ case FNT3: f = fntmark(get3(in)); break;
+ case FNT4: f = fntmark(get4(in)); break;
+ case FNTDEF1: nullfntdef(get1(in)); break;
+ case FNTDEF2: nullfntdef(get2(in)); break;
+ case FNTDEF3: nullfntdef(get3(in)); break;
+ case FNTDEF4: nullfntdef(get4(in)); break;
+ case XXX1: swallow(get1(in),in); break;
+ case XXX2: swallow(get2(in),in); break;
+ case XXX3: swallow(get3(in),in); break;
+ case XXX4: swallow(get4(in),in); break;
+
+ case EOF:
+ croak("noprint_page EOF between BOP and EOP");
+ break;
+
+ default:
+ if (ch >= SETCHAR0 && ch <= SETCHAR127)
+ chrmark((unsigned long) (ch - SETCHAR0),f);
+ else if (ch >= FNTNUM0 && ch <= FNTNUM63)
+ f = fntmark((unsigned long) (ch - FNTNUM0));
+ else croak("noprint_page dvi command %d between BOP and EOP",ch);
+ break;
+ }
+ }
+}
+
+print_page(c,p)
+ long c[10];
+ long p;
+{
+ long ch;
+
+ (void) p;
+ stackptr = 0;
+ h = v = w = x = y = z = h_pix = v_pix = 0;
+ position();
+ for (;;) {
+ if (ferror(in)) croak("print_page dvi input");
+ switch (ch = getc(in)) {
+ case EOF:
+ croak("print_page EOF between BOP and EOP");
+ break;
+
+ case SET1: set(get1(in),1); break;
+ case SET2: set(get2(in),1); break;
+ case SET3: set(get3(in),1); break;
+ case SET4: set(get4(in),1); break;
+ case SETRULE: setrule(1); break;
+ case PUT1: set(get1(in),0); break;
+ case PUT2: set(get2(in),0); break;
+ case PUT3: set(get3(in),0); break;
+ case PUT4: set(get4(in),0); break;
+ case PUTRULE: setrule(0); break;
+ case NOP: break;
+ case EOP: eop(); return;
+ case PUSH: push(); break;
+ case POP: pop(); break;
+ case RIGHT1: right(sget1(in)); break;
+ case RIGHT2: right(sget2(in)); break;
+ case RIGHT3: right(sget3(in)); break;
+ case RIGHT4: right(sget4(in)); break;
+ case W0: right(w); break;
+ case W1: right(w = sget1(in)); break;
+ case W2: right(w = sget2(in)); break;
+ case W3: right(w = sget3(in)); break;
+ case W4: right(w = sget4(in)); break;
+ case X0: right(x); break;
+ case X1: right(x = sget1(in)); break;
+ case X2: right(x = sget2(in)); break;
+ case X3: right(x = sget3(in)); break;
+ case X4: right(x = sget4(in)); break;
+ case DOWN1: down(sget1(in)); break;
+ case DOWN2: down(sget2(in)); break;
+ case DOWN3: down(sget3(in)); break;
+ case DOWN4: down(sget4(in)); break;
+ case Y0: down(y); break;
+ case Y1: down(y = sget1(in)); break;
+ case Y2: down(y = sget2(in)); break;
+ case Y3: down(y = sget3(in)); break;
+ case Y4: down(y = sget4(in)); break;
+ case Z0: down(z); break;
+ case Z1: down(z = sget1(in)); break;
+ case Z2: down(z = sget2(in)); break;
+ case Z3: down(z = sget3(in)); break;
+ case Z4: down(z = sget4(in)); break;
+ case FNT1: f_use_font(get1(in),&fntspc); break;
+ case FNT2: f_use_font(get2(in),&fntspc); break;
+ case FNT3: f_use_font(get3(in),&fntspc); break;
+ case FNT4: f_use_font(get4(in),&fntspc); break;
+ case FNTDEF1: nullfntdef(get1(in)); break;
+ case FNTDEF2: nullfntdef(get2(in)); break;
+ case FNTDEF3: nullfntdef(get3(in)); break;
+ case FNTDEF4: nullfntdef(get4(in)); break;
+ case XXX1: xxx(get1(in)); break;
+ case XXX2: xxx(get2(in)); break;
+ case XXX3: xxx(get3(in)); break;
+ case XXX4: xxx(get4(in)); break;
+
+ default:
+ if (ch >= SETCHAR0 && ch <= SETCHAR127)
+ set((unsigned long) (ch - SETCHAR0),1);
+ else if (ch >= FNTNUM0 && ch <= FNTNUM63)
+ f_use_font((unsigned long) (ch - FNTNUM0),&fntspc);
+ else croak("print_page dvi command %d between BOP and EOP",ch);
+ break;
+ }
+ }
+}
+
+/* Preamble processing.
+ */
+computescale()
+{
+ double dd;
+
+ /* Compute scale factors for this file. */
+ globalmag = dvimag;
+
+ /* This is real hokey, but will probably work for TEX82. */
+ if (dvinum != 25400000 || dviden != 473628672) {
+ fprintf(stderr,"DVI file numerator and denominator weren't exactly ");
+ fprintf(stderr,"what was expected.\nScaling may be wrong.\n");
+ }
+ numerator = ((long) (((double) dvinum)
+ / ((double) 254000)
+ / ((double) 10)));
+ denominator = ((long) (((double) dviden)
+ / ((double) globalmag)
+ * ((double) 1000)
+ / ((double) device_dpi)
+ / ((double) 10)));
+ half_denominator = denominator / 2;
+ debug("Computescale: globalmag=%d numerator=%d denominator=%d\n",
+ globalmag,numerator,denominator);
+
+}
+
+
+preamble()
+{
+ int i = getc(in);
+ int k;
+
+ dvinum = get4(in);
+ dviden = get4(in);
+ dvimag = get4(in);
+ k = get1(in);
+ if (i != 2) croak("id_byte=%d, probably not a dvi file",i);
+ for (i = 0; i < k; i++) pre_comment[i] = getc(in);
+ pre_comment[k] = '\0';
+ computescale();
+ debug("Preamble: dvinum=%d dviden=%d dvimag=%d\n",
+ dvinum,dviden,dvimag);
+ debug(" comment: \"%s\"\n",pre_comment);
+}
+
+/* Beginning of page processing
+ */
+bop()
+{
+ int i;
+ long c[10];
+ long p,fpos;
+
+ for (i = 0; i < 10; i++) c[i] = sget4(in);
+ p = sget4(in);
+ debug("first pass of page %d\n",c[0]);
+ fpos = ftell(in); /* Remember where we are */
+ noprint_page(c,p); /* First pass noprint to get fntvec */
+ /* Tell font module about the fonts */
+ f_newpage(fntvec,chrvec,fntveclen);
+ debug("second pass of page %d\n",c[0]);
+ fseek(in,fpos,0); /* Back up */
+ print_page(c,p); /* And finally do the page */
+ debug("done with page %d\n",c[0]);
+ npages++;
+}
+
+file_term()
+{
+ f_term();
+ close_ef();
+ dev_term();
+}
+
+/* Postamble processing.
+ */
+
+find_postamble()
+{
+ int ch;
+ long i = -4;
+ long q;
+
+ do (void) fseek(in,i--,2); while ((ch = getc(in)) == TRAILER);
+ if (ch != 2) croak("postamble id_byte=%d, probably not a dvi file",ch);
+ (void) fseek(in,i-4,2);
+ if ((ch = getc(in)) != POSTPOST) croak("no POSTPOST where expected");
+ q = sget4(in);
+ (void) fseek(in,q,0);
+ if ((ch = getc(in)) != POST) croak("no POST where expected");
+}
+
+
+postamble()
+{
+ int ch;
+ long p = sget4(in);
+ unsigned long l,u,maxstackdepth,npages;
+
+ dvinum = get4(in);
+ dviden = get4(in);
+ dvimag = get4(in);
+ computescale();
+ l = get4(in);
+ u = get4(in);
+ maxstackdepth = get2(in);
+ npages = get2(in);
+ debug("Postamble: dvinum=%d dviden=%d dvimag=%d maxstackdepth=%d\n",
+ dvinum,dviden,dvimag,maxstackdepth);
+ debug(" npages=%d\n",npages);
+ if (maxstackdepth > DVI_STACK_SIZE)
+ croak("dvi file has too much stack depth");
+ f_init(out,pgmnam,dirvec,dirveclen,numerator
+ ,denominator,globalmag,fontopts);
+ signal(SIGINT, file_term);
+ for (;;) {
+ if (ferror(in)) croak("postamble input");
+ switch (ch = getc(in)) {
+ case EOF:
+ croak("EOF found before POSTPOST");
+ break;
+
+ case FNTDEF1: fntdef(get1(in)); break;
+ case FNTDEF2: fntdef(get2(in)); break;
+ case FNTDEF3: fntdef(get3(in)); break;
+ case FNTDEF4: fntdef(get4(in)); break;
+ case NOP: break;
+ case POSTPOST: return;
+
+ default:
+ croak("dvi command %d in postamble",ch);
+ break;
+ }
+ }
+}
+
+/* Process a dvi file
+ */
+file_init()
+{
+ int ch;
+
+ if ((ch = getc(in)) != PRE)
+ croak("first char %d not PRE, probably not a dvi file",ch);
+ find_postamble();
+ dev_init(out,devopts,&device_dpi);
+ open_ef();
+ postamble();
+ (void) fseek(in,1L,0);
+ preamble();
+}
+
+dvi_file()
+{
+ int ch;
+
+ if (!dirveclen) dirvec[dirveclen++] = PXLDIR;
+ file_init();
+ for (;;) {
+ if (ferror(in)) croak("dvi_file input");
+ switch (ch = getc(in)) {
+ case EOF:
+ croak("EOF found between pages");
+ break;
+
+ case BOP: bop(); break;
+ case POST: file_term(); return;
+ case FNTDEF1: fntdef(get1(in)); break;
+ case FNTDEF2: fntdef(get2(in)); break;
+ case FNTDEF3: fntdef(get3(in)); break;
+ case FNTDEF4: fntdef(get4(in)); break;
+ case NOP: break;
+
+ default:
+ croak("dvi command %d between pages",ch);
+ break;
+ }
+ }
+}
+
+process_stdin()
+{
+ int ch;
+ FILE *tf;
+ char tfn[257];
+ struct stat st;
+
+ if (fstat(fileno(stdin),&st) < 0) croak("can't stat stdin");
+ if ((st.st_mode & S_IFMT) == S_IFREG) {
+ in = stdin; infname = "stdin";
+ dvi_file();
+ in = NULL; infname = NULL;
+ } else {
+ /* Copy the dvi data to a temp file, since we have to do disk seeks. */
+ (void) sprintf(tfn,"/usr/tmp/%s.XXXXXX",pgmnam);
+ if (!(tf = fopen(mktemp(tfn),"w"))) croak("couldn't open %s",tfn);
+ unlink(tfn);
+ while (!ferror(stdin) && (ch = getchar()) != EOF) putc(ch,tf);
+ if (ferror(stdin)) croak("error on stdin");
+ (void) fseek(tf,0L,0);
+ infname = tfn; in = tf;
+ dvi_file();
+ in = NULL; infname = NULL;
+ (void) fclose(tf);
+ }
+}
+
+account()
+{
+ FILE *acctf;
+
+ if (user && acctfile && access(acctfile, 02) >= 0 &&
+ ((acctf = fopen(acctfile, "a")) != NULL)) {
+ fprintf(acctf, "%-5d\t%s:%s\n", npages, host, user);
+ fclose(acctf);
+ }
+}
+
+main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ FILE *f;
+ int nfiles = 0;
+ int i;
+
+ setbuf(stdout,stdoutbuf);
+ pgmnam = argv[0];
+ fontopts = 0;
+ devopts = 0;
+
+
+ for (i = 1; i < argc; i++)
+ if (argv[i][0] == '-') switch(argv[i][1]) {
+
+ case 'd':
+ debugging++;
+ break;
+
+ case 'h':
+ host = argv[++i];
+ break;
+
+ case 'n':
+ user = argv[++i];
+ break;
+
+ case 'x':
+ case 'y':
+ break;
+
+ default:
+ croak("bad switch: %s",argv[i]);
+ break;
+ } else
+ acctfile = argv[i];
+
+ process_stdin();
+ account();
+ exit(0);
+}