home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 5
/
ctrom5b.zip
/
ctrom5b
/
DOS
/
PRINTER
/
LJLPT20
/
LJLPT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-22
|
10KB
|
368 lines
/*
Title: Laserjet Line Printer, Version 2.0
Author: William Luitje
2677 Wayside Drive
Ann Arbor, MI 48103
luitje@m-net.arbornet.org
Date: 22 October 1994
Descr: This little utility takes a given text file and prints it in
177 column by 75 row mode in landscape orientation on your
Laserjet or compatible printer and then returns the printer
to normal. This is great for getting fast, quiet, compact
program listings, unless you're farsighted.
Improv: user configurable line spacing
user configurable top margin
2 columns per page
Rights: Use and modify this program as you wish and at your own risk.
If you use it or if you have ideas for improving it, I'd appre-
ciate hearing from you.
Note: I have written this code in such a way as to avoid dragging in
several big pieces of runtime code, namely floating point support
and the printf routine. You could undoubtedly simplify the
source code somewhat but you would increase the executable size
by thousands of bytes. Hey, I write microcontroller code for
a living and space parsimony is second nature!
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define LPP 75 /* lines per page */
#define CPL 176 /* characters per line */
void initLJ(); /* function prototypes */
void restoreLJ();
void graybar();
void showHelp();
void ESCseq(char *);
void getArgs(int, char *[]);
void doBanner(char *[]);
void buildHeader(char *[]);
void doHeader(int);
void doLineNo(int);
void outLine(unsigned char *);
void newPage(int);
void prbigstr(unsigned char *,unsigned char ,unsigned char ,unsigned ,unsigned);
FILE *printer;
int reqBanner=FALSE;
int reqHeader=FALSE;
int reqLineNo=FALSE;
int reqGraybar=0;
int reqCopies=0;
unsigned char *copiesCmd = "&l#X";
int inputIdx=0;
int outputIdx=0;
int lineno=0;
int totalLines=0;
int pageno=0;
main(int argc, char *argv[])
{
FILE *datafile;
unsigned char line[250], outpath[80];
puts("Laserjet Line Printer 2.0; by luitje@m-net.arbornet.org");
getArgs(argc, argv);
if(!(datafile = fopen(argv[inputIdx],"r"))) {
fputs("\nCouldn't find ",stderr);
fputs(argv[inputIdx],stderr);
exit(1);}
if(outputIdx)
strncpy(outpath,argv[outputIdx],sizeof(outpath));
else
strncpy(outpath,"PRN",sizeof(outpath));
if(!(printer = fopen(outpath,"w"))) {
fputs("\nCouldn't open output file or device ",stderr);
fputs(argv[outputIdx],stderr);
exit(1);}
initLJ();
if(reqBanner) /* do banner page if requested */
doBanner(argv);
if(reqHeader) { /* setup & do first header if requested */
buildHeader(argv);
newPage(FALSE); }
while(fgets(line,sizeof(line)-1,datafile)) { /* print each line */
outLine(line);
}
if(lineno)
fputc(0x0C,printer); /* flush last page */
restoreLJ(); /* restore state of printer */
}
void ESCseq(char *cmd) /* output a given character sequence with prepended ESC */
{
fputc('\x1B',printer);
fputs(cmd,printer);
}
void initLJ() /* initialize printer for our purposes */
{
ESCseq("E"); /* reset printer */
ESCseq("&l1O"); /* set printer to landscape */
ESCseq("&l0L"); /* disable perforation skip */
ESCseq("(10U"); /* set Symbol set to PC-8 */
// ESCseq("&l12D"); /* set printer to 12 lines per inch */
ESCseq("&l5C"); /* set printer to 9.6 lines per inch */
ESCseq("(s16.66H"); /* set font to lineprinter */
if(reqCopies)
ESCseq(copiesCmd); /* set # of copies */
}
void restoreLJ() /* put everything back the way we found it */
{
ESCseq("E");
}
void graybar() /* make background shading for next line */
{
ESCseq("*c3165A"); /* select shade area */
ESCseq("*c40B"); /* select shade area */
ESCseq("*c2G"); /* select 30 % gray */
ESCseq("*c2P"); /* select gray scale */
}
void showHelp()
{
fputs("Copyright 1993-1994 by William Luitje\n",stderr);
fputs("\nusage: ljlpt <switches> file <output path>\n",stderr);
fputs("\n 'file' is the text file to be printed.",stderr);
fputs("\n 'output path' optionally specifies where to send the output (default is PRN)\n",stderr);
fputs("\n Switches are case insensitive, can appear in any order and are chosen from:\n",stderr);
fputs("\n /B - produces a Banner page at the beginning of the printout.",stderr);
fputs("\n /H - produces a three line Header at the top of each page.",stderr);
fputs("\n /L - prints the current Line number at the beginning of each line.",stderr);
fputs("\n /G<#> - produces a Gray background every #th line (default 3).",stderr);
fputs("\n /C<#> - prints # uncollated Copies of your file (default 2).\n",stderr);
exit(1);
}
void getArgs(int argc, char *argv[]) /* find out what we're to do */
{
int i, ch;
if(argc < 2)
showHelp();
for( i=1; i<argc; ++i) {
if(argv[i][0] == '/') {
ch = toupper(argv[i][1]);
if(ch == 'B')
reqBanner = TRUE;
else if(ch == 'H')
reqHeader = TRUE;
else if(ch == 'G') {
if(isdigit(argv[i][2]))
reqGraybar = atoi(&argv[i][2]);
else
reqGraybar = 3;
}
else if(ch == 'C') {
if(isdigit(argv[i][2]))
reqCopies = atoi(&argv[i][2]);
else
reqCopies = '2';
copiesCmd[2] = reqCopies;
}
else if(ch == 'L')
reqLineNo = TRUE;
else
showHelp();
}
else {
if(!inputIdx)
inputIdx = i;
else if(!outputIdx)
outputIdx = i;
else
showHelp();
}
}
}
unsigned char headerLine[120];
void buildHeader(char *argv[])
{
unsigned char buffer[20];
headerLine[0] = 0x00;
strcat(headerLine,"║ File: ");
strncat(headerLine,argv[inputIdx],50);
strcat(headerLine," Time: ");
strcat(headerLine,_strtime(buffer));
strcat(headerLine," Date: ");
strcat(headerLine,_strdate(buffer));
}
void doHeader(int tpageno)
{
unsigned char buffer[20], templine[120];
int lineLen, i;
strcpy(templine,headerLine); /* form changing part of header */
strcat(templine," Page: ");
strcat(templine,itoa(tpageno,buffer,10));
strcat(templine," ║\n");
lineLen = strlen(templine);
fputc('╔',printer); /* output top line of box */
for( i=0; i<lineLen-3; ++i)
fputc('═',printer);
fputs("╗\n",printer);
fputs(templine,printer); /* output changing part of header */
fputc('╚',printer); /* output bottom line of box */
for( i=0; i<lineLen-3; ++i)
fputc('═',printer);
fputs("╝\n",printer);
}
void doBanner(char *argv[])
{
unsigned char buffer[20], *fnStart;
int i;
for( i=0; i<150; ++i) /* print bars */
fputc(0xb1,printer);
fputs("\n\n",printer);
for( i=0; i<150; ++i)
fputc(0xb1,printer);
fputs("\n\n",printer);
if(fnStart = strrchr(argv[inputIdx],'\\')) /* strip directories from input file name */
++fnStart; /* skip the '/' */
else
fnStart = argv[inputIdx]; /* no directory info */
prbigstr(fnStart,0xb1,' ',1,1); /* show input file name */
fputs("\n\n\n\n",printer);
prbigstr(_strtime(buffer),0xb1,' ',1,1); /* show current time */
fputs("\n\n\n\n",printer);
prbigstr(_strdate(buffer),0xb1,' ',1,1); /* show current date */
for( i=0; i<150; ++i)
fputc(0xb1,printer); /* print bars */
fputs("\n\n",printer);
for( i=0; i<150; ++i)
fputc(0xb1,printer);
fputs("\r\f",printer); /* force new page */
}
void doLineNo(int tlineno)
{
unsigned char buffer[20];
int numchars, i;
itoa(tlineno,buffer,10);
numchars = strlen(buffer);
for( i=0; i<5-numchars; ++i)
fputc(' ',printer);
fputs(buffer,printer);
fputc(' ',printer);
}
void outLine(unsigned char *line) /* handle one line of output */
{
unsigned char *ffPtr;
if(ffPtr = strchr(line,0x0C)) { /* any formfeeds? */
*ffPtr = 0;
outLine(line); /* yes, handle line up to formfeed */
newPage(TRUE);
outLine(++ffPtr); /* now look at rest of line */
}
else {
if(lineno >= LPP)
newPage(TRUE);
if(reqGraybar) /* do graybar if requested */
if(((lineno) % reqGraybar) == 1)
graybar();
if(reqLineNo) { /* add line number if requested */
++totalLines;
doLineNo(totalLines);
}
fputs(line,printer);
++lineno;
}
}
void newPage(int reqFlush)
{
unsigned char tempbuf[10];
lineno = 0;
pageno++;
fputs("Printing page ",stderr); /* let user know how we're doing */
fputs(itoa(pageno,tempbuf,10),stderr);
fputc('\r',stderr);
if(reqFlush)
fputs("\f\r",printer); /* flush page */
if(reqHeader) { /* do header if requested */
doHeader(pageno);
lineno = 3;
}
}
#define ROMTABLE (unsigned char far *) 0xF000FA6E
unsigned char far *wtable = ROMTABLE; /* BIOS character table */
void prbigstr(unsigned char *fstr, /* echo "big" characters to printer */
unsigned char ch,
unsigned char bk,
unsigned vmag,
unsigned hmag)
{
int wrow, wcol, wchar;
unsigned char *tmpstr, hmult, vmult;
int nrow = 8;
for (wrow = 0 ; wrow < nrow ; wrow++) { /* loop through each row */
for( vmult=0; vmult<vmag; ++vmult) {
tmpstr = fstr;
while (*tmpstr) { /* loop through chars in string */
if(*tmpstr > 0x7f && wtable == ROMTABLE) {
wchar = 0;
tmpstr++;
}
else
wchar = *(wtable+(nrow * *tmpstr++) +wrow);
for (wcol = 0 ; wcol < 8 ; wcol++) { /* loop through columns */
wchar <<= 1;
if (wchar & 0x100)
for( hmult=0; hmult<hmag; ++hmult)
fputc(ch,printer);
else
if((*(tmpstr) || wcol != 7))
for( hmult=0; hmult<hmag; ++hmult)
fputc(bk,printer);
}
}
fputc('\n',printer);
}
}
}