home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PRINTING / DVIPS54.ZIP / DVIPS / DVIPS.C < prev    next >
C/C++ Source or Header  |  1990-11-25  |  18KB  |  559 lines

  1. /*
  2.  *   This is the main routine.
  3.  */
  4. #ifndef DEFRES
  5. #define DEFRES (300)
  6. #endif
  7. #ifndef DEFPFMT
  8. #define DEFPFMT "letter"
  9. #endif
  10.  
  11. #include "structures.h" /* The copyright notice in that file is included too! */
  12. /*
  13.  *   First we define some globals.
  14.  */
  15. fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
  16. fontdesctype *curfnt ;        /* the currently selected font */
  17. sectiontype *sections ;       /* sections to process document in */
  18. Boolean manualfeed ;          /* manual feed? */
  19. Boolean compressed ;          /* compressed? */
  20. Boolean safetyenclose ;       /* enclose in save/restore for stupid spoolers? */
  21. Boolean removecomments ;      /* remove comments from included PS? */
  22. Boolean nosmallchars ;        /* disable small char optimization for X4045? */
  23. int collatedcopies = 1 ;      /* how many collated copies? */
  24. int sectioncopies = 1 ;       /* how many times to repeat each section? */
  25. shalfword linepos = 0 ;       /* where are we on the line being output? */
  26. integer maxpages ;            /* the maximum number of pages */
  27. Boolean notfirst, notlast ;   /* true if a first page was specified */
  28. Boolean sendcontrolD ;        /* should we send a control D at end? */
  29. integer firstpage ;           /* the number of the first page if specified */
  30. integer lastpage ;
  31. integer firstseq ;
  32. integer lastseq ;
  33. int numcopies ;               /* number of copies of each page to print */
  34. char *oname ;                 /* output file name */
  35. char *iname ;                 /* dvi file name */
  36. char *strings ;               /* strings for program */
  37. char *nextstring, *maxstring ; /* string pointers */
  38. FILE *dvifile, *bitfile ;     /* dvi and output files */
  39. quarterword *curpos ;         /* current position in virtual character packet */
  40. quarterword *curlim ;         /* final byte in virtual character packet */
  41. fontmaptype *ffont ;          /* first font in current frame */
  42. real conv ;                   /* conversion ratio, pixels per DVI unit */
  43. real vconv ;                  /* conversion ratio, pixels per DVI unit */
  44. real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
  45. integer mag ;                 /* the magnification of this document */
  46. Boolean overridemag ;         /* substitute for mag value in DVI file? */
  47. int actualdpi = DEFRES ;      /* the actual resolution of the printer */
  48. int vactualdpi = DEFRES ;      /* the actual resolution of the printer */
  49. int maxdrift ;                /* max pixels away from true rounded position */
  50. int vmaxdrift ;                /* max pixels away from true rounded position */
  51. char *paperfmt = DEFPFMT ;    /* paper format */
  52. int landscape = 0 ;           /* landscape mode */
  53. integer fontmem ;             /* memory remaining in printer */
  54. integer pagecount ;           /* page counter for the sections */
  55. integer pagenum ;             /* the page number we currently look at */
  56. long bytesleft ;              /* number of bytes left in raster */
  57. quarterword *raster ;         /* area for raster manipulations */
  58. integer hh, vv ;              /* horizontal and vertical pixel positions */
  59. char *tfmpath = TFMPATH ;     /* pointer to directories for tfm files */
  60. char *pkpath = PKPATH ;       /* pointer to directories for pk files */
  61. char *vfpath = VFPATH ;       /* pointer to directories for vf files */
  62. char *figpath = FIGPATH ;     /* pointer to directories for figure files */
  63. char *headerpath = HEADERPATH ; /* pointer to directories for header files */
  64. char *configpath = CONFIGPATH;  /* where to find config files */
  65. #ifdef SEARCH_SUBDIRECTORIES
  66. char *fontsubdirpath = FONTSUBDIRPATH ;
  67. #endif
  68. #ifdef FONTLIB
  69. char *flipath = FLIPATH ;     /* pointer to directories for fli files */
  70. char *fliname = FLINAME ;     /* pointer to names of fli files */
  71. #endif
  72. integer swmem ;               /* font memory in the PostScript printer */
  73. int quiet ;                   /* should we only print errors to stderr? */
  74. int filter ;                  /* act as filter default output to stdout,
  75.                                                default input to stdin? */
  76. int prettycolumn ;            /* the column we are at when running pretty */
  77. int totalpages = 0 ;          /* total number of pages */
  78. Boolean reverse ;             /* are we going reverse? */
  79. Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
  80. Boolean usesspecial ;         /* do we use \special? */
  81. Boolean headers_off ;         /* do we send headers or not? */
  82. char *headerfile ;            /* default header file */
  83. char *warningmsg ;            /* a message to write, if set in config file */
  84. Boolean multiplesects ;       /* more than one section? */
  85. Boolean disablecomments ;     /* should we suppress any EPSF comments? */
  86. char *printer ;               /* what printer to send this to? */
  87. char *mfmode ;                /* default MF mode */
  88. frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
  89. fontdesctype *baseFonts[256] ; /* base fonts for dvi file */
  90. integer pagecost;               /* memory used on the page being prescanned */
  91. int delchar;                    /* characters to delete from prescanned page */
  92. integer fsizetol;               /* max dvi units error for psfile font sizes */
  93. Boolean includesfonts;          /* are fonts used in included psfiles? */
  94. fontdesctype *fonthd[MAXFONTHD];/* list headers for included fonts of 1 name */
  95. int nextfonthd;                 /* next unused fonthd[] index */
  96. char xdig[256];                 /* table for reading hexadecimal digits */
  97. char banner[] = BANNER ;        /* our startup message */
  98.  
  99. #ifdef DEBUG
  100. integer debug_flag = 0;
  101. #endif /* DEBUG */
  102. /*
  103.  *   This routine calls the following externals:
  104.  */
  105. extern void outbangspecials() ;
  106. extern void prescanpages() ;
  107. extern void initprinter() ;
  108. extern void cleanprinter() ;
  109. extern void dosection() ;
  110. extern void getdefaults() ;
  111. extern void cmdout() ;
  112. extern void numout() ;
  113. extern int add_header() ;
  114. extern char *strcpy() ;
  115. extern void checkenv() ;
  116. #ifdef FONTLIB
  117. extern void fliload() ;
  118. #endif
  119. /*
  120.  *   This error routine prints an error message; if the first
  121.  *   character is !, it aborts the job.
  122.  */
  123. static char *progname ;
  124. void
  125. error(s)
  126.     char *s ;
  127. {
  128.    extern void exit() ;
  129.  
  130.    (void)fprintf(stderr, "%s: %s\n", progname, s) ;
  131.    if (*s=='!') {
  132.       if (bitfile != NULL) {
  133.          cleanprinter() ;
  134.       }
  135.       exit(1) ; /* fatal */
  136.    }
  137. }
  138.  
  139. /*
  140.  *   Initialize sets up all the globals and data structures.
  141.  */
  142. void
  143. initialize()
  144. {
  145.    extern char *malloc() ;
  146.    int i;
  147.    char *s;
  148.  
  149.    nextfonthd = 0;
  150.    for (i=0; i<256; i++)
  151.       xdig[i] = 0;
  152.    i = 0;
  153.    for (s="0123456789ABCDEF"; *s!=0; s++)
  154.       xdig[*s] = i++;
  155.    i = 10;
  156.    for (s="abcdef"; *s!=0; s++)
  157.       xdig[*s] = i++;
  158.    strings = malloc(STRINGSIZE) ;
  159.    if (strings == 0)
  160.       error("! no memory for strings") ;
  161.    maxpages = 100000 ;
  162.    numcopies = 1 ;
  163.    nextstring = strings ;
  164.    iname = strings ;
  165.    *nextstring++ = 0 ;
  166.    maxstring = strings + STRINGSIZE - 200 ;
  167.    bitfile = NULL ;
  168.    bytesleft = 0 ;
  169.    swmem = SWMEM ;
  170.    oname = OUTPATH ;
  171.    sendcontrolD = 0 ;
  172.    multiplesects = 0 ;
  173.    disablecomments = 0 ;
  174.    maxdrift = -1 ;
  175.    vmaxdrift = -1 ;
  176. }
  177. /*
  178.  *   This routine copies a string into the string `pool', safely.
  179.  */
  180. char *
  181. newstring(s)
  182.    char *s ;
  183. {
  184.    int l ;
  185.  
  186.    if (s == NULL)
  187.       return(NULL) ;
  188.    l = strlen(s) ;
  189.    if (nextstring + l >= maxstring)
  190.       error("! out of string space") ;
  191.    (void)strcpy(nextstring, s) ;
  192.    s = nextstring ;
  193.    nextstring += l + 1 ;
  194.    return(s) ;
  195. }
  196. /*
  197.  *   Finally, our main routine.
  198.  */
  199. #ifndef VMS
  200. void
  201. #endif
  202. main(argc, argv)
  203.     int argc ;
  204.     char *argv[] ;
  205. {
  206.    extern void exit() ;
  207.    int i, lastext = -1 ;
  208.    register sectiontype *sects ;
  209.    int noenv = 0 ; /* do we read PRINTER or not? */
  210.  
  211. #ifdef VMS
  212.    {
  213.      char *ind = strrchr (argv[0], ']');
  214.      if (ind == NULL)
  215.         progname = argv[0];
  216.      else
  217.         progname = ++ind;
  218.    }
  219. #else
  220.    progname = argv[0] ;
  221. #endif
  222. /* we sneak a look at the first arg in case it's debugging */
  223. #ifdef DEBUG
  224.    if (argc > 1 && strncmp(argv[1], "-d", 2)==0) {
  225.       if (sscanf(argv[1]+2, "%d", &debug_flag)==0)
  226.          debug_flag = 0 ;
  227.    }
  228. #endif
  229.    initialize() ;
  230.    checkenv(0) ;
  231.    getdefaults(CONFIGFILE) ;
  232.    getdefaults((char *)0) ;
  233. /*
  234.  *   This next whole big section of code is straightforward; we just scan
  235.  *   the options.  An argument can either immediately follow its option letter
  236.  *   or be separated by spaces.  Any argument not preceded by '-' and an
  237.  *   option letter is considered a file name; the program complains if more
  238.  *   than one file name is given, and uses stdin if none is given.
  239.  */
  240.    for (i=1; i<argc; i++) {
  241.       if (*argv[i]=='-') {
  242.          char *p=argv[i]+2 ;
  243.          char c=argv[i][1] ;
  244.          switch (c) {
  245. case 'c' :
  246.             if (*p == 0 && argv[i+1])
  247.                p = argv[++i] ;
  248.             if (sscanf(p, "%d", &numcopies)==0)
  249.                error("! Bad number of copies option (-c).") ;
  250.             break ;
  251. case 'd' :
  252. #ifdef DEBUG
  253.         if (*p == 0 && argv[i+1])
  254.            p = argv[++i];
  255.         if (sscanf(p, "%d", &debug_flag)==0)
  256.            error("! Bad debug option (-d).");
  257.         break;
  258. #else
  259.             error("not compiled in debug mode") ;
  260.             break ;
  261. #endif /* DEBUG */
  262. case 'e' :
  263.             if (*p == 0 && argv[i+1])
  264.                p = argv[++i] ;
  265.             if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
  266.                error("! Bad maxdrift option (-e).") ;
  267.         vmaxdrift = maxdrift;
  268.             break ;
  269. case 'f' :
  270.             filter = (*p != '0') ;
  271.             if (filter)
  272.                oname = "" ;
  273.             noenv = 1 ;
  274.             break ;
  275. case 'h' : case 'H' :
  276.             if (*p == 0 && argv[i+1])
  277.                p = argv[++i] ;
  278.             if (strcmp(p, "-") == 0)
  279.                headers_off = 1 ;
  280.             else
  281.                (void)add_header(p) ;
  282.             break ;
  283. case 'm' :
  284.             manualfeed = (*p != '0') ;
  285.             break ;
  286. case 'n' :
  287.             if (*p == 0 && argv[i+1])
  288.                p = argv[++i] ;
  289. #ifdef SHORTINT
  290.             if (sscanf(p, "%ld", &maxpages)==0)
  291. #else    /* ~SHORTINT */
  292.             if (sscanf(p, "%d", &maxpages)==0)
  293. #endif    /* ~SHORTINT */
  294.                error("! Bad number of pages option (-n).") ;
  295.             break ;
  296. case 'o' : case 'O' :
  297.             if (*p == 0 && argv[i+1] && *argv[i+1]!='-')
  298.                p = argv[++i] ;
  299.             oname = p ;
  300.             noenv = 1 ;
  301.             break ;
  302. case 'p' :
  303.             if (*p == 0 && argv[i+1])
  304.                p = argv[++i] ;
  305. #ifdef SHORTINT
  306.             switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
  307. #else    /* ~SHORTINT */
  308.             switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
  309. #endif    /* ~SHORTINT */
  310. case 1:        firstseq = 0 ;
  311. case 2:        break ;
  312. default:
  313.                error("! Bad first page option (-p).") ;
  314.             }
  315.             notfirst = 1 ;
  316.             break ;
  317. case 'l':
  318.             if (*p == 0 && argv[i+1])
  319.                p = argv[++i] ;
  320. #ifdef SHORTINT
  321.             switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
  322. #else    /* ~SHORTINT */
  323.             switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
  324. #endif    /* ~SHORTINT */
  325. case 1:        lastseq = 0 ;
  326. case 2:        break ;
  327. default:
  328.                error("! Bad last page option (-p).") ;
  329.             }
  330.             notlast = 1 ;
  331.             break ;
  332. case 'q' : case 'Q' :
  333.             quiet = (*p != '0') ;
  334.             break ;
  335. case 'r' :
  336.             reverse = (*p != '0') ;
  337.             break ;
  338. case 't' :
  339.             if (*p == 0 && argv[i+1])
  340.                p = argv[++i] ;
  341.             if (strcmp(p, "landscape") == 0)
  342.                landscape = 1;
  343.             else
  344.                paperfmt = p ;
  345.             break ;
  346. case 'x' :
  347.             if (*p == 0 && argv[i+1])
  348.                p = argv[++i] ;
  349.             if (sscanf(p, "%d", &mag)==0 || mag < 10 ||
  350.                        mag > 100000)
  351.                error("! Bad magnification parameter (-x).") ;
  352.             overridemag = 1 ;
  353.             break ;
  354. case 'C' :
  355.             if (*p == 0 && argv[i+1])
  356.                p = argv[++i] ;
  357.             if (sscanf(p, "%d", &collatedcopies)==0)
  358.                error("! Bad number of collated copies option (-C).") ;
  359.             break ;
  360. case 'D' :
  361.             if (*p == 0 && argv[i+1])
  362.                p = argv[++i] ;
  363.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  364.                        actualdpi > 10000)
  365.                error("! Bad dpi parameter (-D).") ;
  366.         vactualdpi = actualdpi;
  367.             break ;
  368. case 'K' :
  369.             removecomments = (*p != '0') ;
  370.             break ;
  371. case 'U' :
  372.             nosmallchars = (*p != '0') ;
  373.             break ;
  374. case 'X' :
  375.             if (*p == 0 && argv[i+1])
  376.                p = argv[++i] ;
  377.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  378.                        actualdpi > 10000)
  379.                error("! Bad dpi parameter (-D).") ;
  380.             break ;
  381. case 'Y' :
  382.             if (*p == 0 && argv[i+1])
  383.                p = argv[++i] ;
  384.             if (sscanf(p, "%d", &vactualdpi)==0 || vactualdpi < 10 ||
  385.                        vactualdpi > 10000)
  386.                error("! Bad dpi parameter (-D).") ;
  387.         vactualdpi = vactualdpi;
  388.             break ;
  389. case 'F' :
  390.             sendcontrolD = (*p != '0') ;
  391.             break ;
  392. case 'N' :
  393.             disablecomments = (*p != '0') ;
  394.             break ;
  395. case 'P' :
  396.             if (*p == 0 && argv[i+1])
  397.                p = argv[++i] ;
  398.             printer = p ;
  399.             noenv = 1 ;
  400.             getdefaults("") ;
  401.             break ;
  402. case 'R' :
  403.             reverse = 0 ;
  404.             break ;
  405. case 's' :
  406.             safetyenclose = (*p != '0') ;
  407.             break ;
  408. case 'Z' :
  409.             compressed = (*p != '0') ;
  410.             break ;
  411. case '?' :
  412.             (void)fprintf(stderr, banner) ;
  413.             break ;
  414. default:
  415.             error("! Bad option, not one of cefhlmnopqrtxCDFKNPUXYZ?") ;
  416.          }
  417.       } else {
  418.          if (*iname == 0) {
  419.             register char *p ;
  420.  
  421.             lastext = 0 ;
  422.             iname = nextstring ;
  423.             p = argv[i] ;
  424.             while (*p) {
  425.                *nextstring = *p++ ;
  426.                if (*nextstring == '.')
  427.                   lastext = nextstring - iname ;
  428.                else if (*nextstring == '/' || *nextstring == ':')
  429.                   lastext = 0 ;
  430.                nextstring++ ;
  431.             }
  432.             if (lastext == 0) {
  433.                lastext = nextstring - iname ;
  434.                *nextstring++ = '.' ;
  435.                *nextstring++ = 'd' ;
  436.                *nextstring++ = 'v' ;
  437.                *nextstring++ = 'i' ;
  438.             }
  439.             *nextstring++ = 0 ;
  440.          } else
  441.             error("! Two input file names specified.") ;
  442.       }
  443.    }
  444.    if (noenv == 0) {
  445.       register char *p ;
  446.       extern char *getenv() ;
  447.       if (p = getenv("PRINTER")) {
  448.          strcpy(nextstring, "config.") ;
  449.          strcat(nextstring, p) ;
  450.          getdefaults(nextstring) ;
  451.       }
  452.    }
  453.    checkenv(1) ;
  454.    if (!quiet)
  455.       (void)fprintf(stderr, banner) ;
  456.    if (oname[0] == '-' && oname[1] == 0)
  457.       oname[0] = 0 ;
  458.    if (*oname == 0 && ! filter) {
  459.       oname = nextstring ;
  460.       for (i=0; i<=lastext; i++)
  461.          *nextstring++ = iname[i] ;
  462.       *nextstring++ = 'p' ;
  463.       *nextstring++ = 's' ;
  464.       *nextstring++ = 0 ;
  465.    }
  466. #ifdef DEBUG
  467.    if (dd(D_PATHS)) {
  468. #ifdef SHORTINT
  469.     (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
  470. #else /* ~SHORTINT */
  471.        (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
  472. #endif /* ~SHORTINT */
  473.            iname, oname, swmem) ;
  474.    (void)fprintf(stderr,"tfm path %s\npk path %s\n", tfmpath, pkpath) ;
  475.    (void)fprintf(stderr,"fig path %s\nvf path %s\n", figpath, vfpath) ;
  476.    (void)fprintf(stderr,"config path %s\nheader path %s\n", 
  477.                   configpath, headerpath) ;
  478. #ifdef FONTLIB
  479.    (void)fprintf(stderr,"fli path %s\nfli names %s\n", flipath, fliname) ;
  480. #endif
  481.    } /* dd(D_PATHS) */
  482. #endif /* DEBUG */
  483. /*
  484.  *   Now we try to open the dvi file.
  485.  */
  486.    if (warningmsg)
  487.       error(warningmsg) ;
  488.    headerfile = (compressed? CHEADERFILE : HEADERFILE) ;
  489.    (void)add_header(headerfile) ;
  490.    if (*iname != 0)
  491.       dvifile = fopen(iname, READBIN) ;
  492.    else if (filter)
  493.       dvifile = stdin;
  494.    else
  495.       error("! No input filename supplied.") ;
  496.    if (dvifile==NULL)
  497.       error("! DVI file can't be opened.") ;
  498. #ifdef FONTLIB
  499.    fliload();    /* read the font libaries */
  500. #endif
  501. /*
  502.  *   Now we do our main work.
  503.  */
  504.    if (maxdrift < 0) {
  505.       if (actualdpi <= 599)
  506.          maxdrift = actualdpi / 100 ;
  507.       else if (actualdpi < 1199)
  508.          maxdrift = actualdpi / 200 + 3 ;
  509.       else
  510.          maxdrift = actualdpi / 400 + 6 ;
  511.    }
  512.    if (vmaxdrift < 0) {
  513.       if (vactualdpi <= 599)
  514.          vmaxdrift = vactualdpi / 100 ;
  515.       else if (vactualdpi < 1199)
  516.          vmaxdrift = vactualdpi / 200 + 3 ;
  517.       else
  518.          vmaxdrift = vactualdpi / 400 + 6 ;
  519.    }
  520.    prescanpages() ;
  521.    if (includesfonts)
  522.       (void)add_header(IFONTHEADER) ;
  523.    if (usesPSfonts)
  524.       (void)add_header(PSFONTHEADER) ;
  525.    if (usesspecial)
  526.       (void)add_header(SPECIALHEADER) ;
  527.    sects = sections ;
  528.    if (sects == NULL || sects->next == NULL) {
  529.       sectioncopies = collatedcopies ;
  530.       collatedcopies = 1 ;
  531.    } else {
  532.       totalpages *= collatedcopies ;
  533.       multiplesects = 1 ;
  534.    }
  535.    initprinter() ;
  536.    outbangspecials() ;
  537.    for (i=0; i<collatedcopies; i++) {
  538.       sects = sections ;
  539.       while (sects != NULL) {
  540.          if (! quiet) {
  541.             if (prettycolumn > 77) {
  542.                fprintf(stderr, "\n") ;
  543.                prettycolumn = 0 ;
  544.             }
  545.             (void)fprintf(stderr, ". ") ;
  546.             prettycolumn += 2 ;
  547.          }
  548.          (void)fflush(stderr) ;
  549.          dosection(sects, sectioncopies) ;
  550.          sects = sects->next ;
  551.       }
  552.    }
  553.    cleanprinter() ;
  554.    if (! quiet)
  555.       (void)fprintf(stderr, "\n") ;
  556.    exit(0) ;
  557.    /*NOTREACHED*/
  558. }
  559.