/* $Log: dopage.c,v $ * Revision 0.8 92/11/23 19:46:41 19:46:41 bt (Bo Thide') * Fixed resolution bug. Portable downloading. Added/changed options. PJXL color support * * Revision 0.7 92/11/13 02:41:25 02:41:25 bt (Bo Thide') * More bug fixes and improvements. Support for PaintJet XL * * Revision 0.6 92/11/10 21:47:41 21:47:41 bt (Bo Thide') * Bug fixes. Added -R option. Better font handling. * * Revision 0.5 92/11/09 16:25:28 16:25:28 bt (Bo Thide') * Rewrite of dospecial.c. Extended \special support * * Revision 0.4 92/11/08 02:45:44 02:45:44 bt (Bo Thide') * Changed to portable bit manipulations. Replaced strrstr for non-POSIX compliant C. Fixed numerous bugs. Added support for more \special's. * * Revision 0.3 92/08/24 12:45:36 12:45:36 bt (Bo Thide') * Fixed 8 bit (dc font) support. * * Revision 0.2 92/08/23 17:28:55 17:28:55 bt (Bo Thide') * Source cleaned up. Changed certain function calls. Removed globals. * * Revision 0.1 92/08/22 23:58:47 23:58:47 bt (Bo Thide') * First Release. * */ /* * This is the main printer dependent output routine, which is organized as * a function with side effects. The subroutine is organized as a typical * interpreter, with a multiway branch of the command code followed by 'goto' * statements leading to branches that finish up the activities common to * different commands. dopage() aborts `dvi2pcl' if something unusual happens. * * The definition of dvi files refer to six registers, (h,v,w,x,y,z), which * hold integer values in dvi units. In practice, we also need registers hh * and vv, the pixel analogs of h and v, since it is not always true that * hh = pixel_round(h) or vv = pixel_round(v). * The stack of (h,w,w,x,y,z) values is represented by eight arrays called * hstack,...,zstack, hhstack and vvstack. */ #include #include "dvi.h" #include "globals.h" #include "macros.h" #include "pcl.h" static char rcsid[] = "$Header: dopage.c,v 0.8 92/11/23 19:46:41 bt Exp $"; dopage(bitfile, dvifile, pcllevel, resolution, device) FILE *bitfile; FILE *dvifile; short pcllevel; short resolution; short device; { unsigned char o; int k; int hhh, vvv; bool badchar; long hh, vv; long p, q; long hstack[STACKSIZE], vstack[STACKSIZE], wstack[STACKSIZE]; long xstack[STACKSIZE], ystack[STACKSIZE], zstack[STACKSIZE]; int hhstack[STACKSIZE], vvstack[STACKSIZE]; charfmt *c; h_posed = v_posed = FALSE; s = hh = vv = h = v = w = x = y = z = 0; font = NULL; while (TRUE) { o = getubyte(dvifile); if(o >= DVI_SET1) p = firstpar(dvifile, o); #ifdef DEBUG fprintf(stderr,"\ndopage: o = %d, p = %ld, hh = %ld", o, p, hh); #endif if(o < DVI_SET1) { c = drawchar(bitfile, o, hh, vv, resolution, device); q = c->tfm_width; hh += c->pxl_width; goto move_right; } else switch(o) { case DVI_SET1: case DVI_SET2: case DVI_SET3: case DVI_SET4: c = drawchar(bitfile, p, hh, vv, resolution, device); q = c->tfm_width; hh += c->pxl_width; goto move_right; break; case DVI_PUT1: case DVI_PUT2: case DVI_PUT3: case DVI_PUT4: drawchar(bitfile, p, hh, vv, resolution, device); goto done; break; case DVI_SET_RULE: q = (long)getsquad(dvifile); drawrule(bitfile, rulepixels(p, conv), rulepixels(q, conv), hh, vv); hh += rulepixels(q, conv); goto move_right; break; case DVI_PUT_RULE: q = (long)getsquad(dvifile); drawrule(bitfile, rulepixels(p, conv), rulepixels(q, conv), hh, vv); goto done; break; case DVI_NOP: goto done; break; case DVI_BOP: fprintf(stderr,"\n'DVI_BOP' occurred before 'DVI_EOP'"); goto endfalse; break; case DVI_EOP: if(maxpages) putc('\014',bitfile); /* Formfeed */ if(s) fprintf(stderr,"\nStack not empty at end of page"); return (TRUE); break; case DVI_PUSH: if(s == maxssofar) { maxssofar++; if(s == maxs) fprintf(stderr,"\nDeeper than claimed in postamble"); if(s == STACKSIZE) { fprintf(stderr,"\nStack capacity exceeded"); goto endfalse; } } hstack[s] = h; vstack[s] = v; wstack[s] = w; xstack[s] = x; ystack[s] = y; zstack[s] = z; hhstack[s] = hh; vvstack[s] = vv; s++; goto done; break; case DVI_POP: if(s) { s--; if(hh != hhstack[s]) h_posed = FALSE; if(vv != vvstack[s]) v_posed = FALSE; h = hstack[s]; v = vstack[s]; w = wstack[s]; x = xstack[s]; y = ystack[s]; z = zstack[s]; hh = hhstack[s]; vv = vvstack[s]; } else fprintf(stderr,"\nIllegal at level zero"); goto done; break; case DVI_RIGHT1: case DVI_RIGHT2: case DVI_RIGHT3: case DVI_RIGHT4: goto out_space; break; case DVI_W0: case DVI_W1: case DVI_W2: case DVI_W3: case DVI_W4: w = p; goto out_space; break; case DVI_X0: case DVI_X1: case DVI_X2: case DVI_X3: case DVI_X4: x = p; goto out_space; break; case DVI_DOWN1: case DVI_DOWN2: case DVI_DOWN3: case DVI_DOWN4: goto move_down; break; case DVI_Y0: case DVI_Y1: case DVI_Y2: case DVI_Y3: case DVI_Y4: y = p; goto move_down; break; case DVI_Z0: case DVI_Z1: case DVI_Z2: case DVI_Z3: case DVI_Z4: z = p; goto move_down; break; case DVI_FNT_DEF1: case DVI_FNT_DEF2: case DVI_FNT_DEF3: case DVI_FNT_DEF4: skipfontdef(dvifile); goto done; break; case DVI_XXX1: case DVI_XXX2: case DVI_XXX3: case DVI_XXX4: badchar = FALSE; if((long)nextnamesfree - (long)names + p > NAMESIZE ) prerror("Out of string space during special\n"); for(k = 0 ; k < (int)p ; k++) { q = (long)getubyte(dvifile); if((q < ' ') || (q > '~')) badchar = TRUE; *(nextnamesfree + k) = (char)q; } *(nextnamesfree + p) = 0; if(badchar) fprintf(stderr,"\nNon-ASCII character in xxx command"); dospecial(bitfile, PRESCAN_OFF, pcllevel, hh, vv, resolution); goto done; break; case DVI_PRE: fprintf(stderr,"\nPreamble command within a page"); goto endfalse; break; case DVI_POST: case DVI_POSTPOST: fprintf(stderr,"\nPostamble command within a page"); goto endfalse; break; case DVI_UNDEF0: case DVI_UNDEF1: case DVI_UNDEF2: case DVI_UNDEF3: case DVI_UNDEF4: case DVI_UNDEF5: fprintf(stderr,"\nUndefined DVI command %d.",o); goto done; break; default: font = fontptr[p]; gfont = gfontptr[p]; if(font->down > 0) fprintf(bitfile, PCL4_SELECT_FONT, font->down); goto done; break; } out_space: if((font == NULL) || (p >= font->space) || (p <= -4*font->space)) hh = round(conv*(h+p)); else hh += round(conv*p); q = p; h_posed = FALSE; move_right: hhh = round(conv*(h+q)); if(abs(hhh - hh) > MAXDRIFT) { h_posed = FALSE; hh = hhh > hh ? hhh - MAXDRIFT : hhh + MAXDRIFT; } h += q; if((long)abs(h) > maxhsofar) { if(((long)abs(h) > maxh + 99) && verbose) { fprintf(stderr,"\n|h| > %d\n", maxh); maxh = (long)abs(h); } maxhsofar = (long)abs(h); } goto done; move_down: if((font == NULL) || ((long)abs(p) >= 5*font->space)) vv = round(conv*(v+p)); else vv += round(conv*p); v_posed = FALSE; if((v > 0) && (p > 0) && (v > INFINITY-p)) fprintf(stderr,"Arithmetic overflow. Parameter changed from %d to %d.", p, p=INFINITY-v); if((v < 0) && (p < 0) && (-v > INFINITY+p)) fprintf(stderr,"\ndopage: Arithmetic overflow. Parameter changed from %d to %d.", p, p = -(INFINITY+v)); vvv = round(conv*(v+p)); if(abs(vvv - vv) > MAXDRIFT) vv = vvv > vv ? vvv - MAXDRIFT : vvv + MAXDRIFT; v += p; if((long)abs(v) > maxvsofar) { if(((long)abs(v) > maxv + 99) && verbose) { fprintf(stderr,"\n|v| > %d.",maxv); maxv = (long)abs(v); } maxvsofar = (long)abs(v); } goto done; done: ; } endfalse: prerror("\n! Bad .pcl file: page ended unexpectedly !\n"); }