Index: config-scripts/cups-pdf.m4 =================================================================== --- config-scripts/cups-pdf.m4 (revision 8428) +++ config-scripts/cups-pdf.m4 (revision 8429) @@ -3,7 +3,7 @@ dnl dnl PDF filter configuration stuff for the Common UNIX Printing System (CUPS). dnl -dnl Copyright 2007 by Apple Inc. +dnl Copyright 2007-2009 by Apple Inc. dnl Copyright 2006 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the @@ -14,19 +14,58 @@ dnl AC_ARG_ENABLE(pdftops, [ --enable-pdftops build pdftops filter, default=auto ]) +AC_ARG_WITH(pdftops, [ --with-pdftops set pdftops filter (gs,pdftops,none), default=pdftops ]) +if test "x$enable_pdftops" = xno -a "x$with_pdftops" = x; then + with_pdftops=no +fi + PDFTOPS="" +CUPS_PDFTOPS="" +CUPS_GHOSTSCRIPT="" -if test "x$enable_pdftops" != xno; then - AC_MSG_CHECKING(whether to build pdftops filter) - if test "x$enable_pdftops" = xyes -o $uname != Darwin; then +case "x$with_pdftops" in + x) # Default/auto + if test $uname != Darwin; then + AC_PATH_PROG(CUPS_PDFTOPS, pdftops) + if test "x$CUPS_PDFTOPS" != x; then + AC_DEFINE(HAVE_PDFTOPS) + PDFTOPS="pdftops" + else + AC_PATH_PROG(CUPS_GHOSTSCRIPT, gs) + if test "x$CUPS_GHOSTSCRIPT" != x; then + AC_DEFINE(HAVE_GHOSTSCRIPT) + PDFTOPS="pdftops" + fi + fi + fi + ;; + + xgs) + AC_PATH_PROG(CUPS_GHOSTSCRIPT, gs) + if test "x$CUPS_GHOSTSCRIPT" != x; then + AC_DEFINE(HAVE_GHOSTSCRIPT) PDFTOPS="pdftops" - AC_MSG_RESULT(yes) else - AC_MSG_RESULT(no) + AC_MSG_ERROR(Unable to find gs program!) + exit 1 fi -fi + ;; + xpdftops) + AC_PATH_PROG(CUPS_PDFTOPS, pdftops) + if test "x$CUPS_PDFTOPS" != x; then + AC_DEFINE(HAVE_PDFTOPS) + PDFTOPS="pdftops" + else + AC_MSG_ERROR(Unable to find pdftops program!) + exit 1 + fi + ;; +esac + +AC_DEFINE_UNQUOTED(CUPS_PDFTOPS, "$CUPS_PDFTOPS") +AC_DEFINE_UNQUOTED(CUPS_GHOSTSCRIPT, "$CUPS_GHOSTSCRIPT") AC_SUBST(PDFTOPS) dnl Index: Makefile =================================================================== --- Makefile (revision 8428) +++ Makefile (revision 8429) @@ -3,7 +3,7 @@ # # Top-level Makefile for the Common UNIX Printing System (CUPS). # -# Copyright 2007-2008 by Apple Inc. +# Copyright 2007-2009 by Apple Inc. # Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the @@ -20,7 +20,7 @@ # DIRS = cups backend berkeley cgi-bin filter locale man monitor \ - notifier $(PDFTOPS) scheduler systemv test \ + notifier scheduler systemv test \ $(PHPDIR) \ conf data doc $(FONTS) ppd templates Index: filter/pdftops.c =================================================================== --- filter/pdftops.c (revision 0) +++ filter/pdftops.c (revision 8429) @@ -0,0 +1,407 @@ +/* + * "$Id$" + * + * PDF to PostScript filter front-end for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * which should have been included with this file. If this file is + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for filter... + * cancel_job() - Flag the job as canceled. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void cancel_job(int sig); + + +/* + * Local globals... + */ + +static int job_canceled = 0; + + +/* + * 'main()' - Main entry for filter... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int fd; /* Copy file descriptor */ + char *filename, /* PDF file to convert */ + tempfile[1024]; /* Temporary file */ + char buffer[8192]; /* Copy buffer */ + int bytes; /* Bytes copied */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + const char *val; /* Option value */ + int orientation, /* Output orientation */ + fit; /* Fit output to default page size? */ + ppd_file_t *ppd; /* PPD file */ + ppd_size_t *size; /* Current page size */ + int pdfpid, /* Process ID for pdftops */ + pdfwaitpid, /* Process ID from wait() */ + pdfstatus, /* Status from pdftops */ + pdfargc; /* Number of args for pdftops */ + char *pdfargv[100], /* Arguments for pdftops/gs */ + pdfwidth[255], /* Paper width */ + pdfheight[255]; /* Paper height */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * Make sure status messages are not buffered... + */ + + setbuf(stderr, NULL); + + /* + * Make sure we have the right number of arguments for CUPS! + */ + + if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job user title copies options [filename]\n"), + argv[0]); + return (1); + } + + /* + * Register a signal handler to cleanly cancel a job. + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, cancel_job); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = cancel_job; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, cancel_job); +#endif /* HAVE_SIGSET */ + + /* + * Copy stdin if needed... + */ + + if (argc == 6) + { + /* + * Copy stdin to a temp file... + */ + + if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to copy PDF file: %s\n"), + strerror(errno)); + return (1); + } + + fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n", + tempfile); + + while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + write(fd, buffer, bytes); + + close(fd); + + filename = tempfile; + } + else + { + /* + * Use the filename on the command-line... + */ + + filename = argv[6]; + tempfile[0] = '\0'; + } + + /* + * Load the PPD file and mark options... + */ + + ppd = ppdOpenFile(getenv("PPD")); + num_options = cupsParseOptions(argv[5], 0, &options); + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + /* + * Build the command-line for the pdftops or gs filter... + */ + +#ifdef HAVE_PDFTOPS + pdfargv[0] = (char *)"pdftops"; + pdfargc = 1; +#else + pdfargv[0] = (char *)"gs"; + pdfargv[1] = (char *)"-q"; + pdfargv[2] = (char *)"-dNOPAUSE"; + pdfargv[3] = (char *)"-dBATCH"; + pdfargv[4] = (char *)"-dSAFER"; + pdfargv[5] = (char *)"-sDEVICE=pswrite"; + pdfargv[6] = (char *)"-sOUTPUTFILE=%stdout"; + pdfargc = 7; +#endif /* HAVE_PDFTOPS */ + + if (ppd) + { + /* + * Set language level and TrueType font handling... + */ + + if (ppd->language_level == 1) + { +#ifdef HAVE_PDFTOPS + pdfargv[pdfargc++] = (char *)"-level1"; + pdfargv[pdfargc++] = (char *)"-noembtt"; +#else + pdfargv[pdfargc++] = (char *)"-dLanguageLevel=1"; +#endif /* HAVE_PDFTOPS */ + } + else if (ppd->language_level == 2) + { +#ifdef HAVE_PDFTOPS + pdfargv[pdfargc++] = (char *)"-level2"; + if (!ppd->ttrasterizer) + pdfargv[pdfargc++] = (char *)"-noembtt"; +#else + pdfargv[pdfargc++] = (char *)"-dLanguageLevel=2"; +#endif /* HAVE_PDFTOPS */ + } + else +#ifdef HAVE_PDFTOPS + pdfargv[pdfargc++] = (char *)"-level3"; +#else + pdfargv[pdfargc++] = (char *)"-dLanguageLevel=3"; +#endif /* HAVE_PDFTOPS */ + + if ((val = cupsGetOption("fitplot", num_options, options)) == NULL) + val = cupsGetOption("fit-to-page", num_options, options); + + if (val && strcasecmp(val, "no") && strcasecmp(val, "off") && + strcasecmp(val, "false")) + fit = 1; + else + fit = 0; + + /* + * Set output page size... + */ + + size = ppdPageSize(ppd, NULL); + if (size && fit) + { + /* + * Got the size, now get the orientation... + */ + + orientation = 0; + + if ((val = cupsGetOption("landscape", num_options, options)) != NULL) + { + if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 && + strcasecmp(val, "false") != 0) + orientation = 1; + } + else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL) + { + /* + * Map IPP orientation values to 0 to 3: + * + * 3 = 0 degrees = 0 + * 4 = 90 degrees = 1 + * 5 = -90 degrees = 3 + * 6 = 180 degrees = 2 + */ + + orientation = atoi(val) - 3; + if (orientation >= 2) + orientation ^= 1; + } + +#ifdef HAVE_PDFTOPS + if (orientation & 1) + { + snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->length); + snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->width); + } + else + { + snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->width); + snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->length); + } + + pdfargv[pdfargc++] = (char *)"-paperw"; + pdfargv[pdfargc++] = pdfwidth; + pdfargv[pdfargc++] = (char *)"-paperh"; + pdfargv[pdfargc++] = pdfheight; + pdfargv[pdfargc++] = (char *)"-expand"; + +#else + if (orientation & 1) + { + snprintf(pdfwidth, sizeof(pdfwidth), "-dDEVICEWIDTHPOINTS=%.0f", + size->length); + snprintf(pdfheight, sizeof(pdfheight), "-dDEVICEHEIGHTPOINTS=%.0f", + size->width); + } + else + { + snprintf(pdfwidth, sizeof(pdfwidth), "-dDEVICEWIDTHPOINTS=%.0f", + size->width); + snprintf(pdfheight, sizeof(pdfheight), "-dDEVICEHEIGHTPOINTS=%.0f", + size->length); + } + + pdfargv[pdfargc++] = pdfwidth; + pdfargv[pdfargc++] = pdfheight; +#endif /* HAVE_PDFTOPS */ + } + } + +#ifdef HAVE_PDFTOPS + pdfargv[pdfargc++] = filename; + pdfargv[pdfargc++] = (char *)"-"; +#else + pdfargv[pdfargc++] = (char *)"-c"; + pdfargv[pdfargc++] = (char *)"save pop"; + pdfargv[pdfargc++] = (char *)"-f"; + pdfargv[pdfargc++] = filename; +#endif /* HAVE_PDFTOPS */ + + pdfargv[pdfargc] = NULL; + + if ((pdfpid = fork()) == 0) + { + /* + * Child comes here... + */ + +#ifdef HAVE_PDFTOPS + execv(CUPS_PDFTOPS, pdfargv); + _cupsLangPrintf(stderr, _("ERROR: Unable to execute pdftops program: %s\n"), + strerror(errno)); +#else + execv(CUPS_GHOSTSCRIPT, pdfargv); + _cupsLangPrintf(stderr, _("ERROR: Unable to execute gs program: %s\n"), + strerror(errno)); +#endif /* HAVE_PDFTOPS */ + + exit(1); + } + else if (pdfpid < 0) + { + /* + * Unable to fork! + */ + +#ifdef HAVE_PDFTOPS + _cupsLangPrintf(stderr, _("ERROR: Unable to execute pdftops program: %s\n"), + strerror(errno)); +#else + _cupsLangPrintf(stderr, _("ERROR: Unable to execute gs program: %s\n"), + strerror(errno)); +#endif /* HAVE_PDFTOPS */ + + pdfstatus = 1; + } + else + { + /* + * Parent comes here... + */ + + while ((pdfwaitpid = wait(&pdfstatus)) != pdfpid && errno == EINTR) + { + /* + * Wait until we get a valid process ID or the job is canceled... + */ + + if (job_canceled) + { + kill(pdfpid, SIGTERM); + job_canceled = 0; + } + } + + if (pdfstatus) + { + if (WIFEXITED(pdfstatus)) + { + pdfstatus = WEXITSTATUS(pdfstatus); + + _cupsLangPrintf(stderr, + _("ERROR: pdftops filter exited with status %d!\n"), + pdfstatus); + } + else + { + pdfstatus = WTERMSIG(pdfstatus); + + _cupsLangPrintf(stderr, + _("ERROR: pdftops filter crashed on signal %d!\n"), + pdfstatus); + } + } + } + + /* + * Cleanup and exit... + */ + + if (tempfile[0]) + unlink(tempfile); + + return (pdfstatus); +} + + +/* + * 'cancel_job()' - Flag the job as canceled. + */ + +static void +cancel_job(int sig) /* I - Signal number (unused) */ +{ + (void)sig; + + job_canceled = 1; +} + + +/* + * End of "$Id$". + */ Property changes on: filter/pdftops.c ___________________________________________________________________ Added: svn:eol-style + native Added: svn:keywords + Id Index: filter/Makefile =================================================================== --- filter/Makefile (revision 8428) +++ filter/Makefile (revision 8429) @@ -3,7 +3,7 @@ # # Filter makefile for the Common UNIX Printing System (CUPS). # -# Copyright 2007 by Apple Inc. +# Copyright 2007-2009 by Apple Inc. # Copyright 1997-2006 by Easy Software Products. # # These coded instructions, statements, and computer programs are the @@ -19,7 +19,7 @@ FILTERS = gziptoany hpgltops texttops pstops $(IMGFILTERS) \ - rastertolabel rastertoepson rastertohp + $(PDFTOPS) rastertolabel rastertoepson rastertohp TARGETS = $(FILTERS) \ $(LIBCUPSIMAGE) \ libcupsimage.a \ @@ -39,9 +39,9 @@ IMAGE64OBJS = $(IMAGEOBJS:.o=.64.o) FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o OBJS = $(HPGLOBJS) $(IMAGEOBJS) $(FORMOBJS) \ - gziptoany.o imagetops.o imagetoraster.o common.o pstops.o \ - rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \ - testimage.o testraster.o textcommon.o texttops.o + gziptoany.o imagetops.o imagetoraster.o common.o pdftops.o \ + pstops.o rasterbench.o rastertoepson.o rastertohp.o \ + rastertolabel.o testimage.o testraster.o textcommon.o texttops.o # @@ -324,6 +324,15 @@ # +# pdftops +# + +pdftops: pdftops.o common.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ pdftops.o common.o $(LIBS) + + +# # rastertolabel # Index: filter/Dependencies =================================================================== --- filter/Dependencies (revision 8428) +++ filter/Dependencies (revision 8429) @@ -106,6 +106,9 @@ common.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h common.o: ../cups/array.h ../cups/file.h ../cups/language.h common.o: ../cups/language.h ../cups/string.h ../config.h +pdftops.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pdftops.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/string.h +pdftops.o: ../config.h ../cups/i18n.h ../cups/transcode.h pstops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h pstops.o: ../cups/array.h ../cups/file.h ../cups/language.h pstops.o: ../cups/language.h ../cups/string.h ../config.h ../cups/file.h @@ -246,6 +249,9 @@ common.32.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h common.32.o: common.c ../cups/array.h ../cups/file.h ../cups/language.h common.32.o: common.c ../cups/language.h ../cups/string.h ../config.h +pdftops.32.o: pdftops.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pdftops.32.o: pdftops.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/string.h +pdftops.32.o: pdftops.c ../config.h ../cups/i18n.h ../cups/transcode.h pstops.32.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h pstops.32.o: pstops.c ../cups/array.h ../cups/file.h ../cups/language.h pstops.32.o: pstops.c ../cups/language.h ../cups/string.h ../config.h ../cups/file.h @@ -386,6 +392,9 @@ common.64.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h common.64.o: common.c ../cups/array.h ../cups/file.h ../cups/language.h common.64.o: common.c ../cups/language.h ../cups/string.h ../config.h +pdftops.64.o: pdftops.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pdftops.64.o: pdftops.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/string.h +pdftops.64.o: pdftops.c ../config.h ../cups/i18n.h ../cups/transcode.h pstops.64.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h pstops.64.o: pstops.c ../cups/array.h ../cups/file.h ../cups/language.h pstops.64.o: pstops.c ../cups/language.h ../cups/string.h ../config.h ../cups/file.h Index: config.h.in =================================================================== --- config.h.in (revision 8428) +++ config.h.in (revision 8429) @@ -3,7 +3,7 @@ * * Configuration file for the Common UNIX Printing System (CUPS). * - * Copyright 2007 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -436,6 +436,22 @@ /* + * Location of the poppler/Xpdf pdftops program... + */ + +#undef HAVE_PDFTOPS +#define CUPS_PDFTOPS "/usr/bin/pdftops" + + +/* + * Location of the Ghostscript gs program... + */ + +#undef HAVE_GHOSTSCRIPT +#define CUPS_GHOSTSCRIPT "/usr/bin/gs" + + +/* * Do we have Darwin's CoreFoundation and SystemConfiguration frameworks? */