home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / dvips / output.c < prev    next >
C/C++ Source or Header  |  1994-09-27  |  36KB  |  1,336 lines

  1. /*
  2.  *   These routines do most of the communicating with the printer.
  3.  *
  4.  *   LINELENGTH tells the maximum line length to send out.  It's been
  5.  *   reduced to 72 because sometimes PostScript files are included in
  6.  *   mail messages and many mailers mutilate longer lines.
  7.  */
  8. #define LINELENGTH (72)
  9. #include "dvips.h" /* The copyright notice in that file is included too! */
  10. #include <ctype.h>
  11.  
  12. #ifdef OS2
  13. #include <stdlib.h>
  14. #ifdef _MSC_VER
  15. #define popen(pcmd, pmode)  _popen(pcmd, pmode)
  16. #define pclose(pstream) _pclose(pstream)
  17. #endif
  18. #endif
  19. /*
  20.  *   The external routines called here:
  21.  */
  22. #ifdef AMIGA
  23. #include <stdlib.h>
  24. #include "output_protos.h"
  25. #include "dvips_protos.h"
  26. #include "header_protos.h"
  27. #include "search_protos.h"
  28. #include "finclude_protos.h"
  29. #include "download_protos.h"
  30. #include "papersiz_protos.h"
  31. #include "bbox_protos.h"
  32. #include "pipe.h"
  33. static void chrcmd(char);
  34. static int indelta(integer);
  35. static int topoints(integer);
  36. #else
  37. extern void error() ;
  38. extern void send_headers() ;
  39. extern int add_header() ;
  40. extern FILE *search() ;
  41. extern char *getenv() ;
  42. extern void makepsname() ;
  43. extern void handlepapersize() ;
  44. extern void findbb() ;
  45. #endif
  46. /*
  47.  *   These are the external variables used by these routines.
  48.  */
  49. extern integer hh, vv ;
  50. extern fontdesctype *curfnt ;
  51. extern FILE *bitfile ;
  52. extern char *oname ;
  53. extern Boolean secure ;
  54. extern Boolean reverse ;
  55. extern Boolean removecomments ;
  56. extern Boolean sendcontrolD, disablecomments, multiplesects ;
  57. extern Boolean usesPSfonts, headers_off ;
  58. extern Boolean safetyenclose ;
  59. extern Boolean cropmarks ;
  60. extern Boolean tryepsf ;
  61. extern Boolean compressed ;
  62. extern int numcopies ;
  63. extern int collatedcopies ;
  64. extern integer pagecopies ;
  65. extern int totalpages ;
  66. extern integer pagenum ;
  67. extern Boolean manualfeed ;
  68. extern int landscape ;
  69. extern int quiet ;
  70. extern int prettycolumn ;
  71. extern int actualdpi, vactualdpi ;
  72. extern char *iname, *nextstring ;
  73. extern char *paperfmt ;
  74. extern char *headerpath ;
  75. extern char errbuf[] ;
  76. extern shalfword linepos ;
  77. extern char *figpath ;
  78. extern struct header_list *ps_fonts_used ;
  79. extern char banner[] ;
  80. extern int gargc ;
  81. extern char **gargv ;
  82. extern struct papsiz *papsizes ;
  83. extern integer hpapersize, vpapersize ;
  84. char preamblecomment[256] ; /* usually "TeX output ..." */
  85. /*
  86.  *   We need a few statics to take care of things.
  87.  */
  88. static integer rhh, rvv ;
  89. static int instring ;
  90. static Boolean lastspecial = 1 ;
  91. static shalfword d ;
  92. static Boolean popened = 0 ;
  93. int lastfont ; /* exported to dospecial to fix rotate.tex problem */
  94. #ifndef AMIGA
  95. static void chrcmd();                   /* just a forward declaration */
  96. #endif
  97. static char strbuffer[LINELENGTH + 20], *strbp = strbuffer ;
  98. static struct papsiz *finpapsiz ;
  99. static struct papsiz defpapsiz = {
  100.    0, 40258437L, 52099154L, "letter", ""
  101. } ;
  102. #ifdef CREATIONDATE
  103. #if !defined(VMS) && !defined(MSDOS) && !(defined(OS2) && defined(_MSC_VER)) && !defined(ATARIST) && !defined(AMIGA)
  104.  /* VAXC/MSDOS/AMIGA don't like/need this !! */
  105. #include <sys/types.h>
  106. #include <sys/time.h> /* time(), at least on BSD Unix */
  107. #endif
  108. #include <time.h> /* asctime() and localtime(), at least on BSD Unix */
  109. static time_t jobtime;
  110. #endif
  111. /*
  112.  *   This routine copies a file down the pipe.  Search path uses the
  113.  *   header path.
  114.  *
  115.  *   We add code to handle the case of MS-DOS font files.
  116.  *
  117.  *   Format:  80 {01,02} four byte length in littleendian order data
  118.  *   repeated possibly multiple times.
  119.  */
  120. static char *hxdata = "0123456789ABCDEF" ;
  121. static int infigure ;
  122. extern char *infont ;
  123. static char *begbinary = "\n%%BeginBinary:" ;
  124. void
  125. copyfile(s)
  126.         char *s ;
  127. {
  128.    FILE *f = NULL ;
  129.    int c, prevc = '\n' ;
  130.    long len ;
  131.    char *bbmatch = begbinary ;
  132.    /* begin DOS EPS code */
  133.    int doseps = 0;
  134.    unsigned long dosepsbegin, dosepsend = 0;
  135.    /* end DOS EPS code */
  136. #ifdef VMCMS
  137.    register char *lastdirsep ;
  138.    register char *trunc_s ;
  139.    trunc_s = s ;
  140. #endif
  141. #ifdef MVSXA
  142.    register char *lastdirsep ;
  143.    register char *trunc_s ;
  144.    trunc_s = s ;
  145. #endif
  146.  
  147.    switch (infigure) {
  148.    case 1:
  149. /*
  150.  *   Look in headerpath too, just in case.  This allows common header
  151.  *   or figure files to be installed in the .../ps directory.
  152.  */
  153.       f = search(figpath, s, READ) ;
  154.       if (f == 0)
  155.          f = search(headerpath, s, READ) ;
  156. #ifdef VMCMS
  157.       lastdirsep = strrchr(s, '/') ;
  158.       if ( NULL != lastdirsep ) trunc_s = lastdirsep + 1 ;
  159.       (void)sprintf(errbuf,
  160.    "Couldn't find figure file %s with CMS name %s; continuing", s, trunc_s) ;
  161. #else
  162. #ifdef MVSXA
  163.       lastdirsep = strrchr(s, '/') ;
  164.       if ( NULL != lastdirsep ) trunc_s = lastdirsep + 1 ;
  165.       (void)sprintf(errbuf,
  166.     "Couldn't find figure file %s with MVS name %s; continuing", s, trunc_s) ;
  167. #else
  168.       (void)sprintf(errbuf, "Couldn't find figure file %s; continuing", s) ;
  169. #endif
  170. #endif
  171.       break ;
  172.    default:
  173.       f = search(headerpath, s, READ) ;
  174.       (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
  175.       break ;
  176. #ifndef VMCMS
  177. #ifndef MVSXA
  178. #ifndef VMS
  179. #ifndef MSDOS
  180. #ifndef ATARIST
  181. #ifndef __THINK__
  182.    case 2:
  183. #ifdef SECURE
  184.       (void)sprintf(errbuf, "<%s>: Tick filename execution disabled", s) ;
  185. #else
  186. #ifdef OS2
  187.       if (_osmode == OS2_MODE) {
  188. #endif
  189.       if (secure == 0)
  190.          f = popen(s, "r") ;
  191. #ifdef OS2
  192.       }
  193. #endif
  194.       (void)sprintf(errbuf, "Failure to execute %s; continuing", s) ;
  195. #endif
  196.       break;
  197. #endif
  198. #endif
  199. #endif
  200. #endif
  201. #endif
  202. #endif
  203.    }
  204.    if (f==NULL)
  205.       error(errbuf) ;
  206.    else {
  207.       if (! quiet) {
  208.          if (strlen(s) + prettycolumn > STDOUTSIZE) {
  209.             fprintf(stderr, "\n") ;
  210.             prettycolumn = 0 ;
  211.          }
  212. #ifdef VMCMS
  213.          (void)fprintf(stderr, "<%s>", trunc_s) ;
  214. #else
  215. #ifdef MVSXA
  216.          (void)fprintf(stderr, "<%s>", trunc_s) ;
  217. #else
  218.          (void)fprintf(stderr, "<%s>", s) ;
  219. #endif
  220. #endif
  221.          (void)fflush(stderr) ;
  222.          prettycolumn += 2 + strlen(s) ;
  223.       }
  224.       if (linepos != 0)
  225.          (void)putc('\n', bitfile) ;
  226.       if (! disablecomments)
  227.          if (infigure)
  228.             (void)fprintf(bitfile, "%%%%BeginDocument: %s\n", s) ;
  229.          else if (infont)
  230.             (void)fprintf(bitfile, "%%%%BeginFont: %s\n", infont) ;
  231.          else
  232.             (void)fprintf(bitfile, "%%%%BeginProcSet: %s\n", s) ;
  233.       c = getc(f) ;
  234.       if (c == 0x80) {
  235. #if defined MSDOS || defined OS2 || defined(ATARIST)
  236.          (void)fclose(f) ;  /* close MSDOS font file */
  237.          f = search(headerpath, s, READBIN) ;  /* reopen in BINARY mode */
  238.          (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
  239.          if (f==NULL)
  240.            error(errbuf) ;
  241.          c = getc(f);
  242. #endif
  243.          while (1) {
  244.             c = getc(f) ;
  245.             switch(c) {
  246. case 1:
  247. case 2:
  248.                len = getc(f) ;
  249.                len += getc(f) * 256L ;
  250.                len += getc(f) * 65536L ;
  251.                len += getc(f) * 256L * 65536 ;
  252.                if (c == 1) {
  253.                   while (len > 0) {
  254.                      c = getc(f) ;
  255.                      if (c == EOF) {
  256.                         error("premature EOF in MS-DOS font file") ;
  257.                         len = 0 ;
  258.                      } else {
  259.                         if (c == 13)
  260.                            (void)putc('\n', bitfile) ;
  261.                         else
  262.                            (void)putc(c, bitfile) ;
  263.                         len-- ;
  264.                      }
  265.                   }
  266.                } else {
  267.                   putc('\n', bitfile) ;
  268.                   prevc = 0 ;
  269.                   while (len > 0) {
  270.                      c = getc(f) ;
  271.                      if (c == EOF) {
  272.                         error("premature EOF in MS-DOS font file") ;
  273.                         len = 0 ;
  274.                      } else {
  275.                         (void)putc(hxdata[c >> 4], bitfile) ;
  276.                         (void)putc(hxdata[c & 15], bitfile) ;
  277.                         len-- ;
  278.                         prevc += 2 ;
  279.                         if (prevc >= 76) {
  280.                            putc('\n', bitfile) ;
  281.                            prevc = 0 ;
  282.                         }
  283.                      }
  284.                   }
  285.                }
  286.                break ;
  287. case 3:
  288.                goto msdosdone ;
  289. default:
  290.                error("saw type other than 1, 2, or 3 in MS-DOS font file") ;
  291.                break ;
  292.             }
  293.             c = getc(f) ;
  294.             if (c == EOF)
  295.                break ;
  296.             if (c != 0x80) {
  297.                error("saw non-MSDOS header in MSDOS font file") ;
  298.                break ;
  299.             }
  300.          }
  301. msdosdone:
  302.          prevc = 0 ;
  303.       } else {
  304. /* begin DOS EPS code */
  305.          if (c == 'E'+0x80) {
  306.             if ((getc(f)=='P'+0x80) && (getc(f)=='S'+0x80)
  307.                                 && (getc(f)=='F'+0x80)) {
  308. #if defined MSDOS || defined OS2
  309.                (void)fclose(f) ;  /* close DOS EPS file */
  310.                f = search(headerpath, s, READBIN) ;
  311.                                                    /* reopen in BINARY mode */
  312.                (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
  313.                if (f==NULL)
  314.                  error(errbuf) ;
  315.                fseek(f, 4L, 0);
  316. #endif
  317.                doseps = 1;
  318.                dosepsbegin = getc(f) ;
  319.                dosepsbegin += getc(f) * 256L ;
  320.                dosepsbegin += getc(f) * 65536L ;
  321.                dosepsbegin += getc(f) * 256L * 65536 ;
  322.                dosepsend = getc(f) ;
  323.                dosepsend += getc(f) * 256L ;
  324.                dosepsend += getc(f) * 65536L ;
  325.                dosepsend += getc(f) * 256L * 65536 ;
  326.                dosepsend += dosepsbegin;
  327. #if defined MSDOS || defined OS2
  328.                (void)fclose(f) ;  /* close DOS EPS file */
  329.                f = search(headerpath, s, READ) ;  /* reopen in TEXT mode */
  330.                (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
  331.                if (f==NULL)
  332.                  error(errbuf) ;
  333. #endif
  334.                fseek(f, dosepsbegin, 0);
  335.                c = getc(f);
  336.             }
  337.             else {
  338.                rewind(f);
  339.                c = getc(f);
  340.             }
  341.          }
  342. /* end DOS EPS code */
  343.          if (c != EOF) {
  344.             while (1) {
  345.                if (c == *bbmatch) {
  346.                   bbmatch++ ;
  347.                   if (*bbmatch == '\0') {
  348.                      integer size = 0 ;
  349.  
  350.                      if (removecomments)
  351.                         (void)fputs(begbinary, bitfile) ;
  352.                      (void)putc(c, bitfile) ;
  353.                      while (1) {
  354.                         c = getc(f) ;
  355.                         if (c == ' ')
  356.                            (void)putc(c, bitfile) ;
  357.                         else
  358.                            break ;
  359.                      }
  360.                      while ('0' <= c && c <= '9') {
  361.                         size = size * 10 + c - '0' ;
  362.                         (void)putc(c, bitfile) ;
  363.                         c = getc(f) ;
  364.                      }
  365.                      while (c != '\r' && c != '\n') {
  366.                         if (c == EOF)
  367.                            error("! bad BeginBinary line in epsf") ;
  368.                         (void)putc(c, bitfile) ;
  369.                         c = getc(f) ;
  370.                      }
  371.                      (void)putc(c, bitfile) ;
  372.                      for (; size>0; size--) {
  373.                         c = getc(f) ;
  374.                         if (c == EOF)
  375.                            error("! premature end of file in binary section") ;
  376.                         (void)putc(c, bitfile) ;
  377.                      }
  378.                      c = getc(f) ;
  379.                      if (c == '\n' || c == '\r') {
  380.                         (void)putc(c, bitfile) ;
  381.                         c = getc(f) ;
  382.                      }
  383.                      if (c != '%')
  384.                         error("! expected to see %%EndBinary at end of data") ;
  385.                      while (1) {
  386.                         (void)putc(c, bitfile) ;
  387.                         if (c == '\r' || c == '\n')
  388.                            break ;
  389.                         c = getc(f) ;
  390.                         if (c == EOF)
  391.                            error("! premature end of file in binary section") ;
  392.                      }
  393.                      c = getc(f) ;
  394.                   }
  395.                } else
  396.                   bbmatch = begbinary ;
  397.                if (removecomments && c == '%' && prevc == '\n') {
  398.                          /* skip comments */
  399.                  /* revised:  only skip %% and %! comments */
  400.                   c = getc(f) ;
  401.                   if (c == '%' || c == '!') {
  402.                      while ((c=getc(f))!=EOF) {
  403.                         if (c == '\n' || c == '\r') {
  404.                            c = '\n' ;
  405.                            break ;
  406.                         }
  407.                      }
  408.           } else {
  409.              (void)putc('%', bitfile) ;
  410.              if (c != EOF)
  411.                         (void)putc(c, bitfile) ;
  412.           }
  413. #ifdef VMCMS
  414.                } else if (c != 0x37 ) {
  415. #else
  416. #ifdef MVSXA
  417.                } else if (c != 0x37 ) {
  418. #else
  419.                } else if (c != 4) {
  420. #endif
  421. #endif
  422.                   (void)putc(c, bitfile) ;
  423.                }
  424.                prevc = c ;
  425. /* begin DOS EPS code */
  426.                if (doseps && (ftell(f)>=dosepsend))
  427.                   break;      /* stop at end of DOS EPS PostScript section */
  428. /* end DOS EPS code */
  429.                c = getc(f) ;
  430.                if (c == EOF)
  431.                   break ;
  432.                else if (c == '\r')
  433.                   c = '\n' ;
  434.             }
  435.          }
  436.       }
  437.       if (prevc != '\n')
  438.          (void)putc('\n', bitfile) ;
  439.       linepos = 0 ;
  440. #ifndef VMCMS
  441. #ifndef MVSXA
  442. #ifndef VMS
  443. #ifndef MSDOS
  444. #ifndef ATARIST
  445. #ifndef __THINK__
  446.       if (infigure == 2)
  447. #ifdef OS2
  448.          {
  449.             if (_osmode == OS2_MODE)
  450.                (void)pclose(f) ;
  451.          }
  452. #else
  453.          (void)pclose(f) ;
  454. #endif
  455.       else
  456. #endif
  457. #endif
  458. #endif
  459. #endif
  460. #endif
  461. #endif
  462.          (void)fclose(f) ;
  463.       if (!disablecomments)
  464.          if (infigure)
  465.             (void)fprintf(bitfile, "%%%%EndDocument\n") ;
  466.          else if (infont)
  467.             (void)fprintf(bitfile, "%%%%EndFont\n") ;
  468.          else
  469.             (void)fprintf(bitfile, "%%%%EndProcSet\n") ;
  470.    }
  471. }
  472.  
  473. /*
  474.  *   For included PostScript graphics, we use the above routine, but
  475.  *   with no fatal error message.
  476.  */
  477. void figcopyfile(s, systemtype)
  478. char *s ;
  479. int systemtype ;
  480. {
  481.    infigure = systemtype ? 2 : 1 ;
  482.    copyfile(s) ;
  483.    infigure = 0 ;
  484. }
  485. /*
  486.  *   This next routine writes out a `special' character.  In this case,
  487.  *   we simply put it out, since any special character terminates the
  488.  *   preceding token.
  489.  */
  490. void
  491. specialout(c)
  492.         char c ;
  493. {
  494.    if (linepos >= LINELENGTH) {
  495.       (void)putc('\n', bitfile) ;
  496.       linepos = 0 ;
  497.    }
  498.    (void)putc(c, bitfile) ;
  499.    linepos++ ;
  500.    lastspecial = 1 ;
  501. }
  502.  
  503. void
  504. stringend()
  505. {
  506.    if (linepos + instring >= LINELENGTH - 2) {
  507.       (void)putc('\n', bitfile) ;
  508.       linepos = 0 ;
  509.    }
  510.    (void)putc('(', bitfile) ;
  511.    *strbp = 0 ;
  512.    (void)fputs(strbuffer, bitfile) ;
  513.    (void)putc(')', bitfile) ;
  514.    linepos += instring + 2 ;
  515.    lastspecial = 1 ;
  516.    instring = 0 ;
  517.    strbp = strbuffer ;
  518. }
  519.  
  520. void
  521. scout(c)   /* string character out */
  522.         char c ;
  523. {
  524. /*
  525.  *   Is there room in the buffer?  LINELENGTH-6 is used because we
  526.  *   need room for (, ), and a possible four-byte string \000, for
  527.  *   instance.  If it is too long, we send out the string.
  528.  */
  529.    if (instring > LINELENGTH-6) {
  530.       stringend() ;
  531.       chrcmd('p') ;
  532.    }
  533. /*  changed next line to hex representation for VMCMS port
  534.    if (c<' ' || c > 126 || c=='%' ) {
  535. */
  536.    if ( c<0x20 || c>= 0x7F || c==0x25 ) {
  537.       *strbp++ = '\\' ;
  538.       *strbp++ = '0' + ((c >> 6) & 3) ;
  539.       *strbp++ = '0' + ((c >> 3) & 7) ;
  540.       *strbp++ = '0' + (c & 7) ;
  541.       instring += 4 ;
  542.    } else {
  543. #ifdef VMCMS
  544.      c = ascii2ebcdic[c];
  545. #else
  546. #ifdef MVSXA
  547.      c = ascii2ebcdic[c];
  548. #endif
  549. #endif
  550.      if (c == '(' || c == ')' || c == '\\') {
  551.        *strbp++ = '\\' ;
  552.        *strbp++ = c ;
  553.        instring += 2 ;
  554.      } else {
  555.        *strbp++ = c ;
  556.        instring++ ;
  557.      }
  558.    }
  559. }
  560.  
  561. void
  562. cmdout(s)
  563.         char *s ;
  564. {
  565.    int l ;
  566.  
  567.    /* hack added by dorab */
  568.    if (instring) {
  569.         stringend();
  570.         chrcmd('p');
  571.    }
  572.    l = strlen(s) ;
  573.    if ((! lastspecial && linepos >= LINELENGTH - 20) ||
  574.            linepos + l >= LINELENGTH) {
  575.       (void)putc('\n', bitfile) ;
  576.       linepos = 0 ;
  577.       lastspecial = 1 ;
  578.    } else if (! lastspecial) {
  579.       (void)putc(' ', bitfile) ;
  580.       linepos++ ;
  581.    }
  582.    (void)fputs(s, bitfile) ;
  583.    linepos += l ;
  584.    lastspecial = 0 ;
  585. }
  586.  
  587.  
  588. static void
  589. chrcmd(c)
  590.         char c ;
  591. {
  592.    if ((! lastspecial && linepos >= LINELENGTH - 20) ||
  593.        linepos + 2 > LINELENGTH) {
  594.       (void)putc('\n', bitfile) ;
  595.       linepos = 0 ;
  596.       lastspecial = 1 ;
  597.    } else if (! lastspecial) {
  598.       (void)putc(' ', bitfile) ;
  599.       linepos++ ;
  600.    }
  601.    (void)putc(c, bitfile) ;
  602.    linepos++ ;
  603.    lastspecial = 0 ;
  604. }
  605.  
  606. void
  607. floatout(n)
  608.         float n ;
  609. {
  610.    char buf[20] ;
  611.  
  612.    (void)sprintf(buf, "%.2f", n) ;
  613.    cmdout(buf) ;
  614. }
  615.  
  616. void
  617. numout(n)
  618.         integer n ;
  619. {
  620. #ifdef AMIGA
  621.    char buf[12] ;
  622. #else
  623.    char buf[10] ;
  624. #endif
  625.  
  626. #ifdef SHORTINT
  627.    (void)sprintf(buf, "%ld", n) ;
  628. #else
  629.    (void)sprintf(buf, "%d", n) ;
  630. #endif
  631.    cmdout(buf) ;
  632. }
  633.  
  634. void
  635. mhexout(p, len)
  636. register unsigned char *p ;
  637. register long len ;
  638. {
  639.    register char *hexchar = hxdata ;
  640.    register int n, k ;
  641.  
  642.    while (len > 0) {
  643.       if (linepos > LINELENGTH - 2) {
  644.          (void)putc('\n', bitfile) ;
  645.          linepos = 0 ;
  646.       }
  647.       k = (LINELENGTH - linepos) >> 1 ;
  648.       if (k > len)
  649.          k = len ;
  650.       len -= k ;
  651.       linepos += (k << 1) ;
  652.       while (k--) {
  653.          n = *p++ ;
  654.          (void)putc(hexchar[n >> 4], bitfile) ;
  655.          (void)putc(hexchar[n & 15], bitfile) ;
  656.       }
  657.    }
  658. }
  659.  
  660. void
  661. fontout(n)
  662.         int n ;
  663. {
  664.    char buf[6] ;
  665.  
  666.    if (instring) {
  667.       stringend() ;
  668.       chrcmd('p') ;
  669.    }
  670.    makepsname(buf, n) ;
  671.    cmdout(buf) ;
  672. }
  673.  
  674. void
  675. hvpos()
  676. {
  677.    if (rvv != vv) {
  678.       if (instring) {
  679.          stringend() ;
  680.          numout(hh) ;
  681.          numout(vv) ;
  682.          chrcmd('y') ;
  683.       } else if (rhh != hh) {
  684.          numout(hh) ;
  685.          numout(vv) ;
  686.          chrcmd('a') ;
  687.       } else { /* hard to get this case, but it's there when you need it! */
  688.          numout(vv - rvv) ;
  689.          chrcmd('x') ;
  690.       }
  691.       rvv = vv ;
  692.    } else if (rhh != hh) {
  693.       if (instring) {
  694.          stringend() ;
  695.          if (hh - rhh < 5 && rhh - hh < 5) {
  696. #ifdef VMCMS /*  should replace 'p' in non-VMCMS line as well */
  697.             chrcmd(ascii2ebcdic[(char)(112 + hh - rhh)]) ;
  698. #else
  699. #ifdef MVSXA /*  should replace 'p' in non-MVSXA line as well */
  700.             chrcmd(ascii2ebcdic[(char)(112 + hh - rhh)]) ;
  701. #else
  702.             chrcmd((char)('p' + hh - rhh)) ;
  703. #endif
  704. #endif
  705.          } else if (hh - rhh < d + 5 && rhh - hh < 5 - d) {
  706. #ifdef VMCMS /* should replace 'g' in non-VMCMS line as well  */
  707.             chrcmd(ascii2ebcdic[(char)(103 + hh - rhh - d)]) ;
  708. #else
  709. #ifdef MVSXA /* should replace 'g' in non-MVSXA line as well  */
  710.             chrcmd(ascii2ebcdic[(char)(103 + hh - rhh - d)]) ;
  711. #else
  712.             chrcmd((char)('g' + hh - rhh - d)) ;
  713. #endif
  714. #endif
  715.             d = hh - rhh ;
  716.          } else {
  717.             numout(hh - rhh) ;
  718.             chrcmd('b') ;
  719.             d = hh - rhh ;
  720.          }
  721.       } else {
  722.          numout(hh - rhh) ;
  723.          chrcmd('w') ;
  724.       }
  725.    }
  726.    rhh = hh ;
  727. }
  728.  
  729. /*
  730.  *   initprinter opens the bitfile and writes the initialization sequence
  731.  *   to it.
  732.  */
  733. void newline()
  734. {
  735.    if (linepos != 0) {
  736.       (void)fprintf(bitfile, "\n") ;
  737.       linepos = 0 ;
  738.    }
  739.    lastspecial = 1 ;
  740. }
  741.  
  742. void
  743. nlcmdout(s)
  744.         char *s ;
  745. {
  746.    newline() ;
  747.    cmdout(s) ;
  748.    newline() ;
  749. }
  750. /*
  751.  *   Is the dimension close enough for a match?  We use a quarter inch
  752.  *   as a match; this is 65536*72.27/4 or 1,184,072 scaled points.
  753.  */
  754. static int indelta(i)
  755. integer i ;
  756. {
  757.    if (i < 0)
  758.       i = -i ;
  759.    return (i <= 1184072) ;
  760. }
  761. /*
  762.  *   A case-irrelevant string compare.
  763.  */
  764. int mlower(c)
  765. int c ;
  766. {
  767.    if ('A' <= c && c <= 'Z')
  768.       return c - 'A' + 'a' ;
  769.    else
  770.       return c ;
  771. }
  772. int ncstrcmp(a, b)
  773. char *a, *b ;
  774. {
  775.    while (*a && (*a == *b ||
  776.                        mlower(*a) == mlower(*b)))
  777.       a++, b++ ;
  778.    if (*a == 0 && *b == 0)
  779.       return 0 ;
  780.    else
  781.       return 1 ;
  782. }
  783. /*
  784.  *   Find the paper size.
  785.  */
  786. void findpapersize() {
  787.    if (finpapsiz == 0) {
  788.       struct papsiz *ps ;
  789.  
  790.       if (tryepsf && !landscape) {
  791.          finpapsiz = &defpapsiz ;
  792.          hpapersize = defpapsiz.xsize ;
  793.          vpapersize = defpapsiz.ysize ;
  794.          return ;
  795.       }
  796.       if (cropmarks) {
  797. /*
  798.  *   If user wanted crop marks, we increase the size of the page by
  799.  *   a half inch all around.
  800.  */
  801.          if (hpapersize == 0 || vpapersize == 0) {
  802.             error(
  803.  "warning: -k crop marks wanted, but no paper size specified; using default") ;
  804.             if (landscape) {
  805.                hpapersize = defpapsiz.ysize ;
  806.                vpapersize = defpapsiz.xsize ;
  807.             } else {
  808.                hpapersize = defpapsiz.xsize ;
  809.                vpapersize = defpapsiz.ysize ;
  810.             }
  811.          }
  812.          hpapersize += 2368143L ;
  813.          vpapersize += 2368143L ;
  814.          add_header(CROPHEADER) ;
  815.       }
  816.       if (paperfmt && *paperfmt) {
  817.          for (ps = papsizes; ps; ps = ps->next)
  818.             if (ncstrcmp(paperfmt, ps->name)==0)
  819.                finpapsiz = ps ;
  820.          if (finpapsiz == 0)
  821.             error("no match for papersize") ;
  822.       }
  823.       if (finpapsiz == 0 && hpapersize > 0 && vpapersize > 0) {
  824.          for (ps=papsizes; ps; ps = ps->next) {
  825.             if (indelta(ps->xsize-hpapersize) &&
  826.                 indelta(ps->ysize-vpapersize)) {
  827.                landscape = 0 ;
  828.                break ;
  829.             }
  830.          }
  831.          if (ps == 0) {
  832.             for (ps=papsizes; ps; ps = ps->next) {
  833.                if (indelta(ps->ysize-hpapersize) &&
  834.                    indelta(ps->xsize-vpapersize)) {
  835.                   landscape = 1 ;
  836.                   break ;
  837.                }
  838.             }
  839.             if (ps == 0) {
  840.                for (ps=papsizes; ps; ps = ps->next) {
  841.                   if (ps->ysize == 0 && ps->xsize == 0)
  842.                      break ;
  843.                }
  844.                if (ps == 0) {
  845.                   landscape = (hpapersize > vpapersize) ;
  846.                   error(
  847.                     "no match for special paper size found; using default") ;
  848.                }
  849.             }
  850.          }
  851.          finpapsiz = ps ;
  852.       }
  853.       if (finpapsiz == 0) {
  854.          if (papsizes)
  855.             finpapsiz = papsizes ;
  856.          else
  857.             finpapsiz = &defpapsiz ;
  858. /*
  859.  *   But change xsize/ysize to match so bounding box works.
  860.  */
  861.          if (hpapersize && vpapersize) {
  862.             if (landscape) {
  863.                finpapsiz->ysize = hpapersize ;
  864.                finpapsiz->xsize = vpapersize ;
  865.             } else {
  866.                finpapsiz->xsize = hpapersize ;
  867.                finpapsiz->ysize = vpapersize ;
  868.             }
  869.          }
  870.       }
  871. /*
  872.  *   Here, there was no papersize special.  We set the paper size from
  873.  *   the selected paper format.  If the selected paper format has no
  874.  *   sizes, we use the defaults.
  875.  */
  876.       if (hpapersize == 0 || vpapersize == 0) {
  877.          if (finpapsiz->xsize == 0 || finpapsiz->ysize == 0) {
  878.             finpapsiz->xsize = defpapsiz.xsize ;
  879.             finpapsiz->ysize = defpapsiz.ysize ;
  880.          }
  881.          if (landscape) {
  882.             vpapersize = finpapsiz->xsize ;
  883.             hpapersize = finpapsiz->ysize ;
  884.          } else {
  885.             hpapersize = finpapsiz->xsize ;
  886.             vpapersize = finpapsiz->ysize ;
  887.          }
  888. /*
  889.  *   Here, there was a papersize special, but the selected paper
  890.  *   format has 0 0 for sizes.  We set the sizes here so that the
  891.  *   bounding box works.
  892.  */
  893.       } else if (finpapsiz->xsize == 0 || finpapsiz->ysize == 0) {
  894.          finpapsiz->xsize = hpapersize ;
  895.          finpapsiz->ysize = vpapersize ;
  896. /*
  897.  *   Here, the user specified a size with -t, and there was a
  898.  *   papersize special, and its sizes were greater than zero.
  899.  *   We make sure the sizes are okay.  Note that the user must have
  900.  *   specified landscape if this is desired.
  901.  */
  902.       } else if (paperfmt && *paperfmt) {
  903.          if (landscape) {
  904.             if (!indelta(vpapersize - finpapsiz->xsize) ||
  905.                 !indelta(hpapersize - finpapsiz->ysize)) {
  906.                if (vpapersize > finpapsiz->xsize ||
  907.                    hpapersize > finpapsiz->ysize)
  908.                   error("warning: -t selected paper may be too small") ;
  909.                else
  910.                   error("note: -t selected paper may be too large") ;
  911.             }
  912.          } else {
  913.             if (!indelta(hpapersize - finpapsiz->xsize) ||
  914.                 !indelta(vpapersize - finpapsiz->ysize)) {
  915.                if (hpapersize > finpapsiz->xsize ||
  916.                    vpapersize > finpapsiz->ysize)
  917.                   error("warning: -t selected paper may be too small") ;
  918.                else
  919.                   error("note: -t selected paper may be too large") ;
  920.             }
  921.          }
  922.       }
  923.    }
  924. }
  925. /*
  926.  *   Convert scaled points to PostScript points.  This is the same
  927.  *   as return (i * 72 / (65536 * 72.27)), which is the same as
  928.  *   dividing by 65781.76, but we want to round up.
  929.  */
  930. static int topoints(i)
  931. integer i ;
  932. {
  933.    i += 65780L ;
  934.    return (i / 6578176L)*100 + (i % 6578176) * 100 / 6578176 ;
  935. }
  936. /*
  937.  *   Send out the special paper stuff.  If `hed' is non-zero, only
  938.  *   send out lines starting with `!' else send all other lines out.
  939.  */
  940. void paperspec(s, hed)
  941. char *s ;
  942. int hed ;
  943. {
  944.    int sendit ;
  945.  
  946.    while (*s) {
  947.       s++ ;
  948.       if (*s == '\0')
  949.          return ;
  950.       if (*s == '!') {
  951.          s++ ;
  952.          while (*s == ' ') s++ ;
  953.          sendit = hed ;
  954.       } else
  955.          sendit = ! hed ;
  956.       if (sendit) {
  957.          while (*s && *s != '\n')
  958. #if defined(AMIGA) && defined(__SASC)
  959.             (void)fputc(*s++, bitfile) ; /* default putc is a macro on SAS/C */
  960. #else
  961.             (void)putc(*s++, bitfile) ;
  962. #endif
  963.          putc('\n', bitfile) ;
  964.       } else {
  965.          while (*s && *s != '\n')
  966.             s++ ;
  967.       }
  968.    }
  969. }
  970. char *epsftest() {
  971.    if (tryepsf && totalpages == 1 && paperfmt == 0 && *iname) {
  972.       findbb() ;
  973.       return nextstring ;
  974.    }
  975.    return 0 ;
  976. }
  977. static char *isepsf = 0 ;
  978. static int endprologsent ;
  979. void
  980. initprinter(n)
  981. int n ; /* number of pages if greater than 0 */
  982. {
  983.    void tell_needed_fonts() ;
  984.  
  985.    n *= pagecopies * collatedcopies ;
  986.    if (*oname != 0) {
  987. /*
  988.  *   We check to see if the first character is a exclamation
  989.  *   point, and popen if so.
  990.  */
  991.       if (*oname == '!' || *oname == '|') {
  992. #ifdef MSDOS
  993.             error("! can't open output pipe") ;
  994. #else
  995. #ifdef VMS
  996.             error("! can't open output pipe") ;
  997. #else
  998. #ifdef VMCMS
  999.             error("! can't open output pipe") ;
  1000. #else
  1001. #ifdef MVSXA
  1002.             error("! can't open output pipe") ;
  1003. #else
  1004. #ifdef __THINK__
  1005.             error("! can't open output pipe") ;
  1006. #else
  1007. #ifdef ATARIST
  1008.             error("! can't open output pipe") ;
  1009. #else
  1010. #ifdef OS2
  1011.          if (_osmode != OS2_MODE) {
  1012.             error("! can't open output pipe") ;
  1013.          } else {
  1014. #endif
  1015.          if (secure || (bitfile=popen(oname+1, "w"))==NULL)
  1016.             error("! couldn't open output pipe") ;
  1017.          else
  1018.             popened = 1 ;
  1019. #ifdef OS2
  1020.          }
  1021. #endif
  1022. #endif
  1023. #endif
  1024. #endif
  1025. #endif
  1026. #endif
  1027. #endif
  1028.       } else {
  1029.          if ((bitfile=fopen(oname,"w"))==NULL)
  1030.             error("! couldn't open PostScript file") ;
  1031.       }
  1032.    } else {
  1033.       bitfile = stdout ;
  1034.    }
  1035.    findpapersize() ;
  1036.    if (disablecomments)
  1037.       (void)fprintf(bitfile,
  1038.              "%%!PS (but not EPSF; comments have been disabled)\n") ;
  1039.    else {
  1040.       if (multiplesects)
  1041.          (void)fprintf(bitfile,
  1042.              "%%!PS (but not EPSF because of memory limits)\n") ;
  1043.       else {
  1044.          isepsf = epsftest() ;
  1045.          if (isepsf)
  1046.             (void)fprintf(bitfile, "%%!PS-Adobe-2.0 EPSF-2.0\n") ;
  1047.          else
  1048.             (void)fprintf(bitfile, "%%!PS-Adobe-2.0\n") ;
  1049.       }
  1050.       if (tryepsf && isepsf == 0)
  1051.          error("We tried, but couldn't make it EPSF.") ;
  1052.       (void)fprintf(bitfile, "%%%%Creator: %s", banner + 8) ;
  1053.       if (*iname)
  1054.          (void)fprintf(bitfile, "%%%%Title: %s\n", iname) ;
  1055. #ifdef CREATIONDATE
  1056.       jobtime=time(0);
  1057.       (void)fprintf(bitfile, "%%%%CreationDate: %s",
  1058.                                  asctime(localtime(&jobtime))) ;
  1059. #endif
  1060.       if (! isepsf) {
  1061. /*
  1062.  *   Normally, we wouldn't want to add that second field
  1063.  *   indicating that the page order is reversed, as per page
  1064.  *   644 of the Red book.  But we have to, for many existing
  1065.  *   spoolers.
  1066.  */
  1067.         (void)fprintf(bitfile, "%%%%Pages: %d%s\n", (n ? n : totalpages),
  1068.                                                     (reverse?" -1":"")) ;
  1069.         (void)fprintf(bitfile, "%%%%PageOrder: %sscend\n", reverse?"De":"A");
  1070.       }
  1071.       if (landscape) {
  1072.          fprintf(bitfile, "%%%%Orientation: Landscape\n") ;
  1073.          fprintf(bitfile, "%%%%BoundingBox: 0 0 %d %d\n",
  1074.               topoints(finpapsiz->xsize), topoints(finpapsiz->ysize)) ;
  1075.       } else if (isepsf)
  1076.          fprintf(bitfile, "%%%%BoundingBox: %s\n", isepsf) ;
  1077.       else
  1078.          fprintf(bitfile, "%%%%BoundingBox: 0 0 %d %d\n",
  1079.               topoints(finpapsiz->xsize), topoints(finpapsiz->ysize)) ;
  1080.       tell_needed_fonts() ;
  1081.       paperspec(finpapsiz->specdat, 1) ;
  1082.       (void)fprintf(bitfile, "%%%%EndComments\n") ;
  1083.    }
  1084.    {
  1085.       int i, len ;
  1086.       char *p ;
  1087.  
  1088. /*
  1089.  *   Here, too, we have to be careful not to exceed the line length
  1090.  *   limitation, if possible.
  1091.  */
  1092.       (void)fprintf(bitfile, "%%DVIPSCommandLine:") ;
  1093.       len = 18 ;
  1094.       for (i=0; i<gargc; i++) {
  1095.          p = gargv[i] ;
  1096.          while (*p > ' ')
  1097.             p++ ;
  1098.          if (*p)
  1099.             len += 2 ;
  1100.          len += strlen(gargv[i]) + 1 ;
  1101.          if (len > LINELENGTH) {
  1102.             (void)fprintf(bitfile, "\n%%+") ;
  1103.             len = strlen(gargv[i]) + 3 ;
  1104.             if (*p)
  1105.                len += 2 ;
  1106.          }
  1107.          (void)fprintf(bitfile, (*p ? " \"%s\"" : " %s"), gargv[i]) ;
  1108.       }
  1109.       (void)fprintf(bitfile, "\n%%DVIPSParameters: dpi=%d", actualdpi) ;
  1110.       if (actualdpi != vactualdpi)
  1111.          (void)fprintf(bitfile, "x%d", vactualdpi) ;
  1112.       if (compressed)
  1113.          (void)fprintf(bitfile, ", compressed") ;
  1114.       if (removecomments)
  1115.          (void)fprintf(bitfile, ", comments removed") ;
  1116.       (void)fputc('\n', bitfile) ;
  1117.    }
  1118. #ifdef VMCMS  /* convert preamblecomment to ebcdic so we can read it */
  1119.    {
  1120.       int i ;
  1121.       for ( i=0 ; preamblecomment[i] ; i++ )
  1122.           preamblecomment[i] = ascii2ebcdic[preamblecomment[i]] ;
  1123.    }
  1124. #else
  1125. #ifdef MVSXA   /* IBM: MVS/XA */
  1126.    {
  1127.       int i ;
  1128.       for ( i=0 ; preamblecomment[i] ; i++ )
  1129.           preamblecomment[i] = ascii2ebcdic[preamblecomment[i]] ;
  1130.    }
  1131. #endif  /* VMCMS */
  1132. #endif
  1133.    (void)fprintf(bitfile, "%%DVIPSSource: %s\n", preamblecomment) ;
  1134.    linepos = 0 ;
  1135.    endprologsent = 0 ;
  1136.    if (safetyenclose)
  1137.       (void)fprintf(bitfile, "/SafetyEnclosure save def\n") ;
  1138.    if (! headers_off)
  1139.       send_headers() ;
  1140. }
  1141. void setup() {
  1142.    newline() ;
  1143.    if (endprologsent == 0 && !disablecomments) {
  1144.       (void)fprintf(bitfile, "%%%%EndProlog\n") ;
  1145.       (void)fprintf(bitfile, "%%%%BeginSetup\n") ;
  1146.       if (vactualdpi == actualdpi)
  1147.          (void)fprintf(bitfile, "%%%%Feature: *Resolution %ddpi\n",
  1148.                                            actualdpi) ;
  1149.       else
  1150.          (void)fprintf(bitfile, "%%%%Feature: *Resolution %dx%ddpi\n",
  1151.                                            actualdpi, vactualdpi) ;
  1152.       if (multiplesects && *(finpapsiz->specdat)) {
  1153.          (void)fprintf(bitfile, "TeXDict begin\n") ;
  1154.          paperspec(finpapsiz->specdat, 0) ;
  1155.          (void)fprintf(bitfile, "end\n") ;
  1156.       }
  1157.       if (manualfeed)
  1158.          (void)fprintf(bitfile, "%%%%Feature: *ManualFeed True\n") ;
  1159.       if (multiplesects)
  1160.          (void)fprintf(bitfile, "%%%%EndSetup\n") ;
  1161.    }
  1162.    if (multiplesects && ! disablecomments)
  1163.       (void)fprintf(bitfile, "%%DVIPSBeginSection\n") ;
  1164.    cmdout("TeXDict") ;
  1165.    cmdout("begin") ;
  1166.    if (endprologsent || disablecomments || multiplesects == 0) {
  1167.       (void)fprintf(bitfile, "\n") ;
  1168.       paperspec(finpapsiz->specdat, 0) ;
  1169.    }
  1170.    if (manualfeed) cmdout("@manualfeed") ;
  1171.    if (landscape) cmdout("@landscape") ;
  1172.    if (numcopies != 1) {
  1173.       numout((integer)numcopies) ;
  1174.       cmdout("@copies") ;
  1175.    }
  1176.    if (endprologsent == 0 && !disablecomments) {
  1177.       newline() ;
  1178.       endprologsent = 1 ;
  1179.       if (! multiplesects)
  1180.          (void)fprintf(bitfile, "%%%%EndSetup\n") ;
  1181.    }
  1182. }
  1183. /*
  1184.  *   cleanprinter is the antithesis of the above routine.
  1185.  */
  1186. void
  1187. cleanprinter()
  1188. {
  1189.    (void)fprintf(bitfile, "\n") ;
  1190.    (void)fprintf(bitfile, "userdict /end-hook known{end-hook}if\n") ;
  1191.    if (safetyenclose)
  1192.       (void)fprintf(bitfile, "SafetyEnclosure restore\n") ;
  1193.    if (!disablecomments)
  1194.       (void)fprintf(bitfile, "%%%%EOF\n") ;
  1195.    if (sendcontrolD)
  1196.       (void)putc(4, bitfile) ;
  1197.    if (ferror(bitfile))
  1198.       error("Problems with file writing; probably disk full.") ;
  1199. #ifndef MSDOS
  1200. #ifndef VMS
  1201. #ifndef MVSXA
  1202. #ifndef VMCMS
  1203. #ifndef __THINK__
  1204. #ifndef ATARIST
  1205. #ifdef OS2
  1206.    if (_osmode == OS2_MODE)
  1207. #endif
  1208.       if (popened)
  1209.          (void)pclose(bitfile) ;
  1210. #endif
  1211. #endif
  1212. #endif
  1213. #endif
  1214. #endif
  1215. #endif
  1216.    if (popened == 0)
  1217.       (void)fclose(bitfile) ;
  1218.    bitfile = NULL ;
  1219. }
  1220.  
  1221. /* this tells dvips that it has no clue where it is. */
  1222. static int thispage = 0 ;
  1223. static integer rulex, ruley ;
  1224. void psflush() {
  1225.    rulex = ruley = rhh = rvv = -314159265 ;
  1226.    lastfont = -1 ;
  1227. }
  1228. /*
  1229.  *   pageinit initializes the output variables.
  1230.  */
  1231. void
  1232. pageinit()
  1233. {
  1234.    psflush() ;
  1235.    newline() ;
  1236.    thispage++ ;
  1237.    if (!disablecomments)
  1238.       if (multiplesects)
  1239. #ifdef SHORTINT
  1240.          (void)fprintf(bitfile, "%%DVIPSSectionPage: %ld\n", pagenum) ;
  1241.       else if (! isepsf)
  1242.          (void)fprintf(bitfile, "%%%%Page: %ld %d\n", pagenum, thispage) ;
  1243. #else
  1244.          (void)fprintf(bitfile, "%%DVIPSSectionPage: %d\n", pagenum) ;
  1245.       else if (! isepsf)
  1246.          (void)fprintf(bitfile, "%%%%Page: %d %d\n", pagenum, thispage) ;
  1247. #endif
  1248.    linepos = 0 ;
  1249.    numout((integer)pagenum) ;
  1250.    numout((integer)thispage-1) ;
  1251.    cmdout("bop") ;
  1252.    d = 0 ;
  1253. }
  1254.  
  1255.  
  1256.  
  1257. /*
  1258.  *   This routine ends a page.
  1259.  */
  1260. void
  1261. pageend()
  1262. {
  1263.    if (instring) {
  1264.       stringend() ;
  1265.       chrcmd('p') ;
  1266.    }
  1267.    cmdout("eop") ;
  1268. }
  1269.  
  1270. /*
  1271.  *   drawrule draws a rule at the specified position.
  1272.  *   It does nothing to save/restore the current position,
  1273.  *   or even draw the current string.  (Rules are normally
  1274.  *   set below the baseline anyway, so this saves us on
  1275.  *   output size almost always.)
  1276.  */
  1277. void
  1278. drawrule(rw, rh)
  1279.         integer rw, rh ;
  1280. {
  1281.    numout((integer)hh) ;
  1282.    numout((integer)vv) ;
  1283.    if (rw == rulex && rh == ruley)
  1284.       chrcmd('V') ;
  1285.    else {
  1286.       numout((integer)rw) ;
  1287.       numout((integer)rh) ;
  1288.       chrcmd('v') ;
  1289.       rulex = rw ;
  1290.       ruley = rh ;
  1291.    }
  1292. }
  1293.  
  1294. /*
  1295.  *   drawchar draws a character at the specified position.
  1296.  */
  1297. void
  1298. drawchar(c, cc)
  1299.         chardesctype *c ;
  1300.         int cc ;
  1301. {
  1302.    hvpos() ;
  1303.    if (lastfont != curfnt->psname) {
  1304.       fontout((int)curfnt->psname) ;
  1305.       lastfont = curfnt->psname ;
  1306.    }
  1307.    scout(cc) ;
  1308.    rhh = hh + c->pixelwidth ; /* rvv = rv */
  1309. }
  1310. /*
  1311.  *   This routine sends out the document fonts comment.
  1312.  */
  1313. void tell_needed_fonts() {
  1314.    struct header_list *hl = ps_fonts_used ;
  1315.    char *q ;
  1316.    int roomleft = -1 ;
  1317.    extern char *get_name() ;
  1318.  
  1319.    if (hl == 0)
  1320.       return ;
  1321.    while (0 != (q=get_name(&hl))) {
  1322.       if ((int)strlen(q) >= roomleft) {
  1323.          if (roomleft != -1) {
  1324.             fprintf(bitfile, "\n%%%%+") ;
  1325.             roomleft = LINELENGTH - 3 ;
  1326.          } else {
  1327.             fprintf(bitfile, "%%%%DocumentFonts:") ;
  1328.             roomleft = LINELENGTH - 16 ;
  1329.          }
  1330.       }
  1331.       fprintf(bitfile, " %s", q) ;
  1332.       roomleft -= strlen(q) + 1 ;
  1333.    }
  1334.    fprintf(bitfile, "\n") ;
  1335. }
  1336.