00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <aconf.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <stddef.h>
00013 #include <string.h>
00014 #include "parseargs.h"
00015 #include "GString.h"
00016 #include "gmem.h"
00017 #include "GlobalParams.h"
00018 #include "Object.h"
00019 #include "Stream.h"
00020 #include "Array.h"
00021 #include "Dict.h"
00022 #include "XRef.h"
00023 #include "Catalog.h"
00024 #include "Page.h"
00025 #include "PDFDoc.h"
00026 #include "PSOutputDev.h"
00027 #include "Error.h"
00028 #include "config.h"
00029
00030 static int firstPage = 1;
00031 static int lastPage = 0;
00032 static GBool level1 = gFalse;
00033 static GBool level1Sep = gFalse;
00034 static GBool level2 = gFalse;
00035 static GBool level2Sep = gFalse;
00036 static GBool level3 = gFalse;
00037 static GBool level3Sep = gFalse;
00038 static GBool doEPS = gFalse;
00039 static GBool doForm = gFalse;
00040 #if OPI_SUPPORT
00041 static GBool doOPI = gFalse;
00042 #endif
00043 static GBool noEmbedT1Fonts = gFalse;
00044 static GBool noEmbedTTFonts = gFalse;
00045 static GBool noEmbedCIDPSFonts = gFalse;
00046 static GBool noEmbedCIDTTFonts = gFalse;
00047 static char paperSize[15] = "";
00048 static int paperWidth = 0;
00049 static int paperHeight = 0;
00050 static GBool duplex = gFalse;
00051 static char ownerPassword[33] = "";
00052 static char userPassword[33] = "";
00053 static GBool quiet = gFalse;
00054 static char cfgFileName[256] = "";
00055 static GBool printVersion = gFalse;
00056 static GBool printHelp = gFalse;
00057
00058 static ArgDesc argDesc[] = {
00059 {"-f", argInt, &firstPage, 0,
00060 "first page to print"},
00061 {"-l", argInt, &lastPage, 0,
00062 "last page to print"},
00063 {"-level1", argFlag, &level1, 0,
00064 "generate Level 1 PostScript"},
00065 {"-level1sep", argFlag, &level1Sep, 0,
00066 "generate Level 1 separable PostScript"},
00067 {"-level2", argFlag, &level2, 0,
00068 "generate Level 2 PostScript"},
00069 {"-level2sep", argFlag, &level2Sep, 0,
00070 "generate Level 2 separable PostScript"},
00071 {"-level3", argFlag, &level3, 0,
00072 "generate Level 3 PostScript"},
00073 {"-level3sep", argFlag, &level3Sep, 0,
00074 "generate Level 3 separable PostScript"},
00075 {"-eps", argFlag, &doEPS, 0,
00076 "generate Encapsulated PostScript (EPS)"},
00077 {"-form", argFlag, &doForm, 0,
00078 "generate a PostScript form"},
00079 #if OPI_SUPPORT
00080 {"-opi", argFlag, &doOPI, 0,
00081 "generate OPI comments"},
00082 #endif
00083 {"-noembt1", argFlag, &noEmbedT1Fonts, 0,
00084 "don't embed Type 1 fonts"},
00085 {"-noembtt", argFlag, &noEmbedTTFonts, 0,
00086 "don't embed TrueType fonts"},
00087 {"-noembcidps", argFlag, &noEmbedCIDPSFonts, 0,
00088 "don't embed CID PostScript fonts"},
00089 {"-noembcidtt", argFlag, &noEmbedCIDTTFonts, 0,
00090 "don't embed CID TrueType fonts"},
00091 {"-paper", argString, paperSize, sizeof(paperSize),
00092 "paper size (letter, legal, A4, A3)"},
00093 {"-paperw", argInt, &paperWidth, 0,
00094 "paper width, in points"},
00095 {"-paperh", argInt, &paperHeight, 0,
00096 "paper height, in points"},
00097 {"-duplex", argFlag, &duplex, 0,
00098 "enable duplex printing"},
00099 {"-opw", argString, ownerPassword, sizeof(ownerPassword),
00100 "owner password (for encrypted files)"},
00101 {"-upw", argString, userPassword, sizeof(userPassword),
00102 "user password (for encrypted files)"},
00103 {"-q", argFlag, &quiet, 0,
00104 "don't print any messages or errors"},
00105 {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
00106 "configuration file to use in place of .xpdfrc"},
00107 {"-v", argFlag, &printVersion, 0,
00108 "print copyright and version info"},
00109 {"-h", argFlag, &printHelp, 0,
00110 "print usage information"},
00111 {"-help", argFlag, &printHelp, 0,
00112 "print usage information"},
00113 {"--help", argFlag, &printHelp, 0,
00114 "print usage information"},
00115 {"-?", argFlag, &printHelp, 0,
00116 "print usage information"},
00117 {NULL}
00118 };
00119
00120 int main(int argc, char *argv[]) {
00121 PDFDoc *doc;
00122 GString *fileName;
00123 GString *psFileName;
00124 PSLevel level;
00125 PSOutMode mode;
00126 GString *ownerPW, *userPW;
00127 PSOutputDev *psOut;
00128 GBool ok;
00129 char *p;
00130 int exitCode;
00131
00132 exitCode = 99;
00133
00134
00135 ok = parseArgs(argDesc, &argc, argv);
00136 if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
00137 fprintf(stderr, "pdftops version %s\n", xpdfVersion);
00138 fprintf(stderr, "%s\n", xpdfCopyright);
00139 if (!printVersion) {
00140 printUsage("pdftops", "<PDF-file> [<PS-file>]", argDesc);
00141 }
00142 exit(1);
00143 }
00144 if ((level1 ? 1 : 0) +
00145 (level1Sep ? 1 : 0) +
00146 (level2 ? 1 : 0) +
00147 (level2Sep ? 1 : 0) +
00148 (level3 ? 1 : 0) +
00149 (level3Sep ? 1 : 0) > 1) {
00150 fprintf(stderr, "Error: use only one of the 'level' options.\n");
00151 exit(1);
00152 }
00153 if (doEPS && doForm) {
00154 fprintf(stderr, "Error: use only one of -eps and -form\n");
00155 exit(1);
00156 }
00157 if (level1) {
00158 level = psLevel1;
00159 } else if (level1Sep) {
00160 level = psLevel1Sep;
00161 } else if (level2Sep) {
00162 level = psLevel2Sep;
00163 } else if (level3) {
00164 level = psLevel3;
00165 } else if (level3Sep) {
00166 level = psLevel3Sep;
00167 } else {
00168 level = psLevel2;
00169 }
00170 if (doForm && level < psLevel2) {
00171 fprintf(stderr, "Error: forms are only available with Level 2 output.\n");
00172 exit(1);
00173 }
00174 mode = doEPS ? psModeEPS
00175 : doForm ? psModeForm
00176 : psModePS;
00177 fileName = new GString(argv[1]);
00178
00179
00180 globalParams = new GlobalParams(cfgFileName);
00181 if (paperSize[0]) {
00182 if (!globalParams->setPSPaperSize(paperSize)) {
00183 fprintf(stderr, "Invalid paper size\n");
00184 goto err0;
00185 }
00186 } else {
00187 if (paperWidth) {
00188 globalParams->setPSPaperWidth(paperWidth);
00189 }
00190 if (paperHeight) {
00191 globalParams->setPSPaperHeight(paperHeight);
00192 }
00193 }
00194 if (duplex) {
00195 globalParams->setPSDuplex(duplex);
00196 }
00197 if (level1 || level1Sep || level2 || level2Sep || level3 || level3Sep) {
00198 globalParams->setPSLevel(level);
00199 }
00200 if (noEmbedT1Fonts) {
00201 globalParams->setPSEmbedType1(!noEmbedT1Fonts);
00202 }
00203 if (noEmbedTTFonts) {
00204 globalParams->setPSEmbedTrueType(!noEmbedTTFonts);
00205 }
00206 if (noEmbedCIDPSFonts) {
00207 globalParams->setPSEmbedCIDPostScript(!noEmbedCIDPSFonts);
00208 }
00209 if (noEmbedCIDTTFonts) {
00210 globalParams->setPSEmbedCIDTrueType(!noEmbedCIDTTFonts);
00211 }
00212 #if OPI_SUPPORT
00213 if (doOPI) {
00214 globalParams->setPSOPI(doOPI);
00215 }
00216 #endif
00217 if (quiet) {
00218 globalParams->setErrQuiet(quiet);
00219 }
00220
00221
00222 if (ownerPassword[0]) {
00223 ownerPW = new GString(ownerPassword);
00224 } else {
00225 ownerPW = NULL;
00226 }
00227 if (userPassword[0]) {
00228 userPW = new GString(userPassword);
00229 } else {
00230 userPW = NULL;
00231 }
00232 doc = new PDFDoc(fileName, ownerPW, userPW);
00233 if (userPW) {
00234 delete userPW;
00235 }
00236 if (ownerPW) {
00237 delete ownerPW;
00238 }
00239 if (!doc->isOk()) {
00240 exitCode = 1;
00241 goto err1;
00242 }
00243
00244
00245 if (!doc->okToPrint()) {
00246 error(-1, "Printing this document is not allowed.");
00247 exitCode = 3;
00248 goto err1;
00249 }
00250
00251
00252 if (argc == 3) {
00253 psFileName = new GString(argv[2]);
00254 } else {
00255 p = fileName->getCString() + fileName->getLength() - 4;
00256 if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
00257 psFileName = new GString(fileName->getCString(),
00258 fileName->getLength() - 4);
00259 } else {
00260 psFileName = fileName->copy();
00261 }
00262 psFileName->append(doEPS ? ".eps" : ".ps");
00263 }
00264
00265
00266 if (firstPage < 1) {
00267 firstPage = 1;
00268 }
00269 if (lastPage < 1 || lastPage > doc->getNumPages()) {
00270 lastPage = doc->getNumPages();
00271 }
00272
00273
00274 if ((doEPS || doForm) && firstPage != lastPage) {
00275 error(-1, "EPS and form files can only contain one page.");
00276 goto err2;
00277 }
00278
00279
00280 psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
00281 doc->getCatalog(), firstPage, lastPage, mode);
00282 if (psOut->isOk()) {
00283 doc->displayPages(psOut, firstPage, lastPage, 72, 0, gFalse);
00284 } else {
00285 delete psOut;
00286 exitCode = 2;
00287 goto err2;
00288 }
00289 delete psOut;
00290
00291 exitCode = 0;
00292
00293
00294 err2:
00295 delete psFileName;
00296 err1:
00297 delete doc;
00298 delete globalParams;
00299 err0:
00300
00301
00302 Object::memCheck(stderr);
00303 gMemReport(stderr);
00304
00305 return exitCode;
00306 }