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