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 */