]> granicus.if.org Git - graphviz/commitdiff
- new "loadimage" plugin api
authorellson <devnull@localhost>
Sat, 17 Jun 2006 14:41:25 +0000 (14:41 +0000)
committerellson <devnull@localhost>
Sat, 17 Jun 2006 14:41:25 +0000 (14:41 +0000)
- new loadimage plugins for gd and cairo, both support png2ps

15 files changed:
lib/gvc/Makefile.am
lib/gvc/gvcjob.h
lib/gvc/gvcproc.h
lib/gvc/gvloadimage.c [new file with mode: 0644]
lib/gvc/gvplugin.h
lib/gvc/gvplugin_loadimage.h [new file with mode: 0644]
lib/gvc/gvrender.c
plugin/core/gvrender_core_map.c
plugin/core/gvrender_core_ps.c
plugin/core/gvrender_core_svg.c
plugin/gd/gvloadimage_gd.c [new file with mode: 0644]
plugin/gd/gvrender_gd.c
plugin/pango/gvloadimage_pango.c [new file with mode: 0644]
plugin/pango/gvplugin_pango.c
plugin/pango/gvrender_pango.c

index d9b91c8157183e96f027419a84790f0ede082189..1f163cfdd1772a95fb2ef66e6791b2fb9f794b88 100644 (file)
@@ -16,15 +16,14 @@ LIBS = $(LIBLTDL) $(SOCKET_LIBS)
 
 pkginclude_HEADERS = gvc.h gvcext.h gvplugin.h gvcjob.h gvcint.h \
        gvcommon.h gvplugin_render.h gvplugin_layout.h \
-       gvplugin_textlayout.h gvplugin_device.h \
-       dot_builtins.c \
-       demand_loading.c no_demand_loading.c
+       gvplugin_textlayout.h gvplugin_device.h gvplugin_loadimage.h \
+       dot_builtins.c demand_loading.c no_demand_loading.c
 noinst_HEADERS = gvcproc.h
 noinst_LTLIBRARIES = libgvc_C.la
 pkglib_LTLIBRARIES = libgvc.la libgvc_builtins.la
 pkgconfig_DATA = libgvc.pc libgvc_builtins.pc
 
-libgvc_C_la_SOURCES = gvrender.c gvlayout.c gvdevice.c gvcontext.c gvjobs.c \
+libgvc_C_la_SOURCES = gvrender.c gvlayout.c gvdevice.c gvloadimage.c gvcontext.c gvjobs.c \
        gvevent.c gvplugin.c gvconfig.c gvtextlayout.c gvusershape.c gvc.c
 libgvc_C_la_LIBADD = $(top_builddir)/lib/common/libcommon_C.la
 
index 13279be7ab7eafa2e1bcf12cd68bbe3207e20162..f700bc01e7044e2207478b907e4ecd92d8162051 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
     typedef struct gvrender_engine_s gvrender_engine_t;
     typedef struct gvlayout_engine_s gvlayout_engine_t;
     typedef struct gvtextlayout_engine_s gvtextlayout_engine_t;
+    typedef struct gvloadimage_engine_s gvloadimage_engine_t;
 
     typedef enum { PEN_NONE, PEN_DASHED, PEN_DOTTED, PEN_SOLID } pen_type;
     typedef enum { FILL_NONE, FILL_SOLID } fill_type;
@@ -77,6 +78,7 @@ extern "C" {
        int sz_knowncolors;
        color_type_t color_type;
        char *device;
+       char *loadimage_target;
     } gvrender_features_t;
 
     typedef struct {
@@ -99,6 +101,12 @@ extern "C" {
         char *type;
     } gvplugin_active_render_t;
 
+    typedef struct gvplugin_active_loadimage_t {
+       gvloadimage_engine_t *engine;
+       int id;
+       char *type;
+    } gvplugin_active_loadimage_t;
+
     typedef struct gv_argvlist_s {
        char **argv;
        int argc;
@@ -197,6 +205,7 @@ extern "C" {
 
        gvplugin_active_render_t render;
        gvplugin_active_device_t device;
+       gvplugin_active_loadimage_t loadimage;
        gvdevice_callbacks_t *callbacks;
 
        void *surface;          /* gd or cairo surface */
index 99342fb7a24bd6917bd1501eb31d9a3e22809a95..d507bb10ff3569a55252fd37d6a30b42d56d4242 100644 (file)
@@ -59,6 +59,9 @@ extern "C" {
     extern int gvtextlayout_select(GVC_t * gvc);
     extern bool gvtextlayout(GVC_t *gvc, textpara_t *para, char **fontpath);
 
+/* loadimage */
+    extern void gvloadimage(GVJ_t *job, usershape_t *us, boxf b, bool filled, char *target);
+    
 /* usershapes */
     extern point gvusershape_size(graph_t *g, char *name);
     extern usershape_t *gvusershape_find(char *name);
diff --git a/lib/gvc/gvloadimage.c b/lib/gvc/gvloadimage.c
new file mode 100644 (file)
index 0000000..79746e2
--- /dev/null
@@ -0,0 +1,79 @@
+/* $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             *
+**********************************************************/
+
+/*
+ *  graphics code generator wrapper
+ *
+ *  This library forms the socket for run-time loadable loadimage plugins.  
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "const.h"
+#include "gvplugin_loadimage.h"
+#include "gvcint.h"
+#include "gvcproc.h"
+
+int gvloadimage_select(GVJ_t * job, char *str)
+{
+    gvplugin_available_t *plugin;
+    gvplugin_installed_t *typeptr;
+
+    plugin = gvplugin_load(job->gvc, API_loadimage, str);
+    if (plugin) {
+        typeptr = plugin->typeptr;
+        job->loadimage.engine = (gvloadimage_engine_t *) (typeptr->engine);
+        job->loadimage.id = typeptr->id;
+        return GVRENDER_PLUGIN;
+    }
+    return NO_SUPPORT;
+}
+
+void gvloadimage(GVJ_t * job, usershape_t *us, boxf b, bool filled, char *target)
+{
+    gvloadimage_engine_t *gvli;
+    char type[SMALLBUF];
+
+    switch (us->type) {
+    case FT_PNG:
+       strcpy(type, "png");
+       break;
+    case FT_JPEG:
+       strcpy(type, "jpeg");
+       break;
+    case FT_GIF:
+       strcpy(type, "gif");
+       break;
+    default:
+       strcpy(type, "");
+       break;
+    }
+    strcat(type, "2");
+    strcat(type, target);
+
+    if (type)
+        gvloadimage_select(job, type);
+
+    if ((gvli = job->loadimage.engine)) {
+       if (gvli->loadimage) {
+           gvli->loadimage(job, us, b, filled);
+       }
+    }
+}
index a579900f819b9f53d1b073e177da9f4c9b98714d..00097bcc3d4faa5a3f888c7f169a2d7b7976de74 100644 (file)
@@ -38,7 +38,7 @@ extern "C" {
  * The enumerated type is defined here.  The apis array is
  * inititialized in gvplugin.c by redefining ELEM and reinvoking APIS.
  */
-#define APIS ELEM(render) ELEM(layout) ELEM(textlayout) ELEM(device)
+#define APIS ELEM(render) ELEM(layout) ELEM(textlayout) ELEM(device) ELEM(loadimage)
 
 /*
  * Define api_t using names based on the plugin names with API_ prefixed.
diff --git a/lib/gvc/gvplugin_loadimage.h b/lib/gvc/gvplugin_loadimage.h
new file mode 100644 (file)
index 0000000..5f1c902
--- /dev/null
@@ -0,0 +1,35 @@
+/* $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             *
+**********************************************************/
+
+#ifndef GVPLUGIN_IMAGELOAD_H
+#define GVPLUGIN_IMAGELOAD_H
+
+#include "types.h"
+#include "gvplugin.h"
+#include "gvcjob.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    struct gvloadimage_engine_s {
+       void (*loadimage) (GVJ_t *job, usershape_t *us, boxf b, bool filled);
+    };
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* GVPLUGIN_IMAGELOAD_H */
index 63d89d628c5963b4a774df58d1b4a9068cc74a2f..c176cd52c3a4bb8483add32a890b816bc3031eb5 100644 (file)
@@ -1543,10 +1543,8 @@ void gvrender_ellipse(GVJ_t * job, pointf pf, double rx, double ry, bool filled)
            af[1].x = pf.x + rx;
            af[1].y = pf.y + ry;
 
-           if (! (job->flags & GVRENDER_DOES_TRANSFORM)) {
-               af[0] = gvrender_ptf(job, af[0]);
-               af[1] = gvrender_ptf(job, af[1]);
-            }
+           if (! (job->flags & GVRENDER_DOES_TRANSFORM))
+               gvrender_ptf_A(job, af, af, 2);
            gvre->ellipse(job, af, filled);
        }
     }
@@ -1566,7 +1564,6 @@ void gvrender_ellipse(GVJ_t * job, pointf pf, double rx, double ry, bool filled)
 
 void gvrender_polygon(GVJ_t * job, pointf * af, int n, bool filled)
 {
-    int i;
     gvrender_engine_t *gvre = job->render.engine;
 
     if (gvre && gvre->polygon) {
@@ -1578,8 +1575,7 @@ void gvrender_polygon(GVJ_t * job, pointf * af, int n, bool filled)
                    sizeAF = n+10;
                    AF = grealloc(AF, sizeAF * sizeof(pointf));
                }
-               for (i = 0; i < n; i++)
-                   AF[i] = gvrender_ptf(job, af[i]);
+               gvrender_ptf_A(job, af, AF, n);
                gvre->polygon(job, AF, n, filled);
            }
        }
@@ -1587,6 +1583,7 @@ void gvrender_polygon(GVJ_t * job, pointf * af, int n, bool filled)
 #ifdef WITH_CODEGENS
     else {
        codegen_t *cg = job->codegen;
+        int i;
 
        if (sizeA < n) {
            sizeA = n+10;
@@ -1624,13 +1621,11 @@ void gvrender_beziercurve(GVJ_t * job, pointf * af, int n,
            if (job->flags & GVRENDER_DOES_TRANSFORM)
                gvre->beziercurve(job, af, n, arrow_at_start, arrow_at_end,filled);
            else {
-               int i;
                if (sizeAF < n) {
                    sizeAF = n+10;
                    AF = grealloc(AF, sizeAF * sizeof(pointf));
                }
-               for (i = 0; i < n; i++)
-                   AF[i] = gvrender_ptf(job, af[i]);
+               gvrender_ptf_A(job, af, AF, n);
                gvre->beziercurve(job, AF, n, arrow_at_start, arrow_at_end,filled);
            }
        }
@@ -1654,7 +1649,6 @@ void gvrender_beziercurve(GVJ_t * job, pointf * af, int n,
 
 void gvrender_polylinef(GVJ_t * job, pointf * af, int n)
 {
-    int i;
     gvrender_engine_t *gvre = job->render.engine;
 
     if (gvre && gvre->polyline) {
@@ -1666,8 +1660,7 @@ void gvrender_polylinef(GVJ_t * job, pointf * af, int n)
                    sizeAF = n+10;
                    AF = grealloc(AF, sizeAF * sizeof(pointf));
                }
-               for (i = 0; i < n; i++)
-                   AF[i] = gvrender_ptf(job, af[i]);
+               gvrender_ptf_A(job, af, AF, n);
                gvre->polyline(job, AF, n);
            }
        }
@@ -1675,6 +1668,7 @@ void gvrender_polylinef(GVJ_t * job, pointf * af, int n)
 #ifdef WITH_CODEGENS
     else {
        codegen_t *cg = job->codegen;
+        int i;
 
        if (sizeA < n) {
            sizeA = n+10;
@@ -1761,8 +1755,7 @@ void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n, bool filled)
            sizeAF = n+10;
            AF = grealloc(AF, sizeAF * sizeof(pointf));
         }
-        for (i = 0; i < n; i++)
-           AF[i] = gvrender_ptf(job, a[i]);
+       gvrender_ptf_A(job, a, AF, n);
        af = AF;
     }
 
@@ -1797,8 +1790,12 @@ void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n, bool filled)
        b.UR.y -= (ph - th) / 2.0;
     }
 
-    if (gvre && gvre->usershape)
-        gvre->usershape(job, us, b, filled);
+    if (gvre) {
+       if (gvre->usershape)
+            gvre->usershape(job, us, b, filled);
+       else if (job->render.features->loadimage_target)
+           gvloadimage(job, us, b, filled, job->render.features->loadimage_target);
+    }
 #ifdef WITH_CODEGENS
     else {
         codegen_t *cg = job->codegen;
index b33e208abc537a5859e5f1077d44c74511d84e35..c012e7372d7eb3434a92ab3448865a0573b94bf2 100644 (file)
@@ -179,6 +179,8 @@ static gvrender_features_t mapgen_features_poly = {
     NULL,                      /* knowncolors */
     0,                         /* sizeof knowncolors */
     0,                         /* color_type */
+    NULL,                       /* device */
+    NULL,                       /* gvloadimage target for usershapes */
 };
 
 static gvrender_features_t mapgen_features = {
@@ -189,6 +191,8 @@ static gvrender_features_t mapgen_features = {
     NULL,                      /* knowncolors */
     0,                         /* sizeof knowncolors */
     0,                         /* color_type */
+    NULL,                       /* device */
+    NULL,                       /* gvloadimage target for usershapes */
 };
 
 gvplugin_installed_t gvrender_core_map_types[] = {
index f83ae3e28edb122c8fb10f1461ff919319ba89a7..c5624ad494899ecaa0ab9871da11f502b93b656f 100644 (file)
@@ -39,6 +39,9 @@
 #include "gd.h"
 #endif
 
+/* for CHAR_LATIN1  */
+#include "const.h"
+
 /*
  *     J$: added `pdfmark' URL embedding.  PostScript rendered from
  *         dot files with URL attributes will get active PDF links
@@ -99,14 +102,11 @@ static void psgen_begin_graph(GVJ_t * job)
         cat_preamble(job, job->common->lib);
         epsf_define(job->output_file);
     }
-#if 0
-    // FIXME
     isLatin1 = (GD_charset(obj->g) == CHAR_LATIN1);
     if (isLatin1 && !setupLatin1) {
        fprintf(job->output_file, "setupLatin1\n");     /* as defined in ps header */
        setupLatin1 = TRUE;
     }
-#endif
     /*  Set base URL for relative links (for Distiller >= 3.0)  */
     if (obj->url)
        fprintf(job->output_file, "[ {Catalog} << /URI << /Base (%s) >> >>\n"
@@ -194,7 +194,7 @@ static void psgen_begin_node(GVJ_t * job)
 {
     obj_state_t *obj = job->obj;
 
-    if (obj->url_map_p) {
+    if (obj->url) {
         fprintf(job->output_file, "[ /Rect [ %g %g %g %g ]\n",
                obj->url_map_p[0].x, obj->url_map_p[0].y,
                obj->url_map_p[1].x, obj->url_map_p[1].y);
@@ -211,7 +211,7 @@ psgen_begin_edge(GVJ_t * job)
 {
     obj_state_t *obj = job->obj;
 
-    if (obj->url_map_p) {
+    if (obj->url) {
         fprintf(job->output_file, "[ /Rect [ %g %g %g %g ]\n",
                obj->url_map_p[0].x, obj->url_map_p[0].y,
                obj->url_map_p[1].x, obj->url_map_p[1].y);
@@ -221,7 +221,7 @@ psgen_begin_edge(GVJ_t * job)
                "/ANN pdfmark\n",
                ps_string(obj->url, isLatin1));
     }
-    if (obj->tailurl_map_p) {
+    if (obj->tailurl) {
         fprintf(job->output_file, "[ /Rect [ %g %g %g %g ]\n",
                obj->tailurl_map_p[0].x, obj->tailurl_map_p[0].y,
                obj->tailurl_map_p[1].x, obj->tailurl_map_p[1].y);
@@ -231,7 +231,7 @@ psgen_begin_edge(GVJ_t * job)
                "/ANN pdfmark\n",
                ps_string(obj->tailurl, isLatin1));
     }
-    if (obj->headurl_map_p) {
+    if (obj->headurl) {
         fprintf(job->output_file, "[ /Rect [ %g %g %g %g ]\n",
                obj->headurl_map_p[0].x, obj->headurl_map_p[0].y,
                obj->headurl_map_p[1].x, obj->headurl_map_p[1].y);
@@ -241,7 +241,7 @@ psgen_begin_edge(GVJ_t * job)
                "/ANN pdfmark\n",
                ps_string(obj->headurl, isLatin1));
     }
-    if (obj->tailendurl_map_p) {
+    if (obj->tailurl) {
         fprintf(job->output_file, "[ /Rect [ %g %g %g %g ]\n",
                obj->tailendurl_map_p[0].x, obj->tailendurl_map_p[0].y,
                obj->tailendurl_map_p[1].x, obj->tailendurl_map_p[1].y);
@@ -251,7 +251,7 @@ psgen_begin_edge(GVJ_t * job)
                "/ANN pdfmark\n",
                ps_string(obj->tailurl, isLatin1));
     }
-    if (obj->headendurl_map_p) {
+    if (obj->headurl) {
         fprintf(job->output_file, "[ /Rect [ %g %g %g %g ]\n",
                obj->headendurl_map_p[0].x, obj->headendurl_map_p[0].y,
                obj->headendurl_map_p[1].x, obj->headendurl_map_p[1].y);
@@ -444,13 +444,6 @@ static void psgen_comment(GVJ_t * job, char *str)
     fprintf(job->output_file, "%% %s\n", str);
 }
 
-static void ps_freeimage_gd (void *data)
-{
-#ifdef HAVE_LIBGD
-    gdImageDestroy((gdImagePtr)data);
-#endif
-}
-
 static void ps_freeimage_ps (void *data)
 {
 #if 0
@@ -458,53 +451,6 @@ static void ps_freeimage_ps (void *data)
 #endif
 }
 
-#ifdef HAVE_LIBGD
-static void writePSBitmap (GVJ_t *job, gdImagePtr im, boxf b)
-{
-    int x, y, px;
-
-    fprintf(job->output_file, "gsave\n");
-
-    /* this sets the position of the image */
-    fprintf(job->output_file, "%g %g translate %% lower-left coordinate\n", b.LL.x, b.LL.y);
-
-    /* this sets the rendered size to fit the box */
-    fprintf(job->output_file,"%g %g scale\n", b.UR.x - b.LL.x, b.UR.y - b.LL.y);
-
-    /* xsize ysize bits-per-sample [matrix] */
-    fprintf(job->output_file, "%d %d 8 [%d 0 0 %d 0 %d]\n", im->sx, im->sy,
-                        im->sx, -(im->sy), im->sy);
-
-    fprintf(job->output_file, "{<\n");
-    for (y = 0; y < im->sy; y++) {
-        for (x = 0; x < im->sx; x++) {
-            if (im->trueColor) {
-                px = gdImageTrueColorPixel(im, x, y);
-                fprintf(job->output_file, "%02x%02x%02x",
-                    gdTrueColorGetRed(px),
-                    gdTrueColorGetGreen(px),
-                    gdTrueColorGetBlue(px));
-            }
-            else {
-                px = gdImagePalettePixel(im, x, y);
-                fprintf(job->output_file, "%02x%02x%02x",
-                    im->red[px],
-                    im->green[px],
-                    im->blue[px]);
-            }
-        }
-        fprintf(job->output_file, "\n");
-    }
-
-    fprintf(job->output_file, ">}\n");
-    fprintf(job->output_file, "false 3 colorimage\n");
-
-    fprintf(job->output_file, "grestore\n");
-
-}
-#endif
-
-
 /* ps_usershape:
  * Images for postscript are complicated by the old epsf shape, as
  * well as user-defined shapes using postscript code.
@@ -517,9 +463,6 @@ static void writePSBitmap (GVJ_t *job, gdImagePtr im, boxf b)
 static void
 psgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
 {
-#ifdef HAVE_LIBGD
-    gdImagePtr gd_img = NULL;
-#endif
 #ifdef XXX_PS
     int j;
     ps_image_t *ps_img = NULL;
@@ -551,12 +494,7 @@ psgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
     }
 
     if (us->data) {
-        if (us->datafree == ps_freeimage_gd) {
-#ifdef HAVE_LIBGD
-            gd_img = (gdImagePtr)(us->data);  /* use cached data */
-#endif
-        }
-        else if (us->datafree == ps_freeimage_ps) {
+        if (us->datafree == ps_freeimage_ps) {
 #ifdef XXX_PS
             ps_img = (ps_image_t *)(us->data);  /* use cached data */
 #endif
@@ -567,38 +505,13 @@ psgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
         }
     }
 
-#ifdef HAVE_LIBGD
-#ifdef XXX_PS
-    if (!ps_img && !gd_img) { /* read file into cache */
-#else
-    if (!gd_img) { /* read file into cache */
-#endif
-#else
 #ifdef XXX_PS
     if (!ps_img) { /* read file into cache */
 #else
     if (false) { /* nothing to do */
-#endif
 #endif
         fseek(us->f, 0, SEEK_SET);
         switch (us->type) {
-#ifdef HAVE_LIBGD
-#ifdef HAVE_GD_PNG
-            case FT_PNG:
-                gd_img = gdImageCreateFromPng(us->f);
-                break;
-#endif
-#ifdef HAVE_GD_GIF
-            case FT_GIF:
-                gd_img = gdImageCreateFromGif(us->f);
-                break;
-#endif
-#ifdef HAVE_GD_JPEG
-            case FT_JPEG:
-                gd_img = gdImageCreateFromJpeg(us->f);
-                break;
-#endif
-#endif
 #ifdef XXX_PS
             case FT_PS:
             case FT_EPS:
@@ -608,12 +521,6 @@ psgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
             default:
                 break;
         }
-#ifdef HAVE_LIBGD
-        if (gd_img) {
-            us->data = (void*)gd_img;
-            us->datafree = ps_freeimage_gd;
-        }
-#endif
 #ifdef XXX_PS
         if (ps_img) {
             us->data = (void*)ps_img;
@@ -639,13 +546,6 @@ psgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
     }
 #endif
 
-#ifdef HAVE_LIBGD
-    if (gd_img) {
-        writePSBitmap (job, gd_img, b);
-        return;
-    }
-#endif
-
     /* some other type of image */
     job->common->errorfn("usershape %s is not supported  in PostScript output\n", us->name);
 }
@@ -678,7 +578,7 @@ static gvrender_engine_t psgen_engine = {
     psgen_bezier,
     psgen_polyline,
     psgen_comment,
-    psgen_usershape
+    0,                         /* psgen_usershape */
 };
 
 static gvrender_features_t psgen_features = {
@@ -691,6 +591,8 @@ static gvrender_features_t psgen_features = {
     NULL,                      /* knowncolors */
     0,                         /* sizeof knowncolors */
     HSV_DOUBLE,                        /* color_type */
+    NULL,                       /* device */
+    "ps",                       /* gvloadimage target for usershapes */
 };
 
 gvplugin_installed_t gvrender_core_ps_types[] = {
index a879a855949e9626607ef3d51600ae757b3b3288..ae0048e580d43fbc8a702e31ae69fc34b2edfca6 100644 (file)
@@ -597,6 +597,8 @@ gvrender_features_t svggen_features = {
     svggen_knowncolors,                /* knowncolors */
     sizeof(svggen_knowncolors) / sizeof(char *),       /* sizeof knowncolors */
     RGBA_BYTE,                 /* color_type */
+    NULL,                       /* device */
+    NULL,                       /* gvloadimage target for usershapes */
 };
 
 gvplugin_installed_t gvrender_core_svg_types[] = {
diff --git a/plugin/gd/gvloadimage_gd.c b/plugin/gd/gvloadimage_gd.c
new file mode 100644 (file)
index 0000000..54c6393
--- /dev/null
@@ -0,0 +1,241 @@
+/* $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 <stddef.h>
+#include <string.h>
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#ifdef MSWIN32
+#include <io.h>
+#endif
+#endif
+
+#include "gvplugin_loadimage.h"
+
+#ifdef HAVE_LIBGD
+#include "gd.h"
+
+typedef enum {
+    FORMAT_PNG_GD, FORMAT_GIF_GD, FORMAT_JPG_GD, FORMAT_GD_GD, FORMAT_GD2_GD, FORMAT_XPM_GD, FORMAT_WBMP_GD,
+    FORMAT_PNG_PS, FORMAT_GIF_PS, FORMAT_JPG_PS, FORMAT_GD_PS, FORMAT_GD2_PS, FORMAT_XPM_PS, FORMAT_WBMP_PS,
+} format_type;
+
+
+static void gd_freeimage(void *data)
+{
+    gdImageDestroy((gdImagePtr)data);
+}
+
+static gdImagePtr gd_loadimage(GVJ_t * job, usershape_t *us)
+{
+    gdImagePtr im = NULL;
+
+    if (us->data) {
+       if (us->datafree == gd_freeimage)
+             im = (gdImagePtr)(us->data);  /* use cached data */
+       else {
+            us->datafree(us->data);        /* free incompatible cache data */
+            us->data = NULL;
+       }
+    }
+    if (!im) { /* read file into cache */
+       fseek(us->f, 0, SEEK_SET);
+       switch (us->type) {
+#if 0
+           case FT_GD:
+               im = gdImageCreateFromGd(us->f);
+               break;
+           case FT_GD2:
+               im = gdImageCreateFromGd2(us->f);
+               break;
+#endif
+#ifdef HAVE_GD_PNG
+           case FT_PNG:
+               im = gdImageCreateFromPng(us->f);
+               break;
+#endif
+#ifdef HAVE_GD_GIF
+           case FT_GIF:
+               im = gdImageCreateFromGif(us->f);
+               break;
+#endif
+#ifdef HAVE_GD_JPEG
+           case FT_JPEG:
+               im = gdImageCreateFromJpeg(us->f);
+               break;
+#endif
+#if 0
+#ifdef HAVE_GD_XPM
+           case FT_XPM:
+               im = gdImageCreateFromXpm(us->f);
+               break;
+#endif
+#ifdef HAVE_GD_WBMP
+           case FT_WBMP:
+               im = gdImageCreateFromWbmp(us->f);
+               break;
+#endif
+#endif
+           default:
+               im = NULL;
+       }
+        if (im) {
+           us->data = (void*)im;
+           us->datafree = gd_freeimage;
+       }
+    }
+    return im;
+}
+
+static void gd_loadimage_gd(GVJ_t * job, usershape_t *us, boxf b, bool filled)
+{
+    gdImagePtr im3, im2 = NULL, im = (gdImagePtr) job->surface;
+
+    im2 = gd_loadimage(job, us);
+    if (im2) {
+        if (job->rotation) {
+            im3 = gdImageCreate(im2->sy, im2->sx); /* scratch image for rotation */
+            gdImageCopyRotated(im3, im2, im3->sx / 2., im3->sy / 2.,
+                0, 0, im2->sx, im2->sy, job->rotation);
+            gdImageCopyResized(im, im3, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
+                ROUND(b.UR.y - b.LL.y), ROUND(b.UR.x - b.LL.x), im3->sx, im3->sy);
+            gdImageDestroy(im3);
+        }
+        else {
+            gdImageCopyResized(im, im2, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
+                ROUND(b.UR.x - b.LL.x), ROUND(b.UR.y - b.LL.y), im2->sx, im2->sy);
+        }
+    }
+}
+
+static void gd_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, bool filled)
+{
+    gdImagePtr im = NULL;
+    FILE *out = job->output_file;
+    int X, Y, x, y, px;
+
+    im = gd_loadimage(job, us);
+    if (im) {
+       X = im->sx;
+       Y = im->sy;
+
+        fprintf(out, "gsave\n");
+
+        /* this sets the position of the image */
+        fprintf(out, "%g %g translate %% lower-left coordinate\n", b.LL.x, b.LL.y);
+    
+        /* this sets the rendered size to fit the box */
+        fprintf(out,"%g %g scale\n", b.UR.x - b.LL.x, b.UR.y - b.LL.y);
+    
+        /* xsize ysize bits-per-sample [matrix] */
+        fprintf(out, "%d %d 8 [%d 0 0 %d 0 %d]\n", X, Y, X, -Y, Y);
+    
+        fprintf(out, "{<\n");
+        if (im->trueColor) {
+            for (y = 0; y < Y; y++) {
+                for (x = 0; x < X; x++) {
+                    px = gdImageTrueColorPixel(im, x, y);
+                    fprintf(out, "%02x%02x%02x",
+                        gdTrueColorGetRed(px),
+                        gdTrueColorGetGreen(px),
+                        gdTrueColorGetBlue(px));
+                }
+            }
+            fprintf(out, "\n");
+       }
+        else {
+            for (y = 0; y < Y; y++) {
+                for (x = 0; x < X; x++) {
+                    px = gdImagePalettePixel(im, x, y);
+                    fprintf(out, "%02x%02x%02x",
+                        im->red[px],
+                        im->green[px],
+                        im->blue[px]);
+                }
+            }
+            fprintf(out, "\n");
+        }
+    
+        fprintf(out, ">}\n");
+        fprintf(out, "false 3 colorimage\n");
+    
+        fprintf(out, "grestore\n");
+    }
+}
+
+static gvloadimage_engine_t engine = {
+    gd_loadimage_gd
+};
+
+static gvloadimage_engine_t engine_ps = {
+    gd_loadimage_ps
+};
+
+#endif
+
+gvplugin_installed_t gvloadimage_gd_types[] = {
+#ifdef HAVE_LIBGD
+#if 0
+    {FORMAT_GD_GD, "gd2gd", 1, &engine, NULL},
+    {FORMAT_GD2_GD, "gd22gd", 1, &engine, NULL},
+#endif
+#ifdef HAVE_GD_GIF
+    {FORMAT_GIF_GD, "gif2gd", 1, &engine, NULL},
+#endif
+#ifdef HAVE_GD_JPEG
+    {FORMAT_JPG_GD, "jpeg2gd", 1, &engine, NULL},
+#endif
+#ifdef HAVE_GD_PNG
+    {FORMAT_PNG_GD, "png2gd", 1, &engine, NULL},
+#endif
+#if 0
+#ifdef HAVE_GD_WBMP
+    {FORMAT_WBMP_GD, "wbmp2gd", 1, &engine, NULL},
+#endif
+#ifdef HAVE_GD_XPM
+    {FORMAT_XBM_GD, "xbm2gd", 1, &engine, NULL},
+#endif
+#endif
+#if 0
+    {FORMAT_GD_PS, "gd2ps", 1, &engine_ps, NULL},
+    {FORMAT_GD2_PS, "gd22ps", 1, &engine_ps, NULL},
+#endif
+#ifdef HAVE_GD_GIF
+    {FORMAT_GIF_PS, "gif2ps", 1, &engine_ps, NULL},
+#endif
+#ifdef HAVE_GD_JPEG
+    {FORMAT_JPG_PS, "jpeg2ps", 1, &engine_ps, NULL},
+#endif
+#ifdef HAVE_GD_PNG
+    {FORMAT_PNG_PS, "png2ps", 1, &engine_ps, NULL},
+#endif
+#if 0
+#ifdef HAVE_GD_WBMP
+    {FORMAT_WBMP_PS, "wbmp2ps", 1, &engine_ps, NULL},
+#endif
+#ifdef HAVE_GD_XPM
+    {FORMAT_XBM_PS, "xbm2ps", 1, &engine_ps, NULL},
+#endif
+#endif
+#endif
+    {0, NULL, 0, NULL, NULL}
+};
index bde97ee4a4e029acdd7b66179cddee429afb6440..5ba37f7d4731b927e51ae05e1f3dfd886a039154 100644 (file)
@@ -674,66 +674,6 @@ static void gdgen_polyline(GVJ_t * job, pointf * A, int n)
        gdImageDestroy(brush);
 }
 
-static void gdgen_freeimage(void *data)
-{
-    gdImageDestroy((gdImagePtr)data);
-}
-
-static void
-gdgen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
-{
-    gdImagePtr im3, im2 = NULL, im = (gdImagePtr) job->surface;
-
-    if (us->data) {
-       if (us->datafree == gdgen_freeimage)
-             im2 = (gdImagePtr)(us->data);  /* use cached data */
-       else {
-            us->datafree(us->data);        /* free incompatible cache data */
-            us->data = NULL;
-       }
-    }
-    if (!im2) { /* read file into cache */
-       fseek(us->f, 0, SEEK_SET);
-       switch (us->type) {
-#ifdef HAVE_GD_PNG
-           case FT_PNG:
-               im2 = gdImageCreateFromPng(us->f);
-               break;
-#endif
-#ifdef HAVE_GD_GIF
-           case FT_GIF:
-               im2 = gdImageCreateFromGif(us->f);
-               break;
-#endif
-#ifdef HAVE_GD_JPEG
-           case FT_JPEG:
-               im2 = gdImageCreateFromJpeg(us->f);
-               break;
-#endif
-           default:
-               im2 = NULL;
-       }
-        if (im2) {
-           us->data = (void*)im2;
-           us->datafree = gdgen_freeimage;
-       }
-    }
-    if (im2) {
-        if (job->rotation) {
-            im3 = gdImageCreate(im2->sy, im2->sx); /* scratch image for rotation */
-            gdImageCopyRotated(im3, im2, im3->sx / 2., im3->sy / 2.,
-                0, 0, im2->sx, im2->sy, job->rotation);
-            gdImageCopyResized(im, im3, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
-                ROUND(b.UR.y - b.LL.y), ROUND(b.UR.x - b.LL.x), im3->sx, im3->sy);
-            gdImageDestroy(im3);
-        }
-        else {
-            gdImageCopyResized(im, im2, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
-                ROUND(b.UR.x - b.LL.x), ROUND(b.UR.y - b.LL.y), im2->sx, im2->sy);
-        }
-    }
-}
-
 static gvrender_engine_t gdgen_engine = {
     0,                         /* gdgen_begin_job */
     0,                         /* gdgen_end_job */
@@ -762,7 +702,7 @@ static gvrender_engine_t gdgen_engine = {
     gdgen_bezier,
     gdgen_polyline,
     0,                         /* gdgen_comment */
-    gdgen_usershape
+    0                          /* gdgen_usershape */ /* provided by gvloadimage */
 };
 
 static gvrender_features_t gdgen_features_tc = {
@@ -774,6 +714,7 @@ static gvrender_features_t gdgen_features_tc = {
     0,                         /* sizeof knowncolors */
     RGBA_BYTE,                 /* color_type */
     NULL,                      /* device */
+    "gd",                      /* gvloadimage target for usershapes */
 };
 
 static gvrender_features_t gdgen_features = {
@@ -784,6 +725,7 @@ static gvrender_features_t gdgen_features = {
     0,                         /* sizeof knowncolors */
     RGBA_BYTE,                 /* color_type */
     NULL,                      /* device */
+    "gd",                      /* gvloadimage target for usershapes */
 };
 
 #endif
diff --git a/plugin/pango/gvloadimage_pango.c b/plugin/pango/gvloadimage_pango.c
new file mode 100644 (file)
index 0000000..ed1cdf6
--- /dev/null
@@ -0,0 +1,157 @@
+/* $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 "gvplugin_loadimage.h"
+
+#ifdef HAVE_PANGOCAIRO
+#include <cairo.h>
+
+typedef enum {
+    FORMAT_PNG_CAIRO, FORMAT_PNG_PS,
+} format_type;
+
+static cairo_status_t
+reader (void *closure, unsigned char *data, unsigned int length)
+{
+    if (length == fread(data, 1, length, (FILE *)closure)
+     || feof((FILE *)closure))
+        return CAIRO_STATUS_SUCCESS;
+    return CAIRO_STATUS_READ_ERROR;
+}
+
+static void cairo_freeimage(void *data)
+{
+    cairo_destroy((cairo_t*)data);
+}
+
+static cairo_surface_t* cairo_loadimage(GVJ_t * job, usershape_t *us)
+{
+    cairo_surface_t *surface = NULL; /* source surface */
+
+    if (us->data) {
+        if (us->datafree == cairo_freeimage)
+             surface = (cairo_surface_t*)(us->data); /* use cached data */
+        else {
+             us->datafree(us->data);        /* free incompatible cache data */
+             us->data = NULL;
+        }
+    }
+    if (!surface) { /* read file into cache */
+        fseek(us->f, 0, SEEK_SET);
+        switch (us->type) {
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+            case FT_PNG:
+                surface = cairo_image_surface_create_from_png_stream(reader, us->f);
+                cairo_surface_reference(surface);
+                break;
+#endif
+            default:
+                surface = NULL;
+        }
+        if (surface) {
+            us->data = (void*)surface;
+            us->datafree = cairo_freeimage;
+        }
+    }
+    return surface;
+}
+
+static void pango_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, bool filled)
+{
+    cairo_t *cr = (cairo_t *) job->surface; /* target context */
+    cairo_surface_t *surface = NULL; /* source surface */
+
+    surface = cairo_loadimage(job, us);
+    if (surface) {
+        cairo_save(cr);
+        cairo_translate(cr, ROUND(b.LL.x), ROUND(-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_surface (cr, surface, 0, 0);
+        cairo_paint (cr);
+        cairo_restore(cr);
+    }
+}
+
+static void pango_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, bool filled)
+{
+    cairo_surface_t *surface = NULL; /* source surface */
+    FILE *out = job->output_file;
+    int X, Y, x, y, stride;
+    unsigned char *data, *ix, alpha, red, green, blue;
+
+    surface = cairo_loadimage(job, us);
+    if (surface && (cairo_image_surface_get_format(surface) == CAIRO_FORMAT_ARGB32)) {
+       X = cairo_image_surface_get_width(surface);
+       Y = cairo_image_surface_get_height(surface);
+       stride = cairo_image_surface_get_stride(surface);
+       data = cairo_image_surface_get_data(surface);
+
+        fprintf(out, "gsave\n");
+
+        /* this sets the position of the image */
+        fprintf(out, "%g %g translate %% lower-left coordinate\n", b.LL.x, b.LL.y);
+
+        /* this sets the rendered size to fit the box */
+        fprintf(out,"%g %g scale\n", b.UR.x - b.LL.x, b.UR.y - b.LL.y);
+
+        /* xsize ysize bits-per-sample [matrix] */
+        fprintf(out, "%d %d 8 [%d 0 0 %d 0 %d]\n", X, Y, X, -Y, Y);
+
+        fprintf(out, "{<\n");
+
+        for (y = 0; y < Y; y++) {
+           ix = data + y * stride;
+            for (x = 0; x < X; x++) {
+               /* FIXME - this code may have endian problems */
+               blue = *ix++;
+               green = *ix++;
+               red = *ix++;
+               alpha = *ix++;
+                fprintf(out, "%02x%02x%02x", red, green, blue);
+            }
+            fprintf(out, "\n");
+        }
+
+        fprintf(out, ">}\n");
+        fprintf(out, "false 3 colorimage\n");
+
+        fprintf(out, "grestore\n");
+    }
+}
+
+static gvloadimage_engine_t engine_cairo = {
+    pango_loadimage_cairo
+};
+
+static gvloadimage_engine_t engine_ps = {
+    pango_loadimage_ps
+};
+#endif
+
+gvplugin_installed_t gvloadimage_pango_types[] = {
+#ifdef HAVE_PANGOCAIRO
+    {FORMAT_PNG_CAIRO, "png2cairo", 1, &engine_cairo, NULL},
+    {FORMAT_PNG_PS, "png2ps", 1, &engine_ps, NULL},
+#endif
+    {0, NULL, 0, NULL, NULL}
+};
index 4498261ba1c81ae50c71d5dae22b6b8f60545f5d..fc3ed11985a54dc821225e05daa9194f74909316 100644 (file)
 
 extern gvplugin_installed_t gvrender_pango_types;
 extern gvplugin_installed_t gvtextlayout_pango_types;
+extern gvplugin_installed_t gvloadimage_pango_types;
 
 static gvplugin_api_t apis[] = {
     {API_render, &gvrender_pango_types},
     {API_textlayout, &gvtextlayout_pango_types},
+    {API_loadimage, &gvloadimage_pango_types},
     {(api_t)0, 0},
 };
 
index 83199516306fa2321a870f182744d8f818274b35..c3b52d9c0d387ad61d2fd9a45a1bdc15cb886108 100644 (file)
@@ -115,15 +115,6 @@ writer (void *closure, const unsigned char *data, unsigned int length)
     return CAIRO_STATUS_WRITE_ERROR;
 }
 
-static cairo_status_t
-reader (void *closure, unsigned char *data, unsigned int length)
-{
-    if (length == fread(data, 1, length, (FILE *)closure)
-     || feof((FILE *)closure))
-       return CAIRO_STATUS_SUCCESS;
-    return CAIRO_STATUS_READ_ERROR;
-}
-
 static void cairogen_begin_page(GVJ_t * job)
 {
     cairo_t *cr;
@@ -387,53 +378,6 @@ cairogen_polyline(GVJ_t * job, pointf * A, int n)
     cairo_stroke(cr);
 }
 
-static void cairogen_freeimage(void *data)
-{
-    cairo_destroy((cairo_t*)data);
-}
-
-static void
-cairogen_usershape(GVJ_t * job, usershape_t *us, boxf b, bool filled)
-{
-    cairo_t *cr = (cairo_t *) job->surface; /* target context */
-    cairo_surface_t *surface1 = NULL; /* source surface */
-
-    if (us->data) {
-        if (us->datafree == cairogen_freeimage)
-            surface1 = (cairo_surface_t*)(us->data); /* use cached data */
-        else {
-             us->datafree(us->data);        /* free incompatible cache data */
-             us->data = NULL;
-        }
-    }
-    if (!surface1) { /* read file into cache */
-        fseek(us->f, 0, SEEK_SET);
-        switch (us->type) {
-#ifdef CAIRO_HAS_PNG_FUNCTIONS
-            case FT_PNG:
-                surface1 = cairo_image_surface_create_from_png_stream(reader, us->f);
-               cairo_surface_reference(surface1);
-                break;
-#endif
-            default:
-                surface1 = NULL;
-        }
-        if (surface1) {
-            us->data = (void*)surface1;
-            us->datafree = cairogen_freeimage;
-        }
-    }
-    if (surface1) {
-       cairo_save(cr);
-       cairo_translate(cr, ROUND(b.LL.x), ROUND(-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_surface (cr, surface1, 0, 0);
-       cairo_paint (cr);
-       cairo_restore(cr);
-    }
-}
-
 static gvrender_engine_t cairogen_engine = {
     0,                         /* cairogen_begin_job */
     0,                         /* cairogen_end_job */
@@ -462,7 +406,7 @@ static gvrender_engine_t cairogen_engine = {
     cairogen_bezier,
     cairogen_polyline,
     0,                         /* cairogen_comment */
-    cairogen_usershape
+    0                          /* cairogen_usershape */ /* provided by gvloadimage */
 };
 
 static gvrender_features_t cairogen_features = {
@@ -475,6 +419,7 @@ static gvrender_features_t cairogen_features = {
     0,                         /* sizeof knowncolors */
     RGBA_DOUBLE,               /* color_type */
     0,                         /* device */
+    "cairo",                   /* gvloadimage target for usershapes */
 };
 
 static gvrender_features_t cairogen_features_ps = {
@@ -487,6 +432,7 @@ static gvrender_features_t cairogen_features_ps = {
     0,                         /* sizeof knowncolors */
     RGBA_DOUBLE,               /* color_type */
     0,                         /* device */
+    "cairo",                   /* gvloadimage target for usershapes */
 };
 
 #if 0
@@ -501,6 +447,7 @@ static gvrender_features_t cairogen_features_x = {
     0,                         /* sizeof knowncolors */
     RGBA_DOUBLE,               /* color_type */
     "xlib",                    /* device */
+    "cairo",                   /* gvloadimage target for usershapes */
 };
 
 static gvrender_features_t cairogen_features_gtk = {
@@ -514,6 +461,7 @@ static gvrender_features_t cairogen_features_gtk = {
     0,                         /* sizeof knowncolors */
     RGBA_DOUBLE,               /* color_type */
     "gtk",                     /* device */
+    "cairo",                   /* gvloadimage target for usershapes */
 };
 #endif
 #endif