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