filters

pdftops.cc

00001 //========================================================================
00002 //
00003 // pdftops.cc
00004 //
00005 // Copyright 1996-2002 Glyph & Cog, LLC
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   // parse args
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   // read config file
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   // open PDF file
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   // check for print permission
00245   if (!doc->okToPrint()) {
00246     error(-1, "Printing this document is not allowed.");
00247     exitCode = 3;
00248     goto err1;
00249   }
00250 
00251   // construct PostScript file name
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   // get page range
00266   if (firstPage < 1) {
00267     firstPage = 1;
00268   }
00269   if (lastPage < 1 || lastPage > doc->getNumPages()) {
00270     lastPage = doc->getNumPages();
00271   }
00272 
00273   // check for multi-page EPS or form
00274   if ((doEPS || doForm) && firstPage != lastPage) {
00275     error(-1, "EPS and form files can only contain one page.");
00276     goto err2;
00277   }
00278 
00279   // write PostScript file
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   // clean up
00294  err2:
00295   delete psFileName;
00296  err1:
00297   delete doc;
00298   delete globalParams;
00299  err0:
00300 
00301   // check for memory leaks
00302   Object::memCheck(stderr);
00303   gMemReport(stderr);
00304 
00305   return exitCode;
00306 }
KDE Home | KDE Accessibility Home | Description of Access Keys