#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <error.h>
#include <errno.h>
#ifndef FALSE
#define FALSE (0!=0)
#define TRUE (0==0)
#endif
/*
Add parameters:
--a3
--ledger (11x17) --tabloid
--legal (11x14) (unlikely to be needed)
--a4
--letter (8.5x11)
--half-letter (5.5x8.5)
letter_letter -> ledger
half-letter+half-letter -> letter
a4+a4 -> a3
a5+a5 -> a4
Table 1: Paper Size
w bp h bp w in h in w mm h mm
A0b 2594 3370 36.03 46.81 915 1189
A0 2380 3368 33.06 46.78 840 1188
A1 1684 2380 23.39 33.06 594 840
A2 1190 1684 16.53 23.39 420 594
A3 842 1190 11.69 16.53 297 420
A4 595 842 8.26 11.69 210 297
A5 421 595 5.85 8.26 149 210
A6 298 421 4.14 5.85 105 149
A7 211 298 2.93 4.14 74 105
A8 149 211 2.07 2.93 53 74
A9 106 149 1.47 2.07 37 53
A10 75 106 1.04 1.47 26 37
to scale to given paper size, or use unscaled if it fits already.
Want to force page size to Letter (8.5x11) then abut 2 letter pages side by side.
(If getting fancy, slight left/right offset for margin at spine.)
this may do it:
/usr/bin/pdfjam --nup '2x1' --landscape --papersize '{11in,17in}' --noautoscale 'true' --outfile pdfjam1+2.pdf -- foliotmp2.pdf - foliotmp4.pdf -
if you wanted to glue pages vertically, use --nup 1x2 --no-landscape
If you wanted no auto-scaling of pages (mine stretches output to fill a4 by default), use --noautoscale true
Setting the paper size to something unconventional works with another switch, such as --papersize '{6.125in,9.250in}'.
Suppose we have a document made up of 'US letter' size pages, and we want to convert it to A4:
pdfjam 'my US letter file.pdf' --a4paper --outfile 'my A4 file.pdf'
To offset the content of double-sided printed pages so that they are suitable for binding with a Heftstreifen,
use the --twoside option:
pdfjam --twoside myfile.pdf --offset '1cm 0cm' --suffix 'offset'
Check for pages being a multiple of 4 or 4X+1 if front cover included. (do we need to check for a back cover?)
gtoal@linux:~/src/printer_spread$ pdfinfo TG.pdf
Creator: Adobe Acrobat 7.05
Producer: Adobe Acrobat 7.05 Image Conversion Plug-in
CreationDate: Sat Jun 17 15:49:07 2006 CDT
ModDate: Sat Jun 17 15:50:00 2006 CDT
Tagged: no
UserProperties: no
Suspects: no
Form: AcroForm
JavaScript: no
Pages: 69
Encrypted: no
Page size: 610.56 x 773.52 pts
Page rot: 0
File size: 2269880 bytes
Optimized: no
PDF version: 1.6
*/
#define ELEVENby17 1
#define A3 2
int main(int argc, char **argv) {
int sheet = 1;
int i, rc;
static char pdfseparate[1024];
static char pdfinfo[1024];
static char twoup[1024];
static char landscape[1024];
static char portrait[1024];
int skip_cover = FALSE;
int pages = 0, rotation, paper = 0;
int base_page;
FILE *info;
float width, height;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if ((argc >= 2) && (strcmp(argv[1], "--nocover")==0)) {
argv += 1; argc -= 1; skip_cover = TRUE;
}
if ((argc >= 2) && (strcmp(argv[1], "--11x17")==0)) {
argv += 1; argc -= 1; paper = ELEVENby17;
}
if ((argc >= 2) && (strcmp(argv[1], "--a3")==0)) {
argv += 1; argc -= 1; paper = A3;
}
if (paper == 0) paper = ELEVENby17; // my default
if (argc != 2) {
fprintf(stderr, "syntax: layout [--nocover] file.pdf\n");
exit(1);
}
sprintf(pdfinfo, "pdfinfo %s", argv[1]);
info = popen(pdfinfo, "r");
if (info == NULL) {
fprintf(stderr, "layout: %s\n", strerror(errno));
exit(3);
}
while ((nread = getline(&line, &len, info)) != -1) {
rc = sscanf(line, "Pages: %d\n", &pages);
if (rc == 1) {
fprintf(stderr, "Document contains %d pages\n", pages);
}
rc = sscanf(line, "Page size: %f x %f pts\n", &width, &height);
if (rc == 2) {
fprintf(stderr, "Page size is %f by %f pts\n", width, height);
}
rc = sscanf(line, "Page rot: %d\n", &rotation);
if (rc == 1) {
fprintf(stderr, "Rotation is %d\n", rotation);
}
}
free(line);
pclose(info);
if (pages == 0) {
fprintf(stderr, "layout: no pages to arrange\?\n");
exit(4);
}
system("rm -f foliotmp[0-9]*.pdf");
if (skip_cover) {
sprintf(pdfseparate, "pdfseparate -f 2 %s foliotmp%%d.pdf", argv[1]); // pages numbered from 1 upwards. so cover sheet is page 1
pages -= 1; base_page = 2;
} else {
sprintf(pdfseparate, "pdfseparate %s foliotmp%%d.pdf", argv[1]);
base_page = 1;
}
fprintf(stderr, "%s\n", pdfseparate);
rc = system(pdfseparate);
if (WIFSIGNALED(rc) && (WTERMSIG(rc) == SIGINT || WTERMSIG(rc) == SIGQUIT)) exit(rc);
if (rc != 0) {
if (errno != 0) fprintf(stderr, "layout: %s\n", strerror(errno));
exit(2);
}
// convert each pdf page to an image,
// use imagemagik (convert) to threshold it to remove grey background
// repackage back into same-sized pages
// pdftoppm foliotmp69.pdf |pnmtopng -hist |convert png:- -sharpen 0x3 -white-threshold '90%' foliotmp69-new.pdf
printf(" two-sided printing\n");
printf(" lower side upper side\n");
system("rm -f twoup[0-9]*.pdf");
for (i = 0; i < pages/2; i += 2) {
printf("+-----+-----+ +-----+-----+\n");
printf("| | | | | |\n");
printf("| %02d | %02d | | %02d | %02d |\n", pages+1-(i+2)+1, i+0+1, i+1+1, pages+1-(i+3)+1);
printf("| | | | | |\n");
printf("| | | | | |\n");
printf("+-----+-----+ +-----+-----+ sheet %d\n\n", sheet);
sprintf(twoup, "/usr/bin/pdfjam --nup '2x1' --landscape --papersize '{11in,17in}'"
" --noautoscale 'true' --outfile twoup%04d-a.pdf -- foliotmp%0d.pdf - foliotmp%0d.pdf -", sheet, pages+1-(i+2), i+0);
fprintf(stderr, "%s\n", twoup);
system(twoup);
sprintf(twoup, "/usr/bin/pdfjam --nup '2x1' --landscape --papersize '{11in,17in}'"
" --noautoscale 'true' --outfile twoup%04d-b.pdf -- foliotmp%0d.pdf - foliotmp%0d.pdf -", sheet, i+1, pages+1-(i+3));
fprintf(stderr, "%s\n", twoup);
system(twoup);
sheet += 1;
}
system("pdfjam twoup*.pdf");
sprintf(landscape, "mv twoup%04d-b-pdfjam.pdf landscape-tmp.pdf", sheet-1);
system(landscape);
system("cpdf -rotate 90 -i landscape-tmp.pdf -o portrait-tmp.pdf");
system("/usr/bin/pdfjam --papersize '{17in,11in}' --landscape --twoside --scale 2.2 --outfile portrait.pdf portrait-tmp.pdf");
fprintf(stderr, "Output is in portrait.pdf\n");
// system("rm -f foliotmp[0-9]*.pdf twoup[0-9]*.pdf landscape-tmp.pdf portrait-tmp.pdf");
if (pages&3) {
fprintf(stderr, "Warning: not a multiple of 4 pages. Need to tweak the code to fix that...\n");
exit(5);
}
exit(0);
}