home *** CD-ROM | disk | FTP | other *** search
- /*
- * These routines do most of the communicating with the printer.
- *
- * LINELENGTH tells the maximum line length to send out. It's been
- * reduced to 72 because sometimes PostScript files are included in
- * mail messages and many mailers mutilate longer lines.
- */
- #define LINELENGTH (72)
- #include "dvips.h" /* The copyright notice in that file is included too! */
- #include "paths.h"
- #include <ctype.h>
-
- #ifdef OS2
- #include <stdlib.h>
- #ifdef _MSC_VER
- #define popen(pcmd, pmode) _popen(pcmd, pmode)
- #define pclose(pstream) _pclose(pstream)
- #endif
- #endif
- /*
- * The external routines called here:
- */
- extern void error() ;
- extern void send_headers() ;
- extern int add_header() ;
- extern FILE *search() ;
- extern char *getenv() ;
- extern void makepsname() ;
- extern void handlepapersize() ;
- extern void findbb() ;
- /*
- * These are the external variables used by these routines.
- */
- extern integer hh, vv ;
- extern fontdesctype *curfnt ;
- extern FILE *bitfile ;
- extern char *oname ;
- extern Boolean secure ;
- extern Boolean reverse ;
- extern Boolean removecomments ;
- extern Boolean sendcontrolD, disablecomments, multiplesects ;
- extern Boolean usesPSfonts, headers_off ;
- extern Boolean safetyenclose ;
- extern Boolean cropmarks ;
- extern Boolean tryepsf ;
- extern Boolean compressed ;
- extern int numcopies ;
- extern int collatedcopies ;
- extern integer pagecopies ;
- extern int totalpages ;
- extern integer pagenum ;
- extern Boolean manualfeed ;
- extern int landscape ;
- extern int quiet ;
- extern int prettycolumn ;
- extern int actualdpi, vactualdpi ;
- extern char *iname, *nextstring ;
- extern char *paperfmt ;
- extern char errbuf[] ;
- extern shalfword linepos ;
- extern struct header_list *ps_fonts_used ;
- extern char banner[] ;
- extern int gargc ;
- extern char **gargv ;
- extern struct papsiz *papsizes ;
- extern integer hpapersize, vpapersize ;
- char preamblecomment[256] ; /* usually "TeX output ..." */
- /*
- * We need a few statics to take care of things.
- */
- static integer rhh, rvv ;
- static int instring ;
- static Boolean lastspecial = 1 ;
- static shalfword d ;
- static Boolean popened = 0 ;
- int lastfont ; /* exported to dospecial to fix rotate.tex problem */
- static void chrcmd(); /* just a forward declaration */
- static char strbuffer[LINELENGTH + 20], *strbp = strbuffer ;
- static struct papsiz *finpapsiz ;
- static struct papsiz defpapsiz = {
- 0, 40258437L, 52099154L, "letter", ""
- } ;
- #ifdef CREATIONDATE
- #if !defined(VMS) && !defined(MSDOS) && !(defined(OS2) && defined(_MSC_VER)) && !defined(ATARIST)
- /* VAXC/MSDOS don't like/need this !! */
- #include <sys/types.h>
- #include <sys/time.h> /* time(), at least on BSD Unix */
- #endif
- #include <time.h> /* asctime() and localtime(), at least on BSD Unix */
- static time_t jobtime;
- #endif
- /*
- * This routine copies a file down the pipe. Search path uses the
- * header path.
- *
- * We add code to handle the case of MS-DOS font files.
- *
- * Format: 80 {01,02} four byte length in littleendian order data
- * repeated possibly multiple times.
- */
- static char *hxdata = "0123456789ABCDEF" ;
- static int infigure ;
- extern char *infont ;
- static char *begbinary = "\n%%BeginBinary:" ;
- void
- copyfile(s)
- char *s ;
- {
- FILE *f = NULL ;
- int c, prevc = '\n' ;
- long len ;
- char *bbmatch = begbinary ;
- /* begin DOS EPS code */
- int doseps = 0;
- unsigned long dosepsbegin, dosepsend = 0;
- /* end DOS EPS code */
- #ifdef VMCMS
- register char *lastdirsep ;
- register char *trunc_s ;
- trunc_s = s ;
- #endif
- #ifdef MVSXA
- register char *lastdirsep ;
- register char *trunc_s ;
- trunc_s = s ;
- #endif
-
- switch (infigure) {
- case 1:
- /*
- * Look in headerpath too, just in case. This allows common header
- * or figure files to be installed in the .../ps directory.
- */
- f = search(figpath, s, READ) ;
- if (f == 0)
- f = search(headerpath, s, READ) ;
- #ifdef VMCMS
- lastdirsep = strrchr(s, '/') ;
- if ( NULL != lastdirsep ) trunc_s = lastdirsep + 1 ;
- (void)sprintf(errbuf,
- "Couldn't find figure file %s with CMS name %s; continuing", s, trunc_s) ;
- #else
- #ifdef MVSXA
- lastdirsep = strrchr(s, '/') ;
- if ( NULL != lastdirsep ) trunc_s = lastdirsep + 1 ;
- (void)sprintf(errbuf,
- "Couldn't find figure file %s with MVS name %s; continuing", s, trunc_s) ;
- #else
- (void)sprintf(errbuf, "Couldn't find figure file %s; continuing", s) ;
- #endif
- #endif
- break ;
- default:
- f = search(headerpath, s, READ) ;
- (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
- break ;
- #ifndef VMCMS
- #ifndef MVSXA
- #ifndef VMS
- #ifndef MSDOS
- #ifndef ATARIST
- #ifndef __THINK__
- case 2:
- #ifdef SECURE
- (void)sprintf(errbuf, "<%s>: Tick filename execution disabled", s) ;
- #else
- #ifdef OS2
- if (_osmode == OS2_MODE) {
- #endif
- if (secure == 0)
- f = popen(s, "r") ;
- #ifdef OS2
- }
- #endif
- (void)sprintf(errbuf, "Failure to execute %s; continuing", s) ;
- #endif
- break;
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- }
- if (f==NULL)
- error(errbuf) ;
- else {
- if (! quiet) {
- if (strlen(s) + prettycolumn > STDOUTSIZE) {
- fprintf(stderr, "\n") ;
- prettycolumn = 0 ;
- }
- #ifdef VMCMS
- (void)fprintf(stderr, "<%s>", trunc_s) ;
- #else
- #ifdef MVSXA
- (void)fprintf(stderr, "<%s>", trunc_s) ;
- #else
- (void)fprintf(stderr, "<%s>", s) ;
- #endif
- #endif
- (void)fflush(stderr) ;
- prettycolumn += 2 + strlen(s) ;
- }
- if (linepos != 0)
- (void)putc('\n', bitfile) ;
- if (! disablecomments)
- if (infigure)
- (void)fprintf(bitfile, "%%%%BeginDocument: %s\n", s) ;
- else if (infont)
- (void)fprintf(bitfile, "%%%%BeginFont: %s\n", infont) ;
- else
- (void)fprintf(bitfile, "%%%%BeginProcSet: %s\n", s) ;
- c = getc(f) ;
- if (c == 0x80) {
- #if defined MSDOS || defined OS2 || defined(ATARIST)
- (void)fclose(f) ; /* close MSDOS font file */
- f = search(headerpath, s, READBIN) ; /* reopen in BINARY mode */
- (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
- if (f==NULL)
- error(errbuf) ;
- c = getc(f);
- #endif
- while (1) {
- c = getc(f) ;
- switch(c) {
- case 1:
- case 2:
- len = getc(f) ;
- len += getc(f) * 256L ;
- len += getc(f) * 65536L ;
- len += getc(f) * 256L * 65536 ;
- if (c == 1) {
- while (len > 0) {
- c = getc(f) ;
- if (c == EOF) {
- error("premature EOF in MS-DOS font file") ;
- len = 0 ;
- } else {
- if (c == 13)
- (void)putc('\n', bitfile) ;
- else
- (void)putc(c, bitfile) ;
- len-- ;
- }
- }
- } else {
- putc('\n', bitfile) ;
- prevc = 0 ;
- while (len > 0) {
- c = getc(f) ;
- if (c == EOF) {
- error("premature EOF in MS-DOS font file") ;
- len = 0 ;
- } else {
- (void)putc(hxdata[c >> 4], bitfile) ;
- (void)putc(hxdata[c & 15], bitfile) ;
- len-- ;
- prevc += 2 ;
- if (prevc >= 76) {
- putc('\n', bitfile) ;
- prevc = 0 ;
- }
- }
- }
- }
- break ;
- case 3:
- goto msdosdone ;
- default:
- error("saw type other than 1, 2, or 3 in MS-DOS font file") ;
- break ;
- }
- c = getc(f) ;
- if (c == EOF)
- break ;
- if (c != 0x80) {
- error("saw non-MSDOS header in MSDOS font file") ;
- break ;
- }
- }
- msdosdone:
- prevc = 0 ;
- } else {
- /* begin DOS EPS code */
- if (c == 'E'+0x80) {
- if ((getc(f)=='P'+0x80) && (getc(f)=='S'+0x80)
- && (getc(f)=='F'+0x80)) {
- #if defined MSDOS || defined OS2
- (void)fclose(f) ; /* close DOS EPS file */
- f = search(headerpath, s, READBIN) ;
- /* reopen in BINARY mode */
- (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
- if (f==NULL)
- error(errbuf) ;
- fseek(f, 4L, 0);
- #endif
- doseps = 1;
- dosepsbegin = getc(f) ;
- dosepsbegin += getc(f) * 256L ;
- dosepsbegin += getc(f) * 65536L ;
- dosepsbegin += getc(f) * 256L * 65536 ;
- dosepsend = getc(f) ;
- dosepsend += getc(f) * 256L ;
- dosepsend += getc(f) * 65536L ;
- dosepsend += getc(f) * 256L * 65536 ;
- dosepsend += dosepsbegin;
- #if defined MSDOS || defined OS2
- (void)fclose(f) ; /* close DOS EPS file */
- f = search(headerpath, s, READ) ; /* reopen in TEXT mode */
- (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
- if (f==NULL)
- error(errbuf) ;
- #endif
- fseek(f, dosepsbegin, 0);
- c = getc(f);
- }
- else {
- rewind(f);
- c = getc(f);
- }
- }
- /* end DOS EPS code */
- if (c != EOF) {
- while (1) {
- if (c == *bbmatch) {
- bbmatch++ ;
- if (*bbmatch == '\0') {
- integer size = 0 ;
-
- if (removecomments)
- (void)fputs(begbinary, bitfile) ;
- (void)putc(c, bitfile) ;
- while (1) {
- c = getc(f) ;
- if (c == ' ')
- (void)putc(c, bitfile) ;
- else
- break ;
- }
- while ('0' <= c && c <= '9') {
- size = size * 10 + c - '0' ;
- (void)putc(c, bitfile) ;
- c = getc(f) ;
- }
- while (c != '\r' && c != '\n') {
- if (c == EOF)
- error("! bad BeginBinary line in epsf") ;
- (void)putc(c, bitfile) ;
- c = getc(f) ;
- }
- (void)putc(c, bitfile) ;
- for (; size>0; size--) {
- c = getc(f) ;
- if (c == EOF)
- error("! premature end of file in binary section") ;
- (void)putc(c, bitfile) ;
- }
- c = getc(f) ;
- if (c == '\n' || c == '\r') {
- (void)putc(c, bitfile) ;
- c = getc(f) ;
- }
- if (c != '%')
- error("! expected to see %%EndBinary at end of data") ;
- while (1) {
- (void)putc(c, bitfile) ;
- if (c == '\r' || c == '\n')
- break ;
- c = getc(f) ;
- if (c == EOF)
- error("! premature end of file in binary section") ;
- }
- c = getc(f) ;
- }
- } else
- bbmatch = begbinary ;
- if (removecomments && c == '%' && prevc == '\n') {
- /* skip comments */
- /* revised: only skip %% and %! comments */
- c = getc(f) ;
- if (c == '%' || c == '!') {
- while ((c=getc(f))!=EOF) {
- if (c == '\n' || c == '\r') {
- c = '\n' ;
- break ;
- }
- }
- } else {
- (void)putc('%', bitfile) ;
- if (c != EOF)
- (void)putc(c, bitfile) ;
- }
- #ifdef VMCMS
- } else if (c != 0x37 ) {
- #else
- #ifdef MVSXA
- } else if (c != 0x37 ) {
- #else
- } else if (c != 4) {
- #endif
- #endif
- (void)putc(c, bitfile) ;
- }
- prevc = c ;
- /* begin DOS EPS code */
- if (doseps && (ftell(f)>=dosepsend))
- break; /* stop at end of DOS EPS PostScript section */
- /* end DOS EPS code */
- c = getc(f) ;
- if (c == EOF)
- break ;
- else if (c == '\r')
- c = '\n' ;
- }
- }
- }
- if (prevc != '\n')
- (void)putc('\n', bitfile) ;
- linepos = 0 ;
- #ifndef VMCMS
- #ifndef MVSXA
- #ifndef VMS
- #ifndef MSDOS
- #ifndef ATARIST
- #ifndef __THINK__
- if (infigure == 2)
- #ifdef OS2
- {
- if (_osmode == OS2_MODE)
- (void)pclose(f) ;
- }
- #else
- (void)pclose(f) ;
- #endif
- else
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- (void)fclose(f) ;
- if (!disablecomments)
- if (infigure)
- (void)fprintf(bitfile, "%%%%EndDocument\n") ;
- else if (infont)
- (void)fprintf(bitfile, "%%%%EndFont\n") ;
- else
- (void)fprintf(bitfile, "%%%%EndProcSet\n") ;
- }
- }
-
- /*
- * For included PostScript graphics, we use the above routine, but
- * with no fatal error message.
- */
- void figcopyfile(s, systemtype)
- char *s ;
- int systemtype ;
- {
- infigure = systemtype ? 2 : 1 ;
- copyfile(s) ;
- infigure = 0 ;
- }
- /*
- * This next routine writes out a `special' character. In this case,
- * we simply put it out, since any special character terminates the
- * preceding token.
- */
- void
- specialout(c)
- char c ;
- {
- if (linepos >= LINELENGTH) {
- (void)putc('\n', bitfile) ;
- linepos = 0 ;
- }
- (void)putc(c, bitfile) ;
- linepos++ ;
- lastspecial = 1 ;
- }
-
- void
- stringend()
- {
- if (linepos + instring >= LINELENGTH - 2) {
- (void)putc('\n', bitfile) ;
- linepos = 0 ;
- }
- (void)putc('(', bitfile) ;
- *strbp = 0 ;
- (void)fputs(strbuffer, bitfile) ;
- (void)putc(')', bitfile) ;
- linepos += instring + 2 ;
- lastspecial = 1 ;
- instring = 0 ;
- strbp = strbuffer ;
- }
-
- void
- scout(c) /* string character out */
- char c ;
- {
- /*
- * Is there room in the buffer? LINELENGTH-6 is used because we
- * need room for (, ), and a possible four-byte string \000, for
- * instance. If it is too long, we send out the string.
- */
- if (instring > LINELENGTH-6) {
- stringend() ;
- chrcmd('p') ;
- }
- /* changed next line to hex representation for VMCMS port
- if (c<' ' || c > 126 || c=='%' ) {
- */
- if ( c<0x20 || c>= 0x7F || c==0x25 ) {
- *strbp++ = '\\' ;
- *strbp++ = '0' + ((c >> 6) & 3) ;
- *strbp++ = '0' + ((c >> 3) & 7) ;
- *strbp++ = '0' + (c & 7) ;
- instring += 4 ;
- } else {
- #ifdef VMCMS
- c = ascii2ebcdic[c];
- #else
- #ifdef MVSXA
- c = ascii2ebcdic[c];
- #endif
- #endif
- if (c == '(' || c == ')' || c == '\\') {
- *strbp++ = '\\' ;
- *strbp++ = c ;
- instring += 2 ;
- } else {
- *strbp++ = c ;
- instring++ ;
- }
- }
- }
-
- void
- cmdout(s)
- char *s ;
- {
- int l ;
-
- /* hack added by dorab */
- if (instring) {
- stringend();
- chrcmd('p');
- }
- l = strlen(s) ;
- if ((! lastspecial && linepos >= LINELENGTH - 20) ||
- linepos + l >= LINELENGTH) {
- (void)putc('\n', bitfile) ;
- linepos = 0 ;
- lastspecial = 1 ;
- } else if (! lastspecial) {
- (void)putc(' ', bitfile) ;
- linepos++ ;
- }
- (void)fputs(s, bitfile) ;
- linepos += l ;
- lastspecial = 0 ;
- }
-
-
- static void
- chrcmd(c)
- char c ;
- {
- if ((! lastspecial && linepos >= LINELENGTH - 20) ||
- linepos + 2 > LINELENGTH) {
- (void)putc('\n', bitfile) ;
- linepos = 0 ;
- lastspecial = 1 ;
- } else if (! lastspecial) {
- (void)putc(' ', bitfile) ;
- linepos++ ;
- }
- (void)putc(c, bitfile) ;
- linepos++ ;
- lastspecial = 0 ;
- }
-
- void
- floatout(n)
- float n ;
- {
- char buf[20] ;
-
- (void)sprintf(buf, "%.2f", n) ;
- cmdout(buf) ;
- }
-
- void
- numout(n)
- integer n ;
- {
- char buf[10] ;
-
- #ifdef SHORTINT
- (void)sprintf(buf, "%ld", n) ;
- #else
- (void)sprintf(buf, "%d", n) ;
- #endif
- cmdout(buf) ;
- }
-
- void
- mhexout(p, len)
- register unsigned char *p ;
- register long len ;
- {
- register char *hexchar = hxdata ;
- register int n, k ;
-
- while (len > 0) {
- if (linepos > LINELENGTH - 2) {
- (void)putc('\n', bitfile) ;
- linepos = 0 ;
- }
- k = (LINELENGTH - linepos) >> 1 ;
- if (k > len)
- k = len ;
- len -= k ;
- linepos += (k << 1) ;
- while (k--) {
- n = *p++ ;
- (void)putc(hexchar[n >> 4], bitfile) ;
- (void)putc(hexchar[n & 15], bitfile) ;
- }
- }
- }
-
- void
- fontout(n)
- int n ;
- {
- char buf[6] ;
-
- if (instring) {
- stringend() ;
- chrcmd('p') ;
- }
- makepsname(buf, n) ;
- cmdout(buf) ;
- }
-
- void
- hvpos()
- {
- if (rvv != vv) {
- if (instring) {
- stringend() ;
- numout(hh) ;
- numout(vv) ;
- chrcmd('y') ;
- } else if (rhh != hh) {
- numout(hh) ;
- numout(vv) ;
- chrcmd('a') ;
- } else { /* hard to get this case, but it's there when you need it! */
- numout(vv - rvv) ;
- chrcmd('x') ;
- }
- rvv = vv ;
- } else if (rhh != hh) {
- if (instring) {
- stringend() ;
- if (hh - rhh < 5 && rhh - hh < 5) {
- #ifdef VMCMS /* should replace 'p' in non-VMCMS line as well */
- chrcmd(ascii2ebcdic[(char)(112 + hh - rhh)]) ;
- #else
- #ifdef MVSXA /* should replace 'p' in non-MVSXA line as well */
- chrcmd(ascii2ebcdic[(char)(112 + hh - rhh)]) ;
- #else
- chrcmd((char)('p' + hh - rhh)) ;
- #endif
- #endif
- } else if (hh - rhh < d + 5 && rhh - hh < 5 - d) {
- #ifdef VMCMS /* should replace 'g' in non-VMCMS line as well */
- chrcmd(ascii2ebcdic[(char)(103 + hh - rhh - d)]) ;
- #else
- #ifdef MVSXA /* should replace 'g' in non-MVSXA line as well */
- chrcmd(ascii2ebcdic[(char)(103 + hh - rhh - d)]) ;
- #else
- chrcmd((char)('g' + hh - rhh - d)) ;
- #endif
- #endif
- d = hh - rhh ;
- } else {
- numout(hh - rhh) ;
- chrcmd('b') ;
- d = hh - rhh ;
- }
- } else {
- numout(hh - rhh) ;
- chrcmd('w') ;
- }
- }
- rhh = hh ;
- }
-
- /*
- * initprinter opens the bitfile and writes the initialization sequence
- * to it.
- */
- void newline()
- {
- if (linepos != 0) {
- (void)fprintf(bitfile, "\n") ;
- linepos = 0 ;
- }
- lastspecial = 1 ;
- }
-
- void
- nlcmdout(s)
- char *s ;
- {
- newline() ;
- cmdout(s) ;
- newline() ;
- }
- /*
- * Is the dimension close enough for a match? We use a quarter inch
- * as a match; this is 65536*72.27/4 or 1,184,072 scaled points.
- */
- static int indelta(i)
- integer i ;
- {
- if (i < 0)
- i = -i ;
- return (i <= 1184072) ;
- }
- /*
- * A case-irrelevant string compare.
- */
- int mlower(c)
- int c ;
- {
- if ('A' <= c && c <= 'Z')
- return c - 'A' + 'a' ;
- else
- return c ;
- }
- int ncstrcmp(a, b)
- char *a, *b ;
- {
- while (*a && (*a == *b ||
- mlower(*a) == mlower(*b)))
- a++, b++ ;
- if (*a == 0 && *b == 0)
- return 0 ;
- else
- return 1 ;
- }
- /*
- * Find the paper size.
- */
- void findpapersize() {
- if (finpapsiz == 0) {
- struct papsiz *ps ;
-
- if (tryepsf && !landscape) {
- finpapsiz = &defpapsiz ;
- hpapersize = defpapsiz.xsize ;
- vpapersize = defpapsiz.ysize ;
- return ;
- }
- if (cropmarks) {
- /*
- * If user wanted crop marks, we increase the size of the page by
- * a half inch all around.
- */
- if (hpapersize == 0 || vpapersize == 0) {
- error(
- "warning: -k crop marks wanted, but no paper size specified; using default") ;
- if (landscape) {
- hpapersize = defpapsiz.ysize ;
- vpapersize = defpapsiz.xsize ;
- } else {
- hpapersize = defpapsiz.xsize ;
- vpapersize = defpapsiz.ysize ;
- }
- }
- hpapersize += 2368143L ;
- vpapersize += 2368143L ;
- add_header(CROPHEADER) ;
- }
- if (paperfmt && *paperfmt) {
- for (ps = papsizes; ps; ps = ps->next)
- if (ncstrcmp(paperfmt, ps->name)==0)
- finpapsiz = ps ;
- if (finpapsiz == 0)
- error("no match for papersize") ;
- }
- if (finpapsiz == 0 && hpapersize > 0 && vpapersize > 0) {
- for (ps=papsizes; ps; ps = ps->next) {
- if (indelta(ps->xsize-hpapersize) &&
- indelta(ps->ysize-vpapersize)) {
- landscape = 0 ;
- break ;
- }
- }
- if (ps == 0) {
- for (ps=papsizes; ps; ps = ps->next) {
- if (indelta(ps->ysize-hpapersize) &&
- indelta(ps->xsize-vpapersize)) {
- landscape = 1 ;
- break ;
- }
- }
- if (ps == 0) {
- for (ps=papsizes; ps; ps = ps->next) {
- if (ps->ysize == 0 && ps->xsize == 0)
- break ;
- }
- if (ps == 0) {
- landscape = (hpapersize > vpapersize) ;
- error(
- "no match for special paper size found; using default") ;
- }
- }
- }
- finpapsiz = ps ;
- }
- if (finpapsiz == 0) {
- if (papsizes)
- finpapsiz = papsizes ;
- else
- finpapsiz = &defpapsiz ;
- /*
- * But change xsize/ysize to match so bounding box works.
- */
- if (hpapersize && vpapersize) {
- if (landscape) {
- finpapsiz->ysize = hpapersize ;
- finpapsiz->xsize = vpapersize ;
- } else {
- finpapsiz->xsize = hpapersize ;
- finpapsiz->ysize = vpapersize ;
- }
- }
- }
- /*
- * Here, there was no papersize special. We set the paper size from
- * the selected paper format. If the selected paper format has no
- * sizes, we use the defaults.
- */
- if (hpapersize == 0 || vpapersize == 0) {
- if (finpapsiz->xsize == 0 || finpapsiz->ysize == 0) {
- finpapsiz->xsize = defpapsiz.xsize ;
- finpapsiz->ysize = defpapsiz.ysize ;
- }
- if (landscape) {
- vpapersize = finpapsiz->xsize ;
- hpapersize = finpapsiz->ysize ;
- } else {
- hpapersize = finpapsiz->xsize ;
- vpapersize = finpapsiz->ysize ;
- }
- /*
- * Here, there was a papersize special, but the selected paper
- * format has 0 0 for sizes. We set the sizes here so that the
- * bounding box works.
- */
- } else if (finpapsiz->xsize == 0 || finpapsiz->ysize == 0) {
- finpapsiz->xsize = hpapersize ;
- finpapsiz->ysize = vpapersize ;
- /*
- * Here, the user specified a size with -t, and there was a
- * papersize special, and its sizes were greater than zero.
- * We make sure the sizes are okay. Note that the user must have
- * specified landscape if this is desired.
- */
- } else if (paperfmt && *paperfmt) {
- if (landscape) {
- if (!indelta(vpapersize - finpapsiz->xsize) ||
- !indelta(hpapersize - finpapsiz->ysize)) {
- if (vpapersize > finpapsiz->xsize ||
- hpapersize > finpapsiz->ysize)
- error("warning: -t selected paper may be too small") ;
- else
- error("note: -t selected paper may be too large") ;
- }
- } else {
- if (!indelta(hpapersize - finpapsiz->xsize) ||
- !indelta(vpapersize - finpapsiz->ysize)) {
- if (hpapersize > finpapsiz->xsize ||
- vpapersize > finpapsiz->ysize)
- error("warning: -t selected paper may be too small") ;
- else
- error("note: -t selected paper may be too large") ;
- }
- }
- }
- }
- }
- /*
- * Convert scaled points to PostScript points. This is the same
- * as return (i * 72 / (65536 * 72.27)), which is the same as
- * dividing by 65781.76, but we want to round up.
- */
- static int topoints(i)
- integer i ;
- {
- i += 65780L ;
- return (i / 6578176L)*100 + (i % 6578176) * 100 / 6578176 ;
- }
- /*
- * Send out the special paper stuff. If `hed' is non-zero, only
- * send out lines starting with `!' else send all other lines out.
- */
- void paperspec(s, hed)
- char *s ;
- int hed ;
- {
- int sendit ;
-
- while (*s) {
- s++ ;
- if (*s == '\0')
- return ;
- if (*s == '!') {
- s++ ;
- while (*s == ' ') s++ ;
- sendit = hed ;
- } else
- sendit = ! hed ;
- if (sendit) {
- while (*s && *s != '\n')
- (void)putc(*s++, bitfile) ;
- putc('\n', bitfile) ;
- } else {
- while (*s && *s != '\n')
- s++ ;
- }
- }
- }
- char *epsftest() {
- if (tryepsf && totalpages == 1 && paperfmt == 0 && *iname) {
- findbb() ;
- return nextstring ;
- }
- return 0 ;
- }
- static char *isepsf = 0 ;
- static int endprologsent ;
- void
- initprinter(n)
- int n ; /* number of pages if greater than 0 */
- {
- void tell_needed_fonts() ;
-
- n *= pagecopies * collatedcopies ;
- if (*oname != 0) {
- /*
- * We check to see if the first character is a exclamation
- * point, and popen if so.
- */
- if (*oname == '!' || *oname == '|') {
- #ifdef MSDOS
- error("! can't open output pipe") ;
- #else
- #ifdef VMS
- error("! can't open output pipe") ;
- #else
- #ifdef VMCMS
- error("! can't open output pipe") ;
- #else
- #ifdef MVSXA
- error("! can't open output pipe") ;
- #else
- #ifdef __THINK__
- error("! can't open output pipe") ;
- #else
- #ifdef ATARIST
- error("! can't open output pipe") ;
- #else
- #ifdef OS2
- if (_osmode != OS2_MODE) {
- error("! can't open output pipe") ;
- } else {
- #endif
- if (secure || (bitfile=popen(oname+1, "w"))==NULL)
- error("! couldn't open output pipe") ;
- else
- popened = 1 ;
- #ifdef OS2
- }
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- } else {
- if ((bitfile=fopen(oname,"w"))==NULL)
- error("! couldn't open PostScript file") ;
- }
- } else {
- bitfile = stdout ;
- }
- findpapersize() ;
- if (disablecomments)
- (void)fprintf(bitfile,
- "%%!PS (but not EPSF; comments have been disabled)\n") ;
- else {
- if (multiplesects)
- (void)fprintf(bitfile,
- "%%!PS (but not EPSF because of memory limits)\n") ;
- else {
- isepsf = epsftest() ;
- if (isepsf)
- (void)fprintf(bitfile, "%%!PS-Adobe-2.0 EPSF-2.0\n") ;
- else
- (void)fprintf(bitfile, "%%!PS-Adobe-2.0\n") ;
- }
- if (tryepsf && isepsf == 0)
- error("We tried, but couldn't make it EPSF.") ;
- (void)fprintf(bitfile, "%%%%Creator: %s", banner + 8) ;
- if (*iname)
- (void)fprintf(bitfile, "%%%%Title: %s\n", iname) ;
- #ifdef CREATIONDATE
- jobtime=time(0);
- (void)fprintf(bitfile, "%%%%CreationDate: %s",
- asctime(localtime(&jobtime))) ;
- #endif
- if (! isepsf) {
- /*
- * Normally, we wouldn't want to add that second field
- * indicating that the page order is reversed, as per page
- * 644 of the Red book. But we have to, for many existing
- * spoolers.
- */
- (void)fprintf(bitfile, "%%%%Pages: %d%s\n", (n ? n : totalpages),
- (reverse?" -1":"")) ;
- (void)fprintf(bitfile, "%%%%PageOrder: %sscend\n", reverse?"De":"A");
- }
- if (landscape) {
- fprintf(bitfile, "%%%%Orientation: Landscape\n") ;
- fprintf(bitfile, "%%%%BoundingBox: 0 0 %d %d\n",
- topoints(finpapsiz->xsize), topoints(finpapsiz->ysize)) ;
- } else if (isepsf)
- fprintf(bitfile, "%%%%BoundingBox: %s\n", isepsf) ;
- else
- fprintf(bitfile, "%%%%BoundingBox: 0 0 %d %d\n",
- topoints(finpapsiz->xsize), topoints(finpapsiz->ysize)) ;
- tell_needed_fonts() ;
- paperspec(finpapsiz->specdat, 1) ;
- (void)fprintf(bitfile, "%%%%EndComments\n") ;
- }
- {
- int i, len ;
- char *p ;
-
- /*
- * Here, too, we have to be careful not to exceed the line length
- * limitation, if possible.
- */
- (void)fprintf(bitfile, "%%DVIPSCommandLine:") ;
- len = 18 ;
- for (i=0; i<gargc; i++) {
- p = gargv[i] ;
- while (*p > ' ')
- p++ ;
- if (*p)
- len += 2 ;
- len += strlen(gargv[i]) + 1 ;
- if (len > LINELENGTH) {
- (void)fprintf(bitfile, "\n%%+") ;
- len = strlen(gargv[i]) + 3 ;
- if (*p)
- len += 2 ;
- }
- (void)fprintf(bitfile, (*p ? " \"%s\"" : " %s"), gargv[i]) ;
- }
- (void)fprintf(bitfile, "\n%%DVIPSParameters: dpi=%d", actualdpi) ;
- if (actualdpi != vactualdpi)
- (void)fprintf(bitfile, "x%d", vactualdpi) ;
- if (compressed)
- (void)fprintf(bitfile, ", compressed") ;
- if (removecomments)
- (void)fprintf(bitfile, ", comments removed") ;
- (void)fputc('\n', bitfile) ;
- }
- #ifdef VMCMS /* convert preamblecomment to ebcdic so we can read it */
- {
- int i ;
- for ( i=0 ; preamblecomment[i] ; i++ )
- preamblecomment[i] = ascii2ebcdic[preamblecomment[i]] ;
- }
- #else
- #ifdef MVSXA /* IBM: MVS/XA */
- {
- int i ;
- for ( i=0 ; preamblecomment[i] ; i++ )
- preamblecomment[i] = ascii2ebcdic[preamblecomment[i]] ;
- }
- #endif /* VMCMS */
- #endif
- (void)fprintf(bitfile, "%%DVIPSSource: %s\n", preamblecomment) ;
- linepos = 0 ;
- endprologsent = 0 ;
- if (safetyenclose)
- (void)fprintf(bitfile, "/SafetyEnclosure save def\n") ;
- if (! headers_off)
- send_headers() ;
- }
- void setup() {
- newline() ;
- if (endprologsent == 0 && !disablecomments) {
- (void)fprintf(bitfile, "%%%%EndProlog\n") ;
- (void)fprintf(bitfile, "%%%%BeginSetup\n") ;
- if (vactualdpi == actualdpi)
- (void)fprintf(bitfile, "%%%%Feature: *Resolution %ddpi\n",
- actualdpi) ;
- else
- (void)fprintf(bitfile, "%%%%Feature: *Resolution %dx%ddpi\n",
- actualdpi, vactualdpi) ;
- if (multiplesects && *(finpapsiz->specdat)) {
- (void)fprintf(bitfile, "TeXDict begin\n") ;
- paperspec(finpapsiz->specdat, 0) ;
- (void)fprintf(bitfile, "end\n") ;
- }
- if (manualfeed)
- (void)fprintf(bitfile, "%%%%Feature: *ManualFeed True\n") ;
- if (multiplesects)
- (void)fprintf(bitfile, "%%%%EndSetup\n") ;
- }
- if (multiplesects && ! disablecomments)
- (void)fprintf(bitfile, "%%DVIPSBeginSection\n") ;
- cmdout("TeXDict") ;
- cmdout("begin") ;
- if (endprologsent || disablecomments || multiplesects == 0) {
- (void)fprintf(bitfile, "\n") ;
- paperspec(finpapsiz->specdat, 0) ;
- }
- if (manualfeed) cmdout("@manualfeed") ;
- if (landscape) cmdout("@landscape") ;
- if (numcopies != 1) {
- numout((integer)numcopies) ;
- cmdout("@copies") ;
- }
- if (endprologsent == 0 && !disablecomments) {
- newline() ;
- endprologsent = 1 ;
- if (! multiplesects)
- (void)fprintf(bitfile, "%%%%EndSetup\n") ;
- }
- }
- /*
- * cleanprinter is the antithesis of the above routine.
- */
- void
- cleanprinter()
- {
- (void)fprintf(bitfile, "\n") ;
- (void)fprintf(bitfile, "userdict /end-hook known{end-hook}if\n") ;
- if (safetyenclose)
- (void)fprintf(bitfile, "SafetyEnclosure restore\n") ;
- if (!disablecomments)
- (void)fprintf(bitfile, "%%%%EOF\n") ;
- if (sendcontrolD)
- (void)putc(4, bitfile) ;
- if (ferror(bitfile))
- {
- error("Problems with file writing.") ;
- perror (oname);
- }
- #ifndef MSDOS
- #ifndef VMS
- #ifndef MVSXA
- #ifndef VMCMS
- #ifndef __THINK__
- #ifndef ATARIST
- #ifdef OS2
- if (_osmode == OS2_MODE)
- #endif
- if (popened)
- (void)pclose(bitfile) ;
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- if (popened == 0)
- (void)fclose(bitfile) ;
- bitfile = NULL ;
- }
-
- /* this tells dvips that it has no clue where it is. */
- static int thispage = 0 ;
- static integer rulex, ruley ;
- void psflush() {
- rulex = ruley = rhh = rvv = -314159265 ;
- lastfont = -1 ;
- }
- /*
- * pageinit initializes the output variables.
- */
- void
- pageinit()
- {
- psflush() ;
- newline() ;
- thispage++ ;
- if (!disablecomments)
- if (multiplesects)
- #ifdef SHORTINT
- (void)fprintf(bitfile, "%%DVIPSSectionPage: %ld\n", pagenum) ;
- else if (! isepsf)
- (void)fprintf(bitfile, "%%%%Page: %ld %d\n", pagenum, thispage) ;
- #else
- (void)fprintf(bitfile, "%%DVIPSSectionPage: %d\n", pagenum) ;
- else if (! isepsf)
- (void)fprintf(bitfile, "%%%%Page: %d %d\n", pagenum, thispage) ;
- #endif
- linepos = 0 ;
- numout((integer)pagenum) ;
- numout((integer)thispage-1) ;
- cmdout("bop") ;
- d = 0 ;
- }
-
-
-
- /*
- * This routine ends a page.
- */
- void
- pageend()
- {
- if (instring) {
- stringend() ;
- chrcmd('p') ;
- }
- cmdout("eop") ;
- }
-
- /*
- * drawrule draws a rule at the specified position.
- * It does nothing to save/restore the current position,
- * or even draw the current string. (Rules are normally
- * set below the baseline anyway, so this saves us on
- * output size almost always.)
- */
- void
- drawrule(rw, rh)
- integer rw, rh ;
- {
- numout((integer)hh) ;
- numout((integer)vv) ;
- if (rw == rulex && rh == ruley)
- chrcmd('V') ;
- else {
- numout((integer)rw) ;
- numout((integer)rh) ;
- chrcmd('v') ;
- rulex = rw ;
- ruley = rh ;
- }
- }
-
- /*
- * drawchar draws a character at the specified position.
- */
- void
- drawchar(c, cc)
- chardesctype *c ;
- int cc ;
- {
- hvpos() ;
- if (lastfont != curfnt->psname) {
- fontout((int)curfnt->psname) ;
- lastfont = curfnt->psname ;
- }
- scout(cc) ;
- rhh = hh + c->pixelwidth ; /* rvv = rv */
- }
- /*
- * This routine sends out the document fonts comment.
- */
- void tell_needed_fonts() {
- struct header_list *hl = ps_fonts_used ;
- char *q ;
- int roomleft = -1 ;
- extern char *get_name() ;
-
- if (hl == 0)
- return ;
- while (0 != (q=get_name(&hl))) {
- if ((int)strlen(q) >= roomleft) {
- if (roomleft != -1) {
- fprintf(bitfile, "\n%%%%+") ;
- roomleft = LINELENGTH - 3 ;
- } else {
- fprintf(bitfile, "%%%%DocumentFonts:") ;
- roomleft = LINELENGTH - 16 ;
- }
- }
- fprintf(bitfile, " %s", q) ;
- roomleft -= strlen(q) + 1 ;
- }
- fprintf(bitfile, "\n") ;
- }
-