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