1 //========================================================================
2 //
3 // xpdf.cc
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10 #include "gtypes.h"
11 #include "GString.h"
12 #include "parseargs.h"
13 #include "gfile.h"
14 #include "gmem.h"
15 #include "GlobalParams.h"
16 #include "Object.h"
17 #include "XPDFApp.h"
18 #include "config.h"
19
20 //------------------------------------------------------------------------
21 // command line options
22 //------------------------------------------------------------------------
23
24 static GBool contView = gFalse;
25 static char enableFreeTypeStr[16] = "";
26 static char antialiasStr[16] = "";
27 static char vectorAntialiasStr[16] = "";
28 static char psFileArg[256];
29 static char paperSize[15] = "";
30 static int paperWidth = 0;
31 static int paperHeight = 0;
32 static GBool level1 = gFalse;
33 static char textEncName[128] = "";
34 static char textEOL[16] = "";
35 static char ownerPassword[33] = "\001";
36 static char userPassword[33] = "\001";
37 static GBool fullScreen = gFalse;
38 static char remoteName[100] = "xpdf_";
39 static char remoteCmd[512] = "";
40 static GBool doRemoteReload = gFalse;
41 static GBool doRemoteRaise = gFalse;
42 static GBool doRemoteQuit = gFalse;
43 static GBool printCommands = gFalse;
44 static GBool quiet = gFalse;
45 static char cfgFileName[256] = "";
46 static GBool printVersion = gFalse;
47 static GBool printHelp = gFalse;
48
49 static ArgDesc argDesc[] = {
50 {"-g", argStringDummy, NULL, 0,
51 "initial window geometry"},
52 {"-geometry", argStringDummy, NULL, 0,
53 "initial window geometry"},
54 {"-title", argStringDummy, NULL, 0,
55 "window title"},
56 {"-cmap", argFlagDummy, NULL, 0,
57 "install a private colormap"},
58 {"-rgb", argIntDummy, NULL, 0,
59 "biggest RGB cube to allocate (default is 5)"},
60 {"-rv", argFlagDummy, NULL, 0,
61 "reverse video"},
62 {"-papercolor", argStringDummy, NULL, 0,
63 "color of paper background"},
64 {"-z", argStringDummy, NULL, 0,
65 "initial zoom level (percent, 'page', 'width')"},
66 {"-cont", argFlag, &contView, 0,
67 "start in continuous view mode" },
68 #if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H
69 {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr),
70 "enable FreeType font rasterizer: yes, no"},
71 #endif
72 {"-aa", argString, antialiasStr, sizeof(antialiasStr),
73 "enable font anti-aliasing: yes, no"},
74 {"-aaVector", argString, vectorAntialiasStr, sizeof(vectorAntialiasStr),
75 "enable vector anti-aliasing: yes, no"},
76 {"-ps", argString, psFileArg, sizeof(psFileArg),
77 "default PostScript file name or command"},
78 {"-paper", argString, paperSize, sizeof(paperSize),
79 "paper size (letter, legal, A4, A3, match)"},
80 {"-paperw", argInt, &paperWidth, 0,
81 "paper width, in points"},
82 {"-paperh", argInt, &paperHeight, 0,
83 "paper height, in points"},
84 {"-level1", argFlag, &level1, 0,
85 "generate Level 1 PostScript"},
86 {"-enc", argString, textEncName, sizeof(textEncName),
87 "output text encoding name"},
88 {"-eol", argString, textEOL, sizeof(textEOL),
89 "output end-of-line convention (unix, dos, or mac)"},
90 {"-opw", argString, ownerPassword, sizeof(ownerPassword),
91 "owner password (for encrypted files)"},
92 {"-upw", argString, userPassword, sizeof(userPassword),
93 "user password (for encrypted files)"},
94 {"-fullscreen", argFlag, &fullScreen, 0,
95 "run in full-screen (presentation) mode"},
96 {"-remote", argString, remoteName + 5, sizeof(remoteName) - 5,
97 "start/contact xpdf remote server with specified name"},
98 {"-exec", argString, remoteCmd, sizeof(remoteCmd),
99 "execute command on xpdf remote server (with -remote only)"},
100 {"-reload", argFlag, &doRemoteReload, 0,
101 "reload xpdf remote server window (with -remote only)"},
102 {"-raise", argFlag, &doRemoteRaise, 0,
103 "raise xpdf remote server window (with -remote only)"},
104 {"-quit", argFlag, &doRemoteQuit, 0,
105 "kill xpdf remote server (with -remote only)"},
106 {"-cmd", argFlag, &printCommands, 0,
107 "print commands as they're executed"},
108 {"-q", argFlag, &quiet, 0,
109 "don't print any messages or errors"},
110 {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
111 "configuration file to use in place of .xpdfrc"},
112 {"-v", argFlag, &printVersion, 0,
113 "print copyright and version info"},
114 {"-h", argFlag, &printHelp, 0,
115 "print usage information"},
116 {"-help", argFlag, &printHelp, 0,
117 "print usage information"},
118 {"--help", argFlag, &printHelp, 0,
119 "print usage information"},
120 {"-?", argFlag, &printHelp, 0,
121 "print usage information"},
122 {NULL}
123 };
124
125 //------------------------------------------------------------------------
126
main(int argc,char * argv[])127 int main(int argc, char *argv[]) {
128 XPDFApp *app;
129 GString *fileName;
130 int pg;
131 GString *destName;
132 GString *userPasswordStr, *ownerPasswordStr;
133 GBool ok;
134 int exitCode;
135
136 exitCode = 0;
137 userPasswordStr = ownerPasswordStr = NULL;
138
139 // parse args
140 ok = parseArgs(argDesc, &argc, argv);
141 if (!ok || printVersion || printHelp) {
142 fprintf(stderr, "xpdf version %s\n", xpdfVersion);
143 fprintf(stderr, "%s\n", xpdfCopyright);
144 if (!printVersion) {
145 printUsage("xpdf", "[<PDF-file> [<page> | +<dest>]]", argDesc);
146 }
147 exitCode = 99;
148 goto done0;
149 }
150
151 // read config file
152 globalParams = new GlobalParams(cfgFileName);
153 globalParams->setupBaseFonts(NULL);
154 if (contView) {
155 globalParams->setContinuousView(contView);
156 }
157 if (psFileArg[0]) {
158 globalParams->setPSFile(psFileArg);
159 }
160 if (paperSize[0]) {
161 if (!globalParams->setPSPaperSize(paperSize)) {
162 fprintf(stderr, "Invalid paper size\n");
163 }
164 } else {
165 if (paperWidth) {
166 globalParams->setPSPaperWidth(paperWidth);
167 }
168 if (paperHeight) {
169 globalParams->setPSPaperHeight(paperHeight);
170 }
171 }
172 if (level1) {
173 globalParams->setPSLevel(psLevel1);
174 }
175 if (textEncName[0]) {
176 globalParams->setTextEncoding(textEncName);
177 }
178 if (textEOL[0]) {
179 if (!globalParams->setTextEOL(textEOL)) {
180 fprintf(stderr, "Bad '-eol' value on command line\n");
181 }
182 }
183 if (enableFreeTypeStr[0]) {
184 if (!globalParams->setEnableFreeType(enableFreeTypeStr)) {
185 fprintf(stderr, "Bad '-freetype' value on command line\n");
186 }
187 }
188 if (antialiasStr[0]) {
189 if (!globalParams->setAntialias(antialiasStr)) {
190 fprintf(stderr, "Bad '-aa' value on command line\n");
191 }
192 }
193 if (vectorAntialiasStr[0]) {
194 if (!globalParams->setVectorAntialias(vectorAntialiasStr)) {
195 fprintf(stderr, "Bad '-aaVector' value on command line\n");
196 }
197 }
198 if (printCommands) {
199 globalParams->setPrintCommands(printCommands);
200 }
201 if (quiet) {
202 globalParams->setErrQuiet(quiet);
203 }
204
205 // create the XPDFApp object
206 app = new XPDFApp(&argc, argv);
207
208 // the initialZoom parameter can be set in either the config file or
209 // as an X resource (or command line arg)
210 if (app->getInitialZoom()) {
211 globalParams->setInitialZoom(app->getInitialZoom()->getCString());
212 }
213
214 // check command line
215 ok = ok && argc >= 1 && argc <= 3;
216 if (remoteCmd[0]) {
217 ok = ok && remoteName[5] && !doRemoteReload && !doRemoteRaise &&
218 !doRemoteQuit && argc == 1;
219 }
220 if (doRemoteReload) {
221 ok = ok && remoteName[5] && !doRemoteQuit && argc == 1;
222 }
223 if (doRemoteRaise) {
224 ok = ok && remoteName[5] && !doRemoteQuit;
225 }
226 if (doRemoteQuit) {
227 ok = ok && remoteName[5] && argc == 1;
228 }
229 if (!ok || printVersion || printHelp) {
230 fprintf(stderr, "xpdf version %s\n", xpdfVersion);
231 fprintf(stderr, "%s\n", xpdfCopyright);
232 if (!printVersion) {
233 printUsage("xpdf", "[<PDF-file> [<page> | +<dest>]]", argDesc);
234 }
235 exitCode = 99;
236 goto done1;
237 }
238 if (argc >= 2) {
239 fileName = new GString(argv[1]);
240 } else {
241 fileName = NULL;
242 }
243 pg = 1;
244 destName = NULL;
245 if (argc == 3) {
246 if (argv[2][0] == '+') {
247 destName = new GString(&argv[2][1]);
248 } else {
249 pg = atoi(argv[2]);
250 if (pg < 0) {
251 fprintf(stderr, "Invalid page number (%d)\n", pg);
252 exitCode = 99;
253 goto done2;
254 }
255 }
256 }
257
258 // handle remote server stuff
259 if (remoteName[5]) {
260 app->setRemoteName(remoteName);
261 if (app->remoteServerRunning()) {
262 if (fileName) {
263 if (destName) {
264 app->remoteOpenAtDest(fileName, destName, doRemoteRaise);
265 } else {
266 app->remoteOpen(fileName, pg, doRemoteRaise);
267 }
268 } else if (remoteCmd[0]) {
269 app->remoteExec(remoteCmd);
270 } else if (doRemoteReload) {
271 app->remoteReload(doRemoteRaise);
272 } else if (doRemoteRaise) {
273 app->remoteRaise();
274 } else if (doRemoteQuit) {
275 app->remoteQuit();
276 }
277 goto done2;
278 }
279 if (doRemoteQuit) {
280 goto done2;
281 }
282 }
283
284 // set options
285 app->setFullScreen(fullScreen);
286
287 // check for password string(s)
288 ownerPasswordStr = ownerPassword[0] != '\001' ? new GString(ownerPassword)
289 : (GString *)NULL;
290 userPasswordStr = userPassword[0] != '\001' ? new GString(userPassword)
291 : (GString *)NULL;
292
293 // open the file and run the main loop
294 if (destName) {
295 if (!app->openAtDest(fileName, destName,
296 ownerPasswordStr, userPasswordStr)) {
297 exitCode = 1;
298 goto done2;
299 }
300 } else {
301 if (!app->open(fileName, pg, ownerPasswordStr, userPasswordStr)) {
302 exitCode = 1;
303 goto done2;
304 }
305 }
306 app->run();
307
308 exitCode = 0;
309
310 // clean up
311 done2:
312 if (userPasswordStr) {
313 delete userPasswordStr;
314 }
315 if (ownerPasswordStr) {
316 delete ownerPasswordStr;
317 }
318 if (destName) {
319 delete destName;
320 }
321 if (fileName) {
322 delete fileName;
323 }
324 done1:
325 delete app;
326 delete globalParams;
327
328 // check for memory leaks
329 done0:
330 Object::memCheck(stderr);
331 gMemReport(stderr);
332
333 return exitCode;
334 }
335