1 #include <config.h>
2 #include <stdio.h>
3 #ifdef HAVE_STDLIB_H
4 #include <stdlib.h>
5 #endif
6 #ifdef HAVE_STRING_H
7 #include <string.h>
8 #endif
9 #ifdef HAVE_SYS_STAT_H
10 #include <sys/stat.h>
11 #endif
12 
13 #if TIME_WITH_SYS_TIME
14 #include <sys/time.h>
15 #include <time.h>
16 #else
17 #if HAVE_SYS_TIME_H
18 #include <sys/time.h>
19 #else
20 #include <time.h>
21 #endif
22 #endif
23 
24 #ifdef HAVE_STAT_H
25 #include <stat.h>
26 #endif
27 
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 
32 #include "mad.h"
33 
zfree(unsigned char * s)34 static void zfree (unsigned char *s)
35 {
36     memset (s, 0, strlen ((char *) s));
37     free (s);
38 }
39 
40 /*  Some configuration constants, meassured in points (1/72 inch) */
41 int postscript_option_page_top = 842;	/* A4 = 297mm x 210mm = 842pt x 595pt */
42 int postscript_option_page_right_edge = 595;
43 
44 /*  Set to 1 if your printer doesn't have iso encoding builtin. */
45 int isoencoding_not_builtin = 0;
46 
47 int postscript_option_landscape = 0;
48 int postscript_option_footline_in_landscape = 0;
49 int postscript_option_line_numbers = 0;
50 int postscript_option_font_size = 0;
51 int postscript_option_left_margin = 80;
52 int postscript_option_right_margin = 40;
53 int postscript_option_top_margin = 0;
54 int postscript_option_bottom_margin = 0;
55 char *postscript_option_font = "Courier";
56 char *postscript_option_header_font = "Helvetica-Bold";
57 int postscript_option_header_font_size = 12;
58 char *postscript_option_line_number_font = "Helvetica";
59 int postscript_option_line_number_size = 5;
60 int postscript_option_col_separation = 30;
61 int postscript_option_header_height = 30;
62 int postscript_option_show_header = 1;
63 int postscript_option_wrap_lines = 1;
64 int postscript_option_columns = 1;
65 int postscript_option_chars_per_line = 0;
66 int postscript_option_plain_text = 0;
67 unsigned char *postscript_option_title = 0;
68 unsigned char *postscript_option_file = 0;
69 unsigned char *postscript_option_pipe = 0;
70 unsigned char *option_continuation_string = 0;
71 int postscript_option_tab_size = 8;
72 
postscript_clean(void)73 void postscript_clean (void)
74 {
75     if (postscript_option_title)
76 	free (postscript_option_title);
77     if (postscript_option_file)
78 	free (postscript_option_file);
79     if (postscript_option_pipe)
80 	free (postscript_option_pipe);
81     if (option_continuation_string)
82 	free (option_continuation_string);
83 }
84 
85 
86 void (*postscript_dialog_cannot_open) (unsigned char *) = 0;
87 int (*postscript_dialog_exists) (unsigned char *) = 0;
88 unsigned char *(*postscript_get_next_line) (unsigned char *) = 0;
89 
90 /* utility functions */
91 
ps_string(unsigned char * text)92 unsigned char *ps_string (unsigned char *text)
93 {
94     unsigned char *r, *p, *q;
95     int i = 0;
96     for (i = 0, p = text; *p; p++, i++) {
97 	if ((char *) strchr ("\\()", (int) *p))
98 	    i++;
99 	else if (*p >= 0177 || *p <= 037)
100 	    i += 3;
101     }
102     r = (unsigned char *) malloc (i + 1);
103     for (p = text, q = r; *p; p++, q++) {
104 	if (strchr ("\\()", *p)) {
105 	    *q++ = '\\';
106 	    *q = *p;
107 	} else if (*p >= 0177 || *p <= 037) {
108 	    sprintf ((char *) q, "\\%03o", (int) *p);
109 	    q += 3;
110 	} else {
111 	    *q = *p;
112 	}
113     }
114     *q = 0;
115     return r;
116 }
117 
get_spaces(unsigned char * old,int l)118 static unsigned char *get_spaces (unsigned char *old, int l)
119 {
120     if (old)
121 	zfree (old);
122     if (l < 0)
123 	l = 0;
124     old = (unsigned char *) malloc (l + 1);
125     memset (old, ' ', l + 1 /* 1 extra to prevent warning */ );
126     old[l] = '\0';
127     return old;
128 }
129 
expand_tabs(unsigned char * old)130 static unsigned char *expand_tabs (unsigned char *old)
131 {
132     int i;
133     unsigned char *p, *r, *q, *spaces;
134     spaces = get_spaces (0, postscript_option_tab_size);
135     for (i = 0, p = old; *p; p++, i++)
136 	if (*p == '\t')
137 	    i += 7;
138     r = (unsigned char *) malloc (i + 1);
139     for (i = 0, q = r, p = old; *p; p++, i++)
140 	if (*p == '\t') {
141 	    int n = postscript_option_tab_size - (i % postscript_option_tab_size);
142 	    strncpy ((char *) q, (char *) spaces, n);
143 	    q += n;
144 	    i += n - 1;
145 	} else
146 	    *q++ = *p;
147     *q = '\0';
148     if (old)
149 	zfree (old);
150     zfree (spaces);
151     return r;
152 }
153 
154 /* globals */
155 
156 unsigned char filedate[80];
157 int page_no = 0, line_no = 0, cur_col = 100, total_pages = 0;
158 double cur_pos = -1;
159 double top = 0, right_edge = 0, no_columns = 0, home_pos = 0, bottom_pos = 0;
160 double sep_bar_pos = 0;
161 unsigned char *box_format;
162 double font_size = 0.0, line_height = 0.0, char_width = 0.0;
163 double col_width = 0.0;
164 int chars_per_line = 0;
165 /*  The next few entries are from the AFM file for Adobe's postscript_option_font Courier */
166 double cour_char_width = 600;	/*  The width of each unsigned char in 1000x1000 square */
167 /* sub underline_position  { -82; }   # Where underline goes relative to baseline */
168 /* sub underline_thickness {  40; }   # and it's thickness */
169 static FILE *outfile;
170 unsigned char *top_box, *bot_box;
171 unsigned char *header = 0, *title = 0;
172 int lineNoOut = 0;
173 
portrait_header(void)174 static void portrait_header (void)
175 {
176     fprintf (outfile, "%s", top_box);
177     fprintf (outfile, "%s", bot_box);
178     /*  Then the banner or the filename */
179     fprintf (outfile, "F3 SF\n");
180     if (header) {
181 	fprintf (outfile, "%.1f %.1f M(%s)dup stringwidth pop neg 0 rmoveto show\n",
182 		 (double) right_edge - postscript_option_right_margin,
183 		 (double) top - postscript_option_top_margin - postscript_option_header_font_size, header);
184     }
185     /*  Then print date and page number */
186     fprintf (outfile, "(%s)%.1f %.1f S\n", filedate, (double) postscript_option_left_margin, (double) postscript_option_bottom_margin + postscript_option_header_font_size * 0.3);
187     fprintf (outfile, "%.1f %.1f M(%d)dup stringwidth pop neg 0 rmoveto show\n",
188 	     (double) right_edge - postscript_option_right_margin,
189 	     (double) postscript_option_bottom_margin + postscript_option_header_font_size * 0.3,
190 	     page_no);
191 }
192 
landscape_header(void)193 static void landscape_header (void)
194 {
195     double y;
196     if (postscript_option_footline_in_landscape) {
197 	fprintf (outfile, "%s", bot_box);
198 	y = (double) postscript_option_bottom_margin + postscript_option_header_font_size * 0.3;
199     } else {
200 	fprintf (outfile, "%s", top_box);
201 	y = (double) top - postscript_option_top_margin - postscript_option_header_font_size;
202     }
203     fprintf (outfile, "F3 SF\n");
204     if (header) {
205 	fprintf (outfile, "%.1f %.1f M(%s)dup stringwidth pop 2 div neg 0 rmoveto show\n",
206 		 (double) (postscript_option_left_margin + right_edge - postscript_option_right_margin) / 2, y, header);
207     }
208     fprintf (outfile, "(%s)%.1f %.1f S\n", filedate, (double) postscript_option_left_margin, (double) y);
209     fprintf (outfile, "%.1f %.1f M(%d)dup stringwidth pop neg 0 rmoveto show\n", (double) right_edge - (double) postscript_option_right_margin, (double) y, page_no);
210 }
211 
end_page(void)212 static void end_page (void)
213 {
214     if (total_pages) {
215 	fprintf (outfile, "page_save restore\n");
216 	fprintf (outfile, "showpage\n");
217     }
218 }
219 
new_page(void)220 static void new_page (void)
221 {
222     end_page ();
223     page_no++;
224     total_pages++;
225     fprintf (outfile, "%%%%Page: %d %d\n", page_no, page_no);
226     fprintf (outfile, "%%%%BeginPageSetup\n");
227     fprintf (outfile, "/page_save save def\n");
228     if (postscript_option_landscape)
229 	fprintf (outfile, "90 rotate 0 -%d translate %% landscape mode\n", postscript_option_page_right_edge);
230     if (postscript_option_show_header)
231 	fprintf (outfile, "0.15 setlinewidth\n");
232     fprintf (outfile, "%%%%EndPageSetup\n");
233     if (postscript_option_show_header) {
234 	if (postscript_option_landscape)
235 	    landscape_header ();
236 	else
237 	    portrait_header ();
238 	fprintf (outfile, "F1 SF\n");
239     }
240     if (no_columns > 1) {
241 	int c;
242 	for (c = 1; c < no_columns; c++) {
243 	    double x;
244 	    x = (double) postscript_option_left_margin + (double) c *sep_bar_pos;
245 	    fprintf (outfile, "%.1f %.1f M %.1f %.1f L stroke\n", (double) x, (double) bottom_pos - 10, (double) x, (double) home_pos + 10);
246 	}
247     }
248 }
249 
printLine(unsigned char * p)250 static void printLine (unsigned char *p)
251 {
252     double x = 0;
253     if (cur_pos < bottom_pos) {
254 	cur_pos = home_pos;
255 	if (cur_col < no_columns) {
256 	    cur_col++;
257 	} else {
258 	    cur_col = 1;
259 	    new_page ();
260 	}
261     }
262     cur_pos -= line_height;
263     if (*p) {			/*  no work for empty lines */
264 	double indent = 0;
265 	while (*p == ' ') {
266 	    p++;
267 	    indent++;
268 	}
269 	indent *= char_width;
270 	p = ps_string (p);
271 	x = (double) postscript_option_left_margin + (double) (cur_col - 1) * ((double) col_width + postscript_option_col_separation);
272 	fprintf (outfile, "(%s)%.1f %.1f S\n", p, (double) x + indent, (double) cur_pos);
273 	zfree (p);
274     }
275     if (lineNoOut) {
276 	fprintf (outfile, "F2 SF(%d)%.1f %.1f S F1 SF\n", line_no, (double) x + col_width + 5, (double) cur_pos);
277 	lineNoOut = 0;
278     }
279 }
280 
printLongLines(unsigned char * p)281 static void printLongLines (unsigned char *p)
282 {
283     int maxLength;
284     int lineLength = 0;
285     int rightMargin = 0;
286     unsigned char *spaces = 0;
287     unsigned char *temp = 0;
288     unsigned char *c;
289     int right_space = 0;
290 
291     c = option_continuation_string;
292     if (!c)
293 	c = (unsigned char *) "~";
294     maxLength = chars_per_line - strlen ((char *) c);
295     while (*p) {
296 	unsigned char *q;
297 	if (strlen ((char *) p) > maxLength && postscript_option_wrap_lines) {
298 	    char *t;
299 	    for (lineLength = maxLength - 1, q = p + maxLength - 1; q >= p && *q != ' '; q--, lineLength--);
300 	    if (lineLength < maxLength / 2)
301 		lineLength = maxLength;
302 	    temp = p + lineLength;
303 	    t = (char *) malloc (maxLength + right_space + strlen ((char *) c) + 1);
304 	    strncpy ((char *) t, (char *) p, lineLength);
305 	    if (!right_space)
306 		right_space = maxLength - lineLength;
307 	    spaces = get_spaces (spaces, right_space);
308 	    strcpy ((char *) t + lineLength, (char *) spaces);
309 	    strcat ((char *) t, (char *) option_continuation_string);
310 	    p = (unsigned char *) t;
311 	} else {
312 	    temp = (unsigned char *) "";
313 	    if (strlen ((char *) p) > maxLength)
314 		p[maxLength] = '\0';
315 	    p = (unsigned char *) strdup ((char *) p);
316 	    lineLength = strlen ((char *) p);
317 	}
318 	if (rightMargin == 0) {
319 	    spaces = get_spaces (spaces, 0);
320 	    rightMargin = lineLength;
321 	} else {
322 	    spaces = get_spaces (spaces, rightMargin - lineLength);
323 	}
324 	q = (unsigned char *) malloc (strlen ((char *) spaces) + strlen ((char *) p) + 1);
325 	strcpy ((char *) q, (char *) spaces);
326 	strcat ((char *) q, (char *) p);
327 	zfree (p);
328 	printLine (q);
329 	zfree (q);
330 	p = temp;
331 	maxLength = chars_per_line * 3 / 4;
332     }
333     zfree (spaces);
334 }
335 
prolog(void)336 static void prolog (void)
337 {
338     struct tm *tm;
339     time_t t;
340     time (&t);
341     tm = localtime (&t);
342     fprintf (outfile, "%%!PS-Adobe-2.0\n");
343     if (title)
344 	fprintf (outfile, "%%%%Title: %s\n", title);
345     fprintf (outfile, "%%%%Creator: Cooledit, text editor and IDE.\n");
346     fprintf (outfile, "%%%%CreationDate: (%d %d, %d) (%2d:%02d)\n", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min);
347     fprintf (outfile, "%%%%For: %s\n", /* username ******* */ "(unknown)");
348     fprintf (outfile, "%%%%Pages: (atend)\n");
349     fprintf (outfile, "%%%%DocumentFonts: %s", postscript_option_font);
350     if (postscript_option_line_numbers)
351 	fprintf (outfile, " %s", postscript_option_line_number_font);
352     if (postscript_option_show_header)
353 	fprintf (outfile, " %s", postscript_option_header_font);
354     fprintf (outfile, "\n");
355     fprintf (outfile, "\
356 %%%%EndComments\n\
357 /S{moveto show}bind def\n\
358 /M/moveto load def\n\
359 /L/lineto load def\n\
360 /SF/setfont load def\n\
361 ");
362     if (isoencoding_not_builtin) {
363 	fprintf (outfile, "\
364 ISOLatin1Encoding where { pop } { ISOLatin1Encoding\n\
365 [/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n\
366 /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n\
367 /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n\
368 /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space\n\
369 /exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n\
370 /parenleft/parenright/asterisk/plus/comma/minus/period/slash/zero/one\n\
371 /two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal\n\
372 /greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S\n\
373 /T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum\n\
374 /underscore/quoteleft/a/b/c/d/e/outfile/g/h/i/j/k/l/m/n/o/p/q/r/s\n\
375 /t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde/.notdef/.notdef\n\
376 /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n\
377 /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/dotlessi/grave\n\
378 /acute/circumflex/tilde/macron/breve/dotaccent/dieresis/.notdef/ring\n\
379 /cedilla/.notdef/hungarumlaut/ogonek/caron/space/exclamdown/cent\n\
380 /sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine\n\
381 /guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus\n\
382 /twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla\n\
383 /onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters\n\
384 /questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE\n\
385 /Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex\n\
386 /Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis\n\
387 /multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn\n\
388 /germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae\n\
389 /ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex\n\
390 /idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide\n\
391 /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]\n\
392 def %%ISOLatin1Encoding\n\
393 } ifelse\n\
394 ");
395     }
396     fprintf (outfile, "%%%%BeginProcSet: newencode 1.0 0\n\
397 /NE { %%def\n\
398    findfont begin\n\
399       currentdict dup length dict begin\n\
400          { %%forall\n\
401             1 index/FID ne {def} {pop pop} ifelse\n\
402          } forall\n\
403          /FontName exch def\n\
404          /Encoding exch def\n\
405          currentdict dup\n\
406       end\n\
407    end\n\
408    /FontName get exch definefont pop\n\
409 } bind def\n\
410 %%%%EndProcSet: newencode 1.0 0\n\
411 %%%%EndProlog\n\
412 %%%%BeginSetup\n\
413 ");
414     fprintf (outfile, "ISOLatin1Encoding /%s-ISO/%s NE\n", postscript_option_font, postscript_option_font);
415     if (postscript_option_show_header)
416 	fprintf (outfile, "ISOLatin1Encoding /%s-ISO/%s NE\n", postscript_option_header_font, postscript_option_header_font);
417     fprintf (outfile, "/F1/%s-ISO findfont %.2g scalefont def\n", postscript_option_font, font_size);
418     if (postscript_option_line_numbers)
419 	fprintf (outfile, "/F2/%s findfont %d scalefont def\n", postscript_option_line_number_font, postscript_option_line_number_size);
420     if (postscript_option_show_header)
421 	fprintf (outfile, "/F3/%s-ISO findfont %d scalefont def\n", postscript_option_header_font, postscript_option_header_font_size);
422     fprintf (outfile, "F1 SF\n");
423     fprintf (outfile, "%%%%EndSetup\n");
424 }
425 
426 
postscript_print(void)427 void postscript_print (void)
428 {
429     unsigned char *p = 0;
430     double llx = 0.0, lly = 0.0, urx = 0.0, ury = 0.0;
431     struct stat st;
432     struct tm *tm = 0;
433 
434     outfile = 0;
435 
436     page_no = 0;
437     line_no = 0;
438     cur_col = 100;
439     total_pages = 0;
440     cur_pos = -1;
441     top = 0;
442     right_edge = 0;
443     no_columns = 0;
444     home_pos = 0;
445     bottom_pos = 0;
446     sep_bar_pos = 0;
447     font_size = 0.0;
448     line_height = 0.0;
449     char_width = 0.0;
450     col_width = 0.0;
451     chars_per_line = 0;
452     cour_char_width = 600;
453     lineNoOut = 0;
454 
455     if (!option_continuation_string)
456 	option_continuation_string = (unsigned char *) strdup ("~");
457 
458     if (title)
459 	free (title);
460     title = 0;
461     if (postscript_option_title)
462 	title = ps_string (postscript_option_title);
463 
464     if (postscript_option_landscape) {
465 	top = postscript_option_page_right_edge;
466 	right_edge = postscript_option_page_top;
467 	postscript_option_left_margin = postscript_option_right_margin;		/*  this is a dirty one */
468 	no_columns = postscript_option_columns;
469 	font_size = postscript_option_font_size ? postscript_option_font_size : 7;
470 	if (postscript_option_footline_in_landscape) {
471 	    postscript_option_top_margin = 30;
472 	    postscript_option_bottom_margin = 30;
473 	    home_pos = top - postscript_option_top_margin - postscript_option_header_height;
474 	    bottom_pos = postscript_option_bottom_margin + postscript_option_header_height;
475 	} else {
476 	    postscript_option_top_margin = 45;
477 	    postscript_option_bottom_margin = 30;
478 	    home_pos = top - postscript_option_top_margin - postscript_option_header_height;
479 	    bottom_pos = postscript_option_bottom_margin;
480 	}
481     } else {
482 	top = postscript_option_page_top;
483 	right_edge = postscript_option_page_right_edge;
484 	no_columns = postscript_option_columns;
485 	font_size = postscript_option_font_size ? postscript_option_font_size : 10;
486 	postscript_option_top_margin = 45;
487 	postscript_option_bottom_margin = 45;
488 	home_pos = top - postscript_option_top_margin - (postscript_option_show_header ? postscript_option_header_height : 0);
489 	bottom_pos = postscript_option_bottom_margin + postscript_option_header_height;
490     }
491     col_width = (double) (right_edge - postscript_option_left_margin - postscript_option_right_margin
492      - (no_columns - 1) * postscript_option_col_separation) / no_columns;
493     sep_bar_pos = (right_edge - postscript_option_left_margin - postscript_option_right_margin) / no_columns;
494     if (!font_size)
495 	font_size = (double) ((double) col_width / postscript_option_chars_per_line) / (cour_char_width / 1000);
496     if (postscript_option_chars_per_line)
497 	font_size = (double) ((double) col_width / postscript_option_chars_per_line) / (cour_char_width / 1000);
498     line_height = font_size * 1.08;
499     char_width = cour_char_width * font_size / 1000;
500     chars_per_line = (double) col_width / char_width + 1;
501 
502 /* Compute the box for the page headers. */
503     box_format = (unsigned char *) "%.1f %.1f M %.1f %.1f L %.1f %.1f L %.1f %.1f L closepath \n";
504     llx = postscript_option_left_margin - 10;
505     lly = top - postscript_option_top_margin - postscript_option_header_font_size * 1.3;
506     urx = right_edge - postscript_option_right_margin + 10;
507     ury = top - postscript_option_top_margin;
508 
509     top_box = (unsigned char *) malloc (1024);
510     sprintf ((char *) top_box, (char *) box_format, llx, lly, urx, lly, urx, ury, llx, ury);
511     strcat ((char *) top_box, "gsave .95 setgray fill grestore stroke\n");
512 
513     lly = postscript_option_bottom_margin;
514     ury = lly + postscript_option_header_font_size * 1.3;
515     bot_box = (unsigned char *) malloc (1024);
516     sprintf ((char *) bot_box, (char *) box_format, llx, lly, urx, lly, urx, ury, llx, ury);
517     strcat ((char *) bot_box, "gsave .95 setgray fill grestore stroke\n");
518 
519 /* Open the output pipe or file. */
520     if (postscript_option_file) {
521 	int r;
522 	r = stat ((char *) postscript_option_file, &st);
523 	if (!r)
524 	    if (postscript_dialog_exists)
525 		if (!(*postscript_dialog_exists) (postscript_option_file))
526 		    goto postscript_done;
527 	outfile = fopen ((char *) postscript_option_file, "w+");
528 	if (!outfile) {
529 	    if (postscript_dialog_cannot_open)
530 		(*postscript_dialog_cannot_open) (postscript_option_file);
531 	    goto postscript_done;
532 	}
533     } else if (postscript_option_pipe) {
534 	outfile = (FILE *) popen ((char *) postscript_option_pipe, "w");
535 	if (!outfile) {
536 	    if (postscript_dialog_cannot_open)
537 		(*postscript_dialog_cannot_open) (postscript_option_pipe);
538 	    goto postscript_done;
539 	}
540     }
541     if (postscript_option_plain_text) {
542 	while ((p = (*postscript_get_next_line) (p)))
543 	    fprintf (outfile, "%s\n", p);
544 	goto postscript_done;
545     }
546     prolog ();
547 
548     filedate[0] = '\0';
549     time (&st.st_mtime);
550     tm = localtime (&st.st_mtime);
551     get_file_time (filedate, st.st_mtime, 1);
552 
553     if (title)
554 	header = title;
555     else
556 	header = 0;
557 
558     page_no = 0;
559     line_no = 0;
560     while ((p = (*postscript_get_next_line) (p))) {
561 	line_no++;
562 	if (postscript_option_line_numbers && ((line_no % 5) == 0))
563 	    lineNoOut = line_no;
564 	if (p[0] == 014) {	/*  form feed */
565 	    strcpy ((char *) p, (char *) p + 1);	/*  chop off first unsigned char */
566 	    cur_pos = -1;
567 	    if (!*p)
568 		p = postscript_get_next_line (p);
569 	    if (!p)
570 		break;
571 	}
572 	p = expand_tabs (p);	/*  expand tabs */
573 	if (strlen ((char *) p) <= chars_per_line) {
574 	    printLine (p);
575 	} else {
576 	    printLongLines (p);
577 	}
578     }				/*  while (each line) */
579     cur_pos = -1;		/*  this will force a new column next time */
580     cur_col = 100;		/*  this will force a new page next time */
581 
582     end_page ();
583     fprintf (outfile, "%%%%Trailer\n");
584     fprintf (outfile, "%%%%Pages: %d\n", total_pages);
585   postscript_done:
586     free (top_box);
587     free (bot_box);
588     if (p)
589 	free (p);
590     if (outfile) {
591 	if (postscript_option_file) {
592 	    fflush (outfile);
593 	    fclose (outfile);
594 	} else {
595 	    fflush (outfile);
596 	    pclose (outfile);
597 	}
598     }
599     outfile = 0;
600     if (title)
601 	free (title);
602     title = 0;
603 }
604 
605 
606