]> git.ipfire.org Git - thirdparty/cups.git/blame - pdftops/pdftops.cxx
Load cups into easysw/current.
[thirdparty/cups.git] / pdftops / pdftops.cxx
CommitLineData
ef416fc2 1//
f7deaa1a 2// "$Id: pdftops.cxx 6324 2007-03-11 02:09:46Z mike $"
ef416fc2 3//
4// PDF to PostScript filter front-end for the Common UNIX Printing
5// System (CUPS).
6//
7// Copyright 1997-2006 by Easy Software Products.
8//
9// These coded instructions, statements, and computer programs are the
10// property of Easy Software Products and are protected by Federal
11// copyright law. Distribution and use rights are outlined in the file
12// "LICENSE.txt" which should have been included with this file. If this
13// file is missing or damaged please contact Easy Software Products
14// at:
15//
16// Attn: CUPS Licensing Information
17// Easy Software Products
18// 44141 Airport View Drive, Suite 204
19// Hollywood, Maryland 20636 USA
20//
21// Voice: (301) 373-9600
22// EMail: cups-info@cups.org
23// WWW: http://www.cups.org
24//
25// Contents:
26//
27// main() - Main entry for filter...
28//
29
30//
31// Include necessary headers...
32//
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <stddef.h>
37#include <cups/string.h>
38#include "parseargs.h"
39#include "GString.h"
40#include "gmem.h"
41#include "Object.h"
42#include "Stream.h"
43#include "Array.h"
44#include "Dict.h"
45#include "XRef.h"
46#include "Catalog.h"
47#include "Page.h"
48#include "PDFDoc.h"
49#include "PSOutputDev.h"
50#include "GlobalParams.h"
51#include "Error.h"
52#include "config.h"
53
54#include <cups/cups.h>
55
56
57//
58// 'main()' - Main entry for filter...
59//
60
61int // O - Exit status
62main(int argc, // I - Number of command-line args
63 char *argv[]) // I - Command-line arguments
64{
65 PDFDoc *doc; // Input file
66 GString *fileName; // Input filename
67 GString *psFileName; // Output filename
68 PSLevel level; // PostScript level
69 PSOutputDev *psOut; // Output device
70 int num_options; // Number of options
71 cups_option_t *options; // Options
72 const char *val; // Option value
73 ppd_file_t *ppd; // Current PPD
74 ppd_size_t *size; // Current media size
75 int fd; // Copy file descriptor
76 const char *server_root; // Location of config files
77 char tempfile[1024]; // Temporary file
78 char buffer[8192]; // Copy buffer
79 int bytes; // Bytes copied
80 int width, length; // Size in points
81 int left, bottom, right, top;
82 // Imageable area in points
83 int orientation; // Orientation
84 int temp; // Temporary var
85 int duplex; // Duplex the output?
86 int fit; // Fit the pages to the output
87 int printCommands; // Output debug info for commands?
88
89
90 // Make sure status messages are not buffered...
91 setbuf(stderr, NULL);
92
93 // Make sure we have the right number of arguments for CUPS!
94 if (argc < 6 || argc > 7) {
95 fputs("Usage: pdftops job user title copies options [filename]\n", stderr);
96 return (1);
97 }
98
99 // Copy stdin if needed...
100 if (argc == 6) {
101 if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) {
102 perror("ERROR: Unable to copy PDF file");
103 return (1);
104 }
105
106 fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n",
107 tempfile);
108
109 while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
110 write(fd, buffer, bytes);
111 close(fd);
112
113 fileName = new GString(tempfile);
114 } else {
115 fileName = new GString(argv[6]);
116 tempfile[0] = '\0';
117 }
118
119 // Default to "Universal" size - min of A4 and Letter...
120 left = 0;
121 bottom = 0;
122 right = 595;
123 top = 792;
124 width = 595;
125 length = 792;
126 level = psLevel2;
127 duplex = 0;
128 fit = 0;
129
130 // Get PPD and initialize options as needed...
131 num_options = cupsParseOptions(argv[5], 0, &options);
132
133 if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL)
134 {
135 fprintf(stderr, "DEBUG: pdftops - opened PPD file \"%s\"...\n", getenv("PPD"));
136
137 ppdMarkDefaults(ppd);
138 cupsMarkOptions(ppd, num_options, options);
139
140 if ((size = ppdPageSize(ppd, NULL)) != NULL)
141 {
142 left = (int)size->left;
143 bottom = (int)size->bottom;
144 right = (int)size->right;
145 top = (int)size->top;
146 width = (int)size->width;
147 length = (int)size->length;
148 }
149
150 level = ppd->language_level == 1 ? psLevel1 : psLevel2;
151 }
152
153 // Track the orientation of the print job and update the page
154 // dimensions and margins as needed...
155 orientation = 0;
156
157 if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
158 {
159 if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
160 strcasecmp(val, "false") != 0)
161 orientation = 1;
162 }
163 else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
164 {
165 /*
166 * Map IPP orientation values to 0 to 3:
167 *
168 * 3 = 0 degrees = 0
169 * 4 = 90 degrees = 1
170 * 5 = -90 degrees = 3
171 * 6 = 180 degrees = 2
172 */
173
174 orientation = atoi(val) - 3;
175 if (orientation >= 2)
176 orientation ^= 1;
177 }
178
179 switch (orientation & 3)
180 {
181 case 0 : /* Portait */
182 break;
183
184 case 1 : /* Landscape */
185 temp = left;
186 left = bottom;
187 bottom = temp;
188
189 temp = right;
190 right = top;
191 top = temp;
192
193 temp = width;
194 width = length;
195 length = temp;
196 break;
197
198 case 2 : /* Reverse Portrait */
199 temp = width - left;
200 left = width - right;
201 right = temp;
202
203 temp = length - bottom;
204 bottom = length - top;
205 top = temp;
206 break;
207
208 case 3 : /* Reverse Landscape */
209 temp = width - left;
210 left = width - right;
211 right = temp;
212
213 temp = length - bottom;
214 bottom = length - top;
215 top = temp;
216
217 temp = left;
218 left = bottom;
219 bottom = temp;
220
221 temp = right;
222 right = top;
223 top = temp;
224
225 temp = width;
226 width = length;
227 length = temp;
228 break;
229 }
230
231 if ((val = cupsGetOption("debug", num_options, options)) != NULL &&
232 strcasecmp(val, "no") && strcasecmp(val, "off") &&
233 strcasecmp(val, "false"))
234 printCommands = 1;
235 else
236 printCommands = 0;
237
238 if ((val = cupsGetOption("fitplot", num_options, options)) != NULL &&
239 strcasecmp(val, "no") && strcasecmp(val, "off") &&
240 strcasecmp(val, "false"))
241 fit = 1;
242
243 if ((val = cupsGetOption("sides", num_options, options)) != NULL &&
244 strncasecmp(val, "two-", 4) == 0)
245 duplex = 1;
246 else if ((val = cupsGetOption("Duplex", num_options, options)) != NULL &&
247 strncasecmp(val, "Duplex", 6) == 0)
248 duplex = 1;
249 else if ((val = cupsGetOption("JCLDuplex", num_options, options)) != NULL &&
250 strncasecmp(val, "Duplex", 6) == 0)
251 duplex = 1;
252 else if ((val = cupsGetOption("EFDuplex", num_options, options)) != NULL &&
253 strncasecmp(val, "Duplex", 6) == 0)
254 duplex = 1;
255 else if ((val = cupsGetOption("KD03Duplex", num_options, options)) != NULL &&
256 strncasecmp(val, "Duplex", 6) == 0)
257 duplex = 1;
258 else if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
259 ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
260 ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
261 ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
262 ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
263 ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
264 ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
265 ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
266 duplex = 1;
267
268 if (ppd != NULL)
269 ppdClose(ppd);
270
271 fprintf(stderr, "DEBUG: pdftops - level = %d, width = %d, length = %d\n",
272 level, width, length);
273
274 // read config file
275 if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
276 server_root = CUPS_SERVERROOT;
277
278 snprintf(buffer, sizeof(buffer), "%s/pdftops.conf", server_root);
279
280 globalParams = new GlobalParams(buffer);
281
f7deaa1a 282 if (fit || globalParams->getPSPaperWidth() > 0)
283 {
284 // Only set paper size and area if we are fitting to the job's
285 // page size or the pdftops.conf file does not contain
286 // "psPaperSize match"...
287 globalParams->setPSPaperWidth(width);
288 globalParams->setPSPaperHeight(length);
289 globalParams->setPSImageableArea(left, bottom, right, top);
290 }
291
ef416fc2 292 globalParams->setPSDuplex(duplex);
293 globalParams->setPSExpandSmaller(fit);
294 globalParams->setPSShrinkLarger(fit);
295 globalParams->setPSLevel(level);
296 globalParams->setPSASCIIHex(level == psLevel1);
297 globalParams->setPSEmbedType1(1);
298 globalParams->setPSEmbedTrueType(1);
299 globalParams->setPSEmbedCIDPostScript(1);
300 globalParams->setErrQuiet(0);
301 globalParams->setPrintCommands(printCommands);
302
303 if (printCommands)
304 setbuf(stdout, NULL);
305
306 // open PDF file
307 doc = new PDFDoc(fileName, NULL, NULL);
308
309 // check for print permission
310 if (doc->isOk() && doc->okToPrint())
311 {
312 // CUPS always writes to stdout...
313 psFileName = new GString("-");
314
315 // write PostScript file
316 psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
317 doc->getCatalog(), 1, doc->getNumPages(),
318 psModePS, 0, 0, 0, 0, gFalse,
319 cupsGetOption("page-ranges", num_options, options));
320 if (psOut->isOk())
321 doc->displayPages(psOut, 1, doc->getNumPages(), 72.0, 72.0, 0,
322 gTrue, gFalse, gFalse);
323 delete psOut;
324
325 // clean up
326 delete psFileName;
327 }
328 else
329 {
330 error(-1, "Unable to print this document.");
331 }
332
333 cupsFreeOptions(num_options, options);
334
335 delete doc;
336 delete globalParams;
337
338 // check for memory leaks
339 Object::memCheck(stderr);
340 gMemReport(stderr);
341
342 // Remove temp file if needed...
343 if (tempfile[0])
344 unlink(tempfile);
345
346 return 0;
347}
348
349
350//
f7deaa1a 351// End of "$Id: pdftops.cxx 6324 2007-03-11 02:09:46Z mike $".
ef416fc2 352//