xref: /plan9/sys/src/cmd/postscript/postdaisy/postdaisy.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier /*
2*7dd7cddfSDavid du Colombier  *
3*7dd7cddfSDavid du Colombier  * postdaisy - PostScript translator for Diablo 1640 files.
4*7dd7cddfSDavid du Colombier  *
5*7dd7cddfSDavid du Colombier  * A program that translates Diablo 1640 files into PostScript. Absolutely nothing
6*7dd7cddfSDavid du Colombier  * is guaranteed. Quite a few things haven't been implemented, and what's been
7*7dd7cddfSDavid du Colombier  * done isn't well tested. Most of the documentation used to write this program
8*7dd7cddfSDavid du Colombier  * was taken from the 'Diablo Emulator' section of a recent Imagen manual.
9*7dd7cddfSDavid du Colombier  *
10*7dd7cddfSDavid du Colombier  * Some of document comments that are generated may not be right. Most of the test
11*7dd7cddfSDavid du Colombier  * files I used produced a trailing blank page. I've put a check in formfeed() that
12*7dd7cddfSDavid du Colombier  * won't print the last page if it doesn't contain any text, but PAGES comments may
13*7dd7cddfSDavid du Colombier  * not be right. The DOCUMENTFONTS comment will also be wrong if auto underline or
14*7dd7cddfSDavid du Colombier  * bold printing have been turned on by escape commands.
15*7dd7cddfSDavid du Colombier  *
16*7dd7cddfSDavid du Colombier  * The brute force approach used to implement horizontal and vertical tabs leaves
17*7dd7cddfSDavid du Colombier  * much to be desired, and may not work for very small initial hmi and vmi values.
18*7dd7cddfSDavid du Colombier  * At the very least I should have used malloc() to get space for the two tabstop
19*7dd7cddfSDavid du Colombier  * arrays after hmi and vmi are known!
20*7dd7cddfSDavid du Colombier  *
21*7dd7cddfSDavid du Colombier  * Reverse printing mode hasn't been tested at all, but what's here should be
22*7dd7cddfSDavid du Colombier  * close even though it's not efficient.
23*7dd7cddfSDavid du Colombier  *
24*7dd7cddfSDavid du Colombier  * The PostScript prologue is copied from *prologue before any of the input files
25*7dd7cddfSDavid du Colombier  * are translated. The program expects that the following PostScript procedures
26*7dd7cddfSDavid du Colombier  * are defined in that file:
27*7dd7cddfSDavid du Colombier  *
28*7dd7cddfSDavid du Colombier  *	setup
29*7dd7cddfSDavid du Colombier  *
30*7dd7cddfSDavid du Colombier  *	  mark ... setup -
31*7dd7cddfSDavid du Colombier  *
32*7dd7cddfSDavid du Colombier  *	    Handles special initialization stuff that depends on how this program
33*7dd7cddfSDavid du Colombier  *	    was called. Expects to find a mark followed by key/value pairs on the
34*7dd7cddfSDavid du Colombier  *	    stack. The def operator is applied to each pair up to the mark, then
35*7dd7cddfSDavid du Colombier  *	    the default state is set up.
36*7dd7cddfSDavid du Colombier  *
37*7dd7cddfSDavid du Colombier  *	pagesetup
38*7dd7cddfSDavid du Colombier  *
39*7dd7cddfSDavid du Colombier  *	  page pagesetup -
40*7dd7cddfSDavid du Colombier  *
41*7dd7cddfSDavid du Colombier  *	    Does whatever is needed to set things up for the next page. Expects to
42*7dd7cddfSDavid du Colombier  *	    find the current page number on the stack.
43*7dd7cddfSDavid du Colombier  *
44*7dd7cddfSDavid du Colombier  *	t
45*7dd7cddfSDavid du Colombier  *
46*7dd7cddfSDavid du Colombier  *	  mark str1 x1 str2 x2 ... strn xn y hmi t mark
47*7dd7cddfSDavid du Colombier  *
48*7dd7cddfSDavid du Colombier  *	    Handles all the text on the stack. Characters in the strings are
49*7dd7cddfSDavid du Colombier  *	    printed using hmi as the character advance, and all strings are at
50*7dd7cddfSDavid du Colombier  *	    vertical position y. Each string is begins at the horizontal position
51*7dd7cddfSDavid du Colombier  *	    that preceeds it.
52*7dd7cddfSDavid du Colombier  *
53*7dd7cddfSDavid du Colombier  *	f
54*7dd7cddfSDavid du Colombier  *
55*7dd7cddfSDavid du Colombier  *	  font f -
56*7dd7cddfSDavid du Colombier  *
57*7dd7cddfSDavid du Colombier  *	    Use font f, where f is the full PostScript font name. Only used when
58*7dd7cddfSDavid du Colombier  *	    we switch to auto underline (Courier-Italic) or bold (Courier-Bold)
59*7dd7cddfSDavid du Colombier  *	    printing.
60*7dd7cddfSDavid du Colombier  *
61*7dd7cddfSDavid du Colombier  *	done
62*7dd7cddfSDavid du Colombier  *
63*7dd7cddfSDavid du Colombier  *	  done
64*7dd7cddfSDavid du Colombier  *
65*7dd7cddfSDavid du Colombier  *	    Makes sure the last page is printed. Only needed when we're printing
66*7dd7cddfSDavid du Colombier  *	    more than one page on each sheet of paper.
67*7dd7cddfSDavid du Colombier  *
68*7dd7cddfSDavid du Colombier  * Many default values, like the magnification and orientation, are defined in
69*7dd7cddfSDavid du Colombier  * the prologue, which is where they belong. If they're changed (by options), an
70*7dd7cddfSDavid du Colombier  * appropriate definition is made after the prologue is added to the output file.
71*7dd7cddfSDavid du Colombier  * The -P option passes arbitrary PostScript through to the output file. Among
72*7dd7cddfSDavid du Colombier  * other things it can be used to set (or change) values that can't be accessed by
73*7dd7cddfSDavid du Colombier  * other options.
74*7dd7cddfSDavid du Colombier  *
75*7dd7cddfSDavid du Colombier  */
76*7dd7cddfSDavid du Colombier 
77*7dd7cddfSDavid du Colombier #include <stdio.h>
78*7dd7cddfSDavid du Colombier #include <signal.h>
79*7dd7cddfSDavid du Colombier #include <ctype.h>
80*7dd7cddfSDavid du Colombier #ifdef plan9
81*7dd7cddfSDavid du Colombier #define	isascii(c)	((unsigned char)(c)<=0177)
82*7dd7cddfSDavid du Colombier #endif
83*7dd7cddfSDavid du Colombier #include <sys/types.h>
84*7dd7cddfSDavid du Colombier #include <fcntl.h>
85*7dd7cddfSDavid du Colombier 
86*7dd7cddfSDavid du Colombier #include "comments.h"			/* PostScript file structuring comments */
87*7dd7cddfSDavid du Colombier #include "gen.h"			/* general purpose definitions */
88*7dd7cddfSDavid du Colombier #include "path.h"			/* for the prologue */
89*7dd7cddfSDavid du Colombier #include "ext.h"			/* external variable declarations */
90*7dd7cddfSDavid du Colombier #include "postdaisy.h"			/* a few special definitions */
91*7dd7cddfSDavid du Colombier 
92*7dd7cddfSDavid du Colombier char	*optnames = "a:c:f:h:l:m:n:o:p:r:s:v:x:y:A:C:E:J:L:P:DI";
93*7dd7cddfSDavid du Colombier 
94*7dd7cddfSDavid du Colombier char	*prologue = POSTDAISY;		/* default PostScript prologue */
95*7dd7cddfSDavid du Colombier char	*formfile = FORMFILE;		/* stuff for multiple pages per sheet */
96*7dd7cddfSDavid du Colombier 
97*7dd7cddfSDavid du Colombier int	formsperpage = 1;		/* page images on each piece of paper */
98*7dd7cddfSDavid du Colombier int	copies = 1;			/* and this many copies of each sheet */
99*7dd7cddfSDavid du Colombier 
100*7dd7cddfSDavid du Colombier char	htabstops[COLUMNS];		/* horizontal */
101*7dd7cddfSDavid du Colombier char	vtabstops[ROWS];		/* and vertical tabs */
102*7dd7cddfSDavid du Colombier 
103*7dd7cddfSDavid du Colombier int	res = RES;			/* input file resolution - sort of */
104*7dd7cddfSDavid du Colombier 
105*7dd7cddfSDavid du Colombier int	hmi = HMI;			/* horizontal motion index - 1/120 inch */
106*7dd7cddfSDavid du Colombier int	vmi = VMI;			/* vertical motion index - 1/48 inch */
107*7dd7cddfSDavid du Colombier int	ohmi = HMI;			/* original hmi */
108*7dd7cddfSDavid du Colombier int	ovmi = VMI;			/* and vmi - for tabs and char size */
109*7dd7cddfSDavid du Colombier 
110*7dd7cddfSDavid du Colombier int	hpos = 0;			/* current horizontal */
111*7dd7cddfSDavid du Colombier int	vpos = 0;			/* and vertical position */
112*7dd7cddfSDavid du Colombier 
113*7dd7cddfSDavid du Colombier int	lastx = -1;			/* printer's last horizontal */
114*7dd7cddfSDavid du Colombier int	lasty = -1;			/* and vertical position */
115*7dd7cddfSDavid du Colombier int	lasthmi = -1;			/* hmi for current text strings */
116*7dd7cddfSDavid du Colombier 
117*7dd7cddfSDavid du Colombier int	lastc = -1;			/* last printed character */
118*7dd7cddfSDavid du Colombier int	prevx = -1;			/* at this position */
119*7dd7cddfSDavid du Colombier 
120*7dd7cddfSDavid du Colombier int	leftmargin = LEFTMARGIN;	/* page margins */
121*7dd7cddfSDavid du Colombier int	rightmargin = RIGHTMARGIN;
122*7dd7cddfSDavid du Colombier int	topmargin = TOPMARGIN;
123*7dd7cddfSDavid du Colombier int	bottommargin = BOTTOMMARGIN;
124*7dd7cddfSDavid du Colombier 
125*7dd7cddfSDavid du Colombier int	stringcount = 0;		/* number of strings on the stack */
126*7dd7cddfSDavid du Colombier int	stringstart = 1;		/* column where current one starts */
127*7dd7cddfSDavid du Colombier int	advance = 1;			/* -1 if in backward print mode */
128*7dd7cddfSDavid du Colombier 
129*7dd7cddfSDavid du Colombier int	lfiscr = OFF;			/* line feed implies carriage return */
130*7dd7cddfSDavid du Colombier int	crislf = OFF;			/* carriage return implies line feed */
131*7dd7cddfSDavid du Colombier 
132*7dd7cddfSDavid du Colombier int	linespp = 0;			/* lines per page if it's positive */
133*7dd7cddfSDavid du Colombier int	markedpage = FALSE;		/* helps prevent trailing blank page */
134*7dd7cddfSDavid du Colombier int	page = 0;			/* page we're working on */
135*7dd7cddfSDavid du Colombier int	printed = 0;			/* printed this many pages */
136*7dd7cddfSDavid du Colombier 
137*7dd7cddfSDavid du Colombier Fontmap	fontmap[] = FONTMAP;		/* for translating font names */
138*7dd7cddfSDavid du Colombier char	*fontname = "Courier";		/* use this PostScript font */
139*7dd7cddfSDavid du Colombier int	shadowprint = OFF;		/* automatic bold printing if ON */
140*7dd7cddfSDavid du Colombier 
141*7dd7cddfSDavid du Colombier FILE	*fp_in;				/* read from this file */
142*7dd7cddfSDavid du Colombier FILE	*fp_out = stdout;		/* and write stuff here */
143*7dd7cddfSDavid du Colombier FILE	*fp_acct = NULL;		/* for accounting data */
144*7dd7cddfSDavid du Colombier 
145*7dd7cddfSDavid du Colombier /*****************************************************************************/
146*7dd7cddfSDavid du Colombier 
main(agc,agv)147*7dd7cddfSDavid du Colombier main(agc, agv)
148*7dd7cddfSDavid du Colombier 
149*7dd7cddfSDavid du Colombier     int		agc;
150*7dd7cddfSDavid du Colombier     char	*agv[];
151*7dd7cddfSDavid du Colombier 
152*7dd7cddfSDavid du Colombier {
153*7dd7cddfSDavid du Colombier 
154*7dd7cddfSDavid du Colombier /*
155*7dd7cddfSDavid du Colombier  *
156*7dd7cddfSDavid du Colombier  * A simple program that translates Diablo 1640 files into PostScript. Nothing
157*7dd7cddfSDavid du Colombier  * is guaranteed - the program not well tested and doesn't implement everything.
158*7dd7cddfSDavid du Colombier  *
159*7dd7cddfSDavid du Colombier  */
160*7dd7cddfSDavid du Colombier 
161*7dd7cddfSDavid du Colombier     argc = agc;				/* other routines may want them */
162*7dd7cddfSDavid du Colombier     argv = agv;
163*7dd7cddfSDavid du Colombier 
164*7dd7cddfSDavid du Colombier     prog_name = argv[0];		/* really just for error messages */
165*7dd7cddfSDavid du Colombier 
166*7dd7cddfSDavid du Colombier     init_signals();			/* sets up interrupt handling */
167*7dd7cddfSDavid du Colombier     header();				/* PostScript header comments */
168*7dd7cddfSDavid du Colombier     options();				/* handle the command line options */
169*7dd7cddfSDavid du Colombier     setup();				/* for PostScript */
170*7dd7cddfSDavid du Colombier     arguments();			/* followed by each input file */
171*7dd7cddfSDavid du Colombier     done();				/* print the last page etc. */
172*7dd7cddfSDavid du Colombier     account();				/* job accounting data */
173*7dd7cddfSDavid du Colombier 
174*7dd7cddfSDavid du Colombier     exit(x_stat);			/* not much could be wrong */
175*7dd7cddfSDavid du Colombier 
176*7dd7cddfSDavid du Colombier }   /* End of main */
177*7dd7cddfSDavid du Colombier 
178*7dd7cddfSDavid du Colombier /*****************************************************************************/
179*7dd7cddfSDavid du Colombier 
init_signals()180*7dd7cddfSDavid du Colombier init_signals()
181*7dd7cddfSDavid du Colombier 
182*7dd7cddfSDavid du Colombier {
183*7dd7cddfSDavid du Colombier 
184*7dd7cddfSDavid du Colombier /*
185*7dd7cddfSDavid du Colombier  *
186*7dd7cddfSDavid du Colombier  * Makes sure we handle interrupts.
187*7dd7cddfSDavid du Colombier  *
188*7dd7cddfSDavid du Colombier  */
189*7dd7cddfSDavid du Colombier 
190*7dd7cddfSDavid du Colombier     if ( signal(SIGINT, interrupt) == SIG_IGN )  {
191*7dd7cddfSDavid du Colombier 	signal(SIGINT, SIG_IGN);
192*7dd7cddfSDavid du Colombier 	signal(SIGQUIT, SIG_IGN);
193*7dd7cddfSDavid du Colombier 	signal(SIGHUP, SIG_IGN);
194*7dd7cddfSDavid du Colombier     } else {
195*7dd7cddfSDavid du Colombier 	signal(SIGHUP, interrupt);
196*7dd7cddfSDavid du Colombier 	signal(SIGQUIT, interrupt);
197*7dd7cddfSDavid du Colombier     }   /* End else */
198*7dd7cddfSDavid du Colombier 
199*7dd7cddfSDavid du Colombier     signal(SIGTERM, interrupt);
200*7dd7cddfSDavid du Colombier 
201*7dd7cddfSDavid du Colombier }   /* End of init_signals */
202*7dd7cddfSDavid du Colombier 
203*7dd7cddfSDavid du Colombier /*****************************************************************************/
204*7dd7cddfSDavid du Colombier 
header()205*7dd7cddfSDavid du Colombier header()
206*7dd7cddfSDavid du Colombier 
207*7dd7cddfSDavid du Colombier {
208*7dd7cddfSDavid du Colombier 
209*7dd7cddfSDavid du Colombier     int		ch;			/* return value from getopt() */
210*7dd7cddfSDavid du Colombier     int		old_optind = optind;	/* for restoring optind - should be 1 */
211*7dd7cddfSDavid du Colombier 
212*7dd7cddfSDavid du Colombier /*
213*7dd7cddfSDavid du Colombier  *
214*7dd7cddfSDavid du Colombier  * Scans the option list looking for things, like the prologue file, that we need
215*7dd7cddfSDavid du Colombier  * right away but could be changed from the default. Doing things this way is an
216*7dd7cddfSDavid du Colombier  * attempt to conform to Adobe's latest file structuring conventions. In particular
217*7dd7cddfSDavid du Colombier  * they now say there should be nothing executed in the prologue, and they have
218*7dd7cddfSDavid du Colombier  * added two new comments that delimit global initialization calls. Once we know
219*7dd7cddfSDavid du Colombier  * where things really are we write out the job header, follow it by the prologue,
220*7dd7cddfSDavid du Colombier  * and then add the ENDPROLOG and BEGINSETUP comments.
221*7dd7cddfSDavid du Colombier  *
222*7dd7cddfSDavid du Colombier  */
223*7dd7cddfSDavid du Colombier 
224*7dd7cddfSDavid du Colombier     while ( (ch = getopt(argc, argv, optnames)) != EOF )
225*7dd7cddfSDavid du Colombier 	if ( ch == 'L' )
226*7dd7cddfSDavid du Colombier 	    prologue = optarg;
227*7dd7cddfSDavid du Colombier 	else if ( ch == '?' )
228*7dd7cddfSDavid du Colombier 	    error(FATAL, "");
229*7dd7cddfSDavid du Colombier 
230*7dd7cddfSDavid du Colombier     optind = old_optind;		/* get ready for option scanning */
231*7dd7cddfSDavid du Colombier 
232*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s", CONFORMING);
233*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION);
234*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s %s\n", DOCUMENTFONTS, ATEND);
235*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s %s\n", PAGES, ATEND);
236*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s", ENDCOMMENTS);
237*7dd7cddfSDavid du Colombier 
238*7dd7cddfSDavid du Colombier     if ( cat(prologue) == FALSE )
239*7dd7cddfSDavid du Colombier 	error(FATAL, "can't read %s", prologue);
240*7dd7cddfSDavid du Colombier 
241*7dd7cddfSDavid du Colombier     if ( DOROUND )
242*7dd7cddfSDavid du Colombier 	cat(ROUNDPAGE);
243*7dd7cddfSDavid du Colombier 
244*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s", ENDPROLOG);
245*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s", BEGINSETUP);
246*7dd7cddfSDavid du Colombier     fprintf(stdout, "mark\n");
247*7dd7cddfSDavid du Colombier 
248*7dd7cddfSDavid du Colombier }   /* End of header */
249*7dd7cddfSDavid du Colombier 
250*7dd7cddfSDavid du Colombier /*****************************************************************************/
251*7dd7cddfSDavid du Colombier 
options()252*7dd7cddfSDavid du Colombier options()
253*7dd7cddfSDavid du Colombier 
254*7dd7cddfSDavid du Colombier {
255*7dd7cddfSDavid du Colombier 
256*7dd7cddfSDavid du Colombier     int		ch;			/* return value from getopt() */
257*7dd7cddfSDavid du Colombier     int		n;			/* for CR and LF modes */
258*7dd7cddfSDavid du Colombier 
259*7dd7cddfSDavid du Colombier /*
260*7dd7cddfSDavid du Colombier  *
261*7dd7cddfSDavid du Colombier  * Reads and processes the command line options. Added the -P option so arbitrary
262*7dd7cddfSDavid du Colombier  * PostScript code can be passed through. Expect it could be useful for changing
263*7dd7cddfSDavid du Colombier  * definitions in the prologue for which options have not been defined.
264*7dd7cddfSDavid du Colombier  *
265*7dd7cddfSDavid du Colombier  * Although any PostScript font can be used, things will only work for constant
266*7dd7cddfSDavid du Colombier  * width fonts.
267*7dd7cddfSDavid du Colombier  *
268*7dd7cddfSDavid du Colombier  */
269*7dd7cddfSDavid du Colombier 
270*7dd7cddfSDavid du Colombier     while ( (ch = getopt(argc, argv, optnames)) != EOF )  {
271*7dd7cddfSDavid du Colombier 	switch ( ch )  {
272*7dd7cddfSDavid du Colombier 	    case 'a':			/* aspect ratio */
273*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/aspectratio %s def\n", optarg);
274*7dd7cddfSDavid du Colombier 		    break;
275*7dd7cddfSDavid du Colombier 
276*7dd7cddfSDavid du Colombier 	    case 'c':			/* copies */
277*7dd7cddfSDavid du Colombier 		    copies = atoi(optarg);
278*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/#copies %s store\n", optarg);
279*7dd7cddfSDavid du Colombier 		    break;
280*7dd7cddfSDavid du Colombier 
281*7dd7cddfSDavid du Colombier 	    case 'f':			/* use this PostScript font */
282*7dd7cddfSDavid du Colombier 		    fontname = get_font(optarg);
283*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/font /%s def\n", fontname);
284*7dd7cddfSDavid du Colombier 		    break;
285*7dd7cddfSDavid du Colombier 
286*7dd7cddfSDavid du Colombier 	    case 'h':			/* default character spacing */
287*7dd7cddfSDavid du Colombier 		    ohmi = hmi = atoi(optarg) * HSCALE;
288*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/hmi %s def\n", optarg);
289*7dd7cddfSDavid du Colombier 		    break;
290*7dd7cddfSDavid du Colombier 
291*7dd7cddfSDavid du Colombier 	    case 'l':			/* lines per page */
292*7dd7cddfSDavid du Colombier 		    linespp = atoi(optarg);
293*7dd7cddfSDavid du Colombier 		    break;
294*7dd7cddfSDavid du Colombier 
295*7dd7cddfSDavid du Colombier 	    case 'm':			/* magnification */
296*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/magnification %s def\n", optarg);
297*7dd7cddfSDavid du Colombier 		    break;
298*7dd7cddfSDavid du Colombier 
299*7dd7cddfSDavid du Colombier 	    case 'n':			/* forms per page */
300*7dd7cddfSDavid du Colombier 		    formsperpage = atoi(optarg);
301*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg);
302*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/formsperpage %s def\n", optarg);
303*7dd7cddfSDavid du Colombier 		    break;
304*7dd7cddfSDavid du Colombier 
305*7dd7cddfSDavid du Colombier 	    case 'o':			/* output page list */
306*7dd7cddfSDavid du Colombier 		    out_list(optarg);
307*7dd7cddfSDavid du Colombier 		    break;
308*7dd7cddfSDavid du Colombier 
309*7dd7cddfSDavid du Colombier 	    case 'p':			/* landscape or portrait mode */
310*7dd7cddfSDavid du Colombier 		    if ( *optarg == 'l' )
311*7dd7cddfSDavid du Colombier 			fprintf(stdout, "/landscape true def\n");
312*7dd7cddfSDavid du Colombier 		    else fprintf(stdout, "/landscape false def\n");
313*7dd7cddfSDavid du Colombier 		    break;
314*7dd7cddfSDavid du Colombier 
315*7dd7cddfSDavid du Colombier 	    case 'r':			/* set CR and LF modes */
316*7dd7cddfSDavid du Colombier 		    n = atoi(optarg);
317*7dd7cddfSDavid du Colombier 		    if ( n & 01 )
318*7dd7cddfSDavid du Colombier 			lfiscr = ON;
319*7dd7cddfSDavid du Colombier 		    else lfiscr = OFF;
320*7dd7cddfSDavid du Colombier 		    if ( n & 02 )
321*7dd7cddfSDavid du Colombier 			crislf = ON;
322*7dd7cddfSDavid du Colombier 		    else crislf = OFF;
323*7dd7cddfSDavid du Colombier 		    break;
324*7dd7cddfSDavid du Colombier 
325*7dd7cddfSDavid du Colombier 	    case 's':			/* point size */
326*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/pointsize %s def\n", optarg);
327*7dd7cddfSDavid du Colombier 		    break;
328*7dd7cddfSDavid du Colombier 
329*7dd7cddfSDavid du Colombier 	    case 'v':			/* default line spacing */
330*7dd7cddfSDavid du Colombier 		    ovmi = vmi = atoi(optarg) * VSCALE;
331*7dd7cddfSDavid du Colombier 		    break;
332*7dd7cddfSDavid du Colombier 
333*7dd7cddfSDavid du Colombier 	    case 'x':			/* shift things horizontally */
334*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/xoffset %s def\n", optarg);
335*7dd7cddfSDavid du Colombier 		    break;
336*7dd7cddfSDavid du Colombier 
337*7dd7cddfSDavid du Colombier 	    case 'y':			/* and vertically on the page */
338*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "/yoffset %s def\n", optarg);
339*7dd7cddfSDavid du Colombier 		    break;
340*7dd7cddfSDavid du Colombier 
341*7dd7cddfSDavid du Colombier 	    case 'A':			/* force job accounting */
342*7dd7cddfSDavid du Colombier 	    case 'J':
343*7dd7cddfSDavid du Colombier 		    if ( (fp_acct = fopen(optarg, "a")) == NULL )
344*7dd7cddfSDavid du Colombier 			error(FATAL, "can't open accounting file %s", optarg);
345*7dd7cddfSDavid du Colombier 		    break;
346*7dd7cddfSDavid du Colombier 
347*7dd7cddfSDavid du Colombier 	    case 'C':			/* copy file straight to output */
348*7dd7cddfSDavid du Colombier 		    if ( cat(optarg) == FALSE )
349*7dd7cddfSDavid du Colombier 			error(FATAL, "can't read %s", optarg);
350*7dd7cddfSDavid du Colombier 		    break;
351*7dd7cddfSDavid du Colombier 
352*7dd7cddfSDavid du Colombier 	    case 'E':			/* text font encoding */
353*7dd7cddfSDavid du Colombier 		    fontencoding = optarg;
354*7dd7cddfSDavid du Colombier 		    break;
355*7dd7cddfSDavid du Colombier 
356*7dd7cddfSDavid du Colombier 	    case 'L':			/* PostScript prologue file */
357*7dd7cddfSDavid du Colombier 		    prologue = optarg;
358*7dd7cddfSDavid du Colombier 		    break;
359*7dd7cddfSDavid du Colombier 
360*7dd7cddfSDavid du Colombier 	    case 'P':			/* PostScript pass through */
361*7dd7cddfSDavid du Colombier 		    fprintf(stdout, "%s\n", optarg);
362*7dd7cddfSDavid du Colombier 		    break;
363*7dd7cddfSDavid du Colombier 
364*7dd7cddfSDavid du Colombier 	    case 'R':			/* special global or page level request */
365*7dd7cddfSDavid du Colombier 		    saverequest(optarg);
366*7dd7cddfSDavid du Colombier 		    break;
367*7dd7cddfSDavid du Colombier 
368*7dd7cddfSDavid du Colombier 	    case 'D':			/* debug flag */
369*7dd7cddfSDavid du Colombier 		    debug = ON;
370*7dd7cddfSDavid du Colombier 		    break;
371*7dd7cddfSDavid du Colombier 
372*7dd7cddfSDavid du Colombier 	    case 'I':			/* ignore FATAL errors */
373*7dd7cddfSDavid du Colombier 		    ignore = ON;
374*7dd7cddfSDavid du Colombier 		    break;
375*7dd7cddfSDavid du Colombier 
376*7dd7cddfSDavid du Colombier 	    case '?':			/* don't understand the option */
377*7dd7cddfSDavid du Colombier 		    error(FATAL, "");
378*7dd7cddfSDavid du Colombier 		    break;
379*7dd7cddfSDavid du Colombier 
380*7dd7cddfSDavid du Colombier 	    default:			/* don't know what to do for ch */
381*7dd7cddfSDavid du Colombier 		    error(FATAL, "missing case for option %c\n", ch);
382*7dd7cddfSDavid du Colombier 		    break;
383*7dd7cddfSDavid du Colombier 	}   /* End switch */
384*7dd7cddfSDavid du Colombier     }   /* End while */
385*7dd7cddfSDavid du Colombier 
386*7dd7cddfSDavid du Colombier     argc -= optind;			/* get ready for non-option args */
387*7dd7cddfSDavid du Colombier     argv += optind;
388*7dd7cddfSDavid du Colombier 
389*7dd7cddfSDavid du Colombier }   /* End of options */
390*7dd7cddfSDavid du Colombier 
391*7dd7cddfSDavid du Colombier /*****************************************************************************/
392*7dd7cddfSDavid du Colombier 
get_font(name)393*7dd7cddfSDavid du Colombier char *get_font(name)
394*7dd7cddfSDavid du Colombier 
395*7dd7cddfSDavid du Colombier     char	*name;			/* name the user asked for */
396*7dd7cddfSDavid du Colombier 
397*7dd7cddfSDavid du Colombier {
398*7dd7cddfSDavid du Colombier 
399*7dd7cddfSDavid du Colombier     int		i;			/* for looking through fontmap[] */
400*7dd7cddfSDavid du Colombier 
401*7dd7cddfSDavid du Colombier /*
402*7dd7cddfSDavid du Colombier  *
403*7dd7cddfSDavid du Colombier  * Called from options() to map a user's font name into a legal PostScript name.
404*7dd7cddfSDavid du Colombier  * If the lookup fails *name is returned to the caller. That should let you choose
405*7dd7cddfSDavid du Colombier  * any PostScript font, although things will only work well for constant width
406*7dd7cddfSDavid du Colombier  * fonts.
407*7dd7cddfSDavid du Colombier  *
408*7dd7cddfSDavid du Colombier  */
409*7dd7cddfSDavid du Colombier 
410*7dd7cddfSDavid du Colombier     for ( i = 0; fontmap[i].name != NULL; i++ )
411*7dd7cddfSDavid du Colombier 	if ( strcmp(name, fontmap[i].name) == 0 )
412*7dd7cddfSDavid du Colombier 	    return(fontmap[i].val);
413*7dd7cddfSDavid du Colombier 
414*7dd7cddfSDavid du Colombier     return(name);
415*7dd7cddfSDavid du Colombier 
416*7dd7cddfSDavid du Colombier }   /* End of get_font */
417*7dd7cddfSDavid du Colombier 
418*7dd7cddfSDavid du Colombier /*****************************************************************************/
419*7dd7cddfSDavid du Colombier 
setup()420*7dd7cddfSDavid du Colombier setup()
421*7dd7cddfSDavid du Colombier 
422*7dd7cddfSDavid du Colombier {
423*7dd7cddfSDavid du Colombier 
424*7dd7cddfSDavid du Colombier /*
425*7dd7cddfSDavid du Colombier  *
426*7dd7cddfSDavid du Colombier  * Handles things that must be done after the options are read but before the
427*7dd7cddfSDavid du Colombier  * input files are processed.
428*7dd7cddfSDavid du Colombier  *
429*7dd7cddfSDavid du Colombier  */
430*7dd7cddfSDavid du Colombier 
431*7dd7cddfSDavid du Colombier     writerequest(0, stdout);		/* global requests eg. manual feed */
432*7dd7cddfSDavid du Colombier     setencoding(fontencoding);
433*7dd7cddfSDavid du Colombier     fprintf(stdout, "setup\n");
434*7dd7cddfSDavid du Colombier 
435*7dd7cddfSDavid du Colombier     if ( formsperpage > 1 )  {
436*7dd7cddfSDavid du Colombier 	if ( cat(formfile) == FALSE )
437*7dd7cddfSDavid du Colombier 	    error(FATAL, "can't read %s", formfile);
438*7dd7cddfSDavid du Colombier 	fprintf(stdout, "%d setupforms\n", formsperpage);
439*7dd7cddfSDavid du Colombier     }	/* End if */
440*7dd7cddfSDavid du Colombier 
441*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s", ENDSETUP);
442*7dd7cddfSDavid du Colombier 
443*7dd7cddfSDavid du Colombier }   /* End of setup */
444*7dd7cddfSDavid du Colombier 
445*7dd7cddfSDavid du Colombier /*****************************************************************************/
446*7dd7cddfSDavid du Colombier 
arguments()447*7dd7cddfSDavid du Colombier arguments()
448*7dd7cddfSDavid du Colombier 
449*7dd7cddfSDavid du Colombier {
450*7dd7cddfSDavid du Colombier 
451*7dd7cddfSDavid du Colombier /*
452*7dd7cddfSDavid du Colombier  *
453*7dd7cddfSDavid du Colombier  * Makes sure all the non-option command line arguments are processed. If we get
454*7dd7cddfSDavid du Colombier  * here and there aren't any arguments left, or if '-' is one of the input files
455*7dd7cddfSDavid du Colombier  * we'll process stdin.
456*7dd7cddfSDavid du Colombier  *
457*7dd7cddfSDavid du Colombier  */
458*7dd7cddfSDavid du Colombier 
459*7dd7cddfSDavid du Colombier     fp_in = stdin;
460*7dd7cddfSDavid du Colombier 
461*7dd7cddfSDavid du Colombier     if ( argc < 1 )
462*7dd7cddfSDavid du Colombier 	text();
463*7dd7cddfSDavid du Colombier     else {				/* at least one argument is left */
464*7dd7cddfSDavid du Colombier 	while ( argc > 0 )  {
465*7dd7cddfSDavid du Colombier 	    if ( strcmp(*argv, "-") == 0 )
466*7dd7cddfSDavid du Colombier 		fp_in = stdin;
467*7dd7cddfSDavid du Colombier 	    else if ( (fp_in = fopen(*argv, "r")) == NULL )
468*7dd7cddfSDavid du Colombier 		error(FATAL, "can't open %s", *argv);
469*7dd7cddfSDavid du Colombier 	    text();
470*7dd7cddfSDavid du Colombier 	    if ( fp_in != stdin )
471*7dd7cddfSDavid du Colombier 		fclose(fp_in);
472*7dd7cddfSDavid du Colombier 	    argc--;
473*7dd7cddfSDavid du Colombier 	    argv++;
474*7dd7cddfSDavid du Colombier 	}   /* End while */
475*7dd7cddfSDavid du Colombier     }   /* End else */
476*7dd7cddfSDavid du Colombier 
477*7dd7cddfSDavid du Colombier }   /* End of arguments */
478*7dd7cddfSDavid du Colombier 
479*7dd7cddfSDavid du Colombier /*****************************************************************************/
480*7dd7cddfSDavid du Colombier 
done()481*7dd7cddfSDavid du Colombier done()
482*7dd7cddfSDavid du Colombier 
483*7dd7cddfSDavid du Colombier {
484*7dd7cddfSDavid du Colombier 
485*7dd7cddfSDavid du Colombier /*
486*7dd7cddfSDavid du Colombier  *
487*7dd7cddfSDavid du Colombier  * Finished with all the input files, so mark the end of the pages, make sure the
488*7dd7cddfSDavid du Colombier  * last page is printed, and restore the initial environment.
489*7dd7cddfSDavid du Colombier  *
490*7dd7cddfSDavid du Colombier  */
491*7dd7cddfSDavid du Colombier 
492*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s", TRAILER);
493*7dd7cddfSDavid du Colombier     fprintf(stdout, "done\n");
494*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s %s\n", DOCUMENTFONTS, fontname);
495*7dd7cddfSDavid du Colombier     fprintf(stdout, "%s %d\n", PAGES, printed);
496*7dd7cddfSDavid du Colombier 
497*7dd7cddfSDavid du Colombier }   /* End of done */
498*7dd7cddfSDavid du Colombier 
499*7dd7cddfSDavid du Colombier /*****************************************************************************/
500*7dd7cddfSDavid du Colombier 
account()501*7dd7cddfSDavid du Colombier account()
502*7dd7cddfSDavid du Colombier 
503*7dd7cddfSDavid du Colombier {
504*7dd7cddfSDavid du Colombier 
505*7dd7cddfSDavid du Colombier /*
506*7dd7cddfSDavid du Colombier  *
507*7dd7cddfSDavid du Colombier  * Writes an accounting record to *fp_acct provided it's not NULL. Accounting
508*7dd7cddfSDavid du Colombier  * is requested using the -A or -J options.
509*7dd7cddfSDavid du Colombier  *
510*7dd7cddfSDavid du Colombier  */
511*7dd7cddfSDavid du Colombier 
512*7dd7cddfSDavid du Colombier     if ( fp_acct != NULL )
513*7dd7cddfSDavid du Colombier 	fprintf(fp_acct, " print %d\n copies %d\n", printed, copies);
514*7dd7cddfSDavid du Colombier 
515*7dd7cddfSDavid du Colombier }   /* End of account */
516*7dd7cddfSDavid du Colombier 
517*7dd7cddfSDavid du Colombier /*****************************************************************************/
518*7dd7cddfSDavid du Colombier 
text()519*7dd7cddfSDavid du Colombier text()
520*7dd7cddfSDavid du Colombier 
521*7dd7cddfSDavid du Colombier {
522*7dd7cddfSDavid du Colombier 
523*7dd7cddfSDavid du Colombier     int		ch;			/* next input character */
524*7dd7cddfSDavid du Colombier 
525*7dd7cddfSDavid du Colombier /*
526*7dd7cddfSDavid du Colombier  *
527*7dd7cddfSDavid du Colombier  * Translates the next input file into PostScript. The redirect(-1) call forces
528*7dd7cddfSDavid du Colombier  * the initial output to go to /dev/null - so the stuff formfeed() does at the
529*7dd7cddfSDavid du Colombier  * end of each page doesn't go to stdout.
530*7dd7cddfSDavid du Colombier  *
531*7dd7cddfSDavid du Colombier  */
532*7dd7cddfSDavid du Colombier 
533*7dd7cddfSDavid du Colombier     redirect(-1);			/* get ready for the first page */
534*7dd7cddfSDavid du Colombier     formfeed();				/* force PAGE comment etc. */
535*7dd7cddfSDavid du Colombier     inittabs();
536*7dd7cddfSDavid du Colombier 
537*7dd7cddfSDavid du Colombier     while ( (ch = getc(fp_in)) != EOF )
538*7dd7cddfSDavid du Colombier 	switch ( ch )  {
539*7dd7cddfSDavid du Colombier 	    case '\010':		/* backspace */
540*7dd7cddfSDavid du Colombier 		    backspace();
541*7dd7cddfSDavid du Colombier 		    break;
542*7dd7cddfSDavid du Colombier 
543*7dd7cddfSDavid du Colombier 	    case '\011':		/* horizontal tab */
544*7dd7cddfSDavid du Colombier 		    htab();
545*7dd7cddfSDavid du Colombier 		    break;
546*7dd7cddfSDavid du Colombier 
547*7dd7cddfSDavid du Colombier 	    case '\012':		/* new line */
548*7dd7cddfSDavid du Colombier 		    linefeed();
549*7dd7cddfSDavid du Colombier 		    break;
550*7dd7cddfSDavid du Colombier 
551*7dd7cddfSDavid du Colombier 	    case '\013':		/* vertical tab */
552*7dd7cddfSDavid du Colombier 		    vtab();
553*7dd7cddfSDavid du Colombier 		    break;
554*7dd7cddfSDavid du Colombier 
555*7dd7cddfSDavid du Colombier 	    case '\014':		/* form feed */
556*7dd7cddfSDavid du Colombier 		    formfeed();
557*7dd7cddfSDavid du Colombier 		    break;
558*7dd7cddfSDavid du Colombier 
559*7dd7cddfSDavid du Colombier 	    case '\015':		/* carriage return */
560*7dd7cddfSDavid du Colombier 		    carriage();
561*7dd7cddfSDavid du Colombier 		    break;
562*7dd7cddfSDavid du Colombier 
563*7dd7cddfSDavid du Colombier 	    case '\016':		/* extended character set - SO */
564*7dd7cddfSDavid du Colombier 		    break;
565*7dd7cddfSDavid du Colombier 
566*7dd7cddfSDavid du Colombier 	    case '\017':		/* extended character set - SI */
567*7dd7cddfSDavid du Colombier 		    break;
568*7dd7cddfSDavid du Colombier 
569*7dd7cddfSDavid du Colombier 	    case '\031':		/* next char from supplementary set */
570*7dd7cddfSDavid du Colombier 		    break;
571*7dd7cddfSDavid du Colombier 
572*7dd7cddfSDavid du Colombier 	    case '\033':		/* 2 or 3 byte escape sequence */
573*7dd7cddfSDavid du Colombier 		    escape();
574*7dd7cddfSDavid du Colombier 		    break;
575*7dd7cddfSDavid du Colombier 
576*7dd7cddfSDavid du Colombier 	    default:
577*7dd7cddfSDavid du Colombier 		    oput(ch);
578*7dd7cddfSDavid du Colombier 		    break;
579*7dd7cddfSDavid du Colombier 	}   /* End switch */
580*7dd7cddfSDavid du Colombier 
581*7dd7cddfSDavid du Colombier     formfeed();				/* next file starts on a new page? */
582*7dd7cddfSDavid du Colombier 
583*7dd7cddfSDavid du Colombier }   /* End of text */
584*7dd7cddfSDavid du Colombier 
585*7dd7cddfSDavid du Colombier /*****************************************************************************/
586*7dd7cddfSDavid du Colombier 
inittabs()587*7dd7cddfSDavid du Colombier inittabs()
588*7dd7cddfSDavid du Colombier 
589*7dd7cddfSDavid du Colombier {
590*7dd7cddfSDavid du Colombier 
591*7dd7cddfSDavid du Colombier     int		i;			/* loop index */
592*7dd7cddfSDavid du Colombier 
593*7dd7cddfSDavid du Colombier /*
594*7dd7cddfSDavid du Colombier  *
595*7dd7cddfSDavid du Colombier  * Initializes the horizontal and vertical tab arrays. The way tabs are handled is
596*7dd7cddfSDavid du Colombier  * quite inefficient and may not work for all initial hmi or vmi values.
597*7dd7cddfSDavid du Colombier  *
598*7dd7cddfSDavid du Colombier  */
599*7dd7cddfSDavid du Colombier 
600*7dd7cddfSDavid du Colombier     for ( i = 0; i < COLUMNS; i++ )
601*7dd7cddfSDavid du Colombier 	htabstops[i] = ((i % 8) == 0) ? ON : OFF;
602*7dd7cddfSDavid du Colombier 
603*7dd7cddfSDavid du Colombier     for ( i = 0; i < ROWS; i++ )
604*7dd7cddfSDavid du Colombier 	vtabstops[i] = ((i * ovmi) > BOTTOMMARGIN) ? ON : OFF;
605*7dd7cddfSDavid du Colombier 
606*7dd7cddfSDavid du Colombier }   /* End of inittabs */
607*7dd7cddfSDavid du Colombier 
608*7dd7cddfSDavid du Colombier /*****************************************************************************/
609*7dd7cddfSDavid du Colombier 
cleartabs()610*7dd7cddfSDavid du Colombier cleartabs()
611*7dd7cddfSDavid du Colombier 
612*7dd7cddfSDavid du Colombier {
613*7dd7cddfSDavid du Colombier 
614*7dd7cddfSDavid du Colombier     int		i;			/* loop index */
615*7dd7cddfSDavid du Colombier 
616*7dd7cddfSDavid du Colombier /*
617*7dd7cddfSDavid du Colombier  *
618*7dd7cddfSDavid du Colombier  * Clears all horizontal and vertical tab stops.
619*7dd7cddfSDavid du Colombier  *
620*7dd7cddfSDavid du Colombier  */
621*7dd7cddfSDavid du Colombier 
622*7dd7cddfSDavid du Colombier     for ( i = 0; i < ROWS; i++ )
623*7dd7cddfSDavid du Colombier 	htabstops[i] = OFF;
624*7dd7cddfSDavid du Colombier 
625*7dd7cddfSDavid du Colombier     for ( i = 0; i < COLUMNS; i++ )
626*7dd7cddfSDavid du Colombier 	vtabstops[i] = OFF;
627*7dd7cddfSDavid du Colombier 
628*7dd7cddfSDavid du Colombier }   /* End of cleartabs */
629*7dd7cddfSDavid du Colombier 
630*7dd7cddfSDavid du Colombier /*****************************************************************************/
631*7dd7cddfSDavid du Colombier 
formfeed()632*7dd7cddfSDavid du Colombier formfeed()
633*7dd7cddfSDavid du Colombier 
634*7dd7cddfSDavid du Colombier {
635*7dd7cddfSDavid du Colombier 
636*7dd7cddfSDavid du Colombier /*
637*7dd7cddfSDavid du Colombier  *
638*7dd7cddfSDavid du Colombier  * Called whenever we've finished with the last page and want to get ready for the
639*7dd7cddfSDavid du Colombier  * next one. Also used at the beginning and end of each input file, so we have to
640*7dd7cddfSDavid du Colombier  * be careful about what's done. I've added a simple test before the showpage that
641*7dd7cddfSDavid du Colombier  * should eliminate the extra blank page that was put out at the end of many jobs,
642*7dd7cddfSDavid du Colombier  * but the PAGES comments may be wrong.
643*7dd7cddfSDavid du Colombier  *
644*7dd7cddfSDavid du Colombier  */
645*7dd7cddfSDavid du Colombier 
646*7dd7cddfSDavid du Colombier     if ( fp_out == stdout )		/* count the last page */
647*7dd7cddfSDavid du Colombier 	printed++;
648*7dd7cddfSDavid du Colombier 
649*7dd7cddfSDavid du Colombier     endline();				/* print the last line */
650*7dd7cddfSDavid du Colombier 
651*7dd7cddfSDavid du Colombier     fprintf(fp_out, "cleartomark\n");
652*7dd7cddfSDavid du Colombier     if ( feof(fp_in) == 0 || markedpage == TRUE )
653*7dd7cddfSDavid du Colombier 	fprintf(fp_out, "showpage\n");
654*7dd7cddfSDavid du Colombier     fprintf(fp_out, "saveobj restore\n");
655*7dd7cddfSDavid du Colombier     fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed);
656*7dd7cddfSDavid du Colombier 
657*7dd7cddfSDavid du Colombier     if ( ungetc(getc(fp_in), fp_in) == EOF )
658*7dd7cddfSDavid du Colombier 	redirect(-1);
659*7dd7cddfSDavid du Colombier     else redirect(++page);
660*7dd7cddfSDavid du Colombier 
661*7dd7cddfSDavid du Colombier     fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1);
662*7dd7cddfSDavid du Colombier     fprintf(fp_out, "/saveobj save def\n");
663*7dd7cddfSDavid du Colombier     fprintf(fp_out, "mark\n");
664*7dd7cddfSDavid du Colombier     writerequest(printed+1, fp_out);
665*7dd7cddfSDavid du Colombier     fprintf(fp_out, "%d pagesetup\n", printed+1);
666*7dd7cddfSDavid du Colombier 
667*7dd7cddfSDavid du Colombier     vgoto(topmargin);
668*7dd7cddfSDavid du Colombier     hgoto(leftmargin);
669*7dd7cddfSDavid du Colombier 
670*7dd7cddfSDavid du Colombier     markedpage = FALSE;
671*7dd7cddfSDavid du Colombier 
672*7dd7cddfSDavid du Colombier }   /* End of formfeed */
673*7dd7cddfSDavid du Colombier 
674*7dd7cddfSDavid du Colombier /*****************************************************************************/
675*7dd7cddfSDavid du Colombier 
linefeed()676*7dd7cddfSDavid du Colombier linefeed()
677*7dd7cddfSDavid du Colombier 
678*7dd7cddfSDavid du Colombier {
679*7dd7cddfSDavid du Colombier 
680*7dd7cddfSDavid du Colombier     int		line = 0;		/* current line - based on ovmi */
681*7dd7cddfSDavid du Colombier 
682*7dd7cddfSDavid du Colombier /*
683*7dd7cddfSDavid du Colombier  *
684*7dd7cddfSDavid du Colombier  * Adjust our current vertical position. If we've passed the bottom of the page
685*7dd7cddfSDavid du Colombier  * or exceeded the number of lines per page, print it and go to the upper left
686*7dd7cddfSDavid du Colombier  * corner of the next page. This routine is also called from carriage() if crislf
687*7dd7cddfSDavid du Colombier  * is ON.
688*7dd7cddfSDavid du Colombier  *
689*7dd7cddfSDavid du Colombier  */
690*7dd7cddfSDavid du Colombier 
691*7dd7cddfSDavid du Colombier     vmot(vmi);
692*7dd7cddfSDavid du Colombier 
693*7dd7cddfSDavid du Colombier     if ( lfiscr == ON )
694*7dd7cddfSDavid du Colombier 	hgoto(leftmargin);
695*7dd7cddfSDavid du Colombier 
696*7dd7cddfSDavid du Colombier     if ( linespp > 0 )			/* means something so see where we are */
697*7dd7cddfSDavid du Colombier 	line = vpos / ovmi + 1;
698*7dd7cddfSDavid du Colombier 
699*7dd7cddfSDavid du Colombier     if ( vpos > bottommargin || line > linespp )
700*7dd7cddfSDavid du Colombier 	formfeed();
701*7dd7cddfSDavid du Colombier 
702*7dd7cddfSDavid du Colombier }   /* End of linefeed */
703*7dd7cddfSDavid du Colombier 
704*7dd7cddfSDavid du Colombier /*****************************************************************************/
705*7dd7cddfSDavid du Colombier 
carriage()706*7dd7cddfSDavid du Colombier carriage()
707*7dd7cddfSDavid du Colombier 
708*7dd7cddfSDavid du Colombier {
709*7dd7cddfSDavid du Colombier 
710*7dd7cddfSDavid du Colombier /*
711*7dd7cddfSDavid du Colombier  *
712*7dd7cddfSDavid du Colombier  * Handles carriage return character. If crislf is ON we'll generate a line feed
713*7dd7cddfSDavid du Colombier  * every time we get a carriage return character.
714*7dd7cddfSDavid du Colombier  *
715*7dd7cddfSDavid du Colombier  */
716*7dd7cddfSDavid du Colombier 
717*7dd7cddfSDavid du Colombier     if ( shadowprint == ON )		/* back to normal mode */
718*7dd7cddfSDavid du Colombier 	changefont(fontname);
719*7dd7cddfSDavid du Colombier 
720*7dd7cddfSDavid du Colombier     advance = 1;
721*7dd7cddfSDavid du Colombier     shadowprint = OFF;
722*7dd7cddfSDavid du Colombier 
723*7dd7cddfSDavid du Colombier     hgoto(leftmargin);
724*7dd7cddfSDavid du Colombier 
725*7dd7cddfSDavid du Colombier     if ( crislf == ON )
726*7dd7cddfSDavid du Colombier 	linefeed();
727*7dd7cddfSDavid du Colombier 
728*7dd7cddfSDavid du Colombier }   /* End of carriage */
729*7dd7cddfSDavid du Colombier 
730*7dd7cddfSDavid du Colombier /*****************************************************************************/
731*7dd7cddfSDavid du Colombier 
htab()732*7dd7cddfSDavid du Colombier htab()
733*7dd7cddfSDavid du Colombier 
734*7dd7cddfSDavid du Colombier {
735*7dd7cddfSDavid du Colombier 
736*7dd7cddfSDavid du Colombier     int		col;			/* 'column' we'll be at next */
737*7dd7cddfSDavid du Colombier     int		i;			/* loop index */
738*7dd7cddfSDavid du Colombier 
739*7dd7cddfSDavid du Colombier /*
740*7dd7cddfSDavid du Colombier  *
741*7dd7cddfSDavid du Colombier  * Tries to figure out where the next tab stop is. Wasn't positive about this
742*7dd7cddfSDavid du Colombier  * one, since hmi can change. I'll assume columns are determined by the original
743*7dd7cddfSDavid du Colombier  * value of hmi. That fixes them on the page, which seems to make more sense than
744*7dd7cddfSDavid du Colombier  * letting them float all over the place.
745*7dd7cddfSDavid du Colombier  *
746*7dd7cddfSDavid du Colombier  */
747*7dd7cddfSDavid du Colombier 
748*7dd7cddfSDavid du Colombier     endline();
749*7dd7cddfSDavid du Colombier 
750*7dd7cddfSDavid du Colombier     col = hpos/ohmi + 1;
751*7dd7cddfSDavid du Colombier     for ( i = col; i < ROWS; i++ )
752*7dd7cddfSDavid du Colombier 	if ( htabstops[i] == ON )  {
753*7dd7cddfSDavid du Colombier 	    col = i;
754*7dd7cddfSDavid du Colombier 	    break;
755*7dd7cddfSDavid du Colombier 	}   /* End if */
756*7dd7cddfSDavid du Colombier 
757*7dd7cddfSDavid du Colombier     hgoto(col * ohmi);
758*7dd7cddfSDavid du Colombier     lastx = hpos;
759*7dd7cddfSDavid du Colombier 
760*7dd7cddfSDavid du Colombier }   /* End of htab */
761*7dd7cddfSDavid du Colombier 
762*7dd7cddfSDavid du Colombier /*****************************************************************************/
763*7dd7cddfSDavid du Colombier 
vtab()764*7dd7cddfSDavid du Colombier vtab()
765*7dd7cddfSDavid du Colombier 
766*7dd7cddfSDavid du Colombier {
767*7dd7cddfSDavid du Colombier 
768*7dd7cddfSDavid du Colombier     int		line;			/* line we'll be at next */
769*7dd7cddfSDavid du Colombier     int		i;			/* loop index */
770*7dd7cddfSDavid du Colombier 
771*7dd7cddfSDavid du Colombier /*
772*7dd7cddfSDavid du Colombier  *
773*7dd7cddfSDavid du Colombier  * Looks for the next vertical tab stop in the vtabstops[] array and moves to that
774*7dd7cddfSDavid du Colombier  * line. If we don't find a tab we'll just move down one line - shouldn't happen.
775*7dd7cddfSDavid du Colombier  *
776*7dd7cddfSDavid du Colombier  */
777*7dd7cddfSDavid du Colombier 
778*7dd7cddfSDavid du Colombier     endline();
779*7dd7cddfSDavid du Colombier 
780*7dd7cddfSDavid du Colombier     line = vpos/ovmi + 1;
781*7dd7cddfSDavid du Colombier     for ( i = line; i < COLUMNS; i++ )
782*7dd7cddfSDavid du Colombier 	if ( vtabstops[i] == ON )  {
783*7dd7cddfSDavid du Colombier 	    line = i;
784*7dd7cddfSDavid du Colombier 	    break;
785*7dd7cddfSDavid du Colombier 	}   /* End if */
786*7dd7cddfSDavid du Colombier 
787*7dd7cddfSDavid du Colombier     vgoto(line * ovmi);
788*7dd7cddfSDavid du Colombier 
789*7dd7cddfSDavid du Colombier }   /* End of vtab */
790*7dd7cddfSDavid du Colombier 
791*7dd7cddfSDavid du Colombier /*****************************************************************************/
792*7dd7cddfSDavid du Colombier 
backspace()793*7dd7cddfSDavid du Colombier backspace()
794*7dd7cddfSDavid du Colombier 
795*7dd7cddfSDavid du Colombier {
796*7dd7cddfSDavid du Colombier 
797*7dd7cddfSDavid du Colombier /*
798*7dd7cddfSDavid du Colombier  *
799*7dd7cddfSDavid du Colombier  * Moves backwards a distance equal to the current value of hmi, but don't go
800*7dd7cddfSDavid du Colombier  * past the left margin.
801*7dd7cddfSDavid du Colombier  *
802*7dd7cddfSDavid du Colombier  */
803*7dd7cddfSDavid du Colombier 
804*7dd7cddfSDavid du Colombier     endline();
805*7dd7cddfSDavid du Colombier 
806*7dd7cddfSDavid du Colombier     if ( hpos - leftmargin >= hmi )
807*7dd7cddfSDavid du Colombier 	hmot(-hmi);
808*7dd7cddfSDavid du Colombier     else hgoto(leftmargin);		/* maybe just ignore the backspace?? */
809*7dd7cddfSDavid du Colombier 
810*7dd7cddfSDavid du Colombier     lastx = hpos;
811*7dd7cddfSDavid du Colombier 
812*7dd7cddfSDavid du Colombier }   /* End of backspace */
813*7dd7cddfSDavid du Colombier 
814*7dd7cddfSDavid du Colombier /*****************************************************************************/
815*7dd7cddfSDavid du Colombier 
escape()816*7dd7cddfSDavid du Colombier escape()
817*7dd7cddfSDavid du Colombier 
818*7dd7cddfSDavid du Colombier {
819*7dd7cddfSDavid du Colombier 
820*7dd7cddfSDavid du Colombier     int		ch;			/* control character */
821*7dd7cddfSDavid du Colombier 
822*7dd7cddfSDavid du Colombier /*
823*7dd7cddfSDavid du Colombier  *
824*7dd7cddfSDavid du Colombier  * Handles special codes that are expected to follow an escape character. The
825*7dd7cddfSDavid du Colombier  * initial escape character is followed by one or two bytes.
826*7dd7cddfSDavid du Colombier  *
827*7dd7cddfSDavid du Colombier  */
828*7dd7cddfSDavid du Colombier 
829*7dd7cddfSDavid du Colombier     switch ( ch = getc(fp_in) ) {
830*7dd7cddfSDavid du Colombier 	case 'T':			/* top margin */
831*7dd7cddfSDavid du Colombier 		topmargin = vpos;
832*7dd7cddfSDavid du Colombier 		break;
833*7dd7cddfSDavid du Colombier 
834*7dd7cddfSDavid du Colombier 	case 'L':			/* bottom margin */
835*7dd7cddfSDavid du Colombier 		bottommargin = vpos;
836*7dd7cddfSDavid du Colombier 		break;
837*7dd7cddfSDavid du Colombier 
838*7dd7cddfSDavid du Colombier 	case 'C':			/* clear top and bottom margins */
839*7dd7cddfSDavid du Colombier 		bottommargin = BOTTOMMARGIN;
840*7dd7cddfSDavid du Colombier 		topmargin = TOPMARGIN;
841*7dd7cddfSDavid du Colombier 		break;
842*7dd7cddfSDavid du Colombier 
843*7dd7cddfSDavid du Colombier 	case '9':			/* left margin */
844*7dd7cddfSDavid du Colombier 		leftmargin = hpos;
845*7dd7cddfSDavid du Colombier 		break;
846*7dd7cddfSDavid du Colombier 
847*7dd7cddfSDavid du Colombier 	case '0':			/* right margin */
848*7dd7cddfSDavid du Colombier 		rightmargin = hpos;
849*7dd7cddfSDavid du Colombier 		break;
850*7dd7cddfSDavid du Colombier 
851*7dd7cddfSDavid du Colombier 	case '1':			/* set horizontal tab */
852*7dd7cddfSDavid du Colombier 		htabstops[hpos/ohmi] = ON;
853*7dd7cddfSDavid du Colombier 		break;
854*7dd7cddfSDavid du Colombier 
855*7dd7cddfSDavid du Colombier 	case '8':			/* clear horizontal tab at hpos */
856*7dd7cddfSDavid du Colombier 		htabstops[hpos/ohmi] = OFF;
857*7dd7cddfSDavid du Colombier 		break;
858*7dd7cddfSDavid du Colombier 
859*7dd7cddfSDavid du Colombier 	case '-':			/* set vertical tab */
860*7dd7cddfSDavid du Colombier 		vtabstops[vpos/ovmi] = ON;
861*7dd7cddfSDavid du Colombier 		break;
862*7dd7cddfSDavid du Colombier 
863*7dd7cddfSDavid du Colombier 	case '2':			/* clear all tabs */
864*7dd7cddfSDavid du Colombier 		cleartabs();
865*7dd7cddfSDavid du Colombier 		break;
866*7dd7cddfSDavid du Colombier 
867*7dd7cddfSDavid du Colombier 	case '\014':			/* set lines per page */
868*7dd7cddfSDavid du Colombier 		linespp = getc(fp_in);
869*7dd7cddfSDavid du Colombier 		break;
870*7dd7cddfSDavid du Colombier 
871*7dd7cddfSDavid du Colombier 	case '\037':			/* set hmi to next byte minus 1 */
872*7dd7cddfSDavid du Colombier 		hmi = HSCALE * (getc(fp_in) - 1);
873*7dd7cddfSDavid du Colombier 		break;
874*7dd7cddfSDavid du Colombier 
875*7dd7cddfSDavid du Colombier 	case 'S':			/* reset hmi to default */
876*7dd7cddfSDavid du Colombier 		hmi = ohmi;
877*7dd7cddfSDavid du Colombier 		break;
878*7dd7cddfSDavid du Colombier 
879*7dd7cddfSDavid du Colombier 	case '\011':			/* move to column given by next byte */
880*7dd7cddfSDavid du Colombier 		hgoto((getc(fp_in)-1) * ohmi);
881*7dd7cddfSDavid du Colombier 		break;
882*7dd7cddfSDavid du Colombier 
883*7dd7cddfSDavid du Colombier 	case '?':			/* do carriage return after line feed */
884*7dd7cddfSDavid du Colombier 		lfiscr = ON;
885*7dd7cddfSDavid du Colombier 		break;
886*7dd7cddfSDavid du Colombier 
887*7dd7cddfSDavid du Colombier 	case '!':			/* don't generate carriage return */
888*7dd7cddfSDavid du Colombier 		lfiscr = OFF;
889*7dd7cddfSDavid du Colombier 		break;
890*7dd7cddfSDavid du Colombier 
891*7dd7cddfSDavid du Colombier 	case '5':			/* forward print mode */
892*7dd7cddfSDavid du Colombier 		advance = 1;
893*7dd7cddfSDavid du Colombier 		break;
894*7dd7cddfSDavid du Colombier 
895*7dd7cddfSDavid du Colombier 	case '6':			/* backward print mode */
896*7dd7cddfSDavid du Colombier 		advance = -1;
897*7dd7cddfSDavid du Colombier 		break;
898*7dd7cddfSDavid du Colombier 
899*7dd7cddfSDavid du Colombier 	case '\036':			/* set vmi to next byte minus 1 */
900*7dd7cddfSDavid du Colombier 		vmi = VSCALE * (getc(fp_in) - 1);
901*7dd7cddfSDavid du Colombier 		break;
902*7dd7cddfSDavid du Colombier 
903*7dd7cddfSDavid du Colombier 	case '\013':			/* move to line given by next byte */
904*7dd7cddfSDavid du Colombier 		vgoto((getc(fp_in)-1) * ovmi);
905*7dd7cddfSDavid du Colombier 		break;
906*7dd7cddfSDavid du Colombier 
907*7dd7cddfSDavid du Colombier 	case 'U':			/* positive half line feed */
908*7dd7cddfSDavid du Colombier 		vmot(vmi/2);
909*7dd7cddfSDavid du Colombier 		break;
910*7dd7cddfSDavid du Colombier 
911*7dd7cddfSDavid du Colombier 	case 'D':			/* negative half line feed */
912*7dd7cddfSDavid du Colombier 		vmot(-vmi/2);
913*7dd7cddfSDavid du Colombier 		break;
914*7dd7cddfSDavid du Colombier 
915*7dd7cddfSDavid du Colombier 	case '\012':			/* negative line feed */
916*7dd7cddfSDavid du Colombier 		vmot(-vmi);
917*7dd7cddfSDavid du Colombier 		break;
918*7dd7cddfSDavid du Colombier 
919*7dd7cddfSDavid du Colombier 	case '\015':			/* clear all margins */
920*7dd7cddfSDavid du Colombier 		bottommargin = BOTTOMMARGIN;
921*7dd7cddfSDavid du Colombier 		topmargin = TOPMARGIN;
922*7dd7cddfSDavid du Colombier 		leftmargin = BOTTOMMARGIN;
923*7dd7cddfSDavid du Colombier 		rightmargin = RIGHTMARGIN;
924*7dd7cddfSDavid du Colombier 		break;
925*7dd7cddfSDavid du Colombier 
926*7dd7cddfSDavid du Colombier 	case 'E':			/* auto underscore - use italic font */
927*7dd7cddfSDavid du Colombier 		changefont("/Courier-Oblique");
928*7dd7cddfSDavid du Colombier 		break;
929*7dd7cddfSDavid du Colombier 
930*7dd7cddfSDavid du Colombier 	case 'R':			/* disable auto underscore */
931*7dd7cddfSDavid du Colombier 		changefont(fontname);
932*7dd7cddfSDavid du Colombier 		break;
933*7dd7cddfSDavid du Colombier 
934*7dd7cddfSDavid du Colombier 	case 'O':			/* bold/shadow printing */
935*7dd7cddfSDavid du Colombier 	case 'W':
936*7dd7cddfSDavid du Colombier 		changefont("/Courier-Bold");
937*7dd7cddfSDavid du Colombier 		shadowprint = ON;
938*7dd7cddfSDavid du Colombier 		break;
939*7dd7cddfSDavid du Colombier 
940*7dd7cddfSDavid du Colombier 	case '&':			/* disable bold printing */
941*7dd7cddfSDavid du Colombier 		changefont(fontname);
942*7dd7cddfSDavid du Colombier 		shadowprint = OFF;
943*7dd7cddfSDavid du Colombier 		break;
944*7dd7cddfSDavid du Colombier 
945*7dd7cddfSDavid du Colombier 	case '/':			/* ignored 2 byte escapes */
946*7dd7cddfSDavid du Colombier 	case '\\':
947*7dd7cddfSDavid du Colombier 	case '<':
948*7dd7cddfSDavid du Colombier 	case '>':
949*7dd7cddfSDavid du Colombier 	case '%':
950*7dd7cddfSDavid du Colombier 	case '=':
951*7dd7cddfSDavid du Colombier 	case '.':
952*7dd7cddfSDavid du Colombier 	case '4':
953*7dd7cddfSDavid du Colombier 	case 'A':
954*7dd7cddfSDavid du Colombier 	case 'B':
955*7dd7cddfSDavid du Colombier 	case 'M':
956*7dd7cddfSDavid du Colombier 	case 'N':
957*7dd7cddfSDavid du Colombier 	case 'P':
958*7dd7cddfSDavid du Colombier 	case 'Q':
959*7dd7cddfSDavid du Colombier 	case 'X':
960*7dd7cddfSDavid du Colombier 	case '\010':
961*7dd7cddfSDavid du Colombier 		break;
962*7dd7cddfSDavid du Colombier 
963*7dd7cddfSDavid du Colombier 	case ',':			/* ignored 3 byte escapes */
964*7dd7cddfSDavid du Colombier 	case '\016':
965*7dd7cddfSDavid du Colombier 	case '\021':
966*7dd7cddfSDavid du Colombier 		getc(fp_in);
967*7dd7cddfSDavid du Colombier 		break;
968*7dd7cddfSDavid du Colombier 
969*7dd7cddfSDavid du Colombier 	case '3':			/* graphics mode - should quit! */
970*7dd7cddfSDavid du Colombier 	case '7':
971*7dd7cddfSDavid du Colombier 	case 'G':
972*7dd7cddfSDavid du Colombier 	case 'V':
973*7dd7cddfSDavid du Colombier 	case 'Y':
974*7dd7cddfSDavid du Colombier 	case 'Z':
975*7dd7cddfSDavid du Colombier 		error(FATAL, "graphics mode is not implemented");
976*7dd7cddfSDavid du Colombier 		break;
977*7dd7cddfSDavid du Colombier 
978*7dd7cddfSDavid du Colombier 	default:
979*7dd7cddfSDavid du Colombier 		error(FATAL, "missing case for escape o%o\n", ch);
980*7dd7cddfSDavid du Colombier 		break;
981*7dd7cddfSDavid du Colombier     }	/* End switch */
982*7dd7cddfSDavid du Colombier 
983*7dd7cddfSDavid du Colombier }   /* End of escape */
984*7dd7cddfSDavid du Colombier 
985*7dd7cddfSDavid du Colombier /*****************************************************************************/
986*7dd7cddfSDavid du Colombier 
vmot(n)987*7dd7cddfSDavid du Colombier vmot(n)
988*7dd7cddfSDavid du Colombier 
989*7dd7cddfSDavid du Colombier     int		n;			/* move this far vertically */
990*7dd7cddfSDavid du Colombier 
991*7dd7cddfSDavid du Colombier {
992*7dd7cddfSDavid du Colombier 
993*7dd7cddfSDavid du Colombier /*
994*7dd7cddfSDavid du Colombier  *
995*7dd7cddfSDavid du Colombier  * Move vertically n units from where we are.
996*7dd7cddfSDavid du Colombier  *
997*7dd7cddfSDavid du Colombier  */
998*7dd7cddfSDavid du Colombier 
999*7dd7cddfSDavid du Colombier     vpos += n;
1000*7dd7cddfSDavid du Colombier 
1001*7dd7cddfSDavid du Colombier }   /* End of vmot */
1002*7dd7cddfSDavid du Colombier 
1003*7dd7cddfSDavid du Colombier /*****************************************************************************/
1004*7dd7cddfSDavid du Colombier 
vgoto(n)1005*7dd7cddfSDavid du Colombier vgoto(n)
1006*7dd7cddfSDavid du Colombier 
1007*7dd7cddfSDavid du Colombier     int		n;			/* new vertical position */
1008*7dd7cddfSDavid du Colombier 
1009*7dd7cddfSDavid du Colombier {
1010*7dd7cddfSDavid du Colombier 
1011*7dd7cddfSDavid du Colombier /*
1012*7dd7cddfSDavid du Colombier  *
1013*7dd7cddfSDavid du Colombier  * Moves to absolute vertical position n.
1014*7dd7cddfSDavid du Colombier  *
1015*7dd7cddfSDavid du Colombier  */
1016*7dd7cddfSDavid du Colombier 
1017*7dd7cddfSDavid du Colombier     vpos = n;
1018*7dd7cddfSDavid du Colombier 
1019*7dd7cddfSDavid du Colombier }   /* End of vgoto */
1020*7dd7cddfSDavid du Colombier 
1021*7dd7cddfSDavid du Colombier /*****************************************************************************/
1022*7dd7cddfSDavid du Colombier 
hmot(n)1023*7dd7cddfSDavid du Colombier hmot(n)
1024*7dd7cddfSDavid du Colombier 
1025*7dd7cddfSDavid du Colombier     int		n;			/* move this horizontally */
1026*7dd7cddfSDavid du Colombier 
1027*7dd7cddfSDavid du Colombier {
1028*7dd7cddfSDavid du Colombier 
1029*7dd7cddfSDavid du Colombier /*
1030*7dd7cddfSDavid du Colombier  *
1031*7dd7cddfSDavid du Colombier  * Moves horizontally n units from our current position.
1032*7dd7cddfSDavid du Colombier  *
1033*7dd7cddfSDavid du Colombier  */
1034*7dd7cddfSDavid du Colombier 
1035*7dd7cddfSDavid du Colombier     hpos += n * advance;
1036*7dd7cddfSDavid du Colombier 
1037*7dd7cddfSDavid du Colombier     if ( hpos < leftmargin )
1038*7dd7cddfSDavid du Colombier 	hpos = leftmargin;
1039*7dd7cddfSDavid du Colombier 
1040*7dd7cddfSDavid du Colombier }   /* End of hmot */
1041*7dd7cddfSDavid du Colombier 
1042*7dd7cddfSDavid du Colombier /*****************************************************************************/
1043*7dd7cddfSDavid du Colombier 
hgoto(n)1044*7dd7cddfSDavid du Colombier hgoto(n)
1045*7dd7cddfSDavid du Colombier 
1046*7dd7cddfSDavid du Colombier     int		n;			/* go to this horizontal position */
1047*7dd7cddfSDavid du Colombier 
1048*7dd7cddfSDavid du Colombier {
1049*7dd7cddfSDavid du Colombier 
1050*7dd7cddfSDavid du Colombier /*
1051*7dd7cddfSDavid du Colombier  *
1052*7dd7cddfSDavid du Colombier  * Moves to absolute horizontal position n.
1053*7dd7cddfSDavid du Colombier  *
1054*7dd7cddfSDavid du Colombier  */
1055*7dd7cddfSDavid du Colombier 
1056*7dd7cddfSDavid du Colombier     hpos = n;
1057*7dd7cddfSDavid du Colombier 
1058*7dd7cddfSDavid du Colombier }   /* End of hgoto */
1059*7dd7cddfSDavid du Colombier 
1060*7dd7cddfSDavid du Colombier /*****************************************************************************/
1061*7dd7cddfSDavid du Colombier 
changefont(name)1062*7dd7cddfSDavid du Colombier changefont(name)
1063*7dd7cddfSDavid du Colombier 
1064*7dd7cddfSDavid du Colombier     char	*name;
1065*7dd7cddfSDavid du Colombier 
1066*7dd7cddfSDavid du Colombier {
1067*7dd7cddfSDavid du Colombier 
1068*7dd7cddfSDavid du Colombier /*
1069*7dd7cddfSDavid du Colombier  *
1070*7dd7cddfSDavid du Colombier  * Changes the current font. Used to get in and out of auto underscore and bold
1071*7dd7cddfSDavid du Colombier  * printing.
1072*7dd7cddfSDavid du Colombier  *
1073*7dd7cddfSDavid du Colombier  */
1074*7dd7cddfSDavid du Colombier 
1075*7dd7cddfSDavid du Colombier     endline();
1076*7dd7cddfSDavid du Colombier     fprintf(fp_out, "%s f\n", name);
1077*7dd7cddfSDavid du Colombier 
1078*7dd7cddfSDavid du Colombier }   /* End of changefont */
1079*7dd7cddfSDavid du Colombier 
1080*7dd7cddfSDavid du Colombier /*****************************************************************************/
1081*7dd7cddfSDavid du Colombier 
startline()1082*7dd7cddfSDavid du Colombier startline()
1083*7dd7cddfSDavid du Colombier 
1084*7dd7cddfSDavid du Colombier {
1085*7dd7cddfSDavid du Colombier 
1086*7dd7cddfSDavid du Colombier /*
1087*7dd7cddfSDavid du Colombier  *
1088*7dd7cddfSDavid du Colombier  * Called whenever we want to be certain we're ready to start pushing characters
1089*7dd7cddfSDavid du Colombier  * into an open string on the stack. If stringcount is positive we've already
1090*7dd7cddfSDavid du Colombier  * started, so there's nothing to do. The first string starts in column 1.
1091*7dd7cddfSDavid du Colombier  *
1092*7dd7cddfSDavid du Colombier  */
1093*7dd7cddfSDavid du Colombier 
1094*7dd7cddfSDavid du Colombier     if ( stringcount < 1 )  {
1095*7dd7cddfSDavid du Colombier 	putc('(', fp_out);
1096*7dd7cddfSDavid du Colombier 	stringstart = lastx = hpos;
1097*7dd7cddfSDavid du Colombier 	lasty = vpos;
1098*7dd7cddfSDavid du Colombier 	lasthmi = hmi;
1099*7dd7cddfSDavid du Colombier 	lastc = -1;
1100*7dd7cddfSDavid du Colombier 	prevx = -1;
1101*7dd7cddfSDavid du Colombier 	stringcount = 1;
1102*7dd7cddfSDavid du Colombier     }	/* End if */
1103*7dd7cddfSDavid du Colombier 
1104*7dd7cddfSDavid du Colombier }   /* End of startline */
1105*7dd7cddfSDavid du Colombier 
1106*7dd7cddfSDavid du Colombier /*****************************************************************************/
1107*7dd7cddfSDavid du Colombier 
endline()1108*7dd7cddfSDavid du Colombier endline()
1109*7dd7cddfSDavid du Colombier 
1110*7dd7cddfSDavid du Colombier {
1111*7dd7cddfSDavid du Colombier 
1112*7dd7cddfSDavid du Colombier /*
1113*7dd7cddfSDavid du Colombier  *
1114*7dd7cddfSDavid du Colombier  * Generates a call to the PostScript procedure that processes the text on the
1115*7dd7cddfSDavid du Colombier  * the stack - provided stringcount is positive.
1116*7dd7cddfSDavid du Colombier  *
1117*7dd7cddfSDavid du Colombier  */
1118*7dd7cddfSDavid du Colombier 
1119*7dd7cddfSDavid du Colombier     if ( stringcount > 0 )
1120*7dd7cddfSDavid du Colombier 	fprintf(fp_out, ")%d %d %d t\n", stringstart, lasty, lasthmi);
1121*7dd7cddfSDavid du Colombier 
1122*7dd7cddfSDavid du Colombier     stringcount = 0;
1123*7dd7cddfSDavid du Colombier 
1124*7dd7cddfSDavid du Colombier }   /* End of endline */
1125*7dd7cddfSDavid du Colombier 
1126*7dd7cddfSDavid du Colombier /*****************************************************************************/
1127*7dd7cddfSDavid du Colombier 
endstring()1128*7dd7cddfSDavid du Colombier endstring()
1129*7dd7cddfSDavid du Colombier 
1130*7dd7cddfSDavid du Colombier {
1131*7dd7cddfSDavid du Colombier 
1132*7dd7cddfSDavid du Colombier /*
1133*7dd7cddfSDavid du Colombier  *
1134*7dd7cddfSDavid du Colombier  * Takes the string we've been working on and adds it to the output file. Called
1135*7dd7cddfSDavid du Colombier  * when we need to adjust our horizontal position before starting a new string.
1136*7dd7cddfSDavid du Colombier  * Also called from endline() when we're done with the current line.
1137*7dd7cddfSDavid du Colombier  *
1138*7dd7cddfSDavid du Colombier  */
1139*7dd7cddfSDavid du Colombier 
1140*7dd7cddfSDavid du Colombier     if ( stringcount > 0 )  {
1141*7dd7cddfSDavid du Colombier 	fprintf(fp_out, ")%d(", stringstart);
1142*7dd7cddfSDavid du Colombier 	lastx = stringstart = hpos;
1143*7dd7cddfSDavid du Colombier 	stringcount++;
1144*7dd7cddfSDavid du Colombier     }	/* End if */
1145*7dd7cddfSDavid du Colombier 
1146*7dd7cddfSDavid du Colombier }   /* End of endstring */
1147*7dd7cddfSDavid du Colombier 
1148*7dd7cddfSDavid du Colombier /*****************************************************************************/
1149*7dd7cddfSDavid du Colombier 
oput(ch)1150*7dd7cddfSDavid du Colombier oput(ch)
1151*7dd7cddfSDavid du Colombier 
1152*7dd7cddfSDavid du Colombier     int		ch;			/* next output character */
1153*7dd7cddfSDavid du Colombier 
1154*7dd7cddfSDavid du Colombier {
1155*7dd7cddfSDavid du Colombier 
1156*7dd7cddfSDavid du Colombier /*
1157*7dd7cddfSDavid du Colombier  *
1158*7dd7cddfSDavid du Colombier  * Responsible for adding all printing characters from the input file to the
1159*7dd7cddfSDavid du Colombier  * open string on top of the stack. The only other characters that end up in
1160*7dd7cddfSDavid du Colombier  * that string are the quotes required for special characters. Reverse printing
1161*7dd7cddfSDavid du Colombier  * mode hasn't been tested but it should be close. hpos and lastx should disagree
1162*7dd7cddfSDavid du Colombier  * each time (except after startline() does something), and that should force a
1163*7dd7cddfSDavid du Colombier  * call to endstring() for every character.
1164*7dd7cddfSDavid du Colombier  *
1165*7dd7cddfSDavid du Colombier  */
1166*7dd7cddfSDavid du Colombier 
1167*7dd7cddfSDavid du Colombier     if ( stringcount > 100 )		/* don't put too much on the stack */
1168*7dd7cddfSDavid du Colombier 	endline();
1169*7dd7cddfSDavid du Colombier 
1170*7dd7cddfSDavid du Colombier     if ( vpos != lasty )
1171*7dd7cddfSDavid du Colombier 	endline();
1172*7dd7cddfSDavid du Colombier 
1173*7dd7cddfSDavid du Colombier     if ( advance == -1 )		/* for reverse printing - move first */
1174*7dd7cddfSDavid du Colombier 	hmot(hmi);
1175*7dd7cddfSDavid du Colombier 
1176*7dd7cddfSDavid du Colombier     startline();
1177*7dd7cddfSDavid du Colombier 
1178*7dd7cddfSDavid du Colombier     if ( lastc != ch || hpos != prevx )  {
1179*7dd7cddfSDavid du Colombier 	if ( lastx != hpos )
1180*7dd7cddfSDavid du Colombier 	    endstring();
1181*7dd7cddfSDavid du Colombier 
1182*7dd7cddfSDavid du Colombier 	if ( isascii(ch) && isprint(ch) ) {
1183*7dd7cddfSDavid du Colombier 	    if ( ch == '\\' || ch == '(' || ch == ')' )
1184*7dd7cddfSDavid du Colombier 		putc('\\', fp_out);
1185*7dd7cddfSDavid du Colombier 	    putc(ch, fp_out);
1186*7dd7cddfSDavid du Colombier 	} else fprintf(fp_out, "\\%.3o", ch & 0377);
1187*7dd7cddfSDavid du Colombier 
1188*7dd7cddfSDavid du Colombier 	lastc = ch;
1189*7dd7cddfSDavid du Colombier 	prevx = hpos;
1190*7dd7cddfSDavid du Colombier 	lastx += lasthmi;
1191*7dd7cddfSDavid du Colombier     }	/* End if */
1192*7dd7cddfSDavid du Colombier 
1193*7dd7cddfSDavid du Colombier     if ( advance != -1 )
1194*7dd7cddfSDavid du Colombier 	hmot(hmi);
1195*7dd7cddfSDavid du Colombier 
1196*7dd7cddfSDavid du Colombier     markedpage = TRUE;
1197*7dd7cddfSDavid du Colombier 
1198*7dd7cddfSDavid du Colombier }   /* End of oput */
1199*7dd7cddfSDavid du Colombier 
1200*7dd7cddfSDavid du Colombier /*****************************************************************************/
1201*7dd7cddfSDavid du Colombier 
redirect(pg)1202*7dd7cddfSDavid du Colombier redirect(pg)
1203*7dd7cddfSDavid du Colombier 
1204*7dd7cddfSDavid du Colombier     int		pg;			/* next page we're printing */
1205*7dd7cddfSDavid du Colombier 
1206*7dd7cddfSDavid du Colombier {
1207*7dd7cddfSDavid du Colombier 
1208*7dd7cddfSDavid du Colombier     static FILE	*fp_null = NULL;	/* if output is turned off */
1209*7dd7cddfSDavid du Colombier 
1210*7dd7cddfSDavid du Colombier /*
1211*7dd7cddfSDavid du Colombier  *
1212*7dd7cddfSDavid du Colombier  * If we're not supposed to print page pg, fp_out will be directed to /dev/null,
1213*7dd7cddfSDavid du Colombier  * otherwise output goes to stdout.
1214*7dd7cddfSDavid du Colombier  *
1215*7dd7cddfSDavid du Colombier  */
1216*7dd7cddfSDavid du Colombier 
1217*7dd7cddfSDavid du Colombier     if ( pg >= 0 && in_olist(pg) == ON )
1218*7dd7cddfSDavid du Colombier 	fp_out = stdout;
1219*7dd7cddfSDavid du Colombier     else if ( (fp_out = fp_null) == NULL )
1220*7dd7cddfSDavid du Colombier 	fp_out = fp_null = fopen("/dev/null", "w");
1221*7dd7cddfSDavid du Colombier 
1222*7dd7cddfSDavid du Colombier }   /* End of redirect */
1223*7dd7cddfSDavid du Colombier 
1224*7dd7cddfSDavid du Colombier /*****************************************************************************/
1225*7dd7cddfSDavid du Colombier 
1226