/* * glob.c */ /* * mpage: a program to reduce pages of print so that several pages * of output appear on one printed page. * * Copyright (c) 1994-2004 Marcel J.E. Mol, The Netherlands * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia * * Permission is granted to anyone to make or distribute verbatim * copies of this document as received, in any medium, provided * that this copyright notice is preserved, and that the * distributor grants the recipient permission for further * redistribution as permitted by this notice. * */ #include "mpage.h" /* * to turn on debugging, define the preprocessor macro DEBUG and set * the variable Debug_flag to the sum of the sections to debug. */ # ifdef DEBUG int Debug_flag = DB_PSMPAGE; # endif /* * some basic PS parameters */ int ps_width; /* number of points in the X direction see set_page() */ int ps_height; /* number of points in the Y direction */ char *media; /* name of output media */ struct page_desc paper[] = { { "Letter", 612, 792 }, /* 8.5 x 11 in */ { "LetterSmall", 612, 792 }, { "Tabloid", 792, 1224 }, { "Ledger", 1224, 792 }, /* 8.5 x 14 in */ { "Legal", 612, 1008 }, { "Statement", 396, 612 }, { "Executive", 540, 720 }, { "A0", 2384, 3368 }, /* 840 x 1188 mm */ { "A1", 1684, 2384 }, /* 594 x 840 mm */ { "A2", 1192, 1684 }, /* 420 x 594 mm */ /* { "A3", 842, 1190 }, */ { "A3", 842, 1192 }, /* 297 x 420 mm */ /* ISO 216 conforming says 595x841 ... */ /* { "A4", 595, 842 }, */ { "A4", 596, 842 }, /* 210 x 297 mm */ { "A4Small", 595, 842 }, { "A5", 420, 595 }, { "B4", 729, 1032 }, { "B5", 516, 729 }, { "Folio", 612, 936 }, { "Quarto", 610, 780 }, { "10x14", 720, 1008 }, { (char *) NULL, 0, 0 } }; /* * the structures describe where to put the reduced pages of output on the * printed page. */ /* empty page */ struct pagepoints points_empty[] = { { 0, 0, 0 } }; /* base point for one page, normal aspect */ struct pagepoints one_normal[] = { { xbase1, ybase1, 0 }, { 0, 0, 0 } }; /* base points for two pages, normal aspect */ struct pagepoints two_normal[] = { { xbase1, ytop4, 0 }, { xbase1 , ytop2, 0 }, { 0, 0, 0 } }; /* GPN outside 2 pages */ struct pagepoints two_normal_co[] = { {xbase1, ytop2, 0}, {0, 0, SKIP_PS}, {0, 0, SKIP_PS}, {xbase1, ytop4, 0}, {0, 0, 0} }; /* GPN. inside 2 pages */ struct pagepoints two_normal_ci[] = { {0, 0, SKIP_PS}, {xbase1, ytop4, 0}, {xbase1, ytop2, 0}, {0, 0, SKIP_PS}, {0, 0, 0} }; /* GPN. all 4 pages */ struct pagepoints four_normal_dm[] = { {xbase1, ytop2, STORE_PS}, {xbase1, ytop4, 0}, {xbase1, ytop2, 0}, {0, 0, 0}, {xbase1, ytop4, FLUSH_PS}, {0, 0, 0} }; /* base points for four pages, normal aspect, running reduced pages * read from left to right */ struct pagepoints lr_four_normal[] = { { xbase1, ybase3, 0 }, { xbase2, ybase3, 0 }, { xbase1, ybase1, 0 }, { xbase2, ybase1, 0 }, { 0, 0, 0 } }; /* base points for four pages, normal aspect, running reduced pages * read from top to bottom (up/down) */ struct pagepoints ud_four_normal[] = { { xbase1, ybase3, 0 }, { xbase1, ybase1, 0 }, { xbase2, ybase3, 0 }, { xbase2, ybase1, 0 }, { 0, 0, 0 } }; /* base points for four pages, normal aspect, running reduced pages * read from left to right, adjusting for the fact that we have a landscape * input */ struct pagepoints land_lr_four_normal[] = { { xbase1, ybase1, 0 }, { xbase1, ybase3, 0 }, { xbase2, ybase1, 0 }, { xbase2, ybase3, 0 }, { 0, 0, 0} }; /* base points for four pages, normal aspect, running reduced pages * read from top to bottom (up/down), adjusting for the fact that we have a * landscape input */ struct pagepoints land_ud_four_normal[] = { { xbase1, ybase1, 0 }, { xbase2, ybase1, 0 }, { xbase1, ybase3, 0 }, { xbase2, ybase3, 0 }, { 0, 0, 0} }; /* base points for eight pages, normal aspect, running reduced pages * read from left to right */ struct pagepoints lr_eight_normal[] = { { xbase2, ytop4, 0 }, { xbase2, ytop3, 0 }, { xbase2, ytop2, 0 }, { xbase2, ytop1, 0 }, { xbase1, ytop4, 0 }, { xbase1, ytop3, 0 }, { xbase1, ytop2, 0 }, { xbase1, ytop1, 0 }, { 0, 0, 0 } }; /* base points for eight pages, normal aspect, running reduced pages * read from top to bottom (up/down) */ struct pagepoints ud_eight_normal[] = { { xbase2, ytop4, 0 }, { xbase1, ytop4, 0 }, { xbase2, ytop3, 0 }, { xbase1, ytop3, 0 }, { xbase2, ytop2, 0 }, { xbase1, ytop2, 0 }, { xbase2, ytop1, 0 }, { xbase1, ytop1, 0 }, { 0, 0, 0 } }; /* base points for eight pages, normal aspect, running reduced pages * read from left to right, adjusting for the fact that we have a landscape * input */ struct pagepoints land_lr_eight_normal[] = { { xbase1, ytop4, 0 }, { xbase2, ytop4, 0 }, { xbase1, ytop3, 0 }, { xbase2, ytop3, 0 }, { xbase1, ytop2, 0 }, { xbase2, ytop2, 0 }, { xbase1, ytop1, 0 }, { xbase2, ytop1, 0 }, { 0, 0, 0 } }; /* base points for eight pages, normal aspect, running reduced pages * read from top to bottom (up/down), adjusting for the fact that we have a * landscape input */ struct pagepoints land_ud_eight_normal[] = { { xbase1, ytop4, 0 }, { xbase1, ytop3, 0 }, { xbase1, ytop2, 0 }, { xbase1, ytop1, 0 }, { xbase2, ytop4, 0 }, { xbase2, ytop3, 0 }, { xbase2, ytop2, 0 }, { xbase2, ytop1, 0 }, { 0, 0, 0} }; /* base point for one page, in landscape */ struct pagepoints one_landscape[] = { { xbase1, ytop4, 0 }, { 0, 0, 0 } }; /* base points for two pages, in landscape */ struct pagepoints two_landscape[] = { { xbase1, ybase3, 0 }, { xbase1, ybase1, 0 }, { 0, 0, 0 } }; /* base points for four pages, in landscape, running reduced pages * read from left to right */ struct pagepoints lr_four_landscape[] = { { xbase2, ytop4, 0 }, { xbase2, ytop2, 0 }, { xbase1, ytop4, 0 }, { xbase1, ytop2, 0 }, { 0, 0, 0 } }; /* base points for four pages, in landscape, running reduced pages * read from top to bottom (up/down) */ struct pagepoints ud_four_landscape[] = { { xbase2, ytop4, 0 }, { xbase1, ytop4, 0 }, { xbase2, ytop2, 0 }, { xbase1, ytop2, 0 }, { 0, 0, 0 } }; /* base points for eight pages, in landscape, running reduced pages * read from left to right */ struct pagepoints lr_eight_landscape[] = { { xbase1, ybase4, 0 }, { xbase2, ybase4, 0 }, { xbase1, ybase3, 0 }, { xbase2, ybase3, 0 }, { xbase1, ybase2, 0 }, { xbase2, ybase2, 0 }, { xbase1, ybase1, 0 }, { xbase2, ybase1, 0 }, { 0, 0, 0 } }; /* base points for eight pages, in landscape, running reduced pages * read from top to bottom (up/down) */ struct pagepoints ud_eight_landscape[] = { { xbase1, ybase4, 0 }, { xbase1, ybase3, 0 }, { xbase1, ybase2, 0 }, { xbase1, ybase1, 0 }, { xbase2, ybase4, 0 }, { xbase2, ybase3, 0 }, { xbase2, ybase2, 0 }, { xbase2, ybase1, 0 }, { 0, 0, 0 } }; /* list of sheets (printed page formats) for * left to right reading, in normal aspect */ struct sheet lr_normal[] = { /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal }, /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal }, /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, lr_four_normal }, /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, lr_eight_normal }, }; /* list of sheets (printed page formats) for landscape input * left to right reading, in normal aspect */ struct sheet land_lr_normal[] = { /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal }, /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal }, /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, land_lr_four_normal }, /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, land_lr_eight_normal }, }; /* list of sheets (printed page formats) for * top to bottom reading, in normal aspect */ struct sheet ud_normal[] = { /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal }, /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal }, /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, ud_four_normal }, /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, ud_eight_normal }, }; /* list of sheets (printed page formats) for * left to right reading, in landscape */ struct sheet lr_landscape[] = { /* 0 */ { 132, 52, yht1, xwid1, -90, outline_1, one_landscape }, /* 1 */ { 132, 52, xwid1, yht2, 0, outline_2, two_landscape }, /* 2 */ { 132, 52, yht2, xwid2, -90, outline_4, lr_four_landscape }, /* 3 */ { 132, 52, xwid2, yht4, 0, outline_8, lr_eight_landscape }, }; /* list of sheets (printed page formats) for * top to bottom reading, in landscape */ struct sheet ud_landscape[] = { /* 0 */ { 132, 52, yht1, xwid1, -90, outline_1, one_landscape }, /* 1 */ { 132, 52, xwid1, yht2, 0, outline_2, two_landscape }, /* 2 */ { 132, 52, yht2, xwid2, -90, outline_4, ud_four_landscape }, /* 3 */ { 132, 52, xwid2, yht4, 0, outline_8, ud_eight_landscape }, }; /* list of sheets (printed page formats) for landscape input * top to bottom reading, in landscape */ struct sheet land_ud_normal[] = { /* 0 */ { 80, 66, xwid1, yht1, 0, outline_1, one_normal }, /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal }, /* 2 */ { 80, 66, xwid2, yht2, 0, outline_4, land_ud_four_normal }, /* 3 */ { 80, 66, yht4, xwid2, -90, outline_8, land_ud_eight_normal }, }; /* GPN. sheet */ struct sheet coli [] = { /* 1 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal_co }, /* 2 */ { 80, 66, yht2, xwid1, -90, outline_2, two_normal_ci }, /* 3 */ { 80, 66, yht2, xwid1, -90, outline_2, four_normal_dm }, }; /* array of sheet lists for left to right reading printed pages */ struct sheet *left_right[] = { lr_normal, lr_landscape, land_lr_normal }; /* arrays for top to bottom reading printed pages */ struct sheet *up_down[] = { ud_normal, ud_landscape, land_ud_normal }; /* * Variables for holding the chosen options, The defaults are set here. * the sheetlist pointer is set to point to the array for either up/down * or left/right reading. This array is index by sheetorder, and then * sheetindex. sheetindex encodes the number of reduced pages per printed * page and indexes into the sheet list (0 = 1 page, 1 = two pages, 2 = * four pages, 3 = eight pages). */ struct sheet **sheetlist;/* array of sheet lists (up/down or left/right) */ int sheetaspect = PORTRAIT; /* either normal or landscape */ int sheetorder = UPDOWN; /* up/down or left/right flag */ int sheetindex = 2; /* index to page descriptor array */ int sheetmargin_left = DEFAULTSMARGIN; /* non-printable border on sheet */ int sheetmargin_right = DEFAULTSMARGIN; /* non-printable border on sheet */ int sheetmargin_top = DEFAULTSMARGIN; /* non-printable border on sheet */ int sheetmargin_bottom= DEFAULTSMARGIN; /* non-printable border on sheet */ int pagemargin_left = DEFAULTPMARGIN; /* border for pages */ int pagemargin_right = DEFAULTPMARGIN; /* border for pages */ int pagemargin_top = DEFAULTPMARGIN; /* border for pages */ int pagemargin_bottom = DEFAULTPMARGIN; /* border for pages */ int textmargin_left = DEFAULTTMARGIN; /* border for textbox */ int textmargin_right = DEFAULTTMARGIN; /* border for textbox */ int textmargin_top = DEFAULTTMARGIN; /* border for textbox */ int textmargin_bottom = DEFAULTTMARGIN; /* border for textbox */ int sheetheader_left = 0; /* space for physical sheetheader */ int sheetheader_right = 0; /* space for physical sheetheader */ int sheetheader_top = 0; /* space for physical sheetheader */ int sheetheader_bottom= 0; /* space for physical sheetheader */ struct pagepoints *points = points_empty; int orientation; /* final orientation of text */ int fsize = TSIZE; /* font scale size */ int opt_indent = 0; /* starting column for ascii printing */ int opt_tabstop = DEFAULTTABSTOP; /* width of a tab */ int opt_lines = 0; /* lines to fit on reduced page */ int opt_killtrail = 1; /* Quit reading input on %%TRailer */ int opt_width = 0; /* columns to fit on reduced page */ char * opt_page = PAGE_DEF; /* default paper size */ /* boolean's: set default to 0 or 1 */ int opt_pr = 0; /* if true use pr(1) to format output */ int opt_mp_header = 0; /* let mpage create headers */ int opt_sheetheader = 0; /* let mpage create sheetheaders */ int opt_fold = 0; /* fold lines longer than page width */ int opt_outline = 1; /* don't normally outline the pages */ int opt_verbose = 0; /* print a count of pages produced */ int opt_square = 1; /* print pages with natural aspect ratio */ int opt_reverse = 0; /* by default print sheets in forward order */ int opt_jarg = 0; /* number of -j opt sets */ int opt_first[MAXJARG]; /* start with first sheet per -j */ int opt_last[MAXJARG]; /* print as many as supplied per -j */ int opt_alt[MAXJARG]; /* by default print all sheets, odd+even per -j*/ int opt_file = 1; /* should each file appera on a new sheet */ int opt_duplex = DEFAULT_DUPLEX; /* duplex mode flag */ int opt_tumble = 0; /* tumble overy second pages */ int opt_textbox = 0; /* don't normally draw box around text */ int opt_input = IN_AUTO; /* select input file format */ int opt_encoding = DEFAULT_ENCODING; /* use default encoding or not */ struct pagebox textbox = {0, 0, 80, 66, 0}; char * opt_header = NULL; /* the header for pr's -h option */ char * printque = NULL; /* the printer queuename */ char * prprog = PRPROG; /* the pr filter program */ char * printprog = PRINTPROG; /* the print program */ char * printarg = QUEARG; /* define print queue to printprog */ int doprint = 0; /* send it to the printer */ char * charvec_file; /* file to read character definitions from */ char * libdir = LIBDIR; /* pointer to get library files from */ char * fontname = "Courier"; /* Font to use */ char * dateformat = "%c"; /* Date/time format for date in headers */ char * sheethead = ""; /* Leave empty to get default sheetheader: current filename + physical pagenumber */ /* * various global information */ char MPAGE[] = "mpage"; /* program name */ int ps_pagenum = 0; /* current sheet count (printed or not) */ int ps_outpages= 0; /* sheets printed */ int had_ps = 0; /* did we process ps files */ int first_encoding = -1; /* first encoding in character set */ int last_encoding; /* last encoding in character set */ /* GPN. for coli */ int Coli = 0; /* value of 0 = don't mess, 1 = 4, 1 (outside pages)*/ int use_utf8 = 0; /* is input UTF-8 or not. */ int check_utf8 = 1; /* do we want to check for UTF-8 or not. */ void usage(int errcode) { fprintf(stderr, "\ mpage - print multiple pages on postscript, version %s\n\n\ mpage [-1248aceEfHlkoOrRStTvuVxX] [-b papersize] [-Btextboxmargin]\n\ [-C [encodingfile]] [-da|p] [-D dateformat] [-F fontname]\n\ [-h header] [-I indent] [-j pagespec] [-J startpageno] [-L lines]\n\ [-msheetmargin] [-Mpagemargin] [-p[prprog]] [-P[printer]]\n\ [-s tabstop] [-W width] [-X [header]] [-z printcmd] [-Z quearg]\n\ [file...]]\n", VERSION ); fprintf(stderr, "\n\ -1, -2, -4, -8 Pages per sheet (4) -D strftime format for date specs\n\ -da Force ascii input format -dp Force postscript input format\n\ -a Toggle across/updown layout (u) -l Toggle portrait/landscape (p)\n\ -f Toggle folding long lines (off) -o Toggle printing outlines (on)\n\ -r Reverse printing, last->first sheet -v Toggle verbose output, (on)\n\ -F Text font to be used (%s) -C Character encoding filename\n\ -E Print every second and third page -O Print every first and fourth page\n\ -s Define tabstop width (%d) -k kill on %%TRailer is PS file\n\ -V Show mpage version.\n -u switch of utf-8 check\n\ -b papersize (%s), use l or ? to get a list of sizes\n\ -R Switch to across mode, with first page at lower left corner\n\ -H Create page header for each page for text files\n\ -X Print physical page header (filename + physical pagenumber)\n\ -c Toggle concat pages of different files on same sheet (off)\n\ -S Don't square pages for PS input (default uniform X/Y shrink)\n\ -B Specify textbox margin/thickness (no space): [[lrtb]*]*\n\ -m Specify sheetmargin (no space): [[lrtb]*]*\n\ -M Specify pagemargins (no space): [[lrtb]*]*\n\ -p Pipe through prprog (no space), pr(1) is default.\n\ Mpage assumes the specified pr understands -l, -w and -h options.\n\ -P Specify printer queue (no space). -P only uses default queue.\n\ -z Specify print command (%s).\n\ -Z Specify print command print queue option (%s).\n\ -j Print specified sheets: first[-last][%%interval]\n\ -j 1-10 does first 10 sheets, -j 1%%2 prints odd ones, -j 2%%2 even ones.\n\ -J Set the start of the sheet page count\n\ -t Toggle printing both sides of the paper (Duplex mode, %s)\n\ -T Toggle tumble of every second pages when printing in duplex mode (off)\n", fontname, opt_tabstop, PAGE_DEF, printprog, printarg, opt_duplex ? "on" : "off" ); fprintf(stderr, "\n(c) 1993-2005 Marcel Mol, marcel@mesa.nl (MESA Consulting)\n"); return; } /* usage */