]> granicus.if.org Git - graphviz/commitdiff
some work on vrml plugin
authorellson <devnull@localhost>
Sat, 24 Jun 2006 16:51:22 +0000 (16:51 +0000)
committerellson <devnull@localhost>
Sat, 24 Jun 2006 16:51:22 +0000 (16:51 +0000)
CMakeLists.txt
lib/common/utils.c
lib/gvc/gvloadimage.c
plugin/gd/gvplugin_gd.c
plugin/gd/gvrender_gd.c
plugin/gd/gvrender_gd_vrml.c
plugin/pango/gvplugin_pango.c

index 6fb86a29655f0c85bbe08bc1e79da9b82055b277..2530c7bd16ada36995e7f0b98818189e26e6e862 100644 (file)
@@ -3,14 +3,20 @@
 
 PROJECT(graphviz)
 
-SUBDIRS(
-       lib
-       cmd
-       tclpkg
-       doc
-       contrib
-       graphs
-)
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake
+
+ADD_SUBDIRECTORY(lib)
+ADD_SUBDIRECTORY(cmd)
+ADD_SUBDIRECTORY(tclpkg)
+ADD_SUBDIRECTORY(doc)
+ADD_SUBDIRECTORY(contrib)
+ADD_SUBDIRECTORY(graphs)
+
+# create config.h
+#INCLUDE (ConfigureChecks.cmake)
+#CONFIGURE_FILE (config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )
+
+ADD_DEFINITIONS( -DHAVE_CONFIG_H )
 
 CONFIGURE_FILE(
        "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake.in"
@@ -19,8 +25,7 @@ CONFIGURE_FILE(
 )
 
 ADD_CUSTOM_TARGET(uninstall
-       "${CMAKE_COMMAND}" -P
-       "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+       "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
 )
 
 # FIXME - this config.h comes from ./configure
@@ -30,8 +35,6 @@ ADD_CUSTOM_COMMAND(
        COMMAND cat < ${CMAKE_CURRENT_SOURCE_DIR}/config.h > ${CMAKE_BINARY_DIR}/config.h
 )
 
-ADD_DEFINITIONS( -DHAVE_CONFIG_H )
-
 # FIXME - this ast_common.h comes from ./configure
 ADD_CUSTOM_COMMAND(
        OUTPUT ${CMAKE_BINARY_DIR}/ast_common.h
index 9bdef0ce1ced4150466944332c73bc692557731b..e2e43177883dbd67cbbd92d2690df15d6e3d2583 100644 (file)
@@ -200,8 +200,7 @@ point coord(node_t * n)
  *     "Right" are non-null.
  * 
  */
-pointf Bezier(pointf * V, int degree, double t, pointf * Left,
-             pointf * Right)
+pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right)
 {
     int i, j;                  /* Index variables      */
     pointf Vtemp[W_DEGREE + 1][W_DEGREE + 1];
index 98868d8a0c872cf7c02670882c4d85f890f59af3..50dbd5953f3833cc28c02a346d3b6ad0240d0c93 100644 (file)
@@ -31,6 +31,9 @@
 #include "gvcint.h"
 #include "gvcproc.h"
 
+/* for agerr() */
+#include "graph.h"
+
 int gvloadimage_select(GVJ_t * job, char *str)
 {
     gvplugin_available_t *plugin;
@@ -55,8 +58,8 @@ void gvloadimage(GVJ_t * job, usershape_t *us, boxf b, bool filled, char *target
     strcat(type, "2");
     strcat(type, target);
 
-    if (type)
-        gvloadimage_select(job, type);
+    if (gvloadimage_select(job, type) == NO_SUPPORT)
+           agerr (AGWARN, "No loadimage plugin for \"%s\"\n", type);
 
     if ((gvli = job->loadimage.engine) && gvli->loadimage)
        gvli->loadimage(job, us, b, filled);
index b003014c1f023c5987db99d5be98c9e4d9d2e44b..1444007fe48e111e4a9665bf033cdba0eca3ea9b 100644 (file)
 #include "gvplugin.h"
 
 extern gvplugin_installed_t gvrender_gd_types;
+extern gvplugin_installed_t gvrender_vrml_types;
 extern gvplugin_installed_t gvtextlayout_gd_types;
 extern gvplugin_installed_t gvloadimage_gd_types;
 
 static gvplugin_api_t apis[] = {
     {API_render, &gvrender_gd_types},
+    {API_render, &gvrender_vrml_types},
     {API_textlayout, &gvtextlayout_gd_types},
     {API_loadimage, &gvloadimage_gd_types},
     {(api_t)0, 0},
index c0a9867789564a2e9253b54664bfda6bbf2a62d1..ec5bd1ef65561bbcbd283eb1af6bb70f4795744a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "gvplugin_render.h"
 
+
 #ifdef HAVE_LIBGD
 #include "gd.h"
 
@@ -33,6 +34,7 @@ typedef enum { FORMAT_GD, FORMAT_GD2, FORMAT_GIF, FORMAT_JPEG, FORMAT_PNG,
 
 extern int mapbool(char *);
 extern char *safefile(char *shapefilename);
+extern pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right);
 
 #define BEZIERSUBDIVISION 10
 
@@ -41,47 +43,6 @@ extern char *safefile(char *shapefilename);
 /* fontsize at which text is rendered by a simple line */
 #define FONTSIZE_TOO_SMALL 1.5
 
-/* from Glassner's Graphics Gems */
-#define W_DEGREE 5
-
-/*
- *  Bezier :
- *      Evaluate a Bezier curve at a particular parameter value
- *      Fill in control points for resulting sub-curves if "Left" and
- *      "Right" are non-null.
- *
- */
-static pointf Bezier(pointf * V, int degree, double t, pointf * Left,
-              pointf * Right)
-{
-    int i, j;                   /* Index variables      */
-    pointf Vtemp[W_DEGREE + 1][W_DEGREE + 1];
-
-    /* Copy control points  */
-    for (j = 0; j <= degree; j++) {
-        Vtemp[0][j] = V[j];
-    }
-
-    /* Triangle computation */
-    for (i = 1; i <= degree; i++) {
-        for (j = 0; j <= degree - i; j++) {
-            Vtemp[i][j].x =
-                (1.0 - t) * Vtemp[i - 1][j].x + t * Vtemp[i - 1][j + 1].x;
-            Vtemp[i][j].y =
-                (1.0 - t) * Vtemp[i - 1][j].y + t * Vtemp[i - 1][j + 1].y;
-        }
-    }
-
-    if (Left != NULL)
-        for (j = 0; j <= degree; j++)
-            Left[j] = Vtemp[j][0];
-    if (Right != NULL)
-        for (j = 0; j <= degree; j++)
-            Right[j] = Vtemp[degree - j][j];
-
-    return (Vtemp[degree][0]);
-}
-
 static void gdgen_resolve_color(GVJ_t * job, gvcolor_t * color)
 {
     gdImagePtr im = (gdImagePtr) job->surface;
@@ -415,45 +376,35 @@ static void gdgen_textpara(GVJ_t * job, pointf p, textpara_t * para)
     }
 }
 
-static void
-gdgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
-            int arrow_at_end, int filled)
+int gdgen_set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush)
 {
     gvstyle_t *style = job->style;
-    gdImagePtr im = (gdImagePtr) job->surface;
-    pointf p0, p1, V[4];
-    int i, j, step;
-    int dashstyle[20];
-    int pen, width;
-    gdImagePtr brush = NULL;
-    gdPoint F[4];
-
-    if (!im)
-       return;
+    int i, pen, width, dashstyle[40];
 
     if (style->pen == PEN_DASHED) {
-       for (i = 0; i < 10; i++)
+       for (i = 0; i < 20; i++)
            dashstyle[i] = style->pencolor.u.index;
-       for (; i < 20; i++)
+       for (; i < 40; i++)
            dashstyle[i] = transparent;
        gdImageSetStyle(im, dashstyle, 20);
        pen = gdStyled;
     } else if (style->pen == PEN_DOTTED) {
        for (i = 0; i < 2; i++)
            dashstyle[i] = style->pencolor.u.index;
-       for (; i < 12; i++)
+       for (; i < 24; i++)
            dashstyle[i] = transparent;
-       gdImageSetStyle(im, dashstyle, 12);
+       gdImageSetStyle(im, dashstyle, 24);
        pen = gdStyled;
     } else {
        pen = style->pencolor.u.index;
     }
 
-    width = style->penwidth;
+    width = style->penwidth * job->scale.x;
     if (width < PENWIDTH_NORMAL)
-        width = PENWIDTH_NORMAL;  /* gd can't do thin lines */
+       width = PENWIDTH_NORMAL;  /* gd can't do thin lines */
     gdImageSetThickness(im, width);
-    if (style->penwidth != PENWIDTH_NORMAL) {
+    /* use brush instead of Thickness to improve end butts */
+    if (width != PENWIDTH_NORMAL) {
        brush = gdImageCreate(width, width);
        gdImagePaletteCopy(brush, im);
        gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1,
@@ -465,31 +416,40 @@ gdgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
            pen = gdBrushed;
     }
 
-    V[3].x = A[0].x;
-    V[3].y = A[0].y;
-    F[0].x = ROUND(A[0].x);
-    F[0].y = ROUND(A[0].y);
-    F[3].x = ROUND(A[n-1].x);
-    F[3].y = ROUND(A[n-1].y);
+    return pen;
+}
+
+static void
+gdgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
+            int arrow_at_end, int filled)
+{
+    gvstyle_t *style = job->style;
+    gdImagePtr im = (gdImagePtr) job->surface;
+    pointf p0, p1, V[4];
+    int i, j, step, pen;
+    gdImagePtr brush = NULL;
+    gdPoint F[4];
+
+    if (!im)
+       return;
+
+    pen = gdgen_set_penstyle(job, im, brush);
+
+    V[3] = A[0];
+    PF2P(A[0], F[0]);
+    PF2P(A[n-1], F[3]);
     for (i = 0; i + 3 < n; i += 3) {
        V[0] = V[3];
-       for (j = 1; j <= 3; j++) {
-           V[j].x = A[i + j].x;
-           V[j].y = A[i + j].y;
-       }
+       for (j = 1; j <= 3; j++)
+           V[j] = A[i + j];
        p0 = V[0];
        for (step = 1; step <= BEZIERSUBDIVISION; step++) {
-           p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL,
-                       NULL);
-           gdImageLine(im, ROUND(p0.x), ROUND(p0.y), ROUND(p1.x),
-                       ROUND(p1.y), pen);
-           if (filled) {
-               F[1].x = ROUND(p0.x);
-               F[1].y = ROUND(p0.y);
-               F[2].x = ROUND(p1.x);
-               F[2].y = ROUND(p1.y);
+           p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, NULL);
+           PF2P(p0, F[1]);
+           PF2P(p1, F[2]);
+           gdImageLine(im, F[1].x, F[1].y, F[2].x, F[2].y, pen);
+           if (filled)
                gdImageFilledPolygon(im, F, 4, style->fillcolor.u.index);
-           }
            p0 = p1;
        }
     }
@@ -501,49 +461,16 @@ static void gdgen_polygon(GVJ_t * job, pointf * A, int n, int filled)
 {
     gvstyle_t *style = job->style;
     gdImagePtr im = (gdImagePtr) job->surface;
+    gdImagePtr brush = NULL;
     int i;
     gdPoint *points;
-    int dashstyle[20];
-    int pen, width;
-    gdImagePtr brush = NULL;
+    int pen;
 
     if (!im)
        return;
 
-    if (style->pen == PEN_DASHED) {
-       for (i = 0; i < 10; i++)
-           dashstyle[i] = style->pencolor.u.index;
-       for (; i < 20; i++)
-           dashstyle[i] = transparent;
-       gdImageSetStyle(im, dashstyle, 20);
-       pen = gdStyled;
-    } else if (style->pen == PEN_DOTTED) {
-       for (i = 0; i < 2; i++)
-           dashstyle[i] = style->pencolor.u.index;
-       for (; i < 12; i++)
-           dashstyle[i] = transparent;
-       gdImageSetStyle(im, dashstyle, 12);
-       pen = gdStyled;
-    } else {
-       pen = style->pencolor.u.index;
-    }
+    pen = gdgen_set_penstyle(job, im, brush);
 
-    width = style->penwidth * job->scale.x;
-    if (width < PENWIDTH_NORMAL)
-       width = PENWIDTH_NORMAL;  /* gd can't do thin lines */
-    gdImageSetThickness(im, width);
-    /* use brush instead of Thickness to improve end butts */
-    if (width != PENWIDTH_NORMAL) {
-       brush = gdImageCreate(width, width);
-       gdImagePaletteCopy(brush, im);
-       gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1,
-                              style->pencolor.u.index);
-       gdImageSetBrush(im, brush);
-       if (pen == gdStyled)
-           pen = gdStyledBrushed;
-       else
-           pen = gdBrushed;
-    }
     points = malloc(n * sizeof(gdPoint));
     for (i = 0; i < n; i++) {
        points[i].x = ROUND(A[i].x);
@@ -563,50 +490,16 @@ static void gdgen_ellipse(GVJ_t * job, pointf * A, int filled)
     gvstyle_t *style = job->style;
     gdImagePtr im = (gdImagePtr) job->surface;
     double dx, dy;
-    int i;
-    int dashstyle[40];         /* need 2* size for arcs, I don't know why */
-    int pen, width;
+    int pen;
     gdImagePtr brush = NULL;
 
     if (!im)
        return;
 
-    if (style->pen == PEN_DASHED) {
-       for (i = 0; i < 20; i++)
-           dashstyle[i] = style->pencolor.u.index;
-       for (; i < 40; i++)
-           dashstyle[i] = transparent;
-       gdImageSetStyle(im, dashstyle, 40);
-       pen = gdStyled;
-    } else if (style->pen == PEN_DOTTED) {
-       for (i = 0; i < 2; i++)
-           dashstyle[i] = style->pencolor.u.index;
-       for (; i < 24; i++)
-           dashstyle[i] = transparent;
-       gdImageSetStyle(im, dashstyle, 24);
-       pen = gdStyled;
-    } else {
-       pen = style->pencolor.u.index;
-    }
+    pen = gdgen_set_penstyle(job, im, brush);
 
-    width = style->penwidth * job->scale.x;
-    if (width < PENWIDTH_NORMAL)
-       width = PENWIDTH_NORMAL;  /* gd can't do thin lines */
-    gdImageSetThickness(im, width);
-    /* use brush instead of Thickness to improve outline appearance */
-    if (width != PENWIDTH_NORMAL) {
-       brush = gdImageCreate(width, width);
-       gdImagePaletteCopy(brush, im);
-       gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1,
-                              style->pencolor.u.index);
-       gdImageSetBrush(im, brush);
-       if (pen == gdStyled)
-           pen = gdStyledBrushed;
-       else
-           pen = gdBrushed;
-    }
-    dx = fabs(2 * (A[1].x - A[0].x));
-    dy = fabs(2 * (A[1].y - A[0].y));
+    dx = 2 * (A[1].x - A[0].x);
+    dy = 2 * (A[1].y - A[0].y);
 
     if (filled)
        gdImageFilledEllipse(im, ROUND(A[0].x), ROUND(A[0].y),
index 96b8df6e733812b7efc6306bfdf9208b18070d3b..6f1e0f970ea3943895ac658fc57ecbd33958ab0d 100644 (file)
 
 #include "gvplugin_render.h"
 
-#ifdef HAVE_GD_PNG
+#ifdef HAVE_LIBGD
 #include "gd.h"
+
+#ifdef HAVE_GD_PNG
+
+/* for N_GNEW() */
+#include "memory.h"
+
+/* for ? */
 #include "graph.h"
 
 /* for late_double() */
 
 extern shape_kind shapeOf(node_t *);
 
+extern pointf Bezier(pointf * V, int degree, double t, pointf * Left, pointf * Right);
+extern int gdgen_set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush);
+
 typedef enum { FORMAT_VRML, } format_type;
 
 #ifndef MAXFLOAT
 #define MAXFLOAT 10000000.
 #endif
 
-#define                NONE            0
-#define                NODE            1
-#define                EDGE            2
-#define                CLST            3
-
 #define BEZIERSUBDIVISION 10
 
-/* font modifiers */
-#define REGULAR 0
-#define BOLD           1
-#define ITALIC         2
-
-/* patterns */
-#define P_SOLID                0
-#define P_NONE  15
-#define P_DOTTED 4             /* i wasn't sure about this */
-#define P_DASHED 11            /* or this */
-
-/* bold line constant */
-#define WIDTH_NORMAL 1
-#define WIDTH_BOLD 3
-
-typedef struct {
-    unsigned char r, g, b;
-} Color;
-
-
 /* static int  N_pages; */
 /* static point        Pages; */
 static double Scale;
@@ -87,19 +72,6 @@ static double EdgeLen;     /* length between centers of endpoints */
 static double HeadHt, TailHt;  /* height of arrows */
 static double Fstz, Sndz;  /* z values of tail and head points */
 
-typedef struct context_t {
-    unsigned char pencolor_ix, fillcolor_ix;
-    char *pencolor, *fillcolor;
-    char *fontfam, fontopt, font_was_set;
-    double r, g, b;     /* fill color values */
-    char pen, fill, penwidth;
-    double fontsz;
-} context_t;
-
-#define MAXNEST 4
-static context_t cstk[MAXNEST];
-static int SP;
-
 /* gdirname:
  * Returns directory pathname prefix
  * Code adapted from dgk
@@ -158,48 +130,21 @@ static FILE *nodefile(char *filename, node_t * n)
     return rv;
 }
 
-static void init_png(gdImagePtr im)
-{
-    int transparent;
-
-    if ((transparent = gdImageGetTransparent(im)) == -1) {
-       transparent = gdImageColorResolve(im, 255, 255, 254);
-       gdImageColorTransparent(im, transparent);
-    }
-}
-
-static pointf vrml_node_point(GVJ_t *job, node_t *n, point p)
+static pointf vrml_node_point(GVJ_t *job, node_t *n, pointf p)
 {
     pointf rv;
 
     /* make mp relative to PNG canvas */
     if (job->rotation) {
-       rv.x = (p.y - ND_coord_i(n).y + ND_lw_i(n)) * Scale;
-       rv.y = (ND_coord_i(n).x - p.x + ND_ht_i(n) / 2) * Scale;
+       rv.x = ( p.y - ND_coord_i(n).y + ND_lw_i(n)     ) * Scale;
+       rv.y = (-p.x + ND_coord_i(n).x + ND_ht_i(n) / 2.) * Scale;
     } else {
-       rv.x = (p.x - ND_coord_i(n).x + ND_lw_i(n)) * Scale;
-       rv.y = (ND_coord_i(n).y - p.y + ND_ht_i(n) / 2) * Scale;
+       rv.x = ( p.x - ND_coord_i(n).x + ND_lw_i(n)     ) * Scale;
+       rv.y = (-p.y + ND_coord_i(n).y + ND_ht_i(n) / 2.) * Scale;
     }
     return rv;
 }
 
-static void vrml_font(context_t * cp)
-{
-/* FIX
-       char               *fw, *fa;
-
-       fw = fa = "Regular";
-       switch (cp->fontopt) {
-       case BOLD:
-               fw = "Bold";
-               break;
-       case ITALIC:
-               fa = "Italic";
-               break;
-       }
-*/
-}
-
 /* warmed over VRML code starts here */
 
 static void vrml_resolve_color(GVJ_t * job, gvcolor_t * color)
@@ -218,8 +163,6 @@ static void vrml_resolve_color(GVJ_t * job, gvcolor_t * color)
     color->type = COLOR_INDEX;
 }
 
-static int white, black, transparent, basecolor;
-
 static void vrml_begin_page(GVJ_t *job)
 {
     FILE *out = job->output_file;
@@ -233,14 +176,6 @@ static void vrml_begin_page(GVJ_t *job)
     fprintf(out, "  Transform {\n");
     fprintf(out, "    scale %.3f %.3f %.3f\n", .0278, .0278, .0278);
     fprintf(out, "    children [\n");
-
-    SP = 0;
-    cstk[0].fillcolor = "white";
-    cstk[0].fontfam = "times"; /* font family name */
-    cstk[0].fontopt = REGULAR; /* modifier: REGULAR, BOLD or ITALIC */
-    cstk[0].pen = P_SOLID;     /* pen pattern style, default is solid */
-    cstk[0].fill = P_NONE;
-    cstk[0].penwidth = WIDTH_NORMAL;
 }
 
 static void vrml_end_page(GVJ_t *job)
@@ -271,15 +206,20 @@ static void vrml_begin_node(GVJ_t *job)
     node_t *n = obj->n;
     double z = obj->z;
     int width, height;
+    int transparent;
 
     fprintf(out, "# node %s\n", n->name);
     if (z < MinZ) MinZ = z;
     if (shapeOf(n) != SH_POINT) {
        PNGfile = nodefile(job->output_filename, n);
+
        width = (ND_lw_i(n) + ND_rw_i(n)) * Scale + 3;
        height = (ND_ht_i(n)) * Scale + 3;
        im = gdImageCreate(width, height);
-       init_png(im);
+
+       /* make backround transparent */
+       transparent = gdImageColorResolve(im, 255, 255, 254);
+       gdImageColorTransparent(im, transparent);
     }
 }
 
@@ -291,7 +231,7 @@ static void vrml_end_node(GVJ_t *job)
     if (shapeOf(n) != SH_POINT) {
        gdImagePng(im, PNGfile);
        gdImageDestroy(im);
-       im = 0;
+       im = NULL;
        fclose(PNGfile);
     }
 }
@@ -355,48 +295,10 @@ static void vrml_end_edge(GVJ_t *job)
     fprintf(job->output_file, "] }\n");
 }
 
-static void vrml_begin_context(void)
-{
-    assert(SP + 1 < MAXNEST);
-    cstk[SP + 1] = cstk[SP];
-    SP++;
-}
-
-static void vrml_end_context(void)
-{
-    int psp = SP - 1;
-    assert(SP > 0);
-    if (cstk[SP].font_was_set)
-       vrml_font(&(cstk[psp]));
-    /* free(cstk[psp].fontfam); */
-    SP = psp;
-}
-
-static void vrml_set_font(char *name, double size)
-{
-    char *p, *q;
-    context_t *cp;
-
-    cp = &(cstk[SP]);
-    cp->font_was_set = TRUE;
-    cp->fontsz = size;
-    p = strdup(name);
-    if ((q = strchr(p, '-'))) {
-       *q++ = 0;
-       if (strcasecmp(q, "italic") == 0)
-           cp->fontopt = ITALIC;
-       else if (strcasecmp(q, "bold") == 0)
-           cp->fontopt = BOLD;
-    }
-    cp->fontfam = p;
-    vrml_font(&cstk[SP]);
-}
-
-static void vrml_textpara(GVJ_t *job, pointf pf, textpara_t * para)
+static void vrml_textpara(GVJ_t *job, pointf p, textpara_t * para)
 {
     obj_state_t *obj = job->obj;
     char *err;
-    point p;
     pointf mp;
     int brect[8];
     extern gdFontPtr gdFontSmall;
@@ -404,7 +306,6 @@ static void vrml_textpara(GVJ_t *job, pointf pf, textpara_t * para)
     if (! obj->n)
        return;
 
-    PF2P(pf, p);
     switch (para->just) {
     case 'l':
        break;
@@ -439,7 +340,7 @@ static void vrml_textpara(GVJ_t *job, pointf pf, textpara_t * para)
  * Why the special case for ranks? Is the arithmetic really correct?
  */
 static double 
-interpolate_zcoord(GVJ_t *job, pointf p1, point fst, double fstz, point snd, double sndz)
+interpolate_zcoord(GVJ_t *job, pointf p1, pointf fst, double fstz, pointf snd, double sndz)
 {
     obj_state_t *obj = job->obj;
     edge_t *e = obj->e;
@@ -465,21 +366,11 @@ interpolate_zcoord(GVJ_t *job, pointf p1, point fst, double fstz, point snd, dou
  * Return true if the 3 points starting at A are collinear.
  */
 static int
-collinear (point * A)
+collinear (pointf * A)
 {
-    Ppoint_t a, b, c;
     double w;
 
-    a.x = A->x;
-    a.y = A->y;
-    A++;
-    b.x = A->x;
-    b.y = A->y;
-    A++;
-    c.x = A->x;
-    c.y = A->y;
-
-    w = wind(a,b,c);
+    w = wind(A[0],A[1],A[2]);
     return (fabs(w) <= 1);
 }
 
@@ -488,14 +379,14 @@ collinear (point * A)
  * At present, just check with 4 points, the common case.
  */
 static int
-straight (point * A, int n)
+straight (pointf * A, int n)
 {
     if (n != 4) return 0;
     return (collinear(A) && collinear(A+1));
 }
 
 static void
-doSegment (FILE *out, point* A, point p0, double z0, point p1, double z1)
+doSegment (FILE *out, pointf* A, point p0, double z0, point p1, double z1)
 {
     double d1, d0;
     double delx, dely, delz;
@@ -515,19 +406,18 @@ doSegment (FILE *out, point* A, point p0, double z0, point p1, double z1)
     fprintf(out, "    Shape {\n");
     fprintf(out, "      geometry Cylinder {\n"); 
     fprintf(out, "        bottom FALSE top FALSE\n"); 
-    fprintf(out, "        height %f radius %d }\n", CylHt, cstk[SP].penwidth);
+//    fprintf(out, "        height %f radius %d }\n", CylHt, cstk[SP].penwidth);
     fprintf(out, "      appearance Appearance {\n");
     fprintf(out, "        material Material {\n");
     fprintf(out, "          ambientIntensity 0.33\n");
-    fprintf(out, "          diffuseColor %f %f %f\n", 
-       cstk[SP].r,cstk[SP].g,cstk[SP].b);
+//    fprintf(out, "          diffuseColor %f %f %f\n", cstk[SP].r,cstk[SP].g,cstk[SP].b);
     fprintf(out, "        }\n");
     fprintf(out, "      }\n");
     fprintf(out, "    }\n");
 }
 
 static void
-vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end, int filled)
+vrml_bezier(GVJ_t *job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled)
 {
     FILE *out = job->output_file;
     obj_state_t *obj = job->obj;
@@ -535,13 +425,9 @@ vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end,
     double fstz = obj->tail_z, sndz = obj->head_z;
     pointf p1, V[4];
     int i, j, step;
-    context_t *cp;
 
     assert(obj->e);
 
-    cp = &(cstk[SP]);
-    if (cp->pen == P_NONE)
-       return;
     if (straight(A,n)) {
        doSegment (out, A, ND_coord_i(e->tail),Fstz,ND_coord_i(e->head),Sndz);
        return;
@@ -549,32 +435,27 @@ vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end,
 
     fprintf(out, "Shape { geometry Extrusion  {\n");
     fprintf(out, "  spine [");
-    V[3].x = A[0].x;
-    V[3].y = A[0].y;
+    V[3] = A[0];
     for (i = 0; i + 3 < n; i += 3) {
        V[0] = V[3];
-       for (j = 1; j <= 3; j++) {
-           V[j].x = A[i + j].x;
-           V[j].y = A[i + j].y;
-       }
+       for (j = 1; j <= 3; j++)
+           V[j] = A[i + j];
        for (step = 0; step <= BEZIERSUBDIVISION; step++) {
-           p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL,
-                       NULL);
-           fprintf(out, " %.3f %.3f %.3f", p1.x, p1.y,
+           p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, NULL);
+           fprintf(out, " %g %g %g", p1.x, p1.y,
                    interpolate_zcoord(job, p1, A[0], fstz, A[n - 1], sndz));
        }
     }
     fprintf(out, " ]\n");
-    fprintf(out, "  crossSection [ %d %d, %d %d, %d %d, %d %d ]\n",
-           (cp->penwidth), (cp->penwidth), -(cp->penwidth),
-           (cp->penwidth), -(cp->penwidth), -(cp->penwidth),
-           (cp->penwidth), -(cp->penwidth));
+//    fprintf(out, "  crossSection [ %d %d, %d %d, %d %d, %d %d ]\n",
+//         (cp->penwidth), (cp->penwidth), -(cp->penwidth),
+//         (cp->penwidth), -(cp->penwidth), -(cp->penwidth),
+//         (cp->penwidth), -(cp->penwidth));
     fprintf(out, "}\n");
     fprintf(out, " appearance DEF E%d Appearance {\n", e->id);
     fprintf(out, "   material Material {\n");
     fprintf(out, "   ambientIntensity 0.33\n");
-    fprintf(out, "   diffuseColor %.3f %.3f %.3f\n",
-           cstk[SP].r, cstk[SP].g, cstk[SP].b);
+//    fprintf(out, "   diffuseColor %.3f %.3f %.3f\n", cstk[SP].r, cstk[SP].g, cstk[SP].b);
     fprintf(out, "   }\n");
     fprintf(out, " }\n");
     fprintf(out, "}\n");
@@ -583,8 +464,7 @@ vrml_bezier(GVJ_t *job, point * A, int n, int arrow_at_start, int arrow_at_end,
 /* doArrowhead:
  * If edge is straight, we attach a cone to the edge as a group.
  */
-static void
-doArrowhead (GVJ_t *job, point* A)
+static void doArrowhead (GVJ_t *job, pointf * A)
 {
     FILE *out = job->output_file;
     obj_state_t *obj = job->obj;
@@ -619,7 +499,7 @@ doArrowhead (GVJ_t *job, point* A)
     fprintf(out, "      appearance Appearance {\n");
     fprintf(out, "        material Material {\n");
     fprintf(out, "          ambientIntensity 0.33\n");
-    fprintf(out, "          diffuseColor %f %f %f\n", cstk[SP].r,cstk[SP].g,cstk[SP].b);
+//    fprintf(out, "          diffuseColor %f %f %f\n", cstk[SP].r,cstk[SP].g,cstk[SP].b);
     fprintf(out, "        }\n");
     fprintf(out, "      }\n");
     fprintf(out, "    }\n");
@@ -627,75 +507,41 @@ doArrowhead (GVJ_t *job, point* A)
     fprintf(out, "}\n");
 }
 
-static void vrml_polygon(GVJ_t *job, point * A, int np, int filled)
+static void vrml_polygon(GVJ_t *job, pointf * A, int np, int filled)
 {
     FILE *out = job->output_file;
+    gvstyle_t *style = job->style;
     obj_state_t *obj = job->obj;
     graph_t *g = obj->g;
     node_t *n = obj->n;
     edge_t *e = obj->e;
     double z = obj->z;
     pointf p, mp;
-    int i;
     gdPoint *points;
-    int style[20];
-    int pen, width;
+    int i, pen;
     gdImagePtr brush = NULL;
     double theta;
 
     if (g) {
-       fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n",
-               cstk[SP].r, cstk[SP].g, cstk[SP].b);
+//     fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n",
+//     cstk[SP].r, cstk[SP].g, cstk[SP].b);
        Saw_skycolor = TRUE;
     }
     else if (n) {
+       pen = gdgen_set_penstyle(job, im, brush);
 
-       if (cstk[SP].pen != P_NONE) {
-           cstk[SP].pencolor_ix = vrml_resolve_color(cstk[SP].pencolor);
-           cstk[SP].fillcolor_ix = vrml_resolve_color(cstk[SP].fillcolor);
-           if (cstk[SP].pen == P_DASHED) {
-               for (i = 0; i < 10; i++)
-                   style[i] = cstk[SP].pencolor_ix;
-               for (; i < 20; i++)
-                   style[i] = gdTransparent;
-               gdImageSetStyle(im, style, 20);
-               pen = gdStyled;
-           } else if (cstk[SP].pen == P_DOTTED) {
-               for (i = 0; i < 2; i++)
-                   style[i] = cstk[SP].pencolor_ix;
-               for (; i < 12; i++)
-                   style[i] = gdTransparent;
-               gdImageSetStyle(im, style, 12);
-               pen = gdStyled;
-           } else {
-               pen = cstk[SP].pencolor_ix;
-           }
-           if (cstk[SP].penwidth != WIDTH_NORMAL) {
-               width = cstk[SP].penwidth;
-               brush = gdImageCreate(width, width);
-               gdImagePaletteCopy(brush, im);
-               gdImageFilledRectangle(brush,
-                                      0, 0, width - 1, width - 1,
-                                      cstk[SP].pencolor_ix);
-               gdImageSetBrush(im, brush);
-               if (pen == gdStyled)
-                   pen = gdStyledBrushed;
-               else
-                   pen = gdBrushed;
-           }
-           points = N_GNEW(np, gdPoint);
-           for (i = 0; i < np; i++) {
-               mp = vrml_node_point(job, n, A[i]);
-               points[i].x = ROUND(mp.x);
-               points[i].y = ROUND(mp.y);
-           }
-           if (filled)
-               gdImageFilledPolygon(im, points, np, cstk[SP].fillcolor_ix);
-           gdImagePolygon(im, points, np, pen);
-           free(points);
-           if (brush)
-               gdImageDestroy(brush);
+       points = N_GNEW(np, gdPoint);
+       for (i = 0; i < np; i++) {
+           mp = vrml_node_point(job, n, A[i]);
+           points[i].x = ROUND(mp.x);
+           points[i].y = ROUND(mp.y);
        }
+       if (filled)
+           gdImageFilledPolygon(im, points, np, style->fillcolor.u.index);
+       gdImagePolygon(im, points, np, pen);
+       free(points);
+       if (brush)
+           gdImageDestroy(brush);
 
        fprintf(out, "Shape {\n");
        fprintf(out, "  appearance Appearance {\n");
@@ -703,12 +549,11 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled)
        fprintf(out, "      ambientIntensity 0.33\n");
        fprintf(out, "        diffuseColor 1 1 1\n");
        fprintf(out, "    }\n");
-       fprintf(out, "    texture ImageTexture { url \"node%d.png\" }\n",
-               n->id);
+       fprintf(out, "    texture ImageTexture { url \"node%d.png\" }\n", n->id);
        fprintf(out, "  }\n");
        fprintf(out, "  geometry Extrusion {\n");
        fprintf(out, "    crossSection [");
-       for (i = 0; i < n; i++) {
+       for (i = 0; i < np; i++) {
            p.x = A[i].x - ND_coord_i(n).x;
            p.y = A[i].y - ND_coord_i(n).y;
            fprintf(out, " %.3f %.3f,", p.x, p.y);
@@ -724,8 +569,6 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled)
 
     }
     else if (e) {
-       if (cstk[SP].pen == P_NONE)
-           return;
        if (np != 3) {
            static int flag;
            if (!flag) {
@@ -766,9 +609,8 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled)
        fprintf(out, "      rotation 0 0 1 %.3f\n", theta);
        fprintf(out, "      children [\n");
        fprintf(out, "        Shape {\n");
-       fprintf(out,
-               "          geometry Cone {bottomRadius %.3f height %.3f }\n",
-               cstk[SP].penwidth * 2.5, cstk[SP].penwidth * 10.0);
+       fprintf(out, "          geometry Cone {bottomRadius %.3f height %.3f }\n",
+               style->penwidth * 2.5, style->penwidth * 10.0);
        fprintf(out, "          appearance USE E%d\n", e->id);
        fprintf(out, "        }\n");
        fprintf(out, "      ]\n");
@@ -782,20 +624,16 @@ static void vrml_polygon(GVJ_t *job, point * A, int np, int filled)
  * Output sphere in VRML for point nodes.
  */
 static void 
-doSphere (FILE *out, node_t *n, point p, double z, int rx, int ry)
+doSphere (FILE *out, node_t *n, pointf p, double z, double rx, double ry)
 {
-    pointf  mp;
 
-    if (!(strcmp(cstk[SP].fillcolor, "transparent"))) {
-       return;
-    }
+//    if (!(strcmp(cstk[SP].fillcolor, "transparent"))) {
+//     return;
+//    }
  
-    mp.x = ND_coord_i(n).x;
-    mp.y = ND_coord_i(n).y;
-
     fprintf(out, "Transform {\n");
-    fprintf(out, "  translation %.3f %.3f %.3f\n", mp.x, mp.y, z);
-    fprintf(out, "  scale %d %d %d\n", rx, rx, rx);
+    fprintf(out, "  translation %g %g %g\n", p.x, p.y, z);
+    fprintf(out, "  scale %g %g %g\n", rx, rx, rx);
     fprintf(out, "  children [\n");
     fprintf(out, "    Transform {\n");
     fprintf(out, "      children [\n");
@@ -804,8 +642,8 @@ doSphere (FILE *out, node_t *n, point p, double z, int rx, int ry)
     fprintf(out, "          appearance Appearance {\n");
     fprintf(out, "            material Material {\n");
     fprintf(out, "              ambientIntensity 0.33\n");
-    fprintf(out, "              diffuseColor %f %f %f\n", 
-       cstk[SP].r,cstk[SP].g,cstk[SP].b);
+//    fprintf(out, "              diffuseColor %f %f %f\n", 
+//     cstk[SP].r,cstk[SP].g,cstk[SP].b);
     fprintf(out, "            }\n");
     fprintf(out, "          }\n");
     fprintf(out, "        }\n");
@@ -815,78 +653,51 @@ doSphere (FILE *out, node_t *n, point p, double z, int rx, int ry)
     fprintf(out, "}\n");
 }
 
-static void vrml_ellipse(GVJ_t *job, point p, int rx, int ry, int filled)
+static void vrml_ellipse(GVJ_t * job, pointf * A, int filled)
 {
     FILE *out = job->output_file;
+    gvstyle_t *style = job->style;
     obj_state_t *obj = job->obj;
     node_t *n = obj->n;
     edge_t *e = obj->e;
     double z = obj->z;
-    pointf mp;
-    int i;
-    int style[40];             /* need 2* size for arcs, I don't know why */
-    int pen, width;
+    double rx, ry;
+    int dx, dy;
+    pointf npf, nqf, mp;
+    point np;
+    int pen;
     gdImagePtr brush = NULL;
 
+    rx = A[1].x - A[0].x;
+    ry = A[1].y - A[0].y;
+
     if (n) {
+        P2PF(ND_coord_i(n), mp);
+
        if (shapeOf(n) == SH_POINT) {
-           doSphere (out, n, p, z, rx, ry);
+           doSphere (out, n, A[0], z, rx, ry);
            return;
        }
-       cstk[SP].pencolor_ix = vrml_resolve_color(cstk[SP].pencolor);
-       cstk[SP].fillcolor_ix = vrml_resolve_color(cstk[SP].fillcolor);
-       if (cstk[SP].pen != P_NONE) {
-           if (cstk[SP].pen == P_DASHED) {
-               for (i = 0; i < 20; i++)
-                   style[i] = cstk[SP].pencolor_ix;
-               for (; i < 40; i++)
-                   style[i] = gdTransparent;
-               gdImageSetStyle(im, style, 40);
-               pen = gdStyled;
-           } else if (cstk[SP].pen == P_DOTTED) {
-               for (i = 0; i < 2; i++)
-                   style[i] = cstk[SP].pencolor_ix;
-               for (; i < 24; i++)
-                   style[i] = gdTransparent;
-               gdImageSetStyle(im, style, 24);
-               pen = gdStyled;
-           } else {
-               pen = cstk[SP].pencolor_ix;
-           }
-           if (cstk[SP].penwidth != WIDTH_NORMAL) {
-               width = cstk[SP].penwidth;
-               brush = gdImageCreate(width, width);
-               gdImagePaletteCopy(brush, im);
-               gdImageFilledRectangle(brush,
-                                      0, 0, width - 1, width - 1,
-                                      cstk[SP].pencolor_ix);
-               gdImageSetBrush(im, brush);
-               if (pen == gdStyled)
-                   pen = gdStyledBrushed;
-               else
-                   pen = gdBrushed;
-           }
-           mp = vrml_node_point(job, n, p);
+       pen = gdgen_set_penstyle(job, im, brush);
 
-           if (filled) {
-               gdImageFilledEllipse(im, ROUND(mp.x), ROUND(mp.y),
-                                    ROUND(Scale * (rx + rx)),
-                                    ROUND(Scale * (ry + ry)),
-                                    cstk[SP].fillcolor_ix);
-           }
-           gdImageArc(im, ROUND(mp.x), ROUND(mp.y),
-                      ROUND(Scale * (rx + rx)), ROUND(Scale * (ry + ry)),
-                      0, 360, pen);
-           if (brush)
-               gdImageDestroy(brush);
-       }
+       npf = vrml_node_point(job, n, A[0]);
+       nqf = vrml_node_point(job, n, A[1]);
 
-       mp.x = ND_coord_i(n).x;
-       mp.y = ND_coord_i(n).y;
+       dx = ROUND(2 * (nqf.x - npf.x));
+       dy = ROUND(2 * (nqf.y - npf.y));
+
+       PF2P(npf, np);
+
+       if (filled)
+           gdImageFilledEllipse(im, np.x, np.y, dx, dy, style->fillcolor.u.index);
+       gdImageArc(im, np.x, np.y, dx, dy, 0, 360, pen);
+
+       if (brush)
+           gdImageDestroy(brush);
 
        fprintf(out, "Transform {\n");
-       fprintf(out, "  translation %.3f %.3f %.3f\n", mp.x, mp.y, z);
-       fprintf(out, "  scale %d %d 1\n", rx, ry);
+       fprintf(out, "  translation %g %g %g\n", mp.x, mp.y, z);
+       fprintf(out, "  scale %g %g 1\n", rx, ry);
        fprintf(out, "  children [\n");
        fprintf(out, "    Transform {\n");
        fprintf(out, "      rotation 1 0 0   1.57\n");
@@ -905,24 +716,19 @@ static void vrml_ellipse(GVJ_t *job, point p, int rx, int ry, int filled)
        fprintf(out, "    }\n");
        fprintf(out, "  ]\n");
        fprintf(out, "}\n");
-
     }
     else if (e) {
-       if (cstk[SP].pen == P_NONE)
-           return;
-       mp.x = (double) p.x;
-       mp.y = (double) p.y;
        /* this is gruesome, but how else can we get z coord */
-       if (DIST2(mp, ND_coord_i(e->tail)) < DIST2(mp, ND_coord_i(e->head)))
+       if (DIST2(A[0], ND_coord_i(e->tail)) < DIST2(A[0], ND_coord_i(e->head)))
            z = obj->tail_z;
        else
            z = obj->head_z;
 
        fprintf(out, "Transform {\n");
-       fprintf(out, "  translation %.3f %.3f %.3f\n", mp.x, mp.y, z);
+       fprintf(out, "  translation %g %g %g\n", A[0].x, A[0].y, z);
        fprintf(out, "  children [\n");
        fprintf(out, "    Shape {\n");
-       fprintf(out, "      geometry Sphere {radius %.3f }\n", (double) rx);
+       fprintf(out, "      geometry Sphere {radius %g }\n", (double) rx);
        fprintf(out, "      appearance USE E%d\n", e->id);
        fprintf(out, "    }\n");
        fprintf(out, "  ]\n");
@@ -930,32 +736,8 @@ static void vrml_ellipse(GVJ_t *job, point p, int rx, int ry, int filled)
     }
 }
 
-static void vrml_polyline(point * A, int n)
+static void vrml_polyline(GVJ_t *job, pointf * A, int n)
 {
-/*
-       pointf            p, p1;
-       int                      i;
-
-       if (cstk[SP].pen != P_NONE) {
-               p.x = A[0].x;
-               p.y = A[0].y;
-               for (i = 1; i < n; i++) {
-                       p1.x = A[i].x;
-                       p1.y = A[i].y;
-#ifdef NONEOFTHISEITHER
-                       if (cstk[SP].pen == P_DASHED) {
-                               gdImageDashedLine(im, ROUND(p.x), ROUND(p.y),
-                                       ROUND(p1.x), ROUND(p1.y), cstk[SP].color_ix);
-                       } else {
-                               gdImageLine(im, ROUND(p.x), ROUND(p.y),
-                                       ROUND(p1.x), ROUND(p1.y), cstk[SP].color_ix);
-                       }
-#endif
-                       p.x = p1.x;
-                       p.y = p1.y;
-               }
-       }
-*/
 }
 
 static gvrender_engine_t vrml_engine = {
@@ -1000,10 +782,13 @@ static gvrender_features_t vrml_features = {
     NULL,                       /* gvloadimage target for usershapes */
 };
 #endif                         /* HAVE_GD_PNG */
+#endif                         /* HAVE_LIBGD */
 
-gvplugin_installed_t gvrender_gd_types[] = {
+gvplugin_installed_t gvrender_vrml_types[] = {
+#ifdef HAVE_LIBGD
 #ifdef HAVE_GD_PNG
     {FORMAT_VRML, "vrml", 1, &vrml_engine, &vrml_features},
+#endif
 #endif
     {0, NULL, 0, NULL, NULL}
 };
index fc3ed11985a54dc821225e05daa9194f74909316..1c42040802ff8c18f43bfcaaead61b7b62b47d20 100644 (file)
@@ -27,4 +27,4 @@ static gvplugin_api_t apis[] = {
     {(api_t)0, 0},
 };
 
-gvplugin_library_t gvplugin_pango_LTX_library = { "pango", apis };
+gvplugin_library_t gvplugin_pango_LTX_library = { "cairo", apis };