/*
* 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): [<num>[lrtb]*]*\n\
-m Specify sheetmargin (no space): [<num>[lrtb]*]*\n\
-M Specify pagemargins (no space): [<num>[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, [email protected] (MESA Consulting)\n");
return;
} /* usage */
|