diff --git a/.gitignore b/.gitignore index c77b757..927b494 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ ghostscript-8.70.tar.xz ghostscript-8.71.tar.xz /ghostscript-9.00.tar.xz /ghostscript-9.01.tar.bz2 +/ghostscript-9.02.tar.bz2 diff --git a/ghostscript-colord.patch b/ghostscript-colord.patch deleted file mode 100644 index 40c531f..0000000 --- a/ghostscript-colord.patch +++ /dev/null @@ -1,1277 +0,0 @@ -diff -up ghostscript-9.01/configure.ac.colord ghostscript-9.01/configure.ac ---- ghostscript-9.01/configure.ac.colord 2011-02-02 14:12:15.000000000 +0000 -+++ ghostscript-9.01/configure.ac 2011-03-10 13:48:17.599512567 +0000 -@@ -423,6 +423,37 @@ AC_SUBST(HAVE_FONTCONFIG) - AC_SUBST(FONTCONFIG_CFLAGS) - AC_SUBST(FONTCONFIG_LIBS) - -+dnl DBus support -+HAVE_DBUS="" -+DBUS_CFLAGS="" -+DBUS_LIBS="" -+AC_ARG_ENABLE([dbus], AC_HELP_STRING([--disable-dbus], -+ [Do not use dbus to communicate with external services])) -+if test "$enable_dbus" != "no"; then -+ if test "x$PKGCONFIG" != x; then -+ AC_MSG_CHECKING(for dbus with pkg-config) -+ if $PKGCONFIG --exists dbus-1; then -+ AC_MSG_RESULT(yes) -+ DBUS_CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1`" -+ DBUS_LIBS="`$PKGCONFIG --libs dbus-1`" -+ HAVE_DBUS=-DHAVE_DBUS -+ else -+ AC_MSG_RESULT(no) -+ fi -+ fi -+ if test -z "$HAVE_DBUS"; then -+ AC_CHECK_LIB([dbus], [dbus_message_iter_get_basic], [ -+ AC_CHECK_HEADER([dbus-1.0/dbus/dbus.h], [ -+ DBUS_LIBS="-ldbus-1 -lpthread -lrt" -+ HAVE_DBUS="-DHAVE_DBUS" -+ ]) -+ ]) -+ fi -+fi -+AC_SUBST(HAVE_DBUS) -+AC_SUBST(DBUS_CFLAGS) -+AC_SUBST(DBUS_LIBS) -+ - AC_CHECK_LIB(dl, dlopen) - - AC_ARG_ENABLE([freetype], AC_HELP_STRING([--disable-freetype], -@@ -1439,6 +1470,6 @@ dnl ------------------------------------ - AC_SUBST(OPT_CFLAGS) - AC_SUBST(DBG_CFLAGS) - AC_SUBST(GCFLAGS) --AC_OUTPUT(Makefile cups/pstopxl cups/pstoraster) -+AC_OUTPUT(Makefile cups/pstopxl) - --chmod +x cups/pstopxl cups/pstoraster -+chmod +x cups/pstopxl -diff -up ghostscript-9.01/cups/colord.c.colord ghostscript-9.01/cups/colord.c ---- ghostscript-9.01/cups/colord.c.colord 2011-03-10 13:48:17.600512671 +0000 -+++ ghostscript-9.01/cups/colord.c 2011-03-10 13:48:17.600512671 +0000 -@@ -0,0 +1,367 @@ -+/* -+Copyright (c) 2011, Tim Waugh -+Copyright (c) 2011, Richard Hughes -+ -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+"Software"), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be included -+in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+MIT Open Source License - http://www.opensource.org/ -+ -+*/ -+ -+/* $Id$ */ -+ -+/* Common routines for accessing the colord CMS framework */ -+ -+#include -+#include -+#include -+ -+#ifdef HAVE_DBUS -+ #include -+#endif -+ -+#include "colord.h" -+ -+#define QUAL_COLORSPACE 0 -+#define QUAL_MEDIA 1 -+#define QUAL_RESOLUTION 2 -+#define QUAL_SIZE 3 -+ -+char ** -+colord_get_qualifier_for_ppd (ppd_file_t *ppd) -+{ -+ char q_keyword[PPD_MAX_NAME]; -+ char **tuple = NULL; -+ const char *q1_choice; -+ const char *q2_choice; -+ const char *q3_choice; -+ ppd_attr_t *attr; -+ ppd_attr_t *q1_attr; -+ ppd_attr_t *q2_attr; -+ ppd_attr_t *q3_attr; -+ -+ /* get colorspace */ -+ if ((attr = ppdFindAttr (ppd, "cupsICCQualifier1", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf (q_keyword, sizeof (q_keyword), "Default%s", attr->value); -+ q1_attr = ppdFindAttr (ppd, q_keyword, NULL); -+ } -+ else if ((q1_attr = ppdFindAttr (ppd, "DefaultColorModel", NULL)) == NULL) -+ q1_attr = ppdFindAttr (ppd, "DefaultColorSpace", NULL); -+ -+ if (q1_attr && q1_attr->value && q1_attr->value[0]) -+ q1_choice = q1_attr->value; -+ else -+ q1_choice = ""; -+ -+ /* get colorspace */ -+ if ((attr = ppdFindAttr (ppd, "cupsICCQualifier2", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf (q_keyword, sizeof (q_keyword), "Default%s", attr->value); -+ q1_attr = ppdFindAttr (ppd, q_keyword, NULL); -+ } -+ else if ((q1_attr = ppdFindAttr (ppd, "DefaultColorModel", NULL)) == NULL) -+ q1_attr = ppdFindAttr (ppd, "DefaultColorSpace", NULL); -+ -+ if (q1_attr && q1_attr->value && q1_attr->value[0]) -+ q1_choice = q1_attr->value; -+ else -+ q1_choice = ""; -+ -+ /* get media */ -+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -+ q2_attr = ppdFindAttr(ppd, q_keyword, NULL); -+ } -+ else -+ q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL); -+ -+ if (q2_attr && q2_attr->value && q2_attr->value[0]) -+ q2_choice = q2_attr->value; -+ else -+ q2_choice = ""; -+ -+ /* get resolution */ -+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -+ q3_attr = ppdFindAttr(ppd, q_keyword, NULL); -+ } -+ else -+ q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL); -+ -+ if (q3_attr && q3_attr->value && q3_attr->value[0]) -+ q3_choice = q3_attr->value; -+ else -+ q3_choice = ""; -+ -+ /* return a NULL terminated array so we don't have to break it up later */ -+ tuple = calloc(QUAL_SIZE + 1, sizeof(char*)); -+ tuple[QUAL_COLORSPACE] = strdup(q1_choice); -+ tuple[QUAL_MEDIA] = strdup(q2_choice); -+ tuple[QUAL_RESOLUTION] = strdup(q3_choice); -+ return tuple; -+} -+ -+#ifdef HAVE_DBUS -+ -+static char * -+get_filename_for_profile_path (DBusConnection *con, -+ const char *object_path) -+{ -+ char *filename = NULL; -+ const char *interface = "org.freedesktop.ColorManager.Profile"; -+ const char *property = "Filename"; -+ const char *tmp; -+ DBusError error; -+ DBusMessageIter args; -+ DBusMessage *message = NULL; -+ DBusMessage *reply = NULL; -+ DBusMessageIter sub; -+ -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ object_path, -+ "org.freedesktop.DBus.Properties", -+ "Get"); -+ -+ dbus_message_iter_init_append(message, &args); -+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &interface); -+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &property); -+ -+ /* send syncronous */ -+ dbus_error_init(&error); -+ fprintf(stderr, "DEBUG: Calling %s.Get(%s)\n", interface, property); -+ reply = dbus_connection_send_with_reply_and_block(con, -+ message, -+ -1, -+ &error); -+ if (reply == NULL) { -+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n", -+ error.name, error.message); -+ dbus_error_free(&error); -+ goto out; -+ } -+ -+ /* get reply data */ -+ dbus_message_iter_init(reply, &args); -+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) { -+ fprintf(stderr, "DEBUG: Incorrect reply type\n"); -+ goto out; -+ } -+ -+ dbus_message_iter_recurse(&args, &sub); -+ dbus_message_iter_get_basic(&sub, &tmp); -+ filename = strdup(tmp); -+out: -+ if (message != NULL) -+ dbus_message_unref(message); -+ if (reply != NULL) -+ dbus_message_unref(reply); -+ return filename; -+} -+ -+static char * -+get_profile_for_device_path (DBusConnection *con, -+ const char *object_path, -+ const char **split) -+{ -+ char **key = NULL; -+ char *profile = NULL; -+ char str[256]; -+ const char *tmp; -+ DBusError error; -+ DBusMessageIter args; -+ DBusMessageIter entry; -+ DBusMessage *message = NULL; -+ DBusMessage *reply = NULL; -+ int i = 0; -+ const int max_keys = 7; -+ -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ object_path, -+ "org.freedesktop.ColorManager.Device", -+ "GetProfileForQualifiers"); -+ dbus_message_iter_init_append(message, &args); -+ -+ /* create the fallbacks */ -+ key = calloc(max_keys + 1, sizeof(char*)); -+ -+ /* exact match */ -+ i = 0; -+ snprintf(str, sizeof(str), "%s.%s.%s", -+ split[QUAL_COLORSPACE], -+ split[QUAL_MEDIA], -+ split[QUAL_RESOLUTION]); -+ key[i++] = strdup(str); -+ snprintf(str, sizeof(str), "%s.%s.*", -+ split[QUAL_COLORSPACE], -+ split[QUAL_MEDIA]); -+ key[i++] = strdup(str); -+ snprintf(str, sizeof(str), "%s.*.%s", -+ split[QUAL_COLORSPACE], -+ split[QUAL_RESOLUTION]); -+ key[i++] = strdup(str); -+ snprintf(str, sizeof(str), "%s.*.*", -+ split[QUAL_COLORSPACE]); -+ key[i++] = strdup(str); -+ key[i++] = strdup("*"); -+ dbus_message_iter_open_container(&args, -+ DBUS_TYPE_ARRAY, -+ "s", -+ &entry); -+ for (i=0; key[i] != NULL; i++) { -+ dbus_message_iter_append_basic(&entry, -+ DBUS_TYPE_STRING, -+ &key[i]); -+ } -+ dbus_message_iter_close_container(&args, &entry); -+ -+ /* send syncronous */ -+ dbus_error_init(&error); -+ fprintf(stderr, "DEBUG: Calling GetProfileForQualifiers(%s...)\n", key[0]); -+ reply = dbus_connection_send_with_reply_and_block(con, -+ message, -+ -1, -+ &error); -+ if (reply == NULL) { -+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n", -+ error.name, error.message); -+ dbus_error_free(&error); -+ goto out; -+ } -+ -+ /* get reply data */ -+ dbus_message_iter_init(reply, &args); -+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) { -+ fprintf(stderr, "DEBUG: Incorrect reply type\n"); -+ goto out; -+ } -+ dbus_message_iter_get_basic(&args, &tmp); -+ fprintf(stderr, "DEBUG: Found profile %s\n", tmp); -+ -+ /* get filename */ -+ profile = get_filename_for_profile_path(con, tmp); -+ -+out: -+ if (message != NULL) -+ dbus_message_unref(message); -+ if (reply != NULL) -+ dbus_message_unref(reply); -+ if (key != NULL) { -+ for (i=0; i < max_keys; i++) -+ free(key[i]); -+ free(key); -+ } -+ return profile; -+} -+ -+static char * -+get_profile_for_device_id (DBusConnection *con, -+ const char *device_id, -+ const char **qualifier_tuple) -+{ -+ char *profile = NULL; -+ const char *device_path_tmp; -+ DBusError error; -+ DBusMessageIter args; -+ DBusMessage *message = NULL; -+ DBusMessage *reply = NULL; -+ -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ "/org/freedesktop/ColorManager", -+ "org.freedesktop.ColorManager", -+ "FindDeviceById"); -+ dbus_message_iter_init_append(message, &args); -+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id); -+ -+ /* send syncronous */ -+ dbus_error_init(&error); -+ fprintf(stderr, "DEBUG: Calling FindDeviceById(%s)\n", device_id); -+ reply = dbus_connection_send_with_reply_and_block(con, -+ message, -+ -1, -+ &error); -+ if (reply == NULL) { -+ fprintf(stderr, "DEBUG: Failed to send: %s:%s\n", -+ error.name, error.message); -+ dbus_error_free(&error); -+ goto out; -+ } -+ -+ /* get reply data */ -+ dbus_message_iter_init(reply, &args); -+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) { -+ fprintf(stderr, "DEBUG: Incorrect reply type\n"); -+ goto out; -+ } -+ dbus_message_iter_get_basic(&args, &device_path_tmp); -+ fprintf(stderr, "DEBUG: Found device %s\n", device_path_tmp); -+ profile = get_profile_for_device_path(con, device_path_tmp, qualifier_tuple); -+out: -+ if (message != NULL) -+ dbus_message_unref(message); -+ if (reply != NULL) -+ dbus_message_unref(reply); -+ return profile; -+} -+ -+char * -+colord_get_profile_for_device_id (const char *device_id, -+ const char **qualifier_tuple) -+{ -+ DBusConnection *con; -+ char *filename = NULL; -+ -+ /* connect to system bus */ -+ con = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); -+ if (con == NULL) { -+ fprintf(stderr, "ERROR: Failed to connect to system bus\n"); -+ goto out; -+ } -+ -+ /* get the best profile for the device */ -+ filename = get_profile_for_device_id (con, device_id, qualifier_tuple); -+ if (filename == NULL) { -+ fprintf(stderr, "DEBUG: Failed to get profile filename!\n"); -+ goto out; -+ } -+ fprintf(stderr, "DEBUG: Use profile filename: '%s'\n", filename); -+out: -+ if (con != NULL) -+ dbus_connection_unref(con); -+ return filename; -+} -+ -+#else -+ -+char * -+colord_get_profile_for_device_id (const char *device_id, -+ const char **qualifier_tuple) -+{ -+ fprintf(stderr, "WARN: not compiled with DBus support\n"); -+ return NULL; -+} -+ -+#endif -diff -up ghostscript-9.01/cups/colord.h.colord ghostscript-9.01/cups/colord.h ---- ghostscript-9.01/cups/colord.h.colord 2011-03-10 13:48:17.601512775 +0000 -+++ ghostscript-9.01/cups/colord.h 2011-03-10 13:48:17.601512775 +0000 -@@ -0,0 +1,35 @@ -+/* -+Copyright (c) 2011, Richard Hughes -+ -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+"Software"), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be included -+in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+MIT Open Source License - http://www.opensource.org/ -+ -+*/ -+ -+/* $Id$ */ -+ -+/* Common routines for accessing the colord CMS framework */ -+ -+#include -+ -+char **colord_get_qualifier_for_ppd (ppd_file_t *ppd); -+char *colord_get_profile_for_device_id (const char *device_id, -+ const char **qualifier_tuple); -diff -up ghostscript-9.01/cups/cups.mak.colord ghostscript-9.01/cups/cups.mak ---- ghostscript-9.01/cups/cups.mak.colord 2011-03-10 13:48:17.573509871 +0000 -+++ ghostscript-9.01/cups/cups.mak 2011-03-10 13:48:17.602512879 +0000 -@@ -35,30 +35,30 @@ cups_= $(GLOBJ)gdevcups.$(OBJ) - # CUPSDATA=`cups-config --datadir` - # CUPSPDFTORASTER= 1 if CUPS is new enough (cups-config --version) - --PDFTORASTER_XE=$(BINDIR)$(D)pdftoraster$(XE) -+GSTORASTER_XE=$(BINDIR)$(D)gstoraster$(XE) - --cups: pdftoraster --pdftoraster: $(PDFTORASTER_XE) --pdftoraster_=cups/pdftoraster.c -+cups: gstoraster - --$(PDFTORASTER_XE): $(pdftoraster_) -+gstoraster: $(GSTORASTER_XE) -+gstoraster_=cups/gstoraster.c cups/colord.c -+ -+$(GSTORASTER_XE): $(gstoraster_) - if [ "$(CUPSPDFTORASTER)" = "1" ]; then \ -- $(GLCC) $(LDFLAGS) -DBINDIR='"$(bindir)"' -DGS='"$(GS)"' -o $@ $(pdftoraster_) `cups-config --image --ldflags --libs`; \ -+ $(GLCC) $(LDFLAGS) $(DBUS_CFLAGS) -DBINDIR='"$(bindir)"' -DCUPSDATA='"$(CUPSDATA)"' -DGS='"$(GS)"' -o $@ $(gstoraster_) `cups-config --image --ldflags --libs` $(DBUS_LIBS); \ - fi - -+ - install: install-cups - - install-cups: cups - -mkdir -p $(DESTDIR)$(CUPSSERVERBIN)/filter -- $(INSTALL_PROGRAM) cups/pstoraster $(DESTDIR)$(CUPSSERVERBIN)/filter - if [ "$(CUPSPDFTORASTER)" = "1" ]; then \ -- $(INSTALL_PROGRAM) $(PDFTORASTER_XE) $(DESTDIR)$(CUPSSERVERBIN)/filter; \ -+ $(INSTALL_PROGRAM) $(GSTORASTER_XE) $(DESTDIR)$(CUPSSERVERBIN)/filter; \ - fi - $(INSTALL_PROGRAM) cups/pstopxl $(DESTDIR)$(CUPSSERVERBIN)/filter - -mkdir -p $(DESTDIR)$(CUPSDATA)/mime -- $(INSTALL_DATA) cups/pstoraster.convs $(DESTDIR)$(CUPSDATA)/mime - if [ "$(CUPSPDFTORASTER)" = "1" ]; then \ -- $(INSTALL_DATA) cups/pdftoraster.convs $(DESTDIR)$(CUPSDATA)/mime; \ -+ $(INSTALL_DATA) cups/gstoraster.convs $(DESTDIR)$(CUPSDATA)/mime; \ - fi - -mkdir -p $(DESTDIR)$(CUPSDATA)/model - $(INSTALL_DATA) cups/pxlcolor.ppd $(DESTDIR)$(CUPSDATA)/model -diff -up ghostscript-9.01/cups/gstoraster.c.colord ghostscript-9.01/cups/gstoraster.c ---- ghostscript-9.01/cups/gstoraster.c.colord 2011-03-10 13:48:17.604513086 +0000 -+++ ghostscript-9.01/cups/gstoraster.c 2011-03-10 14:40:00.005019314 +0000 -@@ -0,0 +1,712 @@ -+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: s; c-basic-offset: 8 -*- -+ -+Copyright (c) 2008, Till Kamppeter -+Copyright (c) 2011, Tim Waugh -+Copyright (c) 2011, Richard Hughes -+ -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+"Software"), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be included -+in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+MIT Open Source License - http://www.opensource.org/ -+ -+*/ -+ -+/* $Id$ */ -+ -+/* PS/PDF to CUPS Raster filter based on Ghostscript */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "colord.h" -+ -+#define PDF_MAX_CHECK_COMMENT_LINES 20 -+ -+#ifndef GS -+#define GS "gs" -+#endif -+#ifndef BINDIR -+#define BINDIR "/usr/bin" -+#endif -+#ifndef CUPS_FONTPATH -+#define CUPS_FONTPATH "/usr/share/cups/fonts" -+#endif -+#ifndef CUPSDATA -+#define CUPSDATA "/usr/share/cups" -+#endif -+ -+typedef enum { -+ GS_DOC_TYPE_PDF, -+ GS_DOC_TYPE_PS, -+ GS_DOC_TYPE_UNKNOWN -+} GsDocType; -+ -+#ifdef CUPS_RASTER_SYNCv1 -+typedef cups_page_header2_t gs_page_header; -+#else -+typedef cups_page_header_t gs_page_header; -+#endif /* CUPS_RASTER_SYNCv1 */ -+ -+static GsDocType -+parse_doc_type(FILE *fp) -+{ -+ char buf[5]; -+ GsDocType doc_type; -+ char *rc; -+ -+ /* get the first few bytes of the file */ -+ doc_type = GS_DOC_TYPE_UNKNOWN; -+ rewind(fp); -+ rc = fgets(buf,sizeof(buf),fp); -+ if (rc == NULL) -+ goto out; -+ -+ /* is PDF */ -+ if (strncmp(buf,"%PDF",4) == 0) { -+ doc_type = GS_DOC_TYPE_PDF; -+ goto out; -+ } -+ -+ /* is PS */ -+ if (strncmp(buf,"%!",2) == 0) { -+ doc_type = GS_DOC_TYPE_PS; -+ goto out; -+ } -+out: -+ return doc_type; -+} -+ -+static void -+parse_pdf_header_options(FILE *fp, gs_page_header *h) -+{ -+ char buf[4096]; -+ int i; -+ -+ rewind(fp); -+ /* skip until PDF start header */ -+ while (fgets(buf,sizeof(buf),fp) != 0) { -+ if (strncmp(buf,"%PDF",4) == 0) { -+ break; -+ } -+ } -+ for (i = 0;i < PDF_MAX_CHECK_COMMENT_LINES;i++) { -+ if (fgets(buf,sizeof(buf),fp) == 0) break; -+ if (strncmp(buf,"%%PDFTOPDFNumCopies",19) == 0) { -+ char *p; -+ -+ p = strchr(buf+19,':'); -+ h->NumCopies = atoi(p+1); -+ } else if (strncmp(buf,"%%PDFTOPDFCollate",17) == 0) { -+ char *p; -+ -+ p = strchr(buf+17,':'); -+ while (*p == ' ' || *p == '\t') p++; -+ if (strncasecmp(p,"true",4) == 0) { -+ h->Collate = CUPS_TRUE; -+ } else { -+ h->Collate = CUPS_FALSE; -+ } -+ } -+ } -+} -+ -+static void -+add_pdf_header_options(gs_page_header *h, cups_array_t *gs_args) -+{ -+ int i; -+ char tmpstr[1024]; -+ -+ /* Simple boolean, enumerated choice, numerical, and string parameters */ -+ if (h->MediaClass[0] |= '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-sMediaClass=%s", h->MediaClass); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->MediaColor[0] |= '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-sMediaColor=%s", h->MediaColor); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->MediaType[0] |= '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-sMediaType=%s", h->MediaType); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->OutputType[0] |= '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-sOutputType=%s", h->OutputType); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->AdvanceDistance) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dAdvanceDistance=%d", -+ (unsigned)(h->AdvanceDistance)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->AdvanceMedia) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dAdvanceMedia=%d", -+ (unsigned)(h->AdvanceMedia)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->Collate) { -+ cupsArrayAdd(gs_args, strdup("-dCollate")); -+ } -+ if (h->CutMedia) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dCutMedia=%d", -+ (unsigned)(h->CutMedia)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->Duplex) { -+ cupsArrayAdd(gs_args, strdup("-dDuplex")); -+ } -+ if ((h->HWResolution[0] != 100) || (h->HWResolution[1] != 100)) -+ snprintf(tmpstr, sizeof(tmpstr), "-r%dx%d", -+ (unsigned)(h->HWResolution[0]), (unsigned)(h->HWResolution[1])); -+ else -+ snprintf(tmpstr, sizeof(tmpstr), "-r100x100"); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ if (h->InsertSheet) { -+ cupsArrayAdd(gs_args, strdup("-dInsertSheet")); -+ } -+ if (h->Jog) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dJog=%d", -+ (unsigned)(h->Jog)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->LeadingEdge) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dLeadingEdge=%d", -+ (unsigned)(h->LeadingEdge)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->ManualFeed) { -+ cupsArrayAdd(gs_args, strdup("-dManualFeed")); -+ } -+ if (h->MediaPosition) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dMediaPosition=%d", -+ (unsigned)(h->MediaPosition)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->MediaWeight) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dMediaWeight=%d", -+ (unsigned)(h->MediaWeight)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->MirrorPrint) { -+ cupsArrayAdd(gs_args, strdup("-dMirrorPrint")); -+ } -+ if (h->NegativePrint) { -+ cupsArrayAdd(gs_args, strdup("-dNegativePrint")); -+ } -+ if (h->NumCopies != 1) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dNumCopies=%d", -+ (unsigned)(h->NumCopies)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->Orientation) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dOrientation=%d", -+ (unsigned)(h->Orientation)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->OutputFaceUp) { -+ cupsArrayAdd(gs_args, strdup("-dOutputFaceUp")); -+ } -+ if (h->PageSize[0] != 612) -+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEWIDTHPOINTS=%d", -+ (unsigned)(h->PageSize[0])); -+ else -+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEWIDTHPOINTS=612"); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ if (h->PageSize[1] != 792) -+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEHEIGHTPOINTS=%d", -+ (unsigned)(h->PageSize[1])); -+ else -+ snprintf(tmpstr, sizeof(tmpstr), "-dDEVICEHEIGHTPOINTS=792"); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ if (h->Separations) { -+ cupsArrayAdd(gs_args, strdup("-dSeparations")); -+ } -+ if (h->TraySwitch) { -+ cupsArrayAdd(gs_args, strdup("-dTraySwitch")); -+ } -+ if (h->Tumble) { -+ cupsArrayAdd(gs_args, strdup("-dTumble")); -+ } -+ if (h->cupsMediaType) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsMediaType=%d", -+ (unsigned)(h->cupsMediaType)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsBitsPerColor != 1) -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsBitsPerColor=%d", -+ (unsigned)(h->cupsBitsPerColor)); -+ else -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsBitsPerColor=1"); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ if (h->cupsColorOrder != CUPS_ORDER_CHUNKED) -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorOrder=%d", -+ (unsigned)(h->cupsColorOrder)); -+ else -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorOrder=%d", -+ CUPS_ORDER_CHUNKED); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ if (h->cupsColorSpace != CUPS_CSPACE_K) -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorSpace=%d", -+ (unsigned)(h->cupsColorSpace)); -+ else -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsColorSpace=%d", -+ CUPS_CSPACE_K); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ if (h->cupsCompression) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsCompression=%d", -+ (unsigned)(h->cupsCompression)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsRowCount) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsRowCount=%d", -+ (unsigned)(h->cupsRowCount)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsRowFeed) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsRowFeed=%d", -+ (unsigned)(h->cupsRowFeed)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsRowStep) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsRowStep=%d", -+ (unsigned)(h->cupsRowStep)); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+#ifdef CUPS_RASTER_SYNCv1 -+ if (h->cupsBorderlessScalingFactor != 1.0f) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsBorderlessScalingFactor=%.4f", -+ h->cupsBorderlessScalingFactor); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ for (i=0; i <= 15; i ++) -+ if (h->cupsInteger[i]) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsInteger%d=%d", -+ i, (unsigned)(h->cupsInteger[i])); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ for (i=0; i <= 15; i ++) -+ if (h->cupsReal[i]) { -+ snprintf(tmpstr, sizeof(tmpstr), "-dcupsReal%d=%.4f", -+ i, h->cupsReal[i]); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ for (i=0; i <= 15; i ++) -+ if (h->cupsString[i][0] != '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-scupsString%d=%s", -+ i, h->cupsString[i]); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsMarkerType[0] != '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-scupsMarkerType=%s", -+ h->cupsMarkerType); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsRenderingIntent[0] != '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-scupsRenderingIntent=%s", -+ h->cupsRenderingIntent); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ if (h->cupsPageSizeName[0] != '\0') { -+ snprintf(tmpstr, sizeof(tmpstr), "-scupsPageSizeName=%s", -+ h->cupsPageSizeName); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+#endif /* CUPS_RASTER_SYNCv1 */ -+} -+ -+static int -+gs_spawn (const char *filename, -+ cups_array_t *gs_args, -+ char **envp, -+ FILE *fp) -+{ -+ char *argument; -+ char buf[BUFSIZ]; -+ char **gsargv; -+ const char* apos; -+ int fds[2]; -+ int i; -+ int n; -+ int numargs; -+ int pid; -+ int status = 1; -+ -+ /* Put Ghostscript command line argument into an array for the "exec()" -+ call */ -+ numargs = cupsArrayCount(gs_args); -+ gsargv = calloc(numargs + 1, sizeof(char *)); -+ for (argument = (char *)cupsArrayFirst(gs_args), i = 0; argument; -+ argument = (char *)cupsArrayNext(gs_args), i++) { -+ gsargv[i] = argument; -+ } -+ gsargv[i] = NULL; -+ -+ /* Debug output: Full Ghostscript command line and environment variables */ -+ fprintf(stderr, "DEBUG: Ghostscript command line:"); -+ for (i = 0; gsargv[i]; i ++) { -+ if ((strchr(gsargv[i],' ')) || (strchr(gsargv[i],'\t'))) -+ apos = "'"; -+ else -+ apos = ""; -+ fprintf(stderr, " %s%s%s", apos, gsargv[i], apos); -+ } -+ fprintf(stderr, "\n"); -+ -+ for (i = 0; envp[i]; i ++) -+ fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]); -+ -+ /* Create a pipe for feeding the job into Ghostscript */ -+ if (pipe(fds)) -+ { -+ fds[0] = -1; -+ fds[1] = -1; -+ fprintf(stderr, "ERROR: Unable to establish pipe for Ghostscript call"); -+ goto out; -+ } -+ -+ /* Set the "close on exec" flag on each end of the pipe... */ -+ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) -+ { -+ close(fds[0]); -+ close(fds[1]); -+ fds[0] = -1; -+ fds[1] = -1; -+ fprintf(stderr, "ERROR: Unable to set \"close on exec\" flag on read end of the pipe for Ghostscript call"); -+ goto out; -+ } -+ if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) -+ { -+ close(fds[0]); -+ close(fds[1]); -+ fprintf(stderr, "ERROR: Unable to set \"close on exec\" flag on write end of the pipe for Ghostscript call"); -+ goto out; -+ } -+ -+ if ((pid = fork()) == 0) -+ { -+ /* Couple pipe with STDIN of Ghostscript process */ -+ if (fds[0] != 0) { -+ close(0); -+ if (fds[0] > 0) -+ dup(fds[0]); -+ else { -+ fprintf(stderr, "ERROR: Unable to couple pipe with STDIN of Ghostscript process"); -+ goto out; -+ } -+ } -+ -+ /* Execute Ghostscript command line ... */ -+ execve(filename, gsargv, envp); -+ perror(filename); -+ goto out; -+ } -+ -+ /* Feed job data into Ghostscript */ -+ while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) { -+ if (write(fds[1], buf, n) != n) { -+ fprintf(stderr, "ERROR: Can't feed job data into Ghostscript"); -+ goto out; -+ } -+ } -+ close (fds[1]); -+ -+ if (waitpid (pid, &status, 0) == -1) { -+ perror ("gs"); -+ goto out; -+ } -+out: -+ free(gsargv); -+ return status; -+} -+ -+static char * -+get_ppd_icc_fallback (ppd_file_t *ppd, char **qualifier) -+{ -+ char full_path[1024]; -+ char *icc_profile = NULL; -+ char qualifer_tmp[1024]; -+ const char *profile_key; -+ ppd_attr_t *attr; -+ -+ /* get profile attr, falling back to CUPS */ -+ profile_key = "APTiogaProfile"; -+ attr = ppdFindAttr(ppd, profile_key, NULL); -+ if (attr == NULL) { -+ profile_key = "cupsICCProfile"; -+ attr = ppdFindAttr(ppd, profile_key, NULL); -+ } -+ -+ /* create a string for a quick comparion */ -+ snprintf(qualifer_tmp, sizeof(qualifer_tmp), -+ "%s.%s.%s", -+ qualifier[0], -+ qualifier[1], -+ qualifier[2]); -+ -+ /* neither */ -+ if (attr == NULL) { -+ fprintf(stderr, "INFO: no profiles specified in PPD\n"); -+ goto out; -+ } -+ -+ /* try to find a profile that matches the qualifier exactly */ -+ for (;attr != NULL; attr = ppdFindNextAttr(ppd, profile_key, NULL)) { -+ fprintf(stderr, "INFO: found profile %s in PPD with qualifier '%s'\n", -+ attr->value, attr->spec); -+ -+ /* invalid entry */ -+ if (attr->spec == NULL || attr->value == NULL) -+ continue; -+ -+ /* expand to a full path if not already specified */ -+ if (attr->value[0] != '/') -+ snprintf(full_path, sizeof(full_path), -+ "%s/profiles/%s", CUPSDATA, attr->value); -+ else -+ strncpy(full_path, attr->value, sizeof(full_path)); -+ -+ /* check the file exists */ -+ if (access(full_path, 0)) { -+ fprintf(stderr, "INFO: found profile %s in PPD that does not exist\n", -+ full_path); -+ continue; -+ } -+ -+ /* matches the qualifier */ -+ if (strcmp(qualifer_tmp, attr->spec) == 0) { -+ icc_profile = strdup(full_path); -+ goto out; -+ } -+ } -+ -+ /* no match */ -+ if (attr == NULL) { -+ fprintf(stderr, "INFO: no profiles in PPD for qualifier '%s'\n", -+ qualifer_tmp); -+ goto out; -+ } -+ -+out: -+ return icc_profile; -+} -+ -+int -+main (int argc, char **argv, char *envp[]) -+{ -+ char buf[BUFSIZ]; -+ char *icc_profile = NULL; -+ char **qualifier = NULL; -+ char *tmp; -+ char tmpstr[1024]; -+ const char *t = NULL; -+ cups_array_t *gs_args = NULL; -+ cups_option_t *options = NULL; -+ FILE *fp = NULL; -+ GsDocType doc_type; -+ gs_page_header h; -+ int fd; -+ int i; -+ int n; -+ int num_options; -+ int status = 1; -+ ppd_file_t *ppd = NULL; -+ -+ if (argc < 6 || argc > 7) { -+ fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n", -+ argv[0]); -+ goto out; -+ } -+ -+ num_options = cupsParseOptions(argv[5], 0, &options); -+ -+ t = getenv("PPD"); -+ if ((ppd = ppdOpenFile(t)) == NULL) { -+ fprintf(stderr, "ERROR: Failed to open PPD: %s", t); -+ goto out; -+ } -+ -+ ppdMarkDefaults (ppd); -+ cupsMarkOptions (ppd, num_options, options); -+ -+ if (argc == 6) { -+ /* stdin */ -+ -+ fd = cupsTempFd(buf,BUFSIZ); -+ if (fd < 0) { -+ fprintf(stderr, "ERROR: Can't create temporary file"); -+ goto out; -+ } -+ /* remove name */ -+ unlink(buf); -+ -+ /* copy stdin to the tmp file */ -+ while ((n = read(0,buf,BUFSIZ)) > 0) { -+ if (write(fd,buf,n) != n) { -+ fprintf(stderr, "ERROR: Can't copy stdin to temporary file"); -+ close(fd); -+ goto out; -+ } -+ } -+ if (lseek(fd,0,SEEK_SET) < 0) { -+ fprintf(stderr, "ERROR: Can't rewind temporary file"); -+ close(fd); -+ goto out; -+ } -+ -+ if ((fp = fdopen(fd,"rb")) == 0) { -+ fprintf(stderr, "ERROR: Can't fdopen temporary file"); -+ close(fd); -+ goto out; -+ } -+ } else { -+ /* argc == 7 filename is specified */ -+ -+ if ((fp = fopen(argv[6],"rb")) == 0) { -+ fprintf(stderr, "ERROR: Can't open input file %s",argv[6]); -+ goto out; -+ } -+ } -+ -+ /* find out file type */ -+ doc_type = parse_doc_type(fp); -+ if (doc_type == GS_DOC_TYPE_UNKNOWN) { -+ fprintf(stderr, "ERROR: Can't detect file type"); -+ goto out; -+ } -+ -+ qualifier = colord_get_qualifier_for_ppd (ppd); -+ if (qualifier != NULL) { -+ const char *env_printer = getenv("PRINTER"); -+ char *device_id; -+ -+ if (env_printer) { -+ device_id = malloc (5 + strlen (env_printer) + 1); -+ if (device_id) { -+ strcpy (device_id, "cups-"); -+ strcpy (device_id + 5, env_printer); -+ fprintf(stderr, "DEBUG: PPD uses qualifier '%s.%s.%s'\n", -+ qualifier[0], qualifier[1], qualifier[2]); -+ icc_profile = colord_get_profile_for_device_id (device_id, -+ (const char**) qualifier); -+ free (device_id); -+ } -+ } -+ -+ /* fall back to the PPD */ -+ if (icc_profile == NULL) -+ icc_profile = get_ppd_icc_fallback (ppd, qualifier); -+ -+ if(icc_profile != NULL) -+ fprintf(stderr, "DEBUG: Using ICC Profile '%s'\n", icc_profile); -+ } -+ -+ /* Ghostscript parameters */ -+ gs_args = cupsArrayNew(NULL, NULL); -+ if (!gs_args) -+ { -+ fprintf(stderr, "ERROR: Unable to allocate memory for Ghostscript arguments array\n"); -+ exit(1); -+ } -+ -+ /* Part of Ghostscript command line which is not dependent on the job and/or -+ the driver */ -+ snprintf(tmpstr, sizeof(tmpstr), "%s/%s", BINDIR, GS); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ cupsArrayAdd(gs_args, strdup("-dQUIET")); -+ /*cupsArrayAdd(gs_args, strdup("-dDEBUG"));*/ -+ cupsArrayAdd(gs_args, strdup("-dPARANOIDSAFER")); -+ cupsArrayAdd(gs_args, strdup("-dNOPAUSE")); -+ cupsArrayAdd(gs_args, strdup("-dBATCH")); -+ if (doc_type == GS_DOC_TYPE_PS) -+ cupsArrayAdd(gs_args, strdup("-dNOMEDIAATTRS")); -+ cupsArrayAdd(gs_args, strdup("-sDEVICE=cups")); -+ cupsArrayAdd(gs_args, strdup("-sstdout=%stderr")); -+ cupsArrayAdd(gs_args, strdup("-sOutputFile=%stdout")); -+ -+ /* setPDF specific options */ -+ if (doc_type == GS_DOC_TYPE_PDF) { -+ cupsRasterInterpretPPD(&h,ppd,num_options,options,0); -+ parse_pdf_header_options(fp, &h); -+ -+ /* fixed other values that pdftopdf handles */ -+ h.MirrorPrint = CUPS_FALSE; -+ h.Orientation = CUPS_ORIENT_0; -+ -+ /* get all the data from the header and pass it to ghostscript */ -+ add_pdf_header_options (&h, gs_args); -+ } -+ -+ /* CUPS font path */ -+ if ((t = getenv("CUPS_FONTPATH")) == NULL) -+ t = CUPS_FONTPATH; -+ snprintf(tmpstr, sizeof(tmpstr), "-I%s", t); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ -+ /* set the device output ICC profile */ -+ if(icc_profile != NULL) { -+ snprintf(tmpstr, sizeof(tmpstr), "-sOutputICCProfile=%s", icc_profile); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ -+ /* Switch to taking PostScript commands on the Ghostscript command line */ -+ cupsArrayAdd(gs_args, strdup("-c")); -+ -+ if ((t = cupsGetOption("profile", num_options, options)) != NULL) { -+ snprintf(tmpstr, sizeof(tmpstr), "<>setpagedevice", t); -+ cupsArrayAdd(gs_args, strdup(tmpstr)); -+ } -+ -+ /* Mark the end of PostScript commands supplied on the Ghostscript command -+ line (with the "-c" option), so that we can supply the input file name */ -+ cupsArrayAdd(gs_args, strdup("-f")); -+ -+ /* Let Ghostscript read from STDIN */ -+ cupsArrayAdd(gs_args, strdup("-_")); -+ -+ /* Execute Ghostscript command line ... */ -+ snprintf(tmpstr, sizeof(tmpstr), "%s/%s", BINDIR, GS); -+ -+ /* call Ghostscript */ -+ rewind(fp); -+ status = gs_spawn (tmpstr, gs_args, envp, fp); -+out: -+ if (fp) -+ fclose(fp); -+ if (qualifier != NULL) { -+ for (i=0; qualifier[i] != NULL; i++) -+ free(qualifier[i]); -+ free(qualifier); -+ } -+ if (gs_args) { -+ while ((tmp = cupsArrayFirst(gs_args)) != NULL) { -+ cupsArrayRemove(gs_args,tmp); -+ free(tmp); -+ } -+ cupsArrayDelete(gs_args); -+ } -+ free(icc_profile); -+ if (ppd) -+ ppdClose(ppd); -+ return status; -+} -diff -up ghostscript-9.01/cups/gstoraster.convs.colord ghostscript-9.01/cups/gstoraster.convs ---- ghostscript-9.01/cups/gstoraster.convs.colord 2011-03-10 13:48:17.605513190 +0000 -+++ ghostscript-9.01/cups/gstoraster.convs 2011-03-10 13:48:17.605513190 +0000 -@@ -0,0 +1,30 @@ -+# Copyright (c) 2008, Till Kamppeter -+# Copyright (c) 2011, Richard Hughes -+# -+# Permission is hereby granted, free of charge, to any person obtaining -+# a copy of this software and associated documentation files (the -+# "Software"), to deal in the Software without restriction, including -+# without limitation the rights to use, copy, modify, merge, publish, -+# distribute, sublicense, and/or sell copies of the Software, and to -+# permit persons to whom the Software is furnished to do so, subject to -+# the following conditions: -+# -+# The above copyright notice and this permission notice shall be included -+# in all copies or substantial portions of the Software. -+# -+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+# -+# MIT Open Source License - http://www.opensource.org/ -+# -+# $Id: pdftoraster.convs 8803 2008-06-24 14:16:29Z till $ -+# -+# CUPS file conversion rules for gstoraster filter -+ -+application/vnd.cups-pdf application/vnd.cups-raster 66 gstoraster -+application/vnd.cups-postscript application/vnd.cups-raster 100 gstoraster -diff -up ghostscript-9.01/Makefile.in.colord ghostscript-9.01/Makefile.in ---- ghostscript-9.01/Makefile.in.colord 2011-02-02 14:12:15.000000000 +0000 -+++ ghostscript-9.01/Makefile.in 2011-03-10 13:48:17.607513397 +0000 -@@ -140,7 +140,7 @@ GENOPT= - # -DHAVE_SETLOCALE - # call setlocale(LC_CTYPE) when running as a standalone app - --CAPOPT= @HAVE_MKSTEMP@ @HAVE_HYPOT@ @HAVE_FILE64@ @HAVE_MKSTEMP64@ @HAVE_FONTCONFIG@ @HAVE_LIBIDN@ @HAVE_SETLOCALE@ -+CAPOPT= @HAVE_MKSTEMP@ @HAVE_HYPOT@ @HAVE_FILE64@ @HAVE_MKSTEMP64@ @HAVE_FONTCONFIG@ @HAVE_LIBIDN@ @HAVE_SETLOCALE@ @HAVE_DBUS@ - - # Define the name of the executable file. - -@@ -339,6 +339,10 @@ XCFLAGS=@DYNAMIC_FLAGS@ - FONTCONFIG_CFLAGS=@FONTCONFIG_CFLAGS@ - FONTCONFIG_LIBS=@FONTCONFIG_LIBS@ - -+# DBus flags, used by cups.mak -+DBUS_CFLAGS=@DBUS_CFLAGS@ -+DBUS_LIBS=@DBUS_LIBS@ -+ - # defines from autoconf; note that we don't use these at present. - ACDEFS=@DEFS@ - diff --git a/ghostscript-cups-filters.patch b/ghostscript-cups-filters.patch index ea6565d..0b54ec8 100644 --- a/ghostscript-cups-filters.patch +++ b/ghostscript-cups-filters.patch @@ -1,17 +1,16 @@ -diff -up ghostscript-8.70/cups/cups.mak.cups-filters ghostscript-8.70/cups/cups.mak ---- ghostscript-8.70/cups/cups.mak.cups-filters 2009-10-15 12:42:27.531402610 +0100 -+++ ghostscript-8.70/cups/cups.mak 2009-10-15 12:44:14.835402533 +0100 -@@ -63,10 +63,10 @@ install-cups: cups - $(INSTALL_PROGRAM) $(PDFTORASTER_XE) $(DESTDIR)$(CUPSSERVERBIN)/filter; \ +diff -up ghostscript-9.02/cups/cups.mak.cups-filters ghostscript-9.02/cups/cups.mak +--- ghostscript-9.02/cups/cups.mak.cups-filters 2011-02-28 22:31:28.000000000 +0000 ++++ ghostscript-9.02/cups/cups.mak 2011-04-04 12:39:23.691844891 +0100 +@@ -56,10 +56,8 @@ install-cups: cups + $(INSTALL_PROGRAM) $(GSTORASTER_XE) $(DESTDIR)$(CUPSSERVERBIN)/filter; \ fi $(INSTALL_PROGRAM) cups/pstopxl $(DESTDIR)$(CUPSSERVERBIN)/filter - -mkdir -p $(DESTDIR)$(CUPSSERVERROOT) -- $(INSTALL_DATA) cups/pstoraster.convs $(DESTDIR)$(CUPSSERVERROOT) +- if [ "$(CUPSPDFTORASTER)" = "1" ]; then \ +- $(INSTALL_DATA) cups/gstoraster.convs $(DESTDIR)$(CUPSSERVERROOT); \ +- fi + -mkdir -p $(DESTDIR)$(CUPSDATA)/mime -+ $(INSTALL_DATA) cups/pstoraster.convs $(DESTDIR)$(CUPSDATA)/mime - if [ "$(CUPSPDFTORASTER)" = "1" ]; then \ -- $(INSTALL_DATA) cups/pdftoraster.convs $(DESTDIR)$(CUPSSERVERROOT); \ -+ $(INSTALL_DATA) cups/pdftoraster.convs $(DESTDIR)$(CUPSDATA)/mime; \ - fi ++ $(INSTALL_DATA) cups/gstoraster.convs $(DESTDIR)$(CUPSDATA)/mime -mkdir -p $(DESTDIR)$(CUPSDATA)/model $(INSTALL_DATA) cups/pxlcolor.ppd $(DESTDIR)$(CUPSDATA)/model + $(INSTALL_DATA) cups/pxlmono.ppd $(DESTDIR)$(CUPSDATA)/model diff --git a/ghostscript-gdevcups-debug-uninit.patch b/ghostscript-gdevcups-debug-uninit.patch index 967050b..321f8fa 100644 --- a/ghostscript-gdevcups-debug-uninit.patch +++ b/ghostscript-gdevcups-debug-uninit.patch @@ -1,17 +1,11 @@ -diff -up ghostscript-9.00/cups/gdevcups.c.gdevcups-debug-uninit ghostscript-9.00/cups/gdevcups.c ---- ghostscript-9.00/cups/gdevcups.c.gdevcups-debug-uninit 2010-08-12 19:10:47.000000000 +0100 -+++ ghostscript-9.00/cups/gdevcups.c 2010-10-14 17:39:39.834994296 +0100 -@@ -807,9 +807,10 @@ cups_get_matrix(gx_device *pdev, /* I - +diff -up ghostscript-9.02/cups/gdevcups.c.gdevcups-debug-uninit ghostscript-9.02/cups/gdevcups.c +--- ghostscript-9.02/cups/gdevcups.c.gdevcups-debug-uninit 2011-03-07 15:40:13.000000000 +0000 ++++ ghostscript-9.02/cups/gdevcups.c 2011-04-04 12:40:48.995443449 +0100 +@@ -815,6 +815,7 @@ cups_get_matrix(gx_device *pdev, /* I - dprintf4("DEBUG2: PageSize = [ %d %d ], HWResolution = [ %d %d ]\n", cups->header.PageSize[0], cups->header.PageSize[1], cups->header.HWResolution[0], cups->header.HWResolution[1]); -- dprintf4("DEBUG2: HWMargins = [ %.3f %.3f %.3f %.3f ]\n", -- pdev->HWMargins[0], pdev->HWMargins[1], pdev->HWMargins[2], -- pdev->HWMargins[3]); + if (size_set) -+ dprintf4("DEBUG2: HWMargins = [ %.3f %.3f %.3f %.3f ]\n", -+ pdev->HWMargins[0], pdev->HWMargins[1], pdev->HWMargins[2], -+ pdev->HWMargins[3]); - dprintf6("DEBUG2: matrix = [ %.3f %.3f %.3f %.3f %.3f %.3f ]\n", - pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty); - #endif /* DEBUG */ + dprintf4("DEBUG2: HWMargins = [ %.3f %.3f %.3f %.3f ]\n", + pdev->HWMargins[0], pdev->HWMargins[1], pdev->HWMargins[2], + pdev->HWMargins[3]); diff --git a/ghostscript.spec b/ghostscript.spec index 76c7c70..ca669c8 100644 --- a/ghostscript.spec +++ b/ghostscript.spec @@ -1,11 +1,11 @@ -%define gs_ver 9.01 -%define gs_dot_ver 9.01 +%define gs_ver 9.02 +%define gs_dot_ver 9.02 %{expand: %%define build_with_freetype %{?_with_freetype:1}%{!?_with_freetype:0}} Summary: A PostScript interpreter and renderer Name: ghostscript Version: %{gs_ver} -Release: 3%{?dist} +Release: 1%{?dist} # Included CMap data is Redistributable, no modification permitted, # see http://bugzilla.redhat.com/487510 @@ -29,7 +29,6 @@ Patch21: ghostscript-jbig2-image-refcount.patch Patch27: ghostscript-Fontmap.local.patch Patch28: ghostscript-iccprofiles-initdir.patch Patch29: ghostscript-gdevcups-debug-uninit.patch -Patch30: ghostscript-colord.patch Requires: urw-fonts >= 1.1, ghostscript-fonts Requires: poppler-data @@ -151,9 +150,6 @@ rm -rf libpng zlib jpeg jasper # gdevcups: don't use uninitialized variables in debugging output. %patch29 -p1 -b .gdevcups-debug-uninit -# colord: use colord to get the correct device profile -%patch30 -p1 -b .colord - # Convert manual pages to UTF-8 from8859_1() { iconv -f iso-8859-1 -t utf-8 < "$1" > "${1}_" @@ -346,6 +342,9 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/libgs.so %changelog +* Mon Apr 4 2011 Tim Waugh 9.02-1 +- 9.02. + * Thu Mar 10 2011 Tim Waugh 9.01-3 - colord support: prefix printer name with "cups-" to get device ID. diff --git a/sources b/sources index 3446d52..004a91b 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ 2fbae60417d42779f6488ab897dcaaf6 acro5-cmaps-2001.tar.gz dfc93dd2aaaf2b86d2fd55f654c13261 adobe-cmaps-200406.tar.gz -9824d6a21ad8b4a831f67601959f1181 ghostscript-9.01.tar.bz2 +f67151444bd56a7904579fc75a083dd6 ghostscript-9.02.tar.bz2