--- /dev/null
+# $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
--- /dev/null
+/* $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}
+};