2
Copyright (c) 2007, BBR Inc. All rights reserved.
4
Permission is hereby granted, free of charge, to any person obtaining
5
a copy of this software and associated documentation files (the
6
"Software"), to deal in the Software without restriction, including
7
without limitation the rights to use, copy, modify, merge, publish,
8
distribute, sublicense, and/or sell copies of the Software, and to
9
permit persons to whom the Software is furnished to do so, subject to
10
the following conditions:
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
pdf to pdf filter, utilty version
32
#include "goo/GooString.h"
38
#include "P2POutputStream.h"
41
#include "GlobalParams.h"
42
#include "parseargs.h"
43
#include "PDFFTrueTypeFont.h"
47
GBool fitplot = gFalse;
48
GBool mirror = gFalse;
50
char numberUpLayoutStr[5] = "";
51
unsigned int numberUpLayout = PDFTOPDF_LAYOUT_LRTB;
52
char pageBorderStr[15] = "";
53
char pageSetStr[5] = "";
54
char pageRangesStr[255] = "";
55
unsigned int pageBorder = PDFTOPDF_BORDERNONE;
59
double pageRight = 612.0;
60
double pageBottom = 0;
61
double pageTop = 792.0;
62
double pageWidth = 612.0;
63
double pageLength = 792.0;
68
GBool position = gFalse;
69
char positionStr[15] = "";
73
double naturalScaling = 1.0;
74
int aNaturalScaling = -1;
75
GBool printHelp = gFalse;
76
GBool printVersion = gFalse;
78
GBool landscape = gFalse;
79
char paperSize[15] = "";
82
int bottomMargin = -1;
84
char ownerPassword[33] = "\001";
85
char userPassword[33] = "\001";
86
GBool reverseOrder = gFalse;
87
GBool collate = gFalse;
88
GBool fontEmbedding = gFalse;
89
GBool fontNoCompress = gFalse;
90
GBool contentNoCompress = gFalse;
91
GooString *ownerPW = NULL;
92
GooString *userPW = NULL;
100
{"Letter", 612, 792},
101
{"Legal", 612, 1008},
102
{"Executive", 522, 757},
115
{"Postcard", 283, 421},
120
static ArgDesc argDesc[] = {
121
{const_cast<char *>("-c"), argInt, &copies, 0,
122
const_cast<char *>("number of copies")},
123
{const_cast<char *>("-copies"), argInt, &copies, 0,
124
const_cast<char *>("number of copies")},
125
{const_cast<char *>("-fitplot"),argFlag, &fitplot, 0,
126
const_cast<char *>("fit original page to new page region")},
127
{const_cast<char *>("-number-up"),argInt, &numberUp, 0,
128
const_cast<char *>("number up (1,2,4,6,8,9,16)")},
129
{const_cast<char *>("-number-up-layout"), argString,numberUpLayoutStr,sizeof(numberUpLayoutStr),
130
const_cast<char *>("number up layout (lrtb,lrbt,rltb,rlbt,tblr,tbrl,btlr,btrl)")},
131
{const_cast<char *>("-reverse"), argFlag, &reverseOrder, 0,
132
const_cast<char *>("reverse output order")},
133
{const_cast<char *>("-mirror"), argFlag, &mirror, 0,
134
const_cast<char *>("mirror image")},
135
{const_cast<char *>("-collate"), argFlag, &collate, 0,
136
const_cast<char *>("collate")},
137
{const_cast<char *>("-scaling"),argInt, &aScaling, 0,
138
const_cast<char *>("scaling, in %")},
139
{const_cast<char *>("-natural-scaling"),argInt, &aNaturalScaling, 0,
140
const_cast<char *>("natural scaling, in %")},
141
{const_cast<char *>("-page-border"),argString, pageBorderStr, sizeof(pageBorderStr),
142
const_cast<char *>("page border (none,single,single-thick,double,double-thick)")},
143
{const_cast<char *>("-landscape"),argFlag, &landscape, 0,
144
const_cast<char *>("landscape")},
145
{const_cast<char *>("-orientation"),argInt, &orientation, 0,
146
const_cast<char *>("orientation (0,1,2,3)")},
147
{const_cast<char *>("-paper"), argString, paperSize, sizeof(paperSize),
148
const_cast<char *>("paper size (letter, legal, A0 ... A5, B0 ... B5)")},
149
{const_cast<char *>("-paperw"), argInt, &paperWidth, 0,
150
const_cast<char *>("paper width, in points")},
151
{const_cast<char *>("-paperh"), argInt, &paperHeight, 0,
152
const_cast<char *>("paper height, in points")},
153
{const_cast<char *>("-margin"), argInt, &aMargin, 0,
154
const_cast<char *>("paper margin, in points")},
155
{const_cast<char *>("-page-left"),argInt, &leftMargin, 0,
156
const_cast<char *>("left margin, in points")},
157
{const_cast<char *>("-page-right"),argInt, &rightMargin, 0,
158
const_cast<char *>("right margin, in points")},
159
{const_cast<char *>("-page-bottom"),argInt, &bottomMargin, 0,
160
const_cast<char *>("bottom margin, in points")},
161
{const_cast<char *>("-page-top"), argInt, &topMargin, 0,
162
const_cast<char *>("top margin, in points")},
163
{const_cast<char *>("-page-set"), argString, pageSetStr, sizeof(pageSetStr),
164
const_cast<char *>("page set (odd or even)")},
165
{const_cast<char *>("-page-ranges"),argString, pageRangesStr, sizeof(pageRangesStr),
166
const_cast<char *>("page ranges (Ex. 2-4,8)")},
167
{const_cast<char *>("-font-embedding"),argFlag, &fontEmbedding, 0,
168
const_cast<char *>("embedding fonts")},
169
{const_cast<char *>("-no-compressing-font"),argFlag,&fontNoCompress,0,
170
const_cast<char *>("not compressing embedding fonts")},
171
{const_cast<char *>("-no-compressing-contents"),argFlag,&contentNoCompress,0,
172
const_cast<char *>("not compressing page contents")},
173
{const_cast<char *>("-position"),argString, positionStr, sizeof(positionStr),
174
const_cast<char *>("page position (center,top,left,right,top-left,top-right,bottom,bottom-left,bottom-right)\n")},
175
{const_cast<char *>("-opw"), argString, ownerPassword, sizeof(ownerPassword),
176
const_cast<char *>("owner password (for encrypted files)")},
177
{const_cast<char *>("-upw"), argString, userPassword, sizeof(userPassword),
178
const_cast<char *>("user password (for encrypted files)")},
179
{const_cast<char *>("-v"), argFlag, &printVersion, 0,
180
const_cast<char *>("print version info")},
181
{const_cast<char *>("-h"), argFlag, &printHelp, 0,
182
const_cast<char *>("print usage information")},
183
{const_cast<char *>("-help"), argFlag, &printHelp, 0,
184
const_cast<char *>("print usage information")},
185
{const_cast<char *>("--help"), argFlag, &printHelp, 0,
186
const_cast<char *>("print usage information")},
187
{const_cast<char *>("--?"), argFlag, &printHelp, 0,
188
const_cast<char *>("print usage information")},
192
void CDECL myErrorFun(int pos, char *msg, va_list args)
195
fprintf(stderr, "ERROR (%d): ", pos);
197
fprintf(stderr, "ERROR: ");
199
vfprintf(stderr, msg, args);
200
fprintf(stderr, "\n");
204
Paper *getPaper(char *name)
206
for (Paper *p = papers;p->name != NULL;p++) {
207
if (strcasecmp(name,p->name) == 0) {
214
void parseOpts(int *argc, char **argv)
219
ok = parseArgs(argDesc,argc,argv);
220
if (!ok || *argc < 1 || *argc > 3 || printVersion || printHelp) {
221
fprintf(stderr, "pdf2pdf version %s\n", VERSION);
224
const_cast<char *>("[<input PDF-file> [<output PDF-file>]]"), argDesc);
230
fprintf(stderr,"number of copies should be plus number\n");
233
P2PDoc::options.copies = copies;
236
if (paperSize[0] != '\0') {
237
if ((ppaper = getPaper(paperSize)) == NULL) {
238
fprintf(stderr,"Unknown paper\n");
241
pageWidth = ppaper->width;
242
pageLength = ppaper->height;
245
if (paperWidth < 0) {
246
fprintf(stderr,"paper width should be plus\n");
249
if (paperWidth > 0) {
250
pageWidth = paperWidth;
253
if (paperHeight < 0) {
254
fprintf(stderr,"paper height should be plus\n");
257
if (paperHeight > 0) {
258
pageLength = paperHeight;
267
pageRight = pageWidth - margin;
269
pageTop = pageLength - margin;
273
if (orientation < 0 || orientation > 3) {
274
fprintf(stderr,"orientation value should be one of (0,1,2,3)\n");
278
if (leftMargin >= 0) {
279
switch (orientation & 3) {
281
pageLeft = leftMargin;
284
pageBottom = leftMargin;
287
pageRight = pageWidth - leftMargin;
290
pageTop = pageLength - leftMargin;
295
if (rightMargin >= 0) {
296
switch (orientation & 3) {
298
pageRight = pageWidth - rightMargin;
301
pageTop = pageLength - rightMargin;
304
pageLeft = rightMargin;
307
pageBottom = rightMargin;
312
if (bottomMargin >= 0) {
313
switch (orientation & 3) {
315
pageBottom = bottomMargin;
318
pageLeft = bottomMargin;
321
pageTop = pageLength - bottomMargin;
324
pageRight = pageWidth - bottomMargin;
329
if (topMargin >= 0) {
330
switch (orientation & 3) {
332
pageTop = pageLength - topMargin;
335
pageRight = pageWidth - topMargin;
338
pageBottom = topMargin;
341
pageLeft = topMargin;
358
"Unsupported number-up value %d, should be one of (1,2,4,6,8,16)\n",
363
if (numberUpLayoutStr[0] != '\0') {
364
if (!strcasecmp(numberUpLayoutStr,"lrtb")) {
365
numberUpLayout = PDFTOPDF_LAYOUT_LRTB;
366
} else if (!strcasecmp(numberUpLayoutStr,"lrbt")) {
367
numberUpLayout = PDFTOPDF_LAYOUT_LRBT;
368
} else if (!strcasecmp(numberUpLayoutStr,"rltb")) {
369
numberUpLayout = PDFTOPDF_LAYOUT_RLTB;
370
} else if (!strcasecmp(numberUpLayoutStr,"rlbt")) {
371
numberUpLayout = PDFTOPDF_LAYOUT_RLBT;
372
} else if (!strcasecmp(numberUpLayoutStr,"tblr")) {
373
numberUpLayout = PDFTOPDF_LAYOUT_TBLR;
374
} else if (!strcasecmp(numberUpLayoutStr,"tbrl")) {
375
numberUpLayout = PDFTOPDF_LAYOUT_TBRL;
376
} else if (!strcasecmp(numberUpLayoutStr,"btlr")) {
377
numberUpLayout = PDFTOPDF_LAYOUT_BTLR;
378
} else if (!strcasecmp(numberUpLayoutStr,"btrl")) {
379
numberUpLayout = PDFTOPDF_LAYOUT_BTRL;
381
fprintf(stderr, "Unsupported number-up-layout value %s,\n"
382
" should be one of (lrtb,lrbt,rltb,rlbt,tblr,tbrl,btlr,btrl)\n",
388
P2PDoc::options.reverse = gTrue;
390
if (pageBorderStr[0] != '\0') {
391
if (!strcasecmp(pageBorderStr,"none")) {
392
pageBorder = PDFTOPDF_BORDERNONE;
393
} else if (!strcasecmp(pageBorderStr,"single")) {
394
pageBorder = PDFTOPDF_BORDERHAIRLINE;
395
} else if (!strcasecmp(pageBorderStr,"single-thick")) {
396
pageBorder = PDFTOPDF_BORDERTHICK;
397
} else if (!strcasecmp(pageBorderStr,"double")) {
398
pageBorder = PDFTOPDF_BORDERDOUBLE | PDFTOPDF_BORDERHAIRLINE;
399
} else if (!strcasecmp(pageBorderStr,"double-thick")) {
400
pageBorder = PDFTOPDF_BORDERDOUBLE | PDFTOPDF_BORDERTHICK;
402
fprintf(stderr, "Unsupported page-border value %s,\n"
403
" should be one of (none,single,single-thick,double,double-thick)\n",
408
if (pageSetStr[0] != '\0') {
409
if (strcasecmp(pageSetStr,"even") != 0 &&
410
strcasecmp(pageSetStr,"odd") != 0) {
411
fprintf(stderr, "Page set should be odd or even\n");
414
P2PDoc::options.pageSet = pageSetStr;
416
if (pageRangesStr[0] != '\0') {
417
P2PDoc::options.pageRanges = pageRangesStr;
419
if (positionStr[0] != '\0') {
420
if (strcasecmp(positionStr,"center") == 0) {
423
} else if (strcasecmp(positionStr,"top") == 0) {
426
} else if (strcasecmp(positionStr,"left") == 0) {
429
} else if (strcasecmp(positionStr,"right") == 0) {
432
} else if (strcasecmp(positionStr,"top-left") == 0) {
435
} else if (strcasecmp(positionStr,"top-right") == 0) {
438
} else if (strcasecmp(positionStr,"bottom") == 0) {
441
} else if (strcasecmp(positionStr,"bottom-left") == 0) {
444
} else if (strcasecmp(positionStr,"bottom-right") == 0) {
448
fprintf(stderr, "Unsupported postion value %s,\n"
449
" should be one of (center,top,left,right,top-left,top-right,bottom,bottom-left,bottom-right).\n",
457
P2PDoc::options.collate = gTrue;
461
scaling = aScaling * 0.01;
463
} else if (fitplot) {
466
if (aNaturalScaling > 0) {
467
naturalScaling = aNaturalScaling * 0.01;
470
/* embedding fonts into output PDF */
471
P2PDoc::options.fontEmbedding = fontEmbedding;
472
P2PDoc::options.fontCompress = !fontNoCompress;
473
P2PDoc::options.contentsCompress = !contentNoCompress;
475
if (P2PDoc::options.copies == 1) {
476
/* collate is not needed */
477
P2PDoc::options.collate = gFalse;
480
if (ownerPassword[0] != '\001') {
481
ownerPW = new GooString(ownerPassword);
483
if (userPassword[0] != '\001') {
484
userPW = new GooString(userPassword);
488
int main(int argc, char *argv[]) {
491
P2POutputStream *str;
494
setErrorFunction(::myErrorFun);
495
parseOpts(&argc, argv);
496
#ifdef GLOBALPARAMS_HAS_A_ARG
497
globalParams = new GlobalParams(0);
499
globalParams = new GlobalParams();
502
PDFRectangle box(pageLeft,pageBottom,pageRight,pageTop);
503
PDFRectangle mediaBox(0,0,pageWidth,pageLength);
505
if (argc >=3 && strcmp(argv[2],"-") != 0) {
506
if ((outfp = fopen(argv[2],"wb")) == NULL) {
507
error(-1,const_cast<char *>("Can't open output file:%s"),argv[3]);
513
if (argc <= 1 || strcmp(argv[1],"-") == 0) {
523
error(-1,const_cast<char *>("Can't create temporary file"));
527
/* copy stdin to the tmp file */
528
while ((n = fread(buf,1,BUFSIZ,stdin)) > 0) {
529
if (fwrite(buf,1,n,fp) != n) {
530
error(-1,const_cast<char *>("Can't copy stdin to temporary file"));
538
str = new FileStream(fp,0,gFalse,0,&obj);
539
doc = new PDFDoc(str,ownerPW,userPW);
541
GooString *fileName = new GooString(argv[1]);
542
/* input filenmae is specified */
543
doc = new PDFDoc(fileName,ownerPW,userPW);
549
if (!doc->okToChange() && !doc->okToAssemble()) {
550
error(-1,const_cast<char *>("Neither Changing, nor Assembling is allowed\n"));
553
p2pdoc = new P2PDoc(doc);
558
if (orientation != 0) {
559
p2pdoc->rotate(orientation);
562
if (naturalScaling != 1.0) {
563
p2pdoc->scale(naturalScaling);
564
p2pdoc->position(&box,xposition,yposition);
568
p2pdoc->fit(&box,scaling);
569
p2pdoc->position(&box,xposition,yposition);
572
p2pdoc->nup(numberUp,&box,pageBorder,numberUpLayout,
573
xposition,yposition);
574
} else if (position) {
575
p2pdoc->position(&box,xposition,yposition);
578
if (orientation != 0 || naturalScaling != 1.0 || fitplot
579
|| numberUp != 1 || position) {
580
/* When changing geometry,
581
set all pages's mediaBox to the target page size */
582
p2pdoc->setMediaBox(&mediaBox);
585
if (P2PDoc::options.collate
586
&& p2pdoc->getNumberOfPages() == 1
587
&& !P2PDoc::options.even) {
588
/* collate is not needed, disable it */
589
/* Number of pages is changed by nup and page-ranges,
590
so check this here */
591
P2PDoc::options.collate = gFalse;
594
str = new P2POutputStream(outfp); /* PDF start here */
602
// Check for memory leaks
603
Object::memCheck(stderr);
609
/* replace memory allocation methods for memory check */
611
void * operator new(size_t size)
613
return gmalloc(size);
616
void operator delete(void *p)
621
void * operator new[](size_t size)
623
return gmalloc(size);
626
void operator delete[](void *p)