1//========================================================================
2//
3// pdftops.cc
4//
5// Copyright 1996-2003 Glyph & Cog, LLC
6//
7// Modified for Debian by Hamish Moffatt, 22 May 2002.
8//
9//========================================================================
10
11//========================================================================
12//
13// Modified under the Poppler project - http://poppler.freedesktop.org
14//
15// All changes made under the Poppler project to this file are licensed
16// under GPL version 2 or later
17//
18// Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com>
19// Copyright (C) 2007-2008, 2010, 2015, 2017, 2018, 2020-2022 Albert Astals Cid <aacid@kde.org>
20// Copyright (C) 2009 Till Kamppeter <till.kamppeter@gmail.com>
21// Copyright (C) 2009 Sanjoy Mahajan <sanjoy@mit.edu>
22// Copyright (C) 2009, 2011, 2012, 2014-2016, 2020 William Bader <williambader@hotmail.com>
23// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
24// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
25// Copyright (C) 2013 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
26// Copyright (C) 2014, 2017 Adrian Johnson <ajohnson@redneon.com>
27// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
28// Copyright (C) 2019, 2021, 2023 Oliver Sander <oliver.sander@tu-dresden.de>
29// Copyright (C) 2020 Philipp Knechtges <philipp-dev@knechtges.com>
30// Copyright (C) 2021 Hubert Figuiere <hub@figuiere.net>
31//
32// To see a description of the changes please see the Changelog file that
33// came with your tarball or type make ChangeLog if you are building from git
34//
35//========================================================================
36
37#include "config.h"
38#include <poppler-config.h>
39#include <cstdio>
40#include <cstdlib>
41#include <cstddef>
42#include <cstring>
43#include "parseargs.h"
44#include "goo/GooString.h"
45#include "goo/gmem.h"
46#include "GlobalParams.h"
47#include "Object.h"
48#include "Stream.h"
49#include "Array.h"
50#include "Dict.h"
51#include "XRef.h"
52#include "Catalog.h"
53#include "Page.h"
54#include "PDFDoc.h"
55#include "PDFDocFactory.h"
56#include "PSOutputDev.h"
57#include "Error.h"
58#include "Win32Console.h"
59#include "sanitychecks.h"
60
61#ifdef USE_CMS
62# include <lcms2.h>
63#endif
64
65static bool setPSPaperSize(char *size, int &psPaperWidth, int &psPaperHeight)
66{
67 if (!strcmp(s1: size, s2: "match")) {
68 psPaperWidth = psPaperHeight = -1;
69 } else if (!strcmp(s1: size, s2: "letter")) {
70 psPaperWidth = 612;
71 psPaperHeight = 792;
72 } else if (!strcmp(s1: size, s2: "legal")) {
73 psPaperWidth = 612;
74 psPaperHeight = 1008;
75 } else if (!strcmp(s1: size, s2: "A4")) {
76 psPaperWidth = 595;
77 psPaperHeight = 842;
78 } else if (!strcmp(s1: size, s2: "A3")) {
79 psPaperWidth = 842;
80 psPaperHeight = 1190;
81 } else {
82 return false;
83 }
84 return true;
85}
86
87static int firstPage = 1;
88static int lastPage = 0;
89static bool level1 = false;
90static bool level1Sep = false;
91static bool level2 = false;
92static bool level2Sep = false;
93static bool level3 = false;
94static bool level3Sep = false;
95static bool origPageSizes = false;
96static bool doEPS = false;
97static bool doForm = false;
98#ifdef OPI_SUPPORT
99static bool doOPI = false;
100#endif
101static int splashResolution = 0;
102static bool psBinary = false;
103static bool noEmbedT1Fonts = false;
104static bool noEmbedTTFonts = false;
105static bool noEmbedCIDPSFonts = false;
106static bool noEmbedCIDTTFonts = false;
107static bool fontPassthrough = false;
108static bool optimizeColorSpace = false;
109static bool passLevel1CustomColor = false;
110static char rasterAntialiasStr[16] = "";
111static char forceRasterizeStr[16] = "";
112static bool preload = false;
113static char paperSize[15] = "";
114static int paperWidth = -1;
115static int paperHeight = -1;
116static bool noCrop = false;
117static bool expand = false;
118static bool noShrink = false;
119static bool noCenter = false;
120static bool duplex = false;
121static char ownerPassword[33] = "\001";
122static char userPassword[33] = "\001";
123static bool quiet = false;
124static bool printVersion = false;
125static bool printHelp = false;
126static bool overprint = false;
127static GooString processcolorformatname;
128static SplashColorMode processcolorformat;
129static bool processcolorformatspecified = false;
130#ifdef USE_CMS
131static GooString processcolorprofilename;
132static GfxLCMSProfilePtr processcolorprofile;
133static GooString defaultgrayprofilename;
134static GfxLCMSProfilePtr defaultgrayprofile;
135static GooString defaultrgbprofilename;
136static GfxLCMSProfilePtr defaultrgbprofile;
137static GooString defaultcmykprofilename;
138static GfxLCMSProfilePtr defaultcmykprofile;
139#endif
140
141static const ArgDesc argDesc[] = { { .arg: "-f", .kind: argInt, .val: &firstPage, .size: 0, .usage: "first page to print" },
142 { .arg: "-l", .kind: argInt, .val: &lastPage, .size: 0, .usage: "last page to print" },
143 { .arg: "-level1", .kind: argFlag, .val: &level1, .size: 0, .usage: "generate Level 1 PostScript" },
144 { .arg: "-level1sep", .kind: argFlag, .val: &level1Sep, .size: 0, .usage: "generate Level 1 separable PostScript" },
145 { .arg: "-level2", .kind: argFlag, .val: &level2, .size: 0, .usage: "generate Level 2 PostScript" },
146 { .arg: "-level2sep", .kind: argFlag, .val: &level2Sep, .size: 0, .usage: "generate Level 2 separable PostScript" },
147 { .arg: "-level3", .kind: argFlag, .val: &level3, .size: 0, .usage: "generate Level 3 PostScript" },
148 { .arg: "-level3sep", .kind: argFlag, .val: &level3Sep, .size: 0, .usage: "generate Level 3 separable PostScript" },
149 { .arg: "-origpagesizes", .kind: argFlag, .val: &origPageSizes, .size: 0, .usage: "conserve original page sizes" },
150 { .arg: "-eps", .kind: argFlag, .val: &doEPS, .size: 0, .usage: "generate Encapsulated PostScript (EPS)" },
151 { .arg: "-form", .kind: argFlag, .val: &doForm, .size: 0, .usage: "generate a PostScript form" },
152#ifdef OPI_SUPPORT
153 { .arg: "-opi", .kind: argFlag, .val: &doOPI, .size: 0, .usage: "generate OPI comments" },
154#endif
155 { .arg: "-r", .kind: argInt, .val: &splashResolution, .size: 0, .usage: "resolution for rasterization, in DPI (default is 300)" },
156 { .arg: "-binary", .kind: argFlag, .val: &psBinary, .size: 0, .usage: "write binary data in Level 1 PostScript" },
157 { .arg: "-noembt1", .kind: argFlag, .val: &noEmbedT1Fonts, .size: 0, .usage: "don't embed Type 1 fonts" },
158 { .arg: "-noembtt", .kind: argFlag, .val: &noEmbedTTFonts, .size: 0, .usage: "don't embed TrueType fonts" },
159 { .arg: "-noembcidps", .kind: argFlag, .val: &noEmbedCIDPSFonts, .size: 0, .usage: "don't embed CID PostScript fonts" },
160 { .arg: "-noembcidtt", .kind: argFlag, .val: &noEmbedCIDTTFonts, .size: 0, .usage: "don't embed CID TrueType fonts" },
161 { .arg: "-passfonts", .kind: argFlag, .val: &fontPassthrough, .size: 0, .usage: "don't substitute missing fonts" },
162 { .arg: "-aaRaster", .kind: argString, .val: rasterAntialiasStr, .size: sizeof(rasterAntialiasStr), .usage: "enable anti-aliasing on rasterization: yes, no" },
163 { .arg: "-rasterize", .kind: argString, .val: forceRasterizeStr, .size: sizeof(forceRasterizeStr), .usage: "control rasterization: always, never, whenneeded" },
164 { .arg: "-processcolorformat", .kind: argGooString, .val: &processcolorformatname, .size: 0, .usage: "color format that is used during rasterization and transparency reduction: MONO8, RGB8, CMYK8" },
165#ifdef USE_CMS
166 { "-processcolorprofile", argGooString, &processcolorprofilename, 0, "ICC color profile to use as the process color profile during rasterization and transparency reduction" },
167 { "-defaultgrayprofile", argGooString, &defaultgrayprofilename, 0, "ICC color profile to use as the DefaultGray color space" },
168 { "-defaultrgbprofile", argGooString, &defaultrgbprofilename, 0, "ICC color profile to use as the DefaultRGB color space" },
169 { "-defaultcmykprofile", argGooString, &defaultcmykprofilename, 0, "ICC color profile to use as the DefaultCMYK color space" },
170#endif
171 { .arg: "-optimizecolorspace", .kind: argFlag, .val: &optimizeColorSpace, .size: 0, .usage: "convert gray RGB images to gray color space" },
172 { .arg: "-passlevel1customcolor", .kind: argFlag, .val: &passLevel1CustomColor, .size: 0, .usage: "pass custom color in level1sep" },
173 { .arg: "-preload", .kind: argFlag, .val: &preload, .size: 0, .usage: "preload images and forms" },
174 { .arg: "-paper", .kind: argString, .val: paperSize, .size: sizeof(paperSize), .usage: "paper size (letter, legal, A4, A3, match)" },
175 { .arg: "-paperw", .kind: argInt, .val: &paperWidth, .size: 0, .usage: "paper width, in points" },
176 { .arg: "-paperh", .kind: argInt, .val: &paperHeight, .size: 0, .usage: "paper height, in points" },
177 { .arg: "-nocrop", .kind: argFlag, .val: &noCrop, .size: 0, .usage: "don't crop pages to CropBox" },
178 { .arg: "-expand", .kind: argFlag, .val: &expand, .size: 0, .usage: "expand pages smaller than the paper size" },
179 { .arg: "-noshrink", .kind: argFlag, .val: &noShrink, .size: 0, .usage: "don't shrink pages larger than the paper size" },
180 { .arg: "-nocenter", .kind: argFlag, .val: &noCenter, .size: 0, .usage: "don't center pages smaller than the paper size" },
181 { .arg: "-duplex", .kind: argFlag, .val: &duplex, .size: 0, .usage: "enable duplex printing" },
182 { .arg: "-opw", .kind: argString, .val: ownerPassword, .size: sizeof(ownerPassword), .usage: "owner password (for encrypted files)" },
183 { .arg: "-upw", .kind: argString, .val: userPassword, .size: sizeof(userPassword), .usage: "user password (for encrypted files)" },
184 { .arg: "-overprint", .kind: argFlag, .val: &overprint, .size: 0, .usage: "enable overprint emulation during rasterization" },
185 { .arg: "-q", .kind: argFlag, .val: &quiet, .size: 0, .usage: "don't print any messages or errors" },
186 { .arg: "-v", .kind: argFlag, .val: &printVersion, .size: 0, .usage: "print copyright and version info" },
187 { .arg: "-h", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
188 { .arg: "-help", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
189 { .arg: "--help", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
190 { .arg: "-?", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
191 {} };
192
193int main(int argc, char *argv[])
194{
195 std::unique_ptr<PDFDoc> doc;
196 GooString *fileName;
197 std::string psFileName;
198 PSLevel level;
199 PSOutMode mode;
200 std::optional<GooString> ownerPW, userPW;
201 PSOutputDev *psOut;
202 bool ok;
203 int exitCode;
204 bool rasterAntialias = false;
205 std::vector<int> pages;
206#ifdef USE_CMS
207 cmsColorSpaceSignature profilecolorspace;
208#endif
209
210 Win32Console win32Console(&argc, &argv);
211 exitCode = 99;
212
213 // parse args
214 ok = parseArgs(args: argDesc, argc: &argc, argv);
215 if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
216 fprintf(stderr, format: "pdftops version %s\n", PACKAGE_VERSION);
217 fprintf(stderr, format: "%s\n", popplerCopyright);
218 fprintf(stderr, format: "%s\n", xpdfCopyright);
219 if (!printVersion) {
220 printUsage(program: "pdftops", otherArgs: "<PDF-file> [<PS-file>]", args: argDesc);
221 }
222 if (printVersion || printHelp) {
223 exit(status: 0);
224 } else {
225 exit(status: 1);
226 }
227 }
228 if ((level1 ? 1 : 0) + (level1Sep ? 1 : 0) + (level2 ? 1 : 0) + (level2Sep ? 1 : 0) + (level3 ? 1 : 0) + (level3Sep ? 1 : 0) > 1) {
229 fprintf(stderr, format: "Error: use only one of the 'level' options.\n");
230 exit(status: 1);
231 }
232 if ((doEPS ? 1 : 0) + (doForm ? 1 : 0) > 1) {
233 fprintf(stderr, format: "Error: use only one of -eps, and -form\n");
234 exit(status: 1);
235 }
236 if (level1) {
237 level = psLevel1;
238 } else if (level1Sep) {
239 level = psLevel1Sep;
240 } else if (level2Sep) {
241 level = psLevel2Sep;
242 } else if (level3) {
243 level = psLevel3;
244 } else if (level3Sep) {
245 level = psLevel3Sep;
246 } else {
247 level = psLevel2;
248 }
249 if (doForm && level < psLevel2) {
250 fprintf(stderr, format: "Error: forms are only available with Level 2 output.\n");
251 exit(status: 1);
252 }
253 mode = doEPS ? psModeEPS : doForm ? psModeForm : psModePS;
254 fileName = new GooString(argv[1]);
255
256 // read config file
257 globalParams = std::make_unique<GlobalParams>();
258 if (origPageSizes) {
259 paperWidth = paperHeight = -1;
260 }
261 if (paperSize[0]) {
262 if (origPageSizes) {
263 fprintf(stderr, format: "Error: -origpagesizes and -paper may not be used together.\n");
264 exit(status: 1);
265 }
266 if (!setPSPaperSize(size: paperSize, psPaperWidth&: paperWidth, psPaperHeight&: paperHeight)) {
267 fprintf(stderr, format: "Invalid paper size\n");
268 delete fileName;
269 goto err0;
270 }
271 }
272 if (quiet) {
273 globalParams->setErrQuiet(quiet);
274 }
275
276 if (!processcolorformatname.toStr().empty()) {
277 if (processcolorformatname.toStr() == "MONO8") {
278 processcolorformat = splashModeMono8;
279 processcolorformatspecified = true;
280 } else if (processcolorformatname.toStr() == "CMYK8") {
281 processcolorformat = splashModeCMYK8;
282 processcolorformatspecified = true;
283 } else if (processcolorformatname.toStr() == "RGB8") {
284 processcolorformat = splashModeRGB8;
285 processcolorformatspecified = true;
286 } else {
287 fprintf(stderr, format: "Error: Unknown process color format \"%s\".\n", processcolorformatname.c_str());
288 goto err1;
289 }
290 }
291
292#ifdef USE_CMS
293 if (!processcolorprofilename.toStr().empty()) {
294 processcolorprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(processcolorprofilename.c_str(), "r"));
295 if (!processcolorprofile) {
296 fprintf(stderr, "Error: Could not open the ICC profile \"%s\".\n", processcolorprofilename.c_str());
297 goto err1;
298 }
299 if (!cmsIsIntentSupported(processcolorprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_OUTPUT) && !cmsIsIntentSupported(processcolorprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_OUTPUT)
300 && !cmsIsIntentSupported(processcolorprofile.get(), INTENT_SATURATION, LCMS_USED_AS_OUTPUT) && !cmsIsIntentSupported(processcolorprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT)) {
301 fprintf(stderr, "Error: ICC profile \"%s\" is not an output profile.\n", processcolorprofilename.c_str());
302 goto err1;
303 }
304 profilecolorspace = cmsGetColorSpace(processcolorprofile.get());
305 if (profilecolorspace == cmsSigCmykData) {
306 if (!processcolorformatspecified) {
307 processcolorformat = splashModeCMYK8;
308 processcolorformatspecified = true;
309 } else if (processcolorformat != splashModeCMYK8) {
310 fprintf(stderr, "Error: Supplied ICC profile \"%s\" is a CMYK profile, but process color format is not CMYK8.\n", processcolorprofilename.c_str());
311 goto err1;
312 }
313 } else if (profilecolorspace == cmsSigGrayData) {
314 if (!processcolorformatspecified) {
315 processcolorformat = splashModeMono8;
316 processcolorformatspecified = true;
317 } else if (processcolorformat != splashModeMono8) {
318 fprintf(stderr, "Error: Supplied ICC profile \"%s\" is a monochrome profile, but process color format is not monochrome.\n", processcolorprofilename.c_str());
319 goto err1;
320 }
321 } else if (profilecolorspace == cmsSigRgbData) {
322 if (!processcolorformatspecified) {
323 processcolorformat = splashModeRGB8;
324 processcolorformatspecified = true;
325 } else if (processcolorformat != splashModeRGB8) {
326 fprintf(stderr, "Error: Supplied ICC profile \"%s\" is a RGB profile, but process color format is not RGB.\n", processcolorprofilename.c_str());
327 goto err1;
328 }
329 }
330 }
331#endif
332
333 if (processcolorformatspecified) {
334 if (level1 && processcolorformat != splashModeMono8) {
335 fprintf(stderr, format: "Error: Setting -level1 requires -processcolorformat MONO8");
336 goto err1;
337 } else if ((level1Sep || level2Sep || level3Sep || overprint) && processcolorformat != splashModeCMYK8) {
338 fprintf(stderr, format: "Error: Setting -level1sep/-level2sep/-level3sep/-overprint requires -processcolorformat CMYK8");
339 goto err1;
340 }
341 }
342
343#ifdef USE_CMS
344 if (!defaultgrayprofilename.toStr().empty()) {
345 defaultgrayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultgrayprofilename.c_str(), "r"));
346 if (!checkICCProfile(defaultgrayprofile, defaultgrayprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigGrayData)) {
347 goto err1;
348 }
349 }
350 if (!defaultrgbprofilename.toStr().empty()) {
351 defaultrgbprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultrgbprofilename.c_str(), "r"));
352 if (!checkICCProfile(defaultrgbprofile, defaultrgbprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigRgbData)) {
353 goto err1;
354 }
355 }
356 if (!defaultcmykprofilename.toStr().empty()) {
357 defaultcmykprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultcmykprofilename.c_str(), "r"));
358 if (!checkICCProfile(defaultcmykprofile, defaultcmykprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigCmykData)) {
359 goto err1;
360 }
361 }
362#endif
363
364 // open PDF file
365 if (ownerPassword[0] != '\001') {
366 ownerPW = GooString(ownerPassword);
367 }
368 if (userPassword[0] != '\001') {
369 userPW = GooString(userPassword);
370 }
371 if (fileName->cmp(sA: "-") == 0) {
372 delete fileName;
373 fileName = new GooString("fd://0");
374 }
375
376 doc = PDFDocFactory().createPDFDoc(uri: *fileName, ownerPassword: ownerPW, userPassword: userPW);
377
378 if (!doc->isOk()) {
379 exitCode = 1;
380 goto err1;
381 }
382
383#ifdef ENFORCE_PERMISSIONS
384 // check for print permission
385 if (!doc->okToPrint()) {
386 error(errNotAllowed, -1, "Printing this document is not allowed.");
387 exitCode = 3;
388 goto err1;
389 }
390#endif
391
392 // construct PostScript file name
393 if (argc == 3) {
394 psFileName = std::string(argv[2]);
395 } else if (fileName->cmp(sA: "fd://0") == 0) {
396 error(category: errCommandLine, pos: -1, msg: "You have to provide an output filename when reading from stdin.");
397 goto err1;
398 } else {
399 const char *p = fileName->c_str() + fileName->getLength() - 4;
400 if (!strcmp(s1: p, s2: ".pdf") || !strcmp(s1: p, s2: ".PDF")) {
401 psFileName = std::string(fileName->c_str(), fileName->getLength() - 4);
402
403 } else {
404 psFileName = fileName->toStr();
405 }
406 psFileName += (doEPS ? ".eps" : ".ps");
407 }
408
409 // get page range
410 if (firstPage < 1) {
411 firstPage = 1;
412 }
413 if (lastPage < 1 || lastPage > doc->getNumPages()) {
414 lastPage = doc->getNumPages();
415 }
416 if (lastPage < firstPage) {
417 error(category: errCommandLine, pos: -1, msg: "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
418 goto err1;
419 }
420
421 // check for multi-page EPS or form
422 if ((doEPS || doForm) && firstPage != lastPage) {
423 error(category: errCommandLine, pos: -1, msg: "EPS and form files can only contain one page.");
424 goto err1;
425 }
426
427 for (int i = firstPage; i <= lastPage; ++i) {
428 pages.push_back(x: i);
429 }
430
431 // write PostScript file
432 psOut = new PSOutputDev(psFileName.c_str(), doc.get(), nullptr, pages, mode, paperWidth, paperHeight, noCrop, duplex, /*imgLLXA*/ 0, /*imgLLYA*/ 0,
433 /*imgURXA*/ 0, /*imgURYA*/ 0, psRasterizeWhenNeeded, /*manualCtrlA*/ false, /*customCodeCbkA*/ nullptr, /*customCodeCbkDataA*/ nullptr, level);
434 if (noCenter) {
435 psOut->setPSCenter(false);
436 }
437 if (expand) {
438 psOut->setPSExpandSmaller(true);
439 }
440 if (noShrink) {
441 psOut->setPSShrinkLarger(false);
442 }
443 if (overprint) {
444 psOut->setOverprintPreview(true);
445 }
446
447 if (rasterAntialiasStr[0]) {
448 if (!GlobalParams::parseYesNo2(token: rasterAntialiasStr, flag: &rasterAntialias)) {
449 fprintf(stderr, format: "Bad '-aaRaster' value on command line\n");
450 }
451 }
452
453 if (forceRasterizeStr[0]) {
454 PSForceRasterize forceRasterize = psRasterizeWhenNeeded;
455 if (strcmp(s1: forceRasterizeStr, s2: "whenneeded") == 0) {
456 forceRasterize = psRasterizeWhenNeeded;
457 } else if (strcmp(s1: forceRasterizeStr, s2: "always") == 0) {
458 forceRasterize = psAlwaysRasterize;
459 } else if (strcmp(s1: forceRasterizeStr, s2: "never") == 0) {
460 forceRasterize = psNeverRasterize;
461 } else {
462 fprintf(stderr, format: "Bad '-rasterize' value on command line\n");
463 }
464 psOut->setForceRasterize(forceRasterize);
465 }
466
467 if (splashResolution > 0) {
468 psOut->setRasterResolution(splashResolution);
469 }
470 if (processcolorformatspecified) {
471 psOut->setProcessColorFormat(processcolorformat);
472 }
473#ifdef USE_CMS
474 psOut->setDisplayProfile(processcolorprofile);
475 psOut->setDefaultGrayProfile(defaultgrayprofile);
476 psOut->setDefaultRGBProfile(defaultrgbprofile);
477 psOut->setDefaultCMYKProfile(defaultcmykprofile);
478#endif
479 psOut->setEmbedType1(!noEmbedT1Fonts);
480 psOut->setEmbedTrueType(!noEmbedTTFonts);
481 psOut->setEmbedCIDPostScript(!noEmbedCIDPSFonts);
482 psOut->setEmbedCIDTrueType(!noEmbedCIDTTFonts);
483 psOut->setFontPassthrough(fontPassthrough);
484 psOut->setPreloadImagesForms(preload);
485 psOut->setOptimizeColorSpace(optimizeColorSpace);
486 psOut->setPassLevel1CustomColor(passLevel1CustomColor);
487#ifdef OPI_SUPPORT
488 psOut->setGenerateOPI(doOPI);
489#endif
490 psOut->setUseBinary(psBinary);
491
492 psOut->setRasterAntialias(rasterAntialias);
493 if (psOut->isOk()) {
494 for (int i = firstPage; i <= lastPage; ++i) {
495 doc->displayPage(out: psOut, page: i, hDPI: 72, vDPI: 72, rotate: 0, useMediaBox: noCrop, crop: !noCrop, printing: true);
496 }
497 } else {
498 delete psOut;
499 exitCode = 2;
500 goto err1;
501 }
502 delete psOut;
503
504 exitCode = 0;
505
506 // clean up
507err1:
508 delete fileName;
509err0:
510
511 return exitCode;
512}
513

source code of poppler/utils/pdftops.cc