DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T o

⟦7befa3cc5⟧ TextFile

    Length: 14199 (0x3777)
    Types: TextFile
    Names: »output.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦8d3183c2b⟧ »utils/dvips541.tar.Z« 
        └─⟦008d6ff64⟧ 
            └─⟦this⟧ »./dvips/output.c« 

TextFile

/*
 *   These routines do most of the communicating with the printer.
 *
 *   LINELENGTH tells the maximum line length to send out.
 */
#define LINELENGTH (78)
#include "structures.h" /* The copyright notice in that file is included too! */
#include <ctype.h>
/*
 *   The external routines called here:
 */
extern void error() ;
extern void send_headers() ;
extern FILE *search() ;
extern char *getenv() ;
extern void fonttableout() ;
extern void makepsname() ;
/*
 *   These are the external variables used by these routines.
 */
extern integer hh, vv ;
extern fontdesctype *curfnt ;
extern FILE *bitfile ;
extern char *oname ;
extern Boolean reverse ;
extern Boolean removecomments ;
extern Boolean sendcontrolD, disablecomments, multiplesects ;
extern Boolean usesPSfonts, headers_off ;
extern Boolean safetyenclose ;
extern int numcopies ;
extern int totalpages ;
extern integer pagenum ;
extern Boolean manualfeed ;
extern int landscape ;
extern int quiet ;
extern int prettycolumn ;
extern int actualdpi ;
extern char *iname ;
extern char *paperfmt ;
extern char *headerpath ;
extern char errbuf[] ;
extern shalfword linepos ;
extern char *figpath ;
extern struct header_list *ps_fonts_used ;
extern char banner[] ;
/*
 *   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 {
    char *format;
    int width, height;
} paper_types[] = {
    { "letter",  612,  792 },		/* 8.5 x 11 */
    { "legal",   612, 1008 },		/* 8.5 x 14 */
    { "ledger",  792, 1224 },		/* 11 x 17 */
    { "a4",	 596,  843 },		/* 210mm x 297mm */
    { "a3",      843, 1192 } };		/* 297mm x 420mm */
/*
 *   This routine copies a file down the pipe.  Search path uses the
 *   header path.
 */
static int infigure ;
void
copyfile(s)
        char *s ;
{
   FILE *f ;
   int c, prevc = '\n' ;

   switch (infigure) {
   case 1:
      f = search(figpath, s, READ) ;
      (void)sprintf(errbuf, "Couldn't find figure file %s; continuing", s) ;
      break ;
   default:
      f = search(headerpath, s, READ) ;
      (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
      break ;
#ifndef VMS
#ifndef MSDOS
   case 2:
      f = popen(s, "r") ;
      (void)sprintf(errbuf, "Failure to execute %s; continuing", s) ;
      break;
#endif
#endif
   }
   if (f==NULL)
      error(errbuf) ;
   else {
      if (! quiet) {
         if (strlen(s) + prettycolumn > 76) {
            fprintf(stderr, "\n") ;
            prettycolumn = 0 ;
         }
         (void)fprintf(stderr, "<%s>", s) ;
         (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
            (void)fprintf(bitfile, "%%%%BeginProcSet: %s\n", s) ;
      while ((c=getc(f))!=EOF && c != 4) {
         if (! removecomments && c == '%' && prevc == '\n') {/* skip comments */
            while ((c=getc(f))!=EOF) {
               if (c=='\n')
                  break ;
            }
         } else
            (void)putc(c, bitfile) ;
         prevc = c ;
      }
      if (prevc != '\n')
         (void)putc('\n', bitfile) ;
      linepos = 0 ;
#ifndef VMS
#ifndef MSDOS
      if (infigure == 2)
         (void)pclose(f) ;
      else
#endif
#endif
         (void)fclose(f) ;
      if (!disablecomments)
         if (infigure)
            (void)fprintf(bitfile, "%%%%EndDocument\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') ;
   }
   if (c<' ' || c>126 || c=='%') {
      *strbp++ = '\\' ;
      *strbp++ = '0' + ((c >> 6) & 3) ;
      *strbp++ = '0' + ((c >> 3) & 7) ;
      *strbp++ = '0' + (c & 7) ;
      instring += 4 ;
   } else 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] ;

   (void)sprintf(buf, "%ld", n) ;
   cmdout(buf) ;
}

void
mhexout(p, len)
register unsigned char *p ;
register long len ;
{
   register char *hexchar = "0123456789ABCDEF" ;
   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) {
            chrcmd((char)('p' + hh - rhh)) ;
         } else if (hh - rhh < d + 5 && rhh - hh < 5 - d) {
            chrcmd((char)('g' + hh - rhh - d)) ;
            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() ;
}

void
initprinter()
{
   void tell_needed_fonts() ;
   int i;
   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
         if ((bitfile=popen(oname+1, "w"))==NULL)
            error("! couldn't open output pipe") ;
         else
            popened = 1 ;
#endif
#endif
      } else {
         if ((bitfile=fopen(oname,"w"))==NULL)
            error("! couldn't open PostScript file") ;
      }
   } else {
      bitfile = stdout ;
   }
   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  (void)fprintf(bitfile, "%%!PS-Adobe-2.0\n") ;
      (void)fprintf(bitfile, "%%%%Creator: %s", banner + 8) ;
      if (*iname)
         (void)fprintf(bitfile, "%%%%Title: %s\n", iname) ;
      (void)fprintf(bitfile, "%%%%Pages: %d %d\n", totalpages, 1 - 2*reverse) ;
      if (paperfmt && *paperfmt) {
         for (i=0; i<sizeof(paper_types)/sizeof(paper_types[0]); ++i)
            if (strcmp(paperfmt,paper_types[i].format)==0)
                (void)fprintf(bitfile, "%%%%BoundingBox: 0 0 %d %d\n",
                    paper_types[i].width, paper_types[i].height) ;
      } else
         fprintf(bitfile, "%%%%BoundingBox: 0 0 612 792\n") ;
      tell_needed_fonts() ;
      (void)fprintf(bitfile, "%%%%EndComments\n") ;
   }
   if (safetyenclose)
      (void)fprintf(bitfile, "/SafetyEnclosure save def\n") ;
   if (! headers_off)
      send_headers() ;
}

static int endprologsent ;
void setup() {
   newline() ;
   if (endprologsent == 0 && !disablecomments) {
      fonttableout() ;
      (void)fprintf(bitfile, "%%%%EndProlog\n") ;
      (void)fprintf(bitfile, "%%%%BeginSetup\n") ;
      (void)fprintf(bitfile, "%%%%Feature: *Resolution %d\n", DPI) ;
      if (manualfeed)
         (void)fprintf(bitfile, "%%%%Feature: *ManualFeed True\n") ;
   }
   cmdout("TeXDict") ;
   cmdout("begin") ;
   {
      char pft[100] ;
      strcpy(pft, "@") ;
      if (landscape)
         strcat(pft, "landscape ") ;
      else if (paperfmt)
         strcat(pft, paperfmt) ;
      else
         pft[0] = 0 ;
/*    if (paperfmt) {         doing this has many bad effects!!!
         strcat(pft, " /") ;
         strcat(pft, paperfmt) ;
         strcat(pft, " where {pop ") ;
         strcat(pft, paperfmt) ;
         strcat(pft, "} if") ;
      } */
      cmdout(pft) ;
   }
   if (manualfeed) cmdout("@manualfeed") ;
   if (numcopies != 1) {
      numout((integer)numcopies) ;
      cmdout("@copies") ;
   }
   if (endprologsent == 0 && !disablecomments) {
      newline() ;
      endprologsent = 1 ;
      (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) ;
#ifndef MSDOS
#ifndef VMS
   if (popened)
      (void)pclose(bitfile) ;
#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() ;
   if (!disablecomments && !multiplesects)
      (void)fprintf(bitfile, "%%%%Page: %ld %d\n", pagenum, ++thispage) ;
   linepos = 0 ;
   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 (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") ;
}