[libgxps] tools: Add xpstops tool



commit 8ca6d60d9904b3ab986974deb9055655db553cae
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Sun Oct 30 12:37:38 2011 +0100

    tools: Add xpstops tool

 configure.ac              |    8 ++
 tools/Makefile.am         |   24 +++++-
 tools/gxps-ps-converter.c |  204 +++++++++++++++++++++++++++++++++++++++++++++
 tools/gxps-ps-converter.h |   41 +++++++++
 4 files changed, 276 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index ce222be..7dd5076 100644
--- a/configure.ac
+++ b/configure.ac
@@ -175,6 +175,14 @@ AM_CONDITIONAL(HAVE_CAIRO_PDF, test x$have_cairo_pdf = xyes)
 AC_SUBST(CAIRO_PDF_CFLAGS)
 AC_SUBST(CAIRO_PDF_LIBS)
 
+dnl Cairo PostScript
+PKG_CHECK_MODULES(CAIRO_PS, cairo-ps, [have_cairo_ps="yes"], [have_cairo_ps="no"])
+
+AM_CONDITIONAL(HAVE_CAIRO_PS, test x$have_cairo_ps = xyes)
+
+AC_SUBST(CAIRO_PS_CFLAGS)
+AC_SUBST(CAIRO_PS_LIBS)
+
 dnl gtk-doc
 GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
 
diff --git a/tools/Makefile.am b/tools/Makefile.am
index ffcab7a..50a201a 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -77,4 +77,26 @@ xpstopdf_CFLAGS = \
 xpstopdf_LDADD = \
 	libgxpstools.la		\
 	$(CAIRO_PDF_LIBS)
-endif # HAVE_CAIRO_PDF
\ No newline at end of file
+endif # HAVE_CAIRO_PDF
+
+if HAVE_CAIRO_PS
+bin_PROGRAMS += xpstops
+
+xpstops_SOURCES = \
+	gxps-converter-main.c	\
+	gxps-ps-converter.c	\
+	gxps-ps-converter.h
+
+xpstops_CPPFLAGS = \
+	$(tools_cppflags)				\
+	-DCONVERTER_TYPE=GXPS_TYPE_PS_CONVERTER	\
+	-DCONVERTER_HEADER=gxps-ps-converter.h
+
+xpstops_CFLAGS = \
+	$(tools_cflags)		\
+	$(CAIRO_PS_CFLAGS)
+
+xpstops_LDADD = \
+	libgxpstools.la		\
+	$(CAIRO_PS_LIBS)
+endif # HAVE_CAIRO_PS
\ No newline at end of file
diff --git a/tools/gxps-ps-converter.c b/tools/gxps-ps-converter.c
new file mode 100644
index 0000000..698a8c6
--- /dev/null
+++ b/tools/gxps-ps-converter.c
@@ -0,0 +1,204 @@
+/* GXPSPdfConverter
+ *
+ * Copyright (C) 2011  Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <config.h>
+
+#include "gxps-ps-converter.h"
+#include <libgxps/gxps.h>
+#include <cairo-ps.h>
+#include <string.h>
+
+struct _GXPSPsConverter {
+	GXPSPrintConverter parent;
+
+        cairo_ps_level_t level;
+        guint            eps    : 1;
+        guint            duplex : 1;
+};
+
+struct _GXPSPsConverterClass {
+	GXPSPrintConverterClass parent_class;
+};
+
+G_DEFINE_TYPE (GXPSPsConverter, gxps_ps_converter, GXPS_TYPE_PRINT_CONVERTER)
+
+typedef struct _GXPSPaperSize {
+        const gchar *name;
+        guint width;
+        guint height;
+} GXPSPaperSize;
+
+static const GXPSPaperSize paper_sizes[] =
+{
+        { "match",       0,    0 },
+        { "A0",       2384, 3371 },
+        { "A1",       1685, 2384 },
+        { "A2",       1190, 1684 },
+        { "A3",        842, 1190 },
+        { "A4",        595,  842 },
+        { "A5",        420,  595 },
+        { "B4",        729, 1032 },
+        { "B5",        516,  729 },
+        { "Letter",    612,  792 },
+        { "Tabloid",   792, 1224 },
+        { "Ledger",   1224,  792 },
+        { "Legal",     612, 1008 },
+        { "Statement", 396,  612 },
+        { "Executive", 540,  720 },
+        { "Folio",     612,  936 },
+        { "Quarto",    610,  780 },
+        { "10x14",     720, 1008 },
+};
+
+static gboolean level2 = FALSE;
+static gboolean level3 = FALSE;
+static gboolean eps = FALSE;
+static gboolean duplex = FALSE;
+static gchar *paper = NULL;
+
+static const GOptionEntry options[] =
+{
+        { "level2", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &level2, "generate Level 2 PostScript", NULL },
+        { "level3", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &level3, "generate Level 3 PostScript", NULL },
+        { "eps", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &eps, "generate Encapsulated PostScript", NULL },
+        { "paper", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &paper, "paper size (match, letter, legal, A4, A3, ...)", "PAPER" },
+        { "duplex", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &duplex, "enable duplex printing", NULL },
+        { NULL }
+};
+
+static gboolean
+gxps_ps_converter_init_with_args (GXPSConverter *converter,
+                                  gint          *argc,
+                                  gchar       ***argv,
+                                  GList        **option_groups)
+{
+        GXPSPsConverter    *ps_converter = GXPS_PS_CONVERTER (converter);
+        GXPSPrintConverter *print_converter = GXPS_PRINT_CONVERTER (converter);
+        GOptionContext     *context;
+        GOptionGroup       *option_group;
+        guint               i;
+        GError             *error = NULL;
+
+        option_group = g_option_group_new ("postscrit", "PostScript Options", "Show PostScript Options", NULL, NULL);
+        g_option_group_add_entries (option_group, options);
+
+        *option_groups = g_list_prepend (*option_groups, option_group);
+
+        if (GXPS_CONVERTER_CLASS (gxps_ps_converter_parent_class)->init_with_args) {
+                if (!GXPS_CONVERTER_CLASS (gxps_ps_converter_parent_class)->init_with_args (converter, argc, argv, option_groups))
+                        return FALSE;
+        }
+
+        context = g_option_context_new (NULL);
+        g_option_context_set_ignore_unknown_options (context, TRUE);
+        g_option_context_set_help_enabled (context, FALSE);
+        g_option_context_add_main_entries (context, options, NULL);
+        if (!g_option_context_parse (context, argc, argv, &error)) {
+                g_printerr ("Error parsing arguments: %s\n", error->message);
+                g_error_free (error);
+                g_option_context_free (context);
+
+                return FALSE;
+        }
+        g_option_context_free (context);
+
+        ps_converter->level = (level2 && !level3) ? CAIRO_PS_LEVEL_2 : CAIRO_PS_LEVEL_3;
+        ps_converter->eps = eps;
+        ps_converter->duplex = duplex;
+        for (i = 0; paper && i < G_N_ELEMENTS (paper_sizes); i++) {
+                if (g_ascii_strcasecmp (paper, paper_sizes[i].name) == 0) {
+                        print_converter->paper_width = paper_sizes[i].width;
+                        print_converter->paper_height = paper_sizes[i].height;
+                        break;
+                }
+        }
+
+        g_print ("DBG: paper size: %s %d, %d\n", paper, print_converter->paper_width, print_converter->paper_height);
+
+        return TRUE;
+}
+
+static const gchar *
+gxps_ps_converter_get_extension (GXPSConverter *converter)
+{
+        return "ps";
+}
+
+static void
+gxps_ps_converter_begin_document (GXPSConverter *converter,
+                                  const gchar   *output_filename,
+                                  GXPSPage      *first_page)
+{
+        GXPSPsConverter    *ps_converter = GXPS_PS_CONVERTER (converter);
+        GXPSPrintConverter *print_converter = GXPS_PRINT_CONVERTER (converter);
+        gdouble             width, height;
+
+        GXPS_CONVERTER_CLASS (gxps_ps_converter_parent_class)->begin_document (converter, output_filename, first_page);
+
+        _gxps_converter_print_get_output_size (print_converter, first_page, &width, &height);
+        converter->surface = cairo_ps_surface_create (print_converter->filename, width, height);
+        if (ps_converter->level == CAIRO_PS_LEVEL_2)
+                cairo_ps_surface_restrict_to_level (converter->surface, ps_converter->level);
+        if (ps_converter->eps)
+                cairo_ps_surface_set_eps (converter->surface, 1);
+        if (ps_converter->duplex) {
+                cairo_ps_surface_dsc_comment (converter->surface, "%%Requirements: duplex");
+                cairo_ps_surface_dsc_begin_setup (converter->surface);
+                cairo_ps_surface_dsc_comment (converter->surface, "%%IncludeFeature: *Duplex DuplexNoTumble");
+        }
+        cairo_ps_surface_dsc_begin_page_setup (converter->surface);
+}
+
+static cairo_t *
+gxps_ps_converter_begin_page (GXPSConverter *converter,
+                               GXPSPage      *page,
+                               guint          n_page)
+{
+        GXPSPrintConverter *print_converter = GXPS_PRINT_CONVERTER (converter);
+        gdouble             width, height;
+
+        g_return_val_if_fail (converter->surface != NULL, NULL);
+
+        _gxps_converter_print_get_output_size (print_converter, page, &width, &height);
+        if (width > height) {
+                cairo_ps_surface_dsc_comment (converter->surface, "%%PageOrientation: Landscape");
+                cairo_ps_surface_set_size (converter->surface, height, width);
+        } else {
+                cairo_ps_surface_dsc_comment (converter->surface, "%%PageOrientation: Portrait");
+                cairo_ps_surface_set_size (converter->surface, width, height);
+        }
+
+        return GXPS_CONVERTER_CLASS (gxps_ps_converter_parent_class)->begin_page (converter, page, n_page);
+}
+
+static void
+gxps_ps_converter_init (GXPSPsConverter *converter)
+{
+}
+
+static void
+gxps_ps_converter_class_init (GXPSPsConverterClass *klass)
+{
+        GXPSConverterClass *converter_class = GXPS_CONVERTER_CLASS (klass);
+
+        converter_class->init_with_args = gxps_ps_converter_init_with_args;
+        converter_class->get_extension = gxps_ps_converter_get_extension;
+        converter_class->begin_document = gxps_ps_converter_begin_document;
+        converter_class->begin_page = gxps_ps_converter_begin_page;
+}
diff --git a/tools/gxps-ps-converter.h b/tools/gxps-ps-converter.h
new file mode 100644
index 0000000..40137a1
--- /dev/null
+++ b/tools/gxps-ps-converter.h
@@ -0,0 +1,41 @@
+/* GXPSPsConverter
+ *
+ * Copyright (C) 2011  Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GXPS_PS_CONVERTER_H__
+#define __GXPS_PS_CONVERTER_H__
+
+#include "gxps-print-converter.h"
+
+G_BEGIN_DECLS
+
+#define GXPS_TYPE_PS_CONVERTER           (gxps_ps_converter_get_type ())
+#define GXPS_PS_CONVERTER(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GXPS_TYPE_PS_CONVERTER, GXPSPsConverter))
+#define GXPS_PS_CONVERTER_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GXPS_TYPE_PS_CONVERTER, GXPSPsConverterClass))
+#define GXPS_IS_PS_CONVERTER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GXPS_TYPE_PS_CONVERTER))
+#define GXPS_IS_PS_CONVERTER_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GXPS_TYPE_PS_CONVERTER))
+#define GXPS_PS_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GXPS_TYPE_PS_CONVERTER, GXPSPsConverterClass))
+
+typedef struct _GXPSPsConverter        GXPSPsConverter;
+typedef struct _GXPSPsConverterClass   GXPSPsConverterClass;
+
+GType gxps_ps_converter_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GXPS_PS_CONVERTER_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]