]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/pdftops.c
4 * PDF to PostScript filter front-end for the Common UNIX Printing
7 * Copyright 2007-2009 by Apple Inc.
8 * Copyright 1997-2006 by Easy Software Products.
10 * These coded instructions, statements, and computer programs are the
11 * property of Apple Inc. and are protected by Federal copyright
12 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
13 * which should have been included with this file. If this file is
14 * file is missing or damaged, see the license at "http://www.cups.org/".
18 * main() - Main entry for filter...
19 * cancel_job() - Flag the job as canceled.
23 * Include necessary headers...
26 #include <cups/cups.h>
27 #include <cups/string.h>
28 #include <cups/i18n.h>
38 static void cancel_job(int sig
);
45 static int job_canceled
= 0;
49 * 'main()' - Main entry for filter...
52 int /* O - Exit status */
53 main(int argc
, /* I - Number of command-line args */
54 char *argv
[]) /* I - Command-line arguments */
56 int fd
; /* Copy file descriptor */
57 char *filename
, /* PDF file to convert */
58 tempfile
[1024]; /* Temporary file */
59 char buffer
[8192]; /* Copy buffer */
60 int bytes
; /* Bytes copied */
61 int num_options
; /* Number of options */
62 cups_option_t
*options
; /* Options */
63 const char *val
; /* Option value */
64 int orientation
, /* Output orientation */
65 fit
; /* Fit output to default page size? */
66 ppd_file_t
*ppd
; /* PPD file */
67 ppd_size_t
*size
; /* Current page size */
68 int pdfpid
, /* Process ID for pdftops */
69 pdfwaitpid
, /* Process ID from wait() */
70 pdfstatus
, /* Status from pdftops */
71 pdfargc
; /* Number of args for pdftops */
72 char *pdfargv
[100], /* Arguments for pdftops/gs */
73 pdfwidth
[255], /* Paper width */
74 pdfheight
[255]; /* Paper height */
75 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
76 struct sigaction action
; /* Actions for POSIX signals */
77 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
81 * Make sure status messages are not buffered...
87 * Make sure we have the right number of arguments for CUPS!
90 if (argc
< 6 || argc
> 7)
92 _cupsLangPrintf(stderr
,
93 _("Usage: %s job user title copies options [filename]\n"),
99 * Register a signal handler to cleanly cancel a job.
102 #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
103 sigset(SIGTERM
, cancel_job
);
104 #elif defined(HAVE_SIGACTION)
105 memset(&action
, 0, sizeof(action
));
107 sigemptyset(&action
.sa_mask
);
108 action
.sa_handler
= cancel_job
;
109 sigaction(SIGTERM
, &action
, NULL
);
111 signal(SIGTERM
, cancel_job
);
112 #endif /* HAVE_SIGSET */
115 * Copy stdin if needed...
121 * Copy stdin to a temp file...
124 if ((fd
= cupsTempFd(tempfile
, sizeof(tempfile
))) < 0)
126 _cupsLangPrintError(_("ERROR: Unable to copy PDF file"));
130 fprintf(stderr
, "DEBUG: pdftops - copying to temp print file \"%s\"\n",
133 while ((bytes
= fread(buffer
, 1, sizeof(buffer
), stdin
)) > 0)
134 write(fd
, buffer
, bytes
);
143 * Use the filename on the command-line...
151 * Load the PPD file and mark options...
154 ppd
= ppdOpenFile(getenv("PPD"));
155 num_options
= cupsParseOptions(argv
[5], 0, &options
);
157 ppdMarkDefaults(ppd
);
158 cupsMarkOptions(ppd
, num_options
, options
);
161 * Build the command-line for the pdftops or gs filter...
165 pdfargv
[0] = (char *)"pdftops";
168 pdfargv
[0] = (char *)"gs";
169 pdfargv
[1] = (char *)"-q";
170 pdfargv
[2] = (char *)"-dNOPAUSE";
171 pdfargv
[3] = (char *)"-dBATCH";
172 pdfargv
[4] = (char *)"-dSAFER";
173 pdfargv
[5] = (char *)"-sDEVICE=pswrite";
174 pdfargv
[6] = (char *)"-sOUTPUTFILE=%stdout";
176 #endif /* HAVE_PDFTOPS */
181 * Set language level and TrueType font handling...
184 if (ppd
->language_level
== 1)
187 pdfargv
[pdfargc
++] = (char *)"-level1";
188 pdfargv
[pdfargc
++] = (char *)"-noembtt";
190 pdfargv
[pdfargc
++] = (char *)"-dLanguageLevel=1";
191 #endif /* HAVE_PDFTOPS */
193 else if (ppd
->language_level
== 2)
196 pdfargv
[pdfargc
++] = (char *)"-level2";
197 if (!ppd
->ttrasterizer
)
198 pdfargv
[pdfargc
++] = (char *)"-noembtt";
200 pdfargv
[pdfargc
++] = (char *)"-dLanguageLevel=2";
201 #endif /* HAVE_PDFTOPS */
205 pdfargv
[pdfargc
++] = (char *)"-level3";
207 pdfargv
[pdfargc
++] = (char *)"-dLanguageLevel=3";
208 #endif /* HAVE_PDFTOPS */
210 if ((val
= cupsGetOption("fitplot", num_options
, options
)) == NULL
)
211 val
= cupsGetOption("fit-to-page", num_options
, options
);
213 if (val
&& strcasecmp(val
, "no") && strcasecmp(val
, "off") &&
214 strcasecmp(val
, "false"))
220 * Set output page size...
223 size
= ppdPageSize(ppd
, NULL
);
227 * Got the size, now get the orientation...
232 if ((val
= cupsGetOption("landscape", num_options
, options
)) != NULL
)
234 if (strcasecmp(val
, "no") != 0 && strcasecmp(val
, "off") != 0 &&
235 strcasecmp(val
, "false") != 0)
238 else if ((val
= cupsGetOption("orientation-requested", num_options
, options
)) != NULL
)
241 * Map IPP orientation values to 0 to 3:
245 * 5 = -90 degrees = 3
246 * 6 = 180 degrees = 2
249 orientation
= atoi(val
) - 3;
250 if (orientation
>= 2)
257 snprintf(pdfwidth
, sizeof(pdfwidth
), "%.0f", size
->length
);
258 snprintf(pdfheight
, sizeof(pdfheight
), "%.0f", size
->width
);
262 snprintf(pdfwidth
, sizeof(pdfwidth
), "%.0f", size
->width
);
263 snprintf(pdfheight
, sizeof(pdfheight
), "%.0f", size
->length
);
266 pdfargv
[pdfargc
++] = (char *)"-paperw";
267 pdfargv
[pdfargc
++] = pdfwidth
;
268 pdfargv
[pdfargc
++] = (char *)"-paperh";
269 pdfargv
[pdfargc
++] = pdfheight
;
270 pdfargv
[pdfargc
++] = (char *)"-expand";
275 snprintf(pdfwidth
, sizeof(pdfwidth
), "-dDEVICEWIDTHPOINTS=%.0f",
277 snprintf(pdfheight
, sizeof(pdfheight
), "-dDEVICEHEIGHTPOINTS=%.0f",
282 snprintf(pdfwidth
, sizeof(pdfwidth
), "-dDEVICEWIDTHPOINTS=%.0f",
284 snprintf(pdfheight
, sizeof(pdfheight
), "-dDEVICEHEIGHTPOINTS=%.0f",
288 pdfargv
[pdfargc
++] = pdfwidth
;
289 pdfargv
[pdfargc
++] = pdfheight
;
290 #endif /* HAVE_PDFTOPS */
295 pdfargv
[pdfargc
++] = filename
;
296 pdfargv
[pdfargc
++] = (char *)"-";
298 pdfargv
[pdfargc
++] = (char *)"-c";
299 pdfargv
[pdfargc
++] = (char *)"save pop";
300 pdfargv
[pdfargc
++] = (char *)"-f";
301 pdfargv
[pdfargc
++] = filename
;
302 #endif /* HAVE_PDFTOPS */
304 pdfargv
[pdfargc
] = NULL
;
306 if ((pdfpid
= fork()) == 0)
309 * Child comes here...
313 execv(CUPS_PDFTOPS
, pdfargv
);
314 _cupsLangPrintError(_("ERROR: Unable to execute pdftops program"));
316 execv(CUPS_GHOSTSCRIPT
, pdfargv
);
317 _cupsLangPrintError(_("ERROR: Unable to execute gs program"));
318 #endif /* HAVE_PDFTOPS */
329 _cupsLangPrintError(_("ERROR: Unable to execute pdftops program"));
331 _cupsLangPrintError(_("ERROR: Unable to execute gs program"));
332 #endif /* HAVE_PDFTOPS */
339 * Parent comes here...
342 while ((pdfwaitpid
= wait(&pdfstatus
)) != pdfpid
&& errno
== EINTR
)
345 * Wait until we get a valid process ID or the job is canceled...
350 kill(pdfpid
, SIGTERM
);
357 if (WIFEXITED(pdfstatus
))
359 pdfstatus
= WEXITSTATUS(pdfstatus
);
361 _cupsLangPrintf(stderr
,
362 _("ERROR: pdftops filter exited with status %d!\n"),
367 pdfstatus
= WTERMSIG(pdfstatus
);
369 _cupsLangPrintf(stderr
,
370 _("ERROR: pdftops filter crashed on signal %d!\n"),
377 * Cleanup and exit...
388 * 'cancel_job()' - Flag the job as canceled.
392 cancel_job(int sig
) /* I - Signal number (unused) */