1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
14 #include "parseargs.h"
17 #include "GlobalParams.h"
26 #include "PSOutputDev.h"
30 static int firstPage
= 1;
31 static int lastPage
= 0;
32 static GBool level1
= gFalse
;
33 static GBool level1Sep
= gFalse
;
34 static GBool level2
= gFalse
;
35 static GBool level2Sep
= gFalse
;
36 static GBool level3
= gFalse
;
37 static GBool level3Sep
= gFalse
;
38 static GBool doEPS
= gFalse
;
39 static GBool doForm
= gFalse
;
41 static GBool doOPI
= gFalse
;
43 static GBool noEmbedT1Fonts
= gFalse
;
44 static GBool noEmbedTTFonts
= gFalse
;
45 static GBool noEmbedCIDPSFonts
= gFalse
;
46 static GBool noEmbedCIDTTFonts
= gFalse
;
47 static char paperSize
[15] = "";
48 static int paperWidth
= 0;
49 static int paperHeight
= 0;
50 static GBool noCrop
= gFalse
;
51 static GBool expand
= gFalse
;
52 static GBool noShrink
= gFalse
;
53 static GBool noCenter
= gFalse
;
54 static GBool pageCrop
= gFalse
;
55 static GBool duplex
= gFalse
;
56 static char ownerPassword
[33] = "\001";
57 static char userPassword
[33] = "\001";
58 static GBool quiet
= gFalse
;
59 static char cfgFileName
[256] = "";
60 static GBool printVersion
= gFalse
;
61 static GBool printHelp
= gFalse
;
63 static ArgDesc argDesc
[] = {
64 {"-f", argInt
, &firstPage
, 0,
65 "first page to print"},
66 {"-l", argInt
, &lastPage
, 0,
67 "last page to print"},
68 {"-level1", argFlag
, &level1
, 0,
69 "generate Level 1 PostScript"},
70 {"-level1sep", argFlag
, &level1Sep
, 0,
71 "generate Level 1 separable PostScript"},
72 {"-level2", argFlag
, &level2
, 0,
73 "generate Level 2 PostScript"},
74 {"-level2sep", argFlag
, &level2Sep
, 0,
75 "generate Level 2 separable PostScript"},
76 {"-level3", argFlag
, &level3
, 0,
77 "generate Level 3 PostScript"},
78 {"-level3sep", argFlag
, &level3Sep
, 0,
79 "generate Level 3 separable PostScript"},
80 {"-eps", argFlag
, &doEPS
, 0,
81 "generate Encapsulated PostScript (EPS)"},
82 {"-form", argFlag
, &doForm
, 0,
83 "generate a PostScript form"},
85 {"-opi", argFlag
, &doOPI
, 0,
86 "generate OPI comments"},
88 {"-noembt1", argFlag
, &noEmbedT1Fonts
, 0,
89 "don't embed Type 1 fonts"},
90 {"-noembtt", argFlag
, &noEmbedTTFonts
, 0,
91 "don't embed TrueType fonts"},
92 {"-noembcidps", argFlag
, &noEmbedCIDPSFonts
, 0,
93 "don't embed CID PostScript fonts"},
94 {"-noembcidtt", argFlag
, &noEmbedCIDTTFonts
, 0,
95 "don't embed CID TrueType fonts"},
96 {"-paper", argString
, paperSize
, sizeof(paperSize
),
97 "paper size (letter, legal, A4, A3, match)"},
98 {"-paperw", argInt
, &paperWidth
, 0,
99 "paper width, in points"},
100 {"-paperh", argInt
, &paperHeight
, 0,
101 "paper height, in points"},
102 {"-nocrop", argFlag
, &noCrop
, 0,
103 "don't crop pages to CropBox"},
104 {"-expand", argFlag
, &expand
, 0,
105 "expand pages smaller than the paper size"},
106 {"-noshrink", argFlag
, &noShrink
, 0,
107 "don't shrink pages larger than the paper size"},
108 {"-nocenter", argFlag
, &noCenter
, 0,
109 "don't center pages smaller than the paper size"},
110 {"-pagecrop", argFlag
, &pageCrop
, 0,
111 "treat the CropBox as the page size"},
112 {"-duplex", argFlag
, &duplex
, 0,
113 "enable duplex printing"},
114 {"-opw", argString
, ownerPassword
, sizeof(ownerPassword
),
115 "owner password (for encrypted files)"},
116 {"-upw", argString
, userPassword
, sizeof(userPassword
),
117 "user password (for encrypted files)"},
118 {"-q", argFlag
, &quiet
, 0,
119 "don't print any messages or errors"},
120 {"-cfg", argString
, cfgFileName
, sizeof(cfgFileName
),
121 "configuration file to use in place of .xpdfrc"},
122 {"-v", argFlag
, &printVersion
, 0,
123 "print copyright and version info"},
124 {"-h", argFlag
, &printHelp
, 0,
125 "print usage information"},
126 {"-help", argFlag
, &printHelp
, 0,
127 "print usage information"},
128 {"--help", argFlag
, &printHelp
, 0,
129 "print usage information"},
130 {"-?", argFlag
, &printHelp
, 0,
131 "print usage information"},
135 int main(int argc
, char *argv
[]) {
141 GString
*ownerPW
, *userPW
;
150 ok
= parseArgs(argDesc
, &argc
, argv
);
151 if (!ok
|| argc
< 2 || argc
> 3 || printVersion
|| printHelp
) {
152 fprintf(stderr
, "pdftops version %s\n", xpdfVersion
);
153 fprintf(stderr
, "%s\n", xpdfCopyright
);
155 printUsage("pdftops", "<PDF-file> [<PS-file>]", argDesc
);
159 if ((level1
? 1 : 0) +
160 (level1Sep
? 1 : 0) +
162 (level2Sep
? 1 : 0) +
164 (level3Sep
? 1 : 0) > 1) {
165 fprintf(stderr
, "Error: use only one of the 'level' options.\n");
168 if (doEPS
&& doForm
) {
169 fprintf(stderr
, "Error: use only one of -eps and -form\n");
174 } else if (level1Sep
) {
176 } else if (level2Sep
) {
180 } else if (level3Sep
) {
185 if (doForm
&& level
< psLevel2
) {
186 fprintf(stderr
, "Error: forms are only available with Level 2 output.\n");
189 mode
= doEPS
? psModeEPS
190 : doForm
? psModeForm
192 fileName
= new GString(argv
[1]);
195 globalParams
= new GlobalParams(cfgFileName
);
197 if (!globalParams
->setPSPaperSize(paperSize
)) {
198 fprintf(stderr
, "Invalid paper size\n");
204 globalParams
->setPSPaperWidth(paperWidth
);
207 globalParams
->setPSPaperHeight(paperHeight
);
211 globalParams
->setPSCrop(gFalse
);
214 globalParams
->setPSExpandSmaller(gTrue
);
217 globalParams
->setPSShrinkLarger(gFalse
);
220 globalParams
->setPSCenter(gFalse
);
223 globalParams
->setPSDuplex(duplex
);
225 if (level1
|| level1Sep
|| level2
|| level2Sep
|| level3
|| level3Sep
) {
226 globalParams
->setPSLevel(level
);
228 if (noEmbedT1Fonts
) {
229 globalParams
->setPSEmbedType1(!noEmbedT1Fonts
);
231 if (noEmbedTTFonts
) {
232 globalParams
->setPSEmbedTrueType(!noEmbedTTFonts
);
234 if (noEmbedCIDPSFonts
) {
235 globalParams
->setPSEmbedCIDPostScript(!noEmbedCIDPSFonts
);
237 if (noEmbedCIDTTFonts
) {
238 globalParams
->setPSEmbedCIDTrueType(!noEmbedCIDTTFonts
);
242 globalParams
->setPSOPI(doOPI
);
246 globalParams
->setErrQuiet(quiet
);
250 if (ownerPassword
[0] != '\001') {
251 ownerPW
= new GString(ownerPassword
);
255 if (userPassword
[0] != '\001') {
256 userPW
= new GString(userPassword
);
260 doc
= new PDFDoc(fileName
, ownerPW
, userPW
);
272 // check for print permission
273 if (!doc
->okToPrint()) {
274 error(-1, "Printing this document is not allowed.");
279 // construct PostScript file name
281 psFileName
= new GString(argv
[2]);
283 p
= fileName
->getCString() + fileName
->getLength() - 4;
284 if (!strcmp(p
, ".pdf") || !strcmp(p
, ".PDF")) {
285 psFileName
= new GString(fileName
->getCString(),
286 fileName
->getLength() - 4);
288 psFileName
= fileName
->copy();
290 psFileName
->append(doEPS
? ".eps" : ".ps");
297 if (lastPage
< 1 || lastPage
> doc
->getNumPages()) {
298 lastPage
= doc
->getNumPages();
301 // check for multi-page EPS or form
302 if ((doEPS
|| doForm
) && firstPage
!= lastPage
) {
303 error(-1, "EPS and form files can only contain one page.");
307 // write PostScript file
308 psOut
= new PSOutputDev(psFileName
->getCString(), doc
->getXRef(),
309 doc
->getCatalog(), firstPage
, lastPage
, mode
);
311 doc
->displayPages(psOut
, firstPage
, lastPage
, 72, 72,
312 0, !pageCrop
, globalParams
->getPSCrop(), gFalse
);
330 // check for memory leaks
331 Object::memCheck(stderr
);