]> granicus.if.org Git - graphviz/commitdiff
Add a gs plugin that uses libgs (ghostscript) to interpret PostScript shapes and...
authorellson <devnull@localhost>
Sun, 12 Oct 2008 21:40:32 +0000 (21:40 +0000)
committerellson <devnull@localhost>
Sun, 12 Oct 2008 21:40:32 +0000 (21:40 +0000)
plugin/gs/Makefile.am [new file with mode: 0644]
plugin/gs/gvloadimage_gs.c [new file with mode: 0644]
plugin/gs/gvplugin_gs.c [new file with mode: 0644]

diff --git a/plugin/gs/Makefile.am b/plugin/gs/Makefile.am
new file mode 100644 (file)
index 0000000..3601fa1
--- /dev/null
@@ -0,0 +1,41 @@
+# $Id$ $Revision$
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = \
+       -I$(top_srcdir) \
+       -I$(top_srcdir)/lib/common \
+       -I$(top_srcdir)/lib/pathplan \
+       -I$(top_srcdir)/lib/gvc \
+       -I$(top_srcdir)/lib/graph \
+       -I$(top_srcdir)/lib/cdt \
+       $(GS_CFLAGS) $(PANGOCAIRO_CFLAGS)
+
+if WITH_GS
+if WITH_PANGOCAIRO
+noinst_LTLIBRARIES = libgvplugin_gs_C.la
+if WITH_WIN32
+lib_LTLIBRARIES = libgvplugin_gs.la
+else
+pkglib_LTLIBRARIES = libgvplugin_gs.la
+endif
+endif
+endif
+
+libgvplugin_gs_C_la_SOURCES = \
+       gvplugin_gs.c \
+       gvloadimage_gs.c
+
+libgvplugin_gs_la_LDFLAGS = -version-info $(GVPLUGIN_VERSION_INFO)
+libgvplugin_gs_la_SOURCES = $(libgvplugin_gs_C_la_SOURCES)
+libgvplugin_gs_la_LIBADD = \
+       $(top_builddir)/lib/gvc/libgvc.la $(PANGOCAIRO_LIBS) $(GS_LIBS)
+
+if WITH_WIN32
+libgvplugin_gs_la_LDFLAGS += -no-undefined
+endif
+
+if WITH_DARWIN9
+libgvplugin_gs_la_LDFLAGS += -Wl,-exported_symbol,_gvplugin_gs_LTX_library
+endif
+
+EXTRA_DIST = Makefile.old
diff --git a/plugin/gs/gvloadimage_gs.c b/plugin/gs/gvloadimage_gs.c
new file mode 100644 (file)
index 0000000..f5ec52c
--- /dev/null
@@ -0,0 +1,176 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/stat.h>
+
+#include "gvplugin_loadimage.h"
+
+#ifdef HAVE_GS
+#ifdef HAVE_PANGOCAIRO
+#include <ghostscript/iapi.h>
+#include <cairo/cairo.h>
+#include <cairo/cairo-ps.h>
+
+#ifdef WIN32
+#define NUL_FILE "nul"
+#else
+#define NUL_FILE "/dev/null"
+#endif
+
+typedef enum {
+    FORMAT_PS_CAIRO, FORMAT_EPS_CAIRO,
+} format_type;
+
+typedef struct gs_s {
+    cairo_t* cr;
+    cairo_surface_t* surface;
+    cairo_pattern_t* pattern;
+} gs_t;
+
+static void gvloadimage_gs_free(usershape_t *us)
+{
+    gs_t *gs = (gs_t*)us->data;
+
+    cairo_pattern_destroy(gs->pattern);
+    cairo_surface_destroy(gs->surface);
+    cairo_destroy(gs->cr);
+    free(gs);
+}
+
+static void gs_error(const char *str, int rc)
+{
+    fprintf(stderr, "gs error %s %d\n", str, rc);
+}
+
+static int gs_writer(void *caller_handle, const char *str, int len)
+{
+    GVJ_t *job = (GVJ_t*)caller_handle;
+
+    if (job->common->verbose)
+       return fwrite(str, 1, len, stderr);
+    return len;
+}
+
+static cairo_pattern_t* gvloadimage_gs_load(GVJ_t * job, usershape_t *us)
+{
+    gs_t *gs = NULL;
+    void *instance;
+    int rc, exit_code;
+    char width_height[20], dpi[10], cairo_context[30];
+    char *gs_args[] = {
+       "-dQUIET",
+       "-dNOPAUSE",
+       "-sDEVICE=cairo",
+       cairo_context,
+       width_height,
+       dpi,
+    };
+#define GS_ARGC sizeof(gs_args)/sizeof(gs_args[0])
+
+    assert(job);
+    assert(us);
+    assert(us->name);
+
+    if (us->data) {
+        if (us->datafree == gvloadimage_gs_free && ((gs_t*)(us->data))->cr == (cairo_t *)job->context)
+           gs = (gs_t*)(us->data); /* use cached data */
+       else {
+           us->datafree(us);        /* free incompatible cache data */
+           us->data = NULL;
+       }
+    }
+    if (!gs) {
+       cairo_t *cr; /* temp cr for gs */
+
+       if (!gvusershape_file_access(us))
+           return NULL;
+
+       gs = (gs_t *)malloc(sizeof(gs_t));
+       if (!gs)
+           return NULL;
+
+       gs->cr = (cairo_t *)job->context;
+       gs->surface = cairo_surface_create_similar( 
+                       cairo_get_target(gs->cr),
+                       CAIRO_CONTENT_COLOR_ALPHA,
+                       us->x + us->w,
+                       us->y + us->h);
+       gs->pattern = cairo_pattern_create_for_surface (gs->surface);
+
+       rc = gsapi_new_instance(&instance, (void*)job);
+       if (rc) { gs_error("gsapi_new_instance", rc); return NULL; }
+       rc = gsapi_set_stdio(instance, NULL, gs_writer, gs_writer);
+       if (rc) { gs_error("gsapi_set_stdio", rc); return NULL; }
+       sprintf(width_height, "-g%dx%d", us->x + us->w, us->y + us->h);
+       sprintf(dpi, "-r%d", us->dpi);
+       cr = cairo_create(gs->surface);
+       sprintf(cairo_context, "-sCairoContext=%p", cr);
+       rc = gsapi_init_with_args(instance, GS_ARGC, gs_args);
+       cairo_destroy(cr);
+       if (rc) { gs_error("gsapi_init_with_args", rc); return NULL; }
+
+       rc = gsapi_run_file(instance, us->name, 0, &exit_code); 
+       if (rc) { gs_error("gsapi_run_file", rc); return NULL; }
+
+       rc = gsapi_exit(instance);
+       if (rc) { gs_error("gsapi_exit", rc); return NULL; }
+
+       gsapi_delete_instance(instance);
+
+       us->data = (void*)gs;
+       us->datafree = gvloadimage_gs_free;
+
+        gvusershape_file_release(us);
+    }
+    return gs->pattern;
+}
+
+static void gvloadimage_gs_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
+{
+    cairo_t *cr = (cairo_t *) job->context; /* target context */
+    cairo_pattern_t *pattern = gvloadimage_gs_load(job, us);
+
+    if (pattern) {
+        cairo_save(cr);
+       cairo_translate(cr, b.LL.x - us->x, -b.UR.y);
+       cairo_scale(cr, (b.UR.x - b.LL.x) / us->w, (b.UR.y - b.LL.y) / us->h);
+        cairo_set_source(cr, pattern);
+       cairo_paint(cr);
+        cairo_restore(cr);
+    }
+}
+
+static gvloadimage_engine_t engine_cairo = {
+    gvloadimage_gs_cairo
+};
+#endif
+#endif
+
+gvplugin_installed_t gvloadimage_gs_types[] = {
+#ifdef HAVE_GS
+#ifdef HAVE_PANGOCAIRO
+    {FORMAT_PS_CAIRO,   "ps:cairo", 1, &engine_cairo, NULL},
+    {FORMAT_EPS_CAIRO, "eps:cairo", 1, &engine_cairo, NULL},
+#endif
+#endif
+    {0, NULL, 0, NULL, NULL}
+};
diff --git a/plugin/gs/gvplugin_gs.c b/plugin/gs/gvplugin_gs.c
new file mode 100644 (file)
index 0000000..3727e65
--- /dev/null
@@ -0,0 +1,26 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#include "gvplugin.h"
+
+extern gvplugin_installed_t gvloadimage_gs_types;
+
+static gvplugin_api_t apis[] = {
+    {API_loadimage, &gvloadimage_gs_types},
+    {(api_t)0, 0},
+};
+
+gvplugin_library_t gvplugin_gs_LTX_library = { "gs", apis };