]> git.ipfire.org Git - thirdparty/cups.git/blob - pdftops/pdftops.cxx
Load cups into easysw/current.
[thirdparty/cups.git] / pdftops / pdftops.cxx
1 //
2 // "$Id: pdftops.cxx 4906 2006-01-10 20:53:28Z mike $"
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
61 int // O - Exit status
62 main(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
282 globalParams->setPSPaperWidth(width);
283 globalParams->setPSPaperHeight(length);
284 globalParams->setPSImageableArea(left, bottom, right, top);
285 globalParams->setPSDuplex(duplex);
286 globalParams->setPSExpandSmaller(fit);
287 globalParams->setPSShrinkLarger(fit);
288 globalParams->setPSLevel(level);
289 globalParams->setPSASCIIHex(level == psLevel1);
290 globalParams->setPSEmbedType1(1);
291 globalParams->setPSEmbedTrueType(1);
292 globalParams->setPSEmbedCIDPostScript(1);
293 globalParams->setErrQuiet(0);
294 globalParams->setPrintCommands(printCommands);
295
296 if (printCommands)
297 setbuf(stdout, NULL);
298
299 // open PDF file
300 doc = new PDFDoc(fileName, NULL, NULL);
301
302 // check for print permission
303 if (doc->isOk() && doc->okToPrint())
304 {
305 // CUPS always writes to stdout...
306 psFileName = new GString("-");
307
308 // write PostScript file
309 psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
310 doc->getCatalog(), 1, doc->getNumPages(),
311 psModePS, 0, 0, 0, 0, gFalse,
312 cupsGetOption("page-ranges", num_options, options));
313 if (psOut->isOk())
314 doc->displayPages(psOut, 1, doc->getNumPages(), 72.0, 72.0, 0,
315 gTrue, gFalse, gFalse);
316 delete psOut;
317
318 // clean up
319 delete psFileName;
320 }
321 else
322 {
323 error(-1, "Unable to print this document.");
324 }
325
326 cupsFreeOptions(num_options, options);
327
328 delete doc;
329 delete globalParams;
330
331 // check for memory leaks
332 Object::memCheck(stderr);
333 gMemReport(stderr);
334
335 // Remove temp file if needed...
336 if (tempfile[0])
337 unlink(tempfile);
338
339 return 0;
340 }
341
342
343 //
344 // End of "$Id: pdftops.cxx 4906 2006-01-10 20:53:28Z mike $".
345 //