1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
|
/*
* 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, marcel@mesa.nl (MESA Consulting)\n");
return;
} /* usage */
|