diff options
Diffstat (limited to 'Build/source/texk/psutils/psutils-src/psnup.c')
-rw-r--r-- | Build/source/texk/psutils/psutils-src/psnup.c | 315 |
1 files changed, 0 insertions, 315 deletions
diff --git a/Build/source/texk/psutils/psutils-src/psnup.c b/Build/source/texk/psutils/psutils-src/psnup.c deleted file mode 100644 index 79e280a31f3..00000000000 --- a/Build/source/texk/psutils/psutils-src/psnup.c +++ /dev/null @@ -1,315 +0,0 @@ -/* psnup.c - * Put multiple pages on to one page - * - * (c) Reuben Thomas 2012-2014 - * (c) Angus J. C. Duggan 1991-1997 - * See file LICENSE for details. - */ - -#include "config.h" - -#include <unistd.h> -#include <string.h> -#include "progname.h" -#include "binary-io.h" - -#include "psutil.h" -#include "psspec.h" - -const char *syntax = "[-q] [-wWIDTH] [-hHEIGHT] [-pPAPER] [-WWIDTH] [-HHEIGHT] [-PPAPER] [-l] [-r] [-c] [-f] [-mMARGIN] [-bBORDER] [-dLWIDTH] [-sSCALE] [-NUP] [INFILE [OUTFILE]]\n"; - -const char *argerr_message = "bad dimension\n"; - -/* return next larger exact divisor of number, or 0 if none. There is probably - * a much more efficient method of doing this, but the numbers involved are - * small, so it's not a big loss. */ -_GL_ATTRIBUTE_CONST static int nextdiv(int n, int m) -{ - while (++n <= m) { - if (m%n == 0) - return (n); - } - return (0); -} - -int -main(int argc, char *argv[]) -{ - int horiz = 0, vert = 0, rotate = 0, column = 0; - int flip = 0, leftright = 0, topbottom = 0; - int nup = 1; - double draw = 0; /* draw page borders */ - double scale = 1.0; /* page scale */ - double uscale = 0; /* user supplied scale */ - double ppwid, pphgt; /* paper dimensions */ - double margin, border; /* paper & page margins */ - double vshift, hshift; /* page centring shifts */ - double iwidth, iheight ; /* input paper size */ - double tolerance = 100000; /* layout tolerance */ - off_t sizeheaders[20]; /* headers to remove */ - int opt; - - set_program_name (argv[0]); - - verbose = 1; - - if (!paper_size(NULL, &width, &height)) - die("could not get default paper size"); - - margin = border = vshift = hshift = column = flip = 0; - leftright = topbottom = 1; - iwidth = iheight = -1 ; - - while((opt = - getopt(argc, argv, - "qd::lrfcw:W:h:H:m:b:t:s:p:P:n:1::2::3::4::5::6::7::8::9::")) - != EOF) { - switch(opt) { - case 'q': /* quiet */ - verbose = 0; - break; - case 'd': /* draw borders */ - if (optarg) - draw = singledimen(optarg); - else - draw = 1; - break; - case 'l': /* landscape (rotated left) */ - column = !column; - topbottom = !topbottom; - break; - case 'r': /* seascape (rotated right) */ - column = !column; - leftright = !leftright; - break; - case 'f': /* flipped */ - flip = 1; - break; - case 'c': /* column major layout */ - column = !column; - break; - case 'w': /* page width */ - width = singledimen(optarg); - break; - case 'W': /* input page width */ - iwidth = singledimen(optarg); - break; - case 'h': /* page height */ - height = singledimen(optarg); - break; - case 'H': /* input page height */ - iheight = singledimen(optarg); - break; - case 'm': /* margins around whole page */ - margin = singledimen(optarg); - break; - case 'b': /* border around individual pages */ - border = singledimen(optarg); - break; - case 't': /* layout tolerance */ - tolerance = atof(optarg); - break; - case 's': /* override scale */ - uscale = atof(optarg); - break; - case 'p': /* output (and by default input) paper type */ - if (!paper_size(optarg, &width, &height)) - die("paper size '%s' not recognised", optarg); - break; - case 'P': /* paper type */ - if (!paper_size(optarg, &width, &height)) - die("paper size '%s' not recognised", optarg); - break; - case 'n': /* n-up, for compatibility with other psnups */ - if ((nup = atoi(optarg)) < 1) - die("-n %d too small", nup); - break; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if(optarg) { - char *valuestr = (char *) malloc(strlen(optarg) + 2); - valuestr[0] = opt; - strcpy(&(valuestr[1]), optarg); - - /* really should check that valuestr is only digits here...*/ - if ((nup = atoi(valuestr)) < 1) - die("-n %d too small", nup); - free(valuestr); - } else { - nup = (opt - '0'); - } - break; - case 'v': /* version */ - default: - usage(); - } - } - - infile = stdin; - outfile = stdout; - - /* Be defensive */ - if((argc - optind) < 0 || (argc - optind) > 2) usage(); - - if (optind != argc) { - /* User specified an input file */ - if ((infile = fopen(argv[optind], "rb")) == NULL) - die("can't open input file %s", argv[optind]); - optind++; - } - - if (optind != argc) { - /* User specified an output file */ - if ((outfile = fopen(argv[optind], "wb")) == NULL) - die("can't open output file %s", argv[optind]); - optind++; - } - - if (optind != argc) usage(); - - if (infile == stdin && set_binary_mode(fileno(stdin), O_BINARY) < 0) - die("can't reset stdin to binary mode"); - if (outfile == stdout && set_binary_mode(fileno(stdout), O_BINARY) < 0) - die("can't reset stdout to binary mode"); - - if ((infile=seekable(infile))==NULL) - die("can't seek input"); - - if (width <= 0 || height <= 0) - die("page width and height must be set"); - - /* subtract paper margins from height & width */ - ppwid = width - margin*2; - pphgt = height - margin*2; - - if (ppwid <= 0 || pphgt <= 0) - die("paper margins are too large"); - - scanpages(sizeheaders); - - /* set default values of input height & width */ - if ( iwidth > 0 ) - width = iwidth ; - if ( iheight > 0 ) - height = iheight ; - - /* Finding the best layout is an optimisation problem. We try all of the - * combinations of width*height in both normal and rotated form, and - * minimise the wasted space. */ - { - double best = tolerance; - int hor; - for (hor = 1; hor; hor = nextdiv(hor, nup)) { - int ver = nup/hor; - /* try normal orientation first */ - double scl = MIN(pphgt/(height*ver), ppwid/(width*hor)); - double optim = (ppwid-scl*width*hor)*(ppwid-scl*width*hor) + - (pphgt-scl*height*ver)*(pphgt-scl*height*ver); - if (optim < best) { - best = optim; - /* recalculate scale to allow for internal borders */ - scale = MIN((pphgt-2*border*ver)/(height*ver), - (ppwid-2*border*hor)/(width*hor)); - hshift = (ppwid/hor - width*scale)/2; - vshift = (pphgt/ver - height*scale)/2; - horiz = hor; vert = ver; - rotate = flip; - } - /* try rotated orientation */ - scl = MIN(pphgt/(width*hor), ppwid/(height*ver)); - optim = (pphgt-scl*width*hor)*(pphgt-scl*width*hor) + - (ppwid-scl*height*ver)*(ppwid-scl*height*ver); - if (optim < best) { - best = optim; - /* recalculate scale to allow for internal borders */ - scale = MIN((pphgt-2*border*hor)/(width*hor), - (ppwid-2*border*ver)/(height*ver)); - hshift = (ppwid/ver - height*scale)/2; - vshift = (pphgt/hor - width*scale)/2; - horiz = ver; vert = hor; - rotate = !flip; - } - } - - /* fail if nothing better than worst tolerance was found */ - if (best == tolerance) - die("can't find acceptable layout for %d-up", nup); - } - - if (flip) { /* swap width & height for clipping */ - double tmp = width; - width = height; - height = tmp; - } - - if (rotate) { /* rotate leftright and topbottom orders */ - int tmp = topbottom; - topbottom = !leftright; - leftright = tmp; - column = !column; - } - - /* now construct specification list and run page rearrangement procedure */ - { - int page = 0; - PageSpec *specs, *tail; - - tail = specs = newspec(); - - while (page < nup) { - int up, across; /* page index */ - - if (column) { - if (leftright) /* left to right */ - across = page/vert; - else /* right to left */ - across = horiz-1-page/vert; - if (topbottom) /* top to bottom */ - up = vert-1-page%vert; - else /* bottom to top */ - up = page%vert; - } else { - if (leftright) /* left to right */ - across = page%horiz; - else /* right to left */ - across = horiz-1-page%horiz; - if (topbottom) /* top to bottom */ - up = vert-1-page/horiz; - else /* bottom to top */ - up = page/horiz; - } - if (rotate) { - tail->xoff = margin + (across+1)*ppwid/horiz - hshift; - tail->rotate = 90; - tail->flags |= ROTATE; - } else { - tail->xoff = margin + across*ppwid/horiz + hshift; - } - tail->pageno = page; - if (uscale > 0) - tail->scale = uscale; - else - tail->scale = scale; - tail->flags |= SCALE; - tail->yoff = margin + up*pphgt/vert + vshift; - tail->flags |= OFFSET; - if (++page < nup) { - tail->flags |= ADD_NEXT; - tail->next = newspec(); - tail = tail->next; - } - } - - pstops_write(nup, 1, 0, specs, draw, sizeheaders); /* do page rearrangement */ - } - - return 0; -} - |