home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / DOS / PRINTER / LJLPT20 / LJLPT.C < prev    next >
C/C++ Source or Header  |  1994-10-22  |  10KB  |  368 lines

  1. /*
  2. Title:    Laserjet Line Printer, Version 2.0
  3.  
  4. Author: William Luitje
  5.         2677 Wayside Drive
  6.         Ann Arbor, MI 48103
  7.         luitje@m-net.arbornet.org
  8.  
  9. Date:    22 October 1994
  10.  
  11. Descr:    This little utility takes a given text file and prints it in
  12.         177 column by 75 row mode in landscape orientation on your
  13.         Laserjet or compatible printer and then returns the printer
  14.         to normal.    This is great for getting fast, quiet, compact
  15.         program listings, unless you're farsighted.
  16.  
  17. Improv: user configurable line spacing
  18.         user configurable top margin
  19.         2 columns per page
  20.  
  21. Rights: Use and modify this program as you wish and at your own risk.
  22.         If you use it or if you have ideas for improving it, I'd appre-
  23.         ciate hearing from you.
  24.  
  25. Note:    I have written this code in such a way as to avoid dragging in
  26.         several big pieces of runtime code, namely floating point support
  27.         and the printf routine.  You could undoubtedly simplify the
  28.         source code somewhat but you would increase the executable size
  29.         by thousands of bytes.    Hey, I write microcontroller code for
  30.         a living and space parsimony is second nature!
  31. */
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <time.h>
  36.  
  37. #ifndef TRUE
  38.     #define TRUE 1
  39. #endif
  40.  
  41. #ifndef FALSE
  42.     #define FALSE 0
  43. #endif
  44.  
  45. #define LPP 75                /* lines per page */
  46. #define CPL 176             /* characters per line */
  47.  
  48. void initLJ();                /* function prototypes */
  49. void restoreLJ();
  50. void graybar();
  51. void showHelp();
  52. void ESCseq(char *);
  53. void getArgs(int, char *[]);
  54. void doBanner(char *[]);
  55. void buildHeader(char *[]);
  56. void doHeader(int);
  57. void doLineNo(int);
  58. void outLine(unsigned char *);
  59. void newPage(int);
  60. void prbigstr(unsigned char *,unsigned char ,unsigned char ,unsigned ,unsigned);
  61.  
  62.  
  63. FILE *printer;
  64. int reqBanner=FALSE;
  65. int reqHeader=FALSE;
  66. int reqLineNo=FALSE;
  67. int reqGraybar=0;
  68. int reqCopies=0;
  69. unsigned char *copiesCmd = "&l#X";
  70. int inputIdx=0;
  71. int outputIdx=0;
  72. int lineno=0;
  73. int totalLines=0;
  74. int pageno=0;
  75.  
  76. main(int argc, char *argv[])
  77. {
  78.     FILE *datafile;
  79.     unsigned char line[250], outpath[80];
  80.  
  81.     puts("Laserjet Line Printer 2.0; by luitje@m-net.arbornet.org");
  82.  
  83.     getArgs(argc, argv);
  84.  
  85.     if(!(datafile = fopen(argv[inputIdx],"r"))) {
  86.         fputs("\nCouldn't find ",stderr);
  87.         fputs(argv[inputIdx],stderr);
  88.         exit(1);}
  89.  
  90.     if(outputIdx)
  91.         strncpy(outpath,argv[outputIdx],sizeof(outpath));
  92.     else
  93.         strncpy(outpath,"PRN",sizeof(outpath));
  94.  
  95.     if(!(printer = fopen(outpath,"w"))) {
  96.         fputs("\nCouldn't open output file or device ",stderr);
  97.         fputs(argv[outputIdx],stderr);
  98.         exit(1);}
  99.  
  100.     initLJ();
  101.  
  102.     if(reqBanner)                                    /* do banner page if requested */
  103.         doBanner(argv);
  104.  
  105.     if(reqHeader) {                                 /* setup & do first header if requested */
  106.         buildHeader(argv);
  107.         newPage(FALSE); }
  108.  
  109.     while(fgets(line,sizeof(line)-1,datafile)) {    /* print each line */
  110.         outLine(line);
  111.     }
  112.  
  113.     if(lineno)
  114.         fputc(0x0C,printer);                        /* flush last page */
  115.     restoreLJ();                                    /* restore state of printer */
  116. }
  117. void ESCseq(char *cmd)    /* output a given character sequence with prepended ESC */
  118. {
  119.     fputc('\x1B',printer);
  120.     fputs(cmd,printer);
  121. }
  122. void initLJ()            /* initialize printer for our purposes */
  123. {
  124.     ESCseq("E");        /* reset printer */
  125.     ESCseq("&l1O");        /* set printer to landscape */
  126.     ESCseq("&l0L");     /* disable perforation skip */
  127.     ESCseq("(10U");        /* set Symbol set to PC-8 */
  128. //    ESCseq("&l12D");    /* set printer to 12 lines per inch */
  129.     ESCseq("&l5C");        /* set printer to 9.6 lines per inch */
  130.     ESCseq("(s16.66H");    /* set font to lineprinter */
  131.     if(reqCopies)
  132.         ESCseq(copiesCmd); /* set # of copies */
  133. }
  134. void restoreLJ()        /* put everything back the way we found it */
  135. {
  136.     ESCseq("E");
  137. }
  138. void graybar()            /* make background shading for next line */
  139. {
  140.     ESCseq("*c3165A");        /* select shade area */
  141.     ESCseq("*c40B");        /* select shade area */
  142.     ESCseq("*c2G");         /* select 30 % gray */
  143.     ESCseq("*c2P");         /* select gray scale */
  144. }
  145. void showHelp()
  146. {
  147.     fputs("Copyright 1993-1994 by William Luitje\n",stderr);
  148.     fputs("\nusage:  ljlpt <switches> file <output path>\n",stderr);
  149.     fputs("\n  'file' is the text file to be printed.",stderr);
  150.     fputs("\n  'output path' optionally specifies where to send the output (default is PRN)\n",stderr);
  151.     fputs("\n  Switches are case insensitive, can appear in any order and are chosen from:\n",stderr);
  152.     fputs("\n    /B - produces a Banner page at the beginning of the printout.",stderr);
  153.     fputs("\n    /H - produces a three line Header at the top of each page.",stderr);
  154.     fputs("\n    /L - prints the current Line number at the beginning of each line.",stderr);
  155.     fputs("\n    /G<#> - produces a Gray background every #th line (default 3).",stderr);
  156.     fputs("\n    /C<#> - prints # uncollated Copies of your file (default 2).\n",stderr);
  157.     exit(1);
  158. }
  159. void getArgs(int argc, char *argv[])    /* find out what we're to do */
  160. {
  161.     int i, ch;
  162.  
  163.     if(argc < 2)
  164.         showHelp();
  165.  
  166.     for( i=1; i<argc; ++i) {
  167.         if(argv[i][0] == '/') {
  168.             ch = toupper(argv[i][1]);
  169.             if(ch == 'B')
  170.                 reqBanner = TRUE;
  171.             else if(ch == 'H')
  172.                 reqHeader = TRUE;
  173.             else if(ch == 'G') {
  174.                 if(isdigit(argv[i][2]))
  175.                     reqGraybar = atoi(&argv[i][2]);
  176.                 else
  177.                     reqGraybar = 3;
  178.             }
  179.             else if(ch == 'C') {
  180.                 if(isdigit(argv[i][2]))
  181.                     reqCopies = atoi(&argv[i][2]);
  182.                 else
  183.                     reqCopies = '2';
  184.                 copiesCmd[2] = reqCopies;
  185.             }
  186.             else if(ch == 'L')
  187.                 reqLineNo = TRUE;
  188.             else
  189.                 showHelp();
  190.         }
  191.         else {
  192.             if(!inputIdx)
  193.                 inputIdx = i;
  194.             else if(!outputIdx)
  195.                 outputIdx = i;
  196.             else
  197.                 showHelp();
  198.         }
  199.     }
  200. }
  201.  
  202. unsigned char headerLine[120];
  203.  
  204. void buildHeader(char *argv[])
  205. {
  206.     unsigned char buffer[20];
  207.  
  208.     headerLine[0] = 0x00;
  209.     strcat(headerLine,"║  File:  ");
  210.     strncat(headerLine,argv[inputIdx],50);
  211.     strcat(headerLine,"     Time:  ");
  212.     strcat(headerLine,_strtime(buffer));
  213.     strcat(headerLine,"     Date:  ");
  214.     strcat(headerLine,_strdate(buffer));
  215. }
  216. void doHeader(int tpageno)
  217. {
  218.     unsigned char buffer[20], templine[120];
  219.     int lineLen, i;
  220.  
  221.     strcpy(templine,headerLine);            /* form changing part of header */
  222.     strcat(templine,"     Page:  ");
  223.     strcat(templine,itoa(tpageno,buffer,10));
  224.     strcat(templine,"  ║\n");
  225.     lineLen = strlen(templine);
  226.  
  227.     fputc('╔',printer);                        /* output top line of box */
  228.     for( i=0; i<lineLen-3; ++i)
  229.         fputc('═',printer);
  230.     fputs("╗\n",printer);
  231.  
  232.     fputs(templine,printer);                /* output changing part of header */
  233.  
  234.     fputc('╚',printer);                        /* output bottom line of box */
  235.     for( i=0; i<lineLen-3; ++i)
  236.         fputc('═',printer);
  237.     fputs("╝\n",printer);
  238.  
  239. }
  240.  
  241. void doBanner(char *argv[])
  242. {
  243.     unsigned char buffer[20], *fnStart;
  244.     int i;
  245.  
  246.     for( i=0; i<150; ++i)                            /* print bars */
  247.         fputc(0xb1,printer);
  248.     fputs("\n\n",printer);
  249.     for( i=0; i<150; ++i)
  250.         fputc(0xb1,printer);
  251.     fputs("\n\n",printer);
  252.  
  253.     if(fnStart = strrchr(argv[inputIdx],'\\'))        /* strip directories from input file name */
  254.         ++fnStart;                                    /* skip the '/' */
  255.     else
  256.         fnStart = argv[inputIdx];                    /* no directory info */
  257.     prbigstr(fnStart,0xb1,' ',1,1);                    /* show input file name */
  258.     fputs("\n\n\n\n",printer);
  259.     prbigstr(_strtime(buffer),0xb1,' ',1,1);        /* show current time */
  260.     fputs("\n\n\n\n",printer);
  261.     prbigstr(_strdate(buffer),0xb1,' ',1,1);        /* show current date */
  262.  
  263.     for( i=0; i<150; ++i)
  264.         fputc(0xb1,printer);                        /* print bars */
  265.     fputs("\n\n",printer);
  266.     for( i=0; i<150; ++i)
  267.         fputc(0xb1,printer);
  268.  
  269.     fputs("\r\f",printer);                            /* force new page */
  270. }
  271.  
  272. void doLineNo(int tlineno)
  273. {
  274.     unsigned char buffer[20];
  275.     int numchars, i;
  276.  
  277.     itoa(tlineno,buffer,10);
  278.     numchars = strlen(buffer);
  279.     for( i=0; i<5-numchars; ++i)
  280.         fputc(' ',printer);
  281.     fputs(buffer,printer);
  282.     fputc(' ',printer);
  283. }
  284.  
  285. void outLine(unsigned char *line)            /* handle one line of output */
  286. {
  287.     unsigned char *ffPtr;
  288.  
  289.     if(ffPtr = strchr(line,0x0C)) {         /* any formfeeds? */
  290.         *ffPtr = 0;
  291.         outLine(line);                        /* yes, handle line up to formfeed */
  292.         newPage(TRUE);
  293.         outLine(++ffPtr);                    /* now look at rest of line */
  294.     }
  295.     else {
  296.  
  297.         if(lineno >= LPP)
  298.             newPage(TRUE);
  299.  
  300.         if(reqGraybar)                        /* do graybar if requested */
  301.             if(((lineno) % reqGraybar) == 1)
  302.                 graybar();
  303.  
  304.         if(reqLineNo) {                     /* add line number if requested */
  305.             ++totalLines;
  306.             doLineNo(totalLines);
  307.         }
  308.  
  309.         fputs(line,printer);
  310.         ++lineno;
  311.     }
  312. }
  313. void newPage(int reqFlush)
  314. {
  315.     unsigned char tempbuf[10];
  316.  
  317.     lineno = 0;
  318.     pageno++;
  319.     fputs("Printing page ",stderr);         /* let user know how we're doing */
  320.     fputs(itoa(pageno,tempbuf,10),stderr);
  321.     fputc('\r',stderr);
  322.     if(reqFlush)
  323.         fputs("\f\r",printer);                /* flush page */
  324.     if(reqHeader) {                         /* do header if requested */
  325.         doHeader(pageno);
  326.         lineno = 3;
  327.     }
  328. }
  329.  
  330. #define ROMTABLE (unsigned char far *) 0xF000FA6E
  331. unsigned char far *wtable = ROMTABLE;                /* BIOS character table */
  332.  
  333. void prbigstr(unsigned char *fstr,            /* echo "big" characters to printer */
  334.               unsigned char ch,
  335.               unsigned char bk,
  336.               unsigned vmag,
  337.               unsigned hmag)
  338. {
  339.     int wrow, wcol, wchar;
  340.     unsigned char *tmpstr, hmult, vmult;
  341.     int nrow = 8;
  342.  
  343.     for (wrow = 0 ; wrow < nrow ; wrow++) {        /* loop through each row */
  344.         for( vmult=0; vmult<vmag; ++vmult) {
  345.             tmpstr = fstr;
  346.             while (*tmpstr) {                          /* loop through chars in string */
  347.                 if(*tmpstr > 0x7f && wtable == ROMTABLE) {
  348.                     wchar = 0;
  349.                     tmpstr++;
  350.                 }
  351.                 else
  352.                     wchar = *(wtable+(nrow * *tmpstr++) +wrow);
  353.                 for (wcol = 0 ; wcol < 8 ; wcol++) {    /* loop through columns  */
  354.                     wchar <<= 1;
  355.                     if (wchar & 0x100)
  356.                         for( hmult=0; hmult<hmag; ++hmult)
  357.                             fputc(ch,printer);
  358.                     else
  359.                         if((*(tmpstr) || wcol != 7))
  360.                             for( hmult=0; hmult<hmag; ++hmult)
  361.                                 fputc(bk,printer);
  362.                 }
  363.             }
  364.             fputc('\n',printer);
  365.         }
  366.     }
  367. }
  368.