summaryrefslogtreecommitdiff
path: root/dviware/beebe/src/dvieps.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/beebe/src/dvieps.c')
-rw-r--r--dviware/beebe/src/dvieps.c722
1 files changed, 722 insertions, 0 deletions
diff --git a/dviware/beebe/src/dvieps.c b/dviware/beebe/src/dvieps.c
new file mode 100644
index 0000000000..9eed0ca52e
--- /dev/null
+++ b/dviware/beebe/src/dvieps.c
@@ -0,0 +1,722 @@
+/* -*-C-*- dvieps.c */
+/*-->dvieps*/
+/**********************************************************************/
+/******************************* dvieps *******************************/
+/**********************************************************************/
+
+/***********************************************************************
+DVIEPS was developed from one of the dot-matrix printer drivers by
+Marcus Moehrmann (EMAIL: marcus%fkihh@unido.uucp). The following
+remarks are his.
+
+This is an implementation for Epson and compatible printers. Printers
+with 9 needles are supported; those with 24 are not. I hope that I have
+only used the ESC/P-Standard. The only documentation I have had was a
+description for the NEC Pinwriter P6/P7, but our printer is a Logitec,
+which I used for testing.
+
+There is a difference in paper feeding, because the P6/P7-handbook says
+that
+
+ <ESC> J (n)
+
+performs n/180 inch paper feeding, but our printer performs n/216 inch
+paper feeding, which I think is the standard, so I have used this in the
+driver.
+
+For horizontal resolution I have used the Esc-sequences
+
+ <ESC> * (m) (n1) (n2) [m = 0, 1, 2, 3]
+
+instead of
+
+ <ESC> (x) (n1) (n2) [x = 'K', 'L', 'Y', 'Z']
+
+If this will not work on your printer, change the definitions of
+'EPSON_BIT_IMAGE' and 'EPSON_MICRO_STEP' and the variable 'resolution'
+in procedure 'outline'.
+
+Be careful with the reset command
+
+ <ESC> @
+
+I have done this before any printing, and then after about 1.5 pages the
+printer stopped. The same works quite well on a second printer.
+
+Specialities: There is a switch '-t' for twice-a-line printing, that is,
+print one line in 1/120 inch horizontal spacing, return print head
+without paper feeding, perform a 1/240 inch step and then print the
+second line with 1/120 inch spacing.
+
+***********************************************************************/
+
+#include "dvihead.h"
+
+/**********************************************************************/
+/************************ Device Definitions ************************/
+/**********************************************************************/
+
+/* All output-device-specific definitions go here. This section must
+be changed when modifying a dvi driver for use on a new device */
+
+#undef EPSON
+#define EPSON 1 /* conditional compilation flag */
+
+#define VERSION_NO "2.10 [experimental]" /* DVI driver version number */
+
+#undef HIRES
+#define HIRES 1 /* 0 for 72-dpi version */
+
+#if HIRES
+#define DEVICE_ID "Epson 9-pin family 240/216-dpi matrix printer"
+ /* this string is printed at runtime */
+#define OUTFILE_EXT "eps"
+
+#define XDPI 240 /* horizontal dots/inch */
+#define YDPI 216 /* vertical dots/inch */
+
+#else /* NOT HIRES */
+#define DEVICE_ID "Epson 9-pin family 60/72-dpi matrix printer"
+ /* this string is printed at runtime */
+
+#define OUTFILE_EXT "e72"
+
+#define XDPI 60 /* horizontal dots/inch */
+#define YDPI 72 /* vertical dots/inch */
+#endif /* HIRES */
+
+#define BYTE_SIZE 8 /* output file byte size */
+
+#undef STDRES
+#if HIRES
+#define STDRES 1 /* 0 for low-resolution devices */
+#else /* NOT HIRES */
+#define STDRES 0 /* 0 for low-resolution devices */
+#endif /* HIRES */
+
+#if OS_PCDOS
+#define XPSIZE 6 /* horizontal paper size in inches */
+#else /* NOT OS_PCDOS */
+#define XPSIZE 8 /* horizontal paper size in inches */
+#endif /* OS_PCDOS */
+
+#define XSIZE (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\
+ (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE))
+ /* number of horizontal dots; */
+ /* MUST BE multiple of */
+ /* 2*HOST_WORD_SIZE */
+#define XWORDS ((XSIZE + HOST_WORD_SIZE - 1)/HOST_WORD_SIZE)
+ /* number of words in rows */
+ /* of bitmap array */
+
+#if OS_PCDOS
+#define YPSIZE 8 /* vertical paper size in inches */
+#else /* NOT OS_PCDOS */
+#define YPSIZE 11 /* vertical paper size in inches */
+#endif /* OS_PCDOS */
+
+#define YSIZE (YDPI*YPSIZE) /* number of vertical dots */
+
+#if HIRES
+INT16 paperfeeding; /* outstanding 1/216 inch */
+ /* form-feedings */
+
+BOOLEAN twice_a_line = FALSE; /* this is runtime option '-t' */
+ /* print in 1/120-inch-mode, */
+ /* 2nd line shifted 1/240 inch */
+
+ /* need single-arg outline() */
+BOOLEAN micro_step; /* used in outline() */
+#define OUTLINE(v,flag) {micro_step = flag; outline(v);}
+#endif /* HIRES */
+
+/* The printer bit map. */
+
+#define XBIT XWORDS
+#define YBIT YSIZE
+
+#if (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
+#undef SEGMEM
+#define SEGMEM 1 /* ( ((long)XBIT * (long)YBIT) > 65536L ) */
+#endif /* (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD) */
+
+#define EPSON_ADV_PAPER "\033J%c" /* advance paper n/216 inch */
+#define EPSON_BIT_IMAGE "\033*%c%c%c"
+#define EPSON_MICRO_STEP OUTF2("\033*\003\001%c%c",'\000','\000')
+
+#include "bitmap.h"
+
+#include "main.h"
+#include "abortrun.h"
+#include "actfact.h"
+#include "alldone.h"
+#include "chargf.h"
+#include "charpk.h"
+#include "charpxl.h"
+#include "clrbmap.h"
+#include "clrrow.h"
+#include "dbgopen.h"
+
+/*-->devinit*/
+/**********************************************************************/
+/****************************** devinit *******************************/
+/**********************************************************************/
+
+void
+devinit(argc, argv) /* initialize device */
+int argc;
+char *argv[];
+{
+ (void)getbmap();
+ if (runlengthcode && !quiet)
+ {
+ (void)fprintf(stderr, "[Run-length encoding of output file]");
+ NEWLINE(stderr);
+ }
+
+#if HIRES
+ if (twice_a_line && !quiet)
+ {
+ (void)fprintf(stderr, "[Twice-a-line-printing for high resolution]");
+ NEWLINE(stderr);
+ }
+#endif /* HIRES */
+
+}
+
+/*-->devterm*/
+/**********************************************************************/
+/****************************** devterm *******************************/
+/**********************************************************************/
+
+void
+devterm() /* terminate device */
+{
+}
+
+#include "dispchar.h"
+#include "dvifile.h"
+#include "dviinit.h"
+#include "dviterm.h"
+#include "f20open.h"
+#include "fatal.h"
+#include "fillrect.h"
+#include "findpost.h"
+#include "fixpos.h"
+#include "fontfile.h"
+#include "fontsub.h"
+#include "getbmap.h"
+#include "getbytes.h"
+#include "getfntdf.h"
+#include "getpgtab.h"
+#include "inch.h"
+#include "initglob.h"
+#include "loadchar.h"
+
+/*-->makechar*/
+/**********************************************************************/
+/****************************** makechar ******************************/
+/**********************************************************************/
+
+char
+makechar(p, mask)
+register UNSIGN32 *p[];
+register UNSIGN32 mask;
+{
+ register char c;
+
+#if SEGMEM
+#define Q(n) p[n] /* use precomputed pointers */
+#else /* NOT SEGMEM */
+#define Q(n) (p[0] - (n)*XBIT) /* compute pointers on the fly */
+#endif /* SEGMEM */
+
+ c = '\000'; /* MSB controls top needle */
+
+#if HIRES
+ if (*Q(0) & mask)
+ c |= '\200';
+ if (*Q(3) & mask)
+ c |= '\100';
+ if (*Q(6) & mask)
+ c |= '\040';
+ if (*Q(9) & mask)
+ c |= '\020';
+ if (*Q(12) & mask)
+ c |= '\010';
+ if (*Q(15) & mask)
+ c |= '\004';
+ if (*Q(18) & mask)
+ c |= '\002';
+ if (*Q(21) & mask)
+ c |= '\001';
+#else /* NOT HIRES */
+ if (*Q(0) & mask)
+ c |= '\200';
+ if (*Q(1) & mask)
+ c |= '\100';
+ if (*Q(2) & mask)
+ c |= '\040';
+ if (*Q(3) & mask)
+ c |= '\020';
+ if (*Q(4) & mask)
+ c |= '\010';
+ if (*Q(5) & mask)
+ c |= '\004';
+ if (*Q(6) & mask)
+ c |= '\002';
+ if (*Q(7) & mask)
+ c |= '\001';
+#endif /* HIRES */
+
+ return (c);
+}
+
+#include "movedown.h"
+#include "moveover.h"
+#include "moveto.h"
+#include "nosignex.h"
+#include "openfont.h"
+#include "option.h"
+
+#if HIRES
+/*-->outpaperfeed*/
+/**********************************************************************/
+/*************************** outpaperfeed *****************************/
+/**********************************************************************/
+
+void
+outpaperfeed(count) /* accumulate 1/216 inch paperfeedings */
+INT16 count; /* and write them out if count == 0 */
+{
+
+ register INT16 k;
+
+ if (count)
+ paperfeeding += count;
+ else
+ {
+ for (k = paperfeeding / 255; k; --k)
+ OUTF(EPSON_ADV_PAPER, 255);
+ if ((k = paperfeeding % 255) > 0)
+ OUTF(EPSON_ADV_PAPER, k);
+ paperfeeding = 0;
+ }
+}
+#endif /* HIRES */
+
+/*-->outline*/
+/**********************************************************************/
+/****************************** outline *******************************/
+/**********************************************************************/
+
+void
+outline(pline)
+char *pline;
+{
+ register char* a;
+ register char* b;
+ register char* c;
+ register INT16 left;
+ INT16 len;
+ INT16 linelength;
+ char resolution;
+ BYTE spacing;
+ BYTE space_width;
+
+#if HIRES
+ if (twice_a_line) /* step 1/240 inch forward */
+ {
+ resolution = '\001'; /* 1/120 */
+ space_width = 12; /* 12/120 */
+ linelength = XSIZE / 2;
+ }
+ else
+ {
+ resolution = '\003'; /* 1/240 */
+ space_width = 24; /* 24/240 */
+ linelength = XSIZE;
+ }
+#else /* NOT HIRES */
+ resolution = '\000'; /* 1/60 */
+ space_width = 6; /* 6/60 */
+ linelength = XSIZE;
+#endif /* HIRES */
+
+ for ((left = linelength, c = pline + linelength - 1);
+ (*c == '\000') && (left > 0);
+ (--left, --c)) /* trim white space */
+ ;
+
+ if (left == 0)
+ return; /* NEWLINE() is not needed for any paperfeeding */
+
+#if HIRES
+ (void)outpaperfeed(0); /* print accumulated paperfeedings */
+#endif /* HIRES */
+
+ /*******************************************************************
+ We search for runs as follows. "b" marks the beginning of unwritten
+ data, and "a" anchors the beginning of a run which continues to just
+ before "c". The run length is "c"-"a". Only runs longer than
+ "space_width" are taken, because we print spaces in text mode. This
+ implies that the run only consists of '\000' characters.
+
+ If a long enough run is found, then the string "b" .. "a"-1 is
+ output since its length is now known, followed by the run encoding
+ for the character at "a". Then "a" and "b" are advanced to "c", and
+ the scan continues.
+
+ If the run beginning at "a" is too short, then "a" is simply
+ advanced.
+
+ Since the character strings take on all values on 0 .. 255, we
+ cannot store a termination marker, but must instead keep a counter,
+ "left", which is decremented to 0 when the end of the string is
+ reached.
+
+ ?????????????0000000000000000????????????????????
+ ^ ^ ^
+ | | |
+ b a c
+
+ <-----run------>
+
+
+ We cannot use fprintf %s because 0 bytes terminate string, so we are
+ using putc for writing the line.
+ *******************************************************************/
+
+ if (runlengthcode && (left >= space_width))
+ {
+ for (a = b = pline; (left > 0); --left)
+ {
+ for (c = a; (*a == *++c) && (*a == '\000') && left; --left)
+ ; /* advance over run */
+ len = (INT16) (c - a); /* "c" points past run */
+
+ if (len >= space_width) /* output long run */
+ {
+ if (a > b) /* output previous string */
+ {
+#if HIRES
+ if (micro_step)
+ {
+ EPSON_MICRO_STEP;
+ micro_step = FALSE;
+ }
+#endif /* HIRES */
+ OUTF3(EPSON_BIT_IMAGE, resolution, ((int) (a - b)) % 256,
+ ((int) (a - b)) / 256);
+ for (; b < a; b++)
+ OUTC(*b);
+ }
+
+ c -= len % space_width; /* shorten run */
+ left += len % space_width;
+
+ for (spacing = (BYTE)(len / space_width); spacing; --spacing)
+ OUTC(' '); /* output run */
+
+ a = b = c;
+ }
+ else /* ignore short run */
+ {
+ ++a;
+ left += len - 1;
+ }
+ } /* end for() loop */
+
+ if (a > b) /* output remaining string */
+ {
+#if HIRES
+ if (micro_step)
+ {
+ EPSON_MICRO_STEP;
+ micro_step = FALSE;
+ }
+#endif /* HIRES */
+ OUTF3(EPSON_BIT_IMAGE,resolution,((int) (a - b)) % 256,
+ ((int) (a - b)) / 256);
+ for (; b < a; b++)
+ OUTC(*b);
+ }
+ }
+ else /* no runlength coding */
+ if (left > 0)
+ {
+#if HIRES
+ if (micro_step)
+ {
+ EPSON_MICRO_STEP;
+ micro_step = FALSE;
+ }
+#endif /* HIRES */
+ OUTF3(EPSON_BIT_IMAGE,resolution,left % 256,left / 256);
+ for (c = pline; left; --left, c++)
+ OUTC(*c);
+ }
+ NEWLINE(plotfp);
+}
+
+#include "outrow.h"
+
+/*-->prtbmap*/
+/**********************************************************************/
+/****************************** prtbmap *******************************/
+/**********************************************************************/
+
+void
+prtbmap()
+{
+ register BYTE *c; /* pointer into v8[][] and v8t[][][] */
+ UNSIGN32 *p; /* pointer into bitmap[][] */
+
+#if SEGMEM
+#else /* NOT SEGMEM */
+ UNSIGN32 *ptmp; /* pointer into bitmap[][] */
+#endif /* SEGMEM */
+
+ register UNSIGN32 mask; /* mask for single bit selection */
+ register INT16 k;
+ INT16 i;
+ INT16 j;
+ INT16 ybottom;
+ INT16 ytop;
+
+#if HIRES
+ BYTE v8[3][XSIZE]; /* vertical 8-bit raster encodings */
+ BYTE v8t[3][2][XSIZE / 2]; /* vertical 8-bit raster encodings */
+ /* (twice-a-line) */
+ INT16 second = 0; /* address second byte if not zero */
+
+#undef Q
+#if SEGMEM
+ UNSIGN32 *q[24]; /* pointers to 24 raster lines */
+#define Q(n) q[n] /* use precomputed pointers */
+#else /* NOT SEGMEM */
+#define Q(n) (p - (n)*XBIT) /* compute pointers on the fly */
+#endif /* SEGMEM */
+
+ (void)clearerr(plotfp);
+
+ ytop = YBIT - 1;
+
+ k = -1; /* find bottom non-zero raster */
+ for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
+ {
+
+#if IBM_PC_MICROSOFT
+ for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j, k) == 0)); --k)
+ ; /* trim white space */
+
+#else /* NOT IBM_PC_MICROSOFT */
+ p = BITMAP(j, XBIT - 1);
+ for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
+ --p; /* trim white space */
+#endif /* IBM_PC_MICROSOFT */
+
+ }
+ ybottom = (j / 24) * 24 + 23;
+
+ paperfeeding = 0; /* for outpaperfeed() */
+ OUTF("\0333%c", 0); /* no paperfeeding */
+
+ for (j = ytop; (j >= ybottom); j -= 24) /* loop over raster lines */
+ { /* in groups of 24 */
+
+#if SEGMEM
+#else /* NOT SEGMEM */
+ p = BITMAP(j, 0); /* the j-th raster line */
+#endif /* SEGMEM */
+
+ if (twice_a_line)
+ c = &v8t[0][0][0]; /* vertical 8-bit encodings */
+ else
+ c = &v8[0][0]; /* vertical 8-bit encodings */
+
+ for (i = 0; i < XBIT; (++p, ++i)) /* loop over raster words */
+ {
+ /* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
+ hard way, arghh... */
+ mask = 1;
+ mask <<= (HOST_WORD_SIZE - 1); /* to select leftmost bit */
+
+#if SEGMEM
+ for (k = 0; k < 24; ++k) /* compute pointers to 24 rasters */
+ q[k] = BITMAP(j - k, i);
+#endif /* SEGMEM */
+
+ for (k = 0; k < HOST_WORD_SIZE; (++k)) /* loop over word bits */
+ {
+ /* examine bits in 24 adjacent rows and build two 8-bit */
+ /* character values, the first with rows n,n+3,...,n+21, */
+ /* the second with rows n+1,n+4,...,n+22, the third with */
+ /* rows n+2,n+5,...,n+23. The 2nd and 3rd characters are */
+ /* then printed with 1 dot vertical spacing. */
+
+ /* if twice_a_line is TRUE, the bytes will be written */
+ /* alternating in v8t[x][0][y] and v8t[x][1][y] */
+
+ if (twice_a_line)
+ second = (k % 2) * XSIZE / 2;
+
+#if SEGMEM
+ *(c + second) = (BYTE) makechar(&q[0], mask);
+ *(c + XSIZE + second) = (BYTE) makechar(&q[1], mask);
+ *(c + 2 * XSIZE + second) = (BYTE) makechar(&q[2], mask);
+#else /* NOT SEGMEM */
+ *(c + second) = (BYTE) makechar(&p, mask);
+ ptmp = p - XBIT;
+ *(c + XSIZE + second) = (BYTE) makechar(&ptmp, mask);
+ ptmp = p - 2 * XBIT;
+ *(c + 2 * XSIZE + second) = (BYTE) makechar(&ptmp, mask);
+#endif /* SEGMEM */
+
+ if (twice_a_line)
+ {
+ if (second)
+ c++; /* increment after second byte */
+ }
+ else
+ c++;
+
+ mask >>= 1; /* move masking bit right 1 position */
+ } /* end loop over k */
+ } /* end loop over i */
+
+ if (twice_a_line)
+ {
+ OUTLINE((char *) &v8t[0][0][0], FALSE);
+ OUTLINE((char *) &v8t[0][1][0], TRUE);
+ (void)outpaperfeed(1);
+ OUTLINE((char *) &v8t[1][0][0], FALSE);
+ OUTLINE((char *) &v8t[1][1][0], TRUE);
+ (void)outpaperfeed(1);
+ OUTLINE((char *) &v8t[2][0][0], FALSE);
+ OUTLINE((char *) &v8t[2][1][0], TRUE);
+ (void)outpaperfeed(22);
+ }
+ else
+ {
+ OUTLINE((char *) &v8[0][0], FALSE);
+ (void)outpaperfeed(1);
+ OUTLINE((char *) &v8[1][0], FALSE);
+ (void)outpaperfeed(1);
+ OUTLINE((char *) &v8[2][0], FALSE);
+ (void)outpaperfeed(22);
+ }
+
+ } /* end loop over j */
+
+ OUTS("\0332"); /* ESC 2 = normal paperfeeding */
+ OUTC('\f'); /* eject page with FF */
+
+ (void)fflush(plotfp);
+ if (DISKFULL(plotfp))
+ (void)fatal("prtbmap(): Output error -- disk storage probably full");
+}
+
+#else /* NOT HIRES */
+ BYTE v8[XSIZE + 2]; /* vertical 8-bit raster encodings */
+
+#undef Q
+#if SEGMEM
+ UNSIGN32 *q[8]; /* pointers to 8 raster lines */
+#define Q(n) q[n] /* use precomputed pointers */
+#else /* NOT SEGMEM */
+#define Q(n) (p - (n)*XBIT) /* compute pointers on the fly */
+#endif /* SEGMEM */
+
+ ytop = YBIT - 1;
+
+ k = -1; /* find bottom non-zero raster */
+ for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
+ {
+
+#if IBM_PC_MICROSOFT
+ for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j, k) == 0)); --k)
+ ; /* trim white space */
+#else /* NOT IBM_PC_MICROSOFT */
+ p = BITMAP(j, XBIT - 1);
+ for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
+ --p; /* trim white space */
+#endif /* IBM_PC_MICROSOFT */
+
+ } /* end loop over j */
+ ybottom = (j / 8) * 8 + 7;
+
+ OUTF("\0333%c", 24); /* 24/216 inch paperfeeding */
+
+ for (j = ytop; (j >= ybottom); j -= 8) /* loop over raster lines */
+ { /* in groups of 8 */
+
+#if SEGMEM
+#else /* NOT SEGMEM */
+ p = BITMAP(j, 0); /* the j-th raster line */
+#endif /* SEGMEM */
+
+ c = &v8[0]; /* vertical 8-bit encodings */
+ for (i = 0; i < XBIT; (++p, ++i)) /* loop over raster words */
+ {
+ /* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
+ hard way, arghh... */
+ mask = 1;
+ mask <<= (HOST_WORD_SIZE - 1); /* to select leftmost bit */
+
+#if SEGMEM
+ for (k = 0; k < 8; ++k) /* compute pointers to 8 rasters */
+ q[k] = BITMAP(j - k, i);
+#endif /* SEGMEM */
+
+ for (k = 0; k < HOST_WORD_SIZE; (++c, ++k))/* loop over word bits */
+ {
+ /* examine bits in 8 adjacent rows and build 8-bit */
+ /* character value */
+
+#if SEGMEM
+ *c = (BYTE) makechar(q, mask);
+#else /* NOT SEGMEM */
+ *c = (BYTE) makechar(&p, mask);
+#endif /* SEGMEM */
+
+ mask >>= 1; /* move masking bit right 1 position */
+ } /* end loop over k */
+ } /* end loop over i */
+ --c; /* last character encoded */
+
+ (void)outline((char *) &v8[0]);
+ } /* end loop over j */
+
+ OUTS("\0332"); /* ESC 2 = normal paperfeeding */
+ OUTC('\f'); /* eject page with FF */
+
+ (void)fflush(plotfp);
+ if (DISKFULL(plotfp))
+ (void)fatal("prtbmap(): Output error -- disk storage probably full");
+}
+#endif /* HIRES */
+
+#include "prtpage.h"
+#include "readfont.h"
+#include "readgf.h"
+#include "readpk.h"
+#include "readpost.h"
+#include "readpxl.h"
+#include "reldfont.h"
+#include "rulepxl.h"
+#include "setchar.h"
+#include "setfntnm.h"
+#include "setrule.h"
+#include "signex.h"
+#include "skgfspec.h"
+#include "skipfont.h"
+#include "skpkspec.h"
+#include "special.h"
+#include "strchr.h"
+#include "strcm2.h"
+#include "strid2.h"
+#include "strrchr.h"
+#include "tctos.h"
+#include "usage.h"
+#include "warning.h"