Old glob.c
1 /*
2 * glob.c
3 */
4
5 /*
6 * mpage: a program to reduce pages of print so that several pages
7 * of output appear on one printed page.
8 *
9 * Copyright (c) 1994-2004 Marcel J.E. Mol, The Netherlands
10 * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
11 *
12 * Permission is granted to anyone to make or distribute verbatim
13 * copies of this document as received, in any medium, provided
14 * that this copyright notice is preserved, and that the
15 * distributor grants the recipient permission for further
16 * redistribution as permitted by this notice.
17 *
18 */
19
20 #include "mpage.h"
21
22 /*
23 * to turn on debugging, define the preprocessor macro DEBUG and set
24 * the variable Debug_flag to the sum of the sections to debug.
25 */
26 # ifdef DEBUG
27 int Debug_flag = DB_PSMPAGE;
28 # endif
29
30
31 /*
32 * some basic PS parameters
33 */
34 int ps_width; /* number of points in the X direction see set_page() */
35 int ps_height; /* number of points in the Y direction */
36 char *media; /* name of output media */
37
38 struct page_desc paper[] = {
39 { "Letter", 612, 792 }, /* 8.5 x 11 in */
40 { "LetterSmall", 612, 792 },
41 { "Tabloid", 792, 1224 },
42 { "Ledger", 1224, 792 }, /* 8.5 x 14 in */
43 { "Legal", 612, 1008 },
44 { "Statement", 396, 612 },
45 { "Executive", 540, 720 },
46 { "A0", 2384, 3368 }, /* 840 x 1188 mm */
47 { "A1", 1684, 2384 }, /* 594 x 840 mm */
48 { "A2", 1192, 1684 }, /* 420 x 594 mm */
49 /* { "A3", 842, 1190 }, */
50 { "A3", 842, 1192 }, /* 297 x 420 mm */
51 /* ISO 216 conforming says 595x841 ... */
52 /* { "A4", 595, 842 }, */
53 { "A4", 596, 842 }, /* 210 x 297 mm */
54 { "A4Small", 595, 842 },
55 { "A5", 420, 595 },
56 { "B4", 729, 1032 },
57 { "B5", 516, 729 },
58 { "Folio", 612, 936 },
59 { "Quarto", 610, 780 },
60 { "10x14", 720, 1008 },
61 { (char *) NULL, 0, 0 }
62 };
63
64 /*
65 * the structures describe where to put the reduced pages of output on the
66 * printed page.
67 */
68 /* empty page */
69 struct pagepoints points_empty[] = {
70 { 0, 0, 0 }
71 };
72 /* base point for one page, normal aspect */
73 struct pagepoints one_normal[] = {
74 { xbase1, ybase1, 0 },
75 { 0, 0, 0 }
76 };
77 /* base points for two pages, normal aspect */
78 struct pagepoints two_normal[] = {
79 { xbase1, ytop4, 0 }, { xbase1 , ytop2, 0 },
80 { 0, 0, 0 }
81 };
82
83 /* GPN outside 2 pages */
84 struct pagepoints two_normal_co[] = {
85 {xbase1, ytop2, 0}, {0, 0, SKIP_PS},
86 {0, 0, SKIP_PS}, {xbase1, ytop4, 0},
87 {0, 0, 0}
88
89 };
90 /* GPN. inside 2 pages */
91 struct pagepoints two_normal_ci[] = {
92 {0, 0, SKIP_PS}, {xbase1, ytop4, 0},
93 {xbase1, ytop2, 0}, {0, 0, SKIP_PS},
94 {0, 0, 0}
95 };
96
97 /* GPN. all 4 pages */
98 struct pagepoints four_normal_dm[] = {
99 {xbase1, ytop2, STORE_PS}, {xbase1, ytop4, 0},
100 {xbase1, ytop2, 0}, {0, 0, 0}, {xbase1, ytop4, FLUSH_PS},
101 {0, 0, 0}
102 };
103
104 /* base points for four pages, normal aspect, running reduced pages
105 * read from left to right */
106 struct pagepoints lr_four_normal[] = {
107 { xbase1, ybase3, 0 }, { xbase2, ybase3, 0 },
108 { xbase1, ybase1, 0 }, { xbase2, ybase1, 0 },
109 { 0, 0, 0 }
110 };
111 /* base points for four pages, normal aspect, running reduced pages
112 * read from top to bottom (up/down) */
113 struct pagepoints ud_four_normal[] = {
114 { xbase1, ybase3, 0 }, { xbase1, ybase1, 0 },
115 { xbase2, ybase3, 0 }, { xbase2, ybase1, 0 },
116 { 0, 0, 0 }
117 };
118 /* base points for four pages, normal aspect, running reduced pages
119 * read from left to right, adjusting for the fact that we have a landscape
120 * input */
121 struct pagepoints land_lr_four_normal[] =
122 {
123 { xbase1, ybase1, 0 }, { xbase1, ybase3, 0 },
124 { xbase2, ybase1, 0 }, { xbase2, ybase3, 0 },
125 { 0, 0, 0}
126 };
127 /* base points for four pages, normal aspect, running reduced pages
128 * read from top to bottom (up/down), adjusting for the fact that we have a
129 * landscape input */
130 struct pagepoints land_ud_four_normal[] =
131 {
132 { xbase1, ybase1, 0 }, { xbase2, ybase1, 0 },
133 { xbase1, ybase3, 0 }, { xbase2, ybase3, 0 },
134 { 0, 0, 0}
135 };
136 /* base points for eight pages, normal aspect, running reduced pages
137 * read from left to right */
138 struct pagepoints lr_eight_normal[] = {
139 { xbase2, ytop4, 0 }, { xbase2, ytop3, 0 },
140 { xbase2, ytop2, 0 }, { xbase2, ytop1, 0 },
141 { xbase1, ytop4, 0 }, { xbase1, ytop3, 0 },
142 { xbase1, ytop2, 0 }, { xbase1, ytop1, 0 },
143 { 0, 0, 0 }
144 };
145 /* base points for eight pages, normal aspect, running reduced pages
146 * read from top to bottom (up/down) */
147 struct pagepoints ud_eight_normal[] = {
148 { xbase2, ytop4, 0 }, { xbase1, ytop4, 0 },
149 { xbase2, ytop3, 0 }, { xbase1, ytop3, 0 },
150 { xbase2, ytop2, 0 }, { xbase1, ytop2, 0 },
151 { xbase2, ytop1, 0 }, { xbase1, ytop1, 0 },
152 { 0, 0, 0 }
153 };
154 /* base points for eight pages, normal aspect, running reduced pages
155 * read from left to right, adjusting for the fact that we have a landscape
156 * input */
157 struct pagepoints land_lr_eight_normal[] =
158 {
159 { xbase1, ytop4, 0 }, { xbase2, ytop4, 0 },
160 { xbase1, ytop3, 0 }, { xbase2, ytop3, 0 },
161 { xbase1, ytop2, 0 }, { xbase2, ytop2, 0 },
162 { xbase1, ytop1, 0 }, { xbase2, ytop1, 0 },
163 { 0, 0, 0 }
164 };
165 /* base points for eight pages, normal aspect, running reduced pages
166 * read from top to bottom (up/down), adjusting for the fact that we have a
167 * landscape input */
168 struct pagepoints land_ud_eight_normal[] =
169 {
170 { xbase1, ytop4, 0 }, { xbase1, ytop3, 0 },
171 { xbase1, ytop2, 0 }, { xbase1, ytop1, 0 },
172 { xbase2, ytop4, 0 }, { xbase2, ytop3, 0 },
173 { xbase2, ytop2, 0 }, { xbase2, ytop1, 0 },
174 { 0, 0, 0}
175 };
176 /* base point for one page, in landscape */
177 struct pagepoints one_landscape[] = {
178 { xbase1, ytop4, 0 },
179 { 0, 0, 0 }
180 };
181 /* base points for two pages, in landscape */
182 struct pagepoints two_landscape[] = {
183 { xbase1, ybase3, 0 }, { xbase1, ybase1, 0 },
184 { 0, 0, 0 }
185 };
186 /* base points for four pages, in landscape, running reduced pages
187 * read from left to right */
188 struct pagepoints lr_four_landscape[] = {
189 { xbase2, ytop4, 0 }, { xbase2, ytop2, 0 },
190 { xbase1, ytop4, 0 }, { xbase1, ytop2, 0 },
191 { 0, 0, 0 }
192 };
193 /* base points for four pages, in landscape, running reduced pages
194 * read from top to bottom (up/down) */
195 struct pagepoints ud_four_landscape[] = {
196 { xbase2, ytop4, 0 }, { xbase1, ytop4, 0 },
197 { xbase2, ytop2, 0 }, { xbase1, ytop2, 0 },
198 { 0, 0, 0 }
199 };
200 /* base points for eight pages, in landscape, running reduced pages
201 * read from left to right */
202 struct pagepoints lr_eight_landscape[] = {
203 { xbase1, ybase4, 0 }, { xbase2, ybase4, 0 },
204 { xbase1, ybase3, 0 }, { xbase2, ybase3, 0 },
205 { xbase1, ybase2, 0 }, { xbase2, ybase2, 0 },
206 { xbase1, ybase1, 0 }, { xbase2, ybase1, 0 },
207 { 0, 0, 0 }
208 };
209 /* base points for eight pages, in landscape, running reduced pages
210 * read from top to bottom (up/down) */
211 struct pagepoints ud_eight_landscape[] = {
212 { xbase1, ybase4, 0 }, { xbase1, ybase3, 0 },
213 { xbase1, ybase2, 0 }, { xbase1, ybase1, 0 },
214 { xbase2, ybase4, 0 }, { xbase2, ybase3, 0 },
215 { xbase2, ybase2, 0 }, { xbase2, ybase1, 0 },
216 { 0, 0, 0 }
217 };
218
219 /* list of sheets (printed page formats) for
220 * left to right reading, in normal aspect */
221 struct sheet lr_normal[] = {
222 /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal },
223 /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal },
224 /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, lr_four_normal },
225 /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, lr_eight_normal },
226 };
227
228 /* list of sheets (printed page formats) for landscape input
229 * left to right reading, in normal aspect */
230 struct sheet land_lr_normal[] = {
231 /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal },
232 /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal },
233 /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, land_lr_four_normal },
234 /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, land_lr_eight_normal },
235 };
236
237 /* list of sheets (printed page formats) for
238 * top to bottom reading, in normal aspect */
239 struct sheet ud_normal[] = {
240 /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal },
241 /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal },
242 /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, ud_four_normal },
243 /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, ud_eight_normal },
244 };
245
246 /* list of sheets (printed page formats) for
247 * left to right reading, in landscape */
248 struct sheet lr_landscape[] = {
249 /* 0 */ { 132, 52, yht1, xwid1, -90, outline_1, one_landscape },
250 /* 1 */ { 132, 52, xwid1, yht2, 0, outline_2, two_landscape },
251 /* 2 */ { 132, 52, yht2, xwid2, -90, outline_4, lr_four_landscape },
252 /* 3 */ { 132, 52, xwid2, yht4, 0, outline_8, lr_eight_landscape },
253 };
254
255 /* list of sheets (printed page formats) for
256 * top to bottom reading, in landscape */
257 struct sheet ud_landscape[] = {
258 /* 0 */ { 132, 52, yht1, xwid1, -90, outline_1, one_landscape },
259 /* 1 */ { 132, 52, xwid1, yht2, 0, outline_2, two_landscape },
260 /* 2 */ { 132, 52, yht2, xwid2, -90, outline_4, ud_four_landscape },
261 /* 3 */ { 132, 52, xwid2, yht4, 0, outline_8, ud_eight_landscape },
262 };
263
264 /* list of sheets (printed page formats) for landscape input
265 * top to bottom reading, in landscape */
266 struct sheet land_ud_normal[] = {
267 /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal },
268 /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal },
269 /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, land_ud_four_normal },
270 /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, land_ud_eight_normal },
271 };
272
273 /* GPN. sheet */
274 struct sheet coli [] = {
275 /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal_co },
276 /* 2 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal_ci },
277 /* 3 */ { 80, 66, yht2, xwid1, -90, outline_2, four_normal_dm },
278 };
279
280 /* array of sheet lists for left to right reading printed pages */
281 struct sheet *left_right[] = {
282 lr_normal,
283 lr_landscape,
284 land_lr_normal
285 };
286
287 /* arrays for top to bottom reading printed pages */
288 struct sheet *up_down[] = {
289 ud_normal,
290 ud_landscape,
291 land_ud_normal
292 };
293
294 /*
295 * Variables for holding the chosen options, The defaults are set here.
296 * the sheetlist pointer is set to point to the array for either up/down
297 * or left/right reading. This array is index by sheetorder, and then
298 * sheetindex. sheetindex encodes the number of reduced pages per printed
299 * page and indexes into the sheet list (0 = 1 page, 1 = two pages, 2 =
300 * four pages, 3 = eight pages).
301 */
302 struct sheet **sheetlist;/* array of sheet lists (up/down or left/right) */
303 int sheetaspect = PORTRAIT; /* either normal or landscape */
304 int sheetorder = UPDOWN; /* up/down or left/right flag */
305 int sheetindex = 2; /* index to page descriptor array */
306 int sheetmargin_left = DEFAULTSMARGIN; /* non-printable border on sheet */
307 int sheetmargin_right = DEFAULTSMARGIN; /* non-printable border on sheet */
308 int sheetmargin_top = DEFAULTSMARGIN; /* non-printable border on sheet */
309 int sheetmargin_bottom= DEFAULTSMARGIN; /* non-printable border on sheet */
310 int pagemargin_left = DEFAULTPMARGIN; /* border for pages */
311 int pagemargin_right = DEFAULTPMARGIN; /* border for pages */
312 int pagemargin_top = DEFAULTPMARGIN; /* border for pages */
313 int pagemargin_bottom = DEFAULTPMARGIN; /* border for pages */
314 int textmargin_left = DEFAULTTMARGIN; /* border for textbox */
315 int textmargin_right = DEFAULTTMARGIN; /* border for textbox */
316 int textmargin_top = DEFAULTTMARGIN; /* border for textbox */
317 int textmargin_bottom = DEFAULTTMARGIN; /* border for textbox */
318 int sheetheader_left = 0; /* space for physical sheetheader */
319 int sheetheader_right = 0; /* space for physical sheetheader */
320 int sheetheader_top = 0; /* space for physical sheetheader */
321 int sheetheader_bottom= 0; /* space for physical sheetheader */
322 struct pagepoints *points = points_empty;
323 int orientation; /* final orientation of text */
324 int fsize = TSIZE; /* font scale size */
325 int opt_indent = 0; /* starting column for ascii printing */
326 int opt_tabstop = DEFAULTTABSTOP; /* width of a tab */
327 int opt_lines = 0; /* lines to fit on reduced page */
328 int opt_killtrail = 1; /* Quit reading input on %%TRailer */
329 int opt_width = 0; /* columns to fit on reduced page */
330 char * opt_page = PAGE_DEF; /* default paper size */
331 /* boolean's: set default to 0 or 1 */
332 int opt_pr = 0; /* if true use pr(1) to format output */
333 int opt_mp_header = 0; /* let mpage create headers */
334 int opt_sheetheader = 0; /* let mpage create sheetheaders */
335 int opt_fold = 0; /* fold lines longer than page width */
336 int opt_outline = 1; /* don't normally outline the pages */
337 int opt_verbose = 0; /* print a count of pages produced */
338 int opt_square = 1; /* print pages with natural aspect ratio */
339 int opt_reverse = 0; /* by default print sheets in forward order */
340 int opt_jarg = 0; /* number of -j opt sets */
341 int opt_first[MAXJARG]; /* start with first sheet per -j */
342 int opt_last[MAXJARG]; /* print as many as supplied per -j */
343 int opt_alt[MAXJARG]; /* by default print all sheets, odd+even per -j*/
344 int opt_file = 1; /* should each file appera on a new sheet */
345 int opt_duplex = DEFAULT_DUPLEX; /* duplex mode flag */
346 int opt_tumble = 0; /* tumble overy second pages */
347 int opt_textbox = 0; /* don't normally draw box around text */
348 int opt_input = IN_AUTO; /* select input file format */
349 int opt_encoding = DEFAULT_ENCODING; /* use default encoding or not */
350 struct pagebox textbox = {0, 0, 80, 66, 0};
351
352 char * opt_header = NULL; /* the header for pr's -h option */
353 char * printque = NULL; /* the printer queuename */
354 char * prprog = PRPROG; /* the pr filter program */
355 char * printprog = PRINTPROG; /* the print program */
356 char * printarg = QUEARG; /* define print queue to printprog */
357 int doprint = 0; /* send it to the printer */
358 char * charvec_file; /* file to read character definitions from */
359 char * libdir = LIBDIR; /* pointer to get library files from */
360 char * fontname = "Courier"; /* Font to use */
361 char * dateformat = "%c"; /* Date/time format for date in headers */
362 char * sheethead = ""; /* Leave empty to get default sheetheader:
363 current filename + physical pagenumber */
364
365 /*
366 * various global information
367 */
368 char MPAGE[] = "mpage"; /* program name */
369 int ps_pagenum = 0; /* current sheet count (printed or not) */
370 int ps_outpages= 0; /* sheets printed */
371 int had_ps = 0; /* did we process ps files */
372
373 int first_encoding = -1; /* first encoding in character set */
374 int last_encoding; /* last encoding in character set */
375
376 /* GPN. for coli */
377 int Coli = 0; /* value of 0 = don't mess, 1 = 4, 1 (outside pages)*/
378 int use_utf8 = 0; /* is input UTF-8 or not. */
379 int check_utf8 = 1; /* do we want to check for UTF-8 or not. */
380
381
382
383 void usage(int errcode)
384 {
385 fprintf(stderr, "\
386 mpage - print multiple pages on postscript, version %s\n\n\
387 mpage [-1248aceEfHlkoOrRStTvuVxX] [-b papersize] [-Btextboxmargin]\n\
388 [-C [encodingfile]] [-da|p] [-D dateformat] [-F fontname]\n\
389 [-h header] [-I indent] [-j pagespec] [-J startpageno] [-L lines]\n\
390 [-msheetmargin] [-Mpagemargin] [-p[prprog]] [-P[printer]]\n\
391 [-s tabstop] [-W width] [-X [header]] [-z printcmd] [-Z quearg]\n\
392 [file...]]\n",
393 VERSION
394 );
395
396 fprintf(stderr, "\n\
397 -1, -2, -4, -8 Pages per sheet (4) -D strftime format for date specs\n\
398 -da Force ascii input format -dp Force postscript input format\n\
399 -a Toggle across/updown layout (u) -l Toggle portrait/landscape (p)\n\
400 -f Toggle folding long lines (off) -o Toggle printing outlines (on)\n\
401 -r Reverse printing, last->first sheet -v Toggle verbose output, (on)\n\
402 -F Text font to be used (%s) -C Character encoding filename\n\
403 -E Print every second and third page -O Print every first and fourth page\n\
404 -s Define tabstop width (%d) -k kill on %%TRailer is PS file\n\
405 -V Show mpage version.\n -u switch of utf-8 check\n\
406 -b papersize (%s), use l or ? to get a list of sizes\n\
407 -R Switch to across mode, with first page at lower left corner\n\
408 -H Create page header for each page for text files\n\
409 -X Print physical page header (filename + physical pagenumber)\n\
410 -c Toggle concat pages of different files on same sheet (off)\n\
411 -S Don't square pages for PS input (default uniform X/Y shrink)\n\
412 -B Specify textbox margin/thickness (no space): [<num>[lrtb]*]*\n\
413 -m Specify sheetmargin (no space): [<num>[lrtb]*]*\n\
414 -M Specify pagemargins (no space): [<num>[lrtb]*]*\n\
415 -p Pipe through prprog (no space), pr(1) is default.\n\
416 Mpage assumes the specified pr understands -l, -w and -h options.\n\
417 -P Specify printer queue (no space). -P only uses default queue.\n\
418 -z Specify print command (%s).\n\
419 -Z Specify print command print queue option (%s).\n\
420 -j Print specified sheets: first[-last][%%interval]\n\
421 -j 1-10 does first 10 sheets, -j 1%%2 prints odd ones, -j 2%%2 even ones.\n\
422 -J Set the start of the sheet page count\n\
423 -t Toggle printing both sides of the paper (Duplex mode, %s)\n\
424 -T Toggle tumble of every second pages when printing in duplex mode (off)\n",
425 fontname, opt_tabstop, PAGE_DEF, printprog, printarg,
426 opt_duplex ? "on" : "off"
427 );
428 fprintf(stderr, "\n(c) 1993-2005 Marcel Mol, marcel@mesa.nl (MESA Consulting)\n");
429
430 return;
431
432 } /* usage */